instar 1.2.64 → 1.2.66

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 (41) hide show
  1. package/dist/commands/init.d.ts.map +1 -1
  2. package/dist/commands/init.js +21 -0
  3. package/dist/commands/init.js.map +1 -1
  4. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  5. package/dist/core/PostUpdateMigrator.js +38 -1
  6. package/dist/core/PostUpdateMigrator.js.map +1 -1
  7. package/dist/core/TopicIntent.d.ts +28 -4
  8. package/dist/core/TopicIntent.d.ts.map +1 -1
  9. package/dist/core/TopicIntent.js +41 -9
  10. package/dist/core/TopicIntent.js.map +1 -1
  11. package/dist/core/TopicIntentArcCheck.d.ts +6 -3
  12. package/dist/core/TopicIntentArcCheck.d.ts.map +1 -1
  13. package/dist/core/TopicIntentArcCheck.js +32 -5
  14. package/dist/core/TopicIntentArcCheck.js.map +1 -1
  15. package/dist/core/TopicIntentBriefing.d.ts +2 -0
  16. package/dist/core/TopicIntentBriefing.d.ts.map +1 -1
  17. package/dist/core/TopicIntentBriefing.js +23 -4
  18. package/dist/core/TopicIntentBriefing.js.map +1 -1
  19. package/dist/core/TopicIntentCapture.d.ts.map +1 -1
  20. package/dist/core/TopicIntentCapture.js +1 -1
  21. package/dist/core/TopicIntentCapture.js.map +1 -1
  22. package/dist/core/TopicIntentExtractor.d.ts.map +1 -1
  23. package/dist/core/TopicIntentExtractor.js +19 -7
  24. package/dist/core/TopicIntentExtractor.js.map +1 -1
  25. package/dist/core/installCodexHooks.d.ts +52 -0
  26. package/dist/core/installCodexHooks.d.ts.map +1 -0
  27. package/dist/core/installCodexHooks.js +113 -0
  28. package/dist/core/installCodexHooks.js.map +1 -0
  29. package/dist/server/topicIntentRoutes.d.ts.map +1 -1
  30. package/dist/server/topicIntentRoutes.js +1 -0
  31. package/dist/server/topicIntentRoutes.js.map +1 -1
  32. package/package.json +1 -1
  33. package/src/data/builtin-manifest.json +17 -17
  34. package/upgrades/1.2.65.md +80 -0
  35. package/upgrades/1.2.66.md +57 -0
  36. package/upgrades/side-effects/codex-enforcement-hooks-p1.md +32 -0
  37. package/upgrades/side-effects/codex-enforcement-hooks-p1b.md +29 -0
  38. package/upgrades/side-effects/codex-enforcement-hooks-p2.md +36 -0
  39. package/upgrades/side-effects/codex-enforcement-hooks-p3.md +25 -0
  40. package/upgrades/side-effects/codex-enforcement-hooks-p5c.md +38 -0
  41. package/upgrades/side-effects/topic-intent-task-context-capture.md +104 -0
@@ -0,0 +1,32 @@
1
+ # Side-Effects Review: Codex enforcement hooks — P1 (installCodexHooks writer + tests)
2
+
3
+ ## Change
4
+ New module `src/core/installCodexHooks.ts` + `tests/unit/installCodexHooks.test.ts` (6 tests). The module writes/merges instar's safety-gate registrations into a Codex agent's per-project `<projectDir>/.codex/hooks.json`, mapping the existing gate scripts (`external-operation-gate.js`, `grounding-before-messaging.sh`, `response-review.js`, `deferral-detector.js`, `session-start.sh`, `telegram-topic-context.sh`) to Codex's verified hook events (PreToolUse, PermissionRequest, Stop, SessionStart, UserPromptSubmit), using the verified Codex hooks.json schema.
5
+
6
+ ## Scope of effect (this commit)
7
+ - **Capability-only, NOT yet wired.** This commit adds the writer + tests; it is NOT yet invoked from the init/refresh path (that is P1b, with a wiring-integrity test). So there is **no runtime behavior change** until the wiring lands — the function is inert until called.
8
+ - When wired, it writes a single file: `<projectDir>/.codex/hooks.json`. Nothing else.
9
+
10
+ ## Scoping (correctness-critical)
11
+ - Writes the **per-project** `.codex/hooks.json`, never the global `~/.codex/`. The global root is shared with the operator's personal desktop Codex and every other Codex project — global hooks would intercept the operator's personal sessions. Per-project scoping confines the gates to this agent's project dir. Unit-tested (asserts the path is not under `~/.codex`).
12
+
13
+ ## Merge-safety
14
+ - Instar-owned entries are identified by command path containing `.instar/hooks/instar/`. On re-run, instar groups are replaced; any user-added Codex hooks are preserved verbatim. Idempotent (re-run yields identical file). Both behaviors unit-tested.
15
+
16
+ ## Signal vs Authority
17
+ - The writer carries no runtime authority. The hooks it registers are low-context triggers that route to the server-side authority gates (`/operations/evaluate`, `/review/evaluate`). The writer just emits config; nothing in it decides allow/deny.
18
+
19
+ ## Over/under-block, abstraction
20
+ - N/A — config writer, not a gate. The registered gates are the existing, unchanged authorities. No new decision boundary introduced here.
21
+
22
+ ## Migration parity
23
+ - Not in this commit. `migrateCodexHooks()` (P3) will backfill existing Codex agents. Tracked in the spec phase plan; not deferred-and-forgotten.
24
+
25
+ ## Rollback
26
+ - Trivial: delete the two files. No deployed effect (unwired). Once wired, removing the instar entries from `.codex/hooks.json` is a clean revert with no data migration.
27
+
28
+ ## Tests
29
+ - 6 unit tests: per-project location (not global), all five events with the verified schema, absolute cwd-independent script paths, idempotency, user-hook preservation + instar replace, pure builder. All passing; tsc clean.
30
+
31
+ ## Publish
32
+ - Feature branch `echo/codex-enforcement-hooks`. Not shipped; no separate publish.
@@ -0,0 +1,29 @@
1
+ # Side-Effects Review: Codex enforcement hooks — P1b (wire installCodexHooks into init/refresh)
2
+
3
+ ## Change
4
+ `src/commands/init.ts`: `refreshHooksAndSettings()` now calls `installCodexHooks(projectDir)` gated on `enabledFrameworks.includes('codex-cli')`, mirroring the existing `claudeEnabled → installClaudeSettings` block. Plus a wiring-integrity test (`tests/unit/codex-hooks-wiring.test.ts`).
5
+
6
+ `refreshHooksAndSettings` is the single path that both `instar init` (line ~1097) and the update path invoke — so this one call site covers BOTH new and existing codex agents.
7
+
8
+ ## Runtime behavior change
9
+ - Codex-cli agents now get `<projectDir>/.codex/hooks.json` written on init AND on every update/refresh. Claude-only agents are unaffected (gated). Both verified by the wiring-integrity test (codex → file created with instar gates; claude-only → no file; both → file created).
10
+
11
+ ## Sequencing risk (IMPORTANT — captured, not deferred-and-forgotten)
12
+ - The wiring registers the existing gate scripts (`external-operation-gate.js`, `response-review.js`, etc.) into Codex's hook events. Those scripts currently parse **Claude's** hook stdin payload; the **Codex-payload shim is P2**. So on a *live* Codex session, the scripts could misbehave (parse errors → potentially an erroneous exit-2 block) until P2 lands.
13
+ - **Why this is safe now:** this is a feature branch, NOT deployed. codey runs the released v1.2.53, which does not carry this wiring. No live codex agent has these hooks yet.
14
+ - **Hard sequencing constraint for the build:** **P2 (gate-script Codex-payload shim) MUST land before the P6 deploy.** The phase plan already orders P2 → P6; this review makes the constraint explicit. Do not deploy P1 wiring without P2.
15
+
16
+ ## Signal vs Authority
17
+ - Unchanged from P1: the hooks route to the server-side authority gates; the wiring just ensures they're registered for codex agents. No new authority.
18
+
19
+ ## Migration parity
20
+ - `instar init` + update both flow through `refreshHooksAndSettings`, so existing codex agents get the wiring on their next update. (A dedicated `migrateCodexHooks` / always-overwrite-instar-owned hardening is P3.)
21
+
22
+ ## Rollback
23
+ - Remove the `codexEnabled` block in `refreshHooksAndSettings` + the import. No deployed effect (branch-only).
24
+
25
+ ## Tests
26
+ - Wiring-integrity: 3 tests (codex → wired, claude-only → not wired, both → wired). Plus the P1a unit suite (6). tsc + lint clean.
27
+
28
+ ## Publish
29
+ - Feature branch. Not shipped.
@@ -0,0 +1,36 @@
1
+ # Side-Effects Review: Codex enforcement hooks — P2 (shell-gate works under Codex)
2
+
3
+ ## Change
4
+ Closes the gap from §4.2d (as-wired-in-P1, Codex's native shell/exec/apply_patch would have passed UNGATED).
5
+ 1. **stdin shim** for the two arg-reading safety scripts so they read `tool_input.command` from Codex's stdin JSON when no positional arg is present (Claude's `$1` path unchanged):
6
+ - `dangerous-command-guard.sh` — both source copies kept consistent: `PostUpdateMigrator.getDangerousCommandGuard()` (always-overwrite/migration canonical) AND the inline duplicate in `init.ts`.
7
+ - `grounding-before-messaging.sh` — `PostUpdateMigrator.getGroundingBeforeMessaging()` (canonical, used by migration + init).
8
+ 2. **Mapping fix:** added `dangerous-command-guard.sh` to `installCodexHooks` `buildInstarCodexHookGroups()` PreToolUse group (coupled with the shim — mapping without shim would be the false-install trap).
9
+
10
+ ## Why
11
+ `external-operation-gate.js` only gates `mcp__*` tools (exits 0 otherwise). Codex's destructive class is native `shell`/`exec`/`apply_patch`, which Claude gates via `dangerous-command-guard` on the Bash matcher. P1 omitted that gate from the Codex mapping, and the script couldn't read Codex's input anyway. Both fixed.
12
+
13
+ ## Over/under-block
14
+ - The blocked catastrophic patterns are identical to Claude's (`rm -rf /`, `mkfs.`, `dd if=`, fork-bomb, etc.) — no Codex-specific over-block. Empty/garbage stdin → INPUT empty → no match → pass (no false-block); tested.
15
+
16
+ ## Signal vs Authority
17
+ - `dangerous-command-guard` is a deterministic low-context guard on catastrophic patterns + a config safety-level gate; nuanced authority remains the server-side gate. Adding it to Codex mirrors Claude's posture — no new authority.
18
+
19
+ ## Near-silence
20
+ - Blocks write the reason to **stderr** (the agent sees it), never a user message. No notification spam.
21
+
22
+ ## Migration parity
23
+ - The scripts are always-overwritten on migration (getDangerousCommandGuard / getGroundingBeforeMessaging), so existing Codex agents get the shim on update; the mapping runs via refreshHooksAndSettings (P1b) on init + update.
24
+
25
+ ## Rollback
26
+ - Revert the 3 shim insertions + the one mapping-line addition. No data migration.
27
+
28
+ ## Tests (real, no mocks)
29
+ - Unit: 9 (incl. new assertion that dangerous-command-guard is in the Codex PreToolUse mapping).
30
+ - **Integration (the proof): 5** — generates the REAL script via refreshHooksAndSettings, then: BLOCKS `rm -rf /` via Codex stdin/no-arg (exit 2), PASSES benign via stdin, still BLOCKS via Claude arg path (regression), no false-block on garbage stdin.
31
+
32
+ ## Sequencing
33
+ - Satisfies the P2 hard-constraint (shell gating works under Codex) before any P6 deploy. Remaining: PermissionRequest exit-2 confirmation (P4), the live codey E2E (P5).
34
+
35
+ ## Publish
36
+ - Feature branch. Not shipped.
@@ -0,0 +1,25 @@
1
+ # Side-Effects Review: Codex enforcement hooks — P3 (migration parity)
2
+
3
+ ## Change
4
+ `PostUpdateMigrator.migrateHooks()` now calls `installCodexHooks(this.config.projectDir)` gated on `getEnabledFrameworks().includes('codex-cli')`, writing the per-project `.codex/hooks.json` for existing Codex agents on update. + import.
5
+
6
+ ## Why (Migration Parity Standard — non-negotiable)
7
+ `installCodexHooks` ran ONLY from init's `refreshHooksAndSettings` (verified: that function's sole caller is `init.ts`). Existing agents update via `PostUpdateMigrator`, which wrote the gate SCRIPTS (with the P2 shim) but NOT the `.codex/hooks.json` registration. So without this, an existing Codex agent would get the updated guard scripts yet never the registration that makes Codex fire them — "works for new agents only" = broken. This closes it.
8
+
9
+ ## Scope
10
+ - On update, codex-cli agents get `.codex/hooks.json` written/refreshed (idempotent; preserves user-added Codex hooks via the command-path ownership check). Claude-only agents unaffected (gated). The referenced gate scripts are written earlier in the same `migrateHooks` pass.
11
+
12
+ ## Idempotency
13
+ - Tested: repeated migration yields exactly one instar PreToolUse group (no accumulation).
14
+
15
+ ## Signal vs Authority / Over-block
16
+ - Unchanged from P1/P2 — this only ensures the registration reaches existing agents. No new authority, no new block patterns.
17
+
18
+ ## Rollback
19
+ - Revert the `migrateHooks` codex block + the import. No data migration.
20
+
21
+ ## Tests
22
+ - 3 migration tests: codex-cli agent → `.codex/hooks.json` written (with dangerous-command-guard in PreToolUse); claude-only → not written; idempotent across repeated migrations. Full P1–P3 sweep: 17 green. tsc + lint clean.
23
+
24
+ ## Publish
25
+ - Feature branch. Not shipped.
@@ -0,0 +1,38 @@
1
+ # Side-Effects Review: Codex enforcement hooks — P5c (the guard actually fires)
2
+
3
+ ## Change
4
+ Two source fixes that make the Codex PreToolUse gate actually fire on the real Codex engine (previously it was registered but silently never invoked):
5
+
6
+ 1. **`src/core/installCodexHooks.ts`** — PreToolUse + PermissionRequest matcher changed `'*'` → `'.*'`. Codex treats the matcher as a regex against the tool name; a bare `*` is an invalid quantifier (no preceding atom) that matches nothing, so the gate never fired. `.*` matches all tool calls.
7
+ 2. **`src/core/PostUpdateMigrator.ts`** (dangerous-command-guard + grounding-before-messaging generators) and **`src/commands/init.ts`** (inline dangerous-command-guard) — the stdin shim now reads `tool_input.command OR tool_input.cmd`. Codex's shell tool is `exec_command` and delivers the command in `tool_input.cmd`; Claude uses `tool_input.command`. The prior shim read only `command`, so even when fired against Codex it saw an empty string.
8
+
9
+ ## Why
10
+ Live verification (host codex-cli v0.133.0, interactive, hooks trusted) showed SessionStart + UserPromptSubmit hooks fired but the PreToolUse dangerous-command-guard did NOT — even trusted. Diagnosing from the Codex session rollout log revealed the matcher was an invalid regex AND the command field name differed. The earlier P5b conclusion ("root cause = hook-trust model") was a red herring for the non-firing symptom: trust gates whether hooks run at all, but with trust granted the guard still failed to fire for these two reasons.
11
+
12
+ ## Scope / blast radius
13
+ - Codex agents only in effect: `.codex/hooks.json` is written solely for `enabledFrameworks.includes('codex-cli')`. Claude-only agents are unaffected (the guard scripts gained a stdin fallback that is inert when `$1` is supplied — Claude's existing arg path is unchanged and still tested).
14
+ - With matcher `.*`, all three PreToolUse hooks now fire on every Codex tool call. Verified non-harmful: `external-operation-gate.js` exits 0 for any non-`mcp__*` tool (so `exec_command` passes straight through); `grounding-before-messaging.sh` only blocks when the command matches its messaging regex; `dangerous-command-guard.sh` only blocks catastrophic/risky patterns. No false-block surface introduced.
15
+ - The `cmd`-field fallback is additive: `command or cmd or ''`. Claude payloads (`command`) are read first and unchanged.
16
+
17
+ ## Signal vs Authority / over-block
18
+ - Unchanged authority model: hooks remain low-context triggers that exit-2 on deterministic catastrophic patterns or route to the server-side gate. No new block patterns added; only the delivery (matcher + field) was corrected so existing patterns reach the guard.
19
+
20
+ ## Migration parity
21
+ - Both the init generator (`init.ts`) and the update generator (`PostUpdateMigrator.ts`) carry the shim fix, so new AND existing Codex agents get the working guard. The matcher fix lives in `installCodexHooks.ts`, called from both `refreshHooksAndSettings` (init) and `migrateHooks` (update, P3).
22
+
23
+ ## Live proof (evidence bar)
24
+ Regenerated codey's hooks from freshly-built source via the real `refreshHooksAndSettings` path (no hand-patch, no debug instrumentation), launched real interactive Codex 0.133, instructed it to run `echo 'rm -rf /'` → Codex displayed `• PreToolUse hook (blocked) — BLOCKED: Catastrophic command detected: rm -rf /` and did not execute it. First confirmed firing of the Codex enforcement guard in the real engine. Before the fix the identical setup ran the command unblocked.
25
+
26
+ ## Tests
27
+ - `tests/integration/codex-dangerous-command-block.test.ts` rewritten to the verified Codex shape (`tool_name: 'exec_command'`, `tool_input: { cmd, yield_time_ms }`) — would have failed before the `cmd` shim; plus a Claude-stdin (`command`) case so both field paths are covered.
28
+ - `tests/unit/installCodexHooks.test.ts` asserts `PreToolUse`/`PermissionRequest` matcher === `'.*'` (regression guard against the invalid `*`).
29
+ - Full codex suite: 19 green (7 + 3 + 3 + 6). tsc clean.
30
+
31
+ ## Rollback
32
+ - Revert the matcher to its prior value and drop the `cmd` fallback in the three generators. No data migration. (Rollback re-breaks Codex enforcement — not advised.)
33
+
34
+ ## Follow-on (tracked, NOT deferred-broken)
35
+ - **P6a managed hooks**: trust remains a separate concern — even `--dangerously-bypass-hook-trust` still pops an interactive trust prompt + a model-upsell prompt (would freeze unattended autonomy), and a trust-gated hook lets the agent decline ("continue without trusting"), so it can disable its own guard. Managed hooks (run-by-policy, agent-can't-disable) fix both. Genuine design fork → paused for Justin's input. Does not block this correctness fix shipping.
36
+
37
+ ## Publish
38
+ - Feature branch `echo/codex-enforcement-hooks`. Targets release v1.2.57 once P6 (awareness + crossreview) completes.
@@ -0,0 +1,104 @@
1
+ # Side-effects review — topic-intent task-context capture (rung 1)
2
+
3
+ **Scope**: Generalize topic-intent capture from conversational facts/decisions to
4
+ **task contexts** (method/audience/goal) — the working-frame category that caused
5
+ the founding methodology-drift incident ("we're testing over Telegram") and that
6
+ rung 0 structurally can't catch. Same store, new ref kinds, per-kind decay
7
+ horizons, an "Active task frame" briefing block, an ArcCheck frame-drift signal,
8
+ and per-kind observability. Spec: `docs/specs/topic-intent-task-context-capture.md`
9
+ (approved by justin; Claude-authored + manual review — see spec's honest
10
+ convergence note).
11
+
12
+ **Files touched**:
13
+ - `src/core/TopicIntent.ts` — extend `RefKind` with `method|audience|goal` +
14
+ `TASK_CONTEXT_KINDS`/`isTaskContextKind`; per-kind `DECAY_PROFILES` +
15
+ `decayProfileFor`; `projectConfidence` gains an optional `refKind` param
16
+ (omitted → long profile = rung-0 behavior, byte-for-byte); the three callers
17
+ pass `ref.kind`; `CaptureCounters.refkind_created` (additive, defaulted) +
18
+ `bumpCaptureCounters` optional `refKindsCreated` arg.
19
+ - `src/core/TopicIntentExtractor.ts` — `buildExtractorPrompt` teaches the
20
+ task-frame kinds; `translateProposal` validates `refKind` against an allowlist
21
+ (`VALID_REF_KINDS`) so a garbage/poisoned kind never creates a ref.
22
+ - `src/core/TopicIntentArcCheck.ts` — **new `contradicts-frame` verdict**: a draft
23
+ contradicting a task-context ref fires at **tentative-or-above** (frames decay
24
+ fast and are often only tentative; drifting from one is the founding-incident
25
+ failure). The existing `contradicts-settled` rule is scoped to fact/decision so
26
+ its behavior is unchanged.
27
+ - `src/core/TopicIntentBriefing.ts` — partition refs into a distinct
28
+ **"ACTIVE TASK FRAME"** block (method/audience/goal) vs the SETTLED/TENTATIVE
29
+ proposition blocks; `BriefingResult.counts.frame` added.
30
+ - `src/core/TopicIntentCapture.ts` — `captureTurn` passes the created refKinds to
31
+ `bumpCaptureCounters` for the per-kind breakout.
32
+ - `src/server/topicIntentRoutes.ts` — `capture-metrics` funnel exposes
33
+ `refkind_created`.
34
+ - Tests: `tests/unit/TopicIntent-task-context.test.ts`,
35
+ `tests/integration/topic-intent-task-context.test.ts`,
36
+ `tests/e2e/topic-intent-task-context-lifecycle.test.ts`; updated one existing
37
+ briefing-counts assertion for the additive `frame` field.
38
+
39
+ **Under-block**: The new ArcCheck frame rule is signal-only and fires at
40
+ tentative-or-above — deliberately *lower* threshold than settled propositions,
41
+ so it won't *miss* a frame drift just because the frame is only tentative. No new
42
+ path can suppress a real capture: task-frame extraction rides the same fail-open
43
+ pre-filter as rung 0.
44
+
45
+ **Over-block**: The only "block"-shaped behavior is ArcCheck, which is a signal
46
+ (never a veto) per [[feedback_signal_vs_authority]]. A false frame-drift signal
47
+ costs one "confirm?" nudge, never a blocked send. The refKind allowlist is the
48
+ only new hard reject, and it only drops malformed proposals (no valid kind is
49
+ excluded).
50
+
51
+ **Level-of-abstraction fit**: Task contexts are modeled as additional `RefKind`
52
+ values in the *same* store and the *same* extraction/confidence/decay machinery —
53
+ not a parallel system. The extractor stays the single extraction point (one LLM
54
+ call, extended prompt); the store stays the single authority; the briefing/ArcCheck
55
+ stay the single surfaces. Per-kind decay is a lookup keyed by the ref's own kind,
56
+ not a special-case branch.
57
+
58
+ **Signal vs authority**: Capture records; ArcCheck (incl. the new frame rule)
59
+ signals; neither blocks. The pre-filter remains a brittle detector with no veto.
60
+
61
+ **Interactions**:
62
+ - `projectConfidence` signature gained a 4th optional param. All existing callers
63
+ that omit it get the long profile → **rung-0 confidence math is provably
64
+ unchanged** (pinned by an explicit regression test across 5 time points).
65
+ - The founding-incident e2e caught a real gap during the build: frame contradiction
66
+ needed to fire at tentative tier, which the original (authoritative-only)
67
+ contradicts rule didn't cover — hence the new `contradicts-frame` rule. (This is
68
+ the e2e earning its keep, exactly as intended.)
69
+ - `capture-metrics` GET and the briefing GET keep their existing metering
70
+ side-effects (rung 0); `refkind_created` rides the same lock.
71
+ - Additive `CaptureCounters.refkind_created` is `undefined` on pre-rung-1 files and
72
+ handled everywhere (`?? {}`, lazy-init in the bump) — no migration needed.
73
+
74
+ **External surfaces**:
75
+ - `capture-metrics` funnel gains `refkind_created: Record<kind, count>`.
76
+ - The briefing text gains an "ACTIVE TASK FRAME" section when frame refs exist.
77
+ - New `ArcCheckVerdict` kind `contradicts-frame`.
78
+ - No new endpoint, no config-shape change. (The spec's optional
79
+ `topicIntent.capture.decayProfiles` override is NOT built — decay profiles are
80
+ code constants for v1; the config override is a tracked refinement
81
+ <!-- tracked: cwa-decay-profile-config --> so the numbers can become operator-
82
+ tunable later without a code change.)
83
+
84
+ **Cost**: Zero new per-turn LLM calls — the task-frame extraction is folded into
85
+ the existing single fast-tier call (a slightly longer prompt). The whole loop
86
+ stays inside the rung-0 cost envelope (pre-filter + rate ceiling + LlmQueue cap +
87
+ QuotaTracker shedding).
88
+
89
+ **Migration parity**: Additive `RefKind` values (free-text-tolerant on read) +
90
+ per-kind decay constants (rung-0 kinds keep exact numbers) + additive
91
+ `refkind_created` (defaulted) + the briefing block + the new ArcCheck verdict.
92
+ Server-side — every agent gets it on update. No hook/template/skill/config-shape
93
+ change.
94
+
95
+ **Rollback cost**: Low, strictly additive. Revert: drop the task-frame prompt
96
+ guidance + the `contradicts-frame` rule + restore the single decay profile;
97
+ fact/decision behavior is untouched throughout. The rung-0 kill-switch
98
+ (`topicIntent.capture.enabled`) disables the whole loop including this.
99
+
100
+ **Convergence honesty**: Claude-authored + manual standards/lessons review only;
101
+ full `/spec-converge` + `/crossreview` multi-model tooling is absent on this host.
102
+ Ratified by Justin with that caveat explicit. The CI suite + the founding-incident
103
+ e2e are the strongest current evidence; a fuller multi-model review remains
104
+ advisable before relying on rung 1 in anger.