Skip to content

fix(bp-155): decide the L0a oversize cut over the canonical body (A1.2) - #36

Merged
ascalva merged 2 commits into
mainfrom
build/bp-155-l0a-canonical-cut
Aug 8, 2026
Merged

fix(bp-155): decide the L0a oversize cut over the canonical body (A1.2)#36
ascalva merged 2 commits into
mainfrom
build/bp-155-l0a-canonical-cut

Conversation

@ascalva

@ascalva ascalva commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Summary

Completes bp-155 — the L0a oversize cut in _l0a_chunks (core/ingest/code_corpus.py) now
decides the whole↔windowed split over the canonical body (len(body) <= max_chars),
not the header-bearing full text (len(header + body) <= max_chars). This closes issue #31,
bp-151's parked residue, per Amendment A1.2 of dn-vector-membership-store (owner ruling
2026-08-06). This completes D0: bp-151 took the aggregate rename cost from 11,096 → 3;
this takes it to 0.

  • core/ingest/code_corpus.py — the one-token change (:152), and the KNOWN RESIDUE comment
    replaced with one recording the decision is now canonical-body-scoped, per A1.2. Nothing else
    in the block moved — text=full stays text=full, so L0a embed text keeps its coordinate
    header (D0/R7 untouched).
  • tests/unit/test_code_corpus.py — bp-151's deliberate tripwire,
    test_l0a_oversize_threshold_is_the_one_rename_residue, converted to
    test_l0a_oversize_cut_is_canonical_body_scoped: same straddle-precondition fixture (the
    rename still crosses the OLD header-bearing threshold), the mint-1 assertion flipped to
    mint-0, docstring records it was bp-151's tripwire and that it reddened exactly as designed.

closes #31

Measured (real chunkers, real files, not a fixture — 2026-08-06)

Item 2 — aggregate rename cost: 0. Over all 580 tracked .py files: for each file,
derive L0a/L0b/L1 at its own path and at a length-changed moved path (same directory, longer
basename), sum new (layer, content_hash) atoms across all three layers.

  • Post-fix: 0 new atoms, 0 files affected.
  • Pre-fix (same script against the stashed-out old code, on this tree): 23 new atoms
    across 23 files — nonzero, confirming the measurement has teeth. (Larger than bp-151's
    original 3 because the tree has grown since 45c4a15; not a discrepancy.)
  • A1.5's first falsifier — a residue meaning a fourth path-dependent site — does not fire.
    No issue filed.

Item 3 — L0a boundary-change census: 72 groups across 57 files, all in-band. Comparing
L0a (path, qualname) groups' canonical-body hashes pre/post fix: 73 groups changed
across 58 files; 72/57 are rule-driven, and 1
(core/ingest/code_corpus.py::_l0a_chunks itself) is a measurement artifact — this PR's own
comment edit inside that function's body, not a rule effect. Verified all 72 genuine
changes fall inside the predicted affected band
(max_chars - len(header) <= len(body) <= max_chars) — A1.5's second falsifier (a change
outside the band) does not fire. (Was ≈123/95 at 45c4a15; the tree has moved — this is
what it reads now, not a regression from that number.)

A side-finding, not a defect. For groups in the affected band, the OLD rule routed the
body through chunk_text (core/kernel/ingest/chunk.py), whose _blocks calls .strip()
on a block even when the whole body is a single block under budget — silently stripping the
first line's leading indentation for nested symbols (a class method's body starts
indented). E.g. config/secrets_backend.py::VaultClient.mint_token: old rendering was
'def mint_token(self, role...' (dedented, corrupted); the raw body is
' def mint_token(self, role...' (correct). The new rule takes the whole branch directly
for all 72 slices, so their canonical bodies (and embed text) are the exact, unmangled source
for the first time — a side benefit, not new behavior to chase, and not filed as a separate
issue.

Gate — exact results

Each leg run separately, never piped (pytest -q | tail returns tail's exit code).

$ uv run ruff check .
All checks passed!
(exit 0 — one E501 introduced by the converted test's trailing comment was fixed before this run)

$ uv run mypy core agents eval ops scheduler scripts
Success: no issues found in 262 source files
(exit 0)

$ uv run mypy
...
tests/integration/test_cron.py:91: error: Argument 2 to "cron_handlers" has incompatible type "FakeCurator"; expected "Curator"  [arg-type]
Found 69 errors in 20 files (checked 563 source files)
(exit 1, as designed — tail count 69, unmoved from the pinned baseline)

$ uv run python -m ops.type_gate
Tier-2 membership: OK — every core-importing top-level package is in [tool.mypy].files
Bare-ignore scan: OK — every `# type: ignore` in the checked region carries an error code
Raw shimmed-dependency imports (type-gate) REPORTED (parked, non-fatal) — one pre-existing,
unrelated waiver (finding-0223)
(exit 0)

$ uv run pytest -q
...
FAILED tests/e2e/test_dream_v2_live.py::test_dream_v2_synthesizes_grounded_themes_live
FAILED tests/integration/test_worktree_enforcement.py::test_a_deny_cross_worktree
FAILED tests/integration/test_worktree_enforcement.py::test_c_unsafe_direction_narrow_not_loosened
FAILED tests/integration/test_worktree_enforcement.py::test_d_no_pointer_is_no_plan_not_main_fallback
FAILED tests/unit/test_core_self_containment.py::test_core_imports_nothing_outside_core
5 failed, 2427 passed, 15 skipped, 12 warnings in 224.14s (0:03:44)

5 failed / 2427 passed / 15 skipped — exactly the three known-red classes local-only, green
in CI: the finding-0103 core-self-containment ratchet (1), tests/e2e/test_dream_v2_live.py (1),
and tests/integration/test_worktree_enforcement.py (issue #13 / finding-0280) (3). Same test
names, same count bp-151 reported for its own build. tests/e2e/test_scheduler_live.py's known
flake did not fire in either run below.

Diff-innocence proven: stashed both changed files back to a byte-identical origin/main
(git diff --stat origin/main HEAD empty), re-ran the full suite on the clean base — same 5
failures, same names
, 5 failed, 2427 passed, 15 skipped in 249.76s.

Test plan

  • ruff check . clean
  • mypy core agents eval ops scheduler scripts — 0 issues, 262 files
  • mypy (argless) — tail 69, unmoved
  • ops.type_gate — OK
  • pytest -q — 5 known-red / 2427 passed / 15 skipped, proven diff-innocent against clean
    origin/main
  • test_l0a_oversize_cut_is_canonical_body_scoped passes; inverted (stash the fix) to
    confirm it reproduces the original mint-1 residue, then restored
  • Aggregate rename cost measured at 0 over all 580 tracked .py files (not a fixture)
  • Boundary-change census (72/57) verified entirely inside the predicted affected band

🤖 Generated with Claude Code

https://claude.ai/code/session_011LZZQPyGsoeGL73cbbEp3U

ascalva and others added 2 commits August 6, 2026 12:50
`_l0a_chunks` (core/ingest/code_corpus.py) decided the whole<->windowed split
on the HEADER-BEARING length (`len(header + body) <= max_chars`), so the
path's length participated in a chunk-identity decision: a rename or a move
that crossed the budget flipped a slice whole<->windowed and minted a
spurious atom (issue #31, bp-151's parked residue, ruled by Amendment A1.2 of
dn-vector-membership-store).

The fix is the one token the plan pins: `len(full) <= max_chars` becomes
`len(body) <= max_chars`. Nothing else in the block moves — `text=full` stays
`text=full`, so L0a embed text keeps its coordinate header (D0/R7). The
KNOWN RESIDUE comment is replaced with one recording the decision is now
canonical-body-scoped, per A1.2, and why.

Converts bp-151's deliberate tripwire,
`test_l0a_oversize_threshold_is_the_one_rename_residue` (its docstring named
its own re-entry: "if #31 is ruled that way, this expectation becomes 0 and
this test reddens"), to `test_l0a_oversize_cut_is_canonical_body_scoped`,
asserting the residue is gone while keeping the straddle precondition (the
fixture still crosses the OLD threshold, so the test has teeth).

Measured (2026-08-06, real chunkers over all 580 tracked .py files, not a
fixture):
- Aggregate rename cost: 0 (was 3 at bp-151's 45c4a15 measurement; 23 on
  this tree pre-fix, confirming the measurement has teeth and the tree has
  grown since 45c4a15). A1.5's first falsifier does not fire.
- L0a groups whose canonical body changed under the new rule: 72 across 57
  files (was ~123/95 at 45c4a15; the tree has moved). Verified every one
  falls inside the predicted affected band (max_chars - len(header) <=
  len(body) <= max_chars) — A1.5's second falsifier does not fire. One
  additional group, core/ingest/code_corpus.py::_l0a_chunks, differs too,
  but that is this commit's own comment edit to the function whose body
  includes that comment, not a rule-driven change.

Side effect, noted: for slices in the affected band, the OLD rule routed the
body through `chunk_text`, whose `_blocks` calls `.strip()` on the block —
silently stripping the first line's leading indentation for nested symbols
even though the body itself fit under budget. The new rule takes the whole
branch directly, so those 72 slices' canonical bodies (and embed text) are
now the exact, unmangled source for the first time.

No max_chars retune (A1.5's third falsifier), no other chunker change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011LZZQPyGsoeGL73cbbEp3U
Records the build: the one-token fix, the converted tripwire, the aggregate
rename cost re-measured at 0 (A1.5's first falsifier did not fire), the
72/57 in-band boundary-change census (A1.5's second falsifier did not
fire), the exact gate results with diff-innocence proven on the 5 known-red
tests, and the .strip()-indentation side-finding surfaced while verifying
Item 3. Read-map + Follow-through block per the checkpoint contract.
@ascalva
ascalva merged commit ca7251a into main Aug 8, 2026
7 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

canonical identity has one residue: the L0a oversize cut is decided over header-bearing length, so a rename still mints 1 atom at the threshold

1 participant