From 9c17a9e4d85ae44e86d53e86e034e9c197ef64d3 Mon Sep 17 00:00:00 2001 From: clad2 Date: Wed, 5 Aug 2026 19:40:56 +0000 Subject: [PATCH] docs(runner-probes): record the venue's first delivered drills The owed-probes list keeps delivered probes with their probe-issue URLs: a claim like 'the asymmetry reproduces' should carry a link a reader can open. Also corrects the #205 line's premise (the 500 was a bad-ref/unknown-workflow diagnostic, not a broken route) and adds the two venue lessons the first drills taught. Refs #202 --- changelog.d/202.md | 71 ++++++------------------------------------- docs/RUNNER-PROBES.md | 47 ++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 71 deletions(-) diff --git a/changelog.d/202.md b/changelog.d/202.md index 9f27adf..edd9953 100644 --- a/changelog.d/202.md +++ b/changelog.d/202.md @@ -1,64 +1,11 @@ -### Added +### Changed -- `docs/RUNNER-PROBES.md` documents the standing runner-probe venue, - `heavy-duty/ceremony-runner-probe` — the place runner-only facts are measured - on demand, ruled as option A by the operator (#202). +- `docs/RUNNER-PROBES.md` records the venue's first delivered drills: the + #192 asymmetry re-observed on demand under the workflow token, the dispatch + route's 204 under both identities, and #215's boundary finding — each with + the probe-issue URL it is recorded in (#202). -- `drills/README.md` cross-links it beside the disposal rule, so the exception - is visible where the dangerous habit lives (#202). - -- The runbook states that the drill disposal rule does **not** apply to it. - Archiving it defeats its purpose, and that is exactly how the three existing - drill repos each became unavailable (#202). - -- It records that a probe must run as an Actions job under the workflow token: - the same call answers 500 there and 204 under a PAT, so a probe run any other - way produces a confident wrong answer (#202). - -- Creating the repo is recorded as the operator's step, measured rather than - assumed: a fleet identity gets 403 on org repo creation and 201 in its own - namespace (#202). - -- It carries an executable two-layer arming procedure: an immutable candidate - code SHA and an armed workflow commit on top of it. A single layer is - self-referential — rewriting a workflow makes a new commit, and a commit - cannot contain its own object ID (#202). - -- Callers are pinned by layer: composite actions to the candidate code SHA, - reusable workflows to the armed SHA, which is the only revision whose inner - checkout points at the fork (#202). - -- The arming gate asserts what each carrier IS, not only that the old literal - is gone: every `repository:` equals the fork, every `CEREMONY_SELF_REF` value - equal the candidate code SHA, and callers match the layer they belong to - (#202). - -- It enumerates the carriers from the tree rather than encoding a count, and - distinguishes ceremony's internal self-checkouts from the consumer checkouts - that must stay `${{ github.repository }}` (#202). - -- Both published snippets are ShellCheck-clean when extracted and linted - directly, not merely as part of the repository sweep (#202). - -- The checker validates the MANIFEST against the target it was given, so a - manifest that describes a wrong arming consistently — wrong fork, or the - armed SHA where the candidate belongs — refuses instead of matching a tree - rewritten to the same wrong value (#202). - -- The manifest is generated from the PRE-arming tree, which is the only order - that enumerates the carriers that must change (#202). - -- Both published snippets were driven against a constructed candidate/probe - pair: deletion, both role swaps, wrong owner, wrong - SHA, wrong path, a deleted caller class and an extra carrier all refuse, and - the armed control passes (#202). - -- The manifest records complete caller coordinates, so a path swapped under the - right owner and SHA is caught (#202). - -- Generator and checker share one domain — ceremony callers — so a third-party - `actions/checkout` is neither manifested nor reported as unrecognised (#202). - -- Probe results are written to an issue in the probe repo and carried to the - ceremony issue by a human, so the probe holds no path that can write to the - live board (#202). +- Two venue lessons join the runbook where the next probe author will look: + findings must be written to issues because the venue's log route 404s for + non-admin reads, and report templates must never interpolate `${{ … }}` + expressions (#202). diff --git a/docs/RUNNER-PROBES.md b/docs/RUNNER-PROBES.md index 1e98bc2..6878278 100644 --- a/docs/RUNNER-PROBES.md +++ b/docs/RUNNER-PROBES.md @@ -333,13 +333,42 @@ No probe touches `heavy-duty/ceremony`'s board. No labels, no comments, no runs attributable to a probe. The venue exists so that the live board does not have to be the test fixture. -## The probes this venue owes +## The probes this venue owes — and the records of those delivered -- **ceremony#192** — that the repaired sweep actually lifts a label under the - workflow token, which is the half its acceptance criteria cannot get from - the hermetic contract tests. -- **ceremony#205** — whether `POST /actions/workflows/{file}/dispatches` - works on this instance with a valid ref and inputs. Measured so far: - `GET /actions/workflows` 404s and the dispatch route answers 500 rather than - a 4xx, which is not enough to port against. -- A 0.6.0 consumer exercise once ceremony#198 has merged. +Delivered probes stay listed with their record: the venue's value is that a +claim like "the asymmetry reproduces" carries a URL a reader can open, not a +memory. + +- **ceremony#192** — DELIVERED, first drill (2026-08-05). Under + `${{ github.token }}` in the venue: + `DELETE /issues/{n}/labels/{id}` → **500**, the label still on the issue + afterward — the failure observable in the set, not merely a status — then + `PUT` full-set clear → **200**, set actually empty. Record: + [probe issue #1](https://forgejo.heavyduty.builders/heavy-duty/ceremony-runner-probe/issues/1) + (runs 1 and 4). +- **ceremony#205** — DELIVERED with a correction to the line above's + premise. The dispatch route answers **204** to a valid + `{"ref":"refs/heads/" | "", "inputs":{…}}` under both a PAT + and the workflow token; the earlier opaque `500` came from a bare + unresolvable ref or an unknown/unparseable workflow — the diagnostic !213 + ships now names this. The `GET /actions/workflows` listing still 404s. +- **ceremony#215** — the discriminator drill: REST-body `inputs` DO reach a + top-level dispatched workflow, both contexts + (`inputs.*` and `github.event.inputs.*`), both identities. What loses the + value is the `workflow_call` boundary — a called workflow does not see the + caller's `event.inputs` on this instance. Records: + [probe issues #4 and #5](https://forgejo.heavyduty.builders/heavy-duty/ceremony-runner-probe/issues/4) + (runs 6 and 7). +- A 0.6.0 consumer exercise once ceremony#198 has merged. (#198 merged + 2026-08-05; this probe remains open.) + +Two venue lessons from the first drills, kept where the next probe author will +look: + +- **Rule 4 is load-bearing on this instance**: the probe repo's web log route + 404s for non-admin reads, and a log-only observation (run 2) was lost where + issue-written ones were not. +- **Never let a report template interpolate `${{ … }}`** — an escaped + `${{ github.token }}` in a comment body was expanded by the runner into the + recorded text (the run's ephemeral token; redacted in place). Build report + strings from plain shell variables only.