feat(engine): ground hardening — argv portability + merge-base enforcement#8
Merged
Conversation
argparse on Python 3.10–3.12 cannot bind an optional slug positional that trails value-taking flags once a required positional was consumed in an earlier block: `gate RISK-ACCEPTED --owner X --ticket Y --expires Z <slug>` died `unrecognized arguments: <slug>` (worked on 3.13+ and in the canonical slug-first order). Found in PR #6 review; the test helpers were fixed then (9d52302) — this is the deferred engine half. Empirical blast radius: the gate-waiver shape is the only broken one today (all 7 optional-slug verbs probed on py3.10). Fix at main(): parse_known_args + ordered re-bind of non-flag extras into UNFILLED optional positionals, declared per subparser via set_defaults(_opt_positionals=...) on phase/advance/gate/reopen/heal/guide ("slug") and report ("milestone","task"). Safety rule (frozen §3): ANY flag-like extra refuses the whole re-bind and leftover extras re-raise the stock exit-2 "unrecognized arguments" — a typo'd flag's value is never mis-bound as a slug (wrong-task hazard). Behavior unchanged on 3.13+ (extras empty -> re-bind is a no-op). ADD loop: spec bundle frozen @ v1 (approved by Tin Dang); red suite test_argv_portability.py failed 2/7 on py3.10 pre-build for the right reason; post-build 7/7 and full tooling suite 850/850 on BOTH py3.10 and py3.14; verify auto-resolved PASS (independent adversarial refute-read: EARNED; tamper tripwire clean). Engine pin re-aimed a20734df, x3 trees byte-identical. author: Tin Dang
…e check execute the fork-base rule
The wave-ledger fork-base rule (every roster row's pasted rev-parse HEAD
echo must equal the wave `base:`) existed only as streams.md prose. This
task makes the engine EXECUTE it on two human-chosen surfaces:
A) `add.py check` — standing monitor: validates every
.add/milestones/*/WAVE.md. A FILLED echo != base is FAIL
unverified_fork_base at ANY status; a pending row is FAIL at
status: merging (merge-time strictness) but only WARN
fork_base_pending at status: live (measure-not-block). An
unparseable ledger is FAIL wave_ledger_malformed, fail-closed.
B) `add.py wave-verify [milestone]` — NEW read-only merge-time gate:
strict at any status, per-row report, refusals wave_not_found /
wave_ambiguous; never mutates WAVE.md or state.json.
The build ran the full earned-green discipline: 7 adversarial refute
passes found 11 contract-violating false-green vectors; every one is
now BOTH a frozen contract clause and a pinned suite fixture, across
four human-approved contract versions:
v1 base semantics (3 bounded self-heals: all()-token echo cells,
first-wave:-line status, header-derived echo column,
first-base:-line same-line token)
v2 echo-column ambiguity refusal — exactly one fork-base-matching
header column, >1 names the colliding labels (heal cap exhausted
-> engine HARD-STOP -> human change-request, by design)
v3 strict status terminator — exact token equality; the unfilled
template placeholder `live|merging` and suffix drift are
malformed, never parsed as a valid prefix (2nd HARD-STOP cycle)
v4 status label left anchor — an embedded `substatus:` is not a
status field (close-gap-before-gate micro change-request on a
disclosed pass-6 observation)
Refute passes 6 and 7 both returned EARNED with empty findings; the
human verify gate recorded PASS (autonomy: conservative).
Suite 850 -> 865 tests, green on py3.10 and py3.14. New
test_merge_base_enforcement.py (15 tests, arrange-through-CLI,
render-blind asserts). Census: wave-verify in test_min_pillar
LIFECYCLE + _NONZERO_OK. Engine pin re-aimed
(b441421c938f8306773cd81a1859c1be), x3 trees byte-identical.
streams.md (x3 mirrors) names `add.py wave-verify` as the merge-time
gate before the first merge-back.
Closes the enforcement-deferral recorded at wave-protocol-runtime's
freeze (v19 wave delta #7) — words-exist != method-works, now closed
structurally.
author: Tin Dang
…rsion 28
Human-gated consolidation of the 11 open deltas left by the ground
tasks (engine-argv-portability, engine-merge-base-enforcement) and
wave-protocol-runtime — all 11 confirmed, none rejected.
CONVENTIONS.md +9 new bullets:
(SDD) hand-written-input parsing discipline — exactly-one-match +
terminator-explicit, never substring-first-wins, never \b
(2 deltas merged)
(SDD) name an enforcement-deferral explicitly at the freeze
(TDD) refute-read coverage gaps route as next-loop deltas, never
post-hoc test edits
(TDD) parser suites need grammar-DRIFT fixtures, not only
template-conformant ones
(TDD) token-presence + xN-mirror-parity for prose-discipline changes
(ADD) grounding probes against mutating verbs: sandbox only
(ADD) close-gap-before-gate converges
(ADD) folded runtime-exceptions mirror onto every protocol surface
(ADD) the check SHIFTS, never SKIPS, on an unsatisfiable evidence cell
CONVENTIONS.md +1 flip-cite: the fv27 mechanical-HARD-STOP guard
validated under real fire (2 heal_exhausted cycles on
engine-merge-base-enforcement, both held).
PROJECT.md: foundation-version 27 -> 28; one Key Decisions row.
The 11 delta lines flipped open -> folded in their three TASK.md files.
author: Tin Dang
…tep-seams, udd-design-foundation
Human-confirmed intake (2026-06-11) created after the engine-hardening
ground tasks shipped and the foundation folded to v28:
build-scope-lock (sub-milestone, trust) — §5 BUILD gains a declared
Scope file-touch allowlist + ordered Strategy batches, frozen with
the specification bundle and gate-enforced (touched ⊆ declared,
violations route to the bounded self-heal loop). 3 tasks; the
git-free touch-detection contract freezes first.
next-step-seams (sub-milestone, UX) — every mutating engine verb
prints an engine-sourced `next:` footer naming the driver
([you drive] vs [human gate]); folds in the two stale v20 UX
follow-ups. 3 tasks; the single-resolver footer grammar freezes
first.
udd-design-foundation (new-major) — render-ready UDD foundation
(human adjustment 2026-06-12): DESIGN.md template + a JSON
foundation carrying DTCG-v2025.10-aligned compact token layers
(primitive → semantic → component), a component catalog, and
json-render-compatible prototype content trees, linted fail-closed
by stdlib `add.py check`; renderer never bundled, recipe
documented. 4 tasks; the catalog/content schema pins a named
json-render version at its freeze.
Each MILESTONE.md carries goal · In/Out · shared decisions · the
freeze-first contracts · breadth-first tasks · exit criteria mapped to
task slugs. Created via add.py new-milestone, human-confirmed per
scope.md (confirm-before-create).
author: Tin Dang
…s de-tokenized The seam audit (CI gate) requires exactly ONE machine-readable `Outcome: PASS|RISK-ACCEPTED|HARD-STOP` line in §6; the engine-merge-base-enforcement multi-version history carried three. Format-only fix: the v1/v2 HARD-STOP records and the v3 resolution line are reworded to `Recorded (vN, superseded/resolved): ...` — content verbatim, history intact — leaving the final v4 `Outcome: PASS` as the single canonical token, matching state.json. audit: clean (51 tasks checked). author: Tin Dang
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.
Summary
Two ground tasks hardening the ADD engine before the enhancement milestones:
1.
engine-argv-portability(0c55eb7)add.pyargv parsing is portable across py3.10–3.14: value-flags before an optional positional slug (gate PASS --waive x zz-slugshapes) now bind correctly on py≤3.12main()usesparse_known_args+_rebind_optional_positionalswith explicit_opt_positionalsmarkers on 7 verbs; unknown/flag-like extras still refuse with exit 2test_argv_portability.py(7 tests)2.
engine-merge-base-enforcement(20e9a07)add.py check— standing monitor over everyWAVE.md: FILLED mismatch → FAILunverified_fork_baseat any status; pending row → FAIL atmerging, WARNfork_base_pendingatlive; unparseable → FAILwave_ledger_malformed(fail-closed)add.py wave-verify [milestone]— NEW read-only merge-time gate, strict at any status, per-row report, never mutatestest_merge_base_enforcement.py(15 tests);wave-verifycensus-classified; engine pin re-aimed ×3 byte-identical trees; streams.md ×3 mirrors name the gateTest plan
add.py check: 258 passed, 0 failed