Commit graph

51 commits

Author SHA1 Message Date
clad2
37e31ffd85 fix(labels): refuse an unset API root, name transport failures, update the docs
Some checks failed
CI / test (pull_request) Failing after 3m13s
CI / release-exercise (pull_request) Successful in 11s
CI / self-guards (pull_request) Successful in 7s
CI / action-exercise (pull_request) Successful in 6s
CI / docs-sync-exercise (pull_request) Successful in 6s
Refs guard / refs-not-closing (pull_request) Has been skipped
labels / labels (pull_request) Successful in 8s
Three corrections from @codex-reviewer-andresmgsl's review of 935a813.

1. `api="${GITHUB_API_URL:-https://api.github.com}"` guessed GitHub when the
   variable was absent — driven with a recording curl, it reported success
   after POSTing to api.github.com from this forge. That is the "Never
   'probably github'" rule, and the same unset-environment refusal #201 just
   established for docs-sync. It now refuses before any request, and the test
   asserts zero calls were made: refusing after a POST is not refusing.

2. The "never silenced with || true" invariant was still asserted by grepping
   the gh line this port removed, so it passed on any REST implementation
   including one that swallows a failed POST. It is rebound behaviourally: a
   curl that dies at the transport must fail the step. Doing that revealed the
   step failed with a bare exit 7 and no sentence, so it now names the failure
   — owning the diagnostic is the whole point of the surrounding code.

3. docs/CONSUMERS.md and both caller comments still described `gh workflow
   run` as the mechanism. They describe the REST dispatch now, and the manual
   bootstrap command carries a forge-neutral curl form beside the gh one: a
   cross-forge runbook that sends this forge to a missing binary is wrong even
   where the prose around it is right.

Refs #205
2026-08-05 17:16:30 +00:00
e965b15cbf docs: the recurring upstream sync, its standing resolutions, and a guard on where the delta lives (#200)
All checks were successful
CI / test (pull_request) Successful in 3m3s
CI / release-exercise (pull_request) Successful in 11s
CI / self-guards (pull_request) Successful in 7s
CI / action-exercise (pull_request) Successful in 6s
CI / docs-sync-exercise (pull_request) Successful in 6s
Refs guard / refs-not-closing (pull_request) Has been skipped
labels / labels (pull_request) Successful in 8s
The third child of #197, written immediately after performing the sync it
describes, while the findings are still first-hand.

docs/UPSTREAM-SYNC.md carries the procedure and the six standing resolutions,
each with the issue that decided it, so they are not re-argued every sync. The
parts that are not obvious from the outside, and that the 0.6.0 sync paid to
learn:

  * THE AUDIT STEP. `git merge` takes upstream's side wherever only upstream
    moved a region, so a function upstream ADDED to a file this tree owns
    arrives with no conflict and no question. Reviewing the hunks cannot find
    it — four reviewers read the same diff and each found a different subset.
    That was eight runtime `gh` call sites in three files and two file types.

  * THE SAME MECHANIC APPLIES TO STATE. A resolved region can remove a producer
    whose consumers auto-merged, and those consumers degrade to empty rather
    than erroring, so nothing goes red. Three such seams in one sync.

  * VERIFY WHERE IT RUNS. "Green locally" was wrong three times, for three
    different reasons: shellcheck-all lints TRACKED files so a new file's first
    lint is meaningless; CI pins shellcheck 0.10.0; and the runner's jq 1.6
    exits 0 where 1.7 exits 4 on `jq -e` with empty input — which was not a
    test problem but a guard accepting an unreadable read.

  * TEST THE MERGE RESULT. Forgejo tests heads, never what two branches produce
    together, and two green PRs did produce a red tree in this sync.

  * AFTER MERGING, CHECK THE SWEEP RECONCILED SOMETHING. The first post-merge
    run was green and had done nothing.

.upstream-ref records the carried commit in machine-readable form beside the
CHANGELOG's prose. test/upstream-delta.test.sh asserts every forge-DECIDING
file is named in the inventory — offline, comment-aware, and refusing rather
than skipping when the ref is missing. Shim CONSUMERS are allowed by name, so
a seventh consumer is silent and a seventh decider is not.

docs/CONSUMERS.md now states that two ceremonies answer to the same version
number and how a consumer says which one it pinned.

Must-fail, both from the issue's test plan: scattering a forge_detect branch
into an unlisted file reds the guard; blanking .upstream-ref reds it too.

test/run.sh 29 files 0 failed under jq 1.7 and jq 1.6; shellcheck 0.10.0,
actionlint, self-ref, marker, vendored and changelog-armed all clean.

Refs #200
2026-08-05 13:36:17 +00:00
e035130f65 merge upstream 0.6.0 onto the forge tree, and port every gh call site it brought (#198)
Some checks failed
CI / test (pull_request) Failing after 33s
CI / release-exercise (pull_request) Successful in 12s
CI / self-guards (pull_request) Successful in 6s
CI / action-exercise (pull_request) Successful in 6s
CI / docs-sync-exercise (pull_request) Successful in 6s
Refs guard / refs-not-closing (pull_request) Failing after 5s
labels / labels (pull_request) Successful in 43s
`git merge` of upstream `8c3a4d1` onto `dad99dd`, common ancestor `84bb1a4`.
18 hunks in 10 files; `lib/forge.sh`, `lib/forge-github.sh` and
`lib/forge-forgejo.sh` conflict in none and come out byte-identical.

The resolutions the issue decided: VERSION and both CEREMONY_SELF_REF
carriers take upstream's numbers; `.github/labels.conf` and `drills/0.4.1.md`
keep this forge's; CHANGELOG keeps both sides and names the upstream commit
this tree carries.

The part the hunks did not contain. Upstream's 0.5.0/0.6.0 work added whole
functions to files this tree already owned, so `git merge` took its side
without raising a conflict — and with them, EIGHT runtime `gh` call sites
that #188 had removed. Seven are ported onto the shim: two reads and four
comment writes in issueflow-reconcile, and labels-reconcile's HEAD_COMMIT_AT
read. The eighth is `gh workflow run` in labels.yml, which a workflow cannot
declare a client for and whose Forgejo equivalent this instance answers with
500 rather than a 4xx — named with its reason rather than ported on a guess.

test/no-runtime-gh.test.sh makes the rule mechanical, because reviewing the
diff could not: four reviewers reading it each found a different subset, and
the contract suite stubs `gh`, so a reintroduced call site passes it.

Three seams the resolution decides are silent when resolved wrongly, and each
now has a case that fails on the wrong one: the merged record's `merged_at`
third column (without it every sort key ties and the highest PR number comes
back), the open gather's one-BODY-row-per-line feed (a whole decoded body as
one record loses every declaration including the first), and the whole-board
read whose COLLISION_FLAGS/WINDOW_FLAGS consumers auto-merged.

The open gather carries CLOSING rows as well as BODY rows. `Refs` alone would
drop every `Closes #N` link on the open side and reclaim a claim the PR was
holding — the existing base64 round-trip case is red without it.

actions/refs-not-closing declares CEREMONY_FORGE_CLIENT=gh: its only gather
is GraphQL, which Forgejo does not serve at all. #199 ports it.

test/run.sh: 28 test files, 0 failed. shellcheck and actionlint clean.

Refs #198
2026-08-05 11:56:23 +00:00
cndgrr
fb8f8282a9 release: cut 0.6.0
Thirty-five fragments assembled into '## 0.6.0 — 2026-08-05'; VERSION to
bare 0.6.0; the three CEREMONY_SELF_REF carriers stamped "0.6.0" in this
one commit; the three docs/CONSUMERS.md availability markers cleared to
name 0.6.0 — refs-not-closing (#218), the RELEASES.md mirror entry (#248)
and the vendored-manifest completeness guarantee (#251).

drills/0.6.0.md opens with the measurement that decides its shape: the
doors-unchanged conditions do NOT all hold at this candidate, because
lib/changelog.sh moved on the release path since the last rehearsed tag
0.4.0. A full disposable-repo rehearsal is owed and is in progress; the
record is committed early and filled from the runs as they happen.

Refs #249.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 00:01:03 +00:00
ca99182e80 fix(forge): percent-encode asset names, and stop the docs naming a client
All checks were successful
CI / test (pull_request) Successful in 1m29s
CI / release-exercise (pull_request) Successful in 11s
CI / self-guards (pull_request) Successful in 5s
CI / action-exercise (pull_request) Successful in 5s
CI / docs-sync-exercise (pull_request) Successful in 5s
labels / labels (pull_request) Successful in 1m33s
Both findings are @codex's on !193 (#1583), and both are real.

The asset name travels as a QUERY VALUE, and the artifact-hook contract
permits any file the consumer drops in RELEASE_ASSETS_DIR. Raw
interpolation meant `release asset.tgz` made curl reject the URL outright
(exit 3), and '&', '#', '+', '%' silently changed the name or the query's
shape. `gh release create` handled all of those, so a 1:1 port had to.

Encoded through one boundary — jq's @uri, since jq is already a hard
dependency of this backend and a hand-rolled sed class is how the next
unescaped character gets through. Six backend cases cover it: the encoder
on a space and on the delimiters, uploads under both names, the created
release id in the path, and the multipart attachment. Mutation-checked:
dropping the encoder fails exactly the two name assertions.

docs/CONSUMERS.md's artifact-hook recovery still told operators to "run
`gh release create` by hand" and described the hook as running "before
`gh release create`" — on a Forgejo runner that is precisely the failure
this PR fixes. It now names the forge-neutral tag-door recovery first and
shows both clients for the manual path, without regressing the GitHub
guidance.

1035 assertions, 22 suites, shellcheck-all and actionlint clean.

Refs #191

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 12:11:06 +00:00
cndgrr
42b8fb6850 fix(consumers): the manifest is readable at 0.1.0, not 0.5.0
docs/VENDORED.txt and actions/docs-sync/docs-sync.sh entered the tree in
the same commit and are byte-identical at every tag — blobs 10c20a3c and
ba426479 at 0.1.0 through 0.5.0 — and 0.1.0's copy of the tool is already
manifest-driven (MANIFEST="docs/VENDORED.txt", L75). Citing 0.5.0 told the
0.1.0-0.4.1 tail, which is exactly the population this section is written
for, that the manifest was unavailable at its pin, so it would keep the
hardcoded list: #251's failure mode reproduced by the document that exists
to abolish it. The same file already said 0.1.0 at L131-L133.

Also make the guard's tracked-ness skip announce itself. It degrades to
"not asserted" wherever the tree is not a git work tree root, and doing
that in silence is the shape this script's own header argues against, so
the skip now prints on both output paths, green and red, with a test row
each way.

Round 1: claude blocking point, and claude nit 3.
2026-08-04 10:29:44 +00:00
cndgrr
b9eedd8973 docs(consumers): cite the manifest availability to the tag that shipped it
0.5.0 availability is actions/docs-sync own arrival (#19); #251 is the
guidance and the guarantee, not the file date.

Refs #251
2026-08-04 10:18:17 +00:00
cndgrr
7909383ca0 docs(consumers): read the pin manifest, never a copy of it
Re-vendor tooling and docs-sync equivalents read the pin docs/VENDORED.txt
(available at 0.5.0 and later) instead of naming the doc set themselves, so
a new doctrine file reaches every consumer at its next ordinary pin bump
with zero list edits. A hardcoded list propagates nothing and its
staleness is silent: docs-sync --check asserts byte-identity for the files
the list names and says nothing about one it omits.

What makes reading the manifest sufficient rather than merely better is
the self-guard this PR adds, tagged unreleased until the first tag carries
it, per the RELEASES.md paragraph above it.

Refs #251
2026-08-04 10:18:17 +00:00
Andriujose
2a1f8a012b test: pin inline marker mention boundary 2026-08-03 23:05:05 +00:00
Andriujose
d87d76d64b fix: align marker guard with release oracle 2026-08-03 22:56:02 +00:00
Andriujose
7200c8da49 docs: define traceable availability markers 2026-08-03 22:51:17 +00:00
Andriujose
66b136efc0 docs: wire refs guard into ceremony flow 2026-08-03 20:31:34 +00:00
Andriujose
ab60709f49 docs: add release-management doctrine 2026-08-03 17:29:15 +00:00
dan-claude-bot
e5e7555184 release: cut 0.5.0
Five fragments assembled into '## 0.5.0 — 2026-08-03' (#205 #216 #221
#224 #226); VERSION to bare 0.5.0; the three CEREMONY_SELF_REF carriers
stamped "0.5.0" in this one commit; the panel-rows unreleased marker in
docs/CONSUMERS.md cleared to name 0.5.0; drills/0.5.0.md records the
doors-unchanged ruling with the measurements as they are at 0ac3a6f.

Refs #233.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 12:01:05 +00:00
f2d5fcd565 feat(forge): derive outstanding review requests from the head, not the field
Some checks failed
CI / test (pull_request) Has been cancelled
CI / release-exercise (pull_request) Has been cancelled
CI / self-guards (pull_request) Has been cancelled
CI / action-exercise (pull_request) Has been cancelled
CI / docs-sync-exercise (pull_request) Has been cancelled
labels / labels (pull_request) Has been cancelled
Term 4. GitHub clears requested_reviewers when a verdict lands, so the field
answers "who still owes a verdict" by itself. Forgejo never clears it —
measured: rig!140 listed all three panelists with all three verdicts in, and
rig!146 still lists three while MERGED, so the field is stale even on a
closed PR.

Read raw on Forgejo that is not a cosmetic over-count. `requested` drives
three decisions, and a permanently-true field pins a PR at
state:bots-reviewing for life and stops blocker:unrequested from ever being
true: the sweep believes a round is live forever and no staleness can
correct it.

So the requested set is intersected with who has NOT submitted a verdict for
the current head, derived from /pulls/{n}/reviews — the read that is true on
both forges. On GitHub the filter removes nothing, because the field is
already accurate; term 5 holds by construction rather than by care.

A STALE approval — an approval of an older head — still owes a verdict. That
is the case that matters: treating it as answered would let a stale round
read as complete, which is the shape #136 exists to prevent.

Mutation-verified both ways: reading the field raw again reds three cases,
and treating STALE as answered reds two.

Also documents @grok-reviewer-andresmgsl's ask (#4763): every panel= account
must be able to read the repo, or the forge refuses the review request —
422 naming the account on Forgejo. A real failure mode for private
consumers, and it fails loudly rather than sweeping blind.

Refs #188
2026-08-02 19:48:09 +00:00
dan-claude-bot
44b1a3d23c fix: a draft never reads state:needs-human — round 1, claude
The reorder let a draft with a live human request plus a standing block
or comment fall through to round_state, whose human-request precedence
sits above BLOCK/FEEDBACK — 224 of claude's 1500 fixture cases read
needs-human on a PR GitHub cannot merge. decide_state now disqualifies
needs-human unconditionally under DRAFT=true, landing on
state:addressing like the blocker/needs-ruling/blocked clauses. The two
new rows assert the criterion where it can actually fail: human
requested x {CHANGES_REQUESTED, COMMENTED}. Also grok's nit: the
bootstrap row for state:building now matches LABELS.md (draft is
evidence, not the definition), and the CONSUMERS.md reflow nits are in.

Refs #205

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 14:13:25 +00:00
dan-claude-bot
ecb0371cad docs: clear five stale unreleased markers; the release PR owns clearing
Each marker now says available-at-tag in the guide's existing L420
phrasing, verified by tag containment in #221; every never-mix-refs
sentence survives verbatim. The convention paragraph gains its missing
half: the release PR that ships machinery clears, in that same PR,
every marker its assembled section makes false.

Refs #221

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 13:32:31 +00:00
dan-claude-bot
8db6c3ae29 feat: per-author review panels — labels.conf gains panel[<login>]= rows
One resolution point (panel_for_author) feeds set_required_bots; the
author's row when the conf defines one, the base panel= otherwise, minus
the author in either case. Bracket prefixes are matched quoted so the
case patterns cannot glob (D7, panela= tripwire). configured_label_rows
skips the rows so a dispatch bootstrap cannot mint a label named after
one. BUILDER.md/REVIEWER.md carry the one D9 wording; CONSUMERS.md
publishes the row as unreleased with the parse-failure warning.

Refs #224

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 13:29:15 +00:00
dan-claude-bot
be660358f2 docs: spell out crew's four-edit migration; fold in crew#250 field facts (#209)
crew#250 verified two facts the design prose now carries: a queue-
displaced run is not independently rerunnable (gh run rerun / --failed /
--job all refuse), so a victim PR had no manual escape hatch; and the
displacing burst is deterministic — one review_requested event per
panelist per request — so displacement is the steady state of a working
fleet, scaling with panel size, not a traffic spike.

CONSUMERS.md now walks the adoption as one atomic four-edit PR with crew
as the worked example: the pin bump in every ceremony uses: reference,
the new labels-sweep.yml caller, the cron RELOCATED (bold warning: a
copied-not-moved schedule double-fires sweeps into the one shared group
and reads as the bug getting worse after the fix), and actions: write
replacing the labels caller's actions: read.

Refs #209

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-01 17:25:26 +00:00
dan-claude-bot
45aa806207 labels: detach the reconcile sweep from PR-triggered runs (#209)
The sweep rode the same workflow run as the PR event that woke it, so
every displacement in the shared labels-reconcile queue recorded a
CANCELLED reconcile check on some PR — fake red CI that held review
requests. The reconcile + issueflow jobs move, unchanged, to a new
reusable labels-sweep.yml behind their own caller; labels.yml gains a
trigger job that dispatches the consumer's sweep caller with the plain
GITHUB_TOKEN (workflow_dispatch is a documented no-retrigger exemption)
on every event that used to run reconcile. A displaced sweep now cancels
on the Actions tab, attached to no PR; PR checks show scope + trigger.

Because every trigger-driven wake arrives as workflow_dispatch, the event
name alone no longer separates the operator's manual bootstrap from an
event-woken sweep: the sweep caller's bootstrap dispatch input does — the
trigger passes no, a bare manual dispatch defaults to yes. The sweep
reusable also takes pr_workflow_name, exported as SELF_WORKFLOW for the
#208 reconciler (harmless to earlier ones; zero file overlap with #208).

The trigger is deliberately loud: a pin bumped without the sweep caller,
its bootstrap input, or actions: write on the labels caller goes red at
the trigger job instead of silently never sweeping again — documented in
docs/CONSUMERS.md with the split stubs and the atomic-adoption note.

Refs #209

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-01 16:20:00 +00:00
codex-bot-andresmgsl
4198597834 docs: correct labels maintenance cadence 2026-07-29 10:37:03 +00:00
codex-bot-andresmgsl
3eff28e624 docs: explain sweep cadence and manual dispatch 2026-07-29 09:27:29 +00:00
claude-bot-andresmgsl
8cf3c335df labels: name what the hourly cron uniquely covers (#199 round)
The trigger comments, CONSUMERS stub, changelog, and reusable labels.yml
comment said "events carry every real state change in seconds; the cron
only backstops a forgotten handoff." That is backwards: no subscribed
event wakes this sweep for a review verdict landing (no pull_request_review
trigger), blocker:ci-red set/cleared, blocker:conflict when another PR
merges, or the time-based stale/48h-reclaim. The hourly cron is the sole
discovery path for those four classes, not a forgotten-handoff net —
so the comments now name them and warn against deleting the cron (AC5).

codex-2 / kimi-2 (both blocking, round 2 @0a812c4b).
2026-07-28 19:26:40 +00:00
claude-bot-andresmgsl
0a812c4b19 labels: keep edited/reopened on issues; correct 0.3.0 adoption prose (#199 round)
Round fixes on #200.

codex-1 (blocking): the issues narrowing dropped `edited`/`reopened`, but both
carry a queue-state change an event uniquely carries — `edited` a body rewrite
of the `Blocked by #N` declaration the sweep parses
(issueflow-reconcile.sh:179), `reopened` a closed issue re-entering the queue.
Dropping them tripped #199's must-fail. Narrow to
`[opened, closed, edited, reopened]`, dropping only the churn/validation
actions labeled/unlabeled/assigned/unassigned. Trigger tests now pin
edited/reopened present and the four dropped; labels.test.sh exact-list updated.

kimi (blocking): the "supersedes unreleased #144" prose was false — #144's
edited/reopened shipped in 0.3.0. Dissolved: we now keep them. CONSUMERS prose
rewritten to the real version history (0.2.0 #32 / 0.3.0 #144 / #199 narrows),
and the #137 review-request line corrected from "unreleased" to shipped-in-0.3.0.

kimi (non-blocking): reusable labels.yml comment no longer cites */15.

codex-2 (AC1 after-measurement / closing) escalated to triage on #199 — held,
not guessed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 19:04:27 +00:00
claude-bot-andresmgsl
12887cc9de docs: narrow CONSUMERS stub issues triggers, relax cron to hourly (#199)
Bring the published caller stub to the #199 shape in lockstep with
self-labels.yml (preserving the stub<->caller parity #144 established):
hourly cron, issues: [opened, closed], per-trigger why-comments. Rewrite
the adoption prose — 0.2.0 shipped the broad set; #199 narrows it at its
pin bump and supersedes the unreleased edited/reopened additions (#144).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 18:13:15 +00:00
claude-bot-andresmgsl
be666ebed6 feat: ceremony flips to grouped — changelog.d/shape = grouped, five fragments converted, docs per D6
167/175 gain '### Added', 173/178 '### Changed', 180 '### Fixed' — every
bullet byte-identical, headings only (the #158 bar, inverted). CONSUMERS.md
names the sentinel and the flip procedure; changelog.d/README.md names the
sentinel. 182.md is this PR's own fragment, grouped atop the sentinel it
ships.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 13:14:05 +00:00
codex-bot-andresmgsl
eae000bd62 docs: add actions read to private caller guidance 2026-07-24 22:57:22 +00:00
claude-bot-andresmgsl
0b77d4b860 fix: the CONSUMERS.md stub's issues: types match the caller's, parity-tested
The stub published [opened, labeled, unlabeled, assigned, unassigned,
closed] while ceremony's own caller listens on eight types — PR #32's
70db91f widened the caller by edited and reopened and the stub never
followed. Both are load-bearing: an edited body rewrites the Blocked-by
declaration the reconcile sweep parses, and a reopened issue re-enters
the queue wearing labels derived at close (#144).

The stub's list is now byte-identical to the caller's, a parity row in
test/labels.test.sh keeps it that way (red on a dropped type, a drift,
or a reorder in one file only), and one adoption note names the tag the
widened list rides in on. The caller does not narrow.

Closes #144

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 13:43:35 +00:00
Daniel Marin
6a16a30bab
Merge pull request #143 from claude-bot-andresmgsl/build/137-review-request-wake
fix: review_requested wakes the labels sweep — blocker:unrequested clears when the ask lands
2026-07-24 14:33:11 +01:00
Daniel Marin
ad5c175d0c
Merge pull request #133 from claude-bot-andresmgsl/build/130-labels-scope-clobber
fix: labels/scope writes additively — a label applied mid-job survives
2026-07-24 14:14:03 +01:00
claude-bot-andresmgsl
48a3052934 docs: CONSUMERS release-state notes say 0.2.0 shipped the issues: block (#137 D6)
The three sites called ceremony#32 machinery unreleased after 0.2.0
(tagged 2026-07-24) became the first tag carrying it: the in-stub comment
above the issues: block, the issues: adoption paragraph, and the
triage-actors= paragraph. All three now state availability at 0.2.0 and
later; the 0.1.0-omission guidance and the parse-failure sentence stay —
still true. No type list moves (the caller/stub issues: subset drift is
#144, not this PR).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 13:13:31 +00:00
claude-bot-andresmgsl
c0e796b6c9 fix: review_requested wakes the sweep — blocker:unrequested clears when the ask lands
The reconciler's rule was right and blind: the caller never listened on
review_requested/review_request_removed, so the one event that falsifies
(or restores) blocker:unrequested could not clear it, and a quiet repo
wore the red flag until the advisory cron (#137's timeline: 93 seconds,
cleared only by an unrelated PR's push).

- self-labels.yml + the CONSUMERS.md stub gain both types; the scope job
  skips them (no paths change; running labeler there widens #130's window)
- test/labels.test.sh: caller/stub parity row with mutation cases —
  dropped type either side, one-sided reorder, all red
- CONSUMERS.md no longer claims trigger adoption is a bare pin bump; the
  pending stub edit is named and rides the first tag carrying ceremony#137

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 12:50:09 +00:00
codex-bot-andresmgsl
3792d52b82 docs: exempt release PRs from changelog fragments 2026-07-24 12:41:46 +00:00
claude-bot-andresmgsl
d0b857eb10 docs: the additive-scope contract in CONSUMERS/LABELS; changelog fragment
Part of #130.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 11:57:10 +00:00
claude-bot-andresmgsl
566712c690 docs: CONSUMERS and drills describe fragment-mode adoption
Bootstrap arms with a preamble plus changelog.d/, the guard list gains
changelog-assembled, the conversion checklist gains the fragment
conversion, the changelog rule is fragment-first with the legacy floor
kept for unconverted pins, and the assembly command block gives a reader
everything needed to produce a section (#112 D12, #117).
2026-07-24 11:11:23 +00:00
codex-bot-andresmgsl
22f1a0246f docs: explain core taxonomy bootstrap maintenance 2026-07-24 09:24:40 +00:00
codex-bot-andresmgsl
8ad68192e9 docs: seed grouped changelog re-arms 2026-07-23 23:45:04 +00:00
codex-bot-andresmgsl
2c57216a56 fix: surface wholly blind label sweeps 2026-07-23 23:12:30 +00:00
codex-bot-andresmgsl
0d74c827e7 docs: make consumer labels tag-aware 2026-07-23 16:09:42 +00:00
codex-bot-andresmgsl
162ce6b817 docs: count every consumer workflow caller 2026-07-23 15:34:01 +00:00
codex-bot-andresmgsl
3e96d80389 docs: make consumer guards tag-aware 2026-07-23 15:20:29 +00:00
claude-bot-andresmgsl
9ff049ae45 docs(labels): the ruling sweep behaviors in LABELS.md, CONSUMERS.md, CHANGELOG
LABELS.md's needs-ruling paragraph gains the bare-flag check and the
markerless 7-day nudge; CONSUMERS.md names them in the labels job and
states the caller stub is unchanged since #18 (a pin bump is the whole
upgrade); one CHANGELOG line under Unreleased (#52).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 12:25:24 +00:00
claude-bot-andresmgsl
44d0a79547 feat(guards): wire runner-isolated — self-guards step, consumer entry, changelog (#58) 2026-07-23 12:04:11 +00:00
codex-bot-andresmgsl
43092576ef fix: harden issueflow reconciliation edges 2026-07-23 10:49:36 +00:00
codex-bot-andresmgsl
8174080c9d feat: reconcile the issue work queue 2026-07-23 10:31:15 +00:00
claude-bot-andresmgsl
bd7670703a docs: CONSUMERS.md carries rig's conversion lessons — labels.conf takes no comments, machinery test files go whole, stale doc pointers swept (#13)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 00:34:26 +00:00
claude-bot-andresmgsl
55d0384c22 docs: pin bumps update every ceremony reference; decide table is six rows
Round 1 (PR #48): codex-bot flagged the release-only bump described as a
one-line uses change while the same-tag rule two bullets up requires every
reference on one tag — a release-only setup has four (release caller +
three guards), so a one-line bump splits the consumer across versions.
The bump bullet and the pin-bump procedure now both require every ceremony
uses: reference updated together. Also the README called lib/decide.sh a
5-state table; the spec comment and rendered table have six rows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 23:46:31 +00:00
claude-bot-andresmgsl
79261aa793 docs: CONSUMERS.md — prerequisites, bootstrap and convert checklists, pinning, changelog rule, team-flow adoption (#12)
Extends the existing release-workflow / artifact-hook / labels sections
(from #27 and #39, kept intact) with the remaining adoption guide: the
greenfield bootstrap path, the box/rig/cast conversion checklist, the
exact-tag pinning policy, the portable changelog contributor rule, and
the agent-team-flow adoption checklist with the pin-bump procedure
(docs-sync documented from #19's contract).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 23:46:31 +00:00
claude-bot-andresmgsl
77f195a6ae ci: docs-sync-exercise job + CONSUMERS.md doctrine-mirror section
The fixture consumer is the workspace root (a uses: step cannot cd);
ceremony rides a subdirectory checkout serving as both the local action
ref and the --source override. CONSUMERS.md gains the wiring, bootstrap,
and pin-bump procedure (#12's section, amended in the same cycle).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 21:42:01 +00:00
claude-bot-andresmgsl
ad8ebfe2c9 feat: the reusable release workflow — both doors, one implementation
Closes #9. .github/workflows/release.yml (workflow_call) replaces box's,
rig's and cast's release.yml: the merge door (facts -> decide -> notes ->
tag+publish+bump, every decision in a tested lib script) and the tag door
(the manual fallback and backfill, no bump). Plus lib/facts.sh (the merge
door's impure half, contract-tested against fixture repos with a stubbed
gh), the self-ref pin guard (.github/scripts/self-ref-check.sh + CI step +
tests), the release-exercise scratch caller (dry wiring), the end-to-end
script-chain rehearsal, and the caller + artifact-hook contracts in
docs/CONSUMERS.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 19:55:39 +00:00