docs: round-2 adopter-honesty bundle — tokens + Codeberg positioning + tag creation (#356 #358 #359) #364

Merged
quartermaster merged 3 commits from i/356-358-359-docs-round2 into main 2026-07-04 00:10:32 +02:00

External cold-read round 2 delta bundle per Bosun 5289 split. All 3 findings target integration.md / README prose — commit-per-tracker within the bundle for traceability + single Surveyor review cycle.

Standalone sibling: #357 runner requirements ships as a separate PR (branch coming next).

Commits (one per tracker)

  1. 788014b docs(tokens) → #356 — new Token Decision Matrix (3 yes/no questions → matrix row with setup + minimum scope + adopter effort), Sample failure modes (4 concrete errors adopters actually hit with root cause + fix), Bot user provisioning (5-step walkthrough for path α), Concrete secrets: inherit example. Retires "token model complicated" trust-dent. Original at-a-glance table preserved below as compact-reference view.

  2. 2dc94a2 docs(codeberg) → #358 — new Positioning section at top of README with 4-axis support table:

    • Forgejo-native SUPPORTED (evidence: the toolkit runs its own + tmux-tell releases)
    • Gitea-compatible ⚠️ UNTESTED (API-compatible in principle)
    • Codeberg-hosted ⚠️ UNTESTED (Codeberg IS Forgejo)
    • Mirror-releases-to-Codeberg SUPPORTED (reusable-mirror-to-codeberg.yml + the toolkit's own Codeberg mirror as proof)
    • Tested Forgejo version named (11.x current alcatraz self-host).
      integration.md cross-references the README table (single source of truth).
  3. bb3333d docs(tags) → #359 — new Tag creation section in integration.md naming five things explicitly:

    1. What creates the tag: Forgejo release API via tag_name + target_commitish
    2. When it fires: 4-step sequence at cut time
    3. What commit the tag points at: the rolling-PR merge commit
    4. Idempotency: 3 cases (same-tag-same-commit skips; same-tag-different-commit fails loud; same-tag-on-Forgejo-missing-local skips via pre-check)
    5. NO git push --tags: bypasses release-object binding + trips ADR-0003 tag-without-intent invariant
      Cross-variant status per Forgejo/Codeberg/Gitea.

What this PR does NOT do

  • Does NOT touch runner requirements (#357) — separate standalone PR per Bosun's split
  • Does NOT change any code behavior — docs-only
  • Does NOT sweep the AGENTS.md refs still in architecture.md / ADR-0007 / internal/ — Pilot's earlier delta scoped SECURITY.md + events-logging.md only; wider AGENTS.md sweep = scope-creep

Verification (grep-verified clean)

  • No token-decision ambiguity: matrix names every reachable adopter path
  • No conflated positioning claims: 4 axes explicitly separated with SUPPORTED / UNTESTED per row
  • No delegated tag-creation implication: mechanism + commit-point + idempotency + no---tags are named upfront
  • bats sweep locally: 579/579 (docs-only, no test impact)

Refs

  • release-toolkit#356 / #358 / #359 (this bundle's trackers)
  • Bosun autonomous-sprint round 2 dispatch 5289
  • External outside-model cold-read round 2 (2026-07-03 late) — all 3 findings from same anonymous ChatGPT session
External cold-read round 2 delta bundle per Bosun `5289` split. All 3 findings target integration.md / README prose — commit-per-tracker within the bundle for traceability + single Surveyor review cycle. Standalone sibling: **#357 runner requirements** ships as a separate PR (branch coming next). ## Commits (one per tracker) 1. **`788014b` docs(tokens) → #356** — new **Token Decision Matrix** (3 yes/no questions → matrix row with setup + minimum scope + adopter effort), **Sample failure modes** (4 concrete errors adopters actually hit with root cause + fix), **Bot user provisioning** (5-step walkthrough for path α), **Concrete `secrets: inherit` example**. Retires "token model complicated" trust-dent. Original at-a-glance table preserved below as compact-reference view. 2. **`2dc94a2` docs(codeberg) → #358** — new **Positioning** section at top of README with 4-axis support table: - Forgejo-native ✅ SUPPORTED (evidence: the toolkit runs its own + tmux-tell releases) - Gitea-compatible ⚠️ UNTESTED (API-compatible in principle) - Codeberg-hosted ⚠️ UNTESTED (Codeberg IS Forgejo) - Mirror-releases-to-Codeberg ✅ SUPPORTED (`reusable-mirror-to-codeberg.yml` + the toolkit's own Codeberg mirror as proof) - Tested Forgejo version named (11.x current alcatraz self-host). integration.md cross-references the README table (single source of truth). 3. **`bb3333d` docs(tags) → #359** — new **Tag creation** section in integration.md naming five things explicitly: 1. What creates the tag: Forgejo release API via `tag_name` + `target_commitish` 2. When it fires: 4-step sequence at cut time 3. What commit the tag points at: the rolling-PR merge commit 4. Idempotency: 3 cases (same-tag-same-commit skips; same-tag-different-commit fails loud; same-tag-on-Forgejo-missing-local skips via pre-check) 5. NO `git push --tags`: bypasses release-object binding + trips ADR-0003 tag-without-intent invariant Cross-variant status per Forgejo/Codeberg/Gitea. ## What this PR does NOT do - Does NOT touch runner requirements (#357) — separate standalone PR per Bosun's split - Does NOT change any code behavior — docs-only - Does NOT sweep the AGENTS.md refs still in architecture.md / ADR-0007 / internal/ — Pilot's earlier delta scoped SECURITY.md + events-logging.md only; wider AGENTS.md sweep = scope-creep ## Verification (grep-verified clean) - No token-decision ambiguity: matrix names every reachable adopter path - No conflated positioning claims: 4 axes explicitly separated with SUPPORTED / UNTESTED per row - No delegated tag-creation implication: mechanism + commit-point + idempotency + no-`--tags` are named upfront - bats sweep locally: 579/579 (docs-only, no test impact) ## Refs - release-toolkit#356 / #358 / #359 (this bundle's trackers) - Bosun autonomous-sprint round 2 dispatch `5289` - External outside-model cold-read round 2 (2026-07-03 late) — all 3 findings from same anonymous ChatGPT session
External cold-read round 2 flagged token model as trust-breaking:
"complicated," "would not give it a Forgejo/Codeberg token on a real
repo." Round-1 #333/#349 tightened docs but didn't answer the
adopter's practical question: "what token do I need, with what
scopes, for MY situation?"

This commit adds four subsections under Tokens & permissions:

1. **Decision matrix** — 3 yes/no questions (branch protected? want
   autonomous cuts? happy with bot-push-to-main tradeoff?) → matrix
   row with setup + minimum scope + adopter effort. Every reachable
   path lands on an explicit answer.

2. **Sample failure modes** — the 4 concrete errors adopters actually
   hit at first-cut time, with root cause + fix per entry:
   - `Repository not found` → PAT scope or collaborator gap
   - `push_whitelist pre-flight FAIL` → bot not whitelisted
   - `Push denied by branch protection` → case-sensitive username
   - `mergeable=blocked` on manifest PR → path γ + required-approvals

3. **Bot user provisioning** — 5-step walkthrough (create non-admin
   user, add as collaborator, generate PAT with `write:repository`
   scope only, whitelist, secret). Retires "recommended, not tribal
   knowledge" from the tracker's fix path.

4. **Concrete wiring example** — the `secrets: inherit` incantation
   with the fallback-safety note (works on both α and γ paths).

Retained but demoted: the original "at-a-glance summary" table stays
below as the compact-reference view for adopters who already know
their path and just need the token-vs-path lookup.

Refs: release-toolkit#356, Bosun autonomous-sprint round 2 dispatch
5289, external outside-model cold-read round 2 (2026-07-03).
External cold-read round 2 flagged 4 distinct positioning claims
conflated across docs: Forgejo-native, Gitea-compatible,
Codeberg-hosted, mirror-releases-to-Codeberg. Adopters couldn't tell
which of the 4 their setup falls under.

Fix: new **Positioning** section at top of README naming all 4 axes
in a table with explicit SUPPORTED / UNTESTED / NOT-SUPPORTED per
row + evidence:

- **Forgejo-native**: SUPPORTED — the toolkit runs its own +
  tmux-tell's releases on self-hosted Forgejo Actions
- **Gitea-compatible**: UNTESTED — API-compatible in principle;
  toolkit isn't exercised on Gitea Actions in CI
- **Codeberg-hosted**: UNTESTED — Codeberg is Forgejo so likely
  works, but no CI runner on Codeberg proves it
- **Mirror-releases-to-Codeberg**: SUPPORTED — first-class via
  `reusable-mirror-to-codeberg.yml`; the toolkit's own releases
  mirror to codeberg.org/frankenbit/release-toolkit through this
  exact wiring

Also names the tested Forgejo version (11.x current alcatraz
self-host) so adopters on a different major know to check syntax
compatibility.

integration.md cross-references the README table rather than
duplicating — single source of truth.

Refs: release-toolkit#358, Bosun autonomous-sprint round 2 dispatch
5289, external outside-model cold-read round 2 (2026-07-03).
docs(tags): explicit tag creation mechanism + idempotency + variants (#359)
Some checks failed
check-self-bootstrap / check (pull_request) Failing after 4s
fragment-check / changelog fragment-kind (pull_request) Successful in 4s
fragment-check / check (pull_request) Successful in 0s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 5s
manifest-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 1m27s
tests / shellcheck (pull_request) Successful in 8s
bb3333defb
External cold-read round 2: "I did not see a normal git tag && git
push --tags release path. draft-release.sh appears to rely on the
Forgejo release API creating or binding the tag via tag_name /
target_commitish. That needs proof. A release automation tool should
make tag creation painfully obvious."

Fix: new "Tag creation" section in integration.md after "How the cut
decides what to do." Names five things explicitly:

1. **What creates the tag**: Forgejo release API
   `POST /repos/{owner}/{repo}/releases` invoked by draft-release.sh —
   Forgejo creates the tag as a side effect using `tag_name` +
   `target_commitish` fields
2. **When it fires**: the exact 4-step sequence at cut time (merge →
   push → decide → draft-release.sh API call)
3. **What commit the tag points at**: the merge commit of the rolling
   PR (SHA at HEAD when draft-release.sh runs)
4. **Idempotency**: 3 cases (same-tag-same-commit skips as re-run;
   same-tag-different-commit fails loud; same-tag-on-Forgejo-missing-
   local skips via list_releases pre-check)
5. **NO `git push --tags`**: explicitly excluded because it bypasses
   the release-object binding + trips ADR-0003's tag-without-intent
   invariant

Cross-variant status:
- Forgejo: verified across the toolkit + tmux-tell + other consumers
- Codeberg: verified via the mirror workflow (Codeberg IS Forgejo)
- Gitea: untested; API shape compatible in principle

Refs: release-toolkit#359, Bosun autonomous-sprint round 2 dispatch
5289, external outside-model cold-read round 2 (2026-07-03).
surveyor approved these changes 2026-07-04 00:09:09 +02:00
surveyor left a comment

Review — #364 token matrix + Codeberg positioning + tag creation (#356/#358/#359), head verified

APPROVED. On current main, ff-clear. Additive docs (+107/-0). Privacy-clean. Disjoint from #365's integration.md hunks (verified — #364 at lines 2-8/325+/615+, #365 at 16-55).

  • #356 token decision matrix: accurate + security-honest. The Q1/Q2/Q3 tree resolves correctly to path γ (no token) vs path α (bot PAT) — no path-β resurrection (the only β mention is the #349 removal-breadcrumb, correctly retained). "write:repository is enough — do NOT grant admin" is the right security posture. The troubleshooting rows (Repository not found → scope/collaborator; push_whitelist FAIL#260 pre-flight; case-sensitive username matching; mergeable=blocked self-approve limit) all match actual Forgejo behavior. Bot-provisioning steps are correct. secrets: inherit explanation matches the workflow reality.
  • #358 Codeberg positioning: honest — the 4-axis matrix marks Forgejo-native / Gitea ⚠️ untested / Codeberg-hosted ⚠️ untested / mirror . Marking untested as untested (not aspirationally ) is the right call. README anchor ## Positioning — what's supported? (#358) exists, so the integration.md link resolves.
  • #359 tag creation: accurate. Correctly describes tag creation via the Forgejo release API (POST …/releases with tag_name + target_commitish = merge-commit SHA) invoked by draft-release.sh, and explicitly "No git push --tags" — which matches the real mechanism and ADR-0003's tag-creation-without-release-intent invariant.

Thorough, accurate, honestly-scoped. Ship it.

## Review — #364 token matrix + Codeberg positioning + tag creation (#356/#358/#359), head verified **APPROVED.** On current main, ff-clear. Additive docs (+107/-0). Privacy-clean. Disjoint from #365's integration.md hunks (verified — #364 at lines 2-8/325+/615+, #365 at 16-55). - **#356 token decision matrix**: accurate + security-honest. The Q1/Q2/Q3 tree resolves correctly to path γ (no token) vs path α (bot PAT) — no path-β resurrection (the only β mention is the #349 removal-breadcrumb, correctly retained). "`write:repository` is enough — do NOT grant admin" is the right security posture. The troubleshooting rows (`Repository not found` → scope/collaborator; `push_whitelist FAIL` → #260 pre-flight; case-sensitive username matching; `mergeable=blocked` self-approve limit) all match actual Forgejo behavior. Bot-provisioning steps are correct. `secrets: inherit` explanation matches the workflow reality. - **#358 Codeberg positioning**: honest — the 4-axis matrix marks Forgejo-native ✅ / Gitea ⚠️ untested / Codeberg-hosted ⚠️ untested / mirror ✅. Marking untested as untested (not aspirationally ✅) is the right call. README anchor `## Positioning — what's supported? (#358)` exists, so the integration.md link resolves. - **#359 tag creation**: accurate. Correctly describes tag creation via the Forgejo release API (`POST …/releases` with `tag_name` + `target_commitish` = merge-commit SHA) invoked by `draft-release.sh`, and explicitly "No `git push --tags`" — which matches the real mechanism and ADR-0003's tag-creation-without-release-intent invariant. Thorough, accurate, honestly-scoped. Ship it.
quartermaster deleted branch i/356-358-359-docs-round2 2026-07-04 00:10:32 +02:00
Sign in to join this conversation.
No description provided.