instar 1.3.455 → 1.3.457

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.
@@ -0,0 +1,45 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ Added Slice 2 of the dev-agent dark-gate conformance guard: a
9
+ `DEV_GATED_FEATURES` registry (`src/core/devGatedFeatures.ts`) and a both-sides
10
+ wiring test that applies the REAL config defaults and asserts each registered
11
+ dev-gated feature resolves LIVE under a `developmentAgent: true` config and DARK
12
+ under a fleet config. This catches the half of the #1001 bug that Slice 1's lint
13
+ can't see — a feature whose shipped default hardcodes `enabled: false` (so
14
+ `applyDefaults` injects it) now fails the build, because the feature would be dark
15
+ on dev agents. Seven features are registered; two (`mcpProcessReaper`,
16
+ `resourceLedger`) are deliberately excluded with documented reasons (intentionally
17
+ not dark-on-fleet).
18
+
19
+ ## What to Tell Your User
20
+
21
+ Nothing user-facing — internal developer/CI tooling (audience: agent-only). No
22
+ runtime behavior changes; it only adds a test that guards the dev-gate convention.
23
+
24
+ ## Summary of New Capabilities
25
+
26
+ - `DEV_GATED_FEATURES` registry + `getConfigByPath` (`src/core/devGatedFeatures.ts`).
27
+ - `tests/unit/devGatedFeatures-wiring.test.ts` — both-sides wiring test (+ a teeth
28
+ test proving it catches a planted `enabled: false` regression).
29
+ - Honest limit: Slice 3 (spec-intent cross-check) still catches the
30
+ forgot-the-gate-entirely case; tracked as CMT-1253. <!-- tracked: CMT-1253 -->
31
+
32
+ ## Evidence
33
+
34
+ This is a preventive CI guard, not a runtime bug fix — so "evidence" is a
35
+ demonstration that the guard has teeth on the #1001 mechanism:
36
+ - **Before (no guard):** a dev-gated feature whose shipped default hardcodes
37
+ `enabled: false` ships dark on dev agents undetected — exactly #1001, which was
38
+ caught only by operator review.
39
+ - **Reproduction (guard fires):** copied `src/config/ConfigDefaults.ts`, injected
40
+ `enabled: false` as the first field of the real `growthAnalyst` block, and ran
41
+ the both-sides test → the live-on-dev assertion **FAILS** (red). A baked-in
42
+ `enabled: true` would fail the dark-on-fleet assertion instead.
43
+ - **After (clean tree):** the unmodified tree → **16/16 green** (no registered
44
+ feature currently hardcodes a default). So the guard fires on the regression and
45
+ stays quiet otherwise.
@@ -0,0 +1,104 @@
1
+ # Side-Effects Review — Dev-Agent Dark-Gate Conformance Guard (Slice 1)
2
+
3
+ **Change:** Add a structural guard for the `developmentAgent` dark-feature gate
4
+ so a feature can't ship dark on dev agents by hand-rolling/forgetting the gate
5
+ (the PR #1001 miss). Slice 1:
6
+ - `src/core/devAgentGate.ts` — `resolveDevAgentGate(explicit, config)` funnel
7
+ (`explicit ?? !!config?.developmentAgent`).
8
+ - `scripts/lint-dev-agent-dark-gate.js` — assertion A (no hand-rolled
9
+ `?? !!<x>.developmentAgent` outside the funnel) + assertion B (no hardcoded
10
+ `enabled: false` under a dev-gate marker comment in `ConfigDefaults.ts`).
11
+ Wired into the `lint` npm script (Repo Invariants CI).
12
+ - Migrated the 11 existing hand-rolled sites in `src/server/AgentServer.ts`,
13
+ `src/commands/server.ts`, and `src/server/routes.ts` to the funnel
14
+ (behavior-identical). Assertion B is brace-matched on the config block (not a
15
+ fixed line window) — the fix for the convergence-review finding that a long
16
+ marker comment hid the growthAnalyst block from the original window.
17
+
18
+ **Files:**
19
+ - `src/core/devAgentGate.ts` (new), `tests/unit/devAgentGate.test.ts` (new, 8).
20
+ - `scripts/lint-dev-agent-dark-gate.js` (new), `tests/unit/lint-dev-agent-dark-gate.test.ts` (new, 7).
21
+ - `src/server/AgentServer.ts`, `src/commands/server.ts`, `src/server/routes.ts` — 11 call sites + imports.
22
+ - `scripts/lint-no-direct-destructive.js` — allowlist the new lint (reads
23
+ `git diff --cached` for `--staged`, same as its siblings).
24
+ - `package.json` — `lint` script + two convenience scripts.
25
+ - `tests/unit/growth-analyst-gate-wiring.test.ts`, `tests/unit/resource-sampler-wiring.test.ts`
26
+ — source-pattern assertions updated to the funnel form.
27
+ - `docs/specs/DEV-AGENT-DARK-GATE-CONFORMANCE-SPEC.md` (the design).
28
+
29
+ ## 1. Over-block — what legitimate inputs does this reject that it shouldn't?
30
+ Assertion A bans `?? !!<x>.developmentAgent` everywhere but the funnel. A future
31
+ legitimate need to read `config.developmentAgent` for a non-gate purpose (e.g.
32
+ logging which agent kind it is) would trip it. Mitigation: the regex requires the
33
+ `?? ` nullish-coalesce immediately before `.developmentAgent`, so a bare
34
+ `config.developmentAgent` read does NOT match — only the gate-resolution shape
35
+ does. Assertion B only fires on `enabled: false` in *code* lines within 8 lines
36
+ of a dev-gate marker comment in `ConfigDefaults.ts`; `enabled: true` (fleet-flip)
37
+ and comment prose are deliberately not flagged. Verified clean on the real tree
38
+ (the convention's own documentation does not trip it).
39
+
40
+ ## 2. Under-block — what failure modes does this still miss?
41
+ The honest, central limit (named in the spec's layer table): **a feature that
42
+ should be dev-gated but omits the gate entirely** is invisible to both
43
+ assertions — there is no `?? developmentAgent` to flag and no marker comment to
44
+ anchor on. That is exactly the #1001 *shape* (it had a hardcoded `enabled: false`
45
+ default and a `=== true` construction with no gate). Assertion B catches the
46
+ `enabled: false`-under-marker variant, but not a gate-less feature with no
47
+ marker. The layer that truly catches forgot-entirely is the both-sides wiring
48
+ test over a dev-gated-feature registry (Slice 2) and the spec-intent cross-check
49
+ (Slice 3) — explicitly deferred and tracked (CMT-1253), not silently skipped.
50
+
51
+ ## 3. Level-of-abstraction fit — right layer?
52
+ Yes. The funnel mirrors the established single-funnel pattern (SafeFsExecutor,
53
+ SafeGitExecutor); the lint joins the existing `lint-*` family run in Repo
54
+ Invariants. The guard lives in CI (the same layer that already enforces
55
+ no-direct-destructive, no-unfunneled-topic-creation, etc.), not in a prompt.
56
+
57
+ ## 4. Signal vs authority compliance (docs/signal-vs-authority.md)
58
+ The lint is AUTHORITY (it fails CI / blocks a commit) — appropriate, identical to
59
+ its lint siblings: a deterministic, mechanical invariant with a clear fix
60
+ message, not a judgment call. The runtime helper is pure and behavior-identical
61
+ to the code it replaces, so it holds no new authority over runtime behavior.
62
+
63
+ ## 5. Interactions — shadowing, double-fire, races?
64
+ None. The helper is a pure function with no state. The lint reads files only. The
65
+ migration is a mechanical rewrite (`X ?? !!c.developmentAgent` →
66
+ `resolveDevAgentGate(X, c)`) that `tsc --noEmit` confirms type-identical;
67
+ `resolveDevAgentGate` returns exactly `X ?? !!c?.developmentAgent`, so every
68
+ migrated gate resolves to the same boolean as before for all inputs.
69
+
70
+ ## 6. External surfaces — visible to other agents/users/systems?
71
+ None. No routes, no config, no agent-installed files, no Telegram. Purely
72
+ repo-internal source + CI. No Migration Parity entry needed (the spec's Migration
73
+ Parity section says so explicitly).
74
+
75
+ ## 7. Rollback cost — back-out if wrong?
76
+ Trivial and low-blast-radius. Revert the lint line in `package.json` to disable
77
+ the CI gate instantly; revert the migration commits to restore the hand-rolled
78
+ sites (behavior was never changed, so a revert is a no-op at runtime). No data,
79
+ no state, no deployed artifact to unwind.
80
+
81
+ ## No deferrals
82
+ Slices 2 (registry + both-sides wiring test) and 3 (spec-intent cross-check) are
83
+ NOT deferrals of this slice's scope — they are the explicitly-scoped follow-on
84
+ layers named in the spec and tracked as commitment CMT-1253, so the gap is
85
+ visible and re-surfaced, not dropped.
86
+
87
+ ## Second-pass review (independent)
88
+ **Done — via /spec-converge (5 internal reviewers, 2 iterations; report at
89
+ docs/specs/reports/dev-agent-dark-gate-conformance-convergence.md).** The
90
+ independent pass found three material issues that this change now fixes:
91
+ 1. **Assertion B silently no-op'd on its origin case.** The original fixed 8-line
92
+ window missed the real growthAnalyst block (its ~10-line marker comment pushed
93
+ the fields out of range) — empirically, an injected `enabled: false` reported
94
+ "clean." Fixed by brace-matching the block; re-tested: now caught, real tree
95
+ still clean.
96
+ 2. **An 11th un-migrated site + regex blind spot.** `routes.ts` used
97
+ `?? Boolean(ctx.config.developmentAgent)` — missed by the `!!`-only first pass
98
+ and unmatched by the lint. Migrated; regex broadened to `!!`/`Boolean(`/bracket.
99
+ 3. **Spec overclaim.** Softened "catches #1001 directly" → "when gate-marked" and
100
+ "only legal path" → "for the realistic spellings"; layer table now names the
101
+ alias/wrapper and markerless misses.
102
+ Round 2 (lessons-aware + adversarial) returned CONVERGED — no material findings.
103
+ Security and scalability reviewers found nothing material (fails safe toward
104
+ dark-on-fleet; ~0.3s scan, no regex backtracking).
@@ -0,0 +1,70 @@
1
+ # Side-Effects Review — Dev-Gated-Feature Registry + Both-Sides Wiring Test (Slice 2)
2
+
3
+ **Change:** Slice 2 of DEV-AGENT-DARK-GATE-CONFORMANCE-SPEC (the converged +
4
+ operator-approved spec). Adds the layer that catches a dev-gated feature wired to
5
+ resolve **dark on a dev agent** — the gap Slice 1's lint cannot see.
6
+
7
+ - `src/core/devGatedFeatures.ts` (new) — `DEV_GATED_FEATURES` registry (name +
8
+ config path + description) and a `getConfigByPath` reader.
9
+ - `tests/unit/devGatedFeatures-wiring.test.ts` (new) — for each registered
10
+ feature, applies the REAL `getMigrationDefaults` and asserts
11
+ `resolveDevAgentGate(<configPath>)` is **true** under a `developmentAgent: true`
12
+ config and **false** under a fleet config, plus a "teeth" test confirming an
13
+ injected `enabled: false` default fails the live-on-dev assertion (the literal
14
+ #1001 mechanism).
15
+
16
+ **Registry membership (the design decision in this slice):** only features whose
17
+ intent is "dark fleet / LIVE on dev" are included (growthAnalyst, coherenceJournal,
18
+ warmSessionA2A, secretSync, geminiLoopDriver, respawnBuildContext,
19
+ selfKnowledgeSessionContext — verified to omit `enabled` in defaults). Deliberately
20
+ EXCLUDED, with reasons in code: `monitoring.mcpProcessReaper` (destructive — ships
21
+ OFF + dry-run for everyone incl. dev by design) and `monitoring.resourceLedger`
22
+ (ledger defaults `enabled: true`; only sampling rides the gate off the same key).
23
+
24
+ ## 1. Over-block — what legitimate inputs does this reject that it shouldn't?
25
+ The test asserts every registered feature is live-on-dev / dark-on-fleet. A
26
+ feature that legitimately ships dark-everywhere or live-everywhere would fail if
27
+ wrongly added to the registry — but membership is a deliberate, reviewed choice
28
+ (the two non-conforming features are explicitly excluded with documented reasons),
29
+ so the test only constrains features that genuinely follow the convention.
30
+
31
+ ## 2. Under-block — what failure modes does this still miss?
32
+ Catches the hardcoded-default half of the #1001 shape (a `false` baked into the
33
+ feature's default → `applyDefaults` injects it → live-on-dev assertion fails) for
34
+ **registered** features. Still misses: (a) a dev-gated feature never added to the
35
+ registry; (b) the construction-side half where a site reads `enabled === true`
36
+ without any gate (no default to catch) — that is Slice 3's spec-intent cross-check.
37
+ Both limits are named in the spec's layer table.
38
+
39
+ ## 3. Level-of-abstraction fit — right layer?
40
+ Yes — a unit test over the real config-default assembly (`applyDefaults` +
41
+ `getMigrationDefaults`), the same path PostUpdateMigrator uses. It exercises the
42
+ actual default→gate resolution, not a source regex, so it catches the mechanism
43
+ rather than a spelling.
44
+
45
+ ## 4. Signal vs authority compliance
46
+ The test is CI authority (fails the build) over a deterministic, mechanical
47
+ property — same posture as the rest of the suite. The registry is inert data; it
48
+ holds no runtime authority (Slice 3 consumes it read-only).
49
+
50
+ ## 5. Interactions — shadowing, double-fire, races?
51
+ None. `devGatedFeatures.ts` is pure data + a pure path reader; the test builds
52
+ throwaway config objects. No shared state, no runtime wiring in this slice.
53
+
54
+ ## 6. External surfaces — visible to other agents/users/systems?
55
+ None. No routes, no config, no agent-installed files. Repo-internal source + test.
56
+ No Migration Parity entry needed.
57
+
58
+ ## 7. Rollback cost — back-out if wrong?
59
+ Trivial — delete the two files. No runtime behavior, no state, no deployed artifact.
60
+
61
+ ## No deferrals
62
+ Slice 3 (spec-intent cross-check) is the next slice of the same approved spec,
63
+ tracked under CMT-1253 — not a deferral of this slice's scope. <!-- tracked: CMT-1253 -->
64
+
65
+ ## Second-pass review (independent)
66
+ The registry membership was derived by auditing each `resolveDevAgentGate` site's
67
+ default against the convention: the 7 included features verified to omit `enabled`
68
+ (test green on all = no hidden hardcoded default); the 2 excluded features
69
+ (mcpProcessReaper, resourceLedger) inspected and confirmed intentionally NOT
70
+ dark-on-fleet. The teeth test confirms the guard fires on a planted regression.