Skip to content

docs(agents): record how the Actions workflow registry is keyed, and the paginated-listing rule - #6183

Draft
yinlianghui-tw wants to merge 1 commit into
mainfrom
claude/issue-6069-workflow-registry-note
Draft

docs(agents): record how the Actions workflow registry is keyed, and the paginated-listing rule#6183
yinlianghui-tw wants to merge 1 commit into
mainfrom
claude/issue-6069-workflow-registry-note

Conversation

@yinlianghui-tw

Copy link
Copy Markdown
Collaborator

Fixes#6069

GOVERNED SURFACE — this PR must stay draft and must NOT be armed.AGENTS.md is the first item named in AGENTS.md §受管面 (maintainer ruling 2026-08-18), so the hard rule applies: no gh pr ready, no merge queue, no auto-merge. A human merges it, and that merge is the review record. Flagging it here because the criterion is the file list, and this PR's file list is exactly one governed file.

Round 2 of #6069, implementing the PM ruling of option A on both questions: a hazard note, nothing else. ⛔ No gate, no deregistration, no workflow edits. One file, +59 / -0.

What the note states

Placed in §9 Operational Rules, immediately before §受管面.

  1. The registry is keyed by the workflow's FIRST RUN on any ref. The default branch is irrelevant, and the entry then persists. So a workflow file that ran once on any PR branch is registered forever, even if it never reached main and the branch was abandoned.
  2. state: "active" means "not disabled". It is not a claim about main. That is the whole false friend.
  3. The general paginated-listing rule.list_workflows ignores per_page and returns a fixed 30 entries while truthfully reporting total_count in the same JSON body — so compare total_count against the returned array length before believing any absence. Written as a general rule for paginated listings rather than a workflow-specific one, per the ruling on Q2: the failure is generic and this is the cheapest place to stop the class.
  4. The sound way to answer "does X run here?" is git cat-file -e against origin/mainwith a positive control (ci.yml) — one command, no CI, no heuristic. The note says explicitly that the positive control is not optional, because a mistyped path and a real absence produce the same exit code.

It also records why the cross-check gate was rejected, so the next reader does not re-propose it.

⚠️ What the note says it does NOT know

A hazard note that overstates its own coverage is the defect it exists to prevent, so two boundaries are stated in the note itself:

  • The delete-from-default-branch behaviour is UNKNOWN and UNTESTED here.git log origin/main --diff-filter=D --name-only over .github/workflows/ returns empty, and the set of paths ever present in main's history is identical to today's set. That transition has never been exercised in this repository, so "the entry then persists" is scoped to files that never reached main — they had no default-branch deletion event available to fire.
  • The API-vs-human-tab question is OPEN, not answered. Both github.com/objectstack-ai/objectui/actions and api.github.com return 403 for these sessions, so the MCP tool is the only reachable registry view and the two were never compared.

⭐ Every figure re-measured at claim, and one of them moved

The dispatch required re-taking the 7 / 25 / 36 figures rather than restating them. Re-measured, and the tree had in fact moved — PR #6159 merged at 22:58:38Z, between the first fetch and the measurement, which changed one of the seven:

readinground 1re-measured at c677fe3b8
registry total_count3636
entries returned on page 13030 (per_page: 100 ignored)
entries on page 266 — union 30 + 6 = 36
registered file-path entries3232 (plus 4 dynamic/*)
workflow files on main2526
Direction A — registered, not on main76
Direction B — on main, not registeredEMPTYEMPTY
ever-present path set vs today25 = 2526 = 26

The entry that left Direction A is pre-install-import-graph.yml — the healthy in-flight counter-example the ruling turned on. It was registered at 21:41Z, was Direction A's seventh member when this round began, and graduated to main mid-measurement when #6159 landed. ⭐ That is the gate rejection re-confirmed rather than quoted: a cross-check gate open during those 77 minutes would have reddened a completely healthy PR. The note carries it as the worked example.

Merge state was read from the PR state directly (merged: true, merged_at), never git branch -r --contains — merges here are squashes.

Verification, each quoting its own verdict line

Exit codes captured before any pipe (redirect first, then tail). Union re-run at the final commit 0c36cd3c4, working tree clean.

node scripts/check-control-bytes.mjs exit=0
✅ check-control-bytes: OK (scanned 5106 tracked text file(s); skipped 85 binary).
node scripts/check-doc-links.mjs exit=0
Links are valid across 15 scan roots.
node scripts/check-changeset-presence.mjs exit=0
✅ No source of a released package changed in this range, so no changeset is owed.
npx vitest run scripts/__tests__/ --maxWorkers=2 exit=0
Test Files 71 passed (71) · Tests 1933 passed (1933)

Heavy steps ran through the container's shared verify lock; its own verdict lines read command-exit 0 · held the lock 43s for the suite and 6s for the install.

Gate scope, derived from each gate's own configuration rather than assumed:

  • check:doc-fencesnot implicated.check-doc-fence-languages.mjs scans content/docs plus packages/*/README.md (DOCS_ROOT/DOC_EXTENSIONS in its source). A root AGENTS.md is outside its population, so the added bash fence is not in its scope.
  • lint:rootnot implicated, measured not assumed.eslint --format json AGENTS.md returns one file object carrying "File ignored because no matching configuration was supplied." — the file is not in eslint's population at all, read from eslint's own config resolution.
  • Root vitest only, per objectui#3378 — never package-scoped. Scoped to scripts/__tests__/, which is the honest superset: check-doc-links.test.ts is the one suite that reads AGENTS.md from the real tree (it asserts the file is a SCAN_ROOTS row that opens exactly one file, and walks every markdown link in it). The whole directory was run rather than that one file.

No changeset is owed and none was added — the presence gate's own verdict line says so above, over this range. objectui has no skip-changeset label mechanism, so nothing was labelled; the declaration here is the gate verdict itself.

Control bytes:grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]' AGENTS.md returns no matches (exit 1), alongside the green gate above.

Link discipline: the note adds no markdown links, and AGENTS.md has none at all — consistent with check-doc-links.mjs's own header note, and the reason its disk rule row still passes unchanged.

Not done, and not owed by this seat

CI convergence. The PM verifies the real gate jobs. And per the governed-surface rule at the top, landing is reserved for a human regardless of what CI says — green does not settle whether a text should become operating procedure.


Generated by Claude Code

…the paginated-listing rule
The registry creates an entry at a workflow's FIRST RUN on any ref. The default
branch is irrelevant and the entry then persists, so `state: active` means only
"not disabled" and is not a claim about `main`. Reading it as one produced a
false security-tooling claim that reached two artifacts.
Also records the general rule the finding itself tripped over: `list_workflows`
ignores `per_page` and returns a fixed 30 entries while reporting the true
`total_count`, so compare the count against the returned array length before
believing any absence on a paginated listing.
States plainly what is NOT established here: the delete-from-default-branch
transition has never been exercised in this repository, and whether the API
listing matches the human Actions tab could not be measured.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019b5UBNMtTzKbVtZZGvFuxe
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] The Actions workflow registry disagrees with main in both directions, so list_workflows cannot settle "does X run here"

2 participants

@yinlianghui-tw@claude