instar 1.3.269 → 1.3.271
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 +73 -11
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +24 -3
- package/dist/commands/server.js.map +1 -1
- package/dist/coordination/MandateAudit.d.ts +48 -0
- package/dist/coordination/MandateAudit.d.ts.map +1 -0
- package/dist/coordination/MandateAudit.js +95 -0
- package/dist/coordination/MandateAudit.js.map +1 -0
- package/dist/coordination/MandateGate.d.ts +48 -0
- package/dist/coordination/MandateGate.d.ts.map +1 -0
- package/dist/coordination/MandateGate.js +104 -0
- package/dist/coordination/MandateGate.js.map +1 -0
- package/dist/coordination/MandateStore.d.ts +60 -0
- package/dist/coordination/MandateStore.d.ts.map +1 -0
- package/dist/coordination/MandateStore.js +106 -0
- package/dist/coordination/MandateStore.js.map +1 -0
- package/dist/coordination/ReviewExchange.d.ts +135 -0
- package/dist/coordination/ReviewExchange.d.ts.map +1 -0
- package/dist/coordination/ReviewExchange.js +192 -0
- package/dist/coordination/ReviewExchange.js.map +1 -0
- package/dist/coordination/conditions.d.ts +32 -0
- package/dist/coordination/conditions.d.ts.map +1 -0
- package/dist/coordination/conditions.js +54 -0
- package/dist/coordination/conditions.js.map +1 -0
- package/dist/coordination/types.d.ts +74 -0
- package/dist/coordination/types.d.ts.map +1 -0
- package/dist/coordination/types.js +17 -0
- package/dist/coordination/types.js.map +1 -0
- package/dist/core/ApprovalLedger.d.ts +132 -0
- package/dist/core/ApprovalLedger.d.ts.map +1 -0
- package/dist/core/ApprovalLedger.js +191 -0
- package/dist/core/ApprovalLedger.js.map +1 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +33 -1
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/SecretStore.d.ts.map +1 -1
- package/dist/core/SecretStore.js +10 -1
- package/dist/core/SecretStore.js.map +1 -1
- package/dist/core/SessionBuildContextStore.d.ts +33 -0
- package/dist/core/SessionBuildContextStore.d.ts.map +1 -0
- package/dist/core/SessionBuildContextStore.js +107 -0
- package/dist/core/SessionBuildContextStore.js.map +1 -0
- package/dist/core/SessionManager.d.ts +4 -0
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +44 -3
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/TransferByNickname.d.ts +6 -0
- package/dist/core/TransferByNickname.d.ts.map +1 -1
- package/dist/core/TransferByNickname.js +18 -6
- package/dist/core/TransferByNickname.js.map +1 -1
- package/dist/core/seamlessnessConfig.d.ts.map +1 -1
- package/dist/core/seamlessnessConfig.js +12 -1
- package/dist/core/seamlessnessConfig.js.map +1 -1
- package/dist/core/types.d.ts +34 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/feedback-factory/migration/immutableGuard.d.ts +87 -0
- package/dist/feedback-factory/migration/immutableGuard.d.ts.map +1 -0
- package/dist/feedback-factory/migration/immutableGuard.js +163 -0
- package/dist/feedback-factory/migration/immutableGuard.js.map +1 -0
- package/dist/feedback-factory/migration/importIntegrity.d.ts +112 -0
- package/dist/feedback-factory/migration/importIntegrity.d.ts.map +1 -0
- package/dist/feedback-factory/migration/importIntegrity.js +202 -0
- package/dist/feedback-factory/migration/importIntegrity.js.map +1 -0
- package/dist/feedback-factory/monitor/parityMonitor.d.ts +75 -0
- package/dist/feedback-factory/monitor/parityMonitor.d.ts.map +1 -0
- package/dist/feedback-factory/monitor/parityMonitor.js +98 -0
- package/dist/feedback-factory/monitor/parityMonitor.js.map +1 -0
- package/dist/feedback-factory/monitor/parityMonitorStore.d.ts +44 -0
- package/dist/feedback-factory/monitor/parityMonitorStore.d.ts.map +1 -0
- package/dist/feedback-factory/monitor/parityMonitorStore.js +80 -0
- package/dist/feedback-factory/monitor/parityMonitorStore.js.map +1 -0
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +19 -1
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/scheduler/MentorAutonomousGuardian.d.ts.map +1 -1
- package/dist/scheduler/MentorAutonomousGuardian.js +1 -0
- package/dist/scheduler/MentorAutonomousGuardian.js.map +1 -1
- package/dist/server/AgentServer.d.ts +11 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +102 -1
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/CapabilityIndex.d.ts.map +1 -1
- package/dist/server/CapabilityIndex.js +45 -0
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/routes.d.ts +19 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +482 -4
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +65 -65
- package/src/scaffold/templates.ts +19 -1
- package/upgrades/1.3.270.md +106 -0
- package/upgrades/1.3.271.md +154 -0
- package/upgrades/approval-ledger-phase2.eli16.md +56 -0
- package/upgrades/autoloop-gate-compliance.eli16.md +11 -0
- package/upgrades/feedback-phase3-monitor.eli16.md +51 -0
- package/upgrades/feedback-phase4-integrity.eli16.md +54 -0
- package/upgrades/respawn-build-context-reestablishment.eli16.md +5 -0
- package/upgrades/side-effects/approval-ledger-phase2.md +82 -0
- package/upgrades/side-effects/autoloop-gate-compliance.md +43 -0
- package/upgrades/side-effects/coordination-mandate-enforcement.md +86 -0
- package/upgrades/side-effects/dashboard-pool-sessions.md +103 -0
- package/upgrades/side-effects/feedback-phase3-monitor.md +37 -0
- package/upgrades/side-effects/feedback-phase4-integrity.md +35 -0
- package/upgrades/side-effects/respawn-build-context-reestablishment.md +81 -0
- package/upgrades/side-effects/review-exchange-protocol.md +60 -0
- package/upgrades/side-effects/secret-drop-store-first.md +117 -0
- package/upgrades/side-effects/transfer-idempotency-exactly-once.md +105 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: minor -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
Implemented Phase 2 of the approved Approval-as-Data design: the **approval ledger**.
|
|
9
|
+
Every operator approval is now recorded as durable, signed data — classified as
|
|
10
|
+
approved-as-is, approved-with-change (with the reason for each change), or rejected — and
|
|
11
|
+
the system computes a per-class agreement ratio and streak from those records. The ledger
|
|
12
|
+
tracks approvals wherever they occur: an official spec sign-off, a decision approved in
|
|
13
|
+
chat, or any other surface. New endpoints record a decision, list the records, and return
|
|
14
|
+
the agreement summary with a breakdown by surface. The ledger is signed, append-only, and
|
|
15
|
+
read-only with respect to all other behavior — it never gates, blocks, or changes anything.
|
|
16
|
+
The authoritative source of whether an approval was as-is or changed is always the
|
|
17
|
+
operator; the agent never self-classifies intent, and any record is operator-correctable.
|
|
18
|
+
|
|
19
|
+
Implemented the Coordination Mandate enforcement engine (the design the operator
|
|
20
|
+
signed off as A/A/B): a deny-by-default authority gate for autonomous agent-to-agent
|
|
21
|
+
actions. The operator writes one bounded, expiring, revocable "permission slip"
|
|
22
|
+
delegating specific authorities to a specific pair of agents; the slip — not the agent
|
|
23
|
+
— is what authorizes each action, preserving the rule that the one asking is never the
|
|
24
|
+
one authorizing. Issuance and revocation require the operator's dashboard PIN, so an
|
|
25
|
+
agent's API access alone is structurally unable to create or widen a mandate. A signed
|
|
26
|
+
store verifies authorship on every check (a forged or edited mandate fails), risky
|
|
27
|
+
authorities can be tied to objective real-state conditions the agent cannot fake, and
|
|
28
|
+
every decision — allowed and denied alike — lands in a tamper-evident, hash-chained
|
|
29
|
+
audit log. With no mandate issued, the gate denies everything, so this ships inert and
|
|
30
|
+
changes no behavior until the operator issues the first mandate.
|
|
31
|
+
|
|
32
|
+
Added the Phase-3 invariant-parity monitor for the feedback-factory migration: a
|
|
33
|
+
windowing layer over parity results that computes the objective
|
|
34
|
+
parity-zero-divergence condition (a sustained run of clean passes over a minimum
|
|
35
|
+
real-traffic window) which the future cutover step reads as its go signal. Includes
|
|
36
|
+
a durable, restart-surviving variant (append-only pass journal, torn-line tolerant).
|
|
37
|
+
Internal migration tooling — not yet wired to any live behavior.
|
|
38
|
+
|
|
39
|
+
Added the Phase-4 data-migration integrity tooling for the feedback-factory
|
|
40
|
+
migration: import-as-is preservation of every curated field, per-row checksums
|
|
41
|
+
(in vs out), fingerprint-uniqueness scanning, auto-increment sequence reset,
|
|
42
|
+
schema-equivalence assertion, and the structural never-re-derive guard (the
|
|
43
|
+
processor refuses to mutate any cluster created before the cutover timestamp or
|
|
44
|
+
carrying governance notes). Internal migration tooling — not yet wired to any
|
|
45
|
+
live behavior.
|
|
46
|
+
|
|
47
|
+
SessionManager now samples the live tmux pane cwd for enabled development-agent sessions and stores it in a crash-safe sidecar. Resume spawns prepend a restore note only for fresh, existing `.worktrees` paths; home-only sessions remain a no-op.
|
|
48
|
+
|
|
49
|
+
## What to Tell Your User
|
|
50
|
+
|
|
51
|
+
Your agent now remembers your approvals instead of forgetting them the moment they happen.
|
|
52
|
+
Each time you approve something — a full spec, or just a choice you make in chat — it can
|
|
53
|
+
record whether you took its recommendation as-is or changed it, and why. Over time this
|
|
54
|
+
builds a simple picture of where the agent already proposes what you would have picked, and
|
|
55
|
+
where it still needs to close the gap. You stay the source of truth: the agent only records
|
|
56
|
+
what you explicitly say, and you can correct any entry. This is an internal, read-only
|
|
57
|
+
record — it never changes what the agent does, it just helps it learn your preferences.
|
|
58
|
+
|
|
59
|
+
You can now hand your agent a bounded permission slip instead of approving every step
|
|
60
|
+
of a multi-agent project. You write the slip once from your dashboard with your PIN:
|
|
61
|
+
exactly which actions are allowed, within which limits, for which two agents, until
|
|
62
|
+
when. Your agent can act inside those lines without pinging you, and nothing outside
|
|
63
|
+
them — and you can tear the slip up at any moment. Everything done under a slip is
|
|
64
|
+
written to a tamper-evident log you can review. Until you issue a slip, nothing changes
|
|
65
|
+
at all: the system refuses every delegated action by default.
|
|
66
|
+
|
|
67
|
+
Nothing changes for you. This is internal plumbing for the feedback-system handover:
|
|
68
|
+
a safety meter that has to read "clean for a sustained window" before the one-way
|
|
69
|
+
switch can ever be considered. It ships dormant.
|
|
70
|
+
|
|
71
|
+
Nothing changes for you. This is internal plumbing for the feedback-system
|
|
72
|
+
handover: the checks that guarantee curated history is copied perfectly and can
|
|
73
|
+
never be silently rewritten afterward. It ships dormant.
|
|
74
|
+
|
|
75
|
+
Developer-agent respawns can now re-surface the worktree checkout they were building in before the restart. Normal home-only conversations are unchanged.
|
|
76
|
+
|
|
77
|
+
## Summary of New Capabilities
|
|
78
|
+
|
|
79
|
+
- Record an approval decision through the new approvals endpoint, tagged as approved-as-is,
|
|
80
|
+
approved-with-change, or rejected, with the reason for any change.
|
|
81
|
+
- Read a per-class agreement summary (total, approved-as-is count, ratio, streak, and a
|
|
82
|
+
breakdown by where the approval happened) plus a list of recorded decisions.
|
|
83
|
+
- Maturity: stable for the recording and summary surface; the later auto-approval pilot
|
|
84
|
+
remains a separate, operator-gated phase that is not part of this change.
|
|
85
|
+
|
|
86
|
+
- Issue or revoke a coordination mandate from the dashboard surface with your PIN —
|
|
87
|
+
agent credentials alone cannot do either.
|
|
88
|
+
- Agents check intended agent-to-agent actions against the mandate and get an
|
|
89
|
+
allow-or-deny answer with the reason; denials are the default with no mandate.
|
|
90
|
+
- Review every mandate decision in a chained, tamper-evident audit trail, including
|
|
91
|
+
whether each entry's chain verifies.
|
|
92
|
+
- Maturity: stable for the gate, store, and audit; conditioned authorities (objective
|
|
93
|
+
real-state gates for riskier actions) ship deny-safe and unused by the first mandate.
|
|
94
|
+
|
|
95
|
+
- Internal: order-independent parity windowing (per-report fingerprint,
|
|
96
|
+
terminal-status, recurrence/cycling counts) with a conservative
|
|
97
|
+
cleared-or-blocked gate verdict; survives restarts.
|
|
98
|
+
- Maturity: internal migration tooling, dormant until the dual-forward phase.
|
|
99
|
+
|
|
100
|
+
- Internal: integrity-safe import core + a guarded store wrapper that makes
|
|
101
|
+
pre-cutover and governance-noted clusters structurally immutable.
|
|
102
|
+
- Maturity: internal migration tooling, dormant until the import phase.
|
|
103
|
+
|
|
104
|
+
- SessionManager can record the live pane working directory for running sessions when the development-agent-gated feature is enabled.
|
|
105
|
+
- A resumed respawn receives a `[BUILD-CONTEXT RESTORE]` continuation note only when the prior cwd was a fresh, existing agent worktree.
|
|
106
|
+
- The sidecar state write is crash-safe through the state layer's temp-file plus rename path.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: minor -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
One additive line in the mentor autoloop prompt (`src/scheduler/MentorAutonomousGuardian.ts`), locked by three new unit-test assertions. Earned from PR #792's no-silent-fallbacks CI failure, where a spec's "best-effort, never throws" wording invited the swallowed catch the ratchet counts.
|
|
9
|
+
|
|
10
|
+
The dashboard sessions list now shows EVERY session across ALL machines in the
|
|
11
|
+
multi-machine pool, and every session row states which machine it runs on
|
|
12
|
+
(a machine-nickname badge). Sessions on the machine you're viewing stay fully
|
|
13
|
+
interactive (live terminal, close button); sessions on other machines appear
|
|
14
|
+
as informational rows with a tooltip pointing at the owning machine's
|
|
15
|
+
dashboard.
|
|
16
|
+
|
|
17
|
+
Under the hood: `GET /sessions` self-tags sessions with `machineId` /
|
|
18
|
+
`machineNickname` when the pool is wired, and a new `GET /sessions?scope=pool`
|
|
19
|
+
aggregates every reachable peer's session list (existing cross-machine Bearer
|
|
20
|
+
auth, 5s timeout per peer). A dead or slow peer degrades to a `pool.failed`
|
|
21
|
+
entry — the page never breaks. The plain `/sessions` route keeps its
|
|
22
|
+
back-compatible array shape.
|
|
23
|
+
|
|
24
|
+
Added the ReviewExchange protocol — the structured way two mandate-named agents complete
|
|
25
|
+
a mutual code-review sign-off without the operator relaying messages between them. One
|
|
26
|
+
exchange tracks one review package (content-addressed by checksum, fixed at creation)
|
|
27
|
+
through a strict linear lifecycle: proposed, delivered, verdict recorded, complete — or
|
|
28
|
+
changes-requested, which is terminal so a stale approval can never be replayed onto
|
|
29
|
+
reworked code. Both sign-offs — the reviewing peer's authenticated approval and the
|
|
30
|
+
owner's countersignature — are checked against the operator's coordination mandate
|
|
31
|
+
before acceptance, and every accepted signature stores the audit reference of the gate
|
|
32
|
+
decision that authorized it. With no mandate issued, every sign-off refuses: the
|
|
33
|
+
protocol inherits deny-by-default and ships inert.
|
|
34
|
+
|
|
35
|
+
A submitted Secret Drop is now persisted store-first to the durable
|
|
36
|
+
AES-256-GCM encrypted SecretStore the instant it is received, instead of
|
|
37
|
+
living only in the server's in-memory `received` map. The retrieve route
|
|
38
|
+
transparently falls back to the durable copy when the in-memory one is gone
|
|
39
|
+
(server restart, compaction, cross-machine handoff), and a successful consume
|
|
40
|
+
deletes both copies — one-time semantics are preserved. Opt out with
|
|
41
|
+
`secrets.persistDrops: false` in `.instar/config.json`.
|
|
42
|
+
|
|
43
|
+
This closes the recurring "the user dropped a secret and the agent lost it"
|
|
44
|
+
failure: with the fleet shipping many releases a day, every release restarted
|
|
45
|
+
the server and evaporated any un-consumed submission.
|
|
46
|
+
|
|
47
|
+
Also: the SecretStore master-key manager now forces file-key mode during test
|
|
48
|
+
runs (`VITEST` / `NODE_ENV=test`). The OS keychain entry is machine-global —
|
|
49
|
+
a test constructing a SecretStore against a fresh stateDir used to generate a
|
|
50
|
+
new master key and silently overwrite that shared entry, making every real
|
|
51
|
+
agent vault on the machine undecryptable for keychain-resolving readers. No
|
|
52
|
+
test can touch the real keychain anymore. A `secrets.forceFileKey` config
|
|
53
|
+
plumb is also available for operators who want to pin the key source.
|
|
54
|
+
|
|
55
|
+
The CLAUDE.md template's Secret Drop "Security" bullet is rewritten (the old
|
|
56
|
+
"in-memory only, never written to disk" claim is no longer true), and an
|
|
57
|
+
idempotent migration updates existing agents' CLAUDE.md in place.
|
|
58
|
+
|
|
59
|
+
Two fixes for the 2026-06-05 "move this to the laptop" noise incident, where
|
|
60
|
+
one user message produced contradictory "Moving to Laptop" / "I can't move
|
|
61
|
+
this right now (rate-limited)" replies and executed multiple times.
|
|
62
|
+
|
|
63
|
+
1. **Idempotent topic transfer.** The transfer planner now recognizes a move
|
|
64
|
+
request targeting the machine the topic is already on — or already pinned
|
|
65
|
+
to — BEFORE the rate limit. Duplicates of an already-satisfied move answer
|
|
66
|
+
"This conversation is already running on X — nothing to move" instead of a
|
|
67
|
+
rate-limit rejection. The rate limit keeps its real job: damping rapid
|
|
68
|
+
flip-flops between DIFFERENT machines.
|
|
69
|
+
|
|
70
|
+
2. **Exactly-once ingress turns on with the pool.** The exactly-once inbound
|
|
71
|
+
message gate (the dedupe ledger that stops retried/replayed messages from
|
|
72
|
+
re-executing commands) shipped default-OFF — even on machines whose
|
|
73
|
+
multi-machine session pool was live. The default is now stage-aware: a pool
|
|
74
|
+
at `live-transfer` or `rebalance` gets `exactlyOnceIngress` ON
|
|
75
|
+
automatically. An explicit `multiMachine.exactlyOnceIngress: false` still
|
|
76
|
+
wins.
|
|
77
|
+
|
|
78
|
+
## What to Tell Your User
|
|
79
|
+
|
|
80
|
+
Nothing user-visible. The autonomous mentor loop's instructions now include how to satisfy the repo's ratchet CI gates, so mentor-driven fixes stop tripping no-silent-fallbacks.
|
|
81
|
+
|
|
82
|
+
Open the dashboard on any of your machines and you'll see all your sessions in
|
|
83
|
+
one list — each with a badge saying which machine it's running on. No more
|
|
84
|
+
opening one dashboard per machine to find a session.
|
|
85
|
+
|
|
86
|
+
Your agent can now run a real code review with a partner agent under the permission
|
|
87
|
+
slip you issue — no more relaying review messages between them yourself. The agents
|
|
88
|
+
deliver the code package, record the reviewer's verdict, and counter-sign, and every
|
|
89
|
+
step is checked against your permission slip and written to the same tamper-evident
|
|
90
|
+
log. If you revoke the slip mid-review, the review stops on the spot. Until you issue
|
|
91
|
+
a slip, nothing changes — every review step refuses by default.
|
|
92
|
+
|
|
93
|
+
If you hand me a secret through a drop link, it now survives my server
|
|
94
|
+
restarting, updating, or the conversation moving between machines. You should
|
|
95
|
+
never have to re-send a secret because "I lost it" again. Secrets are stored
|
|
96
|
+
encrypted and are deleted as soon as they're consumed.
|
|
97
|
+
|
|
98
|
+
Asking me to move a conversation to a machine it's already on (or repeating
|
|
99
|
+
the request) now gets a calm "already running there" instead of a confusing
|
|
100
|
+
"rate-limited" error. And if my internals retry a message under load, the
|
|
101
|
+
command runs once — not four times.
|
|
102
|
+
|
|
103
|
+
## Summary of New Capabilities
|
|
104
|
+
|
|
105
|
+
- `buildAutoloopGoal` includes a gate-compliance paragraph: intentional fail-open catches must report via DegradationReporter or carry an inline `@silent-fallback-ok` justification — never a ratchet baseline bump.
|
|
106
|
+
- The mentor is instructed to spell out these gate notes in any task brief or spec it authors for another agent.
|
|
107
|
+
|
|
108
|
+
- Dashboard sessions list shows every session across the pool with a machine badge per row.
|
|
109
|
+
- `GET /sessions?scope=pool` → `{ sessions, pool: { peersOk, failed, ... } }` (agents can answer "what's running across my machines?").
|
|
110
|
+
- `GET /sessions` sessions carry `machineId`/`machineNickname` on pooled installs.
|
|
111
|
+
- CLAUDE.md template bullet + idempotent migration so existing agents learn the capability.
|
|
112
|
+
|
|
113
|
+
- Create a review exchange for an artifact under a mandate, content-addressed so the
|
|
114
|
+
signatures bind to exactly the code that was reviewed.
|
|
115
|
+
- Record delivery, the peer's authenticated verdict, and the owner's countersignature —
|
|
116
|
+
with both sign-offs evaluated through the mandate gate and refused on any deny.
|
|
117
|
+
- Inspect exchanges and their signatures, each carrying the audit reference of the
|
|
118
|
+
gate decision that authorized it.
|
|
119
|
+
- Maturity: stable engine and routes; ships inert (deny-by-default) until the operator
|
|
120
|
+
issues a mandate with the sign-code-review authority.
|
|
121
|
+
|
|
122
|
+
- Secret Drop submissions persist store-first to the encrypted SecretStore and survive server churn.
|
|
123
|
+
- Retrieval transparently falls back to the durable copy; consume deletes both copies.
|
|
124
|
+
- `secrets.persistDrops: false` opts out (default ON).
|
|
125
|
+
- Tests can never pollute the machine-global SecretStore keychain entry (structural guard).
|
|
126
|
+
- `secrets.forceFileKey` pins the master-key source to the per-agent file key.
|
|
127
|
+
|
|
128
|
+
- Duplicate "move to X" requests no-op as "already there" — never "rate-limited."
|
|
129
|
+
- The transfer planner accepts an optional `currentPinOf` hook (pin-aware idempotency).
|
|
130
|
+
- `exactlyOnceIngress` defaults ON whenever the session pool routes real traffic.
|
|
131
|
+
|
|
132
|
+
## Evidence
|
|
133
|
+
|
|
134
|
+
Three tiers green: `tests/unit/dashboard-sessionMachineBadge.test.ts` (8),
|
|
135
|
+
`tests/unit/PostUpdateMigrator-poolSessionsVisibility.test.ts` (3),
|
|
136
|
+
`tests/integration/sessions-pool-scope.test.ts` (5 — including a REAL second
|
|
137
|
+
HTTP server as the peer and a dead-peer degradation case), and
|
|
138
|
+
`tests/e2e/sessions-pool-scope-lifecycle.test.ts` (3 — real AgentServer,
|
|
139
|
+
feature alive single-machine). tsc + lint clean.
|
|
140
|
+
|
|
141
|
+
`tests/integration/secret-drop-store-first.test.ts` (5 route-level tests, both
|
|
142
|
+
sides of every boundary), `tests/unit/secret-store.test.ts` (keychain
|
|
143
|
+
pollution guard), `tests/unit/PostUpdateMigrator-secretDropHardenedRetrieve.test.ts`
|
|
144
|
+
(+3 migration tests), and the Tier-3 e2e
|
|
145
|
+
`tests/e2e/secret-drop-store-first-lifecycle.test.ts` — which boots two REAL
|
|
146
|
+
AgentServers on one stateDir and proves a secret submitted to process 1 is
|
|
147
|
+
retrievable from process 2 after a true restart. tsc + lint clean.
|
|
148
|
+
|
|
149
|
+
`tests/unit/TransferByNickname.test.ts` (+5, including the verbatim incident
|
|
150
|
+
case: already-on-target inside the rate window → noop) and
|
|
151
|
+
`tests/unit/seamlessnessConfig.test.ts` (+4, stage coupling both ways +
|
|
152
|
+
explicit-override both ways). tsc + lint clean. Production logs
|
|
153
|
+
(2026-06-05T04:20Z double pin, zero `exactly-once` lines on a live-transfer
|
|
154
|
+
pool) are the incident evidence.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Approval-as-Data — the approval ledger (Phase 2), explained simply
|
|
2
|
+
|
|
3
|
+
## What this is
|
|
4
|
+
|
|
5
|
+
Until now, when Justin approved something, that approval vanished the moment it
|
|
6
|
+
happened. "Approved" — and no memory of it. So the agent could never learn the
|
|
7
|
+
pattern of *when Justin agrees with its recommendation as-is* versus *when he changes
|
|
8
|
+
it*, and could never get better at recommending the thing he'd have picked anyway.
|
|
9
|
+
|
|
10
|
+
This change builds the **approval ledger**: every approval becomes a durable, signed
|
|
11
|
+
record. Each one is tagged as one of three things:
|
|
12
|
+
|
|
13
|
+
- **approved-as-is** — Justin took the recommendation exactly.
|
|
14
|
+
- **approved-with-change** — Justin approved, but changed something (and we record
|
|
15
|
+
*why* — the single most useful bit).
|
|
16
|
+
- **rejected** — Justin said no (also with the why).
|
|
17
|
+
|
|
18
|
+
From those records, the system computes a simple score per *kind* of decision: out of
|
|
19
|
+
all the decisions of this kind, what fraction did Justin take as-is? That fraction (the
|
|
20
|
+
"agreement ratio"), plus a "current streak" of consecutive as-is approvals, is the
|
|
21
|
+
signal that — much later, and only if Justin opts in — could let a class of low-risk
|
|
22
|
+
decisions auto-approve. That auto-approval part is NOT in this change; this is just the
|
|
23
|
+
memory + the scoreboard.
|
|
24
|
+
|
|
25
|
+
## The restaurant analogy
|
|
26
|
+
|
|
27
|
+
Think of the agent as a sous-chef proposing dishes to the head chef (Justin). Today,
|
|
28
|
+
each "yes" or "change the sauce" is said out loud and then forgotten. The ledger is a
|
|
29
|
+
notebook where the sous-chef writes down every proposal and what the head chef did with
|
|
30
|
+
it — took it as-is, tweaked it (and the tweak), or sent it back. Over weeks, the notebook
|
|
31
|
+
reveals: "For pasta dishes he almost always takes my call; for desserts he usually
|
|
32
|
+
adjusts the sweetness." That's how the sous-chef learns to propose what the chef would
|
|
33
|
+
pick — and which calls the chef trusts him to just make.
|
|
34
|
+
|
|
35
|
+
## The one rule that keeps it honest
|
|
36
|
+
|
|
37
|
+
The agent must **never decide for Justin** whether he agreed. Only Justin's *explicit*
|
|
38
|
+
words count: "go with your picks" = as-is; "change X because Y" = a change with that
|
|
39
|
+
reason. If Justin is silent or vague, nothing is recorded. And Justin can correct any
|
|
40
|
+
entry later (a correction is a new signed line, never a quiet edit). This is what stops
|
|
41
|
+
the agent from flattering itself by marking everything "approved-as-is."
|
|
42
|
+
|
|
43
|
+
## What Justin asked for, and what changed mid-build
|
|
44
|
+
|
|
45
|
+
Justin asked for this, then made one correction while it was being built: the original
|
|
46
|
+
written design only tracked *official spec sign-offs*, but most of his approvals (like
|
|
47
|
+
picking A/A/B in chat) happen in conversation. So the ledger was generalized to track
|
|
48
|
+
approvals **wherever they occur** — a spec, a chat, anywhere — each tagged with where it
|
|
49
|
+
happened. Fittingly, that very correction became the ledger's first recorded
|
|
50
|
+
"change" entry: the first real data point is the feedback that shaped the feature.
|
|
51
|
+
|
|
52
|
+
## What's safe about it
|
|
53
|
+
|
|
54
|
+
It only *reads and records* — it never blocks or changes any behavior. If the agent has
|
|
55
|
+
nowhere to store state, the feature simply isn't there (the API politely says
|
|
56
|
+
"unavailable") rather than breaking anything. Every record is signed so tampering shows.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Mentor autoloop prompt: gate-compliance line
|
|
2
|
+
|
|
3
|
+
Instar has an automated "mentor loop" — a prompt that tells a developer agent how to run one cycle of dogfooding a mentee agent: check its health, assign it a real task, observe, and fix what breaks as a proper PR.
|
|
4
|
+
|
|
5
|
+
That prompt already teaches the ship discipline (three test tiers, the dev gate, verify-before-claim). But it said nothing about the repo's *ratchet gates* — CI checks like no-silent-fallbacks that count known-bad patterns and fail if the count ever goes UP.
|
|
6
|
+
|
|
7
|
+
We learned why that matters the hard way: a spec told the builder a helper should be "best-effort, never throws." The builder did exactly that — wrapped it in a catch that swallowed the error — and CI went red, because a swallowed catch is exactly what the no-silent-fallbacks ratchet counts. The spec's own wording invited the failure.
|
|
8
|
+
|
|
9
|
+
This change adds one paragraph to the mentor-loop prompt: an intentional fail-open catch must either report the failure (through DegradationReporter) or carry an inline `@silent-fallback-ok` justification — and you never bump a ratchet baseline just to get CI green. It also tells the mentor to spell these notes out whenever it authors a task brief or spec for another agent, so the next builder doesn't get trapped by well-meaning "never throws" guidance.
|
|
10
|
+
|
|
11
|
+
One prompt paragraph, three new test assertions locking it in. No behavior change anywhere else.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# ELI16 — Phase-3 parity monitor + cutover gate
|
|
2
|
+
|
|
3
|
+
## What problem does this solve?
|
|
4
|
+
|
|
5
|
+
Before we flip the feedback system from Dawn's Portal to Instar (the "cutover" — a one-way
|
|
6
|
+
door), we run both processors side by side over real traffic for a while and check they
|
|
7
|
+
agree. That side-by-side check ("the parity comparison") already exists. What was missing is
|
|
8
|
+
the part that watches it *over time* and decides when it's genuinely safe to flip.
|
|
9
|
+
|
|
10
|
+
You can't trust a single green check. Traffic is bursty; one quiet minute proves nothing. We
|
|
11
|
+
need to see a real, sustained window where the two systems agreed on every report — and only
|
|
12
|
+
*then* allow the cutover. And crucially, the decision to flip must not come from an agent
|
|
13
|
+
"feeling confident" — it must come from an objective gate that an agent cannot fake.
|
|
14
|
+
|
|
15
|
+
## What this change adds
|
|
16
|
+
|
|
17
|
+
A small, pure `ParityMonitor`:
|
|
18
|
+
|
|
19
|
+
- You feed it each comparison pass (how many clusters were compared, how many divergences).
|
|
20
|
+
- It tracks the current **zero-divergence streak**. The moment any pass diverges, the streak
|
|
21
|
+
resets to zero — so a single disagreement, even after a long clean run, sends us back to
|
|
22
|
+
the start. No "mostly agreed" hand-waving.
|
|
23
|
+
- It exposes one method, `gate(now)`, that returns **cleared** or **blocked** with a reason.
|
|
24
|
+
It clears only when the trailing run of passes is (a) all clean, (b) at least N passes
|
|
25
|
+
long, (c) spanning at least a real time window (default one hour), and (d) covering enough
|
|
26
|
+
clusters to be a meaningful sample. All four must hold.
|
|
27
|
+
|
|
28
|
+
That `cleared` boolean is the objective `parity-zero-divergence` condition. It's exactly what
|
|
29
|
+
the Coordination Mandate's "execute-cutover" authority reads: the agents can only flip the
|
|
30
|
+
one-way door when this gate — not their judgment — says the window is satisfied.
|
|
31
|
+
|
|
32
|
+
## Why it's safe
|
|
33
|
+
|
|
34
|
+
Pure logic, no database, no network, no boot wiring. It only ever *reads* comparison results
|
|
35
|
+
and *computes* a yes/no; it changes nothing and triggers nothing on its own. It's the
|
|
36
|
+
building block the cutover executor will consult. 9 unit tests cover every gate boundary:
|
|
37
|
+
too-few passes, too-short window, too-few clusters, the satisfied window, and the streak
|
|
38
|
+
reset on any divergence (including re-clearing only after a fresh full clean window).
|
|
39
|
+
|
|
40
|
+
## Plain-language risk
|
|
41
|
+
|
|
42
|
+
Near-zero, and the failure mode is conservative: if the policy is too strict, the gate just
|
|
43
|
+
stays *blocked* longer (cutover waits) — never the dangerous direction of clearing early.
|
|
44
|
+
|
|
45
|
+
## Durability note
|
|
46
|
+
|
|
47
|
+
The "they agreed" window can take hours to build up. If we kept it only in memory, restarting
|
|
48
|
+
the server in the middle would silently wipe the streak and we'd have to start over (or worse,
|
|
49
|
+
mis-measure the window across the restart). So each check result is appended to a small log file
|
|
50
|
+
and reloaded when the monitor starts — the window survives restarts. A half-written final line
|
|
51
|
+
from a crash is skipped cleanly, so one bad line never corrupts the rest of the history.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# ELI16 — Phase-4 feedback-migration integrity tooling
|
|
2
|
+
|
|
3
|
+
## What problem does this solve?
|
|
4
|
+
|
|
5
|
+
We're moving the "feedback factory" (the thing that catches user bug reports, groups
|
|
6
|
+
duplicates into clusters, and tracks each cluster's lifecycle) from Dawn's Portal over to
|
|
7
|
+
Instar. The cluster records aren't just data — they hold human and AI *judgment*: which
|
|
8
|
+
bug is which, what was already triaged, what was shipped. That curated judgment is
|
|
9
|
+
irreplaceable. If the move corrupts it, or if the new processor later overwrites it, we
|
|
10
|
+
lose work nobody can recreate.
|
|
11
|
+
|
|
12
|
+
Two specific dangers:
|
|
13
|
+
|
|
14
|
+
1. **A silent bad copy.** "The row counts match" is far too weak a check — a single
|
|
15
|
+
cluster could come across with its status flipped or its governance note dropped and a
|
|
16
|
+
count check would never notice. We need to prove *every curated field of every row*
|
|
17
|
+
survived the move byte-for-byte.
|
|
18
|
+
|
|
19
|
+
2. **A wrong-date backfill overwriting curated history.** After cutover, the processor is
|
|
20
|
+
only supposed to touch *new* reports. But if someone ever re-runs it over old data, it
|
|
21
|
+
would happily "re-cluster" the curated history and discard every triage decision.
|
|
22
|
+
|
|
23
|
+
## What this change adds
|
|
24
|
+
|
|
25
|
+
Two small, pure, well-tested building blocks (no database, no network — just logic, so
|
|
26
|
+
they're fully unit-testable):
|
|
27
|
+
|
|
28
|
+
- **`importIntegrity.ts`** — the import gate. It computes a per-row checksum over every
|
|
29
|
+
curated field and compares source-vs-imported (catching silent corruption), scans the
|
|
30
|
+
source for two clusters sharing a fingerprint *before* importing (which would otherwise
|
|
31
|
+
abort the transaction or silently merge them), asserts the two schemas accept the same
|
|
32
|
+
status values and field types, checks that no feedback row points at a missing cluster
|
|
33
|
+
(referential integrity), and computes the auto-increment sequence reset so the next new
|
|
34
|
+
insert can't collide. `runIntegrityGate()` rolls all of that into one pass/fail.
|
|
35
|
+
|
|
36
|
+
- **`immutableGuard.ts`** — the structural "never re-derive" guard. Instead of *trusting*
|
|
37
|
+
the processor to only run over new traffic, we wrap the store: a cluster that predates
|
|
38
|
+
cutover, or that carries any governance note, is **immutable**, and any attempt to merge
|
|
39
|
+
into it, reopen it, or upsert over it is physically refused and recorded. A wrong-date
|
|
40
|
+
backfill therefore *cannot* overwrite curated state — the write simply does not happen.
|
|
41
|
+
|
|
42
|
+
## Why it's safe
|
|
43
|
+
|
|
44
|
+
Both modules are pure functions plus one store decorator. The guard only ever *refuses*
|
|
45
|
+
writes (it never invents or changes data), and reads pass straight through. Nothing is
|
|
46
|
+
wired into the running server yet — these are the building blocks the Phase-4 cutover will
|
|
47
|
+
use. 36 new unit tests cover both sides of every boundary, including the processor running
|
|
48
|
+
over a guarded store and leaving a curated cluster's count, status, and note untouched.
|
|
49
|
+
|
|
50
|
+
## Plain-language risk
|
|
51
|
+
|
|
52
|
+
Near-zero. Worst case if the guard is mis-tuned: a *legitimate* post-cutover merge is
|
|
53
|
+
refused and shows up in the violations list (loud, not silent) — far better than the
|
|
54
|
+
alternative of silently overwriting curated judgment.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Respawn build-context restore
|
|
2
|
+
|
|
3
|
+
Developer agents can now remember the build checkout they were using before a respawn. When the feature is enabled and a resumed session had been working inside an agent worktree, the resumed conversation starts with a `[BUILD-CONTEXT RESTORE]` note pointing back to that worktree.
|
|
4
|
+
|
|
5
|
+
This is meant for fleet PR build sessions that die or restart mid-task. It does not move the tmux session's home directory, and it does nothing for normal home-only conversations. Stale or removed worktrees are skipped.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Side-effects review — Approval-as-Data ledger (Phase 2)
|
|
2
|
+
|
|
3
|
+
Spec: `docs/specs/AUTONOMOUS-OPERATION-JUDGMENT-AND-APPROVAL-AS-DATA-SPEC.md` (Part B).
|
|
4
|
+
Change: new `src/core/ApprovalLedger.ts` + `POST/GET /approvals`, `GET /approvals/summary`
|
|
5
|
+
wired through `AgentServer` → `RouteContext`; Agent-Awareness blurb in the CLAUDE.md template.
|
|
6
|
+
|
|
7
|
+
## 1. Blast radius
|
|
8
|
+
Additive only. A new module, three new route handlers, one new always-constructed field
|
|
9
|
+
on `AgentServer`, one new `RouteContext` field, one template blurb. No existing route,
|
|
10
|
+
store, sentinel, or gate is modified. The ledger never gates, blocks, throttles, or
|
|
11
|
+
mutates any other state — read paths are pure reads; the one write path appends to its
|
|
12
|
+
own JSONL file.
|
|
13
|
+
|
|
14
|
+
## 2. State / data
|
|
15
|
+
New on-disk file `.instar/state/approval-ledger.jsonl` (append-only, signed). No schema
|
|
16
|
+
migration — the file is created on first write and absent until then. No existing file is
|
|
17
|
+
touched. Torn-trailing-line tolerant on read. Rows are HMAC-signed over `authToken`; an
|
|
18
|
+
empty/missing file yields an empty summary (no crash).
|
|
19
|
+
|
|
20
|
+
## 3. Interactions
|
|
21
|
+
- `RouteContext` gains a REQUIRED `approvalLedger` field. The only production assembler is
|
|
22
|
+
`AgentServer` (updated). Route tests build `ctx: any` partials, so they are unaffected
|
|
23
|
+
(tsc confirms the whole tree compiles).
|
|
24
|
+
- Construction rides the existing `stateDir` availability (like `tokenLedger`); own
|
|
25
|
+
try/catch so an init failure can never cascade into the other ledgers.
|
|
26
|
+
- Shares no lock, queue, or budget with any other component.
|
|
27
|
+
|
|
28
|
+
## 4. Failure modes
|
|
29
|
+
- No `authToken` → falls back to a fixed dev key for signing (integrity-only; documented).
|
|
30
|
+
Signing is never load-bearing for correctness — the operator-authoritative-source rule is.
|
|
31
|
+
- `stateDir` absent → `approvalLedger` is null → routes 503 (handled + tested).
|
|
32
|
+
- Inconsistent row (as-is WITH a divergence, or a change WITHOUT one) → `recordApproval`
|
|
33
|
+
throws → the route returns 400, not 500 (tested). Bad data cannot pollute ratios.
|
|
34
|
+
- Disk-full / write error on append → throws to the caller (route 400/500); no partial
|
|
35
|
+
corrupt state (single `appendFileSync`).
|
|
36
|
+
|
|
37
|
+
## 5. Security / authority
|
|
38
|
+
- The load-bearing invariant is **operator-authoritative `mode` + `divergences`**: the
|
|
39
|
+
agent must not self-classify intent. Enforced by documentation + the design (the route
|
|
40
|
+
records what the caller passes; the caller must pass an explicit operator statement) and
|
|
41
|
+
backstopped by operator-correctable rows. HMAC signing gives integrity, NOT correctness —
|
|
42
|
+
it stops tampering, not ratio inflation; the authority rule stops inflation.
|
|
43
|
+
- All routes are Bearer-gated (standard middleware). Read routes never gate behavior.
|
|
44
|
+
|
|
45
|
+
## 6. Performance
|
|
46
|
+
- O(rows) summary computation over a small append-only file read on each summary call.
|
|
47
|
+
At realistic volumes (tens to low-hundreds of approvals) this is negligible. No polling,
|
|
48
|
+
no background work, no LLM calls. Phase-3 (auto-approval, digest) is out of scope here.
|
|
49
|
+
|
|
50
|
+
## 7. Migration parity
|
|
51
|
+
- No `.claude/settings.json` hook, `.instar/config.json` default, or hook-script change →
|
|
52
|
+
no `PostUpdateMigrator` entry required. The feature is server-side code that activates on
|
|
53
|
+
the next server start after update; existing agents get it by updating, with no on-disk
|
|
54
|
+
migration. Agent-Awareness IS satisfied: the CLAUDE.md template gained an Approval-as-Data
|
|
55
|
+
blurb (`generateClaudeMd`).
|
|
56
|
+
- Always-on when `stateDir` exists (read-only, low-cost) — no enable flag to migrate.
|
|
57
|
+
|
|
58
|
+
## Tests
|
|
59
|
+
- Unit (`tests/unit/ApprovalLedger.test.ts`, 18): record/read/verify, tamper-reject, every
|
|
60
|
+
consistency-guard throw + its passing counterpart, ratio + streak (reset on change/reject),
|
|
61
|
+
auto-eligibility threshold edges, surface generality, corrections, torn-line tolerance.
|
|
62
|
+
- Integration (`tests/integration/approvals-routes.test.ts`, 6): full HTTP round-trip over a
|
|
63
|
+
real ledger; summary + surface breakdown; the 400 + 503 paths.
|
|
64
|
+
- E2E (`tests/e2e/approval-ledger-lifecycle.test.ts`, 5): real AgentServer boot, alive
|
|
65
|
+
(200 not 503), record→summary→list lifecycle, Bearer-gate, and a WIRING-INTEGRITY proof
|
|
66
|
+
that the production HMAC signer is real (persisted row verifies; a tamper fails).
|
|
67
|
+
|
|
68
|
+
## Post-review amendments (same PR, pre-merge)
|
|
69
|
+
|
|
70
|
+
- **State-path fix:** the ledger file follows the `.instar/state/` convention —
|
|
71
|
+
`config.stateDir` IS `.instar`, durable state lives under `state/`
|
|
72
|
+
(`.instar/state/approval-ledger.jsonl`, matching the spec's stated path). The e2e
|
|
73
|
+
wiring-integrity test proves the corrected path end-to-end.
|
|
74
|
+
- **Ratchet exemptions:** the three deny-safe/default-empty catches carry
|
|
75
|
+
`@silent-fallback-ok` markers INSIDE the catch blocks (missing-file → empty
|
|
76
|
+
history; malformed signature → verifies false; init failure → reported via
|
|
77
|
+
console.warn + ledger null → routes 503).
|
|
78
|
+
- **Docs coverage:** the three `/approvals` routes are documented in
|
|
79
|
+
`site/src/content/docs/reference/api.md` (route-floor gate).
|
|
80
|
+
- **Discoverability:** the `/approvals` prefix is classified in
|
|
81
|
+
`CapabilityIndex.ts` (CAPABILITY_INDEX → surfaced in `/capabilities` with its
|
|
82
|
+
three endpoints), satisfying the capabilities-discoverability gate.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Side-Effects Review — Mentor autoloop gate-compliance line
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `autoloop-gate-compliance`
|
|
4
|
+
**Date:** `2026-06-05`
|
|
5
|
+
**Author:** `echo`
|
|
6
|
+
**Second-pass reviewer:** `echo second-pass checklist`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
Adds one static paragraph to `buildAutoloopGoal()` in `src/scheduler/MentorAutonomousGuardian.ts` — the deterministic prompt assembled for the autonomous mentor dogfooding loop. The paragraph teaches ratchet-gate compliance: intentional fail-open catches must report via DegradationReporter or carry an inline `@silent-fallback-ok` justification (never a baseline bump), and task briefs/specs authored for other agents must spell these notes out explicitly. Earned from PR #792's no-silent-fallbacks CI failure, where the spec's "best-effort, never throws" guidance invited the exact swallowed catch the ratchet counts.
|
|
11
|
+
|
|
12
|
+
## Decision-point inventory
|
|
13
|
+
|
|
14
|
+
- `buildAutoloopGoal` — modified — one additional template line appended to the returned prompt string. Pure string assembly; no new branches, no I/O, no config.
|
|
15
|
+
- `tests/unit/MentorAutonomousGuardian.test.ts` — modified — three new content assertions on the assembled prompt.
|
|
16
|
+
|
|
17
|
+
## 1. Over-block
|
|
18
|
+
|
|
19
|
+
None possible. The function returns a string; nothing is gated, blocked, or filtered. The added text instructs the *consuming agent*; it cannot prevent any operation by itself.
|
|
20
|
+
|
|
21
|
+
## 2. Over-permit
|
|
22
|
+
|
|
23
|
+
None. No permission surface is touched.
|
|
24
|
+
|
|
25
|
+
## 3. Token/cost impact
|
|
26
|
+
|
|
27
|
+
The prompt grows by ~430 characters, sent once per autonomous-fix guardian cycle (budget- and min-interval-gated, single-instance). Negligible.
|
|
28
|
+
|
|
29
|
+
## 4. Behavior change for existing consumers
|
|
30
|
+
|
|
31
|
+
The only consumer is `MentorAutonomousGuardian` → spawned loop session goal text. Existing assertions on the prompt (cycle steps, discipline line, topics) are unchanged and still pass — the new line is purely additive. The `degrades gracefully when topics are unset` test still passes (the added text contains no topic interpolation).
|
|
32
|
+
|
|
33
|
+
## 5. Failure modes
|
|
34
|
+
|
|
35
|
+
A string literal cannot throw at runtime. The TypeScript build verifies the template syntax. If the guidance itself were wrong, the blast radius is advisory-only (an agent following it would still produce gate-passing code — DegradationReporter and `@silent-fallback-ok` are both legitimate, documented paths in `tests/unit/no-silent-fallbacks.test.ts`).
|
|
36
|
+
|
|
37
|
+
## 6. Migration parity
|
|
38
|
+
|
|
39
|
+
None required: the prompt is assembled at runtime from shipped code; every agent gets it on its next update through the normal release path. No installed files, hooks, config defaults, or templates change.
|
|
40
|
+
|
|
41
|
+
## 7. Rollback
|
|
42
|
+
|
|
43
|
+
Revert the commit. No persisted state references the new text.
|