adr: recoverable-guard tier - refuse wrong-workflow acts by default, per-call --allow-<state> override #222

Closed
opened 2026-07-17 17:16:38 +00:00 by hexajon · 0 comments
hexajon commented 2026-07-17 17:16:38 +00:00 (Migrated from codeberg.org)

Companion tier to the strict-omission model (docs/adr/0029): today's local-main incident showed a class of act that is recoverable-but-wrong - a commit landing directly on the default branch destroys nothing (a user can branch it off and reset), but it is almost always workflow wreckage, and remote branch protection catches it too late (at push, after work stacks on the wrong base) or not at all (unprotected repos).

Write the ADR pinning the tier:

  • Unrecoverable acts: omitted from every surface (existing 0029 rule, unchanged).
  • Recoverable-but-wrong-workflow acts: REFUSED by default at the service seam (both surfaces inherit, per the dual-surface layering ADR), overridable only by a per-call, transcript-visible param - never sticky config. The no-opt-out ADR already deleted a madtea.allow-default-commit config key for hooks; this ADR records why per-call explicitness is the acceptable escape shape where sticky config is not: an override that must be typed into every call converts a silent accident into a deliberate, reviewable act, and cannot be pre-armed ambiently.
  • Naming family: every recoverable-tier override is --allow- (CLI) / allow_<refused_state>= (MCP), naming the state being tolerated (the cargo --allow-dirty shape). Never bare --force, never a --yes-* (that family answers consent prompts, not refusals).
  • Structural carve-outs stay structural (the empty-repo initial commit, keyed on the absence of HEAD).
  • First members: the default-branch commit guard and the ahead-of-origin alarm (filed separately, depend on this).
  • Amendment note on the finish-refuses-default ADR: commit joins finish, completing the branch-commit-finish loop as the only madtea-shaped path onto the default branch.
  • Refusal text per the terminal-forwarding rules: name the sanctioned next step first (branch creation), the override second; plain language, no ADR numbers in the runtime strings.

Acceptance criteria: ADR file in docs/adr (next free number), house format, cross-references 0006/0009/0014/0026/0029 by their decisions; amendment line added to 0006; docs/adr/README.md indexed.

Companion tier to the strict-omission model (docs/adr/0029): today's local-main incident showed a class of act that is recoverable-but-wrong - a commit landing directly on the default branch destroys nothing (a user can branch it off and reset), but it is almost always workflow wreckage, and remote branch protection catches it too late (at push, after work stacks on the wrong base) or not at all (unprotected repos). Write the ADR pinning the tier: - Unrecoverable acts: omitted from every surface (existing 0029 rule, unchanged). - Recoverable-but-wrong-workflow acts: REFUSED by default at the service seam (both surfaces inherit, per the dual-surface layering ADR), overridable only by a per-call, transcript-visible param - never sticky config. The no-opt-out ADR already deleted a madtea.allow-default-commit config key for hooks; this ADR records why per-call explicitness is the acceptable escape shape where sticky config is not: an override that must be typed into every call converts a silent accident into a deliberate, reviewable act, and cannot be pre-armed ambiently. - Naming family: every recoverable-tier override is --allow-<refused-state> (CLI) / allow_<refused_state>= (MCP), naming the state being tolerated (the cargo --allow-dirty shape). Never bare --force, never a --yes-* (that family answers consent prompts, not refusals). - Structural carve-outs stay structural (the empty-repo initial commit, keyed on the absence of HEAD). - First members: the default-branch commit guard and the ahead-of-origin alarm (filed separately, depend on this). - Amendment note on the finish-refuses-default ADR: commit joins finish, completing the branch-commit-finish loop as the only madtea-shaped path onto the default branch. - Refusal text per the terminal-forwarding rules: name the sanctioned next step first (branch creation), the override second; plain language, no ADR numbers in the runtime strings. Acceptance criteria: ADR file in docs/adr (next free number), house format, cross-references 0006/0009/0014/0026/0029 by their decisions; amendment line added to 0006; docs/adr/README.md indexed.
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
sixfold-space/madtea#222
No description provided.