GOTT · Sibyla · approved 2026-08-11 · reconciled 2026-08-21: P2-3's decision point re-confirmed at S2-6 — the S2 slice-2 governed registry commit (CommitDocumentRegistry / RegistryCommitService) takes the resolver's output and records nothing about why, so the MatchDecision emission still belongs inside the S2-6 resolver; P2-2 closed without consolidation and realized in code — the three S1-9c screens shipped read-only against the separate tables (ITMCLS !65 · MNGACC !66 · COCACC !69), no ReferenceValue; P2-4 closed for EXCRAT and remains deferred for other rate-like tables; P2-6's trigger exists as query 03 of the S1.5-1 contract set
The seven items master-data-and-ui-plan.md deliberately leaves out of S1.5 — each with the concrete event after which deferring it stops being cheap.
Deferring work is only honest if you say when it stops being cheap. Each item carries a decision point — the observable event after which it gets materially more expensive. A date would be a guess; the event is not.
| # | Item | Decision point | Cost if missed |
|---|---|---|---|
| P2-2 | Closed without consolidation — ITMCLS, MNGACC and COCACC stay separate; no ReferenceValue closed | Decided before S1-9c; realized by !65/!66/!69 — do not reopen | None accepted; separate tables preserve their domain boundaries |
| P2-3 | Matching records decisions, not just outcomes inside Phase 1 | S2-6 — when the resolver is first written | Provenance cannot be reconstructed after the fact |
| P2-1 | ExternalIdentity absorbs the integration bindings | A third ERP provider, or the first cross-table binding bug | Two mechanisms for one fact |
| P2-4 | Effective dating for the rate-like tables | Taken 2026-08-12 — built with EXCRAT at 43ad0e7 | The most expensive retrofit on this list — and it was avoided |
| P2-5 | Separate Tenant from Company | The first customer with two legal entities on one subscription | Audit every tenancy-filtered query |
| P2-6 | Contract — drop LegacyCode and the shims | When nothing reads it (measurable) | Dead column, small ongoing confusion |
| P2-7 | BNKACC ↔ BankAccount / CashAccount | Layer 5 bank reconciliation | None — already correctly sequenced by V6-D4 |
ITMCLS, MNGACC and COCACC remain separate. Do not create ReferenceValue, and do not reopen the decision at S1-9c. A discriminator-based table would blur domain boundaries and invite nullable special cases as the domains evolve; the accepted cost of separate descriptors is smaller than that coupling.
!65), MNGACC (!66) and COCACC (!69) — with no ReferenceValue table. SNCACC remains separately justified as a hierarchical chart of accounts and was never part of this consolidation decision.The plan of record stores what was learned — a new ENTALS row, a new ENTITM mapping. It does not store why.
MatchDecision Id uuid PK DocumentId uuid NOT NULL FK SubjectType varchar(16) NOT NULL -- 'Entity' | 'Item' ResolvedToId uuid NULL -- null = no match, went to review Strategy varchar(24) NOT NULL -- 'Nif' | 'Alias' | 'NormalizedName' | 'Human' Confidence numeric(4,3) NULL CandidateJson jsonb NULL -- what else was considered, and its score DecidedBy uuid NULL -- null = automatic DecidedAt timestamptz NOT NULL
CandidateJson is the whole answer — free to capture at the moment of decision, impossible to reconstruct afterwards. It is also the only possible denominator for measuring whether resolution is improving.S2-6. That is where the NIF → alias → name resolver is written. The table is about a day's work then, and emission is a one-line change inside code being written anyway. Retrofitting means starting the history from zero, having discarded every decision made in between.ExternalIdentity absorbs the integration bindingsIntegrationPartyBinding caches a party's external id per provider. Under M-D5 that is exactly ExternalIdentity with Scheme = 'cegid.party'. Same for IntegrationProductBinding and items.
ExternalItemIdentity — over a polymorphic SubjectType. A polymorphic key cannot carry a real foreign key, and on this schema referential integrity is worth more than the deduplication.M-D7 records the decision; this is the implementation. EXCRAT and anything rate-like get ValidFrom / ValidTo and a no-overlap exclusion constraint. ENTMST and the code lists do not — they get audit events.
EXCRAT is first built. Free at creation; adding it to a populated rate table means inventing ValidFrom values that were never recorded. Taken 2026-08-12: S1-5 (43ad0e7, migration 20260811142000_S1ExcratEffectiveDating) built EXCRAT with ValidFrom/ValidTo as generated STORED columns and the GiST exclusion constraint EX_EXCRAT_NoOverlappingRatePeriod. Closed for EXCRAT; still deferred for everything else rate-like.Tenant from CompanyCompanyRegistry carries two jobs: the billing and authentication boundary, and the legal entity that issues and receives invoices. They coincide today. They stop coinciding the first time a group with several legal entities buys one subscription.
LegacyCode and the shimsPhase C of the S1.5 migration. Decision point: when nothing reads it — and that is measurable. The query exists as query 03 of the S1.5-1 schema contract set, so “is anything still reading LegacyCode?” is answered by the suite rather than by memory.
BNKACC ↔ BankAccount / CashAccountAlready correctly deferred by V6-D4; arrives with Layer 5 bank reconciliation. Restated only for completeness, and to repeat the standing instruction: do not touch BankAccount in Phase 1. It is the source side of payment; ENTBNK is the counterparty side. They are not duplicates.
Recorded so they are not re-proposed.
| Proposal | Why not |
|---|---|
Make ENTMST bitemporal | An entity is not a statement about a period (P2-4). An audit log answers the real questions at a fraction of the query complexity |
Polymorphic SubjectType on ExternalIdentity | Cannot carry a real FK. Two tables, per P2-1 |
Fold SNCACC into ReferenceValue | A tree with hierarchy semantics and an open scoping question (O-3), read at step 8 |
| Rekey any internal join to business codes | M-D2. This is the condition the whole exercise exists to remove |
| Do the integration-binding fold inside S1.5 | Spends the exact safety margin that makes the collapse defensible (P2-1) |
| If this happens | Then |
|---|---|
| A multi-entity customer signs | P2-5 moves to Phase 1 and becomes the largest item on it |
| A third ERP integration is scoped | P2-1 moves ahead of P2-4 |
| P2-2 is closed | ITMCLS, MNGACC and COCACC remain separate; S1-9c does not reopen the decision |
S2-6 ships without MatchDecision | P2-3 stops being deferrable and becomes debt with a visible interest rate: every day of resolution history not captured is not recoverable |