Skip to content

Phase 10: deviation reconciliation — the checklist, the drained inbound list and the release register - #104

Merged
Wahbeh-Mohammad merged 17 commits into
mainfrom
10-phase-10-deviation-reconciliation-and-release-readiness-docs
Sep 25, 2026
Merged

Wahbeh-Mohammad merged 17 commits into
mainfrom
10-phase-10-deviation-reconciliation-and-release-readiness-docs

Conversation

@Wahbeh-Mohammad

Copy link
Copy Markdown
Contributor

Closes #34. Third and last PR of phase 10's stack — the documentation and the phase record. 34 files, +1,190 / −179. With it, all eleven phases of the v1 roadmap are on main. Nothing is published: every gem stays at 0.0.0, no tag is cut.

What lands

  • The checklist, written from what was built: 124 own rows (108 MUST / 15 SHOULD / 1 MAY; ✅ 107 · 🚫 11 · N/A 4 · ⏳ 2 in the docs/first-release.md unsatisfied-MUSTs entry) plus 81 cross-reference rows, and two tables phase 9's did not need — the repairs (each with its failing test) and the inbound list, dispositioned.
  • Phase 10's inbound list is emptied by disposition. All 65 bullets (32 from 2026-09-13, 33 added since) carry a dated bracket: 18 repaired · 14 verified already fixed · 32 moved to docs/first-release.md (thirteen of them the amendment set) · 1 withdrawn — none carried forward. The ~30 reviewer leftovers from the per-phase notes that had been routed nowhere are dispositioned in their own table.
  • docs/first-release.md walked line by line: the frozen-chapter amendment blocker now names C1–C19 and the consolidation of every phase's ledger rows into design §10 (a human's act — the trees are frozen); a new blocker enumerates the one-time surface choices phases 4–8 said to "decide before the first tag"; port readings, post-release residues and the closed XCUT-12 trigger.
  • The design's As-built addendum (P10-21–P10-38) and its dated R1 widening; dated bracketed corrections in eighteen earlier-phase documents (placement only, no rewrites); the roadmap's phase-10 status note.
  • CLAUDE.md, README, docs/README.md, docs/sdk-documentation/ (quality-gates page's three new rows; Protocol/Status/URL behaviour on the http, transport and serde pages), and the housekeeping skill's nine checks.

One process-rule change for the maintainer to confirm: CLAUDE.md's routing rule now says the inbound list was drained on 2026-09-25 and audit-or-repair work found from here goes to docs/first-release.md.

Verification

Four independent reviews by fresh agents, a fix round between each: round 0 1 blocking / 8 / 3 → round 1 0 / 3 / 2 → round 2 0 / 1 / 1 → round 3 approve, 0 / 0 / 0. 89 mutations across the rounds, 86 caught, every survivor accounted for. The review record is in the comment below. At this tip, run by the maintainer: full bundle exec rake (24 gates) green on 4.0.6, honest RuboCop over 784 files clean, the probe clean with nine checks, the knowledge verifier OK; 3.2.11 and 3.3.12 matrix sets green; frozen trees untouched.

Known follow-ups

None from the final review. What this phase did not repair is now a dated docs/first-release.md line with its pick-up condition — there is no later phase.

Status maps every three-place code with #standard? for the protocol
range (HTTP-10); Protocol admits HTTP/1.0 (HTTP-33); URL.parse! wraps
every URI error and refuses a host-less http URL (HTTP-47); Model.own
drops a default proc; the HeaderSyntax predicates are total; a closed
stream is refused at Body.stream; the NaN and Complex duration guards;
the configuration chain no longer nests per configure (CFG-13); the
async logging step stops counting the caller's continuation; the proxy
warning's credential belt is unanchored (OBS-11, CFG-22). Every shipped
signature gains the SPDX header (NFR-13). The runtime manifest gains
Protocol::HTTP_1_0 and Status#standard?; the pins the repairs
invalidated move with them.
Both ResponseMappers now hand HTTP/1.0 and any three-place status to
the model (TRANSPORT-24); their YARD says so, and net_http's stray
@decode_content tag is backticked. The adapter pins that used HTTP/1.0
as the unmappable head now use HTTP/1.2. Every shipped signature in
the four adapter gems gains the SPDX header (NFR-13).
TransportSuite.run delegates to Runner.run, tearing its fresh cases
down through the around wrapper so Runner is not widened. The default
gem-name rule in PackagingCase reaches all six namespaces: -core is the
root and http/json are acronyms (NFR-15). The NFR-13 pin over this
repository's own signatures now expects :passed.
Twenty-four blocking gates, the three new ones in DEFAULT_GATES and in
CI's gates job, each with a fixture workspace that turns it red. The
require allowlist refuses a dexpace/ path with a dot segment, and the
rubocop gate runs with --ignore-parent-exclusion.
A requirement ID attributed to a product-spec chapter that does not
carry it, read clause by clause, with ranges expanded and negations
skipped.
All nineteen rows carry a verdict citing gems/ paths and defined
constants, and the amendment set is C1-C18. It rides here because
gates:ledger_audit reads it at run time.
Review round 0 of phase 10 found four code-layer defects.

R0-4: the proxy warning belt stopped at the first '/', '?' or '#', so
a password holding one leaked its prefix into Kernel#warn and the
config sink. ProxyResolution now scrubs the raw value from the
authority's start through the LAST '@' before the redactor runs.

R0-5: Status.of still threw outside 0..999, narrower than HTTP-10's
"any code MUST return a Status". Construction is now total over
Integer; #standard? stays the protocol range.

R0-6: docs/deviations.md row 10 cited send(:new) as the bypass, but
it runs the validating #initialize. The row is now "confirmed,
narrower" (allocate and duck typing remain) with amendment C19.

R0-8: the chapters check listed "appears in" as a negation, blinding
it to the usual positive attribution. An ID run followed by that
phrase now binds forward to the chapter it introduces.
The one rubocop:disable phase 10 added in tools/ledger_audit.rb
carried no reason; it now says why the row check threads the root
and the resolver (review round 1, R1-3).

The chapters check's forward "appears in" binding turned a negative
sentence ("SEAM-13 does not appear in <chapter>") into a positive
attribution. NEGATION gains "not appear in", "does not appear" and
"do not appear" (R1-4).
Review round 2 (R2-2) found two more negated spellings of 'appears
in' that bound forward and would fire as a wrong attribution:
'never appears in' and 'doesn't appear in'. Add 'never appear' and
"n't appear" to the chapters check's NEGATION union; 'appears
nowhere' was already there.
One failing-first test per repair, each run red on the untouched base;
a fiber race under a real reactor proving BearerStamper and
AsyncBearerStamper fetch once (XCUT-12, AUTH-34, AUTH-37); five
interleaving- or environment-dependent tests made deterministic, with
PinnedCeiling holding the materialisation ceiling at its default.
Each new gate is tested through its module and through its rake task
against a fixture workspace, and the chapters check keeps the two
phase-8 pre-correction lines as regression fixtures.
Seven proxy spellings whose password holds '/', '?', '#' or a second
'@' now assert that neither Kernel#warn nor the config sink carries
the username or any password prefix (review round 0, R0-4).

Two chapters cases prove an "appears in" attribution binds forward:
a wrong one fires, a right one does not, and the phase-5 two-run
shape no longer binds its second run to the first run's chapter
(R0-8).
Three proxy spellings put an '@' inside the password ahead of a
reserved character; a scrub through the first '@' leaves c/, b# and
y/ in the warning, and the committed case now fails on that mutant
on 4.0.6 and 3.2.11 (review round 1, R1-1).

A chapters case drives "does not appear in", "do not appear in" and
"did not appear in" through the probe and expects no finding (R1-4).
The chapters check's negated-verb case now also drives 'never appears
in', "doesn't appear in", "don't appear in" and 'appears nowhere
in' (review round 2, R2-2). Removing 'never appear' or "n't appear"
from NEGATION turns the case red on the spelling it covers.
The checklist (203 requirement rows, the 65 inbound bullets, the
repairs and the guards run red); the design's as-built addendum
P10-21 to P10-36; every inbound bullet dated and dispositioned on the
roadmap with the phase-10 status note; docs/first-release.md narrowed
and extended; earlier phases' records corrected by dated brackets;
CLAUDE.md, the READMEs, the gate page and the housekeeping skill
brought to twenty-four gates and nine probe checks.
R0-1: seven own rows carried a verdict copied from 3a that was false
for their ID; SEAM-6 to SEAM-9 now cite phase 2's Registry and IO-30,
IO-31 and IO-39 say retired apparatus. R0-9: SEAM-22 takes phase 2's
"mechanism retired, surviving clause" mark; the tally moves to 107/11.

R0-2: four sdk-documentation passages describe the as-built Protocol
(http/1.0) and Status (total over Integer, #standard?). R0-3, R0-12:
CLAUDE.md names net_http's YARD and test changes and C14's origin.

R0-4, R0-5, R0-6, R0-8 are recorded: repairs 27-29, guards 32-35,
P10-27 and P10-31 amended, P10-37 and P10-38 added, and C19 carried
through first-release.md, the roadmap and CLAUDE.md. R0-7 routes the
5c probe-claims and 7b sse.md items to first-release.md's residues.
R0-10, R0-11: brackets moved to sentence ends and a struck trigger's
old body struck too.
HTTP-19 and BODY-9, carried by lib repairs 6 and 7, gain
cross-reference rows, so the added set is 17 and the checklist holds
205 requirement rows; CLAUDE.md and the roadmap's status note move
with it (review round 1, R1-2). The CFG-22 row and the Guards table
record the last-@ pin and the negated chapters verb (R1-1, R1-4).
The dexpace-async-async entry in docs/first-release.md stops
pointing at the closed XCUT-12 trigger as live (R1-5).
Review round 2 (R2-1): docs/first-release.md's RBS-baseline entry
still said NFR-4 stays pending until a v* tag exists, against P10-35
and the checklist's NFR-4 row. The entry now says it is design §9's
release-tag mechanism, that NFR-4 is met through the surface
snapshot, and that gates:sig_diff is what waits for a tag.

The checklist gains a Review round 2 section and Guards 38 for the
chapters check's two new negations (R2-2).
@Wahbeh-Mohammad Wahbeh-Mohammad added type:docs Documentation only spec:deviation Deliberate, recorded divergence from the normative contract labels Sep 25, 2026
@Wahbeh-Mohammad

Copy link
Copy Markdown
Contributor Author

Review record for the phase 10 stack (#102 → #103 → #104)

4 independent reviews, each by a fresh agent with no memory of the previous one, each re-running every gate itself on every tip (4.0.6 every gate individually at the code tip and the full rake at the tests and docs tips; the matrix set on 3.2.11, 3.3.12 and 3.4.10) and applying its own mutations on both interpreters, with a fix round by a fresh agent between each. The stack was cut from main at b242de6.

Round Verdict Blocking Should-fix Nits Mutations (caught) Disposition
0 changes required 1 8 3 31 (29) all 12 addressed in fix round 1
1 changes required 0 3 2 29 (28) all 5 addressed in fix round 2
2 changes required 0 1 1 27 (27) all 2 addressed in fix round 3
3 (final) approve 0 0 0 2 (2) nothing left open

Nothing was skipped.

Round 0 → fixed in round 1

  • R0-1 blocking — docs/work/mvp/phase10/2026-09-13-phase10-deviation-reconciliation-and-release-readiness-checklist.md:68: Seven own rows carry a copied verdict that is false for their ID. Fixed on docs (91f0d51): SEAM-6..9 now cite phase 2's Dexpace::Registry (registry.rb) and its tests. IO-30, IO-31 and IO-39 now say 'retired apparatus', each taken from 3a's own row. A mechanical check of all 124 own rows against their owners' marks found no other contradictions; the
  • R0-2 should-fix — docs/sdk-documentation/transport-net_http.md:341: sdk-documentation still describes the pre-repair Protocol and Status behaviour. Fixed on docs (91f0d51): transport-net_http.md, http.md (both the Status and Protocol bullets) and transport-async_http.md now describe the built behaviour: Protocol admits http/1.0 (HTTP_1_0), Status is total over Integer with #standard?, and an HTTP/1.2 head still raises.
  • R0-3 should-fix — CLAUDE.md:1478: CLAUDE.md says phase 10 reached net_http only through sig/, which the diff contradicts. Fixed on docs (91f0d51): CLAUDE.md now says phase 10 reached net_http through its sig/ header, two YARD comments and two invalidated tests, per the R1 addendum.
  • R0-4 should-fix — gems/dexpace-core/lib/dexpace/proxy/resolution.rb:186: Proxy warning still leaks a password prefix when the password holds /, ? or #. Fixed on code (0d830c2): ProxyResolution#scrub_userinfo runs on the raw value before the redactor. It replaces everything from the start of the authority (after scheme:/+ or a leading run of '/', never after a bare 'user:') through the LAST '@'. The unanchored belt still runs after th
  • R0-5 should-fix — gems/dexpace-core/lib/dexpace/http/status.rb:270: HTTP-10 marked ✅ repaired (MUST), but Status.of still throws outside 0..999 with no ledger row. Fixed on code (0d830c2): I made Status total over every Integer rather than record 0..999 as a narrower reading, since HTTP-10 says 'any code MUST return a Status'. Only a non-Integer is refused. The existing status_test and response_test pins were invalidated, so they moved on the co
  • R0-6 should-fix — docs/deviations.md:33: Row 10's evidence implies a bypass the tree does not have. Fixed on code (0d830c2): docs/deviations.md row 10 is now 'confirmed, narrower': send(:new) runs the validating #initialize (HTTP-7 raises, measured on 4.0.6 and 3.2.11), and the residual holes are Request.allocate (all-nil members) and duck typing. Added C19 against §4:45 and §10 ite
  • R0-7 should-fix — docs/work/mvp/phase10/2026-09-13-phase10-deviation-reconciliation-and-release-readiness-checklist.md:450: Two leftover items are not routed, and one cites a routing line that does not exist. Fixed on docs (91f0d51): Added both items to first-release.md's post-release residues line, each with its pick-up condition: 5c's probe-claims check not reading the spelled lib-file count, and 7b R1-1 sse.md. Corrected the checklist leftover rows to point at that line.
  • R0-8 should-fix — .claude/skills/housekeeping/chapters.rb:48: The chapters check treats 'appears in' as a negation, so the usual positive attribution is never checked. Fixed on code (0d830c2): Removed 'appears in' from NEGATION. It is now a FORWARD binding: an ID run followed by 'appears in' pairs with the chapter it introduces, or with nothing when that chapter is on the next line. This fixes the phase-5 :538-539 shape without an exemption. Live fi
  • R0-9 should-fix — docs/work/mvp/phase10/2026-09-13-phase10-deviation-reconciliation-and-release-readiness-checklist.md:78: SEAM-22's mark drops the owning row's '🚫 mechanism' half. Fixed on docs (91f0d51): SEAM-22 is now marked '🚫 mechanism (§10.14); surviving clause ✅', matching phase 2. The tally is now ✅ 107 · 🚫 11.
  • R0-10 nit — docs/work/mvp/phase7/2026-09-10-phase7-segmentation-design.md:652: Some dated brackets are placed on the wrong item or in the middle of a sentence. Fixed on docs (91f0d51): Moved brackets to the end of the sentence or item that cites the key: phase 7 seg item 23, phase 0 plan :908-910, phase 5 seg :772-773 (it was inside a bold span), and phase 8b plan :337-338. Reworded the repeated tail in all eight 5bc538ba brackets to 'Only t
  • R0-11 nit — docs/first-release.md:764: The struck XCUT-12 trigger leaves its old instruction unstruck. Fixed on docs (91f0d51): The old body of the struck XCUT-12 trigger is now inside … as well.
  • R0-12 nit — CLAUDE.md:1475: CLAUDE.md says C14 was 'found by the as-built audit'. Fixed on docs (91f0d51): CLAUDE.md: C14 is reconciled from phase 4b's filing; the as-built audit found C15–C19.

Round 1 → fixed in round 2

  • R1-1 should-fix — gems/dexpace-core/test/dexpace/instrumentation/downstream_wirings_test.rb:310: The proxy scrub's 'through the LAST @' rule is untested: a first-@ mutant survives and leaks password fragments. Fixed on tests (8ec8f16): The R0-4 case now includes three spellings with an '@' inside the password ahead of a reserved character: http://user:se@c/ret@proxy.corp (c/), http://user:a@b#c@proxy.corp:1 (b#) and user:x@y/z@proxy.corp:3128 (y/). I ran the index-for-rindex mutant against i
  • R1-2 should-fix — docs/work/mvp/phase10/2026-09-13-phase10-deviation-reconciliation-and-release-readiness-checklist.md:44: Two lib repairs have no requirement row, although the checklist says the 15 added rows cover every ID a repair changed. Fixed on docs (795d30a): Added two cross-reference rows. HTTP-19 (MUST, owner 1, repair 6 / Guards x3). BODY-9 (SHOULD, owner 3b, repair 7 / Guards x4). Levels come from appendix C. The added set goes from 15 to 17 and the total from 203 to 205. I checked the count mechanically: 124 o
  • R1-3 should-fix — tools/ledger_audit.rb:77: A rubocop:disable was added without a reason. Fixed on code (b21031c): tools/ledger_audit.rb:77 now has an inline '-- reason' on its disable: the module keeps no state, so the root and resolver for each run are passed down to every row check. RuboCop with --ignore-parent-exclusion is clean.
  • R1-4 nit — .claude/skills/housekeeping/chapters.rb:55: The forward binding turns 'does not appear in X' into a positive attribution. Fixed on code (b21031c): Chapters::NEGATION now also matches 'not appear in', 'does not appear' and 'do not appear'. I measured that the reviewer's sentence now matches NEGATION. On the tests branch (8ec8f16), chapters_test gains 'a negated appears-in is not an attribution' (does/do/d
  • R1-5 nit — docs/first-release.md:605: A Post-v1 gem entry still points at the XCUT-12 trigger as live. Fixed on docs (795d30a): The dexpace-async-async entry in docs/first-release.md now says only SEAM-24's bridge rides on it. It also says the XCUT-12 fiber-scheduler trigger was closed on 2026-09-25 by phase 10's fiber verification.

Round 2 → fixed in round 3

  • R2-1 should-fix — docs/first-release.md:251: The RBS-baseline entry still says NFR-4 'stays ⏳ until a v* tag exists', contradicting P10-35 and the checklist's NFR-4 ✅. Fixed on docs (91b4dca): I rewrote docs/first-release.md:251-257, the RBS-baseline entry. It now says the entry is design §9's release-tag mechanism, not NFR-4. Appendix C's NFR-4 is a checked-in snapshot that fails the build on drift, and gates:surface_snapshot is exactly that, so NF
  • R2-2 nit — .claude/skills/housekeeping/chapters.rb:48: Two other negated spellings of 'appears in' still bind forward: 'never appears in' and 'doesn't appear in'. Fixed on code (a857785): Chapters::NEGATION gains 'never appear' and "n't appear" ('appears nowhere' was already there). On the tests branch (9b9aa7e), the negated-verb case also covers 'never appears in', "doesn't appear in", "don't appear in" and 'appears nowhere in'. I removed each

Round 3 (final) — approve, no findings

What the final reviewer verified by experiment, both interpreters

  • Deviations row 10's claims: Request.send(:new) with a GET and a body; Request.allocate — InvalidArgumentError 'a GET request must not carry a body (HTTP-7)'; allocate gives [nil, nil, nil, nil]. This matches the row.
  • 12 malformed or credentialed HTTPS_PROXY spellings through Proxy.resolve, $stderr captured (the four R3-1 shapes, the last-@ shape, leading space and tab, bracketed, bare userinfo) — 0 of 12 leak 'secret' on either Ruby, and every warning shows :@.
  • Protocol HTTP/1.0, Status 999, URL.parse!('mailto://host') by hand — http/1.0; standard? is false; InvalidArgumentError.
  • Search for any statement pairing NFR-4 with ⏳ across the register and the docs at the docs tip — None found.

Tips reviewed at the final round: code a857785, tests 9b9aa7e, docs 91b4dca on main b242de6.

Before the push, run by the maintainer

In a detached worktree at the docs tip: full bundle exec rake on 4.0.6 green (all twenty-four gates), bundle exec rubocop --fail-level=convention --ignore-parent-exclusion over 784 files clean, probe.rb clean with nine checks, verify_knowledge_structure.rb OK. The matrix set (test:gems gates:gemspec_audit gates:require_allowlist gates:clean_bundle gates:single_instance) green on 3.2.11 at the tests tip (4,040 runs / 5 skips / 96.11 %) and the code tip (4,023 / 5 / 96.05 %), and on 3.3.12 at the tests tip (4,232 / 9 / 99.82 %). The stack is linear on b242de6 and the diff over docs/product-spec*, docs/sdk-design-ruby* and docs/knowledge/harvested is empty.

Before the review started, a read-only cross-check read the phase-10 plan (written 2026-09-13, before phase 3 existed as code) against the tree and fed 35 as-built points plus the maintainer's eight decisions into the implementer's brief — among them dropping Task 8 (its defect is absent), turning Task 9 into a verification, the "small repairs" task, and repairing phase 5b's live proxy credential leak rather than filing it.

@Wahbeh-Mohammad
Wahbeh-Mohammad changed the base branch from 10-phase-10-deviation-reconciliation-and-release-readiness-tests to main September 25, 2026 18:37
@Wahbeh-Mohammad
Wahbeh-Mohammad merged commit 91d48c5 into main Sep 25, 2026
2 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

spec:deviation Deliberate, recorded divergence from the normative contract type:docs Documentation only

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Phase 10: Deviation Reconciliation and Release Readiness

1 participant