instar 1.3.5 → 1.3.7
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/fingerprint.d.ts +45 -0
- package/dist/feedback-factory/processor/fingerprint.d.ts.map +1 -0
- package/dist/feedback-factory/processor/fingerprint.js +97 -0
- package/dist/feedback-factory/processor/fingerprint.js.map +1 -0
- package/dist/monitoring/FrameworkIssueLedger.d.ts +46 -0
- package/dist/monitoring/FrameworkIssueLedger.d.ts.map +1 -1
- package/dist/monitoring/FrameworkIssueLedger.js +79 -0
- package/dist/monitoring/FrameworkIssueLedger.js.map +1 -1
- package/dist/server/CapabilityIndex.d.ts.map +1 -1
- package/dist/server/CapabilityIndex.js +1 -0
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +9 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/scripts/feedback-factory/_py_fingerprint_ref.py +43 -0
- package/scripts/feedback-factory/fingerprint-corpus.json +38 -0
- package/scripts/feedback-factory/fingerprint-parity.mjs +69 -0
- package/src/data/builtin-manifest.json +46 -46
- package/upgrades/1.3.6.md +43 -0
- package/upgrades/1.3.7.md +29 -0
- package/upgrades/side-effects/feedback-factory-fingerprint.md +36 -0
- package/upgrades/side-effects/framework-issue-capture.md +68 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Side-Effects Review — feedback-factory fingerprint port (Phase 1, increment 1)
|
|
2
|
+
|
|
3
|
+
**Slug:** `feedback-factory-fingerprint`
|
|
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:** Scar (b) only — the dedup fingerprinter. The first, foundational increment of the Phase-1 processor port. Other scars ((a) evidence gate, (c) false-merge/reopen/cycling, (d) lifecycle partitioning) and the processor-job wiring are subsequent increments.
|
|
8
|
+
|
|
9
|
+
## Summary of the change
|
|
10
|
+
|
|
11
|
+
Ports `compute_fingerprint` + its `extract_component` dependency (and the `SEVERITY_PREFIXES`/`SEVERITY_PHRASES` sets) from the reference `the-portal/.claude/scripts/feedback-processor.py` to TypeScript at `src/feedback-factory/processor/fingerprint.ts`. This is the single most correctness-critical port in the migration — it decides whether two reports are the SAME bug. Adds:
|
|
12
|
+
- `src/feedback-factory/processor/fingerprint.ts` — the port (pure functions, no I/O).
|
|
13
|
+
- `tests/unit/feedback-factory/fingerprint.test.ts` — Tier-1 behavioral + both-sides-of-boundary tests + golden-value CI anchors.
|
|
14
|
+
- `scripts/feedback-factory/fingerprint-parity.mjs` + `_py_fingerprint_ref.py` + `fingerprint-corpus.json` — the LOCAL parity gate that runs the REAL reference Python and asserts byte-identical output.
|
|
15
|
+
|
|
16
|
+
The module is **not wired into anything yet** — it is a standalone, importable building block. No route, no job, no behavior change for any agent or user.
|
|
17
|
+
|
|
18
|
+
## The byte-exact-port hazard and how it's handled
|
|
19
|
+
|
|
20
|
+
Per the spec, Python↔JS diverge on regex character classes, `\b`, `.lower()`, and encoding. The parity harness proved this empirically: a first cut diverged on a bare arabic-indic digit because Python's `\b\d+\b` is a Unicode word boundary while JS `\b` is ASCII-only. Fixed by emulating the Unicode boundary with lookarounds (`(?<![\p{L}\p{N}_])\p{Nd}+(?![\p{L}\p{N}_])`). After the fix: **33/33 corpus entries byte-identical to the reference Python**, including non-ASCII digits, em-dash, NBSP, Turkish İ/ı, German ß, hex hashes, and multi-version titles. Dawn's line-by-line review of the port remains a Phase-1 gate before any production cutover.
|
|
21
|
+
|
|
22
|
+
## Seven-dimension review
|
|
23
|
+
|
|
24
|
+
1. **Over/under-reach** — Pure functions, deterministic, no I/O, no global state. Not imported by any runtime path, so it cannot affect existing behavior. Risk is purely *equivalence to the reference*, addressed below.
|
|
25
|
+
2. **Level-of-abstraction fit** — Lives at the processor-logic layer (`src/feedback-factory/processor/`), the correct home for the ported scar logic per the spec's open/operated architecture.
|
|
26
|
+
3. **Signal vs Authority** — N/A; pure computation, no decision authority.
|
|
27
|
+
4. **Interactions** — None. New isolated module; nothing imports it yet. The parity scripts shell out to an external reference path (configurable via `PORTAL_PROCESSOR`) and are LOCAL-only (not CI), so they add no CI dependency on the reference checkout.
|
|
28
|
+
5. **Rollback cost** — Trivial: delete the module + tests + scripts. No data, no migration, no wiring to unwind.
|
|
29
|
+
6. **Migration parity** — N/A. New internal library code shipped in the package; touches no agent-installed file (`.claude/settings.json` / config / CLAUDE.md template / hooks / skills).
|
|
30
|
+
7. **Failure modes** — (a) Port diverges from the reference Python → caught by the parity harness (33/33 now) AND golden-value CI anchors in the unit test (so a future regex/encoding regression fails in CI even without the reference checkout). (b) Reference path absent → parity harness exits 2 with a clear message (it's a local gate, not CI). (c) An adversarial input not in the corpus diverges in production → mitigated by seeding the corpus with the known divergence classes; the corpus is extended as new classes are discovered, and Dawn's review is the human backstop.
|
|
31
|
+
|
|
32
|
+
## Tests
|
|
33
|
+
|
|
34
|
+
- Tier-1 unit (CI): `tests/unit/feedback-factory/fingerprint.test.ts` — `extractComponent` (dotted id, first-word fallback, [TAG] strip, whitelisted-vs-not severity prefix, empty); `computeFingerprint` (32-hex shape, version/int/hash collapse, internal-whitespace collapse, leading-whitespace component divergence, case-insensitivity, type+component incorporation, 3 golden anchors). 14 tests.
|
|
35
|
+
- Parity (local gate, evidence): `scripts/feedback-factory/fingerprint-parity.mjs` → **33/33 byte-identical** to the reference Python.
|
|
36
|
+
- No integration/E2E tier this increment: the module is not yet wired to a route or job; those tiers attach when the processor job + receiver land (subsequent increments). Documented here so the omission is a reasoned decision, not an oversight.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Side-Effects Review — Stage-B auto-capture + funnel (Mentor System §19.2)
|
|
2
|
+
|
|
3
|
+
**Spec:** `docs/specs/FRAMEWORK-ONBOARDING-MENTOR-SPEC.md` (converged 5 iters, approved by Justin)
|
|
4
|
+
**Change:** Adds the Stage-B auto-capture entry point `FrameworkIssueLedger.captureRun()` + a
|
|
5
|
+
`framework_capture_runs` funnel table + `captureStats()` + a read-only route
|
|
6
|
+
`GET /framework-issues/capture-stats`. Builds on §19.1 (the ledger foundation, PR #405).
|
|
7
|
+
**Files:** `src/monitoring/FrameworkIssueLedger.ts`, `src/server/routes.ts`,
|
|
8
|
+
`src/server/CapabilityIndex.ts`, `tests/unit/FrameworkIssueLedger.test.ts`,
|
|
9
|
+
`tests/integration/framework-issues-routes.test.ts`,
|
|
10
|
+
`tests/e2e/framework-issue-ledger-lifecycle.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
|
+
**No.** `captureRun()` is the write-path the mentor tick will call after forensics — it records
|
|
16
|
+
findings and logs the run. It holds no blocking authority. The capture-stats route is read-only
|
|
17
|
+
observability. Signal-only. The decision-bearing components (Stage A, the job, graduation) are
|
|
18
|
+
§19.3–5.
|
|
19
|
+
|
|
20
|
+
## The seven questions
|
|
21
|
+
|
|
22
|
+
1. **Over-block.** None. `captureRun` writes whatever findings it's given (validated against the
|
|
23
|
+
same enum allowlists as `recordObservation`); it rejects only structurally-invalid findings
|
|
24
|
+
(bad bucket/severity), which is correct.
|
|
25
|
+
|
|
26
|
+
2. **Under-block.** The funnel is the explicit guard against the under-detection failure mode it
|
|
27
|
+
exists for: a run that writes nothing is still logged, so an inert/broken writer (runs climbing,
|
|
28
|
+
observations flat) is visible. It does not *interpret* that signal (no alerting yet) — surfacing
|
|
29
|
+
is via the read-only route; an alert/threshold is a later concern (§19.5 observability surface),
|
|
30
|
+
not under-blocking here. There is still no public write route, so no untrusted-write surface.
|
|
31
|
+
|
|
32
|
+
3. **Level-of-abstraction fit.** `captureRun` lives ON the ledger (not a separate DI component)
|
|
33
|
+
because better-sqlite3 has no nested transactions and the capture is a thin orchestration over
|
|
34
|
+
`recordObservation` + `suggestRegressions` + a run-log insert. One atomic entry point for the
|
|
35
|
+
tick to call is the right seam; a separate service would add wiring with no benefit.
|
|
36
|
+
|
|
37
|
+
4. **Signal vs authority.** Compliant. `captureRun` writes signal; regression candidates are
|
|
38
|
+
*surfaced, never auto-linked* (the writer doesn't get to decide a regression — §13.5). Promotion
|
|
39
|
+
and graduation authority stay with the human (§6/§8).
|
|
40
|
+
|
|
41
|
+
5. **Interactions.** `captureRun` calls `recordObservation` per finding (each its own txn — no
|
|
42
|
+
nested-transaction violation), then writes one `framework_capture_runs` row. Episode-collapsing
|
|
43
|
+
in `recordObservation` already prevents double-counting across runs, so re-observing the same
|
|
44
|
+
open issue next tick does not inflate `observationsWritten`. The funnel table is independent of
|
|
45
|
+
the issues/observations tables — no shadowing.
|
|
46
|
+
|
|
47
|
+
6. **External surfaces.** One new read-only route (`/framework-issues/capture-stats`) behind the
|
|
48
|
+
standard Bearer middleware, added to the existing `frameworkIssues` CapabilityIndex entry (no
|
|
49
|
+
new prefix → no discoverability-classification gap). No agent-facing template change needed
|
|
50
|
+
beyond §19.1's. No timing/conversation-state dependence.
|
|
51
|
+
|
|
52
|
+
7. **Rollback cost.** Low. Still dormant — no production caller until the mentor job (§19.4). The
|
|
53
|
+
`framework_capture_runs` table auto-creates at startup (idempotent `CREATE TABLE IF NOT EXISTS`)
|
|
54
|
+
and is harmless read-only data. Back-out = revert; the table can stay or be dropped.
|
|
55
|
+
|
|
56
|
+
## Phase 5 — second-pass
|
|
57
|
+
|
|
58
|
+
**Not required.** Read-only observability + a signal-only write-path; no block/allow, no
|
|
59
|
+
session-lifecycle, nothing named sentinel/guard/gate/watchdog. The spec passed full convergence.
|
|
60
|
+
|
|
61
|
+
## Testing
|
|
62
|
+
|
|
63
|
+
- Tier 1 (unit, +6 = 28 total): captureRun writes findings + reports summary; **every run logged
|
|
64
|
+
to the funnel including a zero-finding run** (inert-writer guard); no double-count across runs;
|
|
65
|
+
regression candidates surfaced not auto-linked; per-framework funnel breakdown; enum guard.
|
|
66
|
+
- Tier 2 (integration, +2 = 11 total): `/framework-issues/capture-stats` 503 + 200-with-funnel.
|
|
67
|
+
- Tier 3 (e2e, +1 = 7 total): a real capture run surfaces in the funnel route on the live server.
|
|
68
|
+
- Affected push-config suite (vs JKHeadley/main): 842 + 299 capability tests green, no regressions.
|