Skip to content

ci: establish post-merge re-audit procedure for generated-CSS producers #2408

Closed

Description

@schlessera

Out of scope

No automatic hash refresh merely to admit current source, per-file owner-map redesign, weakened producer/installation/command/path drift refusal, relaxed CI proof or new generated-artifact support. Do not replace independently owned positives with arbitrary current producer bytes. No runtime optimization or passing-CI claim follows from this ruling.

Context

After #2388 (fcb7d5c53), generated stylesheet/theme and inclusion self-tests bind their positive fixtures to producer bytes frozen at audited revision 498270fbdc4ef2788fdd3babb259b647d77f6c77 (const owner, tests/frozen-generated-source.ts:7). The production pin table (const auditedProducer, scripts/generated-build-inputs.ts:8-20) must keep those audited digests. The decision record (docs/decisions/ci-utility.md, Scheduling and selection) says "legitimate audit drift requires fresh proof and does not redefine the positive fixture".

Several pinned producers change routinely: .github/workflows/ci.yml, scripts/check-pr.ts, scripts/ci-proof.ts. Once one of them changes on main, generatedCssInputs returns undefined for the whole tree and the browser input closure falls back to ordinary resolution. Proof still runs fresh, which is safe, but the generated-CSS binding stays disabled until someone audits the new bytes. #2398 (#2363) is one such change: a one-line job-name edit in ci.yml. It keeps the audited digest, per the ruling above.

Nothing defines that re-audit step. A pin refresh cannot ride along in the changing PR, because the frozen owner must be a commit in main's history. A squash merge discards the PR's own commits, and CI hard-fails when the owner blob is unavailable.

Maintainer decision

Decision (maintainer, 2026-10-18): Select option 1: after each legitimate change to an audited generated-CSS producer lands on main, restore its qualification through a separate post-merge re-audit PR. Do not batch drift indefinitely, refresh pins automatically without audit, or change to per-file ownership as part of this issue.

The re-audit PR selects an available, delivered main revision as its frozen producer owner, reviews the changed producer behavior and the combined producer set, and updates the matching production digests and independently owned positive fixture provenance together. Record the reviewed owner, changed paths/digests, audit rationale and actual proof identities. Preserve #2373/#2388's frozen-positive/current-drift separation and runtime/negative controls. Unreviewed source drift continues to refuse binding and select fresh proof.

The changing PR must not manufacture its own positive-fixture owner from commits that squash merge will discard. Re-audit is a deliberate follow-up to the delivered main source. A new producer change during review requires renewed audit/proof or leaves that change unqualified; do not claim binding for unreviewed bytes. All normal candidate/head/base and merge-proof rules still apply.

Scope

Document and establish this procedure in docs/decisions/ci-utility.md, then perform one re-audit against delivered current-main producer source using the chosen workflow. This issue owns the durable decision-record update; no further maintainer policy choice is required before that documentation and first re-audit.

Acceptance criteria

  • Record the post-merge trigger, main-history owner requirement, audit/proof responsibilities, update sequence and safe drift fallback in docs/decisions/ci-utility.md. Reconcile its existing frozen-positive ownership language without weakening the rule.
  • Perform one post-merge re-audit against an identified delivered main revision. Review changed producer files and their combined build-before-browser/clean-output/locked-tool/checked-exit/receipt guarantees; record evidence rather than treating a digest recomputation as the audit.
  • Update the complete relevant production pin set and matching positive-fixture provenance together, with owner blobs available offline from main history. Restore binding for the reviewed current producer tree; identify any remaining drift rather than masking it.
  • Preserve real frozen positive controls and independent current-source drift negatives across generated CSS/theme and inclusion tests. Keep locked offline compiler and installed-asset byte/mode controls, and source/path/mode/command/order guards where applicable.
  • Prove a producer-digest bypass fails the named intended negative assertion and corrupt positive ownership fails its intended positive assertion. Restore changes and record both receipts; a module-load error is not an intended failing-first receipt.
  • Record audited owner, relevant source identities/digests and actual candidate/head/base/checkouts in the PR. Follow required local and complete selected hosted proof before merge. Newly changed producer bytes require fresh review/proof and cannot be admitted silently.

Verification

Run bun run test tests/generated-theme-inputs.test.ts tests/generated-build-inputs.test.ts tests/inclusion-inputs.test.ts through the ordinary offline wrapper with the real locked compiler controls and restored mutation receipts, then bun run check:pr --base origin/main and complete selected hosted proof as required by the repository. Existing failed receipts remain failed; this issue decision does not itself qualify a new producer tree.

Contract impact

None; internal CI procedure and audit/fixture ownership. No public CLI/MCP/configuration contract change is selected.

Updated 2026-10-18: maintainer selected a separate post-merge re-audit PR after each producer-changing merge. Scope, acceptance criteria and verification now describe the chosen procedure and first re-audit; no policy question remains. Implementation/documentation/audit proof remain outstanding delivery work.

Activity

  1. added
    type: choreTooling, CI, release plumbing, dependencies.
    area: ciCI workflows, the gates they run, release scripts, packaging.
    priority: p2Wanted, not scheduled. Pulled in when a milestone has room.
    needs: decisionBlocked on a maintainer or designer ruling, not on code.
    on Oct 18, 2026
  2. added
    agent-readyContext and acceptance criteria are complete enough for an agent to take this unattended.
    on Oct 18, 2026
  3. changed the title [-]ci: define how the audited generated-CSS producer set is re-audited after legitimate drift[/-] [+]ci: establish post-merge re-audit procedure for generated-CSS producers[/+] on Oct 18, 2026
  4. removed
    needs: decisionBlocked on a maintainer or designer ruling, not on code.
    on Oct 18, 2026
  5. schlessera commented on Oct 18, 2026

    @schlessera
    OwnerAuthor

    Decision (maintainer, 2026-10-18): Select option 1: a separate post-merge re-audit PR after each legitimate audited-producer change lands on main. Use an available delivered-main revision as frozen owner, audit changed behavior and the combined producer set, then update the matching production digests and independently owned positive-fixture provenance together with actual evidence.

    Preserve frozen-positive/current-drift separation, offline owner availability, locked compiler/installed-asset controls and negative/mutation proof. Unreviewed drift still selects fresh proof. Automatic pin updates without behavioral audit, indefinite batching and a per-file ownership redesign are not selected.

    The body now specifies the trigger/procedure, first re-audit, documentation in docs/decisions/ci-utility.md and verification. This issue itself owns that durable decision-record update. No open maintainer question remains: remove needs: decision, add agent-ready, retain p2. No re-audit or implementation proof is claimed by this decision comment.

  6. self-assigned this
    on Oct 20, 2026
  7. schlessera commented on Oct 20, 2026

    @schlessera
    OwnerAuthor

    Claim reaudit-2408-0a14, branch chore/2408-producer-reaudit, from fetched main 468618cf1. Per the maintainer's sequencing for this session: the docs/decisions/ci-utility.md procedure is written first. The first re-audit runs against delivered main after the in-flight #2279 build-once change merges, because that change is expected to alter audited producers. Until then this branch stays a draft, with no hosted runs. No pins change before the audit.

  8. added this to the 0.44.0 milestone on Oct 20, 2026
  9. schlessera commented on Oct 20, 2026

    @schlessera
    OwnerAuthor

    Delivered by #2460, squash e2deae1f3c4e18affacc0da45d6202b0ca4378fc, verified on fetched main. Its parent is af0547c2d4d197ed3766f2817cf56eb5f0486ab4 and its tree fb91cdcb155b4db057855807648b53dabbea0291 exactly matches the confirmed synthetic checkout ff4ca24ac117cc8b096f8d88119949b79d12faec (parents af0547c2d / 1170e46f9).

    Ready run 39506109358, attempt 1, passed all 16 selected jobs and the aggregate. BRAIN_CANDIDATE_RECEIPT names head 1170e46f9 and base af0547c2d, which equalled live main at merge.

    The procedure is recorded in docs/decisions/ci-utility.md. The audited owner is now af0547c2d, and all 12 audited producer digests match it, including the newly added scripts/build-execution.ts. The generated-CSS binding is restored on main. The audit record, both mutation receipts and the isolated-operation analysis are in the PR body.

    Follow-ups:

  10. removed their assignment
    on Oct 20, 2026
  11. schlessera commented on Oct 21, 2026

    @schlessera
    OwnerAuthor

    Second post-merge re-audit delivered by #2470, squash 8b5b1fdc706fcaf4734b8a811acdc8e53f33d890, verified on fetched main. Its parent is b7f6360a8 (#2467) and its tree 095a7d66297bd33f0e57b0d3558cd963e33b5f44 exactly matches the confirmed checkout 752e6b99c.

    Ready run 39556586285, attempt 1, passed all 16 selected jobs and the aggregate. BRAIN_CANDIDATE_RECEIPT names head f8264c75f and base b7f6360a8, which equalled live main at merge.

    The audited owner is now b7f6360a8. The only reviewed drift was #2467's addition to the scripts/build-repeat-observation.ts diagnostic inventory, and the generated-CSS binding is restored on main. The audit record and both mutation receipts are in the PR body.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent-readyContext and acceptance criteria are complete enough for an agent to take this unattended.area: ciCI workflows, the gates they run, release scripts, packaging.priority: p2Wanted, not scheduled. Pulled in when a milestone has room.type: choreTooling, CI, release plumbing, dependencies.

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions