Half-State Patrol #172
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Half-State Patrol | |
| # This board's standing caller of objectstack's half-state patrol: the composite | |
| # action `objectstack-ai/objectstack/.github/actions/half-state-patrol`, pinned | |
| # to an objectstack commit sha (objectui#11174, objectui's half of | |
| # objectstack-ai/objectstack#18471). | |
| # | |
| # ## What lives here, and what does not | |
| # | |
| # This file holds only what is THIS board's: when the patrol runs, what it may | |
| # touch, and the inputs whose values are decided here. Everything else — the | |
| # sweeper (objectstack's `scripts/pm/check-half-states.mjs`), how its findings | |
| # are rendered and delivered, and when a run goes red — is the action's, and | |
| # the action's own header is the authority on it. ⛔ Do not restate that | |
| # behaviour here. A copy of upstream prose describes upstream as of the day it | |
| # was copied and no later: objectui#10208 retired this repository's copy of the | |
| # sweeper for that reason, and objectui#11174 retired the copied steps and the | |
| # prose adopted with them. | |
| # | |
| # ## The pin | |
| # | |
| # The `uses:` ref is a 40-character objectstack commit sha, ⛔ never `@main`: | |
| # `@main` would adopt whatever landed upstream an hour ago, with no reviewed | |
| # moment in this repository and nothing to roll back to. A composite action | |
| # referenced at a sha makes the runner place the WHOLE objectstack repository | |
| # at that sha, so the pin freezes the sweeper as well as `action.yml`. | |
| # | |
| # TO BUMP: pin objectstack `main`'s tip as read at that moment, and record the | |
| # sha and the time it was read in the pull request. ⛔ Not the action's own last | |
| # commit — that would roll the sweeper back to wherever it stood when | |
| # `action.yml` last changed (objectui#11174, the seat's ruling on which sha to | |
| # pin). The pin must contain objectstack `79114850f`, where `anchor-optional` | |
| # was declared: an older one receives that input as an unexpected one, which | |
| # the runner only warns about, and every scheduled run here goes red. | |
| # | |
| # The sha spelling is a declared exception to this repository's action-ref | |
| # convention: `DECLARED_EXCEPTIONS` in `scripts/check-action-ref-convention.mjs` | |
| # carries this workflow, this action and the reason. | |
| # | |
| # ## No anchor issue, by decision (objectui#8740) | |
| # | |
| # This board has no pinned anchor issue: the maintainer declined the setup and | |
| # closed objectui#7852 for it. The step below says so BY | |
| # NAME rather than by omission — `anchor-issue` is passed empty and | |
| # `anchor-optional: true` declares empty to be this board's supported | |
| # configuration (objectstack-ai/objectstack#20793, decision A). The action then | |
| # sweeps, puts the rendered findings in the run summary, emits a `::notice::`, | |
| # skips the anchor write and passes. An issue number is only ever meaningful in | |
| # the repo it was minted in, which is why nothing here guesses one. | |
| # | |
| # ⚠️ The accepted cost, stated rather than rediscovered: the findings live only | |
| # in run summaries, which notify nobody — objectui#5791 measured what that | |
| # silence costs on this board. A seat reading this board's half-states reads the | |
| # patrol's run summaries; there is no anchor to read. | |
| # | |
| # ⛔ The opt-in is empty-only, and the action enforces that, not this file: a | |
| # non-numeric `anchor-issue`, or a sweep that could not run, still fails the | |
| # run. Delivering to an anchor is one input away (a `tracking`-labeled issue's | |
| # number as `anchor-issue`), but it reverses the maintainer's decline, so it is | |
| # the maintainer's call. | |
| # | |
| # ## The closed-card floor (objectui#5985) | |
| # | |
| # `closed-floor` holds the sweeper's closed-card reader (`pm:*` labels left on | |
| # cards that already closed) to cards closed on or after 2026-08-28 — the date | |
| # the strip-on-close convention was written into the pm-dispatch protocol's | |
| # label-discipline section. `pm:*` on a card closed before the convention | |
| # existed is inert history, since the dispatch loop reads state on OPEN cards | |
| # only. The measurement taken on 2026-08-24 says what an unfloored reader does | |
| # here: 815 closed cards carried `pm:dispatched`, and ~87% of the issues in the | |
| # reader's window carried some `pm:*` residue, against the 26% upstream | |
| # measured — rows that report the convention rather than a defect, and that | |
| # consume the whole body budget. Judging from the cutover forward buys the | |
| # row's value with no backfill: ⛔ no bulk relabelling of closed cards was run | |
| # and none is owed. | |
| # | |
| # ⛔ Do not move the date EARLIER without re-measuring: every day it moves back | |
| # pulls in cards closed under no convention at all. The floor is UPSTREAM code; | |
| # what is this repository's own is the value passed to it. | |
| on: | |
| schedule: | |
| # Four times a day, six hours apart, at :37 past the hour. | |
| # | |
| # The minute is offset ON PURPOSE. The triage Routine that heals these same | |
| # states fires hourly near the top of the hour, and a patrol landing at the | |
| # same minute would keep reading the board mid-heal — reporting half-states | |
| # the healer is in the middle of pairing, i.e. manufacturing findings that | |
| # clear themselves. :37 puts this sweep in the quiet part of the healer's | |
| # cycle in both directions. Four runs a day rather than hourly keeps it | |
| # cheap on the core API quota it shares with the dispatch loop's hot path. | |
| - cron: '37 1,7,13,19 * * *' | |
| workflow_dispatch: {} | |
| # A change to the patrol is exercised before it merges: on a pull_request run | |
| # the action still sweeps, proving the pin, the inputs and the transport on a | |
| # real runner, but it skips both anchor steps and writes no issue. | |
| # | |
| # ⚠️ That skip means a pull_request run cannot show the no-anchor opt-in at | |
| # all. The first scheduled or dispatched run after a change here is the live | |
| # reading of it: `configured=false`, a `::notice::`, the anchor write skipped, | |
| # and the run green. | |
| pull_request: | |
| paths: | |
| # The action and the sweeper both arrive at the pinned sha, so this file | |
| # is the only path in this repository a change can break the patrol | |
| # through — and bumping the pin is an edit to it. | |
| - '.github/workflows/half-state-patrol.yml' | |
| # What the action asks of its caller's token: `contents: read`, and | |
| # `issues: write` for its single anchor-body PATCH. With no anchor configured | |
| # here that write is never attempted, and the token is never used for labels, | |
| # comments, assignees or state. | |
| permissions: | |
| contents: read | |
| issues: write | |
| # One patrol at a time. A scheduled run overlapping a manual dispatch would read | |
| # the board twice on one request budget and, were an anchor ever configured, | |
| # race to rewrite the same body — the loser's findings vanishing with no trace | |
| # but an edit-history entry. | |
| concurrency: | |
| group: half-state-patrol | |
| cancel-in-progress: false | |
| jobs: | |
| patrol: | |
| name: Live half-state sweep | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| # The SUBJECT of the sweep, not a source of the code that runs it: the | |
| # sweeper reads this board's own workflows and tracked files from this | |
| # checkout, and refuses to run without it. | |
| - name: Checkout repository | |
| uses: actions/checkout@v7 | |
| # Stays in the caller: the action holds no Node pin of its own and only | |
| # refuses a runner older than the floor its own tree declares. | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v7 | |
| with: | |
| node-version: '22' | |
| - name: Sweep the board | |
| uses: objectstack-ai/objectstack/.github/actions/half-state-patrol@0c5a71b0942d54e56ad365f0b2a173fd84c1c5e1 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| # Empty on purpose, with the opt-in beside it: see "No anchor issue, | |
| # by decision" above. | |
| anchor-issue: '' | |
| anchor-optional: true | |
| closed-floor: '2026-08-28' |