instar 1.3.631 → 1.3.632
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -457,13 +457,18 @@ export function renderAccountMatrix(doc, target, poolScope, pendingScope, transi
|
|
|
457
457
|
tr.appendChild(el(doc, 'th', 'sub-matrix-acct', sanitizeForDisplay(row.account.email, 'label')));
|
|
458
458
|
for (const c of row.cells) {
|
|
459
459
|
const td = el(doc, 'td', `sub-matrix-cell sub-matrix-${c.state}`);
|
|
460
|
-
if (c.state === 'empty' || c.state === 'held' || c.state === 'cant-resolve') {
|
|
461
|
-
// An actionable cell → a
|
|
462
|
-
|
|
460
|
+
if (c.state === 'empty' || c.state === 'needs-reauth' || c.state === 'held' || c.state === 'cant-resolve') {
|
|
461
|
+
// An actionable cell → a button that runs the SAME in-dashboard sign-in flow (PIN → link →
|
|
462
|
+
// paste code). empty → "Set up"; needs-reauth (an existing account whose login expired) →
|
|
463
|
+
// "Sign in"; held/cant-resolve → "Retry". A needs-reauth account already resolves to its
|
|
464
|
+
// email, so the start-cell orchestrator drives a real re-auth — never a cosmetic button.
|
|
465
|
+
const label = c.state === 'empty' ? 'Set up' : (c.state === 'needs-reauth' ? 'Sign in' : 'Retry');
|
|
466
|
+
const btn = el(doc, 'button', 'sub-matrix-setup', label);
|
|
463
467
|
btn.setAttribute('data-matrix-setup', '1');
|
|
464
468
|
btn.setAttribute('data-account-id', sanitizeForDisplay(c.accountId, 'label'));
|
|
465
469
|
btn.setAttribute('data-machine-id', sanitizeForDisplay(c.machineId, 'label'));
|
|
466
470
|
if (c.state !== 'empty') {
|
|
471
|
+
// Show the status word ("⟳ Needs sign-in" / "⚠ Didn't match…") ABOVE the button.
|
|
467
472
|
td.appendChild(el(doc, 'div', 'sub-matrix-glyph', `${MATRIX_CELL_GLYPH[c.state]} ${MATRIX_CELL_WORD[c.state]}`));
|
|
468
473
|
}
|
|
469
474
|
td.appendChild(btn);
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./builtin-manifest.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"generatedAt": "2026-06-
|
|
5
|
-
"instarVersion": "1.3.
|
|
4
|
+
"generatedAt": "2026-06-20T18:23:55.492Z",
|
|
5
|
+
"instarVersion": "1.3.632",
|
|
6
6
|
"entryCount": 202,
|
|
7
7
|
"entries": {
|
|
8
8
|
"hook:session-start": {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
The Subscriptions dashboard's account × machine matrix had a dead-end. A cell whose login had expired showed only the grey text "⟳ Needs sign-in" with **no button to act on** — so you could see an account needed re-authentication but had no way to do anything about it from the dashboard. Every other cell-state was already actionable: an empty cell gets a "Set up" button, a failed cell gets a "Retry" button. The `needs-reauth` state was simply left out of the branch that renders a button and fell through to the "just draw text" path.
|
|
9
|
+
|
|
10
|
+
This fix moves `needs-reauth` into the actionable branch in `dashboard/subscriptions.js`. The cell now shows the status word "⟳ Needs sign-in" **and** a "Sign in" button directly below it. The button carries the same `(account, machine)` ids as the "Set up" button and runs the exact same in-dashboard flow (PIN → provider sign-in link → paste code). Because a needs-sign-in account already resolves to its email, the `start-cell` orchestrator drives a genuine re-authentication — the button is real, not cosmetic. No server route, authority, or data model changed; the PIN gate on starting a login is untouched.
|
|
11
|
+
|
|
12
|
+
## What to Tell Your User
|
|
13
|
+
|
|
14
|
+
If you saw an account in your Subscriptions grid marked "Needs sign-in" with no way to fix it, that's now a one-tap action. The cell shows "Needs sign-in" with a **Sign in** button right below — tap it, enter your PIN, open the sign-in link, and paste the code back, exactly like setting up a new account. Everything stays inside the dashboard; nothing changed about who's allowed to start a login.
|
|
15
|
+
|
|
16
|
+
## Summary of New Capabilities
|
|
17
|
+
|
|
18
|
+
- The account × machine matrix's "Needs sign-in" cell is now actionable: it renders the status word **plus a "Sign in" button** that runs the existing in-dashboard re-authentication flow (PIN → link → paste code).
|
|
19
|
+
- The button works for an account whose login expired on this machine OR on a peer machine — it rides the same PIN-gated, mesh-delivered `start-cell` path the "Set up" button already uses.
|
|
20
|
+
- No change to authorization: starting a login still requires the operator's dashboard PIN.
|
|
21
|
+
|
|
22
|
+
## Evidence
|
|
23
|
+
|
|
24
|
+
- New regression unit test in `tests/unit/subscriptions-render.test.ts`: asserts a `needs-reauth` cell renders the "Needs sign-in" word AND a `.sub-matrix-setup` "Sign in" button wired to the start-cell flow (`data-matrix-setup`, correct account/machine ids). 34/34 in that file pass.
|
|
25
|
+
- Related front-end tests green: `follow-me-controller-wiring.test.ts` (8) and `account-follow-me-locally-executable.test.ts` (9) — confirms the existing tap-handler/flow this button re-uses is unchanged.
|
|
26
|
+
- Traced root cause directly in `renderAccountMatrix`: `needs-reauth` was absent from the actionable-cell branch condition; the server `start-cell` route resolves an existing account's email and drives a real re-auth, so the new button is functional.
|
|
27
|
+
- Side-effects review: `upgrades/side-effects/matrix-needs-signin-button.md` (no block/allow surface; no new authority; machine-local render of an existing pool-scope flow). Tier 1.
|
|
28
|
+
|
|
29
|
+
## ELI16
|
|
30
|
+
|
|
31
|
+
The Subscriptions screen has a grid showing which account is signed in on which machine. Empty squares had a "Set up" button you could tap. But a square for an account whose login had run out just said "Needs sign-in" in grey — with no button. So you could see the problem but couldn't fix it from the screen. Turns out the code that decides "should this square have a button?" simply forgot to include the "needs sign-in" case, so it drew plain text instead. This fix adds the button: the square now says "Needs sign-in" with a "Sign in" button right under it, and tapping it runs the same sign-in steps as setting up a new account (enter your PIN, open the link, paste the code). It actually signs the account back in — it's not a fake button — and it works whether the account expired on this machine or another one.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Side-Effects Review — Account matrix "Needs sign-in" → actionable Sign-in button
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `matrix-needs-signin-button`
|
|
4
|
+
**Date:** `2026-06-20`
|
|
5
|
+
**Author:** `Instar Agent (echo)`
|
|
6
|
+
**Second-pass reviewer:** `not required (no block/allow surface, no lifecycle/gate/sentinel)`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
The account × machine matrix in the Subscriptions dashboard had a cell-state, `needs-reauth` ("Needs sign-in"), that rendered as static text with no actionable control — a dead-end. This change (one branch condition + a button label in `dashboard/subscriptions.js`, plus one unit test in `tests/unit/subscriptions-render.test.ts`) moves `needs-reauth` into the actionable rendering branch so it draws the status word "⟳ Needs sign-in" AND a "Sign in" button directly below it. The button carries the same `data-matrix-setup` / `data-account-id` / `data-machine-id` attributes the empty-cell "Set up" button does, so it routes through the EXISTING, unchanged PIN-gated `start-cell` → sign-in-link → code-paste flow. No server route, authority, or data model is touched.
|
|
11
|
+
|
|
12
|
+
## Decision-point inventory
|
|
13
|
+
|
|
14
|
+
This change touches NO decision point. It is presentation logic only: it decides which DOM (a button vs plain text) to render for an already-computed cell state. The authority that gates starting a login (the dashboard-PIN check on `POST /subscription-pool/matrix/start-cell`) is unchanged and continues to be the sole gate.
|
|
15
|
+
|
|
16
|
+
- `renderAccountMatrix` cell rendering (`dashboard/subscriptions.js`) — modify — adds `needs-reauth` to the set of cell-states that render an actionable button; pure view logic, no gating.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 1. Over-block
|
|
21
|
+
|
|
22
|
+
No block/allow surface — over-block not applicable. The change ADDS an affordance; it rejects nothing.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 2. Under-block
|
|
27
|
+
|
|
28
|
+
No block/allow surface — under-block not applicable. The PIN gate on `start-cell` is unchanged, so this adds no new path that bypasses authorization: tapping "Sign in" still requires the operator's PIN to actually start a login, exactly as "Set up" does.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 3. Level-of-abstraction fit
|
|
33
|
+
|
|
34
|
+
Correct layer. This is a view-rendering concern living in the dashboard front-end, exactly where the sibling "Set up"/"Retry" button logic already lives. It re-uses the existing `start-cell` orchestrator rather than re-implementing any email-resolution / mandate / login logic — it feeds the smart gate that already exists instead of running parallel to it.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 4. Signal vs authority compliance
|
|
39
|
+
|
|
40
|
+
Compliant. The change adds NO blocking authority and NO brittle decision logic. It renders a button that, when tapped, calls an existing PIN-gated authority (`start-cell`). The button itself holds no authority; the server endpoint remains the single authority and is untouched.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 5. Interactions
|
|
45
|
+
|
|
46
|
+
- The new button uses the SAME delegated tap handler (`wireMatrixSetup` → `onSetupTap` → `onConfirmTap` → `start-cell`) as the empty-cell "Set up" button, so it cannot double-fire or shadow another handler — it is the same code path keyed on `data-matrix-setup`.
|
|
47
|
+
- `start-cell` already handles an existing account: it resolves the account email from the accountId (`resolveFollowMeEnrollTarget`) and has self-target idempotency that reuses an in-flight pending login. A needs-reauth account resolves to its email, so the flow drives a real re-auth and does not mint a duplicate when one is already pending.
|
|
48
|
+
- No race with adjacent cleanup: the cell re-renders from durable state each poll; an in-progress login transitions the cell to the in-progress (◷) state with its Cancel button, exactly as a "Set up"-initiated login does.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 6. External surfaces
|
|
53
|
+
|
|
54
|
+
The only external surface is the dashboard UI: a `needs-reauth` cell now shows a "Sign in" button. No change to any API response, agent-to-agent surface, or other system. No new timing/conversation-state dependency — rendering is a pure function of the already-fetched pool/pending state.
|
|
55
|
+
|
|
56
|
+
### 6b. Operator-surface quality
|
|
57
|
+
|
|
58
|
+
This change EXISTS to improve operator-surface quality: it converts a non-actionable status into a one-tap action, matching the operator's directive that everything be actionable from the dashboard. The button label ("Sign in") matches the flow's existing vocabulary; the status word remains visible so the operator still understands WHY the action is offered.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 7. Multi-machine posture (Cross-Machine Coherence)
|
|
63
|
+
|
|
64
|
+
Machine-local rendering of a pool-scope read, BY DESIGN. The matrix already reads `scope=pool` (peers merged) and the `start-cell` flow already delivers the mandate over the mesh for a peer-target cell. A needs-reauth cell on a PEER machine (e.g. the account expired on the Laptop while the Mini fronts the dashboard) routes its "Sign in" through the same proven cross-machine `start-cell` → peer enroll/start path the "Set up" button uses. No new replication or per-machine state is introduced; the change rides the existing cross-machine plumbing.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 8. Rollback cost
|
|
69
|
+
|
|
70
|
+
Trivial. Revert the single commit (one branch condition + label + one test) — the cell returns to showing static "Needs sign-in" text. No data migration, no agent-state repair, no release coordination. Dashboard files ship static (no compiled artifact), so a revert is immediately effective on next deploy.
|