# Party Governance and Project evolution in Beto Status: Proposed implementation plan, revised 21 October 2026. Target: `feat/beto-party-project-governance`. Foundation: `fix/workstation-env` at `89964c3a6`, merged into the target branch. Beto should establish canonical Party and Project records while Waldur remains the initial management interface. Themelio continues to use its working provider integrations while individual reads and actions move behind the Go API. Once Beto's management workflows are ready, one installation-wide cutover transfers Project creation, membership and invitations to Beto. The [identity and account boundaries](identity-model.md), [contract catalogue](contracts.md), [endpoint map](endpoint-map.md) and [draft OpenAPI](openapi/api.openapi.yaml) make the proposed boundaries reviewable. The [Party contracts](../../../../contracts/party_governance/messaging/README.md), [domain](../../contexts/party_governance/README.md) and [application](../../contexts/party_governance/application/README.md) are implemented with persistence, trusted queries and event publication. The [API-owned authentication runtime](../../../api/adaptors/authentication/README.md) and legacy auth adaptor are implemented behind explicit enrolment. The retained Themelio login/AUP flow remains the default; coordinated cutover requires qualification. The [v3 identity contract](../../../../contracts/authentication/README.md#identity-attribute-inventory-and-recovery) adds stable identity, the complete AAI profile, qualified Site association and contact events. Approved subject recovery preserves PartyId and disablement; operator-facing approvals follow later. The [Project source slice](../../contexts/project/README.md) now implements canonical state, queries/events and Project-owned Waldur acquisition. The [migration record](waldur-migration.md) tracks attribution and live qualification gates. Metallo wiring, native management, endpoint migration and fulfilment follow later. ## First-iteration outcome Retained Themelio remains the working product. Establish `party_governance` and `project` as persistent Beto contexts, make the Go API own login and sessions, then move selected Next.js API reads behind it. A legacy auth adaptor keeps retained handlers using the same session authority. Deliver canonical integration events and queries for Metallo; consumer wiring remains a separate slice. The [endpoint boundary](endpoint-map.md#first-iteration-boundary) selects the first reads and preserves repository, allocation, invitation and deployment flows. The [context and port diagram](metallo-integration.md#context-and-port-diagram) shows the boundary; its agreement records evidence and unresolved delivery gates. Metallo accesses Project through published owner queries or projections that its consuming contexts build from Project integration events. Each projection owns its storage, bootstrap, revision handling and freshness policy. Project policy and authoritative persistence stay in Beto. Waldur spans several capabilities. Each consuming context defines the ports it needs and owns their adaptors: identity proof, Project-access observation, account/access fulfilment and allocation reads have separate responsibilities. Project-related Waldur ports belong to Project; Party-related ports belong to their Beto identity/account owners. Metallo's Waldur ports serve other capabilities, such as resources and limits. Shared client code supplies technical mechanisms. One isolated Waldur integration process may implement several ports when they share a provider trust boundary. It contains a separate adaptor and closed interface for each capability. Project source acquisition remains a distinct Project adaptor, even if it is initially deployed beside Party adaptors. ### Why the coexistence direction was tightened The earlier wording protected the existing writer but left the compatibility boundary too broad. It allowed new provider decisions and staff credentials to accumulate in retained Next.js routes and the general onboarding worker. That would make the compatibility layer a temporary owner and make later migration depend on another rewrite. The qualified provider behaviour also requires stricter boundaries. Waldur's Identity Bridge selects an existing account by username and can update it during the call, so ownership must be checked from enrolled issuer/source provenance before that effect. Invitation acceptance needs the current verified Party contact and established Party-to-Waldur binding; a cached GitLab profile cannot authorise it. These findings refine the direction as follows: - retained routes may preserve their HTTP and UI shapes, but new behaviour enters through owner-defined application ports; - provider-specific account and invitation adaptors expose separate typed operations inside an isolated Waldur integration process; - the selected account and invitation paths reach the Waldur staff credential only inside that process; callers receive scoped capabilities and provider-neutral outcomes; - the general compatibility worker coordinates durable onboarding work and the Party binding hand-off without implementing Waldur API decisions; - legacy implementations that are still outside the selected slice remain in place until their replacement passes parity and qualification. The provenance preflight blocks an account that already belongs to another source. Identity Bridge offers no atomic expected-provenance condition, so a concurrent foreign creation between that read and the bridge call can still be updated before the adaptor reports a conflict. API-auth activation remains gated on a provider guarantee, a conditional provider operation or qualification that eliminates this race. Legacy mode remains the deployment default meanwhile. Phases 1–3 form this iteration, delivered through slices A–C below. The full [issue 164](https://github.com/pharos-ai-factory/pharos-platform/issues/164) journey also requires later native management and downstream revocation qualification. Keep native creation, invitation replacement, canonical AUP acceptance and the wider architecture-reset model in later phases. ## Ownership | Concern | Initial arrangement | Destination | | --- | --- | --- | | Authentication | Implemented baseline: retained NextAuth supplies signed assertions. First-iteration cutover: Go API owns OIDC/sessions; the legacy auth adaptor validates through it. | Party Governance remains the authority for canonical identity and eligibility; remaining clients migrate gradually. | | Party identity and authentication lifecycle | Beto owns `PartyId`, exact issuer/subject bindings, status and `authVersion`. | Same ownership, with recovery, security signals and platform grants. | | Project and membership | Waldur supplies management decisions through Project-owned ports and adaptors in Beto. Project owns canonical records, source reconciliation and member resolution. | Beto accepts native management commands; Project fulfilment supplies required downstream representations. | | Invitations | Waldur remains the authoritative invitation store. Party Governance owns the authenticated claim decision and invokes a narrow external-invitation port using current verified recipient evidence and the established Waldur binding. Project observes the resulting membership through its source port. | Party Governance owns native invitation intent and claim; Project owns the resulting membership. | | Provider access | Retain each working writer behind owner-defined application ports. Explicit bindings and retryable fulfilment preserve the GitLab layout consumed by Themelio. Qualify replacements per operation with one writer per target. | Context-owned ports support replacements and later provider choices. | | Orders, allocations, quotas and execution | Existing Waldur and Themelio workflows remain operational. | Their owning contexts evolve separately; Project references their published facts. | Keycloak authenticates the person behind an exact issuer/subject pair. Party Governance determines the platform identity and its eligibility; Project decides Project permissions. AAI organisation attributes, groups and realm roles remain identity evidence until an explicit domain rule gives them meaning. They do not automatically create Organisation membership or Project authority. `party_governance` and `project` are separate contexts within Beto. Signup-time provider setup remains durable compatibility work, but it invokes narrow provider-association ports and hands qualified proof to Party Governance. Project owns its provider representation/access port and required user prerequisites. This slice introduces no Account Provisioning context. Each persisted context has a separate logical database, restricted runtime role and migration history. Domain and application code use owner ports. API business traffic uses typed Protobuf over RabbitMQ; Beto's HTTP surface remains operational. This follows [decision 0046](../../../../docs/decisions/0046-service-communication-and-composition.md). Start with these aggregate boundaries: - `PartyAuthentication`, keyed by `PartyId`: current authentication binding, retired history, platform access state, `authVersion` and pending recovery. - `PartyProviderBinding`: an independently versioned identity record associating a verified external account with a Party. Provider effects have separate progress. - `Project`, keyed by `ProjectId`: name, lifecycle, child memberships and role assignments. Provider identifiers remain opaque bindings. Initial roles are `project-administrator` and `developer`. - `ProjectFulfilment`, if introduced, is keyed by `ProjectId` and records Beto's delegation/readiness view. It does not own GitLab bindings, provider calls or retry work. Source Control owns those effects and reports a redacted result through a future explicit contract. - Later, `Invitation` and `PolicyAcceptance` roots in Party Governance. Platform access grants can be introduced when their clients are migrated. Use `Party` consistently for the person's stable identity in domain contracts. `PartyAuthentication` describes that Party's authentication state and recovery. Latest identity attributes received from the trusted AAI live in a separate Party Governance projection with provenance and its own revision. The [identity model](identity-model.md) defines these concepts, access versus external identity states, provider lifecycle ownership and event versioning. Every command changes one root. State, version, receipt, recorded outcome and outgoing intents commit atomically. Cross-root steps use durable hand-offs, even when both contexts run in the same Beto process. Current-state persistence is sufficient; an event-sourced model adds no requirement to this transition. ## A Project created in Waldur After the first delivery milestone, the sequence is concrete: 1. An authorised user creates the Project and assigns its manager in Waldur. 2. Beto's Project-owned adaptor reads complete source state. Project allocates a canonical ProjectId and records the binding. Notifications and periodic reconciliation request fresh reads through the same owner ports. 3. Verified provider accounts resolve to PartyIds. A manager who has not yet signed in remains an unresolved source member; their first verified login establishes the binding and triggers another resolution attempt. 4. Project records canonical membership and publishes integration facts for Source Control. Beto does not perform the delegated GitLab effect. The Project can appear with pending readiness before GitLab access is ready. 5. Source Control ensures the GitLab groups and permissions that retained Themelio expects. Its projection exposes pending/applied/failed work. A future Beto fulfilment view may consume a redacted result without becoming a writer. 6. Invitations continue through Waldur. Acceptance, role changes and removal follow the same observation and fulfilment path. Waldur creation therefore needs no synchronous callback into Beto. Missed notifications delay discovery until reconciliation; provider failure leaves a visible pending or attention state with retry. The Project keeps this same canonical identity when native Beto management takes over. ## Phase 0 Contracts and provider qualification Agree the catalogue and API shapes, then qualify the narrow provider operations needed for the first complete workflow. These are implementation entry checks: 1. Qualify the Go API's enrolled OIDC client, exact issuer/subject, verified claims, `auth_time` and callback replay protection. Prove shared session validation across both endpoint families, including limited onboarding and legacy AUP. 2. Adapt the Metallo branch's qualified source acquisition behind Project-owned ports. Agree the worker/credential ownership change before activation. Add complete-refresh status and lifecycle proof; the reviewed observation v1 supplies neither deletion proof nor the last successful unchanged read. 3. Qualify Waldur/GitLab identity association. Native Waldur OIDC and the old identity bridge use different identity sources. GitLab's configured OIDC provider name also differs from the legacy bootstrap constant. An email match is insufficient evidence to join accounts or overwrite a foreign identity. 4. Record the GitLab namespace layout and permissions used by repository pickers, repository creation, project details and deployment setup. Preserve those provider paths while introducing canonical IDs. 5. Agree the canonical events and owner queries consumed by Metallo, its receiving contexts and their projections. Record the current writer and proposed owner for each account/group/access operation. Qualify PR 706 with the retained writer and the selected Waldur release before relying on its identity mapping. Use existing compatibility implementations temporarily where necessary. New provider behaviour must sit behind an owner-defined port rather than becoming a new decision in a retained route. Privileged provider credentials for each migrated operation stay in a provider-specific integration process with capability-specific adaptors and credentials. They do not enter Beto, the Go API or the general compatibility worker. Retained Next.js keeps its existing credentials only for operations that have not migrated. Each replacement has a separately reviewed deployment scope. **Exit:** source evidence is pinned, the identity gaps and extensions have named owners, and receiving contracts, permissions and writer boundaries are agreed. Real provider fixtures qualify any newly relied-on operation. This work can proceed alongside Phase 1; the earlier producer evidence does not qualify Beto. ## Phase 1 Canonical Party identity and API-owned authentication Register `party_governance`, its database and broker permissions. Implement `ResolveOrRegisterParty`, `GetCurrentParty` and `CheckPartyAuthentication`. The exact enrolled `(issuer, subject)` resolves one stable Party. Update the AAI attribute projection through durable private delivery and store verified provider associations through independent binding records. Never create a Party from an invitation email, Waldur username or unverified HTTP header. Move OIDC start/callback, browser sessions and logout to the Go API. The legacy auth adaptor validates through this authority and supplies the existing user shape and server-side credentials to retained routes. Replace the API's legacy session dependency with an independent policy-only read before that cutover. Keep legacy AUP reads/writes until Phase 4. The [authentication transition](authentication-transition.md) defines limited onboarding sessions, resumable provider setup, shared gates, logout fencing and the first-signup flow. No auth failure falls back to legacy login. Every protected request and realtime reconnect validates current eligibility and authVersion; privileged owner commands recheck authority. Normal business routes also enforce current AUP and relevant provider readiness. Audit Next.js middleware, server actions, layouts and credential helpers as well as API routes. Establish trusted query actors; browser PartyIds and `PRIVATE-TOKEN` supply no Beto identity. Use a durable provider-binding observation workflow to associate verified Parties with existing GitLab/Waldur accounts. Keep unmatched accounts pending and visible to operators. Identity uniqueness and binding ownership must survive concurrent login and retry. Basic disablement should fence platform sessions from this phase; provider access removal has its own recorded delivery status. An email/name refresh changes the attribute projection's revision; provider binding and provisioning commands use their own root versions. These updates leave `authVersion` unchanged. During coexistence, Party Governance also owns the authenticated decision to claim a Waldur invitation. Its external-invitation port lists invitations for current verified recipient evidence and accepts one explicit invitation per command for the established Waldur account. Waldur remains the invitation store. The provider adaptor records definite, rejected and uncertain outcomes; Project learns the resulting membership through its Waldur source workflow. **Exit:** a first login creates one Party; repeated and concurrent logins preserve it; spoofed claims and email-only linking fail; disabled or retired identities cannot obtain new access. Party registration, binding and authentication facts are exposed for Metallo through qualified broker boundaries. Metallo consumer wiring follows in a separate slice. Both endpoint families use API session authority; onboarding, AUP, logout and retained repository access pass qualification. ## Phase 2 Canonical Projects from Waldur Make Project persistent and replace its static directory with authorised queries. Assign a new independent `ProjectId` once for each observed Waldur Project; enforce uniqueness of the provider/instance/external-ID binding. Retain the Waldur UUID, customer and resource references as external bindings. Project owns complete source reads, notification intake and reconciliation through its provider-independent ports and Waldur adaptors. Persist source acquisition identity/order, fingerprint and management generation with each Project. Fenced workers apply one complete snapshot at a time. Acquisition order, canonical version, delivery deduplication and binding uniqueness remain separate. Current-state reads handle notification gaps and revoke/grant ordering. Only a complete membership read may remove missing members; partial failures preserve prior state. Record successful unchanged refreshes in Project-owned source status. Replays never renew freshness. Closure requires qualified lifecycle proof; empty membership, missing events and ambiguous provider reads cannot supply it. Resolve members through verified Party/provider bindings. Keep unresolved source members as pending observations, outside effective canonical membership. A later binding event retries resolution. Record a source Project with no valid manager as needing attention; avoid fabricating an administrator or rejecting discovery. Map Waldur `PROJECT.MANAGER` to `project-administrator` and `PROJECT.MEMBER` to `developer`. Flag unsupported roles. Waldur's current single-manager setting is an adaptor constraint. Native Beto will require at least one direct administrator and can support several when its downstream providers permit that projection. Expose `ListMyProjects`, `GetProject` and `ListProjectMembers`; add fulfilment reads when that workflow has recorded state. Separate `ListRepositoryDestinations`: the legacy picker requires GitLab Maintainer access. Ordinary membership must not widen that picker. Keep personal namespace choices through the retained selector until their owner has an equivalent query. Publish canonical `ProjectChanged` and `ProjectAccessChanged` facts for Metallo, plus the scoped owner queries needed to bootstrap and repair its projections. Metallo obtains Project data through those queries or its event-built projections. Capability decisions must meet the owner's freshness and revocation contract. **Exit:** a Waldur change reaches Beto and Metallo's canonical consumer; duplicates preserve identity; old or partial evidence cannot restore/revoke access incorrectly. One user cannot enumerate another's Projects. Replace anonymous mock access before returning real data. Late consumer bootstrap and restart recovery are qualified. ## Phase 3 Qualify fulfilment and replace selected legacy reads The active writers are explicit: the retained compatibility account workflow creates/links GitLab accounts; Party Governance records verified associations; Source Control creates/renames Project groups and changes direct memberships. Project publishes desired canonical facts and current authority. A future `ProjectFulfilment` view may record redacted delegated readiness, but owns no GitLab call or retry state. Signup-time personal setup and credentials remain compatibility operations with independent provider progress. Publish verified association proof through a durable Party binding hand-off. Site account operations retain their owner. The isolated Waldur integration process contains capability-specific identity and invitation adaptors. They may share provider transport, retry and observability code. Their interfaces, caller credentials and operations remain separate. The Project-owned Waldur source adaptor does not serve Party or Metallo callers. Provider operations use stable effect identities and read-after-uncertain-write recovery. Serialise effects per target and recheck the latest desired revision before applying a retry. A delayed grant must not restore removed access. A group being ready does not establish that an allocation or execution environment is ready. Resolve or quarantine an uncertain provider effect before allowing a contradictory effect on the same target; qualify this behaviour against the actual provider. Switch the selected Next.js identity/directory reads to the new API using the [endpoint boundary](endpoint-map.md#first-iteration-boundary). Detail and membership reads move only after their complete response composition passes parity. Small boundary adaptors preserve provider IDs, paths and UI shapes. Return explicit availability and pending states. Keep allocation data composed from its existing owner until an equivalent allocation query is ready. Never replace a failed authorisation read with privileged provider data. Define an installation freshness bound for Waldur-derived access before launch, using Project's successful complete-read evidence. Qualify the proposed 60-second bound together with scan interval, duration and delivery lag. Fail closed for new access-sensitive actions when freshness is unknown or expired. Existing direct GitLab tokens remain governed by GitLab until its permissions are reconciled. Show and alert on that revocation lag; a local session fence alone cannot revoke a provider session. **Exit:** the first-iteration journey passes: Waldur creates a Project, an invited user signs in and accepts, Beto resolves membership, GitLab access becomes usable, Themelio creates a repository and launches through its retained workflow, and removing the member revokes the required provider access. Canonical Beto events reach real Metallo consumers, and selected reads run through Go API. Prove restart recovery, missed notifications and a stale grant arriving after removal. Keep the sign-in/sign-out experience, AUP, invitations, personal/repository destinations, Git HTTPS/LFS, allocation views and deployment setup in the same regression journey. The later native-management journey in issue 164 remains a separate milestone. ## Phase 4 Policy and authentication lifecycle Move AUP reads and acceptance into Party Governance. Record the precise immutable release, content digest, Party, presentation evidence and acceptance time. Switch the old layout gate and acceptance route together. Existing acceptance collected during earlier phases may be imported only with sufficient evidence; otherwise request acceptance of the current release again. Authentication and policy acceptance remain separate checks. Extend the API-owned flow with the architecture-reset identity-lifecycle design: one current binding, immutable retired history, separate authentication generation and two-person recovery. Recovery preserves Party and membership IDs. Both operators need recent signed authentication; neither can recover their own identity through this procedure. The Party transaction fences all older credentials by advancing `authVersion` and records disconnect/revocation intents. Independent grant records, technical sessions and provider accounts are updated asynchronously. Every grant resolution checks the generation, so delayed cleanup cannot preserve platform authority. This adapts the reference's lifecycle guarantees to main's one-root transactions. Enable a signed AAI disable/enable/purge receiver only after qualifying its transmitter, retry behaviour and exact platform-facing issuer/subject mapping. Keep pre-login tombstones, source event receipts and ordering evidence; stale enablement cannot undo removal, and purge is terminal for that external identity. Keep platform `accessState` separate from each binding's `identityState`; approved recovery may replace a purged binding while preserving PartyId and any platform disablement. Re-enablement requires a fresh login. Existing provider sessions need explicit removal/disablement work. **Exit:** recovery, disablement and re-enablement preserve Party identity and invalidate old browser, CLI and realtime authority. Exercise two browser windows, provider sessions and delivery outages. Maintain an operator procedure while automatic AAI security delivery remains unavailable. ## Phase 5 Beto management and one management cutover Implement native Project creation, updates, closure, direct member roles and invitations after agreeing its product scope. Issue 164 requests administrator-led creation and invitations to signed-in Parties; the broader self-service and new- recipient designs below require explicit selection before activation. The draft currently models an eligible creator becoming the initial administrator atomically. Project enforces current actor authority and prevents removing the final direct administrator from an active Project. Closure blocks new use and schedules access removal; retention and resource shutdown follow their owning policies. Party Governance invitations support both an existing `PartyId` and an unregistered recipient. An unregistered recipient signs in, proves the intended verified recipient plus possession of the invitation secret, and is then bound to a Party. Existing-Party invitations survive authentication-binding recovery. Preserve the invite-before-first-login workflow that Waldur already supports. Claim records intent in Invitation and durably asks Project to apply membership. Project rechecks current authority, lifecycle and target eligibility, then emits an applied or rejected outcome. Invitation records fulfilment. The user can see `applying`; provider access may still be pending afterwards. Revocation is allowed while an invitation is open; once application starts, use the membership removal workflow after its outcome. This avoids pretending that two roots commit together. Qualify native management in an isolated environment. Then perform one cutover: 1. Pause Waldur Project/member/invitation editing for this installation and stop acceptance of outstanding legacy invitations. Finish or explicitly reissue pending invitations through the native flow, retaining audit references. 2. Complete the final source reconciliation and drain accepted source commands. Advance one installation management generation; late legacy observations fail the generation check. Preserve all canonical IDs and provider bindings. 3. Enable native Beto management routes. Disable management imports from Waldur; keep resource/order observations needed by other workflows. 4. Project to Waldur only the records, membership or resource associations still required by retained workflows. Disable the old bridge's writes for operations now owned by Beto. Alert on manual Waldur drift and repair it from Beto. Before enabling multiple native administrators, qualify disabling Waldur's single-manager constraint where their downstream representation still needs `PROJECT.MANAGER`. A provider limitation must be resolved explicitly at this gate. Use one installation setting and a checked runbook. Ordinary command idempotency, aggregate versions and a generation fence are sufficient. Per-Project authority modes, bidirectional merges and a conflict-resolution service are unnecessary. Before Beto accepts native writes, rollback may return to the Waldur interface. After native writes begin, preserve Beto authority and repair delivery forwards; a return to Waldur requires an explicit export/reconciliation procedure. **Exit:** a Beto-created Project and an invitation to a new user support the same repository and deployment acceptance journey as Phase 3. Late Waldur messages cannot overwrite native changes. Multi-administrator behaviour is qualified against any remaining Waldur projection constraint. ## Phase 6 Broader architecture evolution Introduce Organisation governance, richer role assignments, policy obligations, platform access grants and further Project lifecycle features when their consumers need them. Customer accounts and billing require an explicit owning model; the reference's automatic CustomerAccount creation is not a bootstrap prerequisite. Project initially supports `active` and `closed`. Add `suspended` with defined rules for reads, new/running workloads, provider access and resumption. Replace repository, catalogue and execution routes context by context. A GitLab repository called a "project" remains a repository in the platform model. Platform CLI grants and Git-over-HTTPS credentials have different consumers; retain GitLab PAT support until equivalent Git access is available. Retire each legacy credential and route only after its consumers have moved. ## Implementation slices and checks | Slice | Concrete change | Required evidence | | --- | --- | --- | | 0 | Agree Project-owned source ports, canonical outward contracts, Metallo receiving owners, freshness/proof gaps and per-operation writers | Pinned source evidence; reviewed change from the Metallo branch's observation ownership; typed contracts and permissions | | A | Party foundations/events, then API-owned OIDC/sessions, legacy auth adaptor and resumable compatibility setup | Uniqueness, forged claims, concurrent login, scoped queries/publication, both route families, onboarding/AUP, logout fencing and provider recovery | | B | Persistent Project, owned Waldur acquisition, member resolution, canonical events and owner queries | Duplicates, partial/stale input, unresolved then removed member, independent revisions, late bootstrap and actual Metallo projection/query consumers | | C | Selected Go API reads and provider fulfilment only where required to complete the retained journey | Endpoint parity, one writer per target, uncertain-effect recovery, repository picker separation, allocation/deployment preservation and revocation UAT | | D | Policy evidence and lifecycle | Acceptance evidence, retired bindings, two-operator recovery, generation fences and real AAI signal drill | | E | Native management, invitation hand-offs and cutover | Final-admin invariant, apply/reject recovery, new-user invite, late source rejection and full legacy workflow | | F | Remaining context and client migrations | Per-feature contracts, credential retirement and production UAT | For each slice, promote only implemented OpenAPI operations into the active contract tree. Messaging generation already supports declared Party contracts; HTTP mappings, broker provisioning and runtime activation need their own qualification. Regenerate through `pnpm generate:contracts`; check historical wire identities separately from generated drift. Add narrow broker permissions and required architecture/security negative fixtures when each boundary becomes active. Use owner-native tests for invariants, PostgreSQL for atomicity, RabbitMQ for delivery recovery and real provider qualification for external effects. Browser updates use server-authorised typed Centrifugo projections, initial queries and history-gap reconciliation. Server reconciliation is independent of that browser contract. Run `pnpm verify` and applicable integration, browser, UAT and deployment lanes for each executable slice. ## Design references - The [Project source implementation](../../contexts/project/README.md) supplies persistent canonical state; migrating the legacy HTTP directory remains separate. - [Architecture](../../../../ARCHITECTURE.md), [DDD](../../../../DDD.md) and [context onboarding](../../../../docs/adding-a-context.md) govern implementation. - [Themelio compatibility decision](../../../../docs/decisions/0043-themelio-compat-service.md) explains the retained deployment and its limited credential exception. - [Waldur readiness](../../../metallo/docs/epics/project-provisioning/waldur-readiness.md), [permissions](../../../metallo/docs/epics/project-provisioning/project-permissions.md) and [SSO](../../../metallo/docs/epics/project-provisioning/single-sign-on.md) supply provider observations. Metallo's initial provisioning proposal is advisory; its Waldur-derived canonical IDs and fixed manager count do not constrain Beto. - The [Metallo agreement](metallo-integration.md) pins issue 164, PR 706, the observation branch and architecture-reset at `77c61208f`, including its now-committed authentication lifecycle work. Recovery, retired bindings, stable recipients and generation fences guide the model; cross-root effects use the current foundation's durable hand-offs.