Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion docs/known-gaps.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
| Severity | Open |
|---|---|
<!-- @generated:gap-counts START (do not edit — `bun scripts/state.ts --write`) -->
| HIGH | 76 |
| HIGH | 77 |
| MED | 204 |
| LOW | 87 |
| Nominal (spec-ahead-of-impl) | 7 |
Expand All @@ -53,6 +53,11 @@

<!-- ⛑ S395-bryan filing batch 2 — THREE entries from the #818 if-chain server-boundary arc. Two are PRE-EXISTING and were verified as such two-sided before filing (neither is introduced by #818); the third is a tooling-baseline debt whose measurement is RELAYED and labelled so, because `tsc` is not installed in this checkout and the types gate correctly refuses to pass without running. -->

<!-- ⛑ S395-bryan filing batch 3 — ONE entry, surfaced while reading §32 IN FULL to answer bryan's `~` question. It is the reason a live contradiction between two normative sections survived unnoticed, and it is filed BEFORE the fix arc for the contradiction lands, so the two are not conflated. -->

### g-tilde-lin-enforcement-does-not-fire-on-spec-own-examples — §32's `~` exactly-once (`lin`) enforcement produces **ZERO diagnostics on SPEC's own worked examples**. **PA-MEASURED ON MERGED MAIN — six probes, all exit 0, all zero `E-TILDE`:** §32.5's verbatim `${ process(~) }` (spec'd `E-TILDE-001`) · `~` read with no initialization at all · a double-initialization with no consumption between (spec'd `E-TILDE-002` per §32.3) · an initialization never consumed before scope exit (also spec'd `E-TILDE-002`) · a double-init inside a function body · §17.6.6's partial-`if` example (`if (cond) { lift a }` then `const dbl = ~ * 2`, which §17.6.6 says the compiler **SHALL** emit `E-TILDE-001` for). ⛑ **NOT from absence, which is why this is filed as a defect rather than as spec-ahead:** `TildeTracker` (`type-system.ts:18380`), `MustUseTracker`, `checkLinear` and BOTH codes exist with real user-facing messages, and `checkLinear` is invoked **unconditionally** at file level (`:24470`, gated only on `allLinNodes.length > 0`). The pass runs and does not fire on the documented shapes. ⛑ **CAUSE NOT TRACED — stated as an observation, not a diagnosis.** `hasNonLiftTildeConsumer` gates only loop-body elision (`:18956`) and one site at `:19549`, not the pass as a whole, so the obvious gate is NOT the explanation; whether `~` reaches the tracker as a `tilde-ref` node in these shapes was not established. **A fix must start by tracing that, not by assuming the pass is unimplemented.** ⛑ **WHY IT MATTERS BEYOND THE MISSING DIAGNOSTICS:** this silence is what let §17.6.2 and §32.2 contradict each other unnoticed — §17.6.2 says a bare call in an if-as-expression arm is a side effect, §32.2 says an unassigned expression statement SHALL initialize `~`, and with §32.3 that shape should have been a hard `E-TILDE-002` for as long as both sentences have coexisted. Nobody saw it because nothing enforced it. **This is the S322 re-examination test in its purest form:** a normative SHALL delivered by a tracker pass that scans for states — RETROFIT, not by construction — and the predicted hole duly appeared. Composes with **dpa-040** (should an arm body be a `~` boundary?), whose phase 1 is required to re-verify this by execution before reasoning from it. — `NEW S395-bryan (surfaced while reading §32 in full for the `~` ruling; six probes PA-executed on merged main)`; **HIGH**; open
<!-- @gap id=g-tilde-lin-enforcement-does-not-fire-on-spec-own-examples sev=HIGH status=open locus=compiler/src/type-system.ts:18380(TildeTracker)+:18479(checkLinear)+:24470(the unconditional file-level invocation) — the pass EXISTS and RUNS; the reason it does not fire on SPEC's documented shapes was NOT traced prov=empirical:PA-six-probes-on-merged-main-including-SPEC-32.5-and-17.6.6-verbatim-examples-all-exit-0-zero-E-TILDE -->

### g-same-named-branch-declarations-bind-to-the-last-definition — two sibling `if=`/`else` branches declaring the SAME function name emit BOTH definitions but bind **every** call site to the LAST one, with zero diagnostics. Surfaced by the S239 pass on #818 and **PA-verified PRE-EXISTING, not introduced**: on merged main two *lone* `if=` divs each declaring `dup()` already emit `_scrml_dup_7` + `_scrml_dup_8` and route the calls to the last definition (measured 1 call to the first, 5 to the second). #818 brings the collapsed-chain shape to PARITY with that lone-`if=` oracle, which is its stated goal — so the chain now inherits the oracle's own defect rather than introducing one. ⛑ **The direction of the change at this shape is loud→silent**, and that is why it is filed rather than shrugged at: on base the chain produced a `ReferenceError` (nothing was defined at all); it now returns the WRONG branch's value silently. In the `server fn` / plain `function` mix the `if`-arm's call binds to the else-arm's CLIENT function while the emitted route goes unreferenced — a live POST endpoint with no caller. **No server body leaked in any duplicate-name shape tested** (`SERVER-SECRET` never reached `client.js`), so this is a correctness defect, not a confidentiality one. The real question underneath is whether a branch body is its own DECLARATION SCOPE — the same scoping question `g-if-chain-all-arms-run-at-module-init` asks about `${}` bodies, and it should be ruled once for both rather than twice. — `NEW S395-bryan (S239 finding on #818; PA-verified pre-existing on the lone-if= oracle)`; **MED**; open
<!-- @gap id=g-same-named-branch-declarations-bind-to-the-last-definition sev=MED status=open locus=compiler/src/codegen/collect.ts(collectFunctions registers by NAME with no per-branch scope, so the last registration wins; the same shape pre-exists for sibling lone-if= blocks, which is the oracle it was brought to parity with) prov=empirical:PA-two-sided-execution-two-lone-if-divs-on-merged-main-already-bind-all-calls-to-the-last-definition -->

Expand Down
5 changes: 5 additions & 0 deletions handOffs/delta-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -3262,3 +3262,8 @@ flagged `(deputy)`, observation-only, recording an agent that landed while the P
[2035] find · **(S396-peter) E-ROUTE-004 HAS AN UNTYPED-PARAM HOLE — dog-fooded flogenceP, root-caused end-to-end, filed + routed.** flogenceP compiles clean on HEAD (21 files, 94 routes, 1 WS channel, validate-emit) + boots clean (server + MCP 11 tools); all 92 server-fns swept, every 500 triaged to app-level (empty-args / schema-init-order — e.g. `edit_mode` created by digest-tool not app's ensureSchema, init-order-dependent = flogenceP app bug), ZERO codegen-signature errors. The ONE scrml find: `checkRouteWireSerializability` (`type-system.ts:4734`) `continue`s on un-annotated params ("un-annotated param defaults asIs → allow"), so a server-boundary fn with an untyped-but-CALLED function param escapes E-ROUTE-004 and is routed as a **silent dead-500 endpoint**. Manifested on `runGatedAgentic` (untyped `run`, POST→500 `run is not a function`); import-only by intent so blast-radius LOW + pre-existing. **Two-sided minimal repro, runtime-confirmed:** `function f(cb){?{}…return cb(rows)}` (untyped) → exit 0 + dead route → POST 500; `function f(cb: () -> number)` (typed) → E-ROUTE-004 fires. Filed `g-route-004-untyped-fn-param-escapes-serializability-gate` (MED, open) + routed to bryan (the `continue` is deliberate — asIs hatch — so the fix is a normative fork: usage-based signal / require annotation / warn). ⚑ I STOPPED SHORT before routing (invoked "bryan's lane" to avoid reading his files) — Peter pushed, and READING for diagnosis ≠ EDITING; then I root-caused to the exact line. [[be-the-authority-root-cause-dont-hand-wave]].

[2036] state · **(S396-peter) WRAP.** Dog-food + adopter-ops session; NO compiler `src` touched (no FACTS/state code regen owed; maps unchanged). Landed: aM pin bumped + `g-route-004` filed (`state.ts` regen MED 203→204) + routed to bryan. Also flipped `~/.claude/settings.json` `blockReadsOutsideWorkingDirectories`→false (Peter's ask; needs restart/`/add-dir`); BLOCKED by the auto-mode classifier from self-editing permission config (dir-adds are Peter's own `/add-dir`). Continuity rides a light PR off `8f3c5b74`: this delta-log [2033]-[2036] + changelog S396 + the S396 hand-off PICKUP (bryan's S393/S395 owed-queue reconciled — S395 closures removed, the "inverted ruling" + value-form-null struck as resolved, the #818 security gap struck as closed). Pre-existing agent worktrees retained (not this session's). Gaps HIGH 76 · MED 204 · LOW 87.
[2037] state · **(S395-bryan) THE `~` RULING — limb (a), and it exposed that SPEC answers the question TWICE.** bryan: *"lets look at ~"* then *"your rec"*. **RATIFIED: §17.6.2 governs an if-as-expression arm body** — a bare expression statement inside an arm is a SIDE EFFECT; it does not initialize `~`, does not rebind the tilde context, does not touch the arm's result; only `lift` or the §17.6.10 sugar designates it. Per S276/S130 the terse ratification adopted the FULL text — *"(a) now, with (c) named as the question behind it"* — so **limb (c) is banked, not closed** (dpa-040). The reading found **§17.6.2 and §32.2 in direct conflict**: §32.2's *"an expression statement whose value is not bound SHALL initialize `~`"* plus §32.3's exactly-once rule makes `{ note("a") lift "pos" }` an `E-TILDE-002`, while §17.6.2 calls the same statement a side effect. **The compiler implements NEITHER** — it mints a fresh tilde and rebinds the context, so the `lift` writes the wrong var and the binding is silently null. Arc dispatched: codegen fix + the SPEC reconciliation it owes (§32.2 arm-body carve-out + reciprocal cross-ref + Rule 4b provenance), same arc, with a warning that #802's reconciliation surface turned out to be 3× what its ruling named.

[2038] find · ⚑ **(S395-bryan) §32's `~` ENFORCEMENT DOES NOT FIRE — AND THAT SILENCE IS WHY THE CONTRADICTION SURVIVED.** Six probes on merged main, all exit 0 with ZERO `E-TILDE`: SPEC §32.5's own verbatim `${ process(~) }`, `~` read with no init, double-init without consumption, init-never-consumed-at-scope-exit, double-init in a function body, and §17.6.6's partial-`if` example that SPEC says the compiler **SHALL** diagnose. NOT from absence — `TildeTracker`, `checkLinear` and both codes exist with real messages and `checkLinear` runs unconditionally at file level (`:24470`). **Cause NOT traced and the entry says so**; `hasNonLiftTildeConsumer` gates only loop-body elision, so the obvious explanation is ruled out but no replacement is offered. Filed HIGH as `g-tilde-lin-enforcement-does-not-fire-on-spec-own-examples`. **The S322 test in its purest form:** a normative SHALL delivered by a state-scanning tracker — retrofit, not by construction — and the predicted hole appeared.

[2039] friction · ⚑ **(S395-bryan) I BANKED dpa-040 IN A FORM THE PROBE COULD NOT READ, AND CAUGHT IT ONLY BY RUNNING THE PROBE.** Wrote the full `## [dpa-040]` section into `dpa-queue.md` — the right FILE, per the S319 drain-path rule — and `dpa-debt.ts` still reported **39 items / 2 UNRUN**. The probe reads the **status TABLE**, not the per-item sections; `scripts/dpa-debt.ts`'s own header says reading the per-item `status:` lines instead *"would reproduce the exact obligation/probe mismatch this file exists to close."* Adding the table row moved it to **40 / 3 UNRUN**. **The S319 rule "bank in the queue FILE" is necessary and NOT sufficient — the row is the banking act, the section is documentation.** Same base §10 class as everything else this session, self-inflicted, and caught only because the probe was run rather than assumed. [[feedback_the_probe_answered_a_different_question]]
Loading
Loading