You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[devx] no repo gate catches a context used where GitHub forbids it — an invalid ci.yml reads as a green PR #27227
Filing gate ①: a tooling defect with a named landing point and a reproduction. Raised by devx seat 2 (session_01QSeKYmTYfaPbLQD4BJfomW) from PR #27212 (#27154): the dev's addendum and contract review record 6467449484, open question OQ3, recommendation B.
Business reason. Seats and the maintainer read a PR's check list as the gate verdict. When ci.yml is invalid, GitHub creates no CI run, so none of the required contexts appear. The check list shows only the other workflows, all green, so the PR reads green while nothing ran. Today this is caught only by a human or seat who notices that CI is missing. Without a gate, the next invalid edit to a workflow costs another round: a review run on a head where CI never ran.
Reproduction. PR #27212, head 191e9d5e. The new live-e2e-ui job set LIVE_BACKEND_DIR: ${{ runner.temp }}/live-backend in job-levelenv:. The runner context is available only at step level. GitHub rejected the file:
The only run for ci.yml on that head was a push run named by its file path (.github/workflows/ci.yml), with conclusion failure and 0 jobs.
There was no CI pull_request run.
Every other workflow on the head was green.
actionlint was not part of the dev's pre-push runs. The fix (moving the env to step level) landed in the same PR.
Expected. A repo gate rejects any expression that uses a context in a key where GitHub's context-availability table forbids it. At minimum it covers runner, steps, job and matrix in job-level env:, if:, timeout-minutes and runs-on. The diff fails before push, and in Lint & Repo Gates.
Landing point. Recommendation B from the record: extend scripts/check-workflow-status-functions.mjs, which already parses every job-level if: across .github/workflows/*.yml, with a context-availability table. The alternative is running actionlint in the repo gates; the card's reader picks one and records why.
Reader who acts. devx seat, one PR: the gate, a self-test fixture that reproduces the 191e9d5e shape, and the registry wiring.
Dedupe.search_issues (semantic) for "workflow gate context not allowed job-level env runner.temp invalid workflow false green": 1 hit, #15234 (closed, an unrelated NODE_OPTIONS finding). Exact search for "Live E2E UI timeout-minutes ceiling …": 0 hits. New.
Claim: PM loop round 6 · 2026-10-28T11:39Z
Session: session_01QSeKYmTYfaPbLQD4BJfomW (the dispatching seat; the dispatch note under this claim names the cloud session)
Account: os-justin (the seat's linked user, as GET /user answers it; the card's assignee)
Branch: claude/issue-27227-workflow-context-gate
Worktree: the cloud session's own container
Domain: domain:devx
Seat: domain:devx#2
File surface: scripts/check-workflow-status-functions.mjs, or a new scripts/check-workflow-context-availability.mjs chained into the SAME check:workflow-status-functions script in package.json, plus its --self-test fixtures. The dev picks one and records why. The rule: an expression that names a context in a workflow key where GitHub's context-availability table forbids it is refused. At minimum this covers runner, steps, job and matrix in job-level env:, if:, timeout-minutes and runs-on, plus the matrix exceptions GitHub allows (runs-on, env and timeout-minutes with a strategy.matrix). A self-test fixture reproduces the PR #27212191e9d5e shape: runner.temp in job-level env:. ⛔ No .github/workflows/** edit: the existing lint.yml step that runs pnpm check:workflow-status-functions carries the new rule, so the PR stays off the governed surface. If the live tree has a violation, stop and report it; do not fix it here (stop on breach; explain in the report)
Container & model: S, mode:cloud, model: TIER_DEFAULT (dispatch-gates --tier: "no path-derived mandate"), effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — a gate gap, no regressing PR (the invalid edit was caught and fixed inside PR #27212 before merge)
Ruling-ref: none — filing gate ①, no ruling needed
Thread-read: none
Premise: holds at origin/maincdec7473ef. scripts/check-workflow-status-functions.mjs (735 lines) parses job-level if: across .github/workflows/*.yml and reads no context-availability rule. lint.yml L3253 runs pnpm check:workflow-status-functions. No actionlint invocation exists in package.json, scripts/*.mjs or .github/workflows/*.yml.
Serial constraints cleared: no open PR touches scripts/check-workflow-status-functions.mjs.
Dispatched under claim 6468029898 · 2026-10-28T11:41Z: cloud session session_01QSeKYkorXJzrG4kmSQV2Y7 (mode:cloud, TIER_DEFAULT, effort medium), branch claude/issue-27227-workflow-context-gate. The report comes back here as os-dev-report.
{
"issue": 27227,
"status": "done",
"branch": "claude/issue-27227-workflow-context-gate",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27242",
"session": "session_01QSeKYkorXJzrG4kmSQV2Y7",
"premise_still_valid": true,
"summary": "Added scripts/check-workflow-context-availability.mjs (option b: a new script, chained into the SAME check:workflow-status-functions line in package.json, so the existing lint.yml step carries it; no .github/workflows edit). It transcribes GitHub's 34-row Context availability table (read from the github/docs source contexts.md on 2026-10-28, because docs.github.com is outside this container's allow-list) and refuses any context or special function a key's row does not list. The most specific row wins, and an if: is read as an expression with or without the ${{ }} wrapper. Live tree: 0 findings over 30 files, 78 jobs and 1017 judged expressions. The card's claim was verified and holds at 835b2d1c; the Claim 6468029898 names this branch.",
"tests": "node scripts/check-workflow-context-availability.mjs --self-test: 53 assertions in 9 batteries, with roster, floor and handshake. They cover: the 191e9d5e specimen (runner.temp in job-level env) refused; the same key at step-level env passing; the 16-cell minimum grid judged against the table (13 refuse; matrix passes in env, timeout-minutes and runs-on); the matrix rows passing under strategy.matrix while job-level if: still refuses matrix; expression reading; special functions; workflow-level and workflow_call rows; 5 missing-input shapes; and the real tree. Teeth: a one-shot mutant widened the jobs.*.env row with runner (proven on disk by grep -c = 1) and its self-test exited 1 with 6 failures. Restored, the self-test printed '53 assertions', exit 0, and git status was clean. No permanent mutant file. Head 73f898eb.",
"gates": "On 73f898eb, which is c444d24b merged with origin/main. pnpm check:workflow-status-functions: exit 0. dispatch-gates --commands derived 41; all were run, plus 5 ⛔ roster gates under scripts/. --ran: '41 derived famil(ies) accounted for — 37 run, 4 NOT-MEASURED (4 DERIVED from a recorded exit 3)', exit 0. NOT MEASURED (exit 3, PREREQUISITE NOT MET because no build closure exists and the diff touches no package): check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure, check:sourcemap-no-sources-content, check:published-readme-exports. check:pm-dispatch-gates: exit 0. check-comment-mask-corpus: exit 0, 308s. PR check-runs at report time: Governed Surface Queue Guard success, Check Changeset success; Build Core and the rest in_progress. Not awaited, per contract.",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "0 — ToolSearch loaded the tool schemas only; no mcp__github__ tool was called",
"api_writes": "2 — (1) POST /repos/objectstack-ai/objectstack/dispatches, the fleet-write relay pr_create stroke (run 40685816860, success). It created #27242 as a draft with assignees os-justin and labels skip-changeset, and the body read back as 9716 bytes, byte-identical. (2) POST /repos/objectstack-ai/objectstack/issues/27227/comments, this report, via post-stamped. Also 2 git pushes (not REST).",
"open_questions": [
{
"question": "The card says matrix is allowed in job-level runs-on, env, timeout-minutes and continue-on-error 'when the job has a strategy.matrix'. GitHub's table lists matrix for those keys with no such condition. Should the gate also refuse matrix there when the job has no strategy.matrix?",
"options": [
"A: keep it table-faithful, as shipped: no strategy.matrix condition. GitHub does not reject such a file; the reference just evaluates empty.",
"B: add a second, separately documented rule refusing matrix.* without a strategy.matrix. That is an actionlint-style lint and goes beyond the false-green class this card names."
],
"recommendation": "A, because the card asks to encode the table rather than a memory of it, and the defect class is files GitHub rejects outright. B lints something GitHub accepts."
},
{
"question": "docs.github.com is outside this container's network allow-list, so the table was read from raw.githubusercontent.com/github/docs. Is that an acceptable source of record?",
"options": [
"A: yes; the header names the source path and read date",
"B: re-verify against the rendered page from a seat with docs.github.com access"
],
"recommendation": "A, because the docs page renders from that source file."
}
],
"out_of_scope_findings": []
}
Landed: PR #27242, merged as 295699d51d through the merge queue · 2026-10-28T12:38Z
Merged = reviewed. The merged diff matches the reviewed head 73f898ebea: the sorted +/− lines are hash-identical, 2 files, +711/−1. ACCEPT → PR #27242 comment 6468898202. The card was closed by Fixes #27227. pm:dispatched is removed in this act. Cloud session session_01QSeKYkorXJzrG4kmSQV2Y7 is archived in this act. main's Lint & Repo Gates step now runs the context-availability gate. Nothing remains.
Activity
objectstack-fleet commentedon Oct 28, 2026
Claim: PM loop round 6 · 2026-10-28T11:39Z
Session:
session_01QSeKYmTYfaPbLQD4BJfomW(the dispatching seat; the dispatch note under this claim names the cloud session)Account:
os-justin(the seat's linked user, asGET /useranswers it; the card's assignee)Branch:
claude/issue-27227-workflow-context-gateWorktree: the cloud session's own container
Domain:
domain:devxSeat:
domain:devx#2File surface:
scripts/check-workflow-status-functions.mjs, or a newscripts/check-workflow-context-availability.mjschained into the SAMEcheck:workflow-status-functionsscript inpackage.json, plus its--self-testfixtures. The dev picks one and records why. The rule: an expression that names a context in a workflow key where GitHub's context-availability table forbids it is refused. At minimum this coversrunner,steps,jobandmatrixin job-levelenv:,if:,timeout-minutesandruns-on, plus thematrixexceptions GitHub allows (runs-on,envandtimeout-minuteswith astrategy.matrix). A self-test fixture reproduces the PR #27212191e9d5eshape:runner.tempin job-levelenv:. ⛔ No.github/workflows/**edit: the existinglint.ymlstep that runspnpm check:workflow-status-functionscarries the new rule, so the PR stays off the governed surface. If the live tree has a violation, stop and report it; do not fix it here (stop on breach; explain in the report)Container & model: S,
mode:cloud,model: TIER_DEFAULT(dispatch-gates --tier: "no path-derived mandate"),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility: n/a — a gate gap, no regressing PR (the invalid edit was caught and fixed inside PR #27212 before merge)
Ruling-ref: none — filing gate ①, no ruling needed
Thread-read: none
Premise: holds at
origin/maincdec7473ef.scripts/check-workflow-status-functions.mjs(735 lines) parses job-levelif:across.github/workflows/*.ymland reads no context-availability rule.lint.ymlL3253 runspnpm check:workflow-status-functions. Noactionlintinvocation exists inpackage.json,scripts/*.mjsor.github/workflows/*.yml.Serial constraints cleared: no open PR touches
scripts/check-workflow-status-functions.mjs.Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
Dispatched under claim 6468029898 · 2026-10-28T11:41Z: cloud session
session_01QSeKYkorXJzrG4kmSQV2Y7(mode:cloud,TIER_DEFAULT, effort medium), branchclaude/issue-27227-workflow-context-gate. The report comes back here asos-dev-report.Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
os-dev-report
{ "issue": 27227, "status": "done", "branch": "claude/issue-27227-workflow-context-gate", "pr": "https://github.com/objectstack-ai/objectstack/pull/27242", "session": "session_01QSeKYkorXJzrG4kmSQV2Y7", "premise_still_valid": true, "summary": "Added scripts/check-workflow-context-availability.mjs (option b: a new script, chained into the SAME check:workflow-status-functions line in package.json, so the existing lint.yml step carries it; no .github/workflows edit). It transcribes GitHub's 34-row Context availability table (read from the github/docs source contexts.md on 2026-10-28, because docs.github.com is outside this container's allow-list) and refuses any context or special function a key's row does not list. The most specific row wins, and an if: is read as an expression with or without the ${{ }} wrapper. Live tree: 0 findings over 30 files, 78 jobs and 1017 judged expressions. The card's claim was verified and holds at 835b2d1c; the Claim 6468029898 names this branch.", "tests": "node scripts/check-workflow-context-availability.mjs --self-test: 53 assertions in 9 batteries, with roster, floor and handshake. They cover: the 191e9d5e specimen (runner.temp in job-level env) refused; the same key at step-level env passing; the 16-cell minimum grid judged against the table (13 refuse; matrix passes in env, timeout-minutes and runs-on); the matrix rows passing under strategy.matrix while job-level if: still refuses matrix; expression reading; special functions; workflow-level and workflow_call rows; 5 missing-input shapes; and the real tree. Teeth: a one-shot mutant widened the jobs.*.env row with runner (proven on disk by grep -c = 1) and its self-test exited 1 with 6 failures. Restored, the self-test printed '53 assertions', exit 0, and git status was clean. No permanent mutant file. Head 73f898eb.", "gates": "On 73f898eb, which is c444d24b merged with origin/main. pnpm check:workflow-status-functions: exit 0. dispatch-gates --commands derived 41; all were run, plus 5 ⛔ roster gates under scripts/. --ran: '41 derived famil(ies) accounted for — 37 run, 4 NOT-MEASURED (4 DERIVED from a recorded exit 3)', exit 0. NOT MEASURED (exit 3, PREREQUISITE NOT MET because no build closure exists and the diff touches no package): check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure, check:sourcemap-no-sources-content, check:published-readme-exports. check:pm-dispatch-gates: exit 0. check-comment-mask-corpus: exit 0, 308s. PR check-runs at report time: Governed Surface Queue Guard success, Check Changeset success; Build Core and the rest in_progress. Not awaited, per contract.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "0 — ToolSearch loaded the tool schemas only; no mcp__github__ tool was called", "api_writes": "2 — (1) POST /repos/objectstack-ai/objectstack/dispatches, the fleet-write relay pr_create stroke (run 40685816860, success). It created #27242 as a draft with assignees os-justin and labels skip-changeset, and the body read back as 9716 bytes, byte-identical. (2) POST /repos/objectstack-ai/objectstack/issues/27227/comments, this report, via post-stamped. Also 2 git pushes (not REST).", "open_questions": [ { "question": "The card says matrix is allowed in job-level runs-on, env, timeout-minutes and continue-on-error 'when the job has a strategy.matrix'. GitHub's table lists matrix for those keys with no such condition. Should the gate also refuse matrix there when the job has no strategy.matrix?", "options": [ "A: keep it table-faithful, as shipped: no strategy.matrix condition. GitHub does not reject such a file; the reference just evaluates empty.", "B: add a second, separately documented rule refusing matrix.* without a strategy.matrix. That is an actionlint-style lint and goes beyond the false-green class this card names." ], "recommendation": "A, because the card asks to encode the table rather than a memory of it, and the defect class is files GitHub rejects outright. B lints something GitHub accepts." }, { "question": "docs.github.com is outside this container's network allow-list, so the table was read from raw.githubusercontent.com/github/docs. Is that an acceptable source of record?", "options": [ "A: yes; the header names the source path and read date", "B: re-verify against the rendered page from a seat with docs.github.com access" ], "recommendation": "A, because the docs page renders from that source file." } ], "out_of_scope_findings": [] }objectstack-fleet commentedon Oct 28, 2026
ACCEPT → PR #27242 comment 6468898202 · 2026-10-28T12:25Z · ready + auto-merge armed. Open questions 1 and 2 answered A in the ACCEPT.
Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
Landed: PR #27242, merged as
295699d51dthrough the merge queue · 2026-10-28T12:38ZMerged = reviewed. The merged diff matches the reviewed head
73f898ebea: the sorted +/− lines are hash-identical, 2 files, +711/−1. ACCEPT → PR #27242 comment 6468898202. The card was closed byFixes #27227.pm:dispatchedis removed in this act. Cloud sessionsession_01QSeKYkorXJzrG4kmSQV2Y7is archived in this act.main'sLint & Repo Gatesstep now runs the context-availability gate. Nothing remains.Generated by Claude Code