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
ci(half-state-patrol): the composite action gains a declared opt-in for boards that run with no anchor issue (summary-only), default off — #20793 decision A #20798
Filing gate: ③ maintainer-directed. This executes #20793 decision A (ruling record 5905998989; the maintainer's verbatim answer "A: opt-in action input (Recommended)"). Filed by domain:devx seat 2 (objectstack-ai/objectui#10917), session_01TdiauJaVCHuj45EzZGUxHh, under the maintainer's direct order to handle #18471 (R4 marker objectstack-ai/objectui#109175905019353).
Who acts on it:domain:devx seat 2 (this session) claims and dispatches it in the same round.
What changes (.github/actions/half-state-patrol/action.yml)
One new declared input, default off, named by the implementer (for example anchor-optional).
On: an empty anchor-issue gives a ::notice::, exit 0, and the findings delivered to the run summary. This matches objectui#8740's supported configuration, and the notice names that setting.
Off (the default): an empty anchor fails with ::error:: and exit 1, exactly as action.yml:313-315 does today, so objectstack losing its own variable still fails loudly.
A non-numeric anchor-issue fails in both modes.
The pull_request path is unchanged: it still skips the anchor steps.
Update in the same PR whatever documents or pins the action's inputs: the action's header prose, any scripts/pm/** test that reads the input list, and objectstack's own caller (.github/workflows/half-state-patrol.yml), which keeps the default.
Acceptance
One objectstack PR, with Clause-②: no (CI wiring, no published contract).
The action's anchor step is exercised in all three modes: off + empty → exit 1; on + empty → notice and exit 0 with a summary line; non-numeric → exit 1 in both. Use the repo's own action or workflow tests where they exist, or a runnable probe named in the PR.
Claim: maintainer direct dispatch, round R4 (execution of #20793 decision A; within the maintainer's order to handle #18471)
Session: session_01TdiauJaVCHuj45EzZGUxHh
Account: huangyiirene (the card's assignee)
Branch: claude/issue-20798-patrol-anchor-optional
Worktree: objectstack-issue-20798
Domain: domain:devx
Seat: domain:devx#2 (objectui seat 2, R4 marker objectstack-ai/objectui#109175905019353; taken on the maintainer's named order, as #18471 was at 5905052709)
File surface: .github/actions/half-state-patrol/action.yml; objectstack's caller .github/workflows/half-state-patrol.yml only if its prose must name the new input (its behaviour keeps the default); the tests or docs that read the action's input list. ⛔ Not scripts/pm/check-half-states.mjs or its predicates. (stop on breach; explain in the report)
Container & model: S/M, mode:subagent, model: opus (the tier gate over .github/actions/half-state-patrol/action.yml reads no path-derived mandate; default tier)
Clause-②: no. CI wiring, no published contract, per ruling 5905998989.
Thread-read: none
Serial constraints cleared: none. GET /pulls/{n}/files over all 11 open objectstack PRs finds no .github/actions/half-state-patrol/** and no .github/workflows/half-state-patrol.yml.
{
"issue": 20798,
"status": "done",
"branch": "claude/issue-20798-patrol-anchor-optional",
"pr": "https://github.com/objectstack-ai/objectstack/pull/20812",
"session": "session_01TdiauJaVCHuj45EzZGUxHh (mode:subagent, the parent's session id)",
"premise_still_valid": true,
"summary": "Draft PR #20812 (head c35b098b1) adds one declared input, anchor-optional, default 'false', to .github/actions/half-state-patrol/action.yml, per #20793 decision A. With it on, an empty or whitespace-only anchor-issue gives a ::notice:: naming the setting, exits 0, and writes configured=false. The anchor PATCH is then skipped through the resolve step's output, and a summary line says the run summary is the only delivery. With it off, the empty-anchor ::error:: and exit 1 block of main's action.yml:313-315 is byte-identical and behaves identically: a probe over 5 default-mode scenarios matches main's action line for line. A non-numeric anchor fails in both modes, and a sweep that could not run still fails the run in both. objectstack's caller keeps the default and changed prose only: the sibling-install section names the opt-in. check-half-states.mjs is untouched. One judgment call is in open_questions: the value check on the new input runs on every event, pull_request included.",
"input": {
"name": "anchor-optional",
"required": false,
"default": "'false'",
"accepted": "true|True|TRUE / false|False|FALSE (the core.getBooleanInput set); anything else is ::error:: + exit 1 in 'Locate the patrol sources'",
"description": "`true` declares that an EMPTY `anchor-issue` is this caller's supported configuration: that one case becomes a `::notice::` and a passing run, with the findings delivered to the run summary only. It exists for one consumer, objectui, whose maintainer declined an anchor there (#20793, decision A). The default, `false`, stays LOUD -- an empty anchor fails the run -- because without the declaration an empty value reads the same as a caller that lost its variable, and objectstack's own caller must go red when that happens. It never widens: a non-numeric `anchor-issue` fails either way, and a value other than true or false is refused on every run, pull_request included."
},
"three_mode_readings": [
"Instrument: probe-anchor-modes.py. It is not committed; its full source is in the PR body, and it is run as `python3 probe-anchor-modes.py .github/actions/half-state-patrol/action.yml .`. It executes each step's real run: body under bash --noprofile --norc -eo pipefail, evaluates every if: with success() wrapping as the runner does, and uses real GITHUB_OUTPUT/GITHUB_STEP_SUMMARY files. Only the sweep and the github-script PATCH are stubbed. Run at c35b098b1, exit 0, 14 scenarios.",
"OFF + empty (anchor-optional unset, and explicitly 'false'), schedule: Locate exit 0 anchor_optional=false. Resolve the anchor issue exit 1: `::error::No anchor issue configured for objectstack-ai/objectui. The sweep RAN (see the run summary) but has nowhere to land. Open a `tracking`-labeled anchor issue in this repo and pass its number as the 'anchor-issue' input of the half-state-patrol action.` Update skipped. Publish exit 0 with no skip line. JOB: FAILURE.",
"ON + empty (anchor-optional 'true'), schedule. The same result for a whitespace-only anchor on workflow_dispatch. Resolve exit 0 with outputs configured=false: `::notice::No anchor issue configured for objectstack-ai/objectui, which is a supported configuration for this caller: it declares 'anchor-optional: true' on the half-state-patrol action. The sweep RAN and its rendered body is in this run's summary; nothing was written to any issue, and the missing anchor does not fail this run. To deliver findings to a pinned issue instead, open a `tracking`-labeled anchor issue in this repo and pass its number as the 'anchor-issue' input.` Update skipped. The summary gets `_No anchor issue configured (`anchor-optional` is on and `anchor-issue` is empty): this summary is the ONLY delivery of the findings below — it notifies nobody, by accepted trade. Pass a `tracking` issue's number as `anchor-issue` to have them land on a pinned card instead._` JOB: success.",
"NON-NUMERIC 'abc', in both OFF and ON: Resolve exit 1 `::error::The 'anchor-issue' input is 'abc', which is not an issue number.` Update skipped. JOB: FAILURE in both modes.",
"Other rows: '9857' in either mode gives configured=true and Update runs (the stub PATCHes issue 9857), success. pull_request in either mode skips Resolve and Update, prints `_Anchor write skipped: ...`, success. A bad value 'yes' gives Locate exit 1 `::error::The 'anchor-optional' input is 'yes'. It takes true or false: ...` on both schedule and pull_request, FAILURE. ON + empty with sweep exit 3: the notice, then 'Fail the run if the sweep could not run' exits 1, FAILURE. OFF + empty with sweep exit 3: FAILURE, as on main.",
"Default mode matches main. The same probe was run over main's blob fc455f1ef (BASE 41dcf1188) and over HEAD for off+empty, off+non-numeric, off+number, pr+off+empty and off+empty with sweep exit 3, and compared after stripping the outputs annotation. 66 lines each. The only differing line per scenario is the header, `UNSET(default '-')` against `UNSET(default 'false')`.",
"H1 ablation, on a scratch copy of the committed action.yml and never on the tree. The Update guard's `&& steps.anchor.outputs.configured == 'true'` was removed: grep -c found it 0 times in the copy and 1 time in HEAD. on+empty and on+whitespace then read `(stub) actions/github-script@v9 would PATCH issue #0`. The guard is load-bearing: a real run would 404 on issue 0 and go red."
],
"files_changed": [
".github/actions/half-state-patrol/action.yml (+75/-5)",
".github/workflows/half-state-patrol.yml (+6/-2, prose only; with: unchanged)"
],
"hypotheses": "H1 CONFIRMED. The anchor steps are 'Resolve the anchor issue' (the -z test) and 'Update the pinned anchor issue'. Under the opt-in, Resolve exits 0, so Update's old guard (event != pull_request, plus the implicit success()) would run and PATCH Number('') = issue 0 (see the ablation). Update now reads steps.anchor.outputs.configured == 'true'. The behaviour of both steps in all three modes is in three_mode_readings. H2 FALSIFIED. `git grep -n \"anchor-issue\\|closed-floor\"` outside the action finds only .github/workflows/half-state-patrol.yml:60/115/118/304 (prose and the with: value) and an unrelated hit in scripts/render-release-coverage-anchor.mjs:4. No test under scripts/pm or .github reads the action's input list. The files naming the action's path (scripts/pm/dispatch-gates.mjs) read its directory and run: text, not its inputs.",
"tests": "All at c35b098b1 (git rev-parse --short HEAD), the only commit. (1) The probe above: exit 0, 14 scenarios, readings quoted in three_mode_readings and in the PR body. (2) Gate list from `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack`: 39 commands, from merge base 41dcf1188 over 2 paths. All 39 exit 0. The first pass had 15 exit 3 (PREREQUISITE NOT MET: the dependency `yaml`). They were re-run green after `pnpm install --frozen-lockfile --filter @objectstack/spec-monorepo` (root only, 3.5s). check:pm-dispatch-gates is longer than the foreground cap: it was killed at 280s, then 570s. It ran detached, as its header prescribes, under a foreground `tail --pid` wait, and printed `✓ check:pm-dispatch-gates --self-test: the exit contract holds in all three directions.`, `✓ dispatch-gates self-test: 1976 cases pass.` and `check:pm-dispatch-gates: the battery took 1018.6s on this box.`, with 0 ✗ lines and no ELIFECYCLE. The record is 0 on that reading. `node scripts/pm/dispatch-gates.mjs --ran ran.list` gave `Run reconciliation — 39 derived, 39 run, 0 NOT-MEASURED, 0 UNRUN.` and `✓ dispatch-gates --ran: 39 derived famil(ies) accounted for ... (a DERIVED zero — all 39 recorded an exit code and none of them is 3)`, exit 0. (3) Changeset gates run locally: `check-empty-changeset.mjs --base 41dcf1188` exit 0 (`0 declaring changeset(s) added`). `check-changeset-no-major.mjs --base 41dcf1188 --event EVENT` exit 0, reading `Clause-②: no. ...` (`LEVEL AXIS: this PR declares clause-② no`). No-publish proof: `pnpm ls -r` lists 81 workspace packages (69 public, 12 private), and both changed paths are owned only by the private root @objectstack/spec-monorepo. NOT MEASURED: actionlint, reason: not on PATH and not in node_modules/.bin. Also NOT MEASURED: the workflow-valued families check-half-states.mjs and check-issue-citations.mjs --census, reason: their argv carries runner-only values. This PR's own half-state-patrol.yml pull_request run is their real-runner reading. Non-PR modes on a real runner: not exercised, because a workflow_dispatch of the branch would PATCH objectstack's live anchor. CI at the report: 26 check runs on c35b098b1, 11 success, 8 skipped, 7 in_progress (including 'Live half-state sweep' and 'Check Changeset'). Check Changeset will go red until skip-changeset is applied (see deviations).",
"mcp_calls": "0 - no MCP GitHub tool was called",
"api_writes": "3 REST writes, each a fleet-write relay stroke (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls, draft #20812, relay run 36687521367; body read back byte-identical, 23103 bytes, with the session-URL footer. (2) `label-write.mjs --issue 20812 --assign huangyiirene` → POST /repos/objectstack-ai/objectstack/issues/20812/assignees, relay run 36687617713. No labels were written; the read-back shows size/s and ci/cd, which are bot labels. (3) this os-dev-report → POST /repos/objectstack-ai/objectstack/issues/20798/comments via post-stamped.mjs. Also 2 git pushes, which are not REST: the empty-branch probe at 41dcf1188, then c35b098b1.",
"deviations": [
"Changeset disposition is skip-changeset: nothing publishes, per the proof in tests. This dispatch forbade label writes, so zero label writes were made and the seat must apply `skip-changeset` to #20812. Until then Check Changeset reads red. It is not a required context.",
"`pnpm install` ran the repo's own `prepare` (scripts/setup-git-hooks.mjs). That registered merge.os-regen.* and core.hooksPath in the SHARED clone config at /home/user/objectstack/.git/config, where core.hooksPath was unset before. This is AGENTS.md's per-clone registration and is expected, but it now applies to every worktree of that clone."
],
"open_questions": [
{
"question": "Zone 1 says 'The pull_request path stays unchanged (it still skips the anchor steps)'. The PR judges the new input's VALUE in 'Locate the patrol sources' on every event, pull_request included. For every valid value the PR path is unchanged (the probe rows pr+off+empty and pr+on+empty match main). Only a misspelt opt-in such as 'yes' is refused there, on the PR that adds it. Keep that, or move the check into the Resolve step (non-PR only)?",
"options": [
"A - keep it in Locate (as shipped). A misspelt opt-in turns the caller's own PR run red. That PR run is the acceptance proof the objectui switch relies on, and objectui#11174's report measured that run as blind to anchor behaviour.",
"B - move the case statement into Resolve. The PR path is then byte-for-byte unchanged even for bad values, and a misspelt opt-in first fails on the next scheduled run, with its own ::error:: naming the input. This is a mechanical edit of about 10 lines, and the seat can request it as a patch round."
],
"recommendation": "A. Business: the only consumer (objectui) proves its switch with a pull_request run. Long-term: the check is contract-first, refusing a bad declaration at the earliest run. Anti-AI-error: an AI that writes `anchor-optional: yes` is told on its own PR. Startup: no new surface. B is only right if the seat reads the ruling's wording as literal for invalid values too."
}
],
"out_of_scope_findings": [
"carrier: objectstack-ai/objectui#11174 (its switch deletes the step) · noted, not filed: objectui main's half-state-patrol.yml notice says 'this run is NOT a failure' on an empty anchor, but the same run still goes red in 'Fail the run if the sweep could not run' when the sweep exits 2 or 3. The action's notice here says 'the missing anchor does not fail this run' instead. This is prose-only and outside the three filing classes.",
"dedupe words (for the seat, if anything above is ever filed): half-state-patrol anchor-optional · composite action anchor opt-in value check · summary-only notice wording sweep exit 3"
]
}
Landing record: PR #20812 merged through the queue at 2026-09-30T09:04:10Z, as 79114850f0f559dcb4fb432f5bcfc12947a03de6, which is now the tip of main. domain:devx seat 2 (objectstack-ai/objectui#10917), session_01TdiauJaVCHuj45EzZGUxHh, closing at 2026-09-30T09:08Z.
Reviewed head = landed head. The seat review 5907022336 read c35b098b1, and nothing was pushed after it. The queue built merge group pr-20812-261c529f on that head, and every required context passed there (Lint & Repo Gates, TypeScript Type Check, Test Core 1–6/6, Build Core, Dogfood Regression Gate 1–3/3, Temporal Conformance, Governed Surface Queue Guard).
Activity
objectstack-fleet commentedon Sep 30, 2026
Claim: maintainer direct dispatch, round R4 (execution of #20793 decision A; within the maintainer's order to handle #18471)
Session:
session_01TdiauJaVCHuj45EzZGUxHhAccount:
huangyiirene(the card's assignee)Branch:
claude/issue-20798-patrol-anchor-optionalWorktree:
objectstack-issue-20798Domain:
domain:devxSeat:
domain:devx#2(objectui seat 2, R4 marker objectstack-ai/objectui#109175905019353; taken on the maintainer's named order, as #18471 was at5905052709)File surface:
.github/actions/half-state-patrol/action.yml; objectstack's caller.github/workflows/half-state-patrol.ymlonly if its prose must name the new input (its behaviour keeps the default); the tests or docs that read the action's input list. ⛔ Notscripts/pm/check-half-states.mjsor its predicates. (stop on breach; explain in the report)Container & model:
S/M,mode:subagent, model: opus (the tier gate over.github/actions/half-state-patrol/action.ymlreads no path-derived mandate; default tier)Clause-②: no. CI wiring, no published contract, per ruling
5905998989.Thread-read: none
Serial constraints cleared: none.
GET /pulls/{n}/filesover all 11 open objectstack PRs finds no.github/actions/half-state-patrol/**and no.github/workflows/half-state-patrol.yml.objectstack-fleet commentedon Sep 30, 2026
os-dev-report
{ "issue": 20798, "status": "done", "branch": "claude/issue-20798-patrol-anchor-optional", "pr": "https://github.com/objectstack-ai/objectstack/pull/20812", "session": "session_01TdiauJaVCHuj45EzZGUxHh (mode:subagent, the parent's session id)", "premise_still_valid": true, "summary": "Draft PR #20812 (head c35b098b1) adds one declared input, anchor-optional, default 'false', to .github/actions/half-state-patrol/action.yml, per #20793 decision A. With it on, an empty or whitespace-only anchor-issue gives a ::notice:: naming the setting, exits 0, and writes configured=false. The anchor PATCH is then skipped through the resolve step's output, and a summary line says the run summary is the only delivery. With it off, the empty-anchor ::error:: and exit 1 block of main's action.yml:313-315 is byte-identical and behaves identically: a probe over 5 default-mode scenarios matches main's action line for line. A non-numeric anchor fails in both modes, and a sweep that could not run still fails the run in both. objectstack's caller keeps the default and changed prose only: the sibling-install section names the opt-in. check-half-states.mjs is untouched. One judgment call is in open_questions: the value check on the new input runs on every event, pull_request included.", "input": { "name": "anchor-optional", "required": false, "default": "'false'", "accepted": "true|True|TRUE / false|False|FALSE (the core.getBooleanInput set); anything else is ::error:: + exit 1 in 'Locate the patrol sources'", "description": "`true` declares that an EMPTY `anchor-issue` is this caller's supported configuration: that one case becomes a `::notice::` and a passing run, with the findings delivered to the run summary only. It exists for one consumer, objectui, whose maintainer declined an anchor there (#20793, decision A). The default, `false`, stays LOUD -- an empty anchor fails the run -- because without the declaration an empty value reads the same as a caller that lost its variable, and objectstack's own caller must go red when that happens. It never widens: a non-numeric `anchor-issue` fails either way, and a value other than true or false is refused on every run, pull_request included." }, "three_mode_readings": [ "Instrument: probe-anchor-modes.py. It is not committed; its full source is in the PR body, and it is run as `python3 probe-anchor-modes.py .github/actions/half-state-patrol/action.yml .`. It executes each step's real run: body under bash --noprofile --norc -eo pipefail, evaluates every if: with success() wrapping as the runner does, and uses real GITHUB_OUTPUT/GITHUB_STEP_SUMMARY files. Only the sweep and the github-script PATCH are stubbed. Run at c35b098b1, exit 0, 14 scenarios.", "OFF + empty (anchor-optional unset, and explicitly 'false'), schedule: Locate exit 0 anchor_optional=false. Resolve the anchor issue exit 1: `::error::No anchor issue configured for objectstack-ai/objectui. The sweep RAN (see the run summary) but has nowhere to land. Open a `tracking`-labeled anchor issue in this repo and pass its number as the 'anchor-issue' input of the half-state-patrol action.` Update skipped. Publish exit 0 with no skip line. JOB: FAILURE.", "ON + empty (anchor-optional 'true'), schedule. The same result for a whitespace-only anchor on workflow_dispatch. Resolve exit 0 with outputs configured=false: `::notice::No anchor issue configured for objectstack-ai/objectui, which is a supported configuration for this caller: it declares 'anchor-optional: true' on the half-state-patrol action. The sweep RAN and its rendered body is in this run's summary; nothing was written to any issue, and the missing anchor does not fail this run. To deliver findings to a pinned issue instead, open a `tracking`-labeled anchor issue in this repo and pass its number as the 'anchor-issue' input.` Update skipped. The summary gets `_No anchor issue configured (`anchor-optional` is on and `anchor-issue` is empty): this summary is the ONLY delivery of the findings below — it notifies nobody, by accepted trade. Pass a `tracking` issue's number as `anchor-issue` to have them land on a pinned card instead._` JOB: success.", "NON-NUMERIC 'abc', in both OFF and ON: Resolve exit 1 `::error::The 'anchor-issue' input is 'abc', which is not an issue number.` Update skipped. JOB: FAILURE in both modes.", "Other rows: '9857' in either mode gives configured=true and Update runs (the stub PATCHes issue 9857), success. pull_request in either mode skips Resolve and Update, prints `_Anchor write skipped: ...`, success. A bad value 'yes' gives Locate exit 1 `::error::The 'anchor-optional' input is 'yes'. It takes true or false: ...` on both schedule and pull_request, FAILURE. ON + empty with sweep exit 3: the notice, then 'Fail the run if the sweep could not run' exits 1, FAILURE. OFF + empty with sweep exit 3: FAILURE, as on main.", "Default mode matches main. The same probe was run over main's blob fc455f1ef (BASE 41dcf1188) and over HEAD for off+empty, off+non-numeric, off+number, pr+off+empty and off+empty with sweep exit 3, and compared after stripping the outputs annotation. 66 lines each. The only differing line per scenario is the header, `UNSET(default '-')` against `UNSET(default 'false')`.", "H1 ablation, on a scratch copy of the committed action.yml and never on the tree. The Update guard's `&& steps.anchor.outputs.configured == 'true'` was removed: grep -c found it 0 times in the copy and 1 time in HEAD. on+empty and on+whitespace then read `(stub) actions/github-script@v9 would PATCH issue #0`. The guard is load-bearing: a real run would 404 on issue 0 and go red." ], "files_changed": [ ".github/actions/half-state-patrol/action.yml (+75/-5)", ".github/workflows/half-state-patrol.yml (+6/-2, prose only; with: unchanged)" ], "hypotheses": "H1 CONFIRMED. The anchor steps are 'Resolve the anchor issue' (the -z test) and 'Update the pinned anchor issue'. Under the opt-in, Resolve exits 0, so Update's old guard (event != pull_request, plus the implicit success()) would run and PATCH Number('') = issue 0 (see the ablation). Update now reads steps.anchor.outputs.configured == 'true'. The behaviour of both steps in all three modes is in three_mode_readings. H2 FALSIFIED. `git grep -n \"anchor-issue\\|closed-floor\"` outside the action finds only .github/workflows/half-state-patrol.yml:60/115/118/304 (prose and the with: value) and an unrelated hit in scripts/render-release-coverage-anchor.mjs:4. No test under scripts/pm or .github reads the action's input list. The files naming the action's path (scripts/pm/dispatch-gates.mjs) read its directory and run: text, not its inputs.", "tests": "All at c35b098b1 (git rev-parse --short HEAD), the only commit. (1) The probe above: exit 0, 14 scenarios, readings quoted in three_mode_readings and in the PR body. (2) Gate list from `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack`: 39 commands, from merge base 41dcf1188 over 2 paths. All 39 exit 0. The first pass had 15 exit 3 (PREREQUISITE NOT MET: the dependency `yaml`). They were re-run green after `pnpm install --frozen-lockfile --filter @objectstack/spec-monorepo` (root only, 3.5s). check:pm-dispatch-gates is longer than the foreground cap: it was killed at 280s, then 570s. It ran detached, as its header prescribes, under a foreground `tail --pid` wait, and printed `✓ check:pm-dispatch-gates --self-test: the exit contract holds in all three directions.`, `✓ dispatch-gates self-test: 1976 cases pass.` and `check:pm-dispatch-gates: the battery took 1018.6s on this box.`, with 0 ✗ lines and no ELIFECYCLE. The record is 0 on that reading. `node scripts/pm/dispatch-gates.mjs --ran ran.list` gave `Run reconciliation — 39 derived, 39 run, 0 NOT-MEASURED, 0 UNRUN.` and `✓ dispatch-gates --ran: 39 derived famil(ies) accounted for ... (a DERIVED zero — all 39 recorded an exit code and none of them is 3)`, exit 0. (3) Changeset gates run locally: `check-empty-changeset.mjs --base 41dcf1188` exit 0 (`0 declaring changeset(s) added`). `check-changeset-no-major.mjs --base 41dcf1188 --event EVENT` exit 0, reading `Clause-②: no. ...` (`LEVEL AXIS: this PR declares clause-② no`). No-publish proof: `pnpm ls -r` lists 81 workspace packages (69 public, 12 private), and both changed paths are owned only by the private root @objectstack/spec-monorepo. NOT MEASURED: actionlint, reason: not on PATH and not in node_modules/.bin. Also NOT MEASURED: the workflow-valued families check-half-states.mjs and check-issue-citations.mjs --census, reason: their argv carries runner-only values. This PR's own half-state-patrol.yml pull_request run is their real-runner reading. Non-PR modes on a real runner: not exercised, because a workflow_dispatch of the branch would PATCH objectstack's live anchor. CI at the report: 26 check runs on c35b098b1, 11 success, 8 skipped, 7 in_progress (including 'Live half-state sweep' and 'Check Changeset'). Check Changeset will go red until skip-changeset is applied (see deviations).", "mcp_calls": "0 - no MCP GitHub tool was called", "api_writes": "3 REST writes, each a fleet-write relay stroke (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls, draft #20812, relay run 36687521367; body read back byte-identical, 23103 bytes, with the session-URL footer. (2) `label-write.mjs --issue 20812 --assign huangyiirene` → POST /repos/objectstack-ai/objectstack/issues/20812/assignees, relay run 36687617713. No labels were written; the read-back shows size/s and ci/cd, which are bot labels. (3) this os-dev-report → POST /repos/objectstack-ai/objectstack/issues/20798/comments via post-stamped.mjs. Also 2 git pushes, which are not REST: the empty-branch probe at 41dcf1188, then c35b098b1.", "deviations": [ "Changeset disposition is skip-changeset: nothing publishes, per the proof in tests. This dispatch forbade label writes, so zero label writes were made and the seat must apply `skip-changeset` to #20812. Until then Check Changeset reads red. It is not a required context.", "`pnpm install` ran the repo's own `prepare` (scripts/setup-git-hooks.mjs). That registered merge.os-regen.* and core.hooksPath in the SHARED clone config at /home/user/objectstack/.git/config, where core.hooksPath was unset before. This is AGENTS.md's per-clone registration and is expected, but it now applies to every worktree of that clone." ], "open_questions": [ { "question": "Zone 1 says 'The pull_request path stays unchanged (it still skips the anchor steps)'. The PR judges the new input's VALUE in 'Locate the patrol sources' on every event, pull_request included. For every valid value the PR path is unchanged (the probe rows pr+off+empty and pr+on+empty match main). Only a misspelt opt-in such as 'yes' is refused there, on the PR that adds it. Keep that, or move the check into the Resolve step (non-PR only)?", "options": [ "A - keep it in Locate (as shipped). A misspelt opt-in turns the caller's own PR run red. That PR run is the acceptance proof the objectui switch relies on, and objectui#11174's report measured that run as blind to anchor behaviour.", "B - move the case statement into Resolve. The PR path is then byte-for-byte unchanged even for bad values, and a misspelt opt-in first fails on the next scheduled run, with its own ::error:: naming the input. This is a mechanical edit of about 10 lines, and the seat can request it as a patch round." ], "recommendation": "A. Business: the only consumer (objectui) proves its switch with a pull_request run. Long-term: the check is contract-first, refusing a bad declaration at the earliest run. Anti-AI-error: an AI that writes `anchor-optional: yes` is told on its own PR. Startup: no new surface. B is only right if the seat reads the ruling's wording as literal for invalid values too." } ], "out_of_scope_findings": [ "carrier: objectstack-ai/objectui#11174 (its switch deletes the step) · noted, not filed: objectui main's half-state-patrol.yml notice says 'this run is NOT a failure' on an empty anchor, but the same run still goes red in 'Fail the run if the sweep could not run' when the sweep exits 2 or 3. The action's notice here says 'the missing anchor does not fail this run' instead. This is prose-only and outside the three filing classes.", "dedupe words (for the seat, if anything above is ever filed): half-state-patrol anchor-optional · composite action anchor opt-in value check · summary-only notice wording sweep exit 3" ] }Generated by Claude Code
objectstack-fleet commentedon Sep 30, 2026
Landing record: PR #20812 merged through the queue at 2026-09-30T09:04:10Z, as
79114850f0f559dcb4fb432f5bcfc12947a03de6, which is now the tip ofmain.domain:devxseat 2 (objectstack-ai/objectui#10917),session_01TdiauJaVCHuj45EzZGUxHh, closing at 2026-09-30T09:08Z.5907022336readc35b098b1, and nothing was pushed after it. The queue built merge grouppr-20812-261c529fon that head, and every required context passed there (Lint & Repo Gates, TypeScript Type Check, Test Core 1–6/6, Build Core, Dogfood Regression Gate 1–3/3, Temporal Conformance, Governed Surface Queue Guard).5905998989):anchor-optionalinput, default'false'.anchor-issueis a::notice::and a passing run, and the findings go to the run summary only.main: the seat's probe re-run diffed 66 lines against 66, and the diff was empty.main— objectui's half of objectstack-ai/objectstack#18471 (ruling 只做②) objectui#11174. Its switch pins a sha that contains this merge (79114850for later) and passesanchor-optional: true.pm:dispatchedstripped, closedcompleted.ci(half-state-patrol): a declared `anchor-optional` input lets a boar…
docs(service-automation): re-anchor the dead tracker citations to the…