Skip to content

feat(rfc-008): P2b — bp contract data (11, bp-007 absent) + scaffold-bp + validate-bp-contract (assertions 0+1-15) + CI#384

Merged
lantiscooperdev merged 9 commits into
mainfrom
feat/rfc-008-p2b
Jun 10, 2026
Merged

feat(rfc-008): P2b — bp contract data (11, bp-007 absent) + scaffold-bp + validate-bp-contract (assertions 0+1-15) + CI#384
lantiscooperdev merged 9 commits into
mainfrom
feat/rfc-008-p2b

Conversation

@lantisprime

Copy link
Copy Markdown
Owner

RFC-008 P2b — bp contract data + scaffold + the normative contract validator

Slice 2 of 3 of the approved P2 plan (P2a #381 merged → P2b → P2c). Serves R2 (episodic-memory dictates the enforcement contract), R3 (capability-mapping contract), R4 (default classifier contract). Plan: .review-store/p2b-plan.md (FINAL, both pre-impl reviews folded).

What ships

  1. scripts/scaffold-bp.mjs — generator for the contract DATA. Id-set derived from the SoT patterns/_index.json (11 patterns, bp-007 absent — N-1); uniform STRONG tiers (the RFC's only normative content examples, L927–947; min() composition per L464; user-approved trade per plan A4); merge-on-regenerate preserves authored gates/stop/title/description and refreshes only the hash bindings (review F2); hashes live from scripts/lib/version-hash.mjs (F8/F37).
  2. patterns/bp-001..006, 008..012.json — the 11 contract instances.
  3. scripts/validate-bp-contract.mjs — RFC-008 normative assertion checklist 0 + 1–15 (L446–453 + L478–487): sub-coded assertion 0 (0-set/0-schema/0-idbind, incl. A1 id↔filename binding + F5 near-miss filenames, case-insensitive); de-vacuified closure arms 7/11 (N-3); 7b _priority arm equality (L473) with comment-aware logical-line assembly + per-occurrence token-context allowlist (6-round review-hardened — see below); fail-closed git stable-ID 8/14 (merge-base origin/main, A2 shallow guard, N-5 bootstrap carve-out); payload-schema containment via path-contain.mjs (second importer, N-7); live hash bindings 15 (A5 one-effective-source). Exit 0/1/2, crash→2, pathToFileURL main-guard.
  4. Golden corpus tests/fixtures/bp-contract/ — 17 fixtures + _corpus-index.json with attributed checks; __LIVE_*__ hash-token staging (no hand-typed digests).
  5. tests/test-validate-bp-contract.mjs98 checks: staged-overlay corpus dispatch, git-backed sandboxes, stable-ID E2E branches (rename / removal / removal+major-bump / pure-add full-green / bootstrap / no-baseline / shallow-with-ref), 14 classifier negatives (every review-round member regressed), scaffold round-trip/idempotency/merge-on-regenerate/cwd-negative, containment negatives, EVENT_IDS↔events.json Rule-14 binding (one-word export in validate-plugin-registry.mjs).
  6. CIplugin-validate.yml gains fetch-depth: 0 (load-bearing for 8/14) + the two suites above.

Review provenance (Rule 18)

  • Plan (step 2): negative-scenario-planner 9-axis walk → ACCEPT-with-amendments (20260610-090010-…-d284, A1–A6 folded); second-opinion harness (claude-subagent) R1 → ACCEPT-with-FU, converged: true (20260610-091021-…-f59e, F1–F5 + EVENT_IDS guard folded). User-approved.
  • Code (step 6): negative-scenario-reviewer, 6 rounds — the _priority exactly-one-definition guard was adversarially peeled through five HOLD rounds (spelling class → token-context allowlist → per-occurrence classification → continuation join → comment-aware join), each round's bash-confirmed bypass fixed in its own commit with per-member regressions (d4e1728, 83f7800, 844dcae, 6e9affe, 787edd0) → R6 ACCEPT, converged: true (20260610-151424-…-b0e1). Sole accepted fail-open residual: eval/quoted-string-concat definitions (needs a bash lexer) — documented in-code + P2b FUs: extract shared resolveProjectRoot/readJson to scripts/lib + classifier-guard accepted residuals #383.

Verification (this session)

  • test-validate-bp-contract.mjs 98/0 · validator vs live repo exit 0 (11 contracts, 1 manifest, 15 assertion groups, 75 checks) · regression locks: test-plugin-registry 200/0, test-validate-schemas 40/0, test-p0-schemas 122/0, test-path-contain 14/0.

FUs filed (step 9)

🤖 Generated with Claude Code

lantisprime and others added 9 commits June 10, 2026 17:28
SoT-derived from patterns/_index.json (11 patterns, bp-007 absent, N-1);
uniform STRONG tiers (RFC L927-947 examples; min() composition L464);
merge-on-regenerate preserves authored gates/stop/title/description (F2);
live hashes via scripts/lib/version-hash.mjs (F8/F37).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sub-coded assertion 0 (0-set/0-schema/0-idbind incl. A1 id-filename binding
+ F5 near-miss filenames); de-vacuified closure arms 7/11 (N-3); 7b
_priority arm equality w/ A3 single-definition guard + F3 fail-closed arm
grammar; fail-closed git stable-ID 8/14 (merge-base origin/main, A2 shallow
guard, N-5 bootstrap carve-out); payload-schema containment (13); live hash
bindings (15, A5 one-effective-source). Exports EVENT_IDS from
validate-plugin-registry.mjs for the Rule-14 binding check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ontract.mjs

Staged-overlay corpus dispatch (F1: bare files cannot satisfy the 0-set
guard); live-hash token substitution (no hand-typed digests); git-backed
sandbox with origin/main ref; stable-ID E2E branches a-g incl. A2 shallow
guard + N-5 bootstrap; synthetic-root classifier negatives (F3b); scaffold
round-trip + idempotency + F2 merge-on-regenerate + A6 cwd-negative;
EVENT_IDS<->events.json Rule-14 binding check. 79 checks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…h: 0

fetch-depth: 0 is load-bearing for the fail-closed stable-ID assertions
(8/14); N-6 fork-PR baseline note inline (tracked as issue).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…vent dup-id + case-variant filenames

F-1 (MAJOR): definition recognizer covers bash's full spelling class
(function keyword / space-before-parens / indented) so last-wins duplicate
definitions trip the A3 exactly-one guard; 3 per-spelling regressions.
F-2: event-id uniqueness (events mirror of F1d) + corpus fixture (17).
F-3: case-insensitive loose filename filter (BP-099.JSON named violation).
NITs: GIT_ENV forwarded to validator subprocesses in tests; manifest-load
failure now attributes the skip in assertions 7/11/15.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… allowlist

F-1R2: bash accepts name() + ANY compound command anywhere a command may
appear, so a definition-spelling regex can never close the duplicate class
(N11-N14 captured false-passes: brace-next-line, function-keyword
next-line, non-brace case body, after-same-line-command). Boundary
inverted: every word-bounded _priority occurrence must be the ONE
canonical definition, a $(-call site, or a full-line comment — anything
else is 'cannot prove exactly-one definition' (fail-closed by
construction). Regressions per N-member + call-site/comment FP controls.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…cation

F-1R3: the per-line short-circuit let a $(-call-site line mask a
;-separated redefinition on the same line (P1/P8 bash-confirmed). Each
word-bounded _priority occurrence is now classified individually: paren or
function-keyword opener ANYWHERE counts toward the exactly-one tally; a
$( context masks only its own occurrence; non-canonical single definition
is itself fail-closed. Regressions: P1, P8, live-call-site-line member,
unproven direct-call branch. eval-built definitions documented as the
accepted fail-open residual (needs a bash parser).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…fore the token scan

F-1R4: bash strips backslash-newline during lexing, so a token split
across physical lines (_prio\<newline>rity) is a live redefinition the
per-line scan never sees. One bounded normalization (CRLF-safe join as the
first statement) closes it; split-definition regression + harmless-
continuation FP control added. Remaining residual = eval/quoted-string-
concat tail (genuine lexer territory, documented).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
F-1R5: bash strips backslash-newline only OUTSIDE comments; the R4
unconditional join absorbed a next-line _priority definition into a
preceding trailing-backslash comment line, which the comment skip then
hid (pre-R4 code caught this shape — fix-introduced regression). Join now
honors a trailing backslash only when the logical line does not start
with #. Regression (comment-bs + planted def -> DUP) + FP control
(comment-bs + harmless line -> green); F-1R4 pair stays green. Fail-closed
join divergences (single-quote, mid-line comment) documented alongside the
accepted eval/quote-concat fail-open tail.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@lantiscooperdev lantiscooperdev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Substantive review — RFC-008 P2b (bot review per Rule 17; approval stays user-side)

Reviewed the full diff (33 files at branch point + 5 fix commits, net +1779/−13) against the approved plan (.review-store/p2b-plan.md) and the RFC-008 normative checklist (L446–453, L478–487).

Contract data + scaffold (commits 58f69f1)

  • ✅ Id-set is SoT-derived from patterns/_index.json — 11 contracts, bp-007 correctly absent (N-1); a malformed pattern_id is exit-2 fail-closed, never skipped.
  • ✅ Hashes byte-equal the committed manifest values (sha256:7ea41ed8…/sha256:13f01e5a…) and are computed live via version-hash.mjs — zero hand-typed digests.
  • ✅ Merge-on-regenerate preserves authored gates/stop/title/description (review F2) — the A4 relaxation path survives regeneration; verified by the F2 test (hand-relaxed tier survives a hash refresh).

Validator (e6f9e25 + 5 fix commits)

  • ✅ All 16 assertion groups run unconditionally (F4 no-short-circuit); assertions_run is asserted by the suite — zero-run vacuity impossible.
  • ✅ Exit taxonomy clean: 1 only via the violation tally; UsageError/crash → 2 with JSON payload; pathToFileURL main-guard present.
  • ✅ Stable-ID 8/14: merge-base baseline, set-difference invariant, A2 shallow guard and N-5 bootstrap carve-out all exercised in real temp git repos (E2E branches a–g incl. shallow-clone-with-ref → exit 2).
  • ✅ The _priority exactly-one-definition guard survived a 6-round adversarial cycle (episodes …-4453, …-b3f8, …-6deb, …-59af, …-81db → ACCEPT …-b0e1): per-occurrence token-context allowlist + comment-aware logical-line assembly; every bash-confirmed bypass member has its own regression (14 classifier negatives). The sole fail-open residual (eval/quoted-string-concat) is documented in-code and tracked in #383 with a 5-field block.
  • ✅ Injection flags (--taxonomy/--events/--bp-dir) all route through resolveContained; containment negatives (outside-root, ../ escape) are exit-2 tested. One-effective-source rule (A5) holds — assertion-15 hashes computed from the post-injection documents.

Tests + CI (e1d0c9f, 2c5604a)

  • ✅ 98/0 locally and in CI; corpus fixtures fail at their ATTRIBUTED check (sub-coded for assertion 0), not merely exit 1; __LIVE_*__ token staging avoids the fixture-rot class (lesson 20260610-000157).
  • fetch-depth: 0 is present and is load-bearing for 8/14 (a default shallow checkout would exit 2 by design — fail-closed, not skip); N-6 fork-PR caveat tracked in #382.
  • ✅ Regression locks green: plugin-registry 200/0 (EVENT_IDS export is the only registry touch), validate-schemas 40/0, p0-schemas 122/0, path-contain 14/0.

Notes for the merging user

  • The uniform-STRONG tier content was explicitly approved at the plan gate (A4 framing: maximal-enforcement default, per-pattern relaxation as later data edits — which merge-on-regenerate now preserves).
  • FUs: #382 (fork-PR baseline), #383 (lib extraction + accepted residuals), #377 (two rows added; required-check flip still user-UI).

No blocking findings. Review posted as COMMENT per Rule 17 — approval and merge are user actions.

🤖 Generated with Claude Code

@lantiscooperdev lantiscooperdev merged commit 45aceba into main Jun 10, 2026
2 checks passed
@lantisprime lantisprime deleted the feat/rfc-008-p2b branch June 10, 2026 21:34
lantiscooperdev pushed a commit that referenced this pull request Jun 13, 2026
…rs (#388)

Apply the deferred P2-plan-review findings (F-2, F-5, F-6, F-9, F-10, N-3,
N-4) as documentation-only edits, correcting RFC-008 spec text to match the
validators merged in P2a (#381) and P2b (#384).

- F-5: reword the validate-schemas.mjs "meta-meta/official-meta-schema"
  over-claim to keyword-grammar doc-validity linter (5 locations incl. two
  line-wrapped in P2-bp-contracts.md).
- N-3: drop the vacuous bp-XXX arms from assertions 7 + 11 (contracts carry
  hashes, not label/event ids; real binding is the version-hash equality).
- F-2: document event-id uniqueness in assertion 12 (events mirror of
  assertion 6) — matches shipped validate-bp-contract.mjs.
- N-4: assertion 8 reworded to the shipped set-difference invariant
  (merge-base, fail-closed, bootstrap carve-out); bp set = 11 (bp-007 absent).
- F-6: drop the never-shipped validate-taxonomy-schema.mjs from P2-bp-contracts.
- F-9: tests/lib/{mini-jsonschema,version-hash} refs updated to scripts/lib
  (promoted P1b/P2a) — rewrite in living docs, annotate in historical rows.
- F-10: P2 phase-table counts 12/2 -> 39/5 (git-stat grounded).

Plan second-opinion reviewed via harness (codex): R1 HOLD (one same-class
F-5 miss) -> R2 ACCEPT converged.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.

2 participants