instar 1.3.877 → 1.3.879

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.
Files changed (65) hide show
  1. package/dist/commands/init.d.ts.map +1 -1
  2. package/dist/commands/init.js +8 -0
  3. package/dist/commands/init.js.map +1 -1
  4. package/dist/core/ApprenticeshipMatrixAcceptance.d.ts +124 -0
  5. package/dist/core/ApprenticeshipMatrixAcceptance.d.ts.map +1 -0
  6. package/dist/core/ApprenticeshipMatrixAcceptance.js +240 -0
  7. package/dist/core/ApprenticeshipMatrixAcceptance.js.map +1 -0
  8. package/dist/core/ApprenticeshipProgram.d.ts +25 -3
  9. package/dist/core/ApprenticeshipProgram.d.ts.map +1 -1
  10. package/dist/core/ApprenticeshipProgram.js +72 -25
  11. package/dist/core/ApprenticeshipProgram.js.map +1 -1
  12. package/dist/core/ApprenticeshipStallGate.d.ts +297 -0
  13. package/dist/core/ApprenticeshipStallGate.d.ts.map +1 -0
  14. package/dist/core/ApprenticeshipStallGate.js +935 -0
  15. package/dist/core/ApprenticeshipStallGate.js.map +1 -0
  16. package/dist/core/MessagingToneGate.d.ts +33 -1
  17. package/dist/core/MessagingToneGate.d.ts.map +1 -1
  18. package/dist/core/MessagingToneGate.js +47 -9
  19. package/dist/core/MessagingToneGate.js.map +1 -1
  20. package/dist/core/PostUpdateMigrator.d.ts +8 -0
  21. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  22. package/dist/core/PostUpdateMigrator.js +75 -0
  23. package/dist/core/PostUpdateMigrator.js.map +1 -1
  24. package/dist/core/apprenticeshipStallGate.worker.d.ts +13 -0
  25. package/dist/core/apprenticeshipStallGate.worker.d.ts.map +1 -0
  26. package/dist/core/apprenticeshipStallGate.worker.js +23 -0
  27. package/dist/core/apprenticeshipStallGate.worker.js.map +1 -0
  28. package/dist/core/types.d.ts +13 -0
  29. package/dist/core/types.d.ts.map +1 -1
  30. package/dist/core/types.js.map +1 -1
  31. package/dist/monitoring/SelfUnblockChecklist.d.ts +1 -1
  32. package/dist/monitoring/SelfUnblockChecklist.d.ts.map +1 -1
  33. package/dist/monitoring/SelfUnblockChecklist.js +2 -0
  34. package/dist/monitoring/SelfUnblockChecklist.js.map +1 -1
  35. package/dist/monitoring/SelfUnblockProbeProviders.d.ts +19 -1
  36. package/dist/monitoring/SelfUnblockProbeProviders.d.ts.map +1 -1
  37. package/dist/monitoring/SelfUnblockProbeProviders.js +187 -2
  38. package/dist/monitoring/SelfUnblockProbeProviders.js.map +1 -1
  39. package/dist/monitoring/guardManifest.d.ts.map +1 -1
  40. package/dist/monitoring/guardManifest.js +22 -0
  41. package/dist/monitoring/guardManifest.js.map +1 -1
  42. package/dist/scaffold/templates.d.ts.map +1 -1
  43. package/dist/scaffold/templates.js +4 -2
  44. package/dist/scaffold/templates.js.map +1 -1
  45. package/dist/server/AgentServer.d.ts +1 -0
  46. package/dist/server/AgentServer.d.ts.map +1 -1
  47. package/dist/server/AgentServer.js +22 -0
  48. package/dist/server/AgentServer.js.map +1 -1
  49. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  50. package/dist/server/CapabilityIndex.js +2 -0
  51. package/dist/server/CapabilityIndex.js.map +1 -1
  52. package/dist/server/routes.d.ts +3 -0
  53. package/dist/server/routes.d.ts.map +1 -1
  54. package/dist/server/routes.js +281 -5
  55. package/dist/server/routes.js.map +1 -1
  56. package/package.json +1 -1
  57. package/scripts/stall-matrix-live-check.mjs +309 -0
  58. package/src/data/builtin-manifest.json +64 -64
  59. package/src/scaffold/templates/jobs/instar/stall-matrix-live-check.md +32 -0
  60. package/src/scaffold/templates.ts +4 -2
  61. package/upgrades/1.3.878.md +67 -0
  62. package/upgrades/1.3.879.md +62 -0
  63. package/upgrades/side-effects/correction-derived-hardening.md +188 -0
  64. package/upgrades/side-effects/stall-coverage-matrix-pr-b.md +154 -0
  65. package/upgrades/1.3.877.md +0 -53
@@ -0,0 +1,67 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ Added one section to `docs/apprenticeship/PROGRAM-CONCEPTS.md`: "The
9
+ Hidden-Test Battery (regression tripwires)" — the durable, generic record of
10
+ the mechanism the operator approved on 2026-07-18. The battery is a set of
11
+ undisclosed scenarios that each detect the LOSS of an already-valued behavior:
12
+ passing means nothing broke, never that growth was achieved (growth stays with
13
+ the overseer's judgment). Scenarios stay undisclosed during a drive and are
14
+ scored retrospectively (pass / fail / not-triggered, with evidence pointers)
15
+ as ONE necessary-not-sufficient input to ladder promotions — a failure can
16
+ block a rung, no quantity of passes can earn one. The mechanism itself is
17
+ disclosed to the mentee once (results appear in drive reports the mentee can
18
+ read); only the scenario list stays hidden. The battery is disposable (a
19
+ performed-for scenario is retired; the operator reviews the list at every rung
20
+ change) and guardrailed: never a leaderboard, never a mid-drive threat, never
21
+ a gate on day-to-day work, never scenarios that can harm real users, data, or
22
+ services. Scenarios are preferentially captured from naturally-arising
23
+ situations, manufactured only as a last resort and never on production
24
+ surfaces.
25
+
26
+ This is documentation only. No code, config, hook, job, template, or test
27
+ changes; no runtime surface; no behavior change for any deployed agent.
28
+
29
+ The second half of the stall-coverage standard: the apprenticeship transition gate now verifies each framework's stall-coverage matrix from LIVE state. At `pending→active` a provisional matrix (complete enumeration, hermetic checks) is required; at `active→complete` the full validation runs — resolvable detector/recovery symbols, closePath refs resolved against the live commitments ledger (a delivered or missing ref is a dead anchor), guard postures cross-checked against the guards inventory via each row's guardKey, and the whole verdict executed in a bounded worker (60s, timeout fails closed with a retryable reason distinct from invalidity). Every declared gap, N/A reason, and covered row is enumerated for a recorded operator acceptance: a single-use, content-hash-bound challenge accepted via the dashboard PIN or a verified-operator reply — the transition caller's own token can never self-accept. Install provenance (source-carrying vs fleet) is derived at init with a one-time migration backfill, so a fleet install gets the honest `matrix-unverifiable-no-source` verdict instead of a bogus refusal. A weekly `stall-matrix-live-check` job (ships off, silent no-op without source) re-validates the standing matrices and mints tracked refs for auto-seeded debt.
30
+
31
+ The gate ships OBSERVE-FIRST: `apprenticeship.stallCoverageGate` defaults to `{enabled: true, dryRun: true}` — refusals are suppressed and logged as would-refuse verdicts until the operator flips enforcement on named evidence. The gate registers as a load-bearing-soaking row in the guards inventory (30-day soak) so an unflipped gate becomes visible debt, never silent rot.
32
+
33
+ ## What to Tell Your User
34
+
35
+ Nothing changes in how your agent behaves. The apprenticeship program's
36
+ documentation now records how regression tripwires work: a small, undisclosed
37
+ set of checks that only ever fire when a learning agent LOSES a good habit it
38
+ already had — never a score to chase, never a leaderboard, never a gate on
39
+ daily work — with results reviewed openly after each drive as one input to
40
+ promotion decisions a human still makes.
41
+
42
+ No day-to-day behavior changes. When a new AI framework is onboarded onto your agent's platform, the onboarding sign-off now structurally requires an honest, verified answer for every known way a session can get stuck — and any gap needs your recorded approval, not a quiet checkbox.
43
+
44
+ ## Summary of New Capabilities
45
+
46
+ - None (documentation only). New content: the "Hidden-Test Battery" section in
47
+ `docs/apprenticeship/PROGRAM-CONCEPTS.md`, recording the adopted
48
+ regression-tripwire discipline for the apprenticeship program.
49
+
50
+ - Runtime stall-coverage gate on apprenticeship transitions (dry-run first, operator-owned enforcement flip).
51
+ - PIN/verified-operator acceptance machinery with single-use, content-bound challenges.
52
+ - Weekly matrix live-check job with tracked-ref minting for auto-seeded debt.
53
+
54
+ ## Evidence
55
+
56
+ - `docs/apprenticeship/PROGRAM-CONCEPTS.md` — the new section (mechanism only;
57
+ deliberately no scenario, agent, or organization content).
58
+ - `docs/specs/hidden-test-battery-adoption.eli16.md` — plain-English explainer.
59
+ - `upgrades/side-effects/hidden-test-battery-adoption.md` — side-effects
60
+ review; every question resolves to "documentation-only, no runtime surface";
61
+ multi-machine posture unified-via-git; rollback = revert the doc.
62
+ - Sanity: the whole-tree stall-coverage CI ratchet
63
+ (`tests/unit/stall-coverage-ratchet.test.ts`) runs green on this tree.
64
+
65
+ - 290 tests across 11 suites green (gate unit boundaries both sides, acceptance authority incl. replay/self-acceptance/hash-mismatch refusals, real HTTP 409 + dry-run suppression integration, e2e lifecycle with contentHash + HEAD SHA + dirty-flag audit).
66
+ - Full unit tier run: 37,533 passed (one silent-fallback ratchet trip resolved by annotating deliberate fallbacks; baseline unchanged).
67
+ - tsc clean; guard-manifest lint clean; live-check script smoke-tested (no-source silent no-op; dead-server = named ledger-unreachable, zero partial mints).
@@ -0,0 +1,62 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ - The outbound tone gate gains rule `B21_USER_TASK_SUBSTITUTION` — the gate's
9
+ FIRST ADVISORY-disposition rule (operator directive: sentinels nudge, the
10
+ agent decides, overrides are recorded). A message handing the USER a
11
+ multi-step procedure (portal click-paths, UI steps, command sequences) for
12
+ work the agent could do itself given at most a credential or an approval is
13
+ returned to the agent as a named nudge (422 tone-gate-advisory, notSent) —
14
+ never hard-blocked; the agent may revise, or resend unchanged with
15
+ `metadata.toneAdvisoryAck` (the override is recorded for the decision-quality
16
+ meter). A new `RULE_DISPOSITIONS` registry makes the advisory/blocking split
17
+ structural; the ack can never override a blocking rule. Explicit carve-outs keep
18
+ legitimate messages flowing: user-requested walkthroughs, structurally
19
+ human-reserved actions (dashboard-PIN, physical, payment/legal, CAPTCHA,
20
+ decisions), single one-tap links/codes, genuinely non-delegable personal
21
+ credentials, and a capability-uncertainty default-PASS.
22
+ - The Self-Unblock checklist gains a tenth probe source, `owned-identities`:
23
+ a per-agent registry (`.instar/owned-identities.json`) of identities the
24
+ agent itself provisioned (test users, workspace owners, service accounts).
25
+ Entries advertise their scopes ONLY while their credential pointer resolves
26
+ (agent-home-jailed file stat / vault key-name presence — fail-closed), with
27
+ hard bounds (256 KB, 500 entries, 128-char strings) and no secret value ever
28
+ read or surfaced.
29
+ - CLAUDE.md template + migration: agents learn Rung 0 includes identities they
30
+ created, the registration trigger, the canonical scope-tag form, and the
31
+ prune-stale-entries rule (append-only content-sniffed migration).
32
+
33
+ ## What to Tell Your User
34
+
35
+ Two of your July 18 corrections are now built into the shared machinery. When
36
+ I draft a message handing you step-by-step click work I could do myself, the
37
+ gate now hands it BACK to me with the pitfall named — I make the final call,
38
+ and if I consciously overrule the nudge, that decision is recorded and
39
+ reviewable. This is the nudge-not-block sentinel architecture you asked for,
40
+ applied to its first rule. And before I ever claim something
41
+ "needs you," my blocked-task checker now also consults a registry of accounts
42
+ and identities I myself created — so I can't again ask you about
43
+ infrastructure I built.
44
+
45
+ ## Summary of New Capabilities
46
+
47
+ - Outbound gate rule B21: no more click-lists handed to users for agent-doable
48
+ work.
49
+ - Self-unblock now structurally consults agent-provisioned identities before
50
+ any "operator-only" escalation; register identities you create in
51
+ `.instar/owned-identities.json`.
52
+
53
+ ## Evidence
54
+
55
+ - Spec: docs/specs/correction-derived-hardening.md (converged iter 2,
56
+ codex-cli:gpt-5.5 external both rounds; report in docs/specs/reports/).
57
+ - Tests: tests/unit/messaging-tone-gate-b21.test.ts (7),
58
+ tests/unit/SelfUnblockProbeProviders.test.ts (+10 incl. founding-scenario
59
+ reproduction, jail, clamp, stale-exhausts, wiring ratchet),
60
+ tests/unit/SelfUnblockChecklist.test.ts (order updated),
61
+ tests/unit/PostUpdateMigrator-ownedIdentities.test.ts (4). All green with
62
+ the existing ratchets (rule-id contract, judge-by-meaning keyset).
@@ -0,0 +1,188 @@
1
+ # Side-Effects Review — correction-derived-hardening
2
+
3
+ Spec: `docs/specs/correction-derived-hardening.md` (B21_USER_TASK_SUBSTITUTION
4
+ tone-gate rule + owned-identities self-unblock probe). CMT-904.
5
+
6
+ ## Phase 1 principle check (recorded)
7
+
8
+ Both changes touch decision-point-adjacent surfaces, and both comply with
9
+ signal-vs-authority by construction:
10
+
11
+ - **Change A** adds a meaning-judged rule to the EXISTING single outbound
12
+ authority (the tone-gate LLM). No deterministic detector gains blocking
13
+ power; no new authority is created.
14
+ - **Change B** adds an evidence-producing probe to a RECORDER
15
+ (SelfUnblockChecklist). The settle judgment stays with BlockerLedger's
16
+ injected Tier-1 authority; the probe cannot block anything.
17
+
18
+ ## 1. Over-block
19
+
20
+ - **A:** the risk is citing B21 on legitimate walkthroughs. Mitigated by four
21
+ explicit carve-outs (user-asked, structurally-human-reserved incl.
22
+ dashboard-PIN actions, single one-tap link/code, discussion), a
23
+ false-negative severity bias, and the "the page the agent built IS the one
24
+ tap's destination" clarification so a Secret-Drop link + its form fields is
25
+ never counted as multi-step. Worst case remains a held message with a
26
+ concrete suggestion, visible in review history — recoverable in one resend.
27
+ - **B:** the second-pass reviewer found the real risk here: a STALE entry
28
+ advertising a phantom credential would make every run non-exhausted, and
29
+ BlockerLedger's settle gate would then refuse a true-blocker settle FOREVER —
30
+ static declaration holding blocking authority over the escalation path.
31
+ Closed with the credentialRef LIVENESS GATE (file-stat / vault-key-presence
32
+ before any tag is advertised; unverifiable entries contribute nothing) plus
33
+ an explicit test that a fully-stale registry still EXHAUSTS. Residual: a
34
+ live-but-revoked credential (file exists, credential dead) still biases
35
+ toward a wasted self-attempt — that direction is recoverable (the attempt
36
+ fails, gets recorded, and the settle path accepts a failed attempt on an
37
+ exhausted re-run once the operator prunes or the ref is removed), and is the
38
+ same residual own-vault has for a revoked-but-present key.
39
+
40
+ ## 2. Under-block
41
+
42
+ - **A:** a procedure phrased as pure narrative ("the fix lives in the app
43
+ config page under OAuth") without imperative steps may evade the rule; the
44
+ meaning-judged framing (not literal step-counting) is the mitigation, and the
45
+ severity bias accepts residual under-blocking as the safe direction.
46
+ - **B:** an UNREGISTERED identity stays invisible — the registry only works if
47
+ agents register what they create. Addressed at the behavior layer (template
48
+ trigger + migrator section) rather than by scanning (a filesystem sweep for
49
+ credentials would violate the provider hard-safety rules).
50
+
51
+ ## 3. Level-of-abstraction fit
52
+
53
+ - **A:** correct layer — the tone gate is the single outbound authority and
54
+ already owns the sibling anti-patterns (B17 deferral, B19 parking). A
55
+ PreToolUse hook or a deterministic phrase list would be the wrong layer
56
+ (string-matching an infinitely-rephrasable intent).
57
+ - **B:** correct layer — the checklist is THE exhaustion oracle
58
+ (BlockerLedger's settle gate consumes its runs); a memory note or CLAUDE.md
59
+ prose alone would be willpower, not structure.
60
+
61
+ ## 4. Signal vs authority compliance
62
+
63
+ Compliant (see Phase 1 above). Reference: `docs/signal-vs-authority.md`. The
64
+ B21 rule text is judgment guidance to the existing authority; the
65
+ owned-identities provider is a signal producer feeding a recorder whose
66
+ authority lives elsewhere.
67
+
68
+ ## 5. Interactions
69
+
70
+ - **A/B17-B19 overlap:** handled explicitly in the prompt — extended citation
71
+ precedence `B15 > B16 > B17 > B18 > B21` plus a RELATIONSHIP paragraph
72
+ (B17 = deferring claiming a person is required; B19 = passive parking;
73
+ B21 = actively supplying the procedure). The b18 test's substring assertion
74
+ on the old chain still passes (the new chain contains it).
75
+ - **A/ratchets:** `gate-prompts-judge-by-meaning` (RULE_CLASSES keyset ==
76
+ VALID_RULES) and `tone-gate-rule-id-contract` pass with B21 in both
77
+ registries — verified green.
78
+ - **B/runner:** the defensive full-coverage assert in
79
+ `buildProductionProbeProviders` holds (source + provider land together);
80
+ the canonical-order test updated for the new position (after own-vault).
81
+ Short-circuit semantics unchanged.
82
+ - No double-fire: B21 has no deterministic detector, so no signal path exists
83
+ to race with; the owned-identities probe is read-only over one small file.
84
+
85
+ ## 6. External surfaces
86
+
87
+ - **A:** visible to users only as (rarely) a held message + rewritten resend —
88
+ the same surface every gate rule already has. `/metrics/features` and the
89
+ review history show citations for observability.
90
+ - **B:** a new optional per-agent file `.instar/owned-identities.json`
91
+ (agent-authored; absent = today's behavior). `/blockers/self-unblock-runs`
92
+ entries now include an `owned-identities` probe row. CLAUDE.md gains a
93
+ section on existing agents via the migrator (append-only, content-sniffed).
94
+ - No timing/conversation-state dependence beyond the gate's existing review
95
+ flow.
96
+
97
+ ## 7. Multi-machine posture
98
+
99
+ **Machine-local by design, both changes.** The gate rule is code shipped
100
+ identically to every machine (version parity). The owned-identities registry is
101
+ per-agent-home and machine-local like the vault and the playwright-profile
102
+ registry: entries carry machine-local credential POINTERS, and an entry without
103
+ its credential is a claim the checklist cannot act on. Cross-machine
104
+ replication is deliberately excluded (documented in the spec); the probe's
105
+ absence of a registry on a standby machine degrades to exactly today's
106
+ behavior. No user-facing notices are emitted by either change (no one-voice
107
+ concern); no durable state strands on topic transfer (the registry is not
108
+ topic-scoped); no URLs are generated.
109
+
110
+ ## 8. Rollback cost
111
+
112
+ - **A:** one commit removing B21 from the three registries; no data migration;
113
+ until then the worst failure is a false hold, immediately visible.
114
+ - **B:** one commit removing the source + provider; the registry file becomes
115
+ inert data. The appended CLAUDE.md section is prose; the migration is
116
+ content-sniffed and simply stops matching. Hot-fix release suffices for
117
+ both; no agent state repair.
118
+
119
+ ## Class-Closure Declaration
120
+
121
+ - `unbounded-self-action`: **n/a** — neither change performs or schedules any
122
+ self-triggered action. Change A adds prompt content to an existing gate's
123
+ single per-message review; Change B adds one bounded local file read inside
124
+ an existing on-demand checklist run. No loops, no cadences, no kill/spawn/
125
+ notify authority anywhere in the diff.
126
+
127
+ ## Spec-convergence hardening (round-1 findings folded in)
128
+
129
+ Beyond the second-pass exchange below, the full /spec-converge run (2 rounds,
130
+ six internal perspectives + codex-cli:gpt-5.5 external both rounds, conformance
131
+ gate 0 flags both rounds) drove further hardening before commit: agent-home
132
+ JAIL on file: refs (escape refused before any stat), 256 KB / 500-entry / 128-
133
+ char bounds with a stat cache (rule-(b) compliance), loud server-log warning on
134
+ a present-but-unparseable registry (the silent-recurrence trap), B21
135
+ capability-uncertainty default-PASS + widened human-only carve-out, the
136
+ wiring-integrity ratchet test, canonical scope-tag convention in the template +
137
+ migrator text, and honest disclosure of the resolving-but-stale residual and
138
+ the B21 token cost. Full catalog:
139
+ `docs/specs/reports/correction-derived-hardening-convergence.md`.
140
+
141
+ ## Operator design redirect (2026-07-18 23:00 PDT, incorporated pre-merge)
142
+
143
+ Mid-build the operator directed that B21 must NOT hold blocking authority:
144
+ outbound sentinels nudge a drafted message once; the agent decides; overrides
145
+ are recorded. Implemented as the structural `RULE_DISPOSITIONS` split (B21 as
146
+ `advisory`; the seam returns `tone-gate-advisory`/notSent with the
147
+ `toneAdvisoryAck` resend path; the override is logged as `advisoryOverridden`
148
+ for the decision-quality meter; the ack can never override a blocking rule).
149
+ This REDUCES Change A's authority below what the earlier sections review
150
+ (their over-block analyses become strictly conservative). Migration of
151
+ existing judgment rules to advisory is recorded in the spec as tracked intent
152
+ (CMT-904).
153
+
154
+ ## Feature-delivery ratchet compliance (post-suite fix)
155
+
156
+ The whole-tree feature-delivery-completeness ratchet caught that the new
157
+ migrateClaudeMd section was untracked: registered `'owned-identities'` in
158
+ featureSections and added the migrateFrameworkShadowCapabilities marker so
159
+ Codex/Gemini agents (which provision identities too) also learn the registry —
160
+ without the marker, the founding wrong-escalation would recur on non-Claude
161
+ frameworks (the exact Secret-Drop/Commitments gap class the ratchet was built
162
+ from).
163
+
164
+ ## Second-pass review
165
+
166
+ Required (the change touches a gate). Performed as a REAL independent
167
+ fresh-context reviewer run (claude one-shot over the artifact, spec, and full
168
+ diff), 2026-07-18.
169
+
170
+ **Round 1 — Concern raised:** "the owned-identities probe is the only one of
171
+ the ten sources that can force `exhausted:false` on pure static declaration
172
+ with no liveness check … a stale entry whose scopeTag matches the blocked
173
+ target … means the agent cannot record a true-blocker and cannot escalate to
174
+ the operator even after a genuine failed self-attempt — a self-perpetuating
175
+ loop. This is precisely the 'brittle logic gaining blocking authority' pattern
176
+ the audit targets." Recommended an existence check of the credentialRef
177
+ pointer before advertising (a stat, not a value read).
178
+
179
+ **Iteration:** the recommended design was adopted in full — the credentialRef
180
+ liveness gate (file: stat with agent-home-relative resolution; vault: key-name
181
+ presence via getVaultKeys; unknown/missing schemes advertise nothing), plus
182
+ two new tests (stale registry advertises nothing; a full checklist run over a
183
+ fully-stale registry still exhausts) and the spec/artifact text corrected to
184
+ stop claiming the bias was purely toward wasted self-attempts.
185
+
186
+ **Round 2 — Concur:** re-review of the updated diff confirmed the stranding
187
+ path is closed and no new authority was created (the liveness check is a
188
+ boolean stat feeding a recorder; the settle authority is unchanged).
@@ -0,0 +1,154 @@
1
+ # Side-Effects Review — framework-stall-coverage-matrix PR-B
2
+
3
+ **Change:** PR-B (second of the two staged PRs) of the framework-stall-coverage-matrix
4
+ standard (spec: `docs/specs/framework-stall-coverage-matrix.md`, converged + approved
5
+ 2026-07-18; PR-A merged as #1512). Ships: the runtime apprenticeship gate
6
+ (`src/core/ApprenticeshipStallGate.ts` + worker), the acceptance/override machinery
7
+ (`src/core/ApprenticeshipMatrixAcceptance.ts` + two routes), the
8
+ `stall-matrix-live-check` job (+ driver script), install-provenance derivation +
9
+ one-time migrator backfill, the `/guards` load-bearing-soaking row, and the CLAUDE.md
10
+ template/migration section. Gate ships behind `apprenticeship.stallCoverageGate` with
11
+ inline default `{enabled: true, dryRun: true}` — observe-first, per the spec's
12
+ graduated rollout.
13
+
14
+ ## Phase 1 principle check (recorded)
15
+
16
+ This change IS a decision point: it can refuse apprenticeship transitions (409).
17
+ Compliance shape: the gate's verdicts are the spec-classified INVARIANT half
18
+ (deterministic structural validation — presence, tokens, symbol resolution, ref
19
+ liveness, posture cross-check), executed in a bounded worker; every judgment call
20
+ (whether a covered claim is TRUE, acceptance of gaps/N-A/covered rows, degraded-mode
21
+ sign-off) is routed to an authenticated HUMAN principal via the challenge-bound
22
+ acceptance machinery — requester ≠ acceptor structurally (a bearer principal is
23
+ refused at bind). The fallback ladder ends deterministic: no valid acceptance → refuse
24
+ (no acceptance is ever inferred). This is Judgment-Within-Floors compliant: the floor
25
+ (schema/enumeration/liveness) is deterministic; the human holds the semantic choice.
26
+
27
+ ## 1. Over-block
28
+
29
+ - The gate could refuse a legitimate completion on: a dead closePath ref (fix: reopen
30
+ or re-status the row), a renamed detector symbol (fix: update the row), a stale
31
+ acceptance after an edit (accept-then-edit voids by DESIGN — decision 20), a
32
+ validator timeout (named retryable reason, distinct from invalidity), or an
33
+ unreachable local server during liveness checks (named 'ledger-unreachable
34
+ (retry)' — never conflated with matrix-invalid).
35
+ - Mitigations: ships dryRun (would-refuse logged, nothing blocked) until the operator
36
+ flips enforce on named evidence; refusal reasons name class id + rule; the
37
+ per-instance recorded override (row-scoped, content-bound, expiring) is the relief
38
+ valve for a flaky check; pre-ship instances are grandfathered (warning-only) until
39
+ the required-since minor.
40
+
41
+ ## 2. Under-block
42
+
43
+ - Semantic truth of `covered` remains un-validated by machine — by explicit spec
44
+ design; the acceptance enumeration puts every row class in front of the acceptor.
45
+ - The conversational acceptance arm binds on the operator's reply-anchor; a verified
46
+ operator absent-mindedly replying "yes" to the wrong enumeration message binds that
47
+ enumeration — bounded by the single-use challenge, the rendered set in the message,
48
+ and hash re-resolution at bind (a changed matrix invalidates).
49
+ - While dryRun holds (the shipped state), NOTHING is enforced — the /guards
50
+ load-bearing-soaking row (30-day window, declared 2026-07-18) makes an unflipped
51
+ gate lapse into visible debt rather than rot ("A Dark Feature Guards Nothing"
52
+ applied to this gate itself).
53
+
54
+ ## 3. Level-of-abstraction fit
55
+
56
+ The gate is a separate module consumed by ApprenticeshipProgram through a nullable
57
+ seam — the transition chokepoint remains the single authority; the gate adds a branch
58
+ there rather than a parallel path. Validation executes in a worker (never the event
59
+ loop — instar#1069 posture); acceptance rides the existing challenge mechanics
60
+ (ScopeAccretionRatifier pattern + checkMandatePin funnel) rather than inventing a new
61
+ authority surface.
62
+
63
+ ## 4. Signal vs authority compliance
64
+
65
+ The blocking surface is a deterministic invariant floor at a rare, human-paced,
66
+ audited transition — the documented exemption class — and it holds NO authority over
67
+ semantic meaning: those decisions belong to the PIN/verified-operator acceptor. No
68
+ brittle check gained authority over message flow or session behavior; day-to-day
69
+ sessions are untouched (Phase A cost boundary holds: gate work happens at transitions
70
+ and in the weekly job only).
71
+
72
+ ## 5. Interactions
73
+
74
+ - transition()/evaluateCompletionGate() became async — all callers updated; the routes'
75
+ 409 mapping is unchanged in shape.
76
+ - The gate consumes the PR-A validator through the same deps seam CI uses — no
77
+ double-fire (CI stays hermetic; gate adds only the non-hermetic checks).
78
+ - The live-check job overlaps the gate's non-hermetic checks by DESIGN (the job covers
79
+ the standing seed matrices that never traverse a transition); both write distinct
80
+ audit rows. Its mint flow files idempotent dedupKeyed issues + ONE aggregated
81
+ commitment per pass — flood-safe by construction (aggregation, not per-element).
82
+ - The provenance backfill appends at most one decisions-log record (presence-scan
83
+ idempotent); init and migrator cannot double-record.
84
+
85
+ ## 6. External surfaces
86
+
87
+ Two new Bearer/PIN routes (CapabilityIndex updated); one Telegram enumeration message
88
+ per acceptance request (operator-initiated, never spontaneous); the weekly job ships
89
+ `enabled: false` fleet-wide with a silent no-op on no-source installs. No behavior
90
+ change for running sessions; restart applies the new server surfaces.
91
+
92
+ ## 7. Multi-machine posture
93
+
94
+ Matrix artifacts + gate code: unified-via-git. Gate verdicts: derived-on-read against
95
+ the per-machine apprenticeship registry (the registry's declared machine-local
96
+ posture, operator-ratified in the spec's Multi-machine section); acceptance artifacts
97
+ and provenance records live in the gate machine's decisions log — coherent with
98
+ closePath refs resolving on the gate machine. The live-check job is
99
+ perMachineIndependent. No stranding: a topic transfer does not carry gate state
100
+ because the registry itself is machine-local by declared design.
101
+
102
+ ## 8. Rollback cost
103
+
104
+ Config flag off ⇒ gate branch inert (matrices remain docs + tracked issues); revert
105
+ the PR for a full back-out — no data migration (decisions-log rows and acceptance
106
+ records are append-only audit, harmless to retain). The always-overwrite job template
107
+ un-ships with the revert; per-slug manifests preserve operator enabled-state
108
+ semantics. Cheapest rollback class for a gate: a flag read live at the callsite.
109
+
110
+ ## Second-pass review
111
+
112
+ REQUIRED (gate + session-lifecycle-adjacent + blocking surface). Dedicated reviewer
113
+ subagent audits this artifact against the final diff independently.
114
+
115
+ ### Second-pass reviewer response
116
+
117
+ **Concern raised (2026-07-18):** the row-scoped acceptance/override relief valve
118
+ was UNREACHABLE in production — the only shipped mint surface produced
119
+ whole-set/degraded challenges, so any row carrying an `acceptanceRef` (required
120
+ to clear `unreviewed`) would have failed `acceptance-ref-invalid` at enforce
121
+ time with no legitimate satisfaction path: a latent over-block behind the
122
+ dry-run. All other load-bearing properties were verified: dryRun suppresses
123
+ every refusal class through a single funnel; timeout and ledger-unreachable
124
+ verdicts are distinct and fail closed; bearer principals structurally refused
125
+ at bind; challenges single-use with replay refused; hashes re-resolved at
126
+ bind; refusal hygiene holds; multi-machine claims match the spec's declared
127
+ postures.
128
+
129
+ **Resolution (same session, pre-commit):** (1) the enumerate route is now
130
+ scope-aware (`rows` / `override` scopes mintable through the same PIN and
131
+ reply-anchor paths, Decision-20 canonical row hashing, `acceptanceRef`
132
+ excluded from row serialization to close the mint→bind→write-ref cycle) with
133
+ both-sides production-shaped route tests; (2) HTTP-error conflation fixed —
134
+ only 404/terminal means dead-ref, any other failure is ledger-unreachable
135
+ (retryable), in the gate AND the live-check script; (3) the aggregated
136
+ attention items now carry deterministic dedup ids (per matrix-state /
137
+ per-findings-set) — fixing, en route, a latent missing-required-id 400 on both
138
+ attention posts. Reviewer's remaining non-blocking observations (decisions-log
139
+ fabrication surface consistent with the declared tamper-evident threat model;
140
+ enumeration message formatting) accepted as noted. 296/296 tests green
141
+ post-resolution.
142
+
143
+ **Post-resolution status: concerns resolved; review concurs with the artifact
144
+ as amended.**
145
+
146
+ ## Class-Closure Declaration
147
+
148
+ `unbounded-self-action` — closure: **n/a** (negative declaration). The gate's
149
+ actions are rare, human-paced, operator-driven transition evaluations — never a
150
+ self-triggered loop: attention posts carry deterministic dedup ids (one item per
151
+ matrix-state / per-findings-set; server-side dedup engages on retries), the
152
+ live-check job is an operator-enabled weekly cadence emitting ONE aggregated
153
+ attention item + ONE aggregated commitment per pass, and no respawn/kill/swap
154
+ surface is touched by this change.
@@ -1,53 +0,0 @@
1
- # Upgrade Guide — vNEXT
2
-
3
- <!-- assembled-by: assemble-next-md -->
4
- <!-- bump: patch -->
5
-
6
- ## What Changed
7
-
8
- Added one section to `docs/apprenticeship/PROGRAM-CONCEPTS.md`: "The
9
- Hidden-Test Battery (regression tripwires)" — the durable, generic record of
10
- the mechanism the operator approved on 2026-07-18. The battery is a set of
11
- undisclosed scenarios that each detect the LOSS of an already-valued behavior:
12
- passing means nothing broke, never that growth was achieved (growth stays with
13
- the overseer's judgment). Scenarios stay undisclosed during a drive and are
14
- scored retrospectively (pass / fail / not-triggered, with evidence pointers)
15
- as ONE necessary-not-sufficient input to ladder promotions — a failure can
16
- block a rung, no quantity of passes can earn one. The mechanism itself is
17
- disclosed to the mentee once (results appear in drive reports the mentee can
18
- read); only the scenario list stays hidden. The battery is disposable (a
19
- performed-for scenario is retired; the operator reviews the list at every rung
20
- change) and guardrailed: never a leaderboard, never a mid-drive threat, never
21
- a gate on day-to-day work, never scenarios that can harm real users, data, or
22
- services. Scenarios are preferentially captured from naturally-arising
23
- situations, manufactured only as a last resort and never on production
24
- surfaces.
25
-
26
- This is documentation only. No code, config, hook, job, template, or test
27
- changes; no runtime surface; no behavior change for any deployed agent.
28
-
29
- ## What to Tell Your User
30
-
31
- Nothing changes in how your agent behaves. The apprenticeship program's
32
- documentation now records how regression tripwires work: a small, undisclosed
33
- set of checks that only ever fire when a learning agent LOSES a good habit it
34
- already had — never a score to chase, never a leaderboard, never a gate on
35
- daily work — with results reviewed openly after each drive as one input to
36
- promotion decisions a human still makes.
37
-
38
- ## Summary of New Capabilities
39
-
40
- - None (documentation only). New content: the "Hidden-Test Battery" section in
41
- `docs/apprenticeship/PROGRAM-CONCEPTS.md`, recording the adopted
42
- regression-tripwire discipline for the apprenticeship program.
43
-
44
- ## Evidence
45
-
46
- - `docs/apprenticeship/PROGRAM-CONCEPTS.md` — the new section (mechanism only;
47
- deliberately no scenario, agent, or organization content).
48
- - `docs/specs/hidden-test-battery-adoption.eli16.md` — plain-English explainer.
49
- - `upgrades/side-effects/hidden-test-battery-adoption.md` — side-effects
50
- review; every question resolves to "documentation-only, no runtime surface";
51
- multi-machine posture unified-via-git; rollback = revert the doc.
52
- - Sanity: the whole-tree stall-coverage CI ratchet
53
- (`tests/unit/stall-coverage-ratchet.test.ts`) runs green on this tree.