feat(bus): copy credential lifecycle and revoke (CB4, #1873) #1954

Merged
jason.woltje merged 4 commits from org-cb4 into refactor 2026-11-12 22:43:00 +00:00
4 Commits
Author SHA1 Message Date
jason.woltje 95c2ce1435 fix(organization): CB4 re-check, project.remote.set refuses under a copy binding that still grants the project (#1873) 2026-11-12 16:16:24 -06:00
jason.woltje 2196d37a47 test(bus): CB4 tests for the slot parent check, the resume failure code and the CLI copy remote wiring (#1873) 2026-11-12 16:14:06 -06:00
jason.woltje ef1d3a4583 fix(bus): CB4 review round, fire revokes after the write, archive and delete revoke at Gitea (#1873)
Build review (changes 8) and security review (changes 4):
- P1-1: an owner-approved fire no longer writes the revoke before the
  apply (decision-stale). The fire stops the copy's runs, the fire is
  written, then the retire revoke starts for the fired instance.
- P2 (both): archive and delete from the CLI and the Console pass the
  organization's managed Gitea remote step (copyRemoteFor). A remote
  step that was not attempted or failed keeps the record revoking with
  failed remote, so the bus finishes it after restore; no done tombstone
  over a live token.
- Security P2-1: a bound server that cannot be read is a failed remote
  step, not not-managed. updateOrg refuses project-repo-bound when a
  project a copy binding grants loses or changes its remote or git.
- P3-1 (security): a delete whose organization file cannot be read says
  copiesUnreadable, never an empty copy list.
- P3-2 (security): the remote step requires the record's incarnation to
  equal the registry's live one.
- P3-5 (build): the archive's slot discard checks each parent directory
  (no symlink, own uid, private mode).
- P3-6 (build): resume keeps credential-revoke-failed as the gate code
  while a failed op runs again.
- P3-4 (build): a test pins the refused-begin reopen guard.
2026-11-12 16:08:08 -06:00
jason.woltje 90245765f2 feat(bus): copy revoke CB4, lifecycle events fence and revoke bound copies (#1873)
Every lifecycle event that ends a copy's authority (unbind, emergency
revoke, slot removal or expiry, role change, fire, collision, shadowing,
archive, delete and recreate) now closes admissions, drains in-flight
uses, stops runs with a confirmed ack, removes the slot and revokes the
Gitea token through the org admin slot. The binding moves through a
durable revoking state, so a restart resumes the same op and never
resurrects authority; an uncertain outcome stays fenced.
2026-11-12 16:08:07 -06:00