@dzhechkov/harness-core 0.8.6 → 0.8.10

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 (105) hide show
  1. package/.dz-manifest.json +257 -53
  2. package/README.md +48 -1
  3. package/dist/amendment-trace.d.ts.map +1 -1
  4. package/dist/amendment-trace.js +12 -1
  5. package/dist/amendment-trace.js.map +1 -1
  6. package/dist/compounding.d.ts +54 -0
  7. package/dist/compounding.d.ts.map +1 -1
  8. package/dist/compounding.js +221 -1
  9. package/dist/compounding.js.map +1 -1
  10. package/dist/eta.d.ts +92 -0
  11. package/dist/eta.d.ts.map +1 -0
  12. package/dist/eta.js +488 -0
  13. package/dist/eta.js.map +1 -0
  14. package/dist/feature-adr-checkpoints.js +1 -1
  15. package/dist/feature-adr-decision-recall.d.ts +167 -0
  16. package/dist/feature-adr-decision-recall.d.ts.map +1 -0
  17. package/dist/feature-adr-decision-recall.js +519 -0
  18. package/dist/feature-adr-decision-recall.js.map +1 -0
  19. package/dist/feature-adr-landing.d.ts +37 -0
  20. package/dist/feature-adr-landing.d.ts.map +1 -0
  21. package/dist/feature-adr-landing.js +59 -0
  22. package/dist/feature-adr-landing.js.map +1 -0
  23. package/dist/feature-adr-routing.d.ts +2 -2
  24. package/dist/feature-adr-routing.d.ts.map +1 -1
  25. package/dist/feature-adr-routing.js +7 -11
  26. package/dist/feature-adr-routing.js.map +1 -1
  27. package/dist/guard-promotion.d.ts +41 -0
  28. package/dist/guard-promotion.d.ts.map +1 -1
  29. package/dist/guard-promotion.js +218 -4
  30. package/dist/guard-promotion.js.map +1 -1
  31. package/dist/guard-volume.d.ts +108 -0
  32. package/dist/guard-volume.d.ts.map +1 -0
  33. package/dist/guard-volume.js +536 -0
  34. package/dist/guard-volume.js.map +1 -0
  35. package/dist/guard.d.ts +9 -0
  36. package/dist/guard.d.ts.map +1 -1
  37. package/dist/guard.js +55 -4
  38. package/dist/guard.js.map +1 -1
  39. package/dist/index.d.ts +16 -2
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +11 -1
  42. package/dist/index.js.map +1 -1
  43. package/dist/integration-apply.d.ts +25 -0
  44. package/dist/integration-apply.d.ts.map +1 -0
  45. package/dist/integration-apply.js +299 -0
  46. package/dist/integration-apply.js.map +1 -0
  47. package/dist/integration-evidence.d.ts +46 -0
  48. package/dist/integration-evidence.d.ts.map +1 -0
  49. package/dist/integration-evidence.js +44 -0
  50. package/dist/integration-evidence.js.map +1 -0
  51. package/dist/integration-probe-worker.d.ts +22 -0
  52. package/dist/integration-probe-worker.d.ts.map +1 -0
  53. package/dist/integration-probe-worker.js +334 -0
  54. package/dist/integration-probe-worker.js.map +1 -0
  55. package/dist/integrations-verify.d.ts +60 -0
  56. package/dist/integrations-verify.d.ts.map +1 -0
  57. package/dist/integrations-verify.js +194 -0
  58. package/dist/integrations-verify.js.map +1 -0
  59. package/dist/lesson-generalization.d.ts +29 -0
  60. package/dist/lesson-generalization.d.ts.map +1 -0
  61. package/dist/lesson-generalization.js +84 -0
  62. package/dist/lesson-generalization.js.map +1 -0
  63. package/dist/operations.d.ts +27 -0
  64. package/dist/operations.d.ts.map +1 -1
  65. package/dist/operations.js +178 -2
  66. package/dist/operations.js.map +1 -1
  67. package/dist/patterns.d.ts +27 -1
  68. package/dist/patterns.d.ts.map +1 -1
  69. package/dist/patterns.js +211 -45
  70. package/dist/patterns.js.map +1 -1
  71. package/dist/setup.d.ts.map +1 -1
  72. package/dist/setup.js +20 -17
  73. package/dist/setup.js.map +1 -1
  74. package/dist/target-integrations.d.ts +65 -0
  75. package/dist/target-integrations.d.ts.map +1 -0
  76. package/dist/target-integrations.js +152 -0
  77. package/dist/target-integrations.js.map +1 -0
  78. package/dist/vector-tier.d.ts +6 -1
  79. package/dist/vector-tier.d.ts.map +1 -1
  80. package/dist/vector-tier.js +32 -7
  81. package/dist/vector-tier.js.map +1 -1
  82. package/package.json +9 -8
  83. package/sbom.json +562 -52
  84. package/src/amendment-trace.ts +12 -1
  85. package/src/compounding.ts +300 -1
  86. package/src/eta.ts +590 -0
  87. package/src/feature-adr-checkpoints.ts +1 -1
  88. package/src/feature-adr-decision-recall.ts +652 -0
  89. package/src/feature-adr-landing.ts +109 -0
  90. package/src/feature-adr-routing.ts +7 -11
  91. package/src/guard-promotion.ts +245 -4
  92. package/src/guard-volume.ts +752 -0
  93. package/src/guard.ts +70 -4
  94. package/src/index.ts +63 -2
  95. package/src/integration-apply.ts +332 -0
  96. package/src/integration-evidence.ts +89 -0
  97. package/src/integration-probe-worker.ts +310 -0
  98. package/src/integration-receipts/claude-code/mcp/2.1.235.json +35 -0
  99. package/src/integrations-verify.ts +258 -0
  100. package/src/lesson-generalization.ts +115 -0
  101. package/src/operations.ts +199 -2
  102. package/src/patterns.ts +252 -43
  103. package/src/setup.ts +20 -17
  104. package/src/target-integrations.ts +225 -0
  105. package/src/vector-tier.ts +44 -14
package/README.md CHANGED
@@ -31,6 +31,20 @@ that works.
31
31
 
32
32
  ## What it provides
33
33
 
34
+ ### Evidence-gated companion integrations
35
+
36
+ `runInit` reads and aggregates adjacent `INTEGRATIONS.json` manifests once per run. Requested
37
+ components always produce one of two explicit outcomes: a receipt-backed emission or a named refusal.
38
+ The current measured admission set is one cell—Claude Code `2.1.235`, project MCP—qualified by a
39
+ non-executing live registration probe. The other 19 cells refuse by stable reason code. A
40
+ pending/committed `.dz/integrations-ownership.json` journal prevents an observed user value or forged
41
+ ledger from becoming overwrite authority; AgentDB setup uses this same writer and adopts only its
42
+ known historical shape.
43
+
44
+ `--allow-integrations <sha256:…>` binds consent to the exact aggregate. `--no-integrations` is an
45
+ explicit skills-only short circuit. `--no-verify` cannot authorize emission. A Claude
46
+ `Pending approval` observation is registered but `ready: false`.
47
+
34
48
  | Module | Exports | Purpose |
35
49
  |---|---|---|
36
50
  | `skills` | `loadSkillFromDir`, `listSkills`, `listSkillsDetailed`, `describeSkillLoadFailure`, `formatSkillLoadFailures`, `formatSkillApplyFailures`, `discoverSkillIds` | Read skill directories into `CanonicalSkill` objects. **Two listing functions, deliberately:** `listSkills` THROWS on the first unloadable skill and always will — it is a published export, and silently turning it into a skip-and-collect function would downgrade every unknown third-party consumer from fail-closed to fail-silent without their consent (an incomplete catalogue reported as complete); a pinned regression test asserts it still throws. `listSkillsDetailed` is the total variant callers ask for BY NAME: it returns `{skills, failures}` with a per-id `try/catch`, so one unparseable `SKILL.md` never hides the ones after it (order-independence is the tested property — the offender first, middle or last yields the same counts). Every failure is NAMED — `describeSkillLoadFailure` is the single place a pathless parser throw becomes `{id, absolute path, verbatim reason, first line}`, because the parser is handed only TEXT and can never supply a path. `formatSkillLoadFailures` renders that list for stderr in one of two modes chosen by the CALLER (absolute paths for `dz list`/`dz sync`; relative-to-package for `dz install`, where a `node_modules/**` path is not actionable) |
@@ -45,9 +59,11 @@ that works.
45
59
  | `feature-adr-setup` (P3) | `renderGuardsConfig`, `renderGuardsRunner` | Scaffolds deterministic guard tests into a TARGET project: `guards.config.json` + a zero-dependency `check.mjs` runner (loc-cap, secret-scan, frozen-file sha256 pins, waivers-with-reasons) — `dz feature-adr-setup --guards` |
46
60
  | `usage` | `computeUsage`, `TOKEN_WEIGHTS`, `readUsageLimits`, `deriveUsageCalibration` | Read-only Claude usage ESTIMATE behind `dz usage`. Tokens are COST-WEIGHTED input-equivalents (input 1x, cache-write 1.25x / 1h 2x, cache-read 0.1x, output 5x) — a flat sum is 89-99.7% cache-read (MEASURED) and tracks conversation length, not work. Scans subagent transcripts too (`<session>/subagents/*.jsonl`), follows no symlinks, reads only regular files (symlinked FILES and DIRECTORY components alike are skipped), and caps the walk BY RECENCY so a huge history cannot discard current usage. `pct` stays `null` while limits are unconfigured — an unconfigured estimate is never dressed up as a number |
47
61
  | `cost-ledger` | `deriveCostLedger`, `buildCostLedger`, `verifyCostLedgerReport`, `stageCostAggregates`, `renderCostLedger`, `writeCostLedgerJsonl`, `COST_LEDGER_SCOPE` | Per-stage cost ledger behind `dz usage --by-stage`. A feature-adr run reports ONE number; this joins the workflow's own `stageLabel()` strings to the per-agent transcripts the harness already writes, so a run becomes an itemized receipt. POST-HOC DERIVER, not a writer — no workflow edit, and a KILLED run is still derivable. The invariant: `accounted + unaccounted === runTotal` and `accounted + doubleAttributed === Σ stages`, RAW integer equality (rounding happens exactly once, per sample, at extraction), re-derived from the emitted report by `verifyCostLedgerReport` — the writer clamps, the verifier enforces. A mismatch is a NAMED defect (`Unaccounted`, `DoubleAttributed`, `ForeignSample`, `MissingStageTranscript`, `MalformedRecord`), never a rounding remainder, so `epsilon` defaults to 0. The run total comes from the run's transcript DIRECTORY LISTING, NOT the record's own `totalTokens` — that field is exactly `Σ workflowProgress[].tokens` in 29 of 29 recorded runs (MEASURED), so an invariant against it can never fail. Both sides share ONE estimator with `dz usage` (`weightedTokensOf`). `stageCostAggregates` is a pure feed-forward reader for auto-cost routing that EXCLUDES non-reconciling runs; wiring it into routing is deliberately out of scope. HONEST SCOPE, printed by every surface: local transcript ESTIMATES, not billed amounts — it catches ATTRIBUTION errors, NOT pricing errors; `hasKnownPricing` marks rows priced by the sonnet-class fallback. `INSUFFICIENT_DATA` is a distinct verdict, never collapsed into `BALANCED` |
48
- | `compounding` | `mulberry32`, `bootstrapDelta`, `decidePromotion`, `assembleCompoundingReport` | Pure learning-loop payoff engine behind `dz compounding`: seeded deterministic bootstrap (conservative nearest-rank lower-95), promotion that refuses non-finite/malformed input and anything under 5 samples per arm, and dz-native measurements (pool write-only ratio, guard trajectory by RATE, replay readiness over unique untruncated prompt events). A gate without data says INSUFFICIENT_DATA never a verdict. Compaction keeps the newest query-bearing rows verbatim and aggregates ONLY the rest (read totals are invariant across compactions). Also reports EVENT-CHAIN health of the evidence logs it computed from (`evidenceLogs` in, `instrumentation.chains` out) — verified / defect kinds / uncovered pre-chain prefix, with no logs handed in producing no line at all rather than a vacuous "clean" |
62
+ | `compounding` | `mulberry32`, `bootstrapDelta`, `decidePromotion`, `assembleCompoundingReport`, `assembleLessonToRuleFunnel` | Pure learning-loop payoff engine behind `dz compounding`: seeded deterministic bootstrap (conservative nearest-rank lower-95), promotion that refuses non-finite/malformed input and anything under 5 samples per arm, and dz-native measurements (pool write-only ratio, guard trajectory by RATE, replay readiness over unique untruncated prompt events). Its lesson-to-rule funnel reports UTC calendar-month `eligible attempted → accepted → executions` counts from prospective promotion-run and anchored guard-audit evidence. Zero alone is not a finding: only a non-empty predecessor followed by an empty named successor in three consecutive measured months produces one; unavailable evidence remains `NOT MEASURED` with its reason. Compaction keeps the newest query-bearing rows verbatim and aggregates ONLY the rest (read totals are invariant across compactions). Also reports EVENT-CHAIN health of the evidence logs it computed from (`evidenceLogs` in, `instrumentation.chains` out) — verified / defect kinds / uncovered pre-chain prefix, with no logs handed in producing no line at all rather than a vacuous "clean" |
49
63
  | `event-chain` | `fnv1a32`, `nextChainFields`, `appendChainedLines`, `chainRewrite`, `guardedRewrite`, `verifyEventChain`, `EVENT_CHAIN_SCOPE` | Pure hash-chain over the two learning-evidence logs (`.dz/recall-usage.jsonl`, `.dz/guard-audit.jsonl`): each appended record carries `seq` + `prevHash` (FNV-1a over the previous line AS WRITTEN, so key order cannot make writer and verifier disagree), derived from the LAST LINE ONLY so a per-prompt hook stays O(1). `verifyEventChain` names eight classes — `BrokenLink`, `DuplicateSeq`, `NonMonotonicSeq`, `TornTail`, `DoubleCounted`, `LedgerImbalance`, `MalformedLedger`, `ClaimInterrupted`. The last four exist because a rewriter must not be able to certify itself: the compaction ledger's arithmetic (`Σ weight + dropped === source`, `dropped ∈ [0, source]`) is enforced with NO clamps in the verifier (the clamp belongs to the writer), a damaged ledger line is a defect rather than a silently-disabled check, and a claim that never reached its `throughSeq` — because the segment restarted or the file ended — is reported instead of escaping through the discontinuity. `guardedRewrite` is the concurrency guard for any whole-file rewrite: exclusive lock, plus a re-read of the live file after computing the new text and BEFORE the rename, so a concurrent append aborts the attempt and is folded into a bounded retry rather than overwritten (it narrows the read→rename window; it cannot close it, and says so). Records written before chaining existed stay LEGAL and are counted as an uncovered `preChainPrefix`; an unreadable tail never blocks a write (fresh MARKED segment — an unreadable tail WINDOW is distinguished from an empty file — and the appender starts on a new line so one torn write cannot eat the next record); an unmarked restart is reported once and then re-anchored, so one incident is one defect instead of a cascade. HONEST SCOPE, carried in every result and printed by every surface: corruption detection for our own bugs — FNV-1a is not cryptography, its collisions are constructible, the threat model has no adversary, and a regression test fails if the module regrows tamper-proofing vocabulary |
50
64
  | `feature-adr-checkpoints` | `checkpointInputHash`, `decideCheckpointResume`, `parseCheckpointRead`, `serializeCheckpoint`, `fnv1a64`, `CKPT_SCHEMA_VERSION`, `STAGE_ARTIFACTS`, `DESIGN_SUBSTAGES`, `designStageKey`, `decideDesignFanResume`, `parseArtifactProbe` | The PURE half of feature-adr's durable per-stage checkpoints (`features/<slug>/.fa-state/checkpoints.jsonl`): a dead L/XL run — or the standard stop-after-plan re-invoke — resumes completed stages instead of re-spending them. Resume = INPUT-identity (64-bit salted FNV over a schema-versioned JSON tuple incl. upstream stage results) + presence of EVERY tier-required artifact; a stale-input hash never resumes in ANY mode (`force` relaxes only the artifact probe — the tested load-bearing property). HONEST SCOPE: it does NOT fingerprint the working tree (a crash-resume legitimately sees the dead run's uncommitted writes) — after manual edits use `resume:'never'` and re-QE. Null results are never persisted or resumable; a stage-identifiable corrupt record ERASES its older entry (last-wins holds for corruption too); the code stage's persist predicate is now an ALLOWLIST (`codeCheckpointPersistAllowed` + `codeStageResultShapeValid`, ADR-003 Condition 3): ONLY `landed` on a barrier-required run and `synchronous` on a non-barrier run may be checkpointed — inconclusive, not-landed, garbage and a mislabeled `synchronous` are all refused, and the `landing-v2` hash token makes every pre-protocol code checkpoint stale. **Since 0.5.3 the design fan is checkpointed PER SIBLING** (`design:requirements` / `adr` / `qcsd` / `architecture` via `designStageKey`), so one dead agent no longer discards three finished siblings, and a fix to one step's instructions invalidates that step alone. What may be CONSUMED is judged separately from what may be WRITTEN: `decideDesignFanResume` returns a named reason (`substage-missing` / `artifact-missing` / `probe-not-established` / `ok`) and the workflow REFUSES at the Step-5/6 boundary rather than planning off a partial design. The artifact half is judged against a POST-RUN probe that never prints filenames (`[ -f <exact rel> ]` per required artifact) — a listing is a list of filenames, and a file whose NAME ends in a newline was measured satisfying the requirement for the real file. `parseArtifactProbe` then validates the WHOLE transcript, because the probe is relayed by a model: an agent that merely NARRATES the expected output emits the token byte-identically. Inconclusive is never a pass. The workflow mirrors this inline (wiring-guarded); RU: чекпоинт после каждой дорогой стадии — упавший ран возобновляется, а не пере-тратит завершённое; веер проектирования — по каждому участнику отдельно, а неполный веер получает отказ, а не запись в лог |
65
+ | `feature-adr-decision-recall` | `buildDecisionContext`, `normalizeDecisionRecall`, `parseDecisionRecallFrame`, `mergeDecisionRecallEvents`, `reduceDecisionRecallMetrics`, `summarizeDecisionRecallReceipts`, command builders | The PURE half of an advisory experiment at two live feature-adr decisions: Step 3 ADR-alternative selection and Step 6 plan-route selection. Each context has its own coarse lesson-bandit domain; a strict framed transport accepts at most three complete hits and every empty/error/timeout/parse/transport case returns an empty prompt block. Versioned `entered` / `recalled` / `applied` / optional `owner-label` events in `features/<slug>/.fa-state/decision-recall.jsonl` retain logical decision and attempt identity, per-lesson collision witnesses, exact application dispositions, unknown/conflict populations, and explicit numerators/denominators for offline receipt, application, relevance, and repeat-hit analysis. No metric or threshold can affect a stage verdict. The timing hypothesis is external `[SRC], n=1`; book queries did not supply evidence about when retrieval should run. |
66
+ | `eta` | `parseCheckpointLines`, `segmentRun`, `extractStageSamples`, `estimateEta`, `formatEta`, `ETA_MAX_STAGE_MS` | Pure feature-adr ETA calibration over already-read checkpoint JSONL: malformed/unstamped records stay unknown, resume slices reduce to one sample per run and stage, tier comes only from `router.result.tier`, and every remaining `(tier, stage)` needs at least three distinct runs. Codex-shaped code timing folds dispatch through its next landing witness and renders p25–p75; the typed insufficient/no-checkpoint variants cannot carry a numeric estimate. No filesystem or ambient clock lives in this module — the CLI owns both. |
51
67
  | `discrimination-gate` | `planDiscriminationCheck`, `classifyExecutionEvidence`, `classifyDiscrimination`, `DiscriminationVerdict`, `BaseOutcome`, `TipOutcome`, `ExecutionEvidence`, `CannotIsolateReason`, `DiscriminationFinding`, `MeasurementValid`, `PrimaryAction` | The PURE §42 test-discrimination engine behind `dz discrimination-check`: it plans the pre-feature worktree check and classifies the observations the executor feeds back. **Every trust verdict is gated on execution evidence** (ADR-001, feature wave1-instrument-repair): `classifyExecutionEvidence` turns one captured run into `{exitCode, runner, failureKind, testsExecuted, targetSeen}` off the MEASURED vitest / node --test output shapes (reusing `mutation-gate`'s single regex family), and a row whose outcome VALUE is not backed by that evidence degrades to `CANNOT_ISOLATE` with a typed reason instead of minting trust. **Seven verdicts** (was four): `DISCRIMINATES` (assertion-red at base, evidenced) · `DISCRIMINATES_VIA_ERROR` (evidenced load error at base + evidenced pass at TIP) · `NON_DISCRIMINATING` (evidenced pass at base — a proven false green) · `TEST_FILE_ABSENT` (the named check is not a regular file — stat+isFile, before any worktree) · `LOAD_ERROR_AT_BOTH_REVS` (could not execute at EITHER rev — zero signal) · `FAILS_AT_TIP` (the feature's own test is red WITH the feature) · `CANNOT_ISOLATE` (no established observation; reason ∈ no-execution-evidence | unrecognised-runner-output | no-tests-executed | inconsistent-evidence | tip-control-missing | tip-evidence-missing | timeout). The result carries `findings[]` (one per distinct non-clean verdict — the scalar `aggregate` can only name the worst), plus two ORTHOGONAL axes: `measurementValid` (did the instrument measure at all: `true | false | 'partial'`) and `primaryAction` (the single most urgent operator repair). PARSE-NEVER-SYNTHESIZE: an outcome contradicted by its own evidence is rejected as `inconsistent-evidence`, never reinterpreted. HONEST SCOPE: the bar is "a recognized runner demonstrably executed the named test", NOT resistance to an output-imitating runner; recognising vitest/node --test shapes is in scope, CHOOSING the runner is not. The singular `finding` remains as a DEPRECATED one-release alias for `findings[0] ?? null`. RU: вердикт доверия теперь требует доказательства исполнения — «упало» без доказательства больше не считается доказательством |
52
68
  | `feature-adr-routing` (landed barrier) | `sourceExpectedCodeTargets`, `validateExpectedTargetsBlock`, `codeLandedBarrierPlan`, `decideCodeLanding`, `codeLandedBarrierHasLanded`, `codeLandingProbeCmd`, `parseLandingSignal`, `verifyPreCodeBaseline`, `preCodeBaselineCaptureCmd`, `posixCksum`, `LANDING_PROTOCOL_VERSION`, `LANDING_HASH_TOKEN` | The PURE half of feature-adr's Step-7.5 Codex landing barrier (ADR-003, feature wave1-instrument-repair). Expected targets are SOURCED with an explicit precedence — a non-empty `args` override REPLACES the plan's `EXPECTED_CODE_TARGETS:` block (and narrowing to an all-unpollable set returns EMPTY with reason `override-unpollable`, never a silent fall-through), while Codex's own self-declared paths land in `scrapeDiagnostic` and can NEVER establish or match — the agent under test does not declare its own success criteria. An enabled barrier with no established target is `mode:'inconclusive'`, not the deleted `any-code-change` fallback that read an unrelated dirty file as landed. Landing is a DELTA, not dirtiness: `preCodeBaselineCaptureCmd` records `git hash-object` per pre-existing dirty path with a `count=/cksum=` trailer, `verifyPreCodeBaseline` refuses any truncated or edited baseline as `baseline-unverified` (a truncated baseline makes everything look landed), and a path counts only when it is absent from the baseline or its hash CHANGED. `parseLandingSignal` is the single normalization point — empty stdout is `probe-failure`, unparseable text is `malformed-signal`, and neither is ever a landing. RU: «файл грязный» ≠ «кодер его написал»; барьер теперь умеет сказать «не знаю» |
53
69
  | `feature-adr-training-pairs` (in `feature-adr-checkpoints`) | `buildTrainingPair`, `serializeTrainingPair`, `trainingPairPath`, `trainingPairAppendCmd`, `modelFamily`, `TRAINPAIR_SCHEMA_VERSION`, `TRAINPAIR_MAX_IO_CHARS`, `TRAINPAIR_PRIVACY_NOTE` | The PURE half of feature-adr TRAINING-PAIR capture (backlog 70e0f083): every checkpointed stage emits one SFT-ready JSONL record — STAGE INPUT (full prompt/context) → STAGE OUTPUT (artifact/result) → EVALUATION {QE grade, gradedBy, lessonsInjected} with provenance {model, FAMILY ∈ claude/codex, role} — to `.dz/fa-training/<slug>/<stage>.jsonl` (one file per stage), raw material for future local-model fine-tuning. FAMILY is load-bearing: the downstream dataset must honour the cross-model rule (QE pairs from a DIFFERENT family than the coder). Oversize guard: input+output over 48k chars is TRUNCATED with a named marker + full-text fnv1a64 — never silently dropped, never unbounded. A stage without a QE grade (router) records `grade:null` honestly. Deterministic: `ts` is passed in (the workflow fills it shell-side). Capture is default-ON in the workflow, opt-out `args.captureTrainingPairs:false`, non-blocking (a capture failure never fails the run). PRIVACY: pairs may contain target-repo code; the capture dir carries a README note; NOT gitignored by explicit owner decision. RU: тренировочные пары вход→выход→оценка с каждого прогона feature-adr — сырьё для будущей локальной модели |
@@ -351,8 +367,39 @@ firing result is still data only: `autoAction` is always `false`, and
351
367
  `renderRestartDecisionLog` exposes the effective policy, evidence, source, and reason without
352
368
  persisting anything or restarting a stage.
353
369
 
370
+ ## Volume shadow observations
371
+
372
+ Publish guard evaluation accepts an optional `GuardFacts.volume` input and emits four additive,
373
+ versioned `volume-shadow/v1` observations: `template-context-token-weight`,
374
+ `template-context-largest-file-share`, `feature-artifact-diff-ratio`, and
375
+ `feature-tier-artifact-set`. The template total reports standing rules/commands separately from
376
+ conditional full-skill bodies; their sum is a configured/invokable context envelope, not measured
377
+ per-session consumption. Feature ratios retain numerator, git base/head, feature-path exclusion,
378
+ and the `git-unified-diff-bytes/v1` proxy method.
379
+
380
+ The measured 2026-08-30 ranges are dated starting points, not norms. Missing, incomplete, escaped,
381
+ ambiguous, capped, and zero-denominator evidence becomes a typed `unknown` observation. Every volume
382
+ rule is forced SOFT even under hostile HARD configuration, and observations do not participate in
383
+ the verdict reducer. Source comments, comment density, and prose classification are outside this
384
+ decision domain: justification is neither scored nor offered as a trimming target.
385
+
354
386
  ## Status
355
387
 
388
+ `0.8.10` — staged, not published. Adds the four bounded `volume-shadow/v1` observations and their
389
+ immutable SOFT belt; incomplete evidence remains visible as unknown without changing the verdict.
390
+
391
+ `0.8.9` — staged, not published. Adds the pure decision-point micro-recall contract, strict
392
+ fail-open transport/receipt reducers, post-hoc numerator/denominator metrics, and mutation-defended
393
+ advisory prompt isolation. This is experiment instrumentation, not evidence of local effectiveness.
394
+
395
+ `0.8.8` — staged, not published. Adds evidence-gated `INTEGRATIONS.json` orchestration, one
396
+ receipt-qualified Claude project-MCP emitter, explicit refusal outcomes, and the ownership journal.
397
+
398
+ `0.8.7` — **pure same-tier feature-adr ETA calibration.** `eta.ts` parses timestamped checkpoint
399
+ history, refuses any remaining stage with fewer than three distinct runs, folds Codex dispatch to
400
+ its next landing witness, applies bounded current-run pace evidence, and returns a typed point/range/
401
+ insufficient result with an explicit date window. Filesystem reads remain in harness-cli.
402
+
356
403
  `0.8.5` — **the pure `restart-advisor/1` API for an explicit, advisory-only code-stage
357
404
  restart recommendation.** The CLI supplies D/2 defaults; core itself refuses absent policy.
358
405
  Publication and live feature-adr integration remain outside this implementation step.
@@ -1 +1 @@
1
- {"version":3,"file":"amendment-trace.d.ts","sourceRoot":"","sources":["../src/amendment-trace.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"amendment-trace.d.ts","sourceRoot":"","sources":["../src/amendment-trace.ts"],"names":[],"mappings":"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"}
@@ -262,7 +262,18 @@ export const AMENDMENT_VACUITY_NOTE = 'note: this checks that each amendment RES
262
262
  * are named later than ideation guesses); the SUBJECT may not.
263
263
  */
264
264
  export function amendmentSubject(raw) {
265
- const withoutPointer = raw.split(/→\s*tests?\s/)[0] ?? '';
265
+ // BOTH arrows, for the same reason extractTestIds accepts both: the corpus carries `->` and `→`
266
+ // from two authors, and splitting on only one leaves the whole Confirmation sentence inside the
267
+ // "subject". Two documents that word their Confirmation differently — which they are entitled to,
268
+ // since only the SUBJECT must survive verbatim — then read as a subject change. MEASURED
269
+ // 2026-08-30 on os-matrix-pack-smoke: all 9 amendments resolved to real tests, yet all 9 reported
270
+ // "the plan describes a DIFFERENT change"; the ideation used `->` throughout.
271
+ // The pointer region starts at `Confirmation:` — everything from there on is HOW the amendment is
272
+ // proven (which fixture, which arrow form, which test name), and the rule says only the pointer may
273
+ // differ between the two documents. Splitting at the arrow alone left the Confirmation PROSE inside
274
+ // the subject, so two documents describing the same fixture in different words read as a subject
275
+ // change. Both arrows are still handled, for corpora that omit the `Confirmation:` lead-in.
276
+ const withoutPointer = raw.split(/Confirmation\s*:/i)[0]?.split(/(?:\u2192|->)\s*tests?\s/)[0] ?? '';
266
277
  // Strip ONLY the row's furniture: bullet/table marks, the bold id, an optional `(source)` tag and
267
278
  // a colon. An earlier version consumed up to 80 characters after the id, which ate the SUBJECT
268
279
  // itself whenever a row carried no `(source):` tag — the checker then compared two truncations
@@ -1 +1 @@
1
- {"version":3,"file":"amendment-trace.js","sourceRoot":"","sources":["../src/amendment-trace.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"amendment-trace.js","sourceRoot":"","sources":["../src/amendment-trace.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,7 @@
14
14
  *
15
15
  * Everything here is PURE: callers gather facts (files, store rows); this module only computes.
16
16
  */
17
+ import { type PromotionAcceptanceEvidence, type PromotionRunEvidence } from './guard-promotion.js';
17
18
  /** Deterministic PRNG — same seed, same stream, byte-identical reports. */
18
19
  export declare function mulberry32(seed: number): () => number;
19
20
  export declare const BOOTSTRAP_RESAMPLES = 5000;
@@ -72,8 +73,57 @@ export interface ReplayInstance {
72
73
  export declare function replayableInstances(usage: readonly UsageEvent[], lessonText?: ReadonlyMap<string, string>): ReplayInstance[];
73
74
  export interface GuardEvent {
74
75
  readonly ts: string;
76
+ readonly op?: 'publish' | 'teach' | 'consolidate' | 'reindex';
75
77
  readonly verdict: string;
76
78
  readonly rules: readonly string[];
79
+ readonly violations?: readonly {
80
+ readonly rule: string;
81
+ readonly contentAnchor?: string;
82
+ }[];
83
+ }
84
+ export type FunnelEvidenceSource<T> = {
85
+ readonly status: 'measured';
86
+ readonly rows: readonly T[];
87
+ } | {
88
+ readonly status: 'not-measured';
89
+ readonly reason: string;
90
+ };
91
+ export interface LessonToRuleFunnelFacts {
92
+ readonly promotionRuns: FunnelEvidenceSource<PromotionRunEvidence>;
93
+ readonly guardAudits: FunnelEvidenceSource<GuardEvent>;
94
+ readonly promotionAcceptances?: readonly PromotionAcceptanceEvidence[];
95
+ readonly truncatedPromotionPeriods?: readonly string[];
96
+ readonly acceptanceHistoryComplete?: boolean;
97
+ }
98
+ export type LessonToRuleStage = 'eligible' | 'attempted' | 'accepted' | 'executions';
99
+ export type FunnelStageMeasurement = {
100
+ readonly status: 'measured';
101
+ readonly value: number;
102
+ } | {
103
+ readonly status: 'not-measured';
104
+ readonly reason: string;
105
+ };
106
+ export interface LessonToRuleFunnelPeriod {
107
+ readonly period: string;
108
+ readonly eligible: FunnelStageMeasurement;
109
+ readonly attempted: FunnelStageMeasurement;
110
+ readonly accepted: FunnelStageMeasurement;
111
+ readonly executions: FunnelStageMeasurement;
112
+ }
113
+ export interface LessonToRuleFunnelFinding {
114
+ readonly predecessor: LessonToRuleStage;
115
+ readonly stage: LessonToRuleStage;
116
+ readonly fromPeriod: string;
117
+ readonly toPeriod: string;
118
+ readonly counts: readonly {
119
+ readonly period: string;
120
+ readonly predecessor: number;
121
+ readonly successor: number;
122
+ }[];
123
+ }
124
+ export interface LessonToRuleFunnelReport {
125
+ readonly periods: readonly LessonToRuleFunnelPeriod[];
126
+ readonly findings: readonly LessonToRuleFunnelFinding[];
77
127
  }
78
128
  /**
79
129
  * A raw evidence log, handed over verbatim so the chain verdict has exactly ONE definition
@@ -94,6 +144,8 @@ export interface CompoundingFacts {
94
144
  readonly evidenceLogs?: readonly EvidenceLogFact[];
95
145
  /** Depth of the command-invocation corpus. `null` means no readable log, never zero-by-default. */
96
146
  readonly cmdUsageDepthDays?: number | null;
147
+ /** Prospective route observations; absence is explicit NOT MEASURED, never an empty funnel. */
148
+ readonly lessonToRule?: LessonToRuleFunnelFacts;
97
149
  }
98
150
  export interface PoolPayoff {
99
151
  readonly total: number;
@@ -154,9 +206,11 @@ export interface CompoundingReport {
154
206
  readonly guardTrajectory: readonly GuardRuleTrajectory[];
155
207
  readonly replay: ReplayReadiness;
156
208
  readonly instrumentation: InstrumentationHealth;
209
+ readonly lessonToRuleFunnel: LessonToRuleFunnelReport;
157
210
  /** The one-line honest answer. */
158
211
  readonly verdict: string;
159
212
  }
213
+ export declare function assembleLessonToRuleFunnel(facts: LessonToRuleFunnelFacts, nowTs: string): LessonToRuleFunnelReport;
160
214
  export declare function assembleCompoundingReport(facts: CompoundingFacts): CompoundingReport;
161
215
  export declare function renderCompoundingReport(r: CompoundingReport): string;
162
216
  //# sourceMappingURL=compounding.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compounding.d.ts","sourceRoot":"","sources":["../src/compounding.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compounding.d.ts","sourceRoot":"","sources":["../src/compounding.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,7 @@
15
15
  * Everything here is PURE: callers gather facts (files, store rows); this module only computes.
16
16
  */
17
17
  import { EVENT_CHAIN_SCOPE, verifyEventChainText } from './event-chain.js';
18
+ import { isOffsetIsoTimestamp, } from './guard-promotion.js';
18
19
  // ── Seeded statistics (verbatim-shape port from darwin-mode bench/stats.ts) ──
19
20
  /** Deterministic PRNG — same seed, same stream, byte-identical reports. */
20
21
  export function mulberry32(seed) {
@@ -99,6 +100,181 @@ export function replayableInstances(usage, lessonText = new Map()) {
99
100
  return [...byKey.entries()].map(([id, e]) => ({ id, query: e.query, lessons: e.lessons, class: null }));
100
101
  }
101
102
  const APPLY_LEG_STALE_DAYS = 7;
103
+ const FUNNEL_MONTH_LIMIT = 12;
104
+ const LESSON_TO_RULE_FUNNEL_POLICY = {
105
+ unavailable: (reason) => ({ status: 'not-measured', reason }),
106
+ successor: (stage) => stage,
107
+ };
108
+ function utcMonth(ts) {
109
+ return isOffsetIsoTimestamp(ts) ? new Date(Date.parse(ts)).toISOString().slice(0, 7) : null;
110
+ }
111
+ function monthOffset(period, delta) {
112
+ const [year, month] = period.split('-').map(Number);
113
+ return new Date(Date.UTC(year, month - 1 + delta, 1)).toISOString().slice(0, 7);
114
+ }
115
+ function funnelPeriods(facts, nowTs) {
116
+ const evidenceMonths = [];
117
+ if (facts.promotionRuns.status === 'measured') {
118
+ for (const row of facts.promotionRuns.rows) {
119
+ const period = utcMonth(row.ts);
120
+ if (period !== null)
121
+ evidenceMonths.push(period);
122
+ }
123
+ }
124
+ if (facts.guardAudits.status === 'measured') {
125
+ for (const row of facts.guardAudits.rows) {
126
+ const period = utcMonth(row.ts);
127
+ if (period !== null)
128
+ evidenceMonths.push(period);
129
+ }
130
+ }
131
+ for (const period of facts.truncatedPromotionPeriods ?? [])
132
+ evidenceMonths.push(period);
133
+ const current = utcMonth(nowTs) ?? evidenceMonths.sort().at(-1) ?? '1970-01';
134
+ const floor = monthOffset(current, -(FUNNEL_MONTH_LIMIT - 1));
135
+ const earliest = evidenceMonths.filter((period) => period >= floor && period <= current).sort()[0] ?? current;
136
+ const periods = [];
137
+ for (let period = earliest; period <= current; period = monthOffset(period, 1))
138
+ periods.push(period);
139
+ return periods;
140
+ }
141
+ function promotionMeasurements(facts, period) {
142
+ if (facts.promotionRuns.status === 'not-measured') {
143
+ const unavailable = LESSON_TO_RULE_FUNNEL_POLICY.unavailable(facts.promotionRuns.reason);
144
+ return { eligible: unavailable, attempted: unavailable, accepted: unavailable };
145
+ }
146
+ if (facts.truncatedPromotionPeriods?.includes(period) === true) {
147
+ const unavailable = LESSON_TO_RULE_FUNNEL_POLICY.unavailable(`promotion-history-pruned:${period}`);
148
+ return { eligible: unavailable, attempted: unavailable, accepted: unavailable };
149
+ }
150
+ const runs = facts.promotionRuns.rows.filter((row) => utcMonth(row.ts) === period);
151
+ if (runs.length === 0) {
152
+ const unavailable = LESSON_TO_RULE_FUNNEL_POLICY.unavailable(`promotion-run-not-recorded:${period}`);
153
+ return { eligible: unavailable, attempted: unavailable, accepted: unavailable };
154
+ }
155
+ if (runs.some((row) => row.complete !== true)) {
156
+ const unavailable = LESSON_TO_RULE_FUNNEL_POLICY.unavailable(`promotion-run-incomplete:${period}`);
157
+ return { eligible: unavailable, attempted: unavailable, accepted: unavailable };
158
+ }
159
+ const eligible = new Set();
160
+ const attempted = new Set();
161
+ const accepted = new Set();
162
+ for (const run of runs) {
163
+ for (const candidate of run.candidates) {
164
+ if (candidate.eligible !== true)
165
+ continue;
166
+ eligible.add(candidate.candidateAnchor);
167
+ if (typeof candidate.ruleContentAnchor !== 'string' || candidate.ruleContentAnchor === '')
168
+ continue;
169
+ attempted.add(candidate.candidateAnchor);
170
+ if (candidate.verdict === 'promote')
171
+ accepted.add(candidate.candidateAnchor);
172
+ }
173
+ }
174
+ return {
175
+ eligible: { status: 'measured', value: eligible.size },
176
+ attempted: { status: 'measured', value: attempted.size },
177
+ accepted: { status: 'measured', value: accepted.size },
178
+ };
179
+ }
180
+ function executionMeasurement(facts, period) {
181
+ if (facts.promotionRuns.status === 'not-measured') {
182
+ return LESSON_TO_RULE_FUNNEL_POLICY.unavailable(facts.promotionRuns.reason);
183
+ }
184
+ if (facts.guardAudits.status === 'not-measured') {
185
+ return LESSON_TO_RULE_FUNNEL_POLICY.unavailable(facts.guardAudits.reason);
186
+ }
187
+ const periodAudits = facts.guardAudits.rows.filter((row) => utcMonth(row.ts) === period);
188
+ if (periodAudits.length === 0) {
189
+ return LESSON_TO_RULE_FUNNEL_POLICY.unavailable(`guard-audit-not-recorded:${period}`);
190
+ }
191
+ const audits = periodAudits.filter((row) => row.op === 'publish');
192
+ if (audits.length === 0) {
193
+ return LESSON_TO_RULE_FUNNEL_POLICY.unavailable(`guard-publish-not-recorded:${period}`);
194
+ }
195
+ const violations = audits.flatMap((audit) => {
196
+ const observed = audit.violations ?? audit.rules.map((rule) => ({ rule }));
197
+ return observed.map((violation) => ({ ...violation, auditTs: Date.parse(audit.ts) }));
198
+ });
199
+ if (violations.some((item) => item.rule.startsWith('promoted-') && !item.contentAnchor)) {
200
+ return LESSON_TO_RULE_FUNNEL_POLICY.unavailable(`guard-audit-anchor-missing:${period}`);
201
+ }
202
+ const acceptances = facts.promotionAcceptances ?? facts.promotionRuns.rows.flatMap((run) => run.complete !== true
203
+ ? []
204
+ : run.candidates
205
+ .filter((candidate) => candidate.eligible === true && candidate.verdict === 'promote' && candidate.ruleContentAnchor)
206
+ .map((candidate) => ({ ruleContentAnchor: candidate.ruleContentAnchor, acceptedTs: run.ts })));
207
+ const acceptedAt = new Map();
208
+ for (const acceptance of acceptances) {
209
+ const acceptedTs = Date.parse(acceptance.acceptedTs);
210
+ const prior = acceptedAt.get(acceptance.ruleContentAnchor);
211
+ if (Number.isFinite(acceptedTs) && (prior === undefined || acceptedTs < prior)) {
212
+ acceptedAt.set(acceptance.ruleContentAnchor, acceptedTs);
213
+ }
214
+ }
215
+ const unattributedPromoted = violations.some((item) => item.rule.startsWith('promoted-') &&
216
+ typeof item.contentAnchor === 'string' &&
217
+ (acceptedAt.get(item.contentAnchor) === undefined || acceptedAt.get(item.contentAnchor) > item.auditTs));
218
+ const acceptanceHistoryComplete = facts.acceptanceHistoryComplete ??
219
+ facts.promotionRuns.rows.every((run) => run.complete === true);
220
+ if (unattributedPromoted && !acceptanceHistoryComplete) {
221
+ return LESSON_TO_RULE_FUNNEL_POLICY.unavailable(`promotion-acceptance-history-incomplete:${period}`);
222
+ }
223
+ return {
224
+ status: 'measured',
225
+ value: violations.filter((item) => typeof item.contentAnchor === 'string' &&
226
+ acceptedAt.has(item.contentAnchor) &&
227
+ acceptedAt.get(item.contentAnchor) <= item.auditTs).length,
228
+ };
229
+ }
230
+ function funnelFindings(periods) {
231
+ const edges = [
232
+ ['eligible', 'attempted'],
233
+ ['attempted', 'accepted'],
234
+ ['accepted', 'executions'],
235
+ ];
236
+ const findings = [];
237
+ for (const [predecessor, successor] of edges) {
238
+ let streak = [];
239
+ const emit = () => {
240
+ if (streak.length < 3)
241
+ return;
242
+ const observed = streak.slice(-3);
243
+ findings.push({
244
+ predecessor,
245
+ stage: LESSON_TO_RULE_FUNNEL_POLICY.successor(successor),
246
+ fromPeriod: observed[0].period,
247
+ toPeriod: observed[2].period,
248
+ counts: observed.map((row) => ({
249
+ period: row.period,
250
+ predecessor: row[predecessor].value,
251
+ successor: row[successor].value,
252
+ })),
253
+ });
254
+ };
255
+ for (const row of periods) {
256
+ const before = row[predecessor];
257
+ const after = row[successor];
258
+ if (before.status === 'measured' && after.status === 'measured' && before.value > 0 && after.value === 0) {
259
+ streak.push(row);
260
+ }
261
+ else {
262
+ emit();
263
+ streak = [];
264
+ }
265
+ }
266
+ emit();
267
+ }
268
+ return findings;
269
+ }
270
+ export function assembleLessonToRuleFunnel(facts, nowTs) {
271
+ const periods = funnelPeriods(facts, nowTs).map((period) => ({
272
+ period,
273
+ ...promotionMeasurements(facts, period),
274
+ executions: executionMeasurement(facts, period),
275
+ }));
276
+ return { periods, findings: funnelFindings(periods) };
277
+ }
102
278
  export function assembleCompoundingReport(facts) {
103
279
  const { lessons, usage, guard } = facts;
104
280
  // 1. Pool payoff — the "loops need all three legs" question, quantified.
@@ -212,6 +388,10 @@ export function assembleCompoundingReport(facts) {
212
388
  ? Math.max(0, facts.cmdUsageDepthDays)
213
389
  : null,
214
390
  };
391
+ const lessonToRuleFunnel = assembleLessonToRuleFunnel(facts.lessonToRule ?? {
392
+ promotionRuns: { status: 'not-measured', reason: 'promotion-journal-not-provided' },
393
+ guardAudits: { status: 'not-measured', reason: 'guard-audit-not-provided' },
394
+ }, facts.nowTs);
215
395
  const improvedRules = trajectory.filter((t) => t.improved).length;
216
396
  const verdict = [
217
397
  `pool: ${injectedEver}/${total} lessons ever injected (${Math.round(pool.writeOnlyRatio * 100)}% write-only under the strict bar)`,
@@ -226,7 +406,36 @@ export function assembleCompoundingReport(facts) {
226
406
  : 'evidence chain: CORRUPT — the numbers above are computed from a damaged log',
227
407
  ]),
228
408
  ].join(' · ');
229
- return { pool, guardTrajectory: trajectory, replay, instrumentation, verdict };
409
+ return { pool, guardTrajectory: trajectory, replay, instrumentation, lessonToRuleFunnel, verdict };
410
+ }
411
+ function renderFunnelMeasurement(stage, value) {
412
+ return value.status === 'measured'
413
+ ? `${stage} ${value.value}`
414
+ : `${stage} NOT MEASURED (${value.reason})`;
415
+ }
416
+ function renderPromotionMeasurements(row) {
417
+ const { eligible, attempted, accepted } = row;
418
+ if (eligible.status === 'not-measured' &&
419
+ attempted.status === 'not-measured' &&
420
+ accepted.status === 'not-measured' &&
421
+ eligible.reason === attempted.reason &&
422
+ eligible.reason === accepted.reason) {
423
+ return `eligible/attempted/accepted NOT MEASURED (${eligible.reason})`;
424
+ }
425
+ return [
426
+ renderFunnelMeasurement('eligible', row.eligible),
427
+ renderFunnelMeasurement('attempted', row.attempted),
428
+ renderFunnelMeasurement('accepted', row.accepted),
429
+ ].join(' · ');
430
+ }
431
+ function renderFunnelPeriodMeasurements(row) {
432
+ const values = [row.eligible, row.attempted, row.accepted, row.executions];
433
+ const unavailable = values.filter((value) => value.status === 'not-measured');
434
+ if (unavailable.length === values.length &&
435
+ unavailable.every((value) => value.reason === unavailable[0].reason)) {
436
+ return `eligible/attempted/accepted/executions NOT MEASURED (${unavailable[0].reason})`;
437
+ }
438
+ return `${renderPromotionMeasurements(row)} · ${renderFunnelMeasurement('executions', row.executions)}`;
230
439
  }
231
440
  export function renderCompoundingReport(r) {
232
441
  const out = [];
@@ -259,6 +468,17 @@ export function renderCompoundingReport(r) {
259
468
  if (r.instrumentation.chains.length > 0)
260
469
  out.push(` scope: ${EVENT_CHAIN_SCOPE}`);
261
470
  out.push('');
471
+ out.push(' LESSON → RULE FUNNEL (calendar month, observed traffic only):');
472
+ for (const row of r.lessonToRuleFunnel.periods) {
473
+ out.push(` ${row.period} · ${renderFunnelPeriodMeasurements(row)}`);
474
+ }
475
+ for (const finding of r.lessonToRuleFunnel.findings) {
476
+ const counts = finding.counts
477
+ .map((row) => `${row.period} ${finding.predecessor} ${row.predecessor} → ${finding.stage} ${row.successor}`)
478
+ .join('; ');
479
+ out.push(` FLOW STOP ${finding.stage} (${finding.fromPeriod}..${finding.toPeriod}): ${counts}`);
480
+ }
481
+ out.push('');
262
482
  out.push(` VERDICT: ${r.verdict}`);
263
483
  return out.join('\n');
264
484
  }