instar 1.3.1647 → 1.3.1649

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 (116) hide show
  1. package/dashboard/console/console.css +3 -0
  2. package/dashboard/console/maturation-board-model.js +51 -0
  3. package/dashboard/console/maturation-board.js +17 -1
  4. package/dist/commands/server.d.ts.map +1 -1
  5. package/dist/commands/server.js +20 -0
  6. package/dist/commands/server.js.map +1 -1
  7. package/dist/core/PostUpdateMigrator.d.ts +5 -0
  8. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  9. package/dist/core/PostUpdateMigrator.js +24 -0
  10. package/dist/core/PostUpdateMigrator.js.map +1 -1
  11. package/dist/core/SessionManager.d.ts +6 -121
  12. package/dist/core/SessionManager.d.ts.map +1 -1
  13. package/dist/core/SessionManager.js +40 -7
  14. package/dist/core/SessionManager.js.map +1 -1
  15. package/dist/core/devGatedFeatures.d.ts.map +1 -1
  16. package/dist/core/devGatedFeatures.js +6 -0
  17. package/dist/core/devGatedFeatures.js.map +1 -1
  18. package/dist/core/sessionCapacityRefusedError.d.ts +8 -0
  19. package/dist/core/sessionCapacityRefusedError.d.ts.map +1 -0
  20. package/dist/core/sessionCapacityRefusedError.js +13 -0
  21. package/dist/core/sessionCapacityRefusedError.js.map +1 -0
  22. package/dist/core/types.d.ts +11 -0
  23. package/dist/core/types.d.ts.map +1 -1
  24. package/dist/core/types.js.map +1 -1
  25. package/dist/data/standards-guard-index.json +1 -1
  26. package/dist/data/standards-guard-index.meta.json +2 -2
  27. package/dist/data/standards-registry.meta.json +1 -1
  28. package/dist/messaging/TelegramAdapter.d.ts +10 -0
  29. package/dist/messaging/TelegramAdapter.d.ts.map +1 -1
  30. package/dist/messaging/TelegramAdapter.js +12 -1
  31. package/dist/messaging/TelegramAdapter.js.map +1 -1
  32. package/dist/messaging/telegram-origin/TelegramOriginBoot.d.ts +2 -0
  33. package/dist/messaging/telegram-origin/TelegramOriginBoot.d.ts.map +1 -1
  34. package/dist/messaging/telegram-origin/TelegramOriginBoot.js +2 -0
  35. package/dist/messaging/telegram-origin/TelegramOriginBoot.js.map +1 -1
  36. package/dist/messaging/telegram-origin/TelegramOriginRuntime.d.ts +16 -0
  37. package/dist/messaging/telegram-origin/TelegramOriginRuntime.d.ts.map +1 -1
  38. package/dist/messaging/telegram-origin/TelegramOriginRuntime.js +23 -2
  39. package/dist/messaging/telegram-origin/TelegramOriginRuntime.js.map +1 -1
  40. package/dist/messaging/telegram-origin/TelegramOriginService.d.ts +1 -0
  41. package/dist/messaging/telegram-origin/TelegramOriginService.d.ts.map +1 -1
  42. package/dist/messaging/telegram-origin/TelegramOriginService.js +5 -2
  43. package/dist/messaging/telegram-origin/TelegramOriginService.js.map +1 -1
  44. package/dist/monitoring/BlockerLifecycleService.d.ts +26 -3
  45. package/dist/monitoring/BlockerLifecycleService.d.ts.map +1 -1
  46. package/dist/monitoring/BlockerLifecycleService.js +92 -17
  47. package/dist/monitoring/BlockerLifecycleService.js.map +1 -1
  48. package/dist/monitoring/FeatureEvidenceLog.d.ts +53 -0
  49. package/dist/monitoring/FeatureEvidenceLog.d.ts.map +1 -0
  50. package/dist/monitoring/FeatureEvidenceLog.js +99 -0
  51. package/dist/monitoring/FeatureEvidenceLog.js.map +1 -0
  52. package/dist/monitoring/LadderEvidenceReader.d.ts +31 -0
  53. package/dist/monitoring/LadderEvidenceReader.d.ts.map +1 -0
  54. package/dist/monitoring/LadderEvidenceReader.js +204 -0
  55. package/dist/monitoring/LadderEvidenceReader.js.map +1 -0
  56. package/dist/monitoring/MaturationBoard.d.ts +1 -1
  57. package/dist/monitoring/MaturationBoard.d.ts.map +1 -1
  58. package/dist/monitoring/MaturationBoard.js +5 -1
  59. package/dist/monitoring/MaturationBoard.js.map +1 -1
  60. package/dist/monitoring/MaturationLadder.d.ts +214 -0
  61. package/dist/monitoring/MaturationLadder.d.ts.map +1 -0
  62. package/dist/monitoring/MaturationLadder.js +495 -0
  63. package/dist/monitoring/MaturationLadder.js.map +1 -0
  64. package/dist/monitoring/MaturationLadderService.d.ts +189 -0
  65. package/dist/monitoring/MaturationLadderService.d.ts.map +1 -0
  66. package/dist/monitoring/MaturationLadderService.js +593 -0
  67. package/dist/monitoring/MaturationLadderService.js.map +1 -0
  68. package/dist/monitoring/maturationUniverse.d.ts +14 -0
  69. package/dist/monitoring/maturationUniverse.d.ts.map +1 -0
  70. package/dist/monitoring/maturationUniverse.js +54 -0
  71. package/dist/monitoring/maturationUniverse.js.map +1 -0
  72. package/dist/native/InstarWedgeCanary.app/Contents/MacOS/InstarWedgeCanary +0 -0
  73. package/dist/native/instar-desktop-host +0 -0
  74. package/dist/scaffold/templates.d.ts.map +1 -1
  75. package/dist/scaffold/templates.js +2 -1
  76. package/dist/scaffold/templates.js.map +1 -1
  77. package/dist/scheduler/JobScheduler.d.ts.map +1 -1
  78. package/dist/scheduler/JobScheduler.js +6 -1
  79. package/dist/scheduler/JobScheduler.js.map +1 -1
  80. package/dist/server/AgentServer.d.ts +5 -0
  81. package/dist/server/AgentServer.d.ts.map +1 -1
  82. package/dist/server/AgentServer.js +115 -1
  83. package/dist/server/AgentServer.js.map +1 -1
  84. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  85. package/dist/server/CapabilityIndex.js +9 -0
  86. package/dist/server/CapabilityIndex.js.map +1 -1
  87. package/dist/server/maturationBoardRoutes.d.ts +2 -0
  88. package/dist/server/maturationBoardRoutes.d.ts.map +1 -1
  89. package/dist/server/maturationBoardRoutes.js +34 -1
  90. package/dist/server/maturationBoardRoutes.js.map +1 -1
  91. package/dist/server/maturationLadderRoutes.d.ts +29 -0
  92. package/dist/server/maturationLadderRoutes.d.ts.map +1 -0
  93. package/dist/server/maturationLadderRoutes.js +143 -0
  94. package/dist/server/maturationLadderRoutes.js.map +1 -0
  95. package/dist/server/routes.d.ts.map +1 -1
  96. package/dist/server/routes.js +5 -1
  97. package/dist/server/routes.js.map +1 -1
  98. package/dist/testing/selfActionRegistry.d.ts.map +1 -1
  99. package/dist/testing/selfActionRegistry.js +37 -0
  100. package/dist/testing/selfActionRegistry.js.map +1 -1
  101. package/package.json +1 -1
  102. package/skills/spec-converge/scripts/write-convergence-tag.mjs +5 -2
  103. package/src/core/FeatureMaturationPlanGate.mjs +15 -1
  104. package/src/data/builtin-manifest.json +66 -66
  105. package/src/data/feature-ladders.json +191 -0
  106. package/src/data/standards-guard-index.json +1 -1
  107. package/src/data/standards-guard-index.meta.json +2 -2
  108. package/src/data/standards-registry.meta.json +1 -1
  109. package/src/data/state-coherence-registry.json +32 -0
  110. package/src/scaffold/templates.ts +2 -1
  111. package/upgrades/1.3.1648.md +29 -0
  112. package/upgrades/1.3.1649.md +28 -0
  113. package/upgrades/job-alert-global-cap.eli16.md +9 -0
  114. package/upgrades/side-effects/echo-bugs-recovered-reply-history.md +67 -0
  115. package/upgrades/side-effects/feature-maturation-ladder.md +69 -0
  116. package/upgrades/side-effects/job-alert-global-cap.md +66 -0
@@ -2,7 +2,7 @@
2
2
  "schemaVersion": 1,
3
3
  "generatedFrom": "source-tree",
4
4
  "registrySha256": "e9eb5bb7f56ce6f81c5f80210c1ec7999d4b8c7d2ff1ab5cfd97a269172ce2ac",
5
- "packageVersion": "1.3.1647",
5
+ "packageVersion": "1.3.1649",
6
6
  "guards": [
7
7
  {
8
8
  "ref": "docs/audits/phase-b/f10-triage.md",
@@ -1,5 +1,5 @@
1
1
  {
2
- "sha256": "dae638931d9c2f57b54bd9ea774387a52924c54789ca2f1cff1922a8104457e6",
2
+ "sha256": "925a6e27d3abc6b957a8e865a9623c9a4a607cc43ddbf9bbe70cc8193b2f0e0e",
3
3
  "registrySha256": "e9eb5bb7f56ce6f81c5f80210c1ec7999d4b8c7d2ff1ab5cfd97a269172ce2ac",
4
- "packageVersion": "1.3.1647"
4
+ "packageVersion": "1.3.1649"
5
5
  }
@@ -2,5 +2,5 @@
2
2
  "sha256": "e9eb5bb7f56ce6f81c5f80210c1ec7999d4b8c7d2ff1ab5cfd97a269172ce2ac",
3
3
  "articleCount": 93,
4
4
  "generatedFrom": "docs/STANDARDS-REGISTRY.md",
5
- "packageVersion": "1.3.1647"
5
+ "packageVersion": "1.3.1649"
6
6
  }
@@ -2172,6 +2172,38 @@
2172
2172
  "complianceHold": true,
2173
2173
  "note": "Never pruned by design: keeping declined and stopped ideas stops the same idea being argued twice, and adoption predictions are graded against the record. Volume is small: one row per idea revision, stage change and weekly run."
2174
2174
  }
2175
+ },
2176
+ {
2177
+ "category": "feature-evidence-log",
2178
+ "description": "Rich-context record of what each switched-off feature did on this machine, read by the maturation ladder (feature-maturation-ladder §4). Per-machine facts, read through each machine's route and the board's ladder owner.",
2179
+ "scope": "machine-local",
2180
+ "freshness": "n/a",
2181
+ "conflictShape": "append-only",
2182
+ "transport": "none",
2183
+ "paths": [
2184
+ "logs/feature-evidence.jsonl"
2185
+ ],
2186
+ "grandfathered": false,
2187
+ "retention": {
2188
+ "class": "size-bounded",
2189
+ "note": "Segment rotation at 10 MB, 8 segments kept."
2190
+ }
2191
+ },
2192
+ {
2193
+ "category": "maturation-advances-audit",
2194
+ "description": "Audit of what the ladder raised, each observed rung change, and every move the review made, with evidence and old values (feature-maturation-ladder §8).",
2195
+ "scope": "machine-local",
2196
+ "freshness": "n/a",
2197
+ "conflictShape": "append-only",
2198
+ "transport": "none",
2199
+ "paths": [
2200
+ "logs/maturation-advances.jsonl"
2201
+ ],
2202
+ "grandfathered": false,
2203
+ "retention": {
2204
+ "class": "size-bounded",
2205
+ "note": "Segment rotation at 10 MB, every segment archived: this is the record of what moved and why."
2206
+ }
2175
2207
  }
2176
2208
  ]
2177
2209
  }
@@ -20,7 +20,7 @@ import { JOB_DECLARED_FAILURE_AWARENESS } from "../scheduler/jobDeclaredFailure.
20
20
  // existing-agent migration there) so the two can never drift. Imported as a runtime
21
21
  // function call inside generateClaudeMd — no module-init cycle (PostUpdateMigrator
22
22
  // never imports templates).
23
- import { APPRENTICESHIP_STALL_GATE_CLAUDEMD_SECTION, SESSION_LISTING_HYGIENE_CLAUDEMD_SECTION, PLAYWRIGHT_PROFILE_REGISTRY_CLAUDEMD_SECTION, MACHINE_LOAD_ASSESSMENT_CLAUDEMD_SECTION, CODEX_CONNECT_CLAUDEMD_SECTION, FEATURE_SWITCH_CLAUDEMD_SECTION, NORMAL_CHROME_BROWSER_CLAUDEMD_SECTION, SINGLE_MACHINE_FAILOVER_GAP_CLAUDEMD_SECTION, MISSING_LOGIN_SESSION_CLAUDEMD_SECTION, DYNAMIC_MCP_CLAUDEMD_SECTION, ULTRACODE_SPAWN_CLAUDEMD_SECTION, AGENT_SIGNATURE_PROVENANCE_CLAUDEMD_SECTION, SENDER_REJECTION_CLAUDEMD_SECTION, SCOPE_ACCRETION_CLAUDEMD_SECTION, MESH_SELF_HEALING_CLAUDEMD_SECTION, LEASE_MEDIUM_CLAUDEMD_SECTION, WRITE_ADMISSION_CLAUDEMD_SECTION, DOORWAY_REGISTRY_CLAUDEMD_SECTION, EXTERNAL_HOG_CLAUDEMD_SECTION, ROUTING_SPEND_CLAUDEMD_SECTION, MATURATION_BOARD_CLAUDEMD_SECTION, QUEUE_PACE_CLAUDEMD_SECTION, ECOSYSTEM_IDEAS_CLAUDEMD_SECTION, MOBILE_PAIRING_CLAUDEMD_SECTION, MOBILE_CHAT_CLAUDEMD_SECTION, APP_CONVERSATIONS_CLAUDEMD_SECTION, MOBILE_ROUTES_CLAUDEMD_SECTION, MOBILE_PUSH_CLAUDEMD_SECTION, MOBILE_PEOPLE_CLAUDEMD_SECTION, DECISION_QUALITY_CLAUDEMD_SECTION, BENCHMARK_DIVERGENCE_CLAUDEMD_SECTION, DUPLICATE_RECONCILER_CLAUDEMD_SECTION, AUDIT_CONVERGENCE_CLAUDEMD_SECTION, TONE_ADVISORY_MIGRATION_CLAUDEMD_SECTION, DECISION_JOURNAL_CONFIDENCE_CLAUDEMD_GUIDANCE, WINDOW_RUN_LIVENESS_CLAUDEMD_SECTION, SCRIPT_JOBS_CLAUDEMD_SECTION, SESSION_HANDOFF_CLAUDEMD_SECTION, JOB_RESULT_SUPERVISION_CLAUDEMD_SECTION, DEDICATED_PROFILE_REGISTRY_ROW_ANSWER, CODEX_ARM_SWEEPER_CLAUDEMD_SECTION, MACHINE_MAINTENANCE_CLAUDEMD_SECTION, APP_MEDIA_CLAUDEMD_SECTION, MACHINE_BROWSER_CARE_CLAUDEMD_SECTION, PAIRING_WITHOUT_TELEGRAM_CLAUDEMD_SECTION, SLACK_FROM_APP_CLAUDEMD_SECTION, MACHINE_MAINTENANCE_POOL_CLAUDEMD_SECTION, MACHINE_WEDGE_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
23
+ import { APPRENTICESHIP_STALL_GATE_CLAUDEMD_SECTION, SESSION_LISTING_HYGIENE_CLAUDEMD_SECTION, PLAYWRIGHT_PROFILE_REGISTRY_CLAUDEMD_SECTION, MACHINE_LOAD_ASSESSMENT_CLAUDEMD_SECTION, CODEX_CONNECT_CLAUDEMD_SECTION, FEATURE_SWITCH_CLAUDEMD_SECTION, NORMAL_CHROME_BROWSER_CLAUDEMD_SECTION, SINGLE_MACHINE_FAILOVER_GAP_CLAUDEMD_SECTION, MISSING_LOGIN_SESSION_CLAUDEMD_SECTION, DYNAMIC_MCP_CLAUDEMD_SECTION, ULTRACODE_SPAWN_CLAUDEMD_SECTION, AGENT_SIGNATURE_PROVENANCE_CLAUDEMD_SECTION, SENDER_REJECTION_CLAUDEMD_SECTION, SCOPE_ACCRETION_CLAUDEMD_SECTION, MESH_SELF_HEALING_CLAUDEMD_SECTION, LEASE_MEDIUM_CLAUDEMD_SECTION, WRITE_ADMISSION_CLAUDEMD_SECTION, DOORWAY_REGISTRY_CLAUDEMD_SECTION, EXTERNAL_HOG_CLAUDEMD_SECTION, ROUTING_SPEND_CLAUDEMD_SECTION, MATURATION_BOARD_CLAUDEMD_SECTION, MATURATION_LADDER_CLAUDEMD_SECTION, QUEUE_PACE_CLAUDEMD_SECTION, ECOSYSTEM_IDEAS_CLAUDEMD_SECTION, MOBILE_PAIRING_CLAUDEMD_SECTION, MOBILE_CHAT_CLAUDEMD_SECTION, APP_CONVERSATIONS_CLAUDEMD_SECTION, MOBILE_ROUTES_CLAUDEMD_SECTION, MOBILE_PUSH_CLAUDEMD_SECTION, MOBILE_PEOPLE_CLAUDEMD_SECTION, DECISION_QUALITY_CLAUDEMD_SECTION, BENCHMARK_DIVERGENCE_CLAUDEMD_SECTION, DUPLICATE_RECONCILER_CLAUDEMD_SECTION, AUDIT_CONVERGENCE_CLAUDEMD_SECTION, TONE_ADVISORY_MIGRATION_CLAUDEMD_SECTION, DECISION_JOURNAL_CONFIDENCE_CLAUDEMD_GUIDANCE, WINDOW_RUN_LIVENESS_CLAUDEMD_SECTION, SCRIPT_JOBS_CLAUDEMD_SECTION, SESSION_HANDOFF_CLAUDEMD_SECTION, JOB_RESULT_SUPERVISION_CLAUDEMD_SECTION, DEDICATED_PROFILE_REGISTRY_ROW_ANSWER, CODEX_ARM_SWEEPER_CLAUDEMD_SECTION, MACHINE_MAINTENANCE_CLAUDEMD_SECTION, APP_MEDIA_CLAUDEMD_SECTION, MACHINE_BROWSER_CARE_CLAUDEMD_SECTION, PAIRING_WITHOUT_TELEGRAM_CLAUDEMD_SECTION, SLACK_FROM_APP_CLAUDEMD_SECTION, MACHINE_MAINTENANCE_POOL_CLAUDEMD_SECTION, MACHINE_WEDGE_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
24
24
  import { MINIMUM_OPERATOR_EFFORT_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
25
25
  import { CODEX_DEVICE_LIMIT_CLAUDEMD_BULLET } from '../core/PostUpdateMigrator.js';
26
26
  import { UPDATE_APPLY_VERIFY_HOLD_CLAUDEMD_LINE } from '../core/PostUpdateMigrator.js';
@@ -1041,6 +1041,7 @@ ${WRITE_ADMISSION_CLAUDEMD_SECTION(port)}
1041
1041
  ${DOORWAY_REGISTRY_CLAUDEMD_SECTION(port)}
1042
1042
  ${ROUTING_SPEND_CLAUDEMD_SECTION(port)}
1043
1043
  ${MATURATION_BOARD_CLAUDEMD_SECTION(port)}
1044
+ ${MATURATION_LADDER_CLAUDEMD_SECTION(port)}
1044
1045
  ${QUEUE_PACE_CLAUDEMD_SECTION(port)}
1045
1046
  ${ECOSYSTEM_IDEAS_CLAUDEMD_SECTION(port)}
1046
1047
  ${MOBILE_PAIRING_CLAUDEMD_SECTION(port)}
@@ -0,0 +1,29 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: minor -->
5
+
6
+ ## What Changed
7
+
8
+ Every switched-off feature now has a ladder: numbers it must hit for each rung, read from its own logged behaviour, with on-by-default as the last rung. `src/data/feature-ladders.json` holds them, and a test fails the build if a switched-off feature has no entry. The rung comes from what actually ships, not from a label. The existing readiness scorer now covers these features, with its per-feature scans reduced to one read per pass.
9
+
10
+ A new evidence log lets any feature record what it did with the reason and context, and `GET /maturation/ladder` shows each feature's rung, next rung and numbers now against target. The maturation board shows the same. When a feature's numbers hold long enough it is raised to the recurring review, whose model decides; `POST /maturation/moves` applies that decision behind floors that can only refuse. Numbers never move anything by themselves, and a fleet default stays a reviewed code change. Development agents get this live; it is off on the fleet for now.
11
+
12
+ In the instar source tree, a spec's maturation plan now also names its ladder entry.
13
+
14
+ ## What to Tell Your User
15
+
16
+ Nothing changes for you today. Behind the scenes, features that are still switched off now have clear numbers they must reach before being turned on for everyone, and I can tell you exactly where any of them stands.
17
+
18
+ ## Summary of New Capabilities
19
+
20
+ - Ask why a feature is still off and get its numbers against its targets.
21
+ - A record of what each switched-off feature actually did, with reasons.
22
+ - Features that meet their numbers are raised for a decision instead of waiting to be noticed.
23
+
24
+ ## Evidence
25
+
26
+ - 186 features in the registry, covering all 185 the code reports as switched off, enforced by a test with no baseline file. 172 have thresholds on every rung they still need; 57 read real logs today and 115 read 0 samples until instrumented, by design.
27
+ - Reproduction of the gap: GET /maturation/board on 2026-11-03 showed 224 rows, 4 really on by default, 147 "Nothing planned", 9 numeric targets.
28
+ - Spec converged in 3 rounds with GPT-6 Astra; automatic moves were cut after all reviewers and *The Body and the Mind* said a counter must not decide. A second-family read of the thresholds found 13 wrong bars, which were fixed.
29
+ - Unit, integration and E2E tests cover the parser, rung derivation, every state, evidence reads, move floors, revert, raising, gate and production wiring.
@@ -0,0 +1,28 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ Recovered Telegram session replies now get a topic history row from the confirmed receipt. A before-network connect failure that holds a session reply creates one operator attention item for that destination. Advisory preflight records now state that delivery is not confirmed.
9
+
10
+ The global session limit now returns a typed capacity refusal. Scheduled jobs wait in the existing priority queue without gaining a failure, and one scheduled job may use a guarded extra session place when conversations fill the ordinary allowance and memory is healthy. Old per-job failure reminders pause during the wait.
11
+
12
+ ## What to Tell Your User
13
+
14
+ A delayed reply stays in the server's retry queue. Its delivery state is visible, and a recovered message appears in topic history once Telegram accepts it.
15
+
16
+ Scheduled checks no longer report a failure merely because conversations have filled the Studio's ordinary session allowance. They wait and try again when there is room.
17
+
18
+ ## Summary of New Capabilities
19
+
20
+ Recovered Telegram replies are recorded in topic history; held session replies raise an operator attention item, and advisory rows clearly distinguish preflight from delivery.
21
+
22
+ One scheduled job can run beyond the ordinary conversation allowance when memory is healthy, while the hard host limit and the subscription lane limit still protect the machine.
23
+
24
+ ## Evidence
25
+
26
+ A Mac Studio origin outbox receipt for Echo Bugs topic 10000001534 had Telegram message 1550 after recovery, while the topic history had no row. The focused regression failed before the adapter method and passed after it; the advisory E2E check passed.
27
+
28
+ Regression tests first failed on the old global-limit behavior, then passed for typed waiting, a single guarded extra slot, simultaneous requests, high memory pressure, and conversations beyond the soft cap. The full repository verifier is required before merge.
@@ -0,0 +1,9 @@
1
+ # Scheduled jobs and the global session limit — plain English
2
+
3
+ The first job-alert fix reached the Mac Studio and exposed a second limit. The Studio had twenty running conversations, which filled its ordinary session allowance. Health Check was refused before it reached the six-slot subscription lane. That refusal still counted as a failed job, so a machine with busy conversations could keep producing alerts and miss checks even after the first fix.
4
+
5
+ This correction makes a full global session pool a typed waiting condition, just like a full subscription lane. A scheduled job that reaches the limit waits in the existing priority queue. Its failure count does not rise, and it is retried every fifteen seconds when room becomes available. The scheduler pauses any old per-job failure reminder while the job waits; a real failure after the retry starts the normal failure alert again.
6
+
7
+ People can open conversations beyond the ordinary limit because a conversation is an immediate request. To keep that choice from blocking all scheduled checks, one scheduled job may borrow a single additional session place while the host's memory is healthy. The loan is limited to one running or starting job at a time, even if several jobs trigger together. The hard safety limit of three times the configured session allowance remains in place. High memory pressure closes the loan, and the six-slot subscription lane still has its own cap. This keeps the protection that matters after the June 2026 laptop memory failure.
8
+
9
+ This is a small, reversible correction to the already shipped capacity episode. It adds no new notification type or destination. A short wait remains silent; a long wait still produces one plain Attention message for the episode. The live Studio check that prompted this change found twenty conversations and Health Check's existing “Max sessions” errors; the new behavior must be verified on the next installed release before it can be called live.
@@ -0,0 +1,67 @@
1
+ # Side-Effects Review — Echo Bugs reply recovery visibility
2
+
3
+ **Version / slug:** `echo-bugs-recovered-reply-history`
4
+ **Date:** 2026-11-04
5
+ **Author:** Echo
6
+ **Second-pass reviewer:** independent review agent
7
+
8
+ ## Summary of the change
9
+
10
+ Tier 1, 8 source/test files and about 80 changed lines; one review round and one commit/gate attempt planned. A recovered origin send now mirrors its Telegram receipt into topic history, using the issues chat and real thread to restore the internal topic id. A held session reply caused by a proved connect failure creates a deduplicated hub attention item. The advisory log explicitly marks preflight rows as delivery unconfirmed. The transport's connect error code is logged without credentials. This is built in a fresh worktree based on `JKHeadley/main`, remote `https://github.com/JKHeadley/instar.git`, package version 1.3.1646. Rollback is a revert; the durable origin outbox and retry authority remain unchanged.
11
+
12
+ ## Decision-point inventory
13
+
14
+ - Origin recovery send gate: pass-through. The existing sealed outbox owns retries; this patch only observes a confirmed receipt.
15
+ - History mirror: add. Only a correlated Bot API acceptance from `sendMessage` produces a history row; adapter dedupe prevents a second row.
16
+ - Held session attention: add signal. The proved before-network connect failure creates an operator observation; it does not grant or deny send permission.
17
+ - Advisory API interpretation: modify presentation. `clean` means preflight only and is labeled `not-confirmed`.
18
+
19
+ ## 1. Over-block
20
+
21
+ No block/allow surface; no legitimate message is rejected by this patch.
22
+
23
+ ## 2. Under-block
24
+
25
+ A process crash after the origin store saves a recovered acceptance but before the callback writes history can still leave a log gap. Other hold reasons still rely on existing status and notices. An accepted Telegram receipt does not prove that a human read the message.
26
+
27
+ ## 3. Level-of-abstraction fit
28
+
29
+ The origin transport confirms platform acceptance, and the Telegram adapter owns topic history. The callback joins those layers only after the existing origin authority has accepted the receipt. The attention observation uses the existing hub item system rather than another sender.
30
+
31
+ ## 4. Signal vs authority compliance
32
+
33
+ [Signal vs authority](../../docs/signal-vs-authority.md): no new blocking authority. The connect failure is a transport proof and only feeds logging and attention. Retry permission remains with the outbox.
34
+
35
+ ## 4b. Judgment-point check
36
+
37
+ No static heuristic at a competing-signals decision point. The log mirror requires a concrete receipt, and the alert requires the existing proved-unsent failure class.
38
+
39
+ ## 5. Interactions
40
+
41
+ Normal sends still log in `sendToTopic`; recovered sends bypass it and use this callback. Adapter message-id dedupe handles a callback repeated by a recovery race. The callback runs after durable outcome recording and cannot trigger a resend. Attention uses a stable per-operation id, so repeated holds of the same reply coalesce. A confirmed recovered receipt closes exactly that operation's item, including when attention lifecycle automation is disabled.
42
+
43
+ ## 6. External surfaces
44
+
45
+ The advisory endpoint adds `stage` and `deliveryStatus`; existing fields remain. Recovered sends appear in topic history and search. The operator hub shows delayed session replies while Telegram connect attempts fail. No new Bot API request is made.
46
+
47
+ ## 7. Multi-machine posture
48
+
49
+ Origin operations remain machine-local to their execution owner and are recovered there. A holder logs recovered receipts into its topic history. The hub attention is created on that holder. Forward-to-holder behavior on a standby is unchanged and owned by the separate topic 10000001549 work.
50
+
51
+ ## 8. Rollback cost
52
+
53
+ Revert the code and restart the server. Already-written message history rows remain true receipt records; existing dedupe prevents duplicates. No migration is required.
54
+
55
+ ## Evidence
56
+
57
+ On the Mac Studio, operation `4a9ca1dd-56f3-4294-8cab-7fb7d7f80f47` was accepted on a recovery attempt at 05:44:45 UTC with Telegram message 1550, but topic 10000001534 history lacked that row. Operation `1206bc11-c6b0-441a-8d3f-619fcb82b45b` was still admitted after a proved connect failure; its outbox scheduled a retry. The new regression test failed with `logRecoveredOriginMessage is not a function` before the adapter change and passes afterward. The advisory E2E test passes with the new status fields.
58
+
59
+ ## Class-Closure Declaration
60
+
61
+ `defectClass: unbounded-self-action`, `closure: n/a`. The new notification is a one-shot response to one existing send hold, keyed by that operation id. It installs no timer, retry, or self-triggered loop; the existing origin outbox retains all retry authority. No agent-authored-artifact defect.
62
+
63
+ ## Second-pass review
64
+
65
+ The independent reviewer confirmed that the callback requires a Telegram receipt and existing adapter dedupe prevents a second history row. Concern raised: the new attention item could remain open after delivery. The callback now closes an operation-scoped item after receipt-confirmed recovery, with a fallback when lifecycle automation is disabled. The reviewer also noted that a recovery-path callback test would strengthen the adapter-only test; the targeted integration and E2E checks cover the added history and advisory behavior.
66
+
67
+ **Recheck:** The reviewer concurs with the revised fix. Each pending operation has its own attention item, and confirmed recovery closes it with or without attention lifecycle automation. The documented crash window remains.
@@ -0,0 +1,69 @@
1
+ # Side-Effects Review — Feature maturation ladder
2
+
3
+ **Version / slug:** `feature-maturation-ladder`
4
+ **Date:** `2026-11-03`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `independent subagent, appended below`
7
+
8
+ ## Summary of the change
9
+
10
+ Adds the measured path to default-on: a shipped registry of per-rung thresholds (`src/data/feature-ladders.json`), a coverage test over a code-derived universe (`maturationUniverse`), pure parsing and state logic (`MaturationLadder`), a streaming evidence reader (`LadderEvidenceReader`), a rich-context log (`FeatureEvidenceLog`), a service that feeds D7 and raises commitments (`MaturationLadderService`), routes (`maturationLadderRoutes`), a board owner source and page block, a plan-gate line, and migration and template sections. D7 gains subject hooks and linear per-pass reads. Tier 2: about 2,000 lines of code and tests plus a large data file, 3 spec rounds, dev-gated.
11
+
12
+ ## Decision-point inventory
13
+
14
+ - Rung derivation — add — pure read; gates nothing.
15
+ - Threshold evaluation — pass-through — D7's numeric comparison, unchanged.
16
+ - Raise a feature — add — records a commitment, deduped; decides nothing.
17
+ - `POST /maturation/moves` floors — add — exact-match checks in front of a decision a model already made; can only refuse.
18
+ - Plan gate — modify — also requires a `ladder` line in the instar source tree.
19
+ - Coverage test — add — a new dark flag with no entry fails the build.
20
+
21
+ ---
22
+
23
+ ## 1. Over-block
24
+
25
+ The coverage test refuses a new switched-off flag with no ladder entry; that is intended, and an entry with `tracking: needed` is cheap. The plan gate refuses a spec with no `ladder` line, in the instar source tree only: installed agents' own specs are unaffected, and existing specs are not re-stamped. The moves route refuses a sensitive or coherence-critical feature, which is intended: those take the code path.
26
+
27
+ ## 2. Under-block
28
+
29
+ A feature can write rows while being wrong; thresholds on activity alone would pass. Enough-to-judge requires a quality or harm metric, and the review's model reads the evidence, but a poor metric can still pass the numeric floor. A bearer holder can post favourable grades; no count moves anything by itself. A concurrent config writer could be overwritten between check and write: accepted, one process, rare moves, model in the loop. Registry quality: model-drafted entries, parser-checked and read by a second family, can still mis-specify a bar; the review grades outcomes over time.
30
+
31
+ ## 3. Level-of-abstraction fit
32
+
33
+ D7 stays the only scorer. The service adds subjects and projections rather than a second rule. The board stays a view. The review job stays the only decider. Raising is a signal; the mind holds authority, per *The Body and the Mind*.
34
+
35
+ ## 4. Signal vs authority compliance
36
+
37
+ Compliant, and this is the main thing review changed. Reference: `docs/signal-vs-authority.md`. Numbers are signals. The first design auto-applied reversible moves; it was cut. The route's floors are exact-match checks that can only refuse, in front of a decision a model made.
38
+
39
+ ## 5. Interactions
40
+
41
+ D7's `evaluateMaturation` now reads once per pass; existing D7 tests pass unchanged. Its 6-hour timer now awaits a `prepare` hook, with an overlap guard. In-memory subjects add rows to the D7 ledger: at 172 subjects and 4 passes a day, about 62k evaluation rows and up to about 139k observation rows at the 90-day retention, handled by existing pruning. A stuck evidence read is cut off after 10 minutes so it cannot stop the scorer for other features. Board D7 rows for ladder-only subjects are skipped so one feature stays one row. `maturation:<id>` commitments share the key the review job already uses, so a job-opened one is reused. Raised commitments have no beacon, so they cannot crowd the beacon cap. `StageAdvancer` stays the sole writer of the session-pool stage; the parser and `LiveConfig` both refuse it. `lint-state-registry` gets two new stores.
42
+
43
+ ## 6. External surfaces
44
+
45
+ New routes under `/maturation` (Bearer; dev-gated). The board response gains an owner source and the page gains a line and a list. No operator messages. Schema `maturation-ladder/1` is a published interface for the job. Log contents never leave: only numbers do.
46
+
47
+ ## 6b. Operator-surface quality
48
+
49
+ (1) The page still leads with its one answer sentence; this adds "N ready to move up" to the line under it, and a "Where it is" row plus a short list of numbers under a tapped row. No new primary action: the page changes nothing. (2) No raw internals as primary content: rungs and states read as plain words ("On for development agents", "Not recording anything yet"), and setting names stay under Technical details. (3) No destructive action on this surface; moves and reverts are API-only. (4) Plain language; the list is one line per number and wraps at phone width. The first view adds under ten words.
50
+
51
+ ## 7. Multi-machine posture
52
+
53
+ Unified by derivation and proxied read: the registry is repo-tracked; D7 and the evidence logs are origin-local by D7's approved design and shown machine-tagged through the board's pool merge. Moves are per-machine, like `/guards`, and coherence-critical flags are refused. Raises run on the lease holder only; a lease move can produce a second record for a feature, which costs one report line. `reviewTopic` is per machine.
54
+
55
+ ## 8. Rollback cost
56
+
57
+ Set `maturation.ladder.enabled` false, read live with no restart: routes 503, raising idles, D7 returns to spec-born subjects. No migration to undo. Applied moves stay as settings, each with a revert route and old values in the audit log. A bad registry is refused whole, and fixed by one release.
58
+
59
+ ## Class-Closure Declaration
60
+
61
+ `unbounded-self-action`: closure `guard`, citing `tests/unit/self-action-convergence.test.ts` (ratchet), registered as `maturation-ladder-raise`. Raising is capped at 5 a pass with per-feature cooldowns. Evidence reads are bounded by file size and run once per 6-hour pass with an overlap guard. The review's build sessions are capped at 2 a run, with at most 3 retries in its job body. Moves are request-driven.
62
+
63
+ ## Evidence
64
+
65
+ Unit, integration and E2E tests as listed in the spec, including the E2E wiring test against a real commitment store and scorer; a public docs page for the ladder; the cross-model review flow fixture carries the new plan line; the discoverability and section-tracking tests updated for the new routes and section; second-family read of the thresholds; live check on Echo recorded in the PR.
66
+
67
+ ## Second-pass review
68
+
69
+ Independent subagent, first read: "Concern raised": a failed read counted as silence (false `harmed`); an unreadable config armed harm watches and raised false commitments; the off switch needed a restart; `prepare` had no timeout; the row estimate left out observations. It found the D7 linear change equivalent, no path that moves a feature without the route, and no board regression. All five fixed in this commit, with tests. Concur after fixes.
@@ -0,0 +1,66 @@
1
+ # Side-Effects Review — Global session capacity for scheduled jobs
2
+
3
+ **Version / slug:** `job-alert-global-cap`
4
+ **Date:** 2026-11-03
5
+ **Author:** echo
6
+ **Second-pass reviewer:** independent Codex reviewer
7
+
8
+ ## Summary of the change
9
+
10
+ Tier 1, reversible correction after live evidence on Studio: twenty running conversations caused Health Check to fail at the global session limit before the reroute gate. A typed global refusal now enters the capacity episode. The session manager lends one bounded place to a scheduled job when memory is below the high tier; pending admissions are counted so simultaneous jobs cannot both borrow it. The scheduler suspends old failure reminders during that wait. Approximately eight files and 130 changed code and test lines, plus short release artifacts; one design pass, one reviewer pass, and one commit planned.
11
+
12
+ ## Decision-point inventory
13
+
14
+ - `SessionManager.spawnSession` owns the soft and hard session limits and emits the new typed refusal. Its pending counter closes simultaneous admission races.
15
+ - `SessionManager.confinedRerouteCapacity` reports saturation from the global limit as well as the reroute lane, so the existing job queue waits rather than retrying a known-full host every poll.
16
+ - `JobScheduler` recognizes the typed global refusal and uses the existing durable capacity episode. It suspends a stale per-job failure reminder until a real retry result arrives.
17
+
18
+ ## 1. Over-block
19
+
20
+ If memory is high, the borrowed place closes even when a critical job is waiting. This is deliberate: the rerouted lane's existing memory gate would refuse the same launch, and adding a session under high pressure would recreate the host risk. When another scheduled job is running, the loan is unavailable until that job finishes. A conversation remains possible under the existing operator path.
21
+
22
+ ## 2. Under-block
23
+
24
+ The one-job loan does not force a running conversation to end. A host already at the hard absolute limit or above the memory threshold still cannot start a job; the episode's ten-minute critical or thirty-minute other notice remains the alarm. The global refusal class covers this admission point; unrelated real spawn errors continue through the failure path.
25
+
26
+ ## 3. Level-of-abstraction fit
27
+
28
+ The session manager already owns admission and memory pressure. It makes the bounded loan decision there, while the scheduler owns retry order and notices. A class, rather than the changing error text, tells the scheduler to wait. The queue and alert logic from the preceding release are reused.
29
+
30
+ ## 4. Signal vs authority compliance
31
+
32
+ Required reference: [Signal vs Authority](../../docs/signal-vs-authority.md). The new refusal is a structural resource signal from the existing admission authority. The scheduler does not infer capacity from a string or create another independent gate. The one-place loan is a bounded resource invariant, conditioned on the existing memory tier and absolute limit, rather than a judgment about a conversation's importance.
33
+
34
+ ## 4b. Judgment-point check
35
+
36
+ The job's declared scheduler provenance is the only eligibility signal. Job priority remains with the scheduler queue. No semantic text classifier decides whether to stop a session, admit a job, or alert Justin.
37
+
38
+ ## 5. Interactions
39
+
40
+ Pending headless launches count during admission; this is conservative until each launch settles. One pending or running scheduled job owns the loan. The reroute lane still limits subscription sessions and refuses under high memory pressure. Capacity waits release their machine claim and regain it at retry. A prior failure reminder stops during a capacity wait; if the later spawn really fails, normal alert state starts again.
41
+
42
+ ## 6. External surfaces
43
+
44
+ Health Check and other scheduled jobs can now wait silently at the global session limit. There is no new topic or message format. The existing episode notice remains in Attention. Direct `/sessions/spawn` calls cannot claim the scheduled loan by merely supplying a job slug; the scheduler trigger marker is required.
45
+
46
+ ## Operator surface
47
+
48
+ No new control is added. Existing conversation management remains available if Justin chooses to close one.
49
+
50
+ ## 7. Multi-machine posture
51
+
52
+ Machine-local by design: session count and memory pressure are measured per host. The existing multi-machine job claim and wait-release path determine where a retried job can run. The notice uses the existing one-voice Telegram path; no state is moved between topic owners.
53
+
54
+ ## 8. Rollback cost
55
+
56
+ Reverting this correction restores the previous global admission rule. The typed error has no persistent format, and the already existing capacity episode state is compatible with the previous release. No migration or cleanup is needed.
57
+
58
+ ## Second-pass review
59
+
60
+ Concur with the review. The reviewer checked the typed refusal, the simultaneous-loan race, the absolute and high-memory limits, and the old failure reminder behavior. Tests cover direct-spawn refusal, a single scheduled loan, high pressure, simultaneous requests, and typed-versus-text scheduler handling. No concrete regression was found in this diff.
61
+
62
+ The full verifier exposed one stale end-to-end assertion in `tests/e2e/job-run-history-lifecycle.test.ts`: it required a numeric success rate even when all runs were still pending. The existing API contract returns `null` until a run completes. The assertion now checks both states against that contract; no production stats behavior changed.
63
+
64
+ ## Class-Closure Declaration
65
+
66
+ `defectClass: unbounded-self-action`, `closure: guard`, `enforcementType: ratchet`, citation: `tests/unit/job-capacity-episode.test.ts`. A global-cap refusal enters the existing durable capacity episode. The tests require silence for individual refused jobs, at most one episode notice, and one queued retry per poll after capacity returns. Pending admission counts allow only one borrowed scheduled slot, so repeated polling cannot create an unbounded launch burst.