instar 1.3.154 → 1.3.156

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 (38) hide show
  1. package/dist/config/ConfigDefaults.d.ts.map +1 -1
  2. package/dist/config/ConfigDefaults.js +4 -0
  3. package/dist/config/ConfigDefaults.js.map +1 -1
  4. package/dist/core/AutoUpdater.d.ts.map +1 -1
  5. package/dist/core/AutoUpdater.js +35 -19
  6. package/dist/core/AutoUpdater.js.map +1 -1
  7. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  8. package/dist/core/PostUpdateMigrator.js +14 -0
  9. package/dist/core/PostUpdateMigrator.js.map +1 -1
  10. package/dist/core/PreferencesManager.d.ts +19 -0
  11. package/dist/core/PreferencesManager.d.ts.map +1 -1
  12. package/dist/core/PreferencesManager.js +26 -8
  13. package/dist/core/PreferencesManager.js.map +1 -1
  14. package/dist/core/UpdateGate.d.ts +20 -0
  15. package/dist/core/UpdateGate.d.ts.map +1 -1
  16. package/dist/core/UpdateGate.js +52 -24
  17. package/dist/core/UpdateGate.js.map +1 -1
  18. package/dist/core/types.d.ts +10 -0
  19. package/dist/core/types.d.ts.map +1 -1
  20. package/dist/core/types.js.map +1 -1
  21. package/dist/monitoring/SelfViolationDetector.d.ts +61 -0
  22. package/dist/monitoring/SelfViolationDetector.d.ts.map +1 -0
  23. package/dist/monitoring/SelfViolationDetector.js +153 -0
  24. package/dist/monitoring/SelfViolationDetector.js.map +1 -0
  25. package/dist/scaffold/templates.d.ts.map +1 -1
  26. package/dist/scaffold/templates.js +1 -0
  27. package/dist/scaffold/templates.js.map +1 -1
  28. package/dist/server/routes.d.ts.map +1 -1
  29. package/dist/server/routes.js +89 -1
  30. package/dist/server/routes.js.map +1 -1
  31. package/package.json +1 -1
  32. package/src/data/builtin-manifest.json +63 -63
  33. package/src/scaffold/templates.ts +1 -0
  34. package/upgrades/1.3.142.md +32 -9
  35. package/upgrades/1.3.155.md +26 -0
  36. package/upgrades/1.3.156.md +24 -0
  37. package/upgrades/side-effects/correction-self-violation-signal.md +133 -0
  38. package/upgrades/side-effects/restart-when-idle.md +51 -0
@@ -0,0 +1,26 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: minor -->
5
+
6
+ ## What Changed
7
+
8
+ **A stored preference that gets violated now becomes a learning signal (dark).** This extends the Correction & Preference Learning Sentinel. A learned preference — for example, "don't defer work to a fresh session" or "never ask the user to edit files" — can now carry an optional self-violation pattern. When the agent emits an outbound message that contradicts such a preference, that is recorded as a self-violation in the correction ledger, which reinforces the preference's recurrence so it surfaces more prominently the next session.
9
+
10
+ It is signal-only: the detector observes the finalized outbound message and records — it can never block, delay, or rewrite a message. It is fail-open (any detector error silently no-ops and delivery is unaffected) and dark (gated behind both the master correction-learning flag and a new self-violation sub-flag). A preference without a self-violation pattern is never checked, so existing preference files are fully backward compatible.
11
+
12
+ ## What to Tell Your User
13
+
14
+ The correction-learning system can now notice when the agent's own outgoing message contradicts a preference it has already learned about how you like to work, and quietly use that as a signal to remember the preference more strongly next time. It only ever observes and records — it never blocks, delays, or changes a message — and it stays off until explicitly turned on.
15
+
16
+ ## Summary of New Capabilities
17
+
18
+ - New `src/monitoring/SelfViolationDetector.ts` — pure, deterministic `detectSelfViolation`; precision-biased (a lone weak keyword never fires), never throws.
19
+ - `PreferencesManager` preference records gain an optional `violationPattern` (regex or keyword grammar); fully backward compatible.
20
+ - Observe-only outbound hook in `checkOutboundMessage` records self-violations to the `CorrectionLedger`; structurally independent of the tone-gate verdict and of the message itself.
21
+ - New `monitoring.correctionLearning.selfViolationSignal` config flag (default false).
22
+
23
+ ## Evidence
24
+
25
+ - `SelfViolationDetector` unit (17), self-violation wiring-integrity (5, asserts the outbound message passes through byte-for-byte unchanged and the detector fail-opens), integration (5), and E2E lifecycle (3) — all passed.
26
+ - `npm run build` / `npm run lint` / `docs-coverage` clean.
@@ -0,0 +1,24 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What to Tell Your User
7
+
8
+ If you set an overnight restart window, your agent no longer sits on a downloaded update all day when nothing is going on. It updates right away while idle, and still waits for the window whenever you actually have work in progress — so updates land sooner without ever interrupting you.
9
+
10
+ ## Summary of New Capabilities
11
+
12
+ - The restart-window gate now consults a pure, side-effect-free session probe before deferring: idle (no active sessions) restarts immediately outside the window; active sessions defer to the window as before. The deferral record now also names the blocking sessions instead of leaving them blank.
13
+
14
+ ## Evidence
15
+
16
+ - Unit (UpdateGate): the new idle probe returns active session names, ignores idle background jobs, and — critically — does NOT start the deferral clock or set warning state (proven by a purity test); its classification is asserted identical to the restart gate so the two can never drift.
17
+ - Unit (restart-window): outside the window with an active session still defers; outside the window while idle restarts immediately. Both decision-boundary sides covered.
18
+ - The existing restart gate logic is byte-for-byte unchanged (extracted into a shared classifier); the cascade-dampener integration tests stay green.
19
+
20
+ ## What Changed — Idle agents apply update-restarts immediately instead of waiting for the restart window
21
+
22
+ Agents can set a restart window (e.g. 02:00–05:00) so update-restarts only happen overnight and never interrupt active work. But the window was applied unconditionally: even when the agent was completely idle — no active session, nothing to protect — a downloaded update would sit unapplied for hours until the window opened. The agent ran a stale version all day for no reason.
23
+
24
+ Now the window only holds a restart when there is active work to protect. If the agent is idle when an update lands outside the window, it restarts right away (an idle restart is invisible — it is exactly what already happens for idle agents inside the window). The moment any session is active, the window is honored exactly as before and the restart waits.
@@ -0,0 +1,133 @@
1
+ # Side-Effects Review — Correction & Preference Learning: Self-Violation Signal
2
+
3
+ **Version / slug:** `correction-self-violation-signal`
4
+ **Date:** `2026-05-31`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `not required — observe-only + dark by default; the detector holds no blocking authority and cannot alter/delay/block any outbound message`
7
+
8
+ ## Summary of the change
9
+
10
+ Extends the shipped Correction & Preference Learning Sentinel so a stored-but-violated
11
+ preference becomes a learning signal instead of evaporating. A learned preference can
12
+ carry an OPTIONAL `violationPattern` (regex or keyword set). When the agent sends an
13
+ outbound message that contradicts that pattern, the contradiction is recorded as a
14
+ self-violation in the `CorrectionLedger` (a recurrence-reinforcing `user-preference`
15
+ occurrence keyed on the violated lesson), so the preference's salience grows for the
16
+ next session-start injection.
17
+
18
+ Files: new `src/monitoring/SelfViolationDetector.ts` (pure `detectSelfViolation`);
19
+ `src/core/PreferencesManager.ts` (+optional `violationPattern` on `PreferenceEntry`
20
+ and `RecordPreferencePayload`, persisted/round-tripped, upsert-preserving); the
21
+ outbound seam in `src/server/routes.ts` (a new OBSERVE-ONLY `observeSelfViolation`
22
+ fire-and-forget branch inside `checkOutboundMessage`, structurally independent of the
23
+ tone-gate verdict); config `monitoring.correctionLearning.selfViolationSignal`
24
+ (types.ts + ConfigDefaults.ts); Agent-Awareness (templates.ts) + Migration-Parity
25
+ backfill (PostUpdateMigrator migrateClaudeMd).
26
+
27
+ ## Decision-point inventory
28
+
29
+ - `detectSelfViolation(text, prefs)` (new) — add — pure, deterministic, returns the
30
+ list of violated preferences. No authority; precision-biased (lone weak match never
31
+ fires); never throws.
32
+ - `observeSelfViolation` seam branch (new) — add — records a matched violation to the
33
+ ledger + an audit line. Fire-and-forget VOID; cannot influence delivery.
34
+ - `PreferenceEntry.violationPattern` (new optional field) — add — absent ≡ never
35
+ checked (back-compat).
36
+ - Tone-gate / `checkOutboundMessage` block-decision — UNCHANGED — the observe branch
37
+ runs before the gate-availability early-return and never feeds the gate or the
38
+ return value.
39
+
40
+ ---
41
+
42
+ ## 1. Over-block
43
+
44
+ Not applicable. The feature has NO block/allow surface. The observe branch runs as a
45
+ fire-and-forget `void observeSelfViolation(...).catch(...)` that is structurally
46
+ incapable of returning a block verdict, throwing into the delivery frame, or mutating
47
+ the message. The wiring-integrity + E2E tests assert the message is delivered
48
+ byte-for-byte unchanged whether or not a violation is detected.
49
+
50
+ ## 2. Under-block
51
+
52
+ There is nothing to under-block — the feature never blocks. The "miss" direction
53
+ (a real self-violation going unrecorded) is the deliberately-chosen safe direction:
54
+ precision over recall. A lone/weak keyword never fires, an unparseable pattern is a
55
+ no-check, and a preference without a `violationPattern` is skipped. A false
56
+ self-violation that nags is the bad direction, so the matcher is conservative. A
57
+ missed recording costs only a slightly weaker recurrence signal next session.
58
+
59
+ ## 3. Level-of-abstraction fit
60
+
61
+ Correct. The detector is a pure, exhaustively-tested function (mirrors the
62
+ deterministic `scrubSecrets` / Layer-0 classifier discipline of the same sentinel).
63
+ The recording reuses the shipped `CorrectionLedger.record()` dedupe-upsert and its
64
+ `toApiView()` raw-text-stripping discipline; the occurrence is a `user-preference`
65
+ record at the code-determined `LEARNING_DETERMINISTIC_THRESHOLD` so it feeds the
66
+ existing 3-pronged recurrence gate exactly like any other distilled correction. No
67
+ new persistence layer, no new gate, no new authority.
68
+
69
+ ## 4. Signal vs authority compliance
70
+
71
+ **Required reference:** [docs/signal-vs-authority.md](../../docs/signal-vs-authority.md)
72
+
73
+ - [x] Yes — this change produces a SIGNAL (a ledger occurrence + an audit line) and
74
+ holds ZERO authority over any message. The user's explicit hard rule ("we've been
75
+ bitten by guards that block messages having too much power") is honored structurally:
76
+ the observe call is a separate VOID branch that runs regardless of the
77
+ `MessagingToneGate`'s verdict and never influences it. The single authority for
78
+ outbound delivery remains the `MessagingToneGate` (rules B1–B17), entirely unchanged.
79
+
80
+ ## 5. Interactions
81
+
82
+ - **Shadowing:** none. The observe branch is additive at the top of
83
+ `checkOutboundMessage`; it does not read or alter the signals, the gate result, or
84
+ the 422 path. With the tone gate null, the observe branch still runs (it precedes
85
+ the gate-availability early-return) and the message still passes through.
86
+ - **Double-fire:** the ledger dedupe-upserts on `kind:normalizedLearningHash`, so
87
+ repeated self-violations of the same preference collapse to ONE record with an
88
+ incrementing `occurrenceCount` (asserted by the integration test) — never a pile.
89
+ - **Races:** the observe call is fire-and-forget and lazy-imports its modules; the
90
+ ledger is the shipped WAL SQLite store (single-writer-safe, fail-open on any error).
91
+ Two concurrent sends recording the same preference are both safely upserted.
92
+ - **Feedback loops:** none. The detector reads `.instar/preferences.json` (written by
93
+ `recordPreference`) and writes the ledger; it never writes preferences, so it cannot
94
+ amplify its own pattern. The CorrectionAnalyzer that consumes the ledger is
95
+ off-hot-path (weekly cron) and only ROUTES via the existing by-construction
96
+ authority-bounded driver.
97
+
98
+ ## 6. External surfaces
99
+
100
+ - **Other agents / install base:** pure additive source + a default-OFF config
101
+ sub-flag (auto-applied via ConfigDefaults; code reads `cl?.selfViolationSignal !==
102
+ true` so an agent whose config lacks the field behaves identically — OFF). The
103
+ optional `violationPattern` is fully back-compatible: shipped `.instar/preferences.json`
104
+ files have no such field and are simply never self-violation-checked (unit-tested
105
+ with a legacy-shaped file). Agent-Awareness + Migration-Parity are handled
106
+ (templates.ts bullet for new agents; idempotent content-sniffed migrateClaudeMd
107
+ backfill for existing agents).
108
+ - **External systems:** none. The detector is local + deterministic; no LLM call, no
109
+ network. (Distinct from the capture/distill loop, which is a separate, already-shipped
110
+ surface.)
111
+ - **Persistent state:** existing `correction-ledger.db` only (one extra occurrence
112
+ row per matched violation, bounded by the shipped per-key occurrence cap). Plus a
113
+ best-effort `[self-violation]` stderr audit line. No new files.
114
+ - **Timing:** none. No timers; the observe call is one bounded synchronous detect plus
115
+ one ledger write, off the delivery path.
116
+
117
+ ## 7. Rollback cost
118
+
119
+ Pure additive code + a default-off config sub-flag. Revert the commits → the detector,
120
+ the seam branch, the schema field, the config flag, and the awareness text disappear;
121
+ nothing else changes. Any ledger occurrences already recorded are inert and indexed
122
+ exactly like every other correction record (no schema change to the ledger). No
123
+ migration, no state repair, no user-visible behavior change (it never acted on a
124
+ message).
125
+
126
+ ## Conclusion
127
+
128
+ This review confirmed the change is observe-only: a tested, precision-biased,
129
+ never-throwing decision function plus a fire-and-forget recording branch that is
130
+ structurally incapable of blocking, delaying, or altering any outbound message. It
131
+ ships dark behind both `correctionLearning.enabled` and the new `selfViolationSignal`
132
+ sub-flag, is fully back-compatible with existing preference files, and reuses the
133
+ shipped ledger's privacy + dedupe discipline. Clear to ship.
@@ -0,0 +1,51 @@
1
+ # Side-effects — Restart-when-idle (restart-window idle bypass)
2
+
3
+ ## 1. What files/state does this touch at runtime?
4
+ `AutoUpdater.gatedRestart()` and `UpdateGate`. No new files, no config keys, no schema, no
5
+ persisted state added. The deferral record written on an *active* deferral now carries the actual
6
+ blocking session names (previously `[]`) — same record, richer field.
7
+
8
+ ## 2. Does it change any functional behavior?
9
+ - **Agents with NO restart window configured:** none. `isInRestartWindow()` returns true when no
10
+ window is set, so the window gate is never entered.
11
+ - **Agents WITH a restart window, while ACTIVE (a healthy session running):** none — still defers
12
+ to the window exactly as before.
13
+ - **Agents WITH a restart window, while IDLE (no active sessions):** an update that lands outside
14
+ the window now restarts immediately instead of waiting hours for the window. The restart is the
15
+ same idle silent-restart the in-window path already performs.
16
+
17
+ ## 3. What happens on failure / weird config?
18
+ The probe is best-effort and read-only. If no `sessionManager` is wired, the window gate treats it
19
+ as idle and falls through to the existing "no session manager → silent restart" path one block
20
+ down (consistent semantics). `getBlockingSessions` returns `[]` for zero sessions. No throw path
21
+ added.
22
+
23
+ ## 4. Migration parity — do existing agents get it?
24
+ Yes, via the normal release — it is a **code-only** change compiled into `dist`. No
25
+ `PostUpdateMigrator` pass is needed because no agent-installed file (hook/skill/config/CLAUDE.md
26
+ template) changes. Existing agents pick it up when they update to this version.
27
+
28
+ ## 5. Could it spam / flood / burn resources?
29
+ No. It adds one in-memory session classification (a list walk already done by `canRestart`) per
30
+ restart attempt. No new timers, no new I/O, no new network calls. If anything it *reduces* work by
31
+ skipping the deferral-timer scheduling on idle boxes.
32
+
33
+ ## 6. Rollback / off-switch?
34
+ Revert the PR. The behavior is always-on (no flag) — idle restarts are inherently safe (they are
35
+ what idle agents already get inside the window), so the change is strictly a latency improvement.
36
+ A user who wants strict window-only behavior even while idle would need the reverted code; this is
37
+ documented as a deliberate trade-off, not an oversight.
38
+
39
+ ## 7. Concurrency / ordering?
40
+ None new. The idle probe (`getBlockingSessions`) is pure and side-effect-free — crucially it does
41
+ NOT start or continue `UpdateGate`'s deferral clock or set warning flags (a dedicated purity unit
42
+ test guards this). The real restart guard remains the `canRestart()` call at the session gate,
43
+ which runs after the window gate; a session that becomes active between the two checks is caught
44
+ there and deferred.
45
+
46
+ ## Blast radius
47
+ Small + additive. One conditional at the window gate in `AutoUpdater.ts` + one pure method
48
+ (`getBlockingSessions`) plus a behavior-preserving extraction (`classifyRunningSessions`) in
49
+ `UpdateGate.ts`. The existing restart gate (`canRestart`) is byte-for-byte unchanged and its
50
+ regression tests (cascade-dampener) stay green. Only affects agents that have a restart window
51
+ configured AND are idle when an update lands outside it.