instar 1.3.660 → 1.3.662
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/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +6 -1
- package/dist/commands/server.js.map +1 -1
- package/dist/core/MessagingToneGate.d.ts +124 -1
- package/dist/core/MessagingToneGate.d.ts.map +1 -1
- package/dist/core/MessagingToneGate.js +262 -87
- package/dist/core/MessagingToneGate.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +16 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +4 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/outboundGateBudget.d.ts +1 -1
- package/dist/server/outboundGateBudget.d.ts.map +1 -1
- package/dist/server/outboundGateBudget.js +19 -1
- package/dist/server/outboundGateBudget.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +40 -1
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +63 -63
- package/src/scaffold/templates.ts +4 -0
- package/upgrades/{1.3.660.md → 1.3.661.md} +43 -0
- package/upgrades/1.3.662.md +30 -0
- package/upgrades/side-effects/blindspot-class-symbol-vs-state.md +41 -0
- package/upgrades/side-effects/gate-prompts-judge-by-meaning.md +48 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
The outbound tone gate's behavioral rules (B15–B18 — the "don't quit on yourself / don't call a doable thing impossible / don't park your work on the user" rules) now judge by **meaning**, not by matching a fixed list of literal phrases. Previously B15's prompt told the LLM to block only if the message contained an exact phrase from a list, so a reworded self-stop ("fresh focus, not tired at the tail of a long run") walked straight through. The rule now states the *intent* and judges any paraphrase, with an explicit reason-gate (the agent-state reason is controlling; every carve-out is subordinate to it) and a structured-intermediate the model fills so the verdict is derived from its own reasoning.
|
|
9
|
+
|
|
10
|
+
Alongside it:
|
|
11
|
+
- A new constitution standard, **"Intelligent Prompts — An LLM Gate Must Not String-Match"** (`docs/STANDARDS-REGISTRY.md`), enforced by a forward CI ratchet (`tests/unit/gate-prompts-judge-by-meaning.test.ts`) keyed off a machine-readable `RULE_CLASSES` registry.
|
|
12
|
+
- A deterministic **agent-state signal** (the session clock) fed into B15 so a "near the limit" claim is judged against ground truth (time-box claims only).
|
|
13
|
+
- The gate now **fails CLOSED** (holds the message — never silently delivers) on every no-verdict path: an invalid/empty rule citation (re-prompt then hold), unparseable output (retry then hold), provider exhaustion, and the route-budget slow-timeout (the easiest bypass). Operator kill-switch: `messaging.toneGate.failClosedOnExhaustion` (default true).
|
|
14
|
+
- B1–B7 (literal-artifact detectors) keep matching in-prompt for now — tracked migration to detect-outside-feed-signal is CMT-1793; the codebase-wide convergent audit of the two standards is CMT-1794.
|
|
15
|
+
|
|
16
|
+
## What to Tell Your User
|
|
17
|
+
|
|
18
|
+
Your messages still pass the same outbound safety gate — it's just smarter now. It catches the "I'll pick this up fresh later" self-stop pattern however it's worded, instead of only when an exact phrase appears, and it holds (rather than silently sends) a message if the gate can't reach a verdict. Nothing you do changes; the gate is more reliable.
|
|
19
|
+
|
|
20
|
+
## Summary of New Capabilities
|
|
21
|
+
|
|
22
|
+
- Constitution standard "Intelligent Prompts — An LLM Gate Must Not String-Match" + its CI ratchet.
|
|
23
|
+
- Config: `messaging.toneGate.failClosedOnExhaustion` (default true) — kill-switch to revert the exhaustion/timeout paths to fail-open without a deploy.
|
|
24
|
+
- The outbound tone gate now judges its behavioral rules by meaning and fails closed on any no-verdict path.
|
|
25
|
+
|
|
26
|
+
## Evidence
|
|
27
|
+
|
|
28
|
+
- New + updated tests, all green: the ratchet (8), the reason-gate / structured-intermediate / agentState (15), budget fail-closed (1 new), awareness migration (2), updated existing tone-gate suites (B15/B16/B17/B18/health-alerts/MessagingToneGate, 131), and the route-level integration test (4: paraphrased-incident suppressed, structured-derivation suppressed, fail-closed-holds end-to-end, completion delivers). `npx tsc --noEmit` clean (0 errors).
|
|
29
|
+
- 5-round spec-converge + closing cross-model pass; the Standards-Conformance Gate returns 0 findings on the spec. Convergence report: `docs/specs/reports/gate-prompts-judge-by-meaning-not-literal-lists-convergence.md`.
|
|
30
|
+
- Side-effects review (8 questions + Phase-5 second-pass): `upgrades/side-effects/gate-prompts-judge-by-meaning.md`.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Side-Effects Review — Verify the State, Not Its Symbol (constitution amendment)
|
|
2
|
+
|
|
3
|
+
**Change:** Documentation-only. Adds the constitutional standard "Verify the State, Not Its
|
|
4
|
+
Symbol" to `docs/STANDARDS-REGISTRY.md` (Substrate section), registers it as **P20** in
|
|
5
|
+
`docs/INSTAR-DESIGN-PRINCIPLES-AND-LESSONS.md` (the surface the `/spec-converge` lessons-aware
|
|
6
|
+
reviewer loads), re-points L5 to P20 as its parent, updates the Part-4 reviewer range to P1-P20,
|
|
7
|
+
and lands the supporting analysis spec + ELI16. **No runtime/`src` surface.** Operator-ratified
|
|
8
|
+
(Justin, topic 16566, 2026-06-24) after independent verification that it is a real gap.
|
|
9
|
+
|
|
10
|
+
1. **Over-block** — None. No code path, gate, or filter changes; nothing new can reject input.
|
|
11
|
+
The only behavioral effect is additive: the spec-converge reviewer gains one more lens (P20)
|
|
12
|
+
to flag a future spec — advisory findings, never a hard block of runtime behavior.
|
|
13
|
+
2. **Under-block** — The standard is enforced today only via the lessons-aware reviewer (advisory)
|
|
14
|
+
+ the companion code fix (the crystallizing instance). The `no-uncorroborated-symbol-fire` CI
|
|
15
|
+
ratchet that would mechanically catch *new* violating callsites is named as the next enforcement
|
|
16
|
+
surface, not yet built — so a brittle detector added between now and that ratchet relies on the
|
|
17
|
+
reviewer catching it. Stated honestly in the standard's "Applied through", not hidden.
|
|
18
|
+
3. **Level-of-abstraction fit** — Correct layer. It is a Substrate (model-level truth) standard, a
|
|
19
|
+
parent of the existing L5 lesson and the AUP-wedge note; placed beside its siblings
|
|
20
|
+
(No Silent Degradation, Distrust Temporary Success) and registered in the same P-catalog the
|
|
21
|
+
reviewer already consumes. No new abstraction invented.
|
|
22
|
+
4. **Signal vs authority (P2)** — Compliant and explicitly differentiated: the standard's text
|
|
23
|
+
states it is *orthogonal* to Signal-vs-Authority (which governs who may BLOCK) — it governs the
|
|
24
|
+
*evidentiary correctness* a detector must have whether it is a signal-emitter or a gate. The
|
|
25
|
+
amendment itself holds no authority; it is documentation feeding an advisory reviewer.
|
|
26
|
+
5. **Interactions** — Touches the shared P-catalog: P18/P19 already existed, so the new entry is
|
|
27
|
+
**P20** (verified free) and the Part-4 range bumped P1-P19 → P1-P20. L5 gains a parent pointer.
|
|
28
|
+
No collision with the unrelated registry "No Unbounded Loops" P19 reference (left intact). No
|
|
29
|
+
migration surface (these docs are not agent-installed files; Migration Parity N/A).
|
|
30
|
+
6. **External surfaces** — None. Internal developer-facing docs only; no user/agent/API surface,
|
|
31
|
+
no template (`generateClaudeMd`) change, no config, no hook.
|
|
32
|
+
7. **Multi-machine posture** — N/A (documentation). The standard it describes is, for detectors,
|
|
33
|
+
machine-local-by-design (each machine verifies its own sessions) — captured in the companion
|
|
34
|
+
fix's own side-effects review, not here.
|
|
35
|
+
8. **Rollback cost** — Trivial: revert the doc commit. No data, no state, no deployed behavior to
|
|
36
|
+
unwind. The companion code fix ships and rolls back independently on its own branch.
|
|
37
|
+
|
|
38
|
+
**Second-pass review:** Not required — documentation-only, no block/allow decision, no session
|
|
39
|
+
lifecycle, no gate/sentinel/watchdog code. (The companion CODE fix
|
|
40
|
+
`ratelimit-sentinel-false-positive-hardening`, which DOES touch sentinels, carries its own
|
|
41
|
+
mandatory Phase-5 second-pass on its own branch.)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Side-Effects Review — gate-prompts-judge-by-meaning-not-literal-lists
|
|
2
|
+
|
|
3
|
+
**Change:** Make the outbound tone gate's behavioral rules (B15–B18) judge by MEANING, not by literal-phrase presence; author the new constitution standard "Intelligent Prompts — An LLM Gate Must Not String-Match" with a CI ratchet; feed a deterministic agent-state (session-clock) signal into B15; and flip every gating no-verdict path to FAIL-CLOSED (invalid-rule, JSON-parse, provider-exhaustion, route-budget timeout) with an operator kill-switch.
|
|
4
|
+
|
|
5
|
+
**Spec:** docs/specs/gate-prompts-judge-by-meaning-not-literal-lists.md (review-convergence + approved:true). ELI16 + convergence report shipped.
|
|
6
|
+
|
|
7
|
+
**Signal-vs-Authority (Phase 1):** This IS a decision point (the outbound gate). The change is the *purest application* of Signal-vs-Authority — it removes brittle string-matching authority from the LLM's own prompt and routes deterministic detection through signals (B8/B9/B12 pattern), letting the full-context mind judge. No brittle check gains blocking authority; the CI ratchet is a signal-only developer-loop guard (fails CI, makes no runtime decision).
|
|
8
|
+
|
|
9
|
+
## The 8 questions
|
|
10
|
+
|
|
11
|
+
1. **Over-block** — Meaning-based judgment could over-block honest status disclosure ("at 95% context, continuing"). MITIGATED structurally: §Design 1 step 1 makes "a stop is ACTUALLY proposed" the hard precondition (mention ≠ stop → PASS), and step 4b scopes the freshness tell to agent-fatigue framing (external-dependency timing passes). Both have explicit PASS fixtures. An over-block is also self-correcting (the agent gets the reason + rephrases).
|
|
12
|
+
2. **Under-block** — A sufficiently sophisticated semantic rewrite of a *literal-gate construction* could evade the CI ratchet (documented honest limit; human review of judgment-prompt changes still required). At runtime, the meaning-based gate is strictly *harder* to evade than the old literal list. B1–B7 still literal-match in-prompt (tracked debt CMT-1793).
|
|
13
|
+
3. **Level-of-abstraction fit** — Correct layer: the deterministic detectors (dangerous-command/free-text floors, jargon/junk signals, the new session-clock signal) live OUTSIDE the prompt and feed it; the LLM judges. This is the architecture the new standard mandates. B1–B7's in-prompt matching is the one not-yet-migrated spot (CMT-1793).
|
|
14
|
+
4. **Signal vs authority compliance** — Compliant by construction (see Phase 1). The ratchet enforces it forward.
|
|
15
|
+
5. **Interactions** — The fail-closed change interacts with: the capacity-shed sibling path (now consistent — both hold), the route-budget fail-open (now opt-in fail-closed via the kill-switch), and the `no-silent-llm-fallback` ratchet (gate already satisfies it via `gating:true`; no REVIEWED_ADVISORY edit — asserted by a test). The structured-intermediate is back-compat: absent block ⇒ legacy path unchanged. The agentState signal is fail-open-skip on error (never blocks an outbound).
|
|
16
|
+
6. **External surfaces** — The gate's blocking verdict is user-visible. A new config key `messaging.toneGate.failClosedOnExhaustion` (default true). A new CLAUDE.md section (+ framework-shadow mirror to AGENTS.md/GEMINI.md). The new STANDARDS-REGISTRY standard. No new HTTP route. The fail-closed direction means a *total LLM outage* holds `/telegram/reply` outbound (held-not-lost, retried) — system/lifeline/post-update sends use separate routes and are unaffected.
|
|
17
|
+
7. **Multi-machine posture** — **REPLICATED.** The prompt is rebuilt from source on every review; the provider is stateless; the ratchet + standard ship compiled. The agentState signal reads local topic-bound clock on the serving machine (where the gate already runs, pre-adapter). The CLAUDE.md/shadow awareness note rides normal per-machine migration (converges as each machine updates). No machine-local state affects the verdict. Uniform by construction.
|
|
18
|
+
8. **Rollback cost** — Prompt revert is a one-file `git revert`. The fail-closed flips are independently revertable per return path, AND the provider-exhaustion + slow-timeout paths carry a live operator kill-switch (`failClosedOnExhaustion:false`) — revertable without a deploy (mobile-first). The CI ratchet is removable by deleting the test.
|
|
19
|
+
|
|
20
|
+
## Tracked follow-ups (no orphan deferrals)
|
|
21
|
+
- B1–B7 detect-outside-feed-signal migration — CMT-1793 (frozen PHASE2_MIGRATION_DEBT allowlist + stale-allowlist test).
|
|
22
|
+
- Availability-aware kind-routing + codebase-wide gating-fail-open sweep — CMT-1794 (DEFERRED_REFINEMENT, non-placeholder-commitment-pinned).
|
|
23
|
+
- Dedicated production-init E2E ("gate alive") + the live Playwright-Telegram channel proof — driven by the orchestrating session before merge (the integration tier already exercises the real route + real gate end-to-end).
|
|
24
|
+
|
|
25
|
+
## Phase 5 — Second-pass review (high-risk: gate/sentinel/outbound-block)
|
|
26
|
+
|
|
27
|
+
Independent re-audit (performed inline by the build fork, which cannot spawn a subagent):
|
|
28
|
+
|
|
29
|
+
- **Fail-closed availability:** Verified system/lifeline/`post-update` sends use SEPARATE routes (`routes.ts:10430`), so failing closed at the `/telegram/reply` seam only holds conversational + automated traffic during a *total* outage — held-not-lost, kill-switch-revertable. Sound.
|
|
30
|
+
- **Structured-derivation safety:** The derivation only ever makes the verdict MORE conservative (derives a BLOCK from the model's own structured reasoning); it never flips a block to a pass. A contradictory structured verdict re-prompts then holds. Sound.
|
|
31
|
+
- **Back-compat:** A response with no `structured` block follows the exact legacy path (verified by an explicit test). Existing callers (`new MessagingToneGate(provider)`) compile unchanged (config optional). Sound.
|
|
32
|
+
- **Ratchet brittleness:** The ratchet keys off the machine-readable RULE_CLASSES registry (not prose), checks both boundary directions, fails closed on an unclassified rule, and has a negative test proving it catches a reworded construction. Its honest limit is documented in the standard + the test header. Sound.
|
|
33
|
+
- **Concern raised + resolved:** the re-prompt doubles provider calls on a discipline-failure branch — bounded to ONE extra call, only on the rare wanted-block-mis-cited / unparseable / contradictory branch, inside the existing route budget, and the error path collapses to hold (no back-door into the deferred fail-open). Acceptable.
|
|
34
|
+
|
|
35
|
+
**Verdict: Concur with the review.** No blocking concern. The change strengthens the gate and is compliant with Signal-vs-Authority and No Silent Degradation.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Follow-up — CI failure fixes (post-merge-prep, 2026-06-25)
|
|
40
|
+
|
|
41
|
+
The first implementation commit (cb2ac82dd) left 4 CI checks red. Root causes + fixes (all verified green locally: the 4 named test files = 123 tests passing; tone-gate regression sweep b15/b16/b17 + attention + MessagingToneGate = 42 passing):
|
|
42
|
+
|
|
43
|
+
1. **`post-update-gate-budget-route:101` (422 vs 200) — a real design correction.** The §6 review above ASSUMED `/telegram/post-update` "uses separate routes and is unaffected" by the slow-timeout fail-closed flip. **That assumption was wrong:** `/telegram/post-update` (routes.ts ~10467) calls `checkOutboundMessage` → `evaluateOutbound` → the tone gate, exactly like `/telegram/reply`. So the global slow-timeout fail-closed flip ALSO held post-update (an automated, fixed-template "I'm back up"/release channel), which must stay available. Fix: the slow-review timeout fail-closed is now **per-call**, defaulting CLOSED (the safe direction; conversational `/telegram/reply` keeps failing closed unchanged), with `/telegram/post-update` passing `failClosedOnBudgetTimeout:false` to fail OPEN on the *no-verdict-in-time* path only. A fast real BLOCK still holds post-update; only the slow path delivers. Default-closed (not the originally-sketched default-open opt-in) so a NEW conversational caller is safe-by-construction and cannot silently regress to fail-open. Still also gated by the global `failClosedOnExhaustion` kill-switch.
|
|
44
|
+
2. **`feature-delivery-completeness:327` — parity tracking.** The new `### Outbound Message Gate` CLAUDE.md section (added to templates.ts + the migrator) was not yet listed in the test's tracked `featureSections`, so the migrator-vs-template parity check failed. Fix: add the section marker to the tracked list (the migrator already emits it in both `migrateClaudeMd` and the framework-shadow markers).
|
|
45
|
+
3. **`spawn-cap-fail-closed-gates:93` (test 3b) — obsolete contract.** That test (forkbomb-prevention spec) asserted the tone gate fails OPEN on a generic provider error. §Design 6 of THIS spec deliberately flipped the provider-exhaustion path to fail CLOSED. Fix: updated 3b to assert `pass:false, failedClosed:true` (with a comment recording the cross-spec contract change). The sentinel/input-guard generic-error paths (1b/2b) remain fail-open — only the outbound tone gate changed.
|
|
46
|
+
4. **`provider-fallback-default-policy-lifecycle:151` — same obsolete contract.** Asserted the tone gate fails OPEN when the provider swap-chain is exhausted. Updated to assert fail CLOSED (`failedClosed:true, pass:false`), preserving the test's actual wiring-integrity intent (the router re-throws to the caller; the caller's now-fail-closed policy decides).
|
|
47
|
+
|
|
48
|
+
**Side-effects of the follow-up:** only `/telegram/post-update`'s no-verdict-in-time outcome changes (hold→deliver); every other caller's behavior is unchanged (default-closed). No new config, route, or persistent state. Rollback = revert the routes.ts hunk; the global kill-switch remains.
|