guard: enable the forge-client guard - tag the recoverable deletes, add the completeness test, flip the install on #780

Closed
opened 2026-10-15 23:34:20 +00:00 by hexajon · 2 comments
Owner

Follow-up to #660 (sequenced per the atomic-PR split). #660 lands the
forge-client guard plumbing - the Guard interface, the service adapter, the
path-to-template matcher, operation tagging on the write ops - but the
production InstallWriteGuard stays GATED OFF, and the per-handler out-of-scope
checks stay in place. So #660 enforces nothing new on its own.

This issue ENABLES it, in one coherent change:

  • Tag every recoverable-delete service method (about 64: label, milestone,
    comment, reaction, attachment, hook, deploy-key, release-asset, secret,
    variable, runner, team, package, push-mirror, and the org/user/admin
    variants) with its canonical Recoverable operation key, so the fail-closed
    client guard does not refuse a legitimate recoverable delete.
  • Add a source-level completeness test that fails the gate when any
    s.client.Delete* call site lacks a guard.WithOperation tag, so a new delete op
    without a tag can never be a silent production regression.
  • Flip the production install on (call InstallWriteGuard at startup).
  • Remove the per-handler guardOutOfScopeForgeWrite calls (tools_files.go,
    tools_branches_crud.go); the client now runs that rule on every surface.

Acceptance:

  • The 8 write ops from #660 (files create/update/delete/batch, apply_patch,
    sync_fork, merge_upstream, branch rename) refuse a default-branch write on CLI
    and MCP, now that the install is on.
  • An out-of-scope content write is refused at the client on every surface, with
    no per-handler check left.
  • Every recoverable delete still works (its operation tag is Recoverable); the
    completeness test proves none is untagged.
  • A delete that ADR 0029 omits is refused at the client.

This is what fulfils ADR 0046 "one guard on every surface" for the forge client.
Needs #660. Part of #670.

Follow-up to #660 (sequenced per the atomic-PR split). #660 lands the forge-client guard plumbing - the Guard interface, the service adapter, the path-to-template matcher, operation tagging on the write ops - but the production InstallWriteGuard stays GATED OFF, and the per-handler out-of-scope checks stay in place. So #660 enforces nothing new on its own. This issue ENABLES it, in one coherent change: - Tag every recoverable-delete service method (about 64: label, milestone, comment, reaction, attachment, hook, deploy-key, release-asset, secret, variable, runner, team, package, push-mirror, and the org/user/admin variants) with its canonical Recoverable operation key, so the fail-closed client guard does not refuse a legitimate recoverable delete. - Add a source-level completeness test that fails the gate when any s.client.Delete* call site lacks a guard.WithOperation tag, so a new delete op without a tag can never be a silent production regression. - Flip the production install on (call InstallWriteGuard at startup). - Remove the per-handler guardOutOfScopeForgeWrite calls (tools_files.go, tools_branches_crud.go); the client now runs that rule on every surface. Acceptance: - The 8 write ops from #660 (files create/update/delete/batch, apply_patch, sync_fork, merge_upstream, branch rename) refuse a default-branch write on CLI and MCP, now that the install is on. - An out-of-scope content write is refused at the client on every surface, with no per-handler check left. - Every recoverable delete still works (its operation tag is Recoverable); the completeness test proves none is untagged. - A delete that ADR 0029 omits is refused at the client. This is what fulfils ADR 0046 "one guard on every surface" for the forge client. Needs #660. Part of #670.
Author
Owner

Folded into #660. The forge-client guard enablement was already built, so I'm
landing it fully enabled in #660 as one PR rather than reverting and rebuilding
it here. #660 tags the recoverable deletes, adds the completeness test, refuses
the two gated unprovable destroys (packages/delete, admin/unadopted-delete) per
ADR 0046, and turns the install on - all in one change.

Folded into #660. The forge-client guard enablement was already built, so I'm landing it fully enabled in #660 as one PR rather than reverting and rebuilding it here. #660 tags the recoverable deletes, adds the completeness test, refuses the two gated unprovable destroys (packages/delete, admin/unadopted-delete) per ADR 0046, and turns the install on - all in one change.
Author
Owner

Folded into #660; see the note above.

Folded into #660; see the note above.
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#780
No description provided.