feat: Worker portal Stage 2 ADR — promote-PR mechanism
Description
Ratify the promote-PR mechanism as an ADR before any Stage 3 runtime code lands. This ADR defines the git-host integration surface, signing of generated PRs, rollback story, and the service/component that owns git-host API access. ADR-only — no runtime code.
The "promote live → baseline" mechanism converts a jurisdiction's live overrides into a real PR against the jurisdiction's TOML baseline. This is the most novel architectural commitment in Stage 3 and needs careful ratification.
Acceptance Criteria
-
docs/modules/ROOT/pages/adrs/adr-NNN-promote-pr-mechanism.adoc - ADR documents:
- Git-host integration surface: where does git-host API access live?
canopy-opsservice (new), inline in canopy-web, or a dedicatedcanopy-promotionservice — pick one with rationale - Supported git hosts: GitLab (primary), GitHub (later?), self-hosted Gitea (possibly)
- PR generation contract: diff format, commit author identity, signing strategy
- PR signing: GPG/EdDSA per project signing convention; how the service holds signing keys
- Rollback story: if a promote produces a bad TOML, how does the jurisdiction recover?
- Failure modes: git-host unreachable, auth expired, base branch moved, merge conflict
- Secrets: where does the git-host PAT live? (See ADR-017 for encrypted-secrets pattern)
- Git-host integration surface: where does git-host API access live?
- Antora nav updated
- Cross-referenced from worker-portal-redesign.adoc Design section
-
cargo xtask check-docsclean
Open questions (resolve in ADR)
- Service ownership: new
canopy-ops/canopy-promotionservice vs inline in canopy-web vs library used by canopy-web? (See #460 open question 1.) - PR signing identity: per-jurisdiction bot vs single canopy service identity?
- Branch naming convention for generated PRs:
studio-promote/{jurisdiction}/{date}or similar?
Context & References
- Tracking issue: #460
- Epic: &51
- Plan: worker-portal-redesign.adoc, Stage 2
- Blocks: Stage 3 promote-live-to-baseline child issue
- Related: ADR-017 (encrypted secrets at rest), ADR-019 (service identity)
Labels
type::feature, priority::medium, program::infrastructure, service::web, workflow::ready