Skip to content

ADR 0001: V1 SA Construction Model

Status

Accepted

Date

2026-04-05

Context

dirac-odoo v0 established Serviced Account (SA) as a governance boundary in Odoo, with SA-local memberships and PA-driven {actor, sa} context.

The next design step requires a clearer construction model for:

  • the difference between SA Administration and SA Management
  • canonical SA roots and branch structure
  • SA-local membership boundaries
  • the identity and anchor objects required to create an SA

This ADR records the construction decisions that have been resolved so far. It does not yet define the detailed operational workflows for changing sa_manager, releasing teams, or reassigning customers.

Decision

1. SAA and SAM are separate concerns

  • SA Administration (SAA) is the structural and administrative authority.
  • SA Management (SAM) is the business-management layer that operates within the valid SA and membership structures maintained by SAA.
  • In Odoo terms, the admin of OV<x> governs SA<x> and all descendant SAs in that branch through an SA Admin Panel.
  • SAA has administrative authority over SA records, SA hierarchy, and SA membership structures, but only through invariant-preserving actions.

2. Canonical SA roots are required

  • SA_ROOT is a proper SA.
  • Each SA<x> is a proper SA under SA_ROOT.
  • Every SA in an OV<x> branch must remain inside that branch enclosure.
  • The SA hierarchy and the membership hierarchy are separate structures:
  • SA hierarchy answers which child SAs roll up under a parent SA
  • membership hierarchy answers who manages whom inside one SA

3. Every SA must be created with exactly one initial manager

  • Every SA must be created with an initial sa_manager.
  • Manager existence is mandatory at creation time.
  • The proposed membership flag is_manager is rejected.
  • SA.sa_manager is the single source of truth for current manager identity.

4. Membership is SA-local and closed

  • Membership is local to one SA.
  • No membership is inferred from parent SA, child SA, or sibling SA.
  • The same human may appear in multiple SAs only through separate membership rows.
  • For child-SA creation, the initial manager membership must be created explicitly as part of the same atomic creation flow.
  • As an SoP default only, if the caller does not specify an initial manager for a newly created child SA, the system may use the parent SA's current manager person as the default seed identity, but must still create a new local membership row in the child SA.

5. res.partner is the identity anchor, but not an SA-semantic object

  • res.partner remains the identity anchor for people and organizations.
  • res.partner by itself carries no SA meaning.
  • SA meaning exists only through SA-local membership and SA-governance objects.
  • The underlying Odoo company boundary is treated as a hard containment layer that reduces the blast radius of SA bugs.

6. Every SA requires one canonical company-partner anchor

  • Every SA must have exactly one canonical anchor res.partner with is_company = true.
  • The anchor partner is fixed for the lifetime of the SA unless an explicit exceptional migration process is later defined.
  • The anchor partner is required and exclusive to that SA.
  • Each SA therefore requires creation of its own company-partner anchor record.
  • Best practice is to create separate Odoo company-partner anchors where governance meaning warrants it.

6.1 Soft hierarchy mirror on company partners

  • In normal operation, the SA hierarchy should be mirrored by res.partner.parent_id on the anchor company-partner records.
  • This mirror is a soft-alignment rule for now and is not enforced as a hard invariant.
  • Periodic cleanup or reconciliation may be required if the Odoo-side partner hierarchy drifts from the SA hierarchy.

7. SA creation must be validated inside the correct OV<x> enclosure

  • An SA<x> branch SA may be created only from a res.partner currently under the corresponding OV<x> domain.
  • More generally, SA creation in an OV<x> branch must use an anchor partner valid inside that same branch enclosure.
  • This constraint must be validated by the system and must not rely only on ordinary admin visibility restrictions.

Consequences

  • SAA can safely manage SA structure without collapsing into ordinary business management.
  • SAM can consume the resulting structures for business roll-up and team management without redefining platform authority.
  • SA trees remain branch-contained under OV<x>, with explicit creation rules instead of implicit inheritance.
  • Membership remains auditable and local to one SA, even when the same res.partner participates in multiple SAs.
  • Future work must define invariant-safe workflows for:
  • sa_manager transition
  • member hierarchy rules, including nullability of manager links
  • team release and customer reassignment operations
  • roll-up semantics across both the member tree and the SA tree