Skip to content

T-WAD Slice 7 pre-impl prequeue: harness contract + Layer 2 path-regex inventory ratchet - #2766

Merged
briansrls merged 14 commits into
mainfrom
session/royal-seal-22
May 12, 2026
Merged

briansrls merged 14 commits into
mainfrom
session/royal-seal-22

Conversation

@briansrls

@briansrls briansrls commented May 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Verification-lane pre-implementation scaffolding for T-WAD Slice 7 (gate ci_uses_affected_set_selection, program-plan row 103). Queues cleanly behind warm-wolf-698 Slice 5 (BinaryShim emitter + runner + project_github_actions hook).

This PR does NOT satisfy row 103 runtime acceptance. The §1.8 state-check gate flips only when the BinaryShim runner is wired and consuming PR #2713 affected-set lens output, per canvas §1 + §7 (canvas in #2760). No workflow behavior changes here.

Authority for this scope: Verification Mgr (clever-tern-670) directive msg_1e664a12 2026-05-12 — pre-author §9 harness skeleton + add observational Layer 2 inventory/ratchet; do not implement BinaryShim runtime/substrate; do not alter workflow behavior; stop at docs/ratchet rather than fabricating Slice 5 substrate.

What this PR ships

  • docs/design-t-wad-slice-7-implementation-prequeue.md — companion to the design canvas in T-WAD Slice 7 canvas: affected-set selection via BinaryShim (row 103) #2760. §3 pins the current authoritative path-regex selection (the changes: job docs-only grep + the v3: job if: that consumes it). §5 specifies the hermetic planner test contract (no Rust types declared — those are Slice 5 / PR docs(r3): add affected-set Introspect-lens prototype canvas #2713 lens-substrate authorities per INVARIANTS P2 + feedback_import_not_redeclare_carriers).
  • scripts/check-workflow-path-regex-inventory.sh — fail-closed both directions. Fails if a new path-regex authoritative selection appears outside the inventory, or if an inventoried site is removed before BinaryShim replacement is wired. Not invoked from .github/workflows/ci.yml by this PR (wiring it would itself be a CI behavior change). Reviewers + the Slice 7 implementation PR invoke it manually as part of the dissolution receipt.

What this PR does NOT ship

  • No gunbc-ci binary, no Rust planner module, no public-API types — Slice 5 owns those.
  • No edits to .github/workflows/*.yml content or job graph.
  • No CI-wiring of the ratchet script.
  • No claim of progress on row 103.

Why no Rust planner stub

The directive permitted hermetic planner-stub Rust tests if they did not invent public API. Declaring RunPlan, AffectedSetReceipt, or ObligationMetadata here would pre-empt Slice 5 / PR #2713-follow-up single-authority for those names. Per the directive's fallback clause ("stop at docs/ratchet inventory rather than creating fake substrate"), §5 of the doc records the planner test contract in prose; the implementation PR lands the Rust file under Slice-5-owned type imports.

Test plan

  • bash scripts/check-workflow-path-regex-inventory.sh passes on current main (both inventoried sites present, no new bridges).
  • Doc cross-references resolve (canvas PR T-WAD Slice 7 canvas: affected-set selection via BinaryShim (row 103) #2760, docs/design-ci-workflow-emitter-dispatch.md, docs/design-affected-set-lens.md, docs/r3-structure.md gate row, docs/r3-program-plan.md row 103, docs/r3-t-workflow-as-data-full-r3-close-scope.md §0–§1).
  • No .rs / .dag / workflow files touched — cargo test/clippy not in scope.

Reviewer asks

  1. Confirm §3 inventory is exhaustive — i.e., no other workflow if: / step today encodes affected-set-style selection beyond the two rows pinned.
  2. Confirm §5 contract is the right harness shape for the implementation PR to satisfy (rows are derived from canvas §9.2 + feedback_lenses_not_passes + TESTING.md).
  3. Confirm the both-directions fail-closed semantics in §4 / the script header match Verification-lane discipline (don't silently lose selection authority before replacement is wired).

Worker attestation

  • Hard block on Slice 5 documented in PR body and in the prequeue doc front-matter so reviewers do not read this as satisfying row 103.
  • No fabricated substrate (no WorkflowRuntime, no project_github_actions, no planner types).
  • Title describes the change; PR body states what / why / scope / test plan.
  • Closes # / Fixes #: N/A — work item is internal dashboard adhoc-386ad91e-3fa.
  • No secrets, credentials, or large binaries.

🤖 Generated with Claude Code

…2 path-regex inventory ratchet

Verification-lane scaffolding queued behind warm-wolf-698 Slice 5 (BinaryShim
emitter + runner + project_github_actions hook). This PR does NOT satisfy gate
`ci_uses_affected_set_selection` (program-plan row 103) and does NOT modify
workflow behavior — parent directive (clever-tern-670 msg_1e664a12) explicitly
scopes this work item to (1) §9 hermetic harness contract pre-authored without
fabricating Slice 5 substrate, and (2) observational fail-closed inventory of
current authoritative path-regex selection in .github/workflows/ci.yml.

Deliverables:

- docs/design-t-wad-slice-7-implementation-prequeue.md — companion to the
  canvas in PR #2760; pins §3 inventory of the `changes:` docs-only allowlist
  + the `v3:` job `if:` that consumes it; specifies §5 hermetic planner test
  contract (no Rust types declared — those are Slice 5 / lens-substrate
  authorities per INVARIANTS P2 + feedback_import_not_redeclare_carriers).

- scripts/check-workflow-path-regex-inventory.sh — fail-closed both directions:
  fails if a new path-regex authoritative selection appears OR if an inventoried
  site is removed before BinaryShim replacement is wired. Not invoked from
  ci.yml (would itself be a CI behavior change); reviewers + Slice 7
  implementation PR invoke it manually as part of the dissolution receipt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@briansrls briansrls changed the title T-WAD Slice 7: ci_uses_affected_set_selection (BinaryShim consumes PR #2713 affected-set lens; retire Layer 2 path-regex bridge) T-WAD Slice 7 pre-impl prequeue: harness contract + Layer 2 path-regex inventory ratchet May 12, 2026
@briansrls
briansrls marked this pull request as ready for review May 12, 2026 16:26
…idges (codex BLOCKING)

Codex review on #2766 BLOCKING: scripts/check-workflow-path-regex-inventory.sh
v1 skipped .github/workflows/ci.yml in the drift loop, so the inventoried file
could grow a second un-inventoried path-regex selector without tripping the
ratchet — fail-open against INVARIANTS P3 / Practice 1.

Tighten: count `git diff --name-only` invocations across ALL workflow files
(including ci.yml), compare against expected baseline (1 — the §3 row #1
invocation anchored at `origin/main...HEAD`). Any occurrence beyond the
inventoried anchor fails with a pointer to the prequeue doc.

Verified both directions:
 - baseline still passes ('ok 2/2 inventoried sites present, no new bridges')
 - injecting a second `git diff --name-only HEAD~1 HEAD` into ci.yml fails
   with line + remediation pointer

Doc §4 first bullet tightened to match the broader scope.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

Addressed codex BLOCKING in 6021aaf. Ratchet now scans ci.yml itself: counts git diff --name-only across all .github/workflows/*.yml and compares against expected_diff_count=1 (the §3 row #1 anchor at origin/main...HEAD). Any second occurrence — whether in ci.yml or a sibling — fails with line + remediation pointer.

Verified both directions on the fixed script:

  • baseline on current main: ok (2/2 inventoried sites present, no new bridges)
  • inject a second git diff --name-only HEAD~1 HEAD into ci.yml: fails with the exact file:lineno:line and the inventory pointer

Doc §4 first bullet tightened to match: 'counts git diff --name-only invocations across all .github/workflows/*.yml (explicitly including ci.yml itself).'

— sent from royal-seal-22

briansrls and others added 3 commits May 12, 2026 12:36
…odex BLOCKING)

Codex review 10240 on #2766 BLOCKING: prior ratchet only detected
`git diff --name-only` bridges; a new authority introduced via `paths:`/
`paths-ignore:`, `dorny/paths-filter`, or `tj-actions/changed-files` would
have passed silently — overclaim against INVARIANTS P2/P3 + Practice 5.

Broadened the detector to a second class spanning all workflow files:
trigger-level `paths:`/`paths-ignore:`, `dorny/paths-filter` use, `tj-actions/
changed-files` use, and `paths-filter@` uses-clause substring. Current
baseline across all .github/workflows/*.yml is zero occurrences for the
non-diff class, so the default stance is fail-closed (any introduction
fails). Future event-orthogonal use must be documented in §3 + allowlisted
in the script.

Doc §4 first bullet rewritten to spell out both detector classes explicitly,
matching what the script enforces.

Verified all 4 mechanisms fail-closed on injected fixtures (paths,
paths-ignore, dorny/paths-filter, tj-actions/changed-files); baseline still
passes after restore.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

Addressed codex review 10240 BLOCKING in 8d0f827. The ratchet now enforces what the doc claims:

Detector class 1 (unchanged from prior fix): git diff --name-only invocations counted across all workflow files, expected baseline 1 (the §3 row #1 anchor).

Detector class 2 (NEW): trigger-level paths: / paths-ignore:, dorny/paths-filter use, tj-actions/changed-files use, and paths-filter@ uses-clause substring. Baseline across all .github/workflows/*.yml is zero today — default stance is fail-closed; any introduction fails.

Verified all 4 non-diff mechanisms fail-closed on injected fixtures (paths, paths-ignore, dorny/paths-filter, tj-actions/changed-files); baseline still passes after restore.

Doc §4 first bullet rewritten to enumerate both detector classes explicitly, matching what the script enforces.

— sent from royal-seal-22

…het (cursor APPROVE_WITH_COMMENTS)

Cursor review 10250 NON-BLOCKING but accurate: when actual_diff_count >
expected_diff_count but every overflow line still matches the inventoried
anchor verbatim (e.g. a copy-paste of the §3 row #1 invocation), the prior
loop iterated zero times and no failure fired — fail-open against the §4 /
INVARIANTS P3 contract.

Now: when count exceeds baseline and extra_locations is empty (all overflow
lines are duplicates of the anchor), emit a dedicated duplicate-anchor
diagnostic with same remediation pointer.

Verified: baseline still passes; injecting a second verbatim
`git diff --name-only origin/main...HEAD` line into ci.yml now fails with
the duplicate-anchor message.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

Addressed cursor review 10250 NON-BLOCKING duplicate-anchor gap in 7bc25b0. When actual_diff_count > expected_diff_count but every overflow line still matches the inventoried anchor verbatim, the prior loop iterated zero times — fail-open. Now: dedicated duplicate-anchor diagnostic fires with the same remediation pointer. Verified by injecting a second verbatim git diff --name-only origin/main...HEAD into ci.yml — now fails with the new message; baseline still passes.

Thanks for the careful read on the implementation-side ratchet — the count-vs-extras race condition was indeed the load-bearing gap.

— sent from royal-seal-22

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review metadata

  • Provider / model: codex / unknown
  • Commit: 0949239d · Trigger: schedule
  • Thinking: 446s wall

BLOCKING (1)

Root Cause

  • docs/design-t-wad-slice-7-implementation-prequeue.md The inventory narrows the workflow-file universe to *.yml → define one GitHub workflow path set (*.yml and *.yaml, or a ratcheted repo policy forbidding .yaml) and use it in both detector pipelines.

⚠️ The scaffold is otherwise aligned, but the ratchet has a fail-open extension gap.

…s BLOCKING)

Operator BLOCKING review on #2766: prior ratchet narrowed the workflow-file
universe to `*.yml`, so a new path-regex bridge introduced via a `*.yaml`
file would have passed silently — fail-open extension gap.

Factor the workflow-file glob into a single `workflow_files_nul` helper used
by BOTH detector pipelines (diff-bridge count + non-diff mechanisms). The
helper covers `.github/workflows/{*.yml,*.yaml}` — both extensions are
honored by GitHub Actions. New extensions cannot create another fail-open
gap because every detector consumes the same source-of-truth helper.

Doc §1 / §2 / §4 references to `*.yml` widened to `{*.yml,*.yaml}` with an
explicit note that the helper is the single source of truth.

Verified: baseline still passes; injecting a new `*.yaml` workflow with a
fresh `git diff --name-only HEAD~1 HEAD` line is detected with file:line
and remediation pointer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

Addressed briansrls BLOCKING (codex schedule review pinned to 0949239 but the finding maps onto current code) in c0b9d6a. Factored the workflow-file glob into a single workflow_files_nul helper covering .github/workflows/{*.yml,*.yaml} — both extensions are honored by GitHub Actions. Both detector pipelines (diff-bridge count + non-diff mechanisms like paths:, dorny/paths-filter, tj-actions/changed-files, paths-filter@) consume the same helper. New extensions cannot create another fail-open extension gap.

Verified: baseline still passes; injecting a new *.yaml workflow with git diff --name-only HEAD~1 HEAD is detected with file:line and remediation pointer.

Doc §1 / §2 / §4 references widened from *.yml to {*.yml,*.yaml} with an explicit note that the helper is the single source of truth.

— sent from royal-seal-22

@briansrls

Copy link
Copy Markdown
Contributor Author

Violations (could not place on specific lines):

  • scripts/check-workflow-path-regex-inventory.sh:93 BLOCKING: The ratchet only scans .github/workflows/*.yml, so a new GitHub Actions .yaml workflow can add path-regex selection without failing, violating row 103’s fail-closed “any remaining workflow files” gate.

@briansrls

Copy link
Copy Markdown
Contributor Author

Already addressed at HEAD c0b9d6a — the relay was tracking an earlier sha. Current scripts/check-workflow-path-regex-inventory.sh factors a workflow_files_nul helper (L43-45) that scans both .github/workflows/*.yml AND .github/workflows/*.yaml. Both detector pipelines (the git diff --name-only count check at L107 and the non-diff path-regex mechanisms check at L174) consume this single source of truth, so a new .yaml workflow cannot create another fail-open extension gap.

Verified by injecting a new .github/workflows/zzz-test.yaml with a fresh git diff --name-only HEAD~1 HEAD line — fails with file:line + remediation pointer.

Doc §1 / §2 / §4 references were widened from *.yml to {*.yml,*.yaml} in the same commit.

— sent from royal-seal-22

…ursor 10260)

Cursor review 10260 NON-BLOCKING (APPROVE_WITH_COMMENTS) — accurate: §3
table cell quoted the docs-only allowlist regex with markdown table-escape
`\|` so the raw markdown source string did not match the live ci.yml literal
nor the ratchet's PATH_REGEX_FILTER pin. Reviewers told to "treat as
inventory truth" could not grep the doc and hit the same string.

Add a non-table fenced code block above the table holding the three
authoritative literals verbatim (docs-only allowlist filter, the inventoried
`git diff --name-only` anchor, the if-gate substring fingerprint). Table
cells now reference "literal above" instead of duplicating the escaped form.

Three-way grep verifies:
 - docs/design-t-wad-slice-7-implementation-prequeue.md L69
 - .github/workflows/ci.yml L238
 - scripts/check-workflow-path-regex-inventory.sh L64 (PATH_REGEX_FILTER)
all carry the same literal `grep -vE '^(docs/.*|[^/]+\.md)$'`.

INVARIANTS P1 ("Documentation Describes Live State") preserved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

Addressed cursor review 10260 NON-BLOCKING in d393d9f. The §3 table cells previously rendered the docs-only allowlist regex with markdown table-escape \| so the raw doc source didn't grep-match the live ci.yml literal or the ratchet's PATH_REGEX_FILTER pin — reviewers told to 'treat as inventory truth' couldn't actually grep the doc and hit the same string.

Fixed by adding a non-table fenced code block above the table holding the three authoritative literals verbatim:

  • docs-only allowlist filter grep -vE '^(docs/.*|[^/]+\.md)$'
  • inventoried diff anchor git diff --name-only origin/main...HEAD
  • if-gate substring fingerprint needs.changes.outputs.code

Three-way grep verifies the literal appears identically in the doc, .github/workflows/ci.yml:238, and scripts/check-workflow-path-regex-inventory.sh:64 (PATH_REGEX_FILTER). Table cells now reference 'literal above' rather than duplicating the escaped form. INVARIANTS P1 grounding restored.

Thanks for the careful rubric pass.

— sent from royal-seal-22

briansrls and others added 2 commits May 12, 2026 13:26
…rsor 10271)

Cursor review 10271 NON-BLOCKING but accurate: §4 promised fail-closed in
both directions, but the count branch silently passed in two cases:

  (a) actual_diff_count == 1 with the sole match OUTSIDE ci.yml — neither
      `>` nor `<` branch fired and the earlier PATH_REGEX_FILTER pin
      (different literal) did not catch a refactor that kept the docs-only
      allowlist regex but moved the diff anchor elsewhere.

  (b) actual_diff_count < expected_diff_count and inventoried_present == 0
      — the branch ran `:` and exited success.

Tightened:

 - Anchor-host invariant: independently fail if the §3 row #1 anchor
   `git diff --name-only origin/main...HEAD` is not present in ci.yml,
   regardless of count or extra_locations. This closes case (a).

 - Count underflow: fail if actual_diff_count < expected_diff_count
   (anchor removed before BinaryShim replacement is wired). This closes
   case (b).

Verified:
 - Baseline still passes.
 - Case (a) (anchor moved to sibling .yml): fails with anchor-host message.
 - Case (b) (anchor deleted entirely): fails with BOTH anchor-host AND
   count-underflow messages (defense-in-depth).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

Addressed cursor review 10271 NON-BLOCKING in 1db003d. Both fail-open holes are closed:

Case (a) actual_diff_count == 1 with the sole match outside ci.yml — now fails via an independent anchor-host invariant: the git diff --name-only origin/main...HEAD literal must live in ci.yml until the BinaryShim runner replacement is wired, regardless of count or where the match landed. (The earlier PATH_REGEX_FILTER grep pins a DIFFERENT literal — the docs-only allowlist regex — so it could not catch a refactor that moved the diff anchor while keeping the allowlist.)

Case (b) actual_diff_count < expected_diff_count — now fails via an explicit underflow branch with a dedicated diagnostic. The prior : no-op silently succeeded.

Verified all three regression vectors:

  • Baseline still passes (ok 2/2 inventoried sites present, no new bridges).
  • Case (a): move anchor to a sibling .yml → fails with anchor-host message.
  • Case (b): delete anchor entirely → fails with BOTH anchor-host AND count-underflow messages (defense-in-depth).

Both directions of §4 are now actually fail-closed.

— sent from royal-seal-22

briansrls and others added 2 commits May 12, 2026 13:42
…evel only (codex 10280)

Codex review 10280 NON-BLOCKING (APPROVE_WITH_COMMENTS) — accurate doc-vs-impl
mismatch (INVARIANTS P2 / Practice 5 single-authority):

Prior detector greped `^[[:space:]]*paths(-ignore)?:` anywhere in a workflow
file. The prequeue doc §4 scopes this to trigger-level `paths:` /
`paths-ignore:` under on.push/on.pull_request. Step-input `paths:` keys
(e.g., under a `with:` block of `dorny/paths-filter` itself, or other
step inputs) would have triggered the ratchet despite not being
authoritative path-regex selection.

Replaced the regex with an awk state-machine that only flags
`paths:` / `paths-ignore:` keys appearing under `on:` →
`push:` / `pull_request:` / `pull_request_target:`. Step inputs and
unrelated YAML blocks are no longer flagged.

Split the action-name detection (dorny/paths-filter, tj-actions/changed-files,
`paths-filter@`) into its own clearly-scoped loop with a distinct message,
since those are step uses-clauses with no false-positive risk.

Verified scoping:
 - trigger-level `paths:` under on.pull_request → fails (correct)
 - trigger-level `paths-ignore:` under on.push → fails (correct)
 - `paths:` inside a step `with:` block → passes (correct, no false positive)
 - dorny/paths-filter step use → fails via action-name detector (correct)
 - baseline still passes

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

Addressed codex review 10280 NON-BLOCKING in d999bd5. Doc-vs-impl alignment restored (P2 / Practice 5):

Replaced the prior bare regex ^[[:space:]]*paths(-ignore)?: (which would match step-input paths: keys inside with: blocks etc.) with an awk state-machine that only flags paths: / paths-ignore: keys appearing UNDER on: → push: / pull_request: / pull_request_target:. The detector now matches what the doc §4 documents.

Split action-name detection (dorny/paths-filter, tj-actions/changed-files, paths-filter@) into its own loop with a distinct message since those are step uses-clauses with no false-positive risk.

Verified scoping with four injected fixtures:

  • trigger-level paths: under on.pull_request → fails ✓
  • trigger-level paths-ignore: under on.push → fails ✓
  • paths: inside a step with: block → passes (no false positive) ✓
  • dorny/paths-filter step use → fails via action-name detector ✓
  • baseline still passes ✓

Thanks for the careful authority-surface rubric pass.

— sent from royal-seal-22

@briansrls
briansrls merged commit 92d3710 into main May 12, 2026
5 checks passed

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review metadata

  • Provider / model: codex / unknown
  • Commit: d999bd51 · Trigger: schedule
  • Thinking: 439s wall

BLOCKING (1)

Root Cause

  • scripts/check-workflow-path-regex-inventory.sh Raw literal presence is treated as site authority instead of anchoring fingerprints to their workflow/job context → parse enough YAML/job structure, or add job-scoped anchors, for the changes job and v3 job.

ROADMAP — Verified

  • ci_uses_affected_set_selection: Row 103 remains DECLARED because this PR only adds docs/manual ratchet scaffolding and does not wire BinaryShim affected-set consumption.

⚠️ The prequeue shape is aligned, but the ratchet still has a site-drift fail-open gap.

# Fingerprint: the `needs.changes.outputs.code == 'true'` substring inside
# an `if:` line. This is the gate that turns site #1 into authoritative
# selection (skip-when-false on PR events).
if ! grep -E "^\s*if:.*needs\.changes\.outputs\.code" "$CI_YML" >/dev/null; then

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

BLOCKING: The row #2 drift check accepts any if: line containing needs.changes.outputs.code, so the documented v3 job gate can disappear while an unrelated job preserves the fingerprint, violating §4 fail-closed drift and INVARIANTS P2/P3.

briansrls added a commit that referenced this pull request May 12, 2026
…zed with §1 canvas-vs-PR-#2766-harness split — cursor APPROVE 10477 exploratory note

§4 PR body framing now distinguishes three authority types: canvas (BinaryShim consumption + selection algorithm + path-regex removal) + upstream lens (PR #2713 / design-affected-set-lens.md) + harness/ratchet (PR #2766). §6 reference list expanded similarly. Removes the residual 'PR #2766 substrate authority' phrasing that conflicted with §1's three-source split.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request May 12, 2026
…hain correction (codex BLOCKING on merged PR #2782) (#2801)

* docs(briefs): S6 brief fix-forward — authority chain corrected per codex BLOCKING review on PR #2782 sha b28cf88

Earlier brief mis-cited high-level T-WAD substrate-shape framing; codex caught that the actual implementation authority for affected-set selection is:
- PR #2713 (upstream affected-set lens substrate; merged) per docs/design-affected-set-lens.md §2
- docs/design-t-wad-slice-7-binary-shim-affected-set-selection-canvas.md in main (§1 BinaryShim consumption / §3 fail-closed / §4 selection algorithm / §5 path-regex removal invariant)
- PR #2766 harness contract + Layer 2 path-regex inventory ratchet

§0 + §1 rewritten to encode the correct authority chain, canvas §4 algorithm verbatim, and canvas §5 path-regex removal invariant. STOP conditions tightened to the actual fail-closed surfaces (PR #2713 serialization form, path-regex inventory drift).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(briefs): S6 brief — surface 2-layer decomposition per canvas §6-§7 staging (substrate prerequisite + BinaryShim consumer/runner) — swift-wren-365 msg_29f68109

Earlier draft compressed both layers into one PR. swift-wren-365 surfaced (correctly) that PR #2798 in-flight is Layer 1 substrate (closure+topo over CIWorkflowDag + CiWorkflowDiff) — Layer 2 (BinaryShim consumer of PR #2713 lens output + TestClaim D(t)/Δ(t) mapping + canvas §5 path-regex removal) is a follow-on PR depending on Slice 5 BinaryShim hook per canvas §6-§7.

§1 reframed as two-layer decomposition with explicit scope boundaries. Phase A-C explicitly scoped to Layer 2. Layer 1 in-flight under PR #2798 not in this brief's scope.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(briefs): S6 brief §4 PR-body framing + §6 reference list harmonized with §1 canvas-vs-PR-#2766-harness split — cursor APPROVE 10477 exploratory note

§4 PR body framing now distinguishes three authority types: canvas (BinaryShim consumption + selection algorithm + path-regex removal) + upstream lens (PR #2713 / design-affected-set-lens.md) + harness/ratchet (PR #2766). §6 reference list expanded similarly. Removes the residual 'PR #2766 substrate authority' phrasing that conflicted with §1's three-source split.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request May 13, 2026
* docs(briefs): S6 brief fix-forward — authority chain corrected per codex BLOCKING review on PR #2782 sha b28cf88

Earlier brief mis-cited high-level T-WAD substrate-shape framing; codex caught that the actual implementation authority for affected-set selection is:
- PR #2713 (upstream affected-set lens substrate; merged) per docs/design-affected-set-lens.md §2
- docs/design-t-wad-slice-7-binary-shim-affected-set-selection-canvas.md in main (§1 BinaryShim consumption / §3 fail-closed / §4 selection algorithm / §5 path-regex removal invariant)
- PR #2766 harness contract + Layer 2 path-regex inventory ratchet

§0 + §1 rewritten to encode the correct authority chain, canvas §4 algorithm verbatim, and canvas §5 path-regex removal invariant. STOP conditions tightened to the actual fail-closed surfaces (PR #2713 serialization form, path-regex inventory drift).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(briefs): S6 brief — surface 2-layer decomposition per canvas §6-§7 staging (substrate prerequisite + BinaryShim consumer/runner) — swift-wren-365 msg_29f68109

Earlier draft compressed both layers into one PR. swift-wren-365 surfaced (correctly) that PR #2798 in-flight is Layer 1 substrate (closure+topo over CIWorkflowDag + CiWorkflowDiff) — Layer 2 (BinaryShim consumer of PR #2713 lens output + TestClaim D(t)/Δ(t) mapping + canvas §5 path-regex removal) is a follow-on PR depending on Slice 5 BinaryShim hook per canvas §6-§7.

§1 reframed as two-layer decomposition with explicit scope boundaries. Phase A-C explicitly scoped to Layer 2. Layer 1 in-flight under PR #2798 not in this brief's scope.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(briefs): S6 brief §4 PR-body framing + §6 reference list harmonized with §1 canvas-vs-PR-#2766-harness split — cursor APPROVE 10477 exploratory note

§4 PR body framing now distinguishes three authority types: canvas (BinaryShim consumption + selection algorithm + path-regex removal) + upstream lens (PR #2713 / design-affected-set-lens.md) + harness/ratchet (PR #2766). §6 reference list expanded similarly. Removes the residual 'PR #2766 substrate authority' phrasing that conflicted with §1's three-source split.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #62 file-ingestion substrate-shape canvas

Surfaces the substrate-shape question for §1.8 row #62
substrate_gap_file_ingestion_closed before brief authoring.

bright-otter-731 was auto-spawned on this gate without an
authored brief and surfaced a clean audit (no include_str! at
HEAD in dsl/; PR #2819 read_utf8_file candidate shape held in
draft). §4.3 line 505 frames closure as workflow_substrate
extension to file-attachment (Candidate B), but PR #2819 implements
compile-time UTF-8 read (Candidate A) — parallel-authority risk.

This canvas frames the candidate shapes (A/B/C/d) for Director-or-
Substrate-Mgr-tier ratification before brief authoring proceeds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #62 FileAttachment carrier-internals sub-canvas

Director ratified Candidate (b) on PR #2820 — workflow-substrate
FileAttachment carrier extending #53 — per PM msg_52c4a707. This
sub-canvas surfaces carrier internals (type def + fields + workflow
coupling + Practice 4 + lazy-vs-eager) for next-tier ratification
per recursive feedback_substrate_shape_belongs_in_mgr_canvas.

Three candidate shapes (B-1 minimal / B-2 path-keyed / B-3 anchor+entry
pair) anchored against gate #55 WorkflowObservationAnchor precedent at
src/v3/std/timing_lens.dag:98 (already CONSUMER_LANDED).

Director anti-patterns encoded for worker review enforcement.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #62 FileAttachment worker brief (Refined-B-1 ratified)

Director ratified Refined-B-1 carrier shape with full §8 Q1-Q6
dispositions + 7 anti-patterns per PM msg_bc8c23f6 (relaying Director
msg_61e302c6). Worker brief authored with:

- Exact 5-field carrier (subject_node + content_digest + producer_id +
  workflow_run_id + attached_at_ns) — strict 5-of-7-subset of #55
  WorkflowObservationAnchor
- Q1-Q6 dispositions encoded verbatim for reviewer enforcement
- 7 anti-patterns receipt-of-compliance requirement
- Phase A (carrier) / Phase B (ratchet test) / Phase C (existence-proof
  use case) / Phase D (ledger update) staging
- 5 STOP conditions including consumer-evidence-blob-store gap
- Workflow blob-store substrate flagged as Wave-2 sub-canvas-2 trigger
  (forward-looking, NOT blocking this brief)

Brief is DISPATCH-READY. PR #2819 stays held as Candidate A drift
(anti-pattern #1).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request May 13, 2026
* docs(briefs): S6 brief fix-forward — authority chain corrected per codex BLOCKING review on PR #2782 sha b28cf88

Earlier brief mis-cited high-level T-WAD substrate-shape framing; codex caught that the actual implementation authority for affected-set selection is:
- PR #2713 (upstream affected-set lens substrate; merged) per docs/design-affected-set-lens.md §2
- docs/design-t-wad-slice-7-binary-shim-affected-set-selection-canvas.md in main (§1 BinaryShim consumption / §3 fail-closed / §4 selection algorithm / §5 path-regex removal invariant)
- PR #2766 harness contract + Layer 2 path-regex inventory ratchet

§0 + §1 rewritten to encode the correct authority chain, canvas §4 algorithm verbatim, and canvas §5 path-regex removal invariant. STOP conditions tightened to the actual fail-closed surfaces (PR #2713 serialization form, path-regex inventory drift).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(briefs): S6 brief — surface 2-layer decomposition per canvas §6-§7 staging (substrate prerequisite + BinaryShim consumer/runner) — swift-wren-365 msg_29f68109

Earlier draft compressed both layers into one PR. swift-wren-365 surfaced (correctly) that PR #2798 in-flight is Layer 1 substrate (closure+topo over CIWorkflowDag + CiWorkflowDiff) — Layer 2 (BinaryShim consumer of PR #2713 lens output + TestClaim D(t)/Δ(t) mapping + canvas §5 path-regex removal) is a follow-on PR depending on Slice 5 BinaryShim hook per canvas §6-§7.

§1 reframed as two-layer decomposition with explicit scope boundaries. Phase A-C explicitly scoped to Layer 2. Layer 1 in-flight under PR #2798 not in this brief's scope.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(briefs): S6 brief §4 PR-body framing + §6 reference list harmonized with §1 canvas-vs-PR-#2766-harness split — cursor APPROVE 10477 exploratory note

§4 PR body framing now distinguishes three authority types: canvas (BinaryShim consumption + selection algorithm + path-regex removal) + upstream lens (PR #2713 / design-affected-set-lens.md) + harness/ratchet (PR #2766). §6 reference list expanded similarly. Removes the residual 'PR #2766 substrate authority' phrasing that conflicted with §1's three-source split.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #62 file-ingestion substrate-shape canvas

Surfaces the substrate-shape question for §1.8 row #62
substrate_gap_file_ingestion_closed before brief authoring.

bright-otter-731 was auto-spawned on this gate without an
authored brief and surfaced a clean audit (no include_str! at
HEAD in dsl/; PR #2819 read_utf8_file candidate shape held in
draft). §4.3 line 505 frames closure as workflow_substrate
extension to file-attachment (Candidate B), but PR #2819 implements
compile-time UTF-8 read (Candidate A) — parallel-authority risk.

This canvas frames the candidate shapes (A/B/C/d) for Director-or-
Substrate-Mgr-tier ratification before brief authoring proceeds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #62 FileAttachment carrier-internals sub-canvas

Director ratified Candidate (b) on PR #2820 — workflow-substrate
FileAttachment carrier extending #53 — per PM msg_52c4a707. This
sub-canvas surfaces carrier internals (type def + fields + workflow
coupling + Practice 4 + lazy-vs-eager) for next-tier ratification
per recursive feedback_substrate_shape_belongs_in_mgr_canvas.

Three candidate shapes (B-1 minimal / B-2 path-keyed / B-3 anchor+entry
pair) anchored against gate #55 WorkflowObservationAnchor precedent at
src/v3/std/timing_lens.dag:98 (already CONSUMER_LANDED).

Director anti-patterns encoded for worker review enforcement.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #62 FileAttachment worker brief (Refined-B-1 ratified)

Director ratified Refined-B-1 carrier shape with full §8 Q1-Q6
dispositions + 7 anti-patterns per PM msg_bc8c23f6 (relaying Director
msg_61e302c6). Worker brief authored with:

- Exact 5-field carrier (subject_node + content_digest + producer_id +
  workflow_run_id + attached_at_ns) — strict 5-of-7-subset of #55
  WorkflowObservationAnchor
- Q1-Q6 dispositions encoded verbatim for reviewer enforcement
- 7 anti-patterns receipt-of-compliance requirement
- Phase A (carrier) / Phase B (ratchet test) / Phase C (existence-proof
  use case) / Phase D (ledger update) staging
- 5 STOP conditions including consumer-evidence-blob-store gap
- Workflow blob-store substrate flagged as Wave-2 sub-canvas-2 trigger
  (forward-looking, NOT blocking this brief)

Brief is DISPATCH-READY. PR #2819 stays held as Candidate A drift
(anti-pattern #1).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 SymbolicCost Tier 1 carrier-extension canvas

Director ratified Path A Tier 1 on 2026-05-13 (PM msg_4fd650b7
relaying msg_ad5e934d) with 5 sub-canvas questions Q1-Q5 routed
to Mgr. This canvas surfaces dispositions on each for next-tier
ratification before worker brief authoring.

Mgr recommendations:
- Q1 Rational ordering: c (layered OrderedField + lazy migration)
- Q2 Linear-vs-Polynomial: Y (collapse to PolynomialCost(degree=1)
  per §P5; net 10 variants not 11)
- Q3 algebra rules: tabulated 10 new interaction rules; PolyLog
  reserved for log^k only (n log n stays composite); Factorial²
  = UnknownCost (Tier-2 R4-deferral receipt)
- Q4 STOP SIGNAL: re-resets at 11th variant (or 12th if Tier-2)
- Q5 carrier-shape canvas: this document
- §8 Tier-2 mechanism: defer to R4 (InverseAckermann doesn't
  fit IteratedAlgebra; no uniform compositional surface)

5 Director anti-patterns encoded + 2 Mgr-derived for worker review.

Gates on §1.8 row #105 PR #2824 landing + Director ratification of
§12 questions before worker dispatch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 SymbolicCost Tier 1 worker brief (canvas ratified)

Director ratified canvas PR #2828 Q1-Q5 + §8 Tier-2 disposition per
PM msg_a055c38b relaying msg_d86a5987. Worker brief encodes ratified
shape as single coordinated PR with 7 sub-phases:

- Phase A: OrderedField<T> witness landing + Rational re-declaration
- Phase B: STOP SIGNAL rewrite (cap at 11)
- Phase C: SymbolicCost carrier reshape (Q2-Y collapse Linear)
- Phase D: algebra interaction rules (13-rule table; §5.1 composite
  for poly·log; §5.2 (n!)² → UnknownCost verbatim)
- Phase E: bootstrap ratchet test
- Phase F: cost-lens consumer migration (LinearCost → PolyCost(d=1))
- Phase G: §1.8 row #105 ledger update

7 anti-patterns + 5 reviewer ratchets + 6 STOP conditions encoded.
DISPATCH GATES on PR #2824 (row anchor) AND PR #2828 (canvas) both
merged; brief is ready when cascade clears.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 — encode invariants in type carriers (codex BLOCKING fix)

codex BLOCKING #10726 on PR #2828 (Practice 2 + Practice 6 violations):
1. Worker brief moved invariants (degree>0, exponent≥1, base≥2) into
   fold normalizer instead of carrier — admits illegal states
2. Canvas §187 said 'Rational ≥ 0' while worker said 'degree > 0' —
   split authority on the invariant

Both findings valid. Fix:

Canvas §6 STOP-SIGNAL text:
- Replaced 'PolynomialCost(Rational ≥ 0)' with 'PolynomialCost { degree:
  PositiveRational }' + adds PolyLogCost { exponent: PositiveInt } +
  ExponentialCost { base: IntAtLeastTwo } verbatim
- Adds new "Type-level refinement carriers" subsection citing
  DegreeAtLeastTwo precedent (algebra.dag:171-173)

Worker brief §5:
- New §5.0 introduces PositiveRational, PositiveInt, IntAtLeastTwo as
  Peano-style inductive carriers (strict-mirror of DegreeAtLeastTwo)
- §5.1 SymbolicCost now uses these refinement types for fields:
  PolynomialCost.degree: PositiveRational
  PolyLogCost.exponent: PositiveInt
  ExponentialCost.base: IntAtLeastTwo
- Removed the "refinements live in fold normalizer" paragraph

Illegal states (degree≤0, exponent≤0, base≤1) now structurally
unrepresentable per Practice 2 + Practice 6.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 — fix variant arithmetic 10 → 9 per operator BLOCKING

Operator BLOCKING on PR #2828 canvas:135 caught real arithmetic error:
Q2-Y removes LinearCost (-1) and adds 3 NEW variants (PolyLogCost +
ExponentialCost + FactorialCost), so net is 7 - 1 + 3 = 9, not 10.
PolynomialCost is PROMOTED (degree type changed Rational), NOT added as
a new variant — that was the counting mistake.

Confirmed variant set per canvas §6 + worker §5.1:
1. ConstantCost
2. PolynomialCost { degree: PositiveRational }
3. PolyLogCost { exponent: PositiveInt }
4. LogCost
5. ProductCost
6. SumCost
7. ExponentialCost { base: IntAtLeastTwo }
8. FactorialCost
9. UnknownCost

Total: 9 variants. Confirmed.

All references updated:
- "10 variants" → "9 variants"
- "11th variant" → "10th variant" (STOP-SIGNAL trigger threshold)
- "Net 7 → 10/11" → "Net 7 → 9"
- "variant cap at 11" → "variant cap at 10"
- "10 ratified + 1 trigger" → "9 ratified + 1 trigger"
- "STOP-SIGNAL re-reset to 11" → "STOP-SIGNAL re-reset to 10"

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 — Q1 premise correction per operator BLOCKING canvas:48

Operator BLOCKING #2 on PR #2828 canvas:48 caught real authority error:
Field<T> at dsl/std/algebra.dag:294 ALREADY has compare: fn(T,T)->Ordering.
The canvas claim "Rational supports add+mul+inverse, NOT order" was wrong —
Field carries the foundational order primitive. Introducing OrderedField<T>
would create parallel order authority.

This invalidates the original Q1-c ratification premise (PM msg_a055c38b).
Q1 disposition needs RE-RATIFICATION:

Revised candidate set (canvas §3 REVISED):
- Q1-α (Mgr-rec): use existing Field.compare via Rational; lt/le/gt/ge as
  cost-lens-local free functions. Zero new substrate.
- Q1-β: extend Field<T> in-place with 6 derived predicate fields. Larger
  blast radius; mirrors OrderedRing predicate set on Field directly.
- Q1-γ: OrderedField as Field-superset via type-level inheritance. Requires
  DSL grammar prerequisite (worker grep-verifies).

Worker brief Phase A regenerated under Q1-α assumption (smallest scope):
- NO OrderedField type introduction
- NO Rational re-declaration
- Cost-lens-local rational_lt/le/gt/ge/max helpers derived from
  rational.compare (existing Field operation)

Anti-pattern #6 reworded: "Parallel order authority — adding any new
OrderedField or equivalent witness when Field.compare already exists at
algebra.dag:294 (Q1 premise-corrected anti-pattern)".

Canvas + worker brief both note re-ratification required; if Director
prefers Q1-β or Q1-γ, Phase A regenerates.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 — fix unsound multiplicative absorption rules per operator BLOCKING worker:140

Operator BLOCKING caught real asymptotic-analysis error: multiplicative
absorption rules like `PolyCost(d) · ExpCost(c, v) = ExpCost(c, v)` are
UNSOUND. n^d · c^n / c^n = n^d is unbounded as n → ∞, so n^d · c^n is
NOT O(c^n) strictly. Same problem with FactorialCost · PolyCost and
FactorialCost · ExpCost.

Fix: multiplicative absorption rules removed; replaced with composite
ProductCost retention:
- PolyCost(d) · ExpCost(c, v) → ProductCost([PolyCost(d), ExpCost(c, v)])
- FactorialCost(v) · PolyCost(d) → ProductCost([FactorialCost, PolyCost(d)])
- FactorialCost(v) · ExpCost(c, v) → ProductCost([FactorialCost, ExpCost])

ADDITIVE dominance rules unchanged (those ARE sound — n^d + c^n = O(c^n)
because dominant term wins; only multiplicative absorption is unsound).

Both canvas §5 + worker brief §6 rule tables updated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 — Q1-α Director-RATIFIED; add 6th anti-pattern

Director re-ratified Q1 to Q1-α per msg_676ad4e7 (supersedes
msg_d86a5987 Q1-c), retraction explicit. Updates:

Canvas + worker brief §3:
- "PENDING re-ratification" framing removed
- Q1-c rejection cites INVARIANTS P1 + row #24 + Q-MachineConstraint-Carrier
- Q1-β + Q1-γ rejections documented (Director rationale verbatim)

Anti-patterns:
- NEW Director-ratified #6: "Introducing parallel ordered-algebraic-structure
  carriers (Ordered<X>) when underlying carrier already provides compare:
  fn(T,T) -> Ordering"
- NEW Mgr-derived #7: "Multiplicative absorption rules where one variant
  absorbs another asymptotically" (operator BLOCKING worker:140 retained as
  permanent anti-pattern receipt)

Canvas: 6 Director + 2 Mgr-derived = 8 total
Worker brief: 8 anti-patterns total (matches canvas)
PR body framing template + reviewer ratchet count updated 7 → 8

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 — refinement types for PolyLogExponent + ExponentialBase per operator BLOCKING PR #2824:333

Operator BLOCKING #4 on PR #2824 (relayed via PM msg_92bc8538):
- PolyLogCost { exponent: Int } admits exponent=0 (ConstantCost dup),
  exponent=1 (LogCost dup), negative; cannot represent log^7.5 (AKS
  Tier-1 case)
- ExponentialCost { base: Int } admits base=0/1 (degenerate/ConstantCost)
- Same Practice 2/6 illegal-states-unrepresentable class as prior codex
  BLOCKING (commit 3d21cb7)

Fix:
- NEW refinement carrier ExponentialBase (Int ≥ 2; renames IntAtLeastTwo
  to PM-ledger naming per row #105 commit 8049ccd)
- NEW refinement carrier PolyLogExponent (Rational > 1; admits 7.5/AKS)
- PolyLogCost.exponent: PositiveInt → PolyLogExponent
- ExponentialCost.base: IntAtLeastTwo → ExponentialBase
- PositiveRational unchanged (PolynomialCost.degree already correctly
  bounded > 0 by this carrier)

7th Director-pending anti-pattern added: "Tier-1 variant constructed
with raw Int/Rational bypassing refinement type" (matches PM's row #105
ledger 7th anti-pattern per PR #2824:8049ccde4).

Updated counts:
- Canvas §10: 6→7 Director + 2 Mgr-derived
- Worker brief §11: 8→9 anti-patterns total

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 worker brief — pre-wire P5 receipt requirement per claude APPROVE 10773

claude review 10773 exploratory observation (non-blocking): when worker
authors symbolic_cost_tier1_carrier_test.rs, INVARIANTS P5 requires
explicit single checkable receipt (deletion / SG-0 census shrink /
named-lane deferral) in PR body. Pre-wire so worker doesn't re-derive.

Added §13 verification bullet: canonical receipt is Phase F cost-lens
consumer migration (deletes LinearCost variant + collapses fallback
dispatch paths) — that net hand-Rust deletion is the P5 receipt for the
new test file.

Also corrected refinement carrier name list (was: PositiveRational/
PositiveInt/IntAtLeastTwo; now: PositiveRational/PositiveInt/
ExponentialBase/PolyLogExponent matching the post-d93e2eaffe naming).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 worker brief — address codex BLOCKING 014544f findings 2/3/4

codex review 014544f surfaced 4 BLOCKING findings (sha pre-d93e2eaffe).
Findings 1 + partial-2 covered by intervening d93e2ea (refinement
types). Residual findings 2/3/4 addressed in this commit:

Finding 2 — refinement-mixed-with-product on PolyLogExponent:
- Previous shape was `{ numerator, denominator }` with textual "numerator
  > denominator" invariant — exact refinement-mixed-with-product pattern
  codex forbids
- New inductive shape: PolyLogExponentSuccessor | PolyLogExponentFractional
  with FractionalPart in (0, 1] structurally; whole ≥ 1 + fraction > 0
  yields value > 1 by carrier shape
- HARD STOP added: do NOT author as record-with-comment-invariant
- Worker grep-verifies DSL refinement support; if not available, ratify
  inductive shape pre-authoring

Finding 3 — cross-variable dominance gap:
- §6 algebra rules table prefaced with explicit "Variable-scoping
  precondition" — rules assume same-variable operands; different-variable
  operations preserve as SumCost/ProductCost composite, not folded by
  dominance
- Cross-variable dominance explicitly named undefined within Tier-1
  substrate (Tier-2 / polynomial-multivariate scope post-R3)

Finding 4 — P5 receipt category specificity:
- §13 verification bullet now requires "exactly ONE P5 receipt category
  with concrete path + LOC count" (not narrative)
- 3 categories enumerated: (a) hand-Rust deletion + LOC; (b) SG-0 census
  shrink + delta; (c) T-PB-B ROADMAP row + dissolution-trigger
- Phase F LinearCost removal noted as LIKELY (a) source but worker MUST
  measure actual numbers, not assume narrative-equivalence

Finding 1 (refinement-over-existing-Rational vs fresh records) surfaces a
refinement-mechanism canvas question; routed to PM/Director (no fix in
this commit; the residual product-shape for PositiveRational is preserved
pending Director disposition on substrate-refinement-mechanism).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 — fix FactorialCost dominance over-reach per operator BLOCKING worker:158

Operator BLOCKING: 'FactorialCost(v) + anything = FactorialCost(v)' rule
would erase UnknownCost (conservative-top) and incomparable SizeVariable
dimensions, violating P2/P3.

Fix: expand FactorialCost addition rule from single 'anything' catch-all
to per-variant explicit enumeration:
- FactorialCost + same-variable cost (Factorial/Exp/Poly/PolyLog/Log/
  Constant) → FactorialCost (absorption valid)
- FactorialCost + UnknownCost → SumCost composite (UnknownCost is
  conservative-top per algebra.dag; NEVER absorbed)
- FactorialCost + FactorialCost different-variable → SumCost composite
  (cross-variable undefined per §6 precondition)

Same-variable precondition from prior commit (c787f75 finding #3 fix)
now explicitly applied per-rule for the FactorialCost row.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 — refinement mechanism IS ratified; reshape carriers per PM msg_a52ed981

PM-grep correction (msg_a52ed981): substrate refinement-mechanism `type
X = Y where predicate` is ALREADY RATIFIED at HEAD per gunbc#828
issuecomment-4390333451 Path 3 + Director Option 2. Mgr missed grep-
verifying this when authoring path (i)/(ii) framing — same discipline
class as feedback_grep_substrate_before_naming_ratification.

Precedent: dsl/std/integer.dag:181 (`PositiveInt = Nat where gt_zero`).
KNOWN_PREDICATES registry at lower.rs:798-862:
  range / non_empty / brand / gt_zero / unicode_scalar

Reshape (worker brief §5.0 + canvas §6):
- PositiveRational = Rational where gt_zero (REQUIRES gt_zero
  allowed_carriers extension to include Rational — Phase A atomic)
- ExponentialBase = Int where range(min: 2) (IMMEDIATELY available;
  range predicate has Int in allowed_carriers)
- PolyLogExponent = Rational where gt_one (REQUIRES NEW gt_one
  predicate; allowed_carriers Rational + Int; mirrors gt_zero shape;
  Phase A atomic)
- PositiveInt reuses existing dsl/std/integer.dag:181 declaration

ZERO new authority introduced. P1 single-authority + Practice 4 + Q-
MachineConstraint-Carrier "no dual representations" all satisfied via
refinement over canonical Rational/Int carriers.

NEW Mgr-derived anti-pattern #8 added: parallel rational-number
carriers when refinement-mechanism is available (PM-grep-corrected per
msg_a52ed981 + codex 014544f finding #1).

Phase A KNOWN_PREDICATES extensions:
1. gt_zero allowed_carriers + Rational
2. New gt_one predicate (Rational + Int; Bare arg)
Both atomic with carrier landing per §P5.

HARD STOP added: do NOT author fresh records/inductive sums when
refinement is available.

Anti-pattern counts: canvas §10 → 7 Director + 3 Mgr-derived = 10;
worker brief §11 → 10 anti-patterns total.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 canvas/worker — cursor 10801 stale-cite cleanup

Cursor review 10801 (PR #2828) — 6 stale-ratification cites cleaned to
the Q1-α / 9-variant ratified state:

Canvas (PR #2828):
- L13-14 front matter: Field<T>/Rational "no order" → carries compare
  (Director ratified Q1-α via existing Field.compare; line ref :287→:294)
- §6 L216 variant count: "10 post-Q2-Y" → "9 post-Q2-Y" (matches §5 L153
  and Q2-Y disposition; PolynomialCost.degree promotion is not a new
  variant)
- §6 algebra bullets: Q1-c OrderedField.add/compare → Field.add/compare
  on Rational + rational_max lens-local helper (Q1-α)
- §12 Q1 Mgr-rec: stale "c — OrderedField" replaced with full ratified
  Q1-α/Q2-Y/Q3/Q4/Q5/§8 disposition block as audit trail
- §13 reference list: Field<T> "no order" + Q1-c cite → Q1-α via compare

Worker brief:
- §7 phase E receipt: "10 variant count" / "All 10 variant names" → 9
- §10 STOP #3: "Q1-c re-declaration target" → "Q1-α refinement target"
- §14 out-of-scope: "Q1-c lazy migration" → Q1-α (Field unchanged)
- §15 PR body template: "Companion substrate (Q1-c)" → (Q1-α)
- §11 anti-patterns: duplicate #8 numbering fixed → renumber to 1-10
- §16 reference: feedback_strict_mirror Q1-c → Q1-α discipline

INVARIANTS P2 single-authority restored across both briefs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 canvas — fix §10 Mgr-derived duplicate #8 numbering

Per claude/claude-opus-4-7 review 10819 cosmetic note: Mgr-derived
anti-patterns had 7,8,8 → renumber to 8,9,10 (continuing from
Director-enumerated 1-7). Matches the §11 worker brief enumeration.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 worker — fix Phase E sample-test multiplicative absorption

Codex REQUEST_CHANGES review 10837: worker brief §7 line 225 sample test
asserted ExpCost(2,n) · PolyCost(d) collapses to ExpCost(2,n), which
contradicts §6 algebra + anti-pattern #9 (multiplicative cross-class
absorption is unsound; only ProductCost composite is correct).

Fix-forward: corrected sample to assert ProductCost composite under
multiplication; added the additive-sound sibling test (ExpCost + PolyCost
DOES absorb to ExpCost) so both directions of the SUM-sound vs
PRODUCT-unsound asymmetry are receipt-tested.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 canvas — codex 10852 two contradictions in dispatch artifact

Codex REQUEST_CHANGES review 10852 — both findings load-bearing:

1. §5 L172 FactorialCost rule: "FactorialCost(v) + anything = FactorialCost(v)"
   contradicted worker brief's per-variant rules (preserve composites for
   UnknownCost + cross-variable FactorialCost(w)). Expanded canvas table
   to match worker:
   - Same-variable Tier-1-below: absorb to FactorialCost(v)
   - Cross-variable FactorialCost(w): SumCost composite
   - + UnknownCost: SumCost composite (conservative-top, never absorbed)
   - + SumCost/ProductCost composites: distribute and re-fold per §6
   Mirrors operator BLOCKING #5 fix to worker brief (commit adb8417).

2. §5.1 L183 n log n shape: "ProductCost([LinearCost(n), LogCost(n)])"
   reintroduced the LinearCost variant dissolved by ratified Q2-Y.
   Corrected to "ProductCost([PolynomialCost { var: n, degree: 1 },
   LogCost(n)])" — post-Q2-Y collapse via PolynomialCost(degree=1).

INVARIANTS P2 single-authority restored across canvas + worker for both
fold rules. Anti-pattern §11 #10 (LinearCost-consumer paths preserved)
no longer self-violated by the canvas guidance.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 worker — reconcile authority chain (codex 48328e4)

Codex BLOCKING review sha 48328e4: worker brief frontmatter / authority
chain / §9 ledger update / §15 PR body template cited the pre-Q1-α
ratification msg_d86a5987 alone, without msg_676ad4e7 (Q1-α supersession)
reconciliation. The substantive carrier + algebra fixes were clean but
the authority chain leaked the superseded shape.

Fix-forward: every load-bearing authority cite (frontmatter, §0 status,
§2 inputs ratification line, §4 cite-in-comment-block, §9 row-#105 ledger
update text, §13 PR body cite list, §15 PR template, §16 reference) now
cites the **composite ratification**:

  PM msg_a055c38b relaying Director msg_d86a5987 (Q2-Q5 + §8 base)
  RECONCILED BY Director msg_676ad4e7 (Q1-α supersedes prior Q1-c)

Worker dispatches on this composite — not the pre-Q1-α msg_d86a5987 alone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 — Director scope-extension msg_2c1bfb0e (signed Rational)

Director RATIFIED scope-extension on PR #2828 (msg_2c1bfb0e via PM
msg_e5ed6db8 2026-05-13) per operator directive: PolynomialCost.degree
admits signed Rational (arbitrary roots + inverse/decay coverage), no
where-refinement. Q6 dominance ordering + Q7 SymbolicCost preserves full
expression both ratified; new anti-pattern #11 forbidding parallel
InverseCost/ReciprocalCost variants.

Canvas (PR #2828) updates:
- §1 PROMOTE: PolynomialCost.degree = signed Rational (no refinement);
  subsumes negative degrees for asymptotic-decay
- §4 Q2-Y candidate: drop "where degree > 0"; plain Rational
- §6 refinement-carriers: PositiveRational DROPPED (struck-through with
  Director cite); ExponentialBase + PolyLogExponent unchanged
- NEW §6.1 Q6 asymptotic-dominance ordering verbatim Director conjecture
  (reverse-sign-convention via Field.compare; Q1-α authority)
- NEW §6.2 Q7 SymbolicCost preserves full expression; Big-O is derived
  operation (dominant_term / asymptotic_class)
- §10 anti-pattern #11: no parallel InverseCost/ReciprocalCost when
  carrier-extension dissolves question
- §12 ratifications Q6 + Q7 added; Practice 4 GREEN per Director
  pre-emption

Worker brief updates:
- §1 PROMOTE: signed Rational, no refinement
- §5.0 PositiveRational refinement DROPPED with struck-through comment
- §5.1 PolynomialCost.degree: Rational (Q6 signed)
- NEW §6.0 Q7 canonical-form preservation: SymbolicCost preserves all
  terms; canonicalize ≠ dominant_term; mixed-sign canonicalization test
- NEW §6.1 Q6 dominance rule encoded via Field.compare reverse-sign
- §6.2 same-variable algebra fold rules header
- §11 anti-pattern #11 mirrored
- §16 Director msg_2c1bfb0e reference added

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 — purge stale PositiveRational refs (cursor 10886)

Cursor APPROVE_WITH_COMMENTS review 10886: post-Q6 scope-extension
(243fd63), several PositiveRational / degree≤0 refinement references
remained in canvas STOP-SIGNAL prose + worker brief verbatim STOP block,
"zero new authority" line, hard-stop directive, STOP condition #4,
anti-pattern #7, and §13 verification axis listing. Worker could follow
the verbatim STOP/anti-pattern text and encode wrong carrier shape
relative to ratified Q6/Q2-Y signed-Rational.

Fix-forward:
- Canvas §6 STOP-SIGNAL prose: PolynomialCost { degree: PositiveRational } → { degree: Rational } (signed per Q6)
- Canvas §10 anti-pattern #7: drop degree≤0/PositiveRational requirement on PolynomialCost; explicit exclusion citing Q6
- Worker §4 verbatim STOP block: same PolynomialCost.degree text fix
- Worker §5.0 "ZERO new authority": drop PositiveRational from refinement list; note PolynomialCost.degree plain signed
- Worker §5.0 hard-stop directive: drop PositiveRational; add Q6 carve-out note
- Worker §10 STOP #4 variant collision: drop PositiveRational from de-dup list; add anti-pattern-#7-fires note
- Worker §11 anti-pattern #7: degree≤0 dropped; explicit PolynomialCost.degree exclusion per Q6
- Worker §13 verification axis: PositiveRational removed from refinement-carriers test list

INVARIANTS P1/P2 single-authority restored across both briefs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 — STOP-SIGNAL line range :60-72 → :69-72

Cursor REQUEST_CHANGES 10904: brief cited STOP-SIGNAL as :60-72 across
7 surfaces but the live file has STOP at :69-72 and Pattern 3/4
dissolution receipt at :49-67. A literal Phase B "replace :60-72" would
delete part of the dissolution receipt — INVARIANTS P1 (dispatch prose
must ground in identifiable file facts) + P2 (single edit locus).

Fix-forward:
- Canvas L10 / L46 / L325 STOP-cite: :60-72 → :69-72
- Worker L42 / L90 (Phase B replace) / L261 / L350 / L373: :60-72 → :69-72
- Worker §4 Phase B: explicit DO-NOT-TOUCH callout on :49-67 dissolution
  receipt; replacement is surgical 4-line STOP block only

Brief is now internally consistent with canvas:204 ("Current
src/v3/std/algebra.dag:69-72") which was already correct.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 worker — drop stale gt_zero extension from Phase A list

Cursor APPROVE_WITH_COMMENTS 10920: §5.0 KNOWN_PREDICATES extension list
still required extending gt_zero's allowed_carriers to Rational, but
PositiveRational was dropped in the Q6 scope-extension (243fd63) —
no in-scope refinement uses gt_zero on Rational anymore. Conflicting
dispatch vs the comment block above.

Fix-forward: Phase A list now has only the gt_one addition (genuinely
required for PolyLogExponent = Rational where gt_one). Explicit
parenthetical: gt_zero extension NOT required; range allowed_carriers
already includes Int for ExponentialBase. Only gt_one is new.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 — Q6 zero-degree collision + Q7 worker semantics + AP count

Codex BLOCKING review 4bd0cb5 — 2 BLOCKING + 1 non-blocking:

1. Q6 carrier admits degree=0 colliding with ConstantCost (n^0 ≡ 1):
   Fix-forward: keep ratified plain signed Rational carrier; add explicit
   canonicalize-fold rule canvas §6.1 + worker §6 algebra:
   `canonicalize(PolyCost(_, 0)) ⇒ ConstantCost(1)`. Same dissolution
   discipline class as Q2-Y LinearCost ≡ PolyCost(d=1) collapse. Single
   authority for "value=1 constant" via ConstantCost, not parallel via
   PolyCost(_, 0).

2. Q7 output-semantics drift between canvas + worker §14:
   Fix-forward: worker §14 reframed — symbolic_cost_of returns EXACT
   canonical SymbolicCost (Q7 contract change, not backwards-compatible
   reduction). Big-O is derived via dominant_term projection. Legacy
   single-term consumers MUST wrap with dominant_term; canonical-form
   change is expected and ratified.

3. Anti-pattern off-by-one (non-blocking): worker §11 enumerated 11
   items but header + §12 + §13 + §15 PR template said 10. Fix-forward:
   updated all 4 cite-list surfaces to 11 (7 Director-enumerated + 4
   Mgr-derived).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 — Q6 Option B Practice-2 carrier refinement (msg_b80bcaa8)

Director RATIFIED Option B on Q6 zero-degree Practice-2 tension via
msg_b80bcaa8 (relayed by PM msg_9d248cbd 2026-05-13). Practice-2
carrier-level `where nonzero` refinement preferred over Practice-4
canonicalize-fold dissolution; sign-admission intent preserved.

Director-distilled discipline rule (NEW, load-bearing):
> Same-variant redundancy → Practice-4 collapse (Q2-Y LinearCost ≡
> PolyCost(d=1)). Cross-variant redundancy → Practice-2 carrier
> refinement (PolyCost(d=0) ≡ ConstantCost(1)). Type-level state-space
> tightening beats API-level normalization when redundant state crosses
> variant boundaries.

Canvas + worker fix-forward:
- §1 PROMOTE / §3 Q2-Y candidate / §6 STOP-SIGNAL / §6.1 dissolution
  text: `Rational` → `Rational where nonzero` (sign-admission via msg_2c1bfb0e
  preserved; only degree=0 excluded)
- Canvas §6.1: reframed from canonicalize-fold to carrier-level
  refinement; Practice-2 vs Practice-4 disambiguation rule encoded
- Worker §5 Phase A KNOWN_PREDICATES list: add `nonzero` predicate
  (allowed_carriers: Rational; arg_shape: Bare); now 2 new predicates
  (gt_one + nonzero), not 1
- Worker §5 "ZERO new authority" line: cite cross-variant vs
  same-variant rule
- Worker §6 algebra table: canonicalize-fold rule REMOVED (type prevents
  construction); multiplicative cancellation rule split into d1+d2≠0
  and d1+d2=0 cases (=0 maps to ConstantCost(1) directly without
  PolyCost(d=0) intermediate which is type-rejected)
- Worker §7 bootstrap ratchet: type-rejection negative test added
  (PolyCost(_, Rational(0)) must be structurally rejected; ±n admits)
- §11 anti-pattern #12 (new, Director-added): forbid canonicalize-fold
  for cross-variant redundancy when carrier refinement available
- AP cite-list counts: 11 → 12 across §11 header / §12 / §13 / §15

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 canvas — reconcile Q2-Y refinement + variant arithmetic

Cursor APPROVE_WITH_COMMENTS 10980 — 2 internal-consistency findings:

1. Q2-Y parenthetical "no where refinement" contradicted the snippet
   directly above showing `where nonzero` (post msg_b80bcaa8 Option B).
   Reconciled: explicit "no positivity / gt_zero refinement" framing
   per Director msg_2c1bfb0e sign-admission intent, AND explicit
   acknowledgment that `where nonzero` IS present per msg_b80bcaa8
   Practice-2 carrier-level Option B (sign-orthogonal, excludes only 0).

2. Q2-Y Pros bullet "11 → 10 net" contradicted §4 closing "**9** net
   under Q2-Y". Reconciled: corrected to "7 → 9 net" matching §1
   ratified scope (+3 new variants -1 collapsed = +3 net over existing
   7) and §4 closing reconciliation pointer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 — codex 77088ff non-blocking wording hygiene

Codex no-blocking + 2 non-blocking improvements (77088ff review):

- worker L156: "no such refinement" → "no positivity refinement, but
  DOES carry where nonzero" (clarifies sign-admission vs zero-exclusion
  distinction for downstream readers).
- canvas L285: §10 anti-pattern header "7 Director + 3 Mgr-derived"
  → "7 Director + 5 Mgr-derived; 12 total" (matches actual 12-item
  list per worker §11 cite-list).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* WIP: R3 Substrate Mgr — lane through R3 close

* docs(r3): gate #105 — named NonZeroRational alias (codex worker:167)

Codex BLOCKING worker:167: inline `Rational where nonzero` in struct
field types is unsupported by HEAD parser/lowerer — `where` refinements
attach only to type aliases / parameters (precedent
`type PositiveInt = Nat where gt_zero` at dsl/std/integer.dag:181).
Inline use would require unsupported substrate syntax instead of
making illegal degree=0 unrepresentable through a proper named
refinement carrier.

Fix-forward: introduce `type NonZeroRational = Rational where nonzero`
at the type-alias layer (alongside existing
`PolyLogExponent = Rational where gt_one` +
`ExponentialBase = Int where range(min: 2)`). PolynomialCost.degree
field type references the named alias: `degree: NonZeroRational`.

Updates across both briefs:
- All `degree: Rational where nonzero` → `degree: NonZeroRational`
  (5 canvas occurrences + 10 worker occurrences)
- Worker §5.0 dag block: NonZeroRational alias declaration added with
  rationale comment citing codex worker:167 + HEAD parser constraint
- Canvas §6 refinement-carriers list: NonZeroRational row added with
  named-alias note
- Worker §5.0 HARD STOP directive: NonZeroRational added to the
  hard-stop list (named alias, not fresh record); HEAD parser
  constraint cited
- Worker §10 STOP #4 variant-collision list: NonZeroRational added
- Worker §5.0 P1/P2 narrative: clarified "DOES carry NonZeroRational
  named-alias" framing
- Worker §7 bootstrap ratchet test: type-rejection test asserts both
  the type-alias declaration AND the degree=0 rejection at carrier
  level
- Worker §13 verification axis: NonZeroRational added to refinement-
  carriers test list

INVARIANTS P2 + Practice 2 carrier-level illegal-states-unrepresentable
satisfied via named alias (P5 / parser-supported substrate syntax).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(r3): gate #105 canvas — fix §6 'no refinement' stale text (codex canvas:218)

Canvas §6 closing paragraph still said "PolynomialCost.degree intentionally
has no refinement" — pre-msg_b80bcaa8 framing that contradicts the
NonZeroRational alias declared 3 lines above + ratified by msg_b80bcaa8.

Fix-forward: reframe as "no positivity refinement, but DOES carry
NonZeroRational named alias for zero-exclusion". Sign-admission
preserved (msg_2c1bfb0e); zero-exclusion enforced (msg_b80bcaa8).
Also added explicit reference to degree=0 alongside exponent≤1 / base≤1
in the structurally-unrepresentable set.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* WIP: R3 Substrate Mgr — lane through R3 close

* docs(r3): gate #105 canvas — STOP-SIGNAL Tier-2 cite msg_ad5e934d → msg_d86a5987 (cursor 11087)

Cursor APPROVE_WITH_COMMENTS 11087: canvas §6 STOP-SIGNAL cited
msg_ad5e934d for Tier-2 R4-deferral, but the worker brief §4 verbatim
STOP block cited msg_d86a5987 for the same sentence. msg_ad5e934d was
the original Path A Tier-1 ratification; the §8 Tier-2-deferral
disposition was ratified in msg_d86a5987 (per composite-ratification
text already used elsewhere in worker §0/§2/§9/§13/§15). Canvas
STOP-SIGNAL aligned to msg_d86a5987 for single-authority trace.

INVARIANTS P2 single authoritative trace restored.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <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.

1 participant