docs: clarify chore: vs feat: for internal-infrastructure commits #14

Closed
opened 2026-06-24 19:00:46 +02:00 by quartermaster · 1 comment

Why

Today's v0.2.1 dogfood cut hit a bump-escalation: cut as v0.3.0 instead of v0.2.1 because PR #6's commit subject was feat(workflows): toolkit's own consumer workflows for v0.2.1+ dogfood. The feat: type triggered MINOR bump.

But the dogfood workflows are INTERNAL substrate — from an external-consumer POV (cellblock, tmux-tell, future projects), nothing changed. The 4 reusable workflows (_release-prep.yml etc.) existed since v0.1.0; PR #6 only added the toolkit's OWN consumer-shape wrappers that fire on the toolkit's own pushes. External consumers don't reference them.

The right commit type would have been chore: (or refactor: if framed as internal-cleanup-of-bootstrap-state). The toolkit's cc_bump_level_from_subject correctly handled feat: as minor; the human gap was the type choice.

Failure mode

Today: cut produced v0.3.0 prematurely. Recovery: closed prep PR + operator re-dispatched with bump_override: patch. Worked, but the recovery is operator-friction that documentation can save.

Proposed addition to docs/conventions.md

A new subsection under "Conventional commits" titled something like "When to use chore: for internal-infrastructure changes":

Use chore: (not feat:) for:

  • Internal infrastructure that doesn't change the consumer-facing surface (the toolkit's own dogfood workflows, internal scripts, build/test plumbing)
  • Bootstrap state cleanup that wires the toolkit to operate on its own substrate
  • Repository hygiene (README updates, internal docs, infrastructure refactoring)

Use feat: only when:

  • A new user-facing surface lands (new config option, new reusable workflow, new script flag)
  • An existing consumer would observe new behavior on next pin-bump

Test: "Would a consumer pinning to this version observe ANY new capability or behavior change?" If no → chore:. If yes → feat:.

Optionally fold into an ADR documenting the decision shape with the worked instance.

Disposition lean

(A) Single section addition to docs/conventions.md — small scope, ships in next patch or minor cut.

Cross-tracker

  • Worked instance: today's v0.2.1 cut escalated to v0.3.0 unexpectedly (closed prep PR + re-dispatched)
  • Sibling: release-toolkit#9 + #10 (other fail-loud-when-environment-mismatch fixes that shipped in v0.2.1)

— QM, 2026-06-24, surfaced from v0.2.1 dogfood cut escalation.

## Why Today's v0.2.1 dogfood cut hit a bump-escalation: cut as v0.3.0 instead of v0.2.1 because PR #6's commit subject was `feat(workflows): toolkit's own consumer workflows for v0.2.1+ dogfood`. The `feat:` type triggered MINOR bump. But the dogfood workflows are INTERNAL substrate — from an external-consumer POV (cellblock, tmux-tell, future projects), nothing changed. The 4 reusable workflows (`_release-prep.yml` etc.) existed since v0.1.0; PR #6 only added the toolkit's OWN consumer-shape wrappers that fire on the toolkit's own pushes. External consumers don't reference them. The right commit type would have been `chore:` (or `refactor:` if framed as internal-cleanup-of-bootstrap-state). The toolkit's `cc_bump_level_from_subject` correctly handled `feat:` as minor; the human gap was the type choice. ## Failure mode Today: cut produced v0.3.0 prematurely. Recovery: closed prep PR + operator re-dispatched with `bump_override: patch`. Worked, but the recovery is operator-friction that documentation can save. ## Proposed addition to `docs/conventions.md` A new subsection under "Conventional commits" titled something like "When to use `chore:` for internal-infrastructure changes": > Use `chore:` (not `feat:`) for: > - **Internal infrastructure** that doesn't change the consumer-facing surface (the toolkit's own dogfood workflows, internal scripts, build/test plumbing) > - **Bootstrap state cleanup** that wires the toolkit to operate on its own substrate > - **Repository hygiene** (README updates, internal docs, infrastructure refactoring) > > Use `feat:` only when: > - A new user-facing surface lands (new config option, new reusable workflow, new script flag) > - An existing consumer would observe new behavior on next pin-bump > > Test: "Would a consumer pinning to this version observe ANY new capability or behavior change?" If no → `chore:`. If yes → `feat:`. Optionally fold into an ADR documenting the decision shape with the worked instance. ## Disposition lean (A) Single section addition to `docs/conventions.md` — small scope, ships in next patch or minor cut. ## Cross-tracker - Worked instance: today's v0.2.1 cut escalated to v0.3.0 unexpectedly (closed prep PR + re-dispatched) - Sibling: release-toolkit#9 + #10 (other fail-loud-when-environment-mismatch fixes that shipped in v0.2.1) — QM, 2026-06-24, surfaced from v0.2.1 dogfood cut escalation.
Author
Owner

AC tick (pre-merge bookkeeping, post-merge catchup)

Shipped via PR #27 (commit 208eba4) + corrected via PR #32 (commit 533ab44) for the fragment-kind mismatch surfaced in the same slice.

Disposition (A) ACs

  • New ### Choosing chore: vs feat: for internal-infrastructure changes subsection added to docs/conventions.md under "Conventional commits" — landed in 208eba4
  • Consumer-facing-surface test stated as the discriminator ("Would a consumer pinning to this version observe ANY new capability or behavior change on their next pin-bump?")
  • Worked-instance reference included (v0.2.1 cut-escalation from PR #6 feat(workflows): → unintended v0.3.0 bump)
  • refactor: as the right alternative named for substantial internal restructuring (emits as ### Internal, no bump)

Deferred-conditional (surfaced post-merge, follow-up tracked)

  • Discipline-sibling for fragment-kind: the test applies to BOTH commit-subjects AND fragment-kind naming. I violated the fragment-kind sibling in the SAME slice (named slice 2's fragment .added.md → bump-escalation to v0.4.0; recovered via PR #32.internal.md). Tracked as #34 for the "state test once, map onto both surfaces" docs restructure per Surveyor 85cc framing.
  • Adopter-friendly worked-instance: current text cites internal PR #6 / #14 refs that external adopters can't follow. Tracked as #30; will fold into #34's restructure since both touch the same subsection.
  • Observability-not-discipline prevention: fragment-kind vs change-type lint as the next layer of defense per Surveyor 85cc. Tracked as #35; v0.4.x-class candidate.

Cross-tracker confirmation

  • Original sibling: #9 + #10 — both shipped in v0.2.1 ✓
  • This issue's worked instance (v0.2.1 cut → v0.3.0 escalation): the PR #32 hot-recovery validates the discipline operates as designed (the discipline caught its own author in the same session — load-bearing not just existing).

Closed via PR #27 merge. AC + deferred-conditional summary recorded.

— QM, 2026-06-24, v0.3.1 post-publish AC-tick pass.

## AC tick (pre-merge bookkeeping, post-merge catchup) Shipped via PR #27 (commit 208eba4) + corrected via PR #32 (commit 533ab44) for the fragment-kind mismatch surfaced in the same slice. ### Disposition (A) ACs - [x] **New `### Choosing chore: vs feat: for internal-infrastructure changes` subsection added to `docs/conventions.md`** under "Conventional commits" — landed in 208eba4 - [x] **Consumer-facing-surface test stated** as the discriminator (*"Would a consumer pinning to this version observe ANY new capability or behavior change on their next pin-bump?"*) - [x] **Worked-instance reference included** (v0.2.1 cut-escalation from PR #6 `feat(workflows):` → unintended v0.3.0 bump) - [x] **`refactor:` as the right alternative** named for substantial internal restructuring (emits as `### Internal`, no bump) ### Deferred-conditional (surfaced post-merge, follow-up tracked) - [x] *Discipline-sibling for fragment-kind:* the test applies to BOTH commit-subjects AND fragment-kind naming. I violated the fragment-kind sibling in the SAME slice (named slice 2's fragment `.added.md` → bump-escalation to v0.4.0; recovered via PR #32 → `.internal.md`). Tracked as **#34** for the "state test once, map onto both surfaces" docs restructure per Surveyor 85cc framing. - [x] *Adopter-friendly worked-instance:* current text cites internal PR #6 / #14 refs that external adopters can't follow. Tracked as **#30**; will fold into #34's restructure since both touch the same subsection. - [x] *Observability-not-discipline prevention:* fragment-kind vs change-type lint as the next layer of defense per Surveyor 85cc. Tracked as **#35**; v0.4.x-class candidate. ### Cross-tracker confirmation - Original sibling: #9 + #10 — both shipped in v0.2.1 ✓ - This issue's worked instance (v0.2.1 cut → v0.3.0 escalation): the PR #32 hot-recovery validates the discipline operates as designed (the discipline caught its own author in the same session — load-bearing not just existing). Closed via PR #27 merge. AC + deferred-conditional summary recorded. — QM, 2026-06-24, v0.3.1 post-publish AC-tick pass.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
frankenbit/release-toolkit#14
No description provided.