instar 1.3.337 → 1.3.339
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 +37 -2
- package/dist/commands/server.js.map +1 -1
- package/dist/core/LearningVelocityScorer.d.ts +40 -0
- package/dist/core/LearningVelocityScorer.d.ts.map +1 -0
- package/dist/core/LearningVelocityScorer.js +67 -0
- package/dist/core/LearningVelocityScorer.js.map +1 -0
- package/dist/core/OwnerSuspectBreaker.d.ts +79 -0
- package/dist/core/OwnerSuspectBreaker.d.ts.map +1 -0
- package/dist/core/OwnerSuspectBreaker.js +106 -0
- package/dist/core/OwnerSuspectBreaker.js.map +1 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +17 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/SessionRouter.d.ts +7 -0
- package/dist/core/SessionRouter.d.ts.map +1 -1
- package/dist/core/SessionRouter.js +14 -2
- package/dist/core/SessionRouter.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/routes.d.ts.map +1 -1
- package/dist/server/routes.js +62 -0
- 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.337.md → 1.3.338.md} +41 -0
- package/upgrades/1.3.339.md +48 -0
- package/upgrades/side-effects/exo3-g5-ci-greening.md +29 -0
- package/upgrades/side-effects/owner-suspect-breaker.md +52 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: minor -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
Adds a **learning-velocity metric** — Salim Ismail's EXO 3.0 KPI inversion (from
|
|
9
|
+
*Your KPI System Is Training You to Miss the Future*). Backward-looking
|
|
10
|
+
operational KPIs (throughput, utilization, efficiency) reward the existing model
|
|
11
|
+
and suppress the weak signals where the future shows up. The EXO 3.0 answer is to
|
|
12
|
+
measure how fast you're **learning** — adaptability, experimentation, capability
|
|
13
|
+
creation.
|
|
14
|
+
|
|
15
|
+
Instar already emits the raw learning events (registered learnings, captured
|
|
16
|
+
corrections, evolution actions); this turns them into a signal:
|
|
17
|
+
|
|
18
|
+
- `GET /metrics/learning-velocity?windowDays=30` → `{ totalEvents, eventsPerDay,
|
|
19
|
+
byType, typeDiversity, trend, adaptabilityScore, reason }`.
|
|
20
|
+
- `trend` is `accelerating` | `steady` | `declining` | `insufficient-data`
|
|
21
|
+
(first-half vs second-half of the window).
|
|
22
|
+
- `adaptabilityScore` (0–100) blends velocity (saturating) with category
|
|
23
|
+
diversity.
|
|
24
|
+
|
|
25
|
+
Read-only + advisory — it never gates anything. A flat or declining trend is the
|
|
26
|
+
EXO 3.0 warning sign that the org is optimizing the old model instead of learning.
|
|
27
|
+
|
|
28
|
+
## What to Tell Your User
|
|
29
|
+
|
|
30
|
+
Your agent can now answer "are we actually learning, or just running?" with real numbers. Ask it for its learning velocity and you get a trend — accelerating, steady, or declining — built from its genuine learning events (lessons it recorded, corrections it absorbed, capabilities it grew) instead of backward-looking activity stats. The EXO 3.0 idea behind it: traditional KPIs measure how well the OLD model runs; learning velocity measures whether you're building the next one. A flat or declining trend is your early warning that things are coasting.
|
|
31
|
+
|
|
32
|
+
## Summary of New Capabilities
|
|
33
|
+
|
|
34
|
+
- `GET /metrics/learning-velocity?windowDays=30` — `{ totalEvents, eventsPerDay, byType, typeDiversity, trend, adaptabilityScore (0-100), reason }`, computed from registered learnings, corrections, and evolution actions. Read-only + advisory — never gates.
|
|
35
|
+
- PROACTIVE trigger: "are we learning/adapting?" → read this metric and contrast it with operational throughput.
|
|
36
|
+
|
|
37
|
+
## Evidence
|
|
38
|
+
|
|
39
|
+
Three-tier coverage, all green, `tsc --noEmit` clean:
|
|
40
|
+
|
|
41
|
+
- Unit — `LearningVelocityScorer.test.ts` (6): empty, window exclusion,
|
|
42
|
+
accelerating, declining, insufficient-data, and byType/diversity/adaptability.
|
|
43
|
+
- Integration — `learning-velocity-routes.test.ts` (3): the route reads a real
|
|
44
|
+
`learning-registry.json` + corrections over HTTP and computes.
|
|
45
|
+
- E2E — `learning-velocity-lifecycle.test.ts` (1): a real server on a real port,
|
|
46
|
+
feature alive end-to-end (200, not 404/503).
|
|
47
|
+
|
|
48
|
+
CLAUDE.md scaffold template documents the endpoint.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Side-effects — EXO 3.0 G5 (#794) CI greening on post-rebase main
|
|
2
|
+
|
|
3
|
+
## Change set
|
|
4
|
+
|
|
5
|
+
- `tests/integration/learning-velocity-routes.test.ts` + `tests/e2e/learning-velocity-lifecycle.test.ts`
|
|
6
|
+
— teardown `fs.rmSync` → `SafeFsExecutor.safeRmSync` (lint compliance; test-only).
|
|
7
|
+
- `src/core/PostUpdateMigrator.ts` — migrateClaudeMd Learning-Velocity Metric
|
|
8
|
+
section (content-sniffed, idempotent) + shadow marker
|
|
9
|
+
`'**Learning-Velocity Metric (EXO 3.0'`.
|
|
10
|
+
- `tests/unit/feature-delivery-completeness.test.ts` — featureSections entry.
|
|
11
|
+
- `upgrades/next/learning-velocity-metric.md` — the two required user sections.
|
|
12
|
+
|
|
13
|
+
## Side effects considered
|
|
14
|
+
|
|
15
|
+
- **Existing agents' CLAUDE.md grows** one section on next migration; sniff
|
|
16
|
+
phrase 'Learning-Velocity Metric (EXO 3.0' matches template + migrator variants.
|
|
17
|
+
- **Shadow mirror**: marker bounded by the next-marker scan like its siblings.
|
|
18
|
+
- **No discoverability change**: `/metrics/learning-velocity` rides the
|
|
19
|
+
already-classified `/metrics` prefix — no CapabilityIndex edit needed.
|
|
20
|
+
- **No metric behavior change**: LearningVelocityScorer and its route untouched.
|
|
21
|
+
|
|
22
|
+
## Verification
|
|
23
|
+
|
|
24
|
+
- Learning-velocity unit/integration/e2e + completeness suites green locally;
|
|
25
|
+
`check-repo-invariants` holds; destructive lint clean; `tsc --noEmit` 0.
|
|
26
|
+
|
|
27
|
+
## Rollback
|
|
28
|
+
|
|
29
|
+
Revert this single commit; feature commits untouched.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Side-Effects Review — Owner-Suspect Breaker
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `owner-suspect-breaker`
|
|
4
|
+
**Date:** `2026-06-06`
|
|
5
|
+
**Author:** `Echo (instar-dev agent, autonomous session per Justin's direction)`
|
|
6
|
+
**Second-pass reviewer:** `adversarial reviewer subagent — OBJECT on probe 1 (forever-suspect under load), CONFIRMED BY REPRODUCTION and fixed in-review (absolute per-episode TTL + regression test); probes 2–5 CONCUR`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
Wires the SessionRouter's previously-inert `markOwnerSuspect` hook into a real per-peer circuit: `OwnerSuspectBreaker` (pure core; absolute-TTL half-open windows, default 30s; per-peer `FailureEpisodeLatch` for first-log/one-signal/recovery accounting; state deleted on success). Wiring composes `!isSuspect` into `isMachineAlive`, filters suspect machines from placement candidates (all-suspect → unfiltered fallback), and the new `onOwnerResponsive` router dep closes windows on any delivery ack. Plus the router `chains`-map leak fix (entries deleted when their tail settles while current). Files: `OwnerSuspectBreaker.ts` (new), `SessionRouter.ts` (two small additions), `server.ts` wiring block, tests.
|
|
11
|
+
|
|
12
|
+
## Decision-point inventory
|
|
13
|
+
|
|
14
|
+
- `isMachineAlive` composition — **modify** — a suspect peer reads as not-alive for ROUTING, sending its sessions down the EXISTING failover re-place path. The decision of where they land is unchanged (placement); the decision of when a peer is suspect is new (retry exhaustion, the signal the router already emitted).
|
|
15
|
+
- Placement candidate filter — **modify** — suspect machines excluded unless that empties the set.
|
|
16
|
+
- `OwnerSuspectBreaker` — **add** — per-peer state machine consuming the router's existing exhaustion signal.
|
|
17
|
+
- `chains` cleanup + `onOwnerResponsive` — **add (hygiene/signal)**.
|
|
18
|
+
|
|
19
|
+
## 1. Over-block
|
|
20
|
+
|
|
21
|
+
The reviewer's probe-1 OBJECT was exactly an over-block: with window-extension semantics, a steady <TTL message stream re-marked a suspect peer on every dispatch (no delivery is attempted while suspect → `recordSuccess` unreachable → TTL the only exit → extended forever). Reproduced: a peer healthy from t=40s stayed suspect at t=10min with 31 forced failovers. **Fixed in-review**: `markSuspect` no longer extends an open window (absolute per-episode TTL) — half-open is reached on schedule regardless of traffic, regression-tested. Residual over-block: a genuinely-healthy peer that failed one message's retries pays one 30s window — bounded, and any successful delivery (e.g. a different session's forward in the half-open probe) clears it instantly.
|
|
22
|
+
|
|
23
|
+
## 2. Under-block
|
|
24
|
+
|
|
25
|
+
(a) Suspect-window message POLICY is deliberately out of scope: messages still take the existing re-place path (the only message-preserving path while `queueMessage` is a production no-op). The queue-vs-replace stability trade — and the durable-queue investment it requires — is an operator decision; lettered options go to Justin <!-- tracked: CMT-1109 -->. (b) The no-op `queueMessage` also affects the `placing/transferring` branch (pre-existing; surfaced in the options message). (c) `spawnOnMachine` remains un-breakered (reviewer probe 3: deliberate — the all-suspect fallback depends on it attempting, and it throws-to-caller on failure).
|
|
26
|
+
|
|
27
|
+
## 3. Level-of-abstraction fit / 4. Signal vs authority
|
|
28
|
+
|
|
29
|
+
The breaker consumes the router's OWN exhaustion signal and feeds the router's OWN aliveness dep — no new decision-maker, no second routing brain; placement, CAS, and ownership semantics untouched. Per `docs/signal-vs-authority.md`: the suspect window is a routing-availability signal with bounded lifetime; the failover authority it triggers is the pre-existing path. Composition lives in the wiring (the router stays pure/dep-shaped).
|
|
30
|
+
|
|
31
|
+
## 5. Interactions
|
|
32
|
+
|
|
33
|
+
- **Swap count ("fewer swaps" directive):** unchanged — a session moves at most once per peer-down episode; the breaker removes the OTHER sessions' retry tax, not adds moves (reviewer probe 1 trace, post-fix).
|
|
34
|
+
- **Pins:** a HARD-pinned session does not migrate during a suspect window (placement returns `hard-pin-unavailable`; resolves in place after the TTL — reviewer probe 2).
|
|
35
|
+
- **All-suspect fallback:** placement proceeds unfiltered; `spawnOnMachine` is not `isMachineAlive`-gated so it attempts and throws-to-caller — no wedge (probe 3).
|
|
36
|
+
- **Stale-ownership acks** close the window — correct: the breaker measures transport health to the peer, which any ack proves (probe 4).
|
|
37
|
+
- **Chains cleanup race:** identity-check guard preserves per-session serialization under concurrent re-route; traced clean (probe 5).
|
|
38
|
+
- **Sustained-suspicion signal:** one DegradationReporter record per 10min episode per peer (`SessionPool.ownerDelivery`); reporter's internal cooldown bounds user-facing volume.
|
|
39
|
+
|
|
40
|
+
## 6. External surfaces / 7. Rollback
|
|
41
|
+
|
|
42
|
+
Logs + degradation records only; no API/schema/config/persistent state; no migration. Rollback = revert (the wiring block removal restores the inert-hook status quo; the leak and retry-tax return).
|
|
43
|
+
|
|
44
|
+
## Conclusion
|
|
45
|
+
|
|
46
|
+
The audit's vaguest lead ("load-shedding") resolved into the sharpest finding of the night: a fully-designed breaker hook shipped dead at the wiring layer. The fix is composition, not invention — and the adversarial pass caught a genuine inversion (the busier a recovered peer, the longer it stayed exiled) before it ever ran. Policy beyond the existing semantics goes to the operator, as it should.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Phase 5 — Second-pass review (routing authority → required)
|
|
51
|
+
|
|
52
|
+
The adversarial reviewer ran six probes at line level with live reproduction: (1) forever-suspect under steady traffic — OBJECT, reproduced (peer healthy at t=40s still suspect at t=10min, 31 forced failovers), fixed in-review (absolute per-episode TTL in `markSuspect`) + regression test; (2) swap-count + pin behavior — no added moves; pinned sessions hold through windows; (3) all-suspect fallback — cannot wedge (`spawnOnMachine` un-gated, throws-to-caller); (4) stale-ack window-clearing — semantically correct for a transport-health breaker; (5) chains-cleanup serialization — identity guard traced clean; (6) ran breaker/router unit + dispatch integration + session-pool e2e suites and tsc — all green. **Verdict: CONCUR with the applied fix.**
|