instar 1.3.10 → 1.3.12
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/feedback-factory/processor/transitions.d.ts +44 -0
- package/dist/feedback-factory/processor/transitions.d.ts.map +1 -0
- package/dist/feedback-factory/processor/transitions.js +102 -0
- package/dist/feedback-factory/processor/transitions.js.map +1 -0
- package/dist/monitoring/FrameworkIssueLedger.d.ts +21 -0
- package/dist/monitoring/FrameworkIssueLedger.d.ts.map +1 -1
- package/dist/monitoring/FrameworkIssueLedger.js +74 -2
- package/dist/monitoring/FrameworkIssueLedger.js.map +1 -1
- package/dist/server/CapabilityIndex.d.ts.map +1 -1
- package/dist/server/CapabilityIndex.js +2 -0
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +30 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/scripts/feedback-factory/_py_transitions_ref.py +49 -0
- package/scripts/feedback-factory/transitions-corpus.json +40 -0
- package/scripts/feedback-factory/transitions-parity.mjs +71 -0
- package/src/data/builtin-manifest.json +46 -46
- package/upgrades/1.3.11.md +40 -0
- package/upgrades/1.3.12.md +26 -0
- package/upgrades/side-effects/feedback-factory-transitions.md +34 -0
- package/upgrades/side-effects/mentor-playbook-observability.md +62 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Side-Effects Review — feedback-factory lifecycle state machine (Phase 1, increment 3)
|
|
2
|
+
|
|
3
|
+
**Slug:** `feedback-factory-transitions`
|
|
4
|
+
**Date:** `2026-05-26`
|
|
5
|
+
**Author:** Echo
|
|
6
|
+
**Spec:** `docs/specs/feedback-factory-migration.md` (converged v2, approved by Justin 2026-05-26)
|
|
7
|
+
**Scope:** The pure lifecycle decision logic — `V2_STATES`/`V2_TRANSITIONS`/`TRANSITION_GATES` constants, `can_transition` (:1045, scar a's evidence gate + the state machine + chronic circuit-breaker), and `detect_cycling` (:1139). The DB-coupled drivers (`cmd_transition`, the version-anchored half of `can_transition_to_verified`) are later increments.
|
|
8
|
+
|
|
9
|
+
## Summary of the change
|
|
10
|
+
|
|
11
|
+
Byte-exact port of the above from `the-portal/.claude/scripts/feedback-processor.py` to `src/feedback-factory/processor/transitions.ts`. Pure functions, no I/O. **Not wired into any route/job yet** — no behavioral change. Adds the transitions parity harness + Tier-1 unit tests.
|
|
12
|
+
|
|
13
|
+
This is the heart of scar (a): the evidence gate (terminal transitions to `wontfix`/`closed`/`chronic_escalated` require ≥20-char justification — unified with the `clusters.ts` API hard gate) and the chronic circuit-breaker (auto-block `chronic` at `recurrenceCount ≥ 3`, forcing `chronic_escalated`).
|
|
14
|
+
|
|
15
|
+
## Equivalence verification
|
|
16
|
+
|
|
17
|
+
- **33/33 cases match the reference Python** — both the `allowed` decision AND the exact `reason` string (the reasons interpolate Python's `sorted(set)` list-repr; the port reproduces it via `pyListRepr` so even the diagnostic text is byte-identical), plus all `detect_cycling` results.
|
|
18
|
+
- The check ORDER is preserved exactly (invalid target → unknown current → illegal transition → evidence gate → hard gate → chronic breaker), so the first-failing reason matches the reference for every case.
|
|
19
|
+
|
|
20
|
+
## Seven-dimension review
|
|
21
|
+
|
|
22
|
+
1. **Over/under-reach** — Pure deterministic functions, no I/O, no global state, not imported by any runtime path. Cannot affect existing behavior. The constants are exported read-only.
|
|
23
|
+
2. **Level-of-abstraction fit** — Processor-logic layer, alongside the fingerprint + similarity ports. Correct home. The state machine is data (constants) + a pure validator — no DB coupling, which is why it ports cleanly now (the DB-coupled verification driver waits for the data layer).
|
|
24
|
+
3. **Signal vs Authority** — `can_transition` is the structural evidence gate (scar a): it *enforces* that terminal transitions carry evidence, mirroring the `clusters.ts` API hard gate. This is legitimate authority that already exists in the reference (not new authority introduced by the port). The processor still never force-closes; it validates.
|
|
25
|
+
4. **Interactions** — None. New isolated module; nothing imports it yet. Parity scripts are LOCAL-only (external reference path via `PORTAL_PROCESSOR`).
|
|
26
|
+
5. **Rollback cost** — Trivial: delete the module + tests + scripts.
|
|
27
|
+
6. **Migration parity** — N/A. New internal library code; touches no agent-installed file.
|
|
28
|
+
7. **Failure modes** — (a) Port diverges from reference → caught by the parity harness (33/33, decisions+reasons+cycling) + unit assertions in CI. (b) A new lifecycle state added to the reference but not the port → the "every transition target is a known state" unit test + future parity runs catch drift; Dawn's review is the human backstop. (c) Reason-string repr divergence → parity asserts reasons byte-for-byte.
|
|
29
|
+
|
|
30
|
+
## Tests
|
|
31
|
+
|
|
32
|
+
- Tier-1 unit (CI): `tests/unit/feedback-factory/transitions.test.ts` — state legality, terminal states, evidence gate (both sides of 20 chars), dispatch hard gate, chronic circuit-breaker (recurrence 2 vs 3), cycling detection, constants integrity. 12 tests.
|
|
33
|
+
- Parity (local gate, evidence): `scripts/feedback-factory/transitions-parity.mjs` → **33/33** decisions + reasons + cycling identical to the reference Python.
|
|
34
|
+
- No integration/E2E this increment: not yet wired to a route/job; those tiers attach with the clustering/transition driver. Reasoned decision, documented.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Side-Effects Review — Playbook promotion (non-Echo gate) + observability (§19.5)
|
|
2
|
+
|
|
3
|
+
**Spec:** `docs/specs/FRAMEWORK-ONBOARDING-MENTOR-SPEC.md` (converged 5 iters, approved by Justin)
|
|
4
|
+
**Change:** Two additions to the FrameworkIssueLedger (§19.1) + two read-only-ish routes:
|
|
5
|
+
`promotePlaybook()` (none→candidate→extracted→superseded, with a **non-Echo attestation gate** on
|
|
6
|
+
candidate→extracted, §13.6) and `observability()` (bucket-distribution + leak/probable-loop/extracted
|
|
7
|
+
counts, §15). New routes `POST /framework-issues/:id/promote` and `GET /framework-issues/observability`.
|
|
8
|
+
**Files:** `src/monitoring/FrameworkIssueLedger.ts`, `src/server/routes.ts`,
|
|
9
|
+
`src/server/CapabilityIndex.ts`, `tests/unit/FrameworkIssueLedger.test.ts`,
|
|
10
|
+
`tests/integration/framework-issues-routes.test.ts`, `upgrades/NEXT.md`.
|
|
11
|
+
|
|
12
|
+
## Principle check (Phase 1)
|
|
13
|
+
|
|
14
|
+
Does this involve a decision point that gates info flow / blocks actions / constrains behavior?
|
|
15
|
+
**Yes — and it's a structural authority boundary, the good kind.** `promotePlaybook` enforces that
|
|
16
|
+
the proposing agent (Echo) cannot promote its own lesson into the reusable playbook — candidate→
|
|
17
|
+
extracted requires a non-Echo attestation. This is a *gate on the agent itself*, not authority over
|
|
18
|
+
the user's world; it can only refuse a promotion (signal/anti-gaming), never block another component.
|
|
19
|
+
`observability` is pure read-only telemetry.
|
|
20
|
+
|
|
21
|
+
## The seven questions
|
|
22
|
+
|
|
23
|
+
1. **Over-block.** `promotePlaybook` refuses candidate→extracted by Echo (or an empty attester) —
|
|
24
|
+
intentional (§13.6). Other transitions (none→candidate, →superseded) are unrestricted. No
|
|
25
|
+
legitimate promotion by a non-Echo actor is blocked.
|
|
26
|
+
2. **Under-block.** The attester is a free-string compared case-insensitively against `echo`. A
|
|
27
|
+
determined Echo could pass a different literal — but the route is operator/human-driven and the
|
|
28
|
+
recorded `promoted_by` makes any promotion auditable (a spoofed attester is visible). The gate is
|
|
29
|
+
the structural deterrent + the audit trail is the backstop; matches the `difficultyAttestedBy`
|
|
30
|
+
pattern from §7.3.
|
|
31
|
+
3. **Level-of-abstraction fit.** Both methods live on the ledger that owns the data; the routes are
|
|
32
|
+
thin pass-throughs. `observability` reuses indexed columns (bucket, playbook_status, signature).
|
|
33
|
+
Correct layer.
|
|
34
|
+
4. **Signal vs authority.** Compliant. `observability` is signal. `promotePlaybook`'s only authority
|
|
35
|
+
is to *refuse* a self-promotion (an anti-gaming guard on the proposer) — it never gates messaging,
|
|
36
|
+
sessions, or other components. Promotion to `extracted` is reserved for a non-Echo actor (§13.6).
|
|
37
|
+
5. **Interactions.** Adds a `promoted_by` column via an idempotent `ALTER TABLE … ADD COLUMN`
|
|
38
|
+
(duplicate-column errors swallowed in init) so ledgers created by §19.1/§19.2 (v1.3.5–1.3.9)
|
|
39
|
+
migrate forward on first boot. No interaction with the capture funnel or Stage-A paths.
|
|
40
|
+
6. **External surfaces.** Two routes behind Bearer auth, added to the existing `frameworkIssues`
|
|
41
|
+
CapabilityIndex entry (no new prefix → no discoverability gap). No template/config change.
|
|
42
|
+
7. **Rollback cost.** Low. Revert removes the routes/methods; the `promoted_by` column is harmless if
|
|
43
|
+
left. No data migration beyond the additive column.
|
|
44
|
+
|
|
45
|
+
## Phase 5 — second-pass
|
|
46
|
+
|
|
47
|
+
**Not required.** The promotion gate is a single pure attestation check (`promotedBy != echo`),
|
|
48
|
+
unit-tested on both sides (Echo refused; non-Echo allowed + recorded); `observability` is read-only.
|
|
49
|
+
No session lifecycle, no spawning, no blocking of another component, nothing named
|
|
50
|
+
sentinel/guard/watchdog. The decision-bearing live loop (§19.4) already carried its dedicated
|
|
51
|
+
second-pass.
|
|
52
|
+
|
|
53
|
+
## Testing
|
|
54
|
+
|
|
55
|
+
- Tier 1 (unit, +6): promotePlaybook none→candidate by any actor; **candidate→extracted REFUSED for
|
|
56
|
+
Echo / empty attester**; allowed + `promoted_by` recorded for a non-Echo actor; invalid-status
|
|
57
|
+
guard; unknown-issue null; observability bucket-distribution + leak/extracted counts.
|
|
58
|
+
- Tier 2 (integration, +5): observability 503/200; promote rejects Echo (400), allows non-Echo (200),
|
|
59
|
+
404 unknown.
|
|
60
|
+
- route-completeness + capabilities-discoverability gates pass (new catch uses `instanceof`; new
|
|
61
|
+
routes fall under the classified `/framework-issues` prefix).
|
|
62
|
+
- Affected push-config suite green vs canonical main; route docs-coverage 56% ≥ 55% floor.
|