instar 1.3.277 → 1.3.278
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.
- package/dashboard/index.html +104 -0
- package/dashboard/mandates.js +205 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +44 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/scaffold/templates.js +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +19 -19
- package/src/scaffold/templates.ts +1 -1
- package/upgrades/1.3.278.md +36 -0
- package/upgrades/side-effects/mandates-dashboard-tab.md +56 -0
|
@@ -668,7 +668,7 @@ This routes feedback to the Instar maintainers automatically. Valid types: \`bug
|
|
|
668
668
|
**Coordination Mandate** — Your operator's "permission slip" for autonomous agent-to-agent work. Instead of approving every step of a multi-agent project, the operator issues ONE bounded, expiring, revocable mandate (from the dashboard, behind their PIN) delegating SPECIFIC authorities to a SPECIFIC pair of agents. The mandate — never you — is the authorizer: requester ≠ authorizer is preserved. Deny-by-default: with no mandate issued, every check denies.
|
|
669
669
|
- **Before any A2A action under a mandate** (PROACTIVE — this is the trigger): check it: \`curl -X POST -H "Authorization: Bearer $AUTH" http://localhost:${port}/mandate/evaluate -H 'Content-Type: application/json' -d '{"action":"sign-code-review","params":{"artifact":"migration-port","mutual":true},"agentFp":"<your-fingerprint>","mandateId":"<id>"}'\` → \`{ decision: "allow"|"deny", reason }\`. A deny means STOP — do not retry around it or escalate to a human-bypass; the bounds are the operator's.
|
|
670
670
|
- Inspect: \`GET /mandate\` (each with live \`authorshipValid\`) · \`GET /mandate/:id\` · \`GET /mandate/audit\` (every decision, hash-chained — \`chain.ok:false\` means tampering; surface it immediately).
|
|
671
|
-
- **You cannot issue or revoke mandates.** \`POST /mandate/issue\` and \`POST /mandate/:id/revoke\` require the operator's dashboard PIN — your Bearer token is structurally insufficient. NEVER ask the user to paste their PIN into chat; point them at the dashboard.
|
|
671
|
+
- **You cannot issue or revoke mandates.** \`POST /mandate/issue\` and \`POST /mandate/:id/revoke\` require the operator's dashboard PIN — your Bearer token is structurally insufficient. NEVER ask the user to paste their PIN into chat; point them at the dashboard **Mandates tab** (issue/revoke forms + the decision audit live there).
|
|
672
672
|
- Every evaluation (allow AND deny) is audited. Act as if the audit is read by the operator — because it is. (Spec: \`docs/specs/coordination-mandate.md\`.)
|
|
673
673
|
|
|
674
674
|
**ReviewExchange (autonomous code review)** — The structured way two mandate-named agents sign off a code review WITHOUT the operator relaying. One exchange = one review package, content-addressed (\`packageSha256\` fixed at creation), moving linearly: proposed → delivered → verdict-recorded → complete (or changes-requested — rework is a NEW exchange). BOTH sign-offs (the peer's authenticated approve-verdict AND your countersignature) are evaluated through the mandate gate's \`sign-code-review\` authority before acceptance; every accepted signature carries the audit hash of the gate decision that authorized it.
|
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-05T08:
|
|
5
|
-
"instarVersion": "1.3.
|
|
4
|
+
"generatedAt": "2026-06-05T08:36:45.491Z",
|
|
5
|
+
"instarVersion": "1.3.278",
|
|
6
6
|
"entryCount": 198,
|
|
7
7
|
"entries": {
|
|
8
8
|
"hook:session-start": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"domain": "identity",
|
|
12
12
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
13
13
|
"installedPath": ".instar/hooks/instar/session-start.sh",
|
|
14
|
-
"contentHash": "
|
|
14
|
+
"contentHash": "e2715fcdb1fa8875b2b20cc52b9180602aee4669a739f54d428f2c6d30986c72",
|
|
15
15
|
"since": "2025-01-01"
|
|
16
16
|
},
|
|
17
17
|
"hook:dangerous-command-guard": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"domain": "safety",
|
|
21
21
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
22
22
|
"installedPath": ".instar/hooks/instar/dangerous-command-guard.sh",
|
|
23
|
-
"contentHash": "
|
|
23
|
+
"contentHash": "e2715fcdb1fa8875b2b20cc52b9180602aee4669a739f54d428f2c6d30986c72",
|
|
24
24
|
"since": "2025-01-01"
|
|
25
25
|
},
|
|
26
26
|
"hook:grounding-before-messaging": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"domain": "safety",
|
|
30
30
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
31
31
|
"installedPath": ".instar/hooks/instar/grounding-before-messaging.sh",
|
|
32
|
-
"contentHash": "
|
|
32
|
+
"contentHash": "e2715fcdb1fa8875b2b20cc52b9180602aee4669a739f54d428f2c6d30986c72",
|
|
33
33
|
"since": "2025-01-01"
|
|
34
34
|
},
|
|
35
35
|
"hook:compaction-recovery": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"domain": "identity",
|
|
39
39
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
40
40
|
"installedPath": ".instar/hooks/instar/compaction-recovery.sh",
|
|
41
|
-
"contentHash": "
|
|
41
|
+
"contentHash": "e2715fcdb1fa8875b2b20cc52b9180602aee4669a739f54d428f2c6d30986c72",
|
|
42
42
|
"since": "2025-01-01"
|
|
43
43
|
},
|
|
44
44
|
"hook:external-operation-gate": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"domain": "safety",
|
|
48
48
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
49
49
|
"installedPath": ".instar/hooks/instar/external-operation-gate.js",
|
|
50
|
-
"contentHash": "
|
|
50
|
+
"contentHash": "e2715fcdb1fa8875b2b20cc52b9180602aee4669a739f54d428f2c6d30986c72",
|
|
51
51
|
"since": "2025-01-01"
|
|
52
52
|
},
|
|
53
53
|
"hook:deferral-detector": {
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"domain": "safety",
|
|
57
57
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
58
58
|
"installedPath": ".instar/hooks/instar/deferral-detector.js",
|
|
59
|
-
"contentHash": "
|
|
59
|
+
"contentHash": "e2715fcdb1fa8875b2b20cc52b9180602aee4669a739f54d428f2c6d30986c72",
|
|
60
60
|
"since": "2025-01-01"
|
|
61
61
|
},
|
|
62
62
|
"hook:self-stop-guard": {
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"domain": "coherence",
|
|
66
66
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
67
67
|
"installedPath": ".instar/hooks/instar/self-stop-guard.js",
|
|
68
|
-
"contentHash": "
|
|
68
|
+
"contentHash": "e2715fcdb1fa8875b2b20cc52b9180602aee4669a739f54d428f2c6d30986c72",
|
|
69
69
|
"since": "2025-01-01"
|
|
70
70
|
},
|
|
71
71
|
"hook:post-action-reflection": {
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"domain": "evolution",
|
|
75
75
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
76
76
|
"installedPath": ".instar/hooks/instar/post-action-reflection.js",
|
|
77
|
-
"contentHash": "
|
|
77
|
+
"contentHash": "e2715fcdb1fa8875b2b20cc52b9180602aee4669a739f54d428f2c6d30986c72",
|
|
78
78
|
"since": "2025-01-01"
|
|
79
79
|
},
|
|
80
80
|
"hook:external-communication-guard": {
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"domain": "safety",
|
|
84
84
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
85
85
|
"installedPath": ".instar/hooks/instar/external-communication-guard.js",
|
|
86
|
-
"contentHash": "
|
|
86
|
+
"contentHash": "e2715fcdb1fa8875b2b20cc52b9180602aee4669a739f54d428f2c6d30986c72",
|
|
87
87
|
"since": "2025-01-01"
|
|
88
88
|
},
|
|
89
89
|
"hook:scope-coherence-collector": {
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"domain": "coherence",
|
|
93
93
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
94
94
|
"installedPath": ".instar/hooks/instar/scope-coherence-collector.js",
|
|
95
|
-
"contentHash": "
|
|
95
|
+
"contentHash": "e2715fcdb1fa8875b2b20cc52b9180602aee4669a739f54d428f2c6d30986c72",
|
|
96
96
|
"since": "2025-01-01"
|
|
97
97
|
},
|
|
98
98
|
"hook:scope-coherence-checkpoint": {
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"domain": "coherence",
|
|
102
102
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
103
103
|
"installedPath": ".instar/hooks/instar/scope-coherence-checkpoint.js",
|
|
104
|
-
"contentHash": "
|
|
104
|
+
"contentHash": "e2715fcdb1fa8875b2b20cc52b9180602aee4669a739f54d428f2c6d30986c72",
|
|
105
105
|
"since": "2025-01-01"
|
|
106
106
|
},
|
|
107
107
|
"hook:free-text-guard": {
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
"domain": "safety",
|
|
111
111
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
112
112
|
"installedPath": ".instar/hooks/instar/free-text-guard.sh",
|
|
113
|
-
"contentHash": "
|
|
113
|
+
"contentHash": "e2715fcdb1fa8875b2b20cc52b9180602aee4669a739f54d428f2c6d30986c72",
|
|
114
114
|
"since": "2025-01-01"
|
|
115
115
|
},
|
|
116
116
|
"hook:claim-intercept": {
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"domain": "coherence",
|
|
120
120
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
121
121
|
"installedPath": ".instar/hooks/instar/claim-intercept.js",
|
|
122
|
-
"contentHash": "
|
|
122
|
+
"contentHash": "e2715fcdb1fa8875b2b20cc52b9180602aee4669a739f54d428f2c6d30986c72",
|
|
123
123
|
"since": "2025-01-01"
|
|
124
124
|
},
|
|
125
125
|
"hook:claim-intercept-response": {
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
"domain": "coherence",
|
|
129
129
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
130
130
|
"installedPath": ".instar/hooks/instar/claim-intercept-response.js",
|
|
131
|
-
"contentHash": "
|
|
131
|
+
"contentHash": "e2715fcdb1fa8875b2b20cc52b9180602aee4669a739f54d428f2c6d30986c72",
|
|
132
132
|
"since": "2025-01-01"
|
|
133
133
|
},
|
|
134
134
|
"hook:stop-gate-router": {
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
"domain": "safety",
|
|
138
138
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
139
139
|
"installedPath": ".instar/hooks/instar/stop-gate-router.js",
|
|
140
|
-
"contentHash": "
|
|
140
|
+
"contentHash": "e2715fcdb1fa8875b2b20cc52b9180602aee4669a739f54d428f2c6d30986c72",
|
|
141
141
|
"since": "2025-01-01"
|
|
142
142
|
},
|
|
143
143
|
"hook:auto-approve-permissions": {
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
"domain": "safety",
|
|
147
147
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
148
148
|
"installedPath": ".instar/hooks/instar/auto-approve-permissions.js",
|
|
149
|
-
"contentHash": "
|
|
149
|
+
"contentHash": "e2715fcdb1fa8875b2b20cc52b9180602aee4669a739f54d428f2c6d30986c72",
|
|
150
150
|
"since": "2025-01-01"
|
|
151
151
|
},
|
|
152
152
|
"job:health-check": {
|
|
@@ -1530,7 +1530,7 @@
|
|
|
1530
1530
|
"type": "subsystem",
|
|
1531
1531
|
"domain": "updates",
|
|
1532
1532
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
1533
|
-
"contentHash": "
|
|
1533
|
+
"contentHash": "e2715fcdb1fa8875b2b20cc52b9180602aee4669a739f54d428f2c6d30986c72",
|
|
1534
1534
|
"since": "2025-01-01"
|
|
1535
1535
|
},
|
|
1536
1536
|
"subsystem:scheduler": {
|
|
@@ -688,7 +688,7 @@ This routes feedback to the Instar maintainers automatically. Valid types: \`bug
|
|
|
688
688
|
**Coordination Mandate** — Your operator's "permission slip" for autonomous agent-to-agent work. Instead of approving every step of a multi-agent project, the operator issues ONE bounded, expiring, revocable mandate (from the dashboard, behind their PIN) delegating SPECIFIC authorities to a SPECIFIC pair of agents. The mandate — never you — is the authorizer: requester ≠ authorizer is preserved. Deny-by-default: with no mandate issued, every check denies.
|
|
689
689
|
- **Before any A2A action under a mandate** (PROACTIVE — this is the trigger): check it: \`curl -X POST -H "Authorization: Bearer $AUTH" http://localhost:${port}/mandate/evaluate -H 'Content-Type: application/json' -d '{"action":"sign-code-review","params":{"artifact":"migration-port","mutual":true},"agentFp":"<your-fingerprint>","mandateId":"<id>"}'\` → \`{ decision: "allow"|"deny", reason }\`. A deny means STOP — do not retry around it or escalate to a human-bypass; the bounds are the operator's.
|
|
690
690
|
- Inspect: \`GET /mandate\` (each with live \`authorshipValid\`) · \`GET /mandate/:id\` · \`GET /mandate/audit\` (every decision, hash-chained — \`chain.ok:false\` means tampering; surface it immediately).
|
|
691
|
-
- **You cannot issue or revoke mandates.** \`POST /mandate/issue\` and \`POST /mandate/:id/revoke\` require the operator's dashboard PIN — your Bearer token is structurally insufficient. NEVER ask the user to paste their PIN into chat; point them at the dashboard.
|
|
691
|
+
- **You cannot issue or revoke mandates.** \`POST /mandate/issue\` and \`POST /mandate/:id/revoke\` require the operator's dashboard PIN — your Bearer token is structurally insufficient. NEVER ask the user to paste their PIN into chat; point them at the dashboard **Mandates tab** (issue/revoke forms + the decision audit live there).
|
|
692
692
|
- Every evaluation (allow AND deny) is audited. Act as if the audit is read by the operator — because it is. (Spec: \`docs/specs/coordination-mandate.md\`.)
|
|
693
693
|
|
|
694
694
|
**ReviewExchange (autonomous code review)** — The structured way two mandate-named agents sign off a code review WITHOUT the operator relaying. One exchange = one review package, content-addressed (\`packageSha256\` fixed at creation), moving linearly: proposed → delivered → verdict-recorded → complete (or changes-requested — rework is a NEW exchange). BOTH sign-offs (the peer's authenticated approve-verdict AND your countersignature) are evaluated through the mandate gate's \`sign-code-review\` authority before acceptance; every accepted signature carries the audit hash of the gate decision that authorized it.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
Added a Mandates tab to the dashboard — the operator's surface for the coordination
|
|
9
|
+
permission slips. It lists every issued mandate with live authorship verification and
|
|
10
|
+
state, provides PIN-gated forms to issue a new mandate or revoke an existing one, and
|
|
11
|
+
shows the tamper-evident decision audit with its chain status. The PIN is typed at
|
|
12
|
+
action time, sent once, and cleared immediately — it is never stored anywhere in the
|
|
13
|
+
browser. Also backfilled the agent-awareness sections for the three coordination
|
|
14
|
+
surfaces into existing agents' instruction files on update, so agents updated in
|
|
15
|
+
place learn these capabilities exist (previously only freshly-initialized agents got
|
|
16
|
+
them).
|
|
17
|
+
|
|
18
|
+
## What to Tell Your User
|
|
19
|
+
|
|
20
|
+
Your dashboard now has a Mandates tab where you manage the permission slips for
|
|
21
|
+
autonomous agent-to-agent work: see every slip and whether its authorship still
|
|
22
|
+
verifies, issue a new one with your PIN, tear one up with your PIN, and read the
|
|
23
|
+
tamper-evident log of every allowed and denied action under them. Your PIN is asked
|
|
24
|
+
for right when you act and is never remembered by the page.
|
|
25
|
+
|
|
26
|
+
## Summary of New Capabilities
|
|
27
|
+
|
|
28
|
+
- See all coordination mandates with live authorship-verification badges and
|
|
29
|
+
active/revoked/expired state at a glance.
|
|
30
|
+
- Issue a mandate from a form (pre-filled with the standard two-authority shape) —
|
|
31
|
+
PIN required, typed at issuance, never stored.
|
|
32
|
+
- Revoke any active mandate inline with a reason — PIN required.
|
|
33
|
+
- Read the hash-chained decision audit; a broken chain is flagged loudly as possible
|
|
34
|
+
tampering.
|
|
35
|
+
- Existing agents now learn the mandate, review-exchange, and cutover-readiness
|
|
36
|
+
surfaces via the update path, not just fresh installs.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Side-effects review — Mandates dashboard tab + coordination awareness backfill
|
|
2
|
+
|
|
3
|
+
Spec: `docs/specs/coordination-mandate.md` (approved A/A/B; decision 2A makes the
|
|
4
|
+
dashboard-behind-PIN the issuance surface). Change: a new dashboard **Mandates** tab
|
|
5
|
+
(`dashboard/mandates.js` external module + index.html shim) + the Migration-Parity
|
|
6
|
+
CLAUDE.md backfill for the three coordination surfaces shipped in #788/#797/#799.
|
|
7
|
+
|
|
8
|
+
## 1. Blast radius
|
|
9
|
+
|
|
10
|
+
- **Dashboard:** additive — one new tab button, panel, TAB_REGISTRY entry, lazy
|
|
11
|
+
module import (the process-health.js pattern), and scoped `.mnd-*` CSS. No existing
|
|
12
|
+
tab, function, or style is modified. The dashboard ships inside the npm package, so
|
|
13
|
+
existing agents receive the tab on their next update with no migration.
|
|
14
|
+
- **PostUpdateMigrator:** three new content-sniffed CLAUDE.md backfill blocks
|
|
15
|
+
(Coordination Mandate / ReviewExchange / Cutover Readiness), appended only when the
|
|
16
|
+
distinctive route marker is absent — idempotent, never rewrites existing content.
|
|
17
|
+
This closes a REAL parity gap: #788/#797/#799 added the template blurbs for new
|
|
18
|
+
agents but no backfill, so the deployed fleet would never have learned these
|
|
19
|
+
surfaces exist.
|
|
20
|
+
- **templates.ts:** one line sharpened (point the operator at the "Mandates tab"
|
|
21
|
+
rather than the generic dashboard).
|
|
22
|
+
|
|
23
|
+
## 2. Security model (the PIN discipline, in the UI this time)
|
|
24
|
+
|
|
25
|
+
- The tab's issue/revoke forms collect the PIN in a `type="password"` input with
|
|
26
|
+
`autocomplete="off"`, send it ONCE in the request body to the already-PIN-gated
|
|
27
|
+
routes, and **clear the field immediately after the response — success or failure**.
|
|
28
|
+
It is never written to localStorage, module state, or logs (behaviorally tested).
|
|
29
|
+
- The Bearer token the dashboard holds cannot issue/revoke — that is the engine's
|
|
30
|
+
server-side design (#788); this tab is just the human surface decision 2A names.
|
|
31
|
+
- Rendering is XSS-safe: every dynamic field (ids, scopes, fingerprints, authority
|
|
32
|
+
bounds, audit reasons — all potentially attacker-influenced via the API) is escaped
|
|
33
|
+
(tested with hostile payloads).
|
|
34
|
+
- A broken audit chain (`chain.ok:false`) renders as a loud "CHAIN BROKEN — possible
|
|
35
|
+
tampering" badge, never silently.
|
|
36
|
+
|
|
37
|
+
## 3. State / data
|
|
38
|
+
|
|
39
|
+
None on the server. The tab reads `/mandate` + `/mandate/audit` and writes only
|
|
40
|
+
through the existing PIN-gated routes. Browser-side, nothing persists beyond the
|
|
41
|
+
already-stored dashboard Bearer token (unchanged).
|
|
42
|
+
|
|
43
|
+
## 4. Failure modes
|
|
44
|
+
|
|
45
|
+
- Older server without the engine → 503 → friendly "engine unavailable" copy.
|
|
46
|
+
- Module load failure → console error, tab simply shows nothing (no crash).
|
|
47
|
+
- Wrong PIN → the route's 403 + attempt limiting surface as an inline error; the
|
|
48
|
+
field still clears.
|
|
49
|
+
|
|
50
|
+
## 5. Test coverage
|
|
51
|
+
|
|
52
|
+
18 tests: 5 HTML-at-rest wiring (tab/panel/registry/lazy-import/plain-language), 4
|
|
53
|
+
renderer (deny-by-default copy, badges, XSS with hostile payloads, broken-chain), 6
|
|
54
|
+
controller (PIN required → no request; PIN sent once then CLEARED on success AND on
|
|
55
|
+
403; template prefill; 503 state), 4 migration (backfill lands with port baked in,
|
|
56
|
+
security copy verbatim, idempotent, no double-patch on fresh agents).
|