epic #220: The Body Cap Measures the Concept, Not Its Neighbours - #234
Merged
Conversation
sameera
marked this pull request as ready for review
August 4, 2026 10:39
The 400-word cap counted Integration Points alongside the page's own content, so a page was measured on its popularity as much as on its breadth. With the store at 48 pages the neighbour list dominated — neighbour prose is 16.2% of all capped body text and no page exceeds 400 words on its own content — and drains had started dropping real touches edges to stay under the cap. 0003 §2.2 now counts the body minus Integration Points and minus the Decision Log: on a well-formed page, exactly Summary, How It Works and Key Invariants. The exclusion form is normative so a newly invented section still counts. The excised region is bounded per entry instead — a 40-word hard ceiling, a 25-word advisory, a 12-bullet degree advisory — and the section states the worst-case page size 400 + 40·d, the 6,160-word per-task budget at the 5-7 page retrieval cap, and the store-level trigger at which moving interaction prose off the page is revisited. The cap stays at 400; only the denominator moves. §6.3 is restated to match, and the schema record's amendment history gains exactly one entry. Closes #221
The body-cap check counted the whole body up to the Decision Log, so a page's Integration Points bullets competed with its own prose for the 400 words. A well-connected page was flagged as too broad and told to split, which is the wrong remedy for a neighbour list. The counted region is now the body minus Integration Points and minus the Decision Log. It is computed by exclusion — the walk drops lines inside an excluded section and keeps everything else — so a section a future page invents still counts and the cap cannot be evaded by adding a heading. On a well-formed page the region is exactly Summary, How It Works and Key Invariants, as 0003 §2.2 now states. Word counting moves behind one helper, the single convention the per-bullet ceiling will share. Every one of the 47 active pages passes the new denominator with no edit to any page, pinned by a test that walks the real store. The bundle is rebuilt and re-pinned. That also corrects the claude-components half of the pin, which main was already carrying stale. Closes #222
Moving Integration Points outside the body cap left it unbounded, so the region needs its own bound — and a bound whose remedy is legal. Each bullet is now measured on its own, spanning its marker through the line before the next one so wrapping never changes its length: over 40 words is a blocking finding on a strict greater-than, over 25 is an advisory. 40 sits five words above the store's longest bullet and is a tenth of the own-content budget; 25 fires on 4 of 198 bullets today. Degree is watched, not limited. A page over 12 bullets is named in an advisory, because the store's one genuine hub carries 15 edges and a blocking limit would have no legal remedy — splitting a hub increases total edge prose. A full-store run also reports the two revisit triggers, neighbour prose above a quarter of body text and a highest degree above 25; a changed-file run skips them rather than paying for a second full-store pass. Findings now carry a severity and every line leads with its token, the summary counts the classes separately, and the exit status becomes the sole gate: a run whose only findings are advisories exits zero. The store today prints five advisories and exits 0. Closes #223
The distiller's surfaces still read the cap as covering the whole body, so a drain facing a full page had no legal way to record a real edge and the honest move was to drop it and describe the interaction in prose. PR #219 did exactly that, three times. The page-patching step now caps a page's own content and states that Integration Points is bounded per entry instead, at 40 words a bullet, so a page over 400 total body words through its neighbour list needs no split and no compression. The split step and the eviction of last resort both name own-content overflow as their only trigger; neighbour-list pressure is explicitly not one. The reciprocity fan-out states the remedy the new ceiling needs: write the bullet within 40 words, and if the interaction genuinely will not fit, that is two interactions — declare two edges, never drop or demote one. The validator step's rule becomes "a non-zero exit blocks" rather than "any finding blocks", with advisories named as the exception a drain carries into the PR body and proceeds past. The store's usage README matches the new denominator and the per-bullet bound. Closes #224
sameera
force-pushed
the
epic-220-concept-cap-denominator
branch
from
August 4, 2026 10:52
654ed49 to
278fd9e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the story sub-issues of #220, one commit per story in blocked_by order.
Each commit body carries its own
Closes #<story>line, so merging this PRinto
maincloses the stories it implements. The epic itself closes through/nxs.close, not by merge.Draft opened by
utils/implement-epic.sh;/nxs.analyzeruns against it next.