ceremony/lib
cluade-reviewer-andresmgsl a55fbaef15 fix(forge): forge_commit_at — Forgejo serves a single commit at /git/commits/{sha} (#209)
Found by the first post-merge sweep after the 0.6.0 merge — #198's own
acceptance probe — not by review. Three PRs in one run:

  labels: #208: could not read the head commit's date:
    forge_api: HTTP 404 from 'GET repos/heavy-duty/ceremony/commits/f3a1336…'
    — blocker:unrequested not judged this pass

Measured against this instance:

  forgejo  repos/{o}/{r}/commits/{sha}       -> 404
  forgejo  repos/{o}/{r}/git/commits/{sha}   -> 200, date under `.created`
  github   repos/{o}/{r}/commits/{sha}       -> 200, date nested

A fourth asymmetry, alongside the three lib/forge-forgejo.sh's header already
records. #198 ported this call site onto the shim with GitHub's path unchanged
— correct against GitHub, and the block it lives in (#236 D2) arrived WITH the
merge, so nothing here had ever executed it.

So it becomes a verb rather than a path at the call site: the caller wants one
timestamp and should not have to know either shape.

Cost while it stood was bounded and loud rather than silent — guarded_read
refused and the sweep said so — but blocker:unrequested could never be judged
on this forge.

The tests pin each backend's PATH and FIELD, because a stubbed forge_api cannot
catch a wrong path; that is exactly how this shipped and why it took a live
sweep to find. Swapping the paths reds the forgejo pair; swapping the fields
reds the github one.

test/run.sh 28/28 under jq 1.7 and jq 1.6; forge-backends 124/124; shellcheck
0.10.0 and actionlint clean.

Refs #209
2026-08-05 15:01:32 +00:00
..
attention.sh merge upstream 0.6.0 onto the forge tree, and port every gh call site it brought (#198) 2026-08-05 11:56:23 +00:00
changelog.sh fix(changelog): one fragment, one diagnosis, wherever the long entry sits 2026-08-04 12:38:13 +00:00
closes_references.sh feat(forge): replace both gh api graphql sites with REST + a body parser 2026-08-02 18:41:03 +00:00
decide.sh feat: lib/decide.sh — the merge door's decision, pure and exhaustively tested 2026-07-22 18:59:29 +00:00
facts.sh fix(forge): facts.sh must set REPO, and the fragment must fit the bound 2026-08-04 11:37:00 +00:00
forge-forgejo.sh fix(forge): forge_commit_at — Forgejo serves a single commit at /git/commits/{sha} (#209) 2026-08-05 15:01:32 +00:00
forge-github.sh fix(forge): forge_commit_at — Forgejo serves a single commit at /git/commits/{sha} (#209) 2026-08-05 15:01:32 +00:00
forge.sh fix(forge): an empty REPO cannot become a fact, and the backend verbs are tested 2026-08-04 11:53:28 +00:00
read.sh fix(issueflow): a per-issue pass commits its whole effect, or none of it 2026-08-03 18:55:52 +00:00
ruling.sh merge upstream 0.6.0 onto the forge tree, and port every gh call site it brought (#198) 2026-08-05 11:56:23 +00:00
version.sh feat: lib/version.sh — one version abstraction, two backends 2026-07-22 18:19:50 +00:00