Repository navigation
v27 B3: a publishing workflow with no pull-request trigger still counts as CI when it runs a check before it publishes - #620
Conversation
…at checks before it publishes is counted; one that does not stays excluded; v17 pinned Counted under v27 (fail before the fix): the npm test script then npm publish in one job on push to main; the test in a job the publishing job needs, directly or transitively; pytest before a twine upload on a release tag. Still excluded (pass): setup, an unverified build and a gh-pages deploy; a check with continue-on-error, || true or if: false; a check after the publish; a check in a job not needed; a publish that runs if: always(); a test command named in echo text. v17's output for every fixture is pinned from 206074f, before the change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…heck before it publishes is counted by B3; one that publishes without checking stays excluded Operator's ruling of 1 November 2026. Under v27 only, a workflow publishingWorkflowDetail reads as publishing is counted when a check runs before every publish, in the publishing job or in a job it needs, directly or transitively (checksBeforeEveryPublish). A check is a command in the verification vocabulary the publish-only reader already uses (namesVerificationCommand, now shared by both), read from command position (isCheckCommand), in an unconditional step whose shell is not conditional and whose failure stops the job (failureStopsJobAt). continue-on-error, || true, a condition that can be false, a publish after the check, and any always()/cancelled()/failure() in the file do not count. B3's note names a counted workflow in one clause and keeps the F3-b trigger and environment text. v17 and every other rubric are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…en-publish workflows, B2/B3 agreement, glossary and v27 description The npm release workflow in ci-claims-publish-and-lockfile and the b3-test-then-publish-workflow fixture run npm test before npm publish, so under the correction v27 counts them as v17 does; their v27 expectations move to the counted note, and the PyPI pair, which builds and publishes without a check, keeps its exclusion test. The B2/B3 agreement test admits B3's counted sentence after the shared ones; the credited counts still agree. The PR-gate CI count glossary and v27's description say a check before every publish keeps the workflow counted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ted only through a needed test job; pip install pytest, tsc-alias and npm test --if-present are not checks Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e bad property excludes only what carries no evidence of the good one Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review at head 9c00569This is an independent adversarial pass: 39 probe workflows scored through Blocker
Should-fix
Nits
Holds
Merging is the operator's call. I'd hold it for finding 1. |
|
Held for the blocker in comment 6562959964; superseded by goal_cejel_v27_b3_publishing_with_checks_v2_2026-11-01, which starts from this branch. |
A v27 rubric correction to #517, on the operator's ruling of 1 November: under
witan-rubric-v27-prospective-2026-10-19, B3 excludes a publishing workflow with no pull-request trigger only when it publishes without checking. A workflow that runs a check before it publishes is default-branch CI that also publishes, and is counted again. v17 and every other rubric are unchanged.CONSTRAINTS-VERSION: 2026-08-01.5
Hand back
checksBeforeEveryPublishinsrc/witan/repo-signals.tsreads the workflow v27 already reads as publishing. It counts the workflow when every publishing step has a check before it, either earlier in the same job or in a job that jobneeds, directly or transitively (workflowJobsnow reads each job's id andneeds:as a name, flow list or block list). A check is a command in the vocabulary the publish-only reader already refuses on.namesVerificationCommandnow holds that vocabulary, shared by both readers, so no second list exists and no workflow can be both publish-only and checked.isCheckCommandreads the command from command position, soecho npm testandpip install pytestare not checks, andtsc-aliasis nottsc. The check must be in an unconditional step with a non-conditional shell, on a line wherefailureStopsJobAtholds. These do not count:continue-on-error,|| true, anif:that can be false (includingif: false), and--if-present. Anyalways(),cancelled()orfailure()in the file refuses outright. A job calling a reusable workflow must need a checking job. Scope limit: check actions (uses:steps) are not recognised, because no shared action list exists and the card forbids inventing one. Such a workflow stays excluded, as before.|| true, check after publish, check in a job not needed,if: always()publish, echoed test word andif: falseall keep the old note and disclosure byte for byte.<path> is counted as CI verification because a check runs before it publishes; it <F3-b trigger and environment clause>. The sentence comes after any unchanged uncredited note and fits the 1000-character limit, falling back to a shorter form and then to a count.publishesreason. A workflow counted under A is credited by both criteria, which the new test asserts for every fixture. The existing "B2 and B3 never disagree" test now accepts B3's counted sentence, and its credited-count equality still holds on every fixture.Tests (red first)
0c75f58d8committedb3-publishing-with-checks.test.tsred. It covered these cases: npm test then npm publish on push to main; the test in a needed job; the test in a transitively needed job; pytest before a twine upload on a release tag. Nine tests failed under v27. The excluded cases passed.d3f3517fcis the fix.c0c9a76bfupdates existing v27 expectations.cf062bc4badds edge cases: a reusable publish counted only through a needed test job;pip install pytest,tsc-aliasandnpm test --if-presentare not checks.fixtures/b3-publishing-with-checks-v17.jsonpins v17's full per-criterion output for every card fixture. Scores, statuses, notes, disclosures, metric values and finding summaries were scored at206074f1f, before the change, and v17 still matches after it.checkNoRise,lostFindings).v27 expectations that moved, and pins
npm testbeforenpm publish. That is the ruling's case:ci-claims-publish-and-lockfile.test.ts, the npm pair is now counted, gated or not, with the counted note. The PyPI pair, which builds and publishes without a check, keeps its exclusion test.false-assurance-v27.test.tsb3-test-then-publish-workflowis now counted, at v17's depth, with the counted note. I also updated that fixture's purpose string.ci-claims-main-v27.jsonfixture pin moved. Every later: B3 credits an ungated publish workflow as CI; removing the human gate raises the score #517 evasion and control fixture builds and publishes without a check.certificate-presentation.ts, which describes v27, so it no longer says "whatever else it runs". It now says a check before every publish keeps the workflow counted. That glossary is rendered on any certificate showingdefault_branch_ci_depth, v17 included, so this is a text change visible under v17. It changes no score, note or metric. The precedent is earlier v27 glossary edits (3b9d0bdef,c9e30ecfe). If v17 certificate bytes must not move at all, revert that one hunk; nothing else depends on it.Verification
pnpm typecheck: clean.pnpm test(full suite, 172 files): 6107 passed, 2 failed, 2 skipped. Neither failure comes from this change:maeve-lesson-delivery.test.ts: a seed already onmain,PENDING_cejel_name_the_repo_on_external_commits_in_preregistrations_2026-10-23.json, is 8 days old against the 7-day bound. That directory's open retire PRs are maeve: retire 11 delivered holding-dir seed file(s) #613 and maeve: retire 11 delivered holding-dir seed file(s) #615.ingest.test.ts"rejects a non-regular explicit ingest candidate": this also fails when run alone. On this macOS hosttmpdir()sits under a symlinked/var, so the code throws "refusing symlinked ingest directory" before the non-regular check. This branch does not touch the ingest code.Lesson
Staged as
docs/orchestration/maeve-unanchored-lessons/PENDING_cejel_exclude-only-what-carries-no-evidence_2026-10-31.json, validated by the pre-commit hook. In prose: a closure that stopped crediting any release workflow once a step published, "whatever else it runs", removed the false assurance of an unchecked publish. It also removed the real evidence of the checks those workflows run first. When a closure removes credit for one bad property, exclude only what carries no evidence of the good one, and pin both sides with a counted fixture and an excluded fixture.Dunstan handback
No tests entry is declared. This repository is a single root package with no turbo, so a JUnit run matching CI's test job would be the full suite.
Land with a merge commit. Propose-only: do not merge from this session.
🤖 Generated with Claude Code