From 81cdce41739357aa4aa7c2bcf18fd4cda3ec6b03 Mon Sep 17 00:00:00 2001 From: codex Date: Sun, 16 Aug 2026 18:54:39 +0200 Subject: [PATCH 1/5] docs(canon): ADR-007 workplan identity, single registrar, worker topology (proposed) Globally unique PREFIX-WP-NNNN; one prefix per repo; forward-only running numbers; prefixes never derived from flavor markers. Exactly one registrar mints hub IDs into git-tracked files. Automated normalization may not promote proposed to active. Repo manipulation defaults to a worker agent in that repo; prj- repos may act across their declared participants. Fleet scan of 955 workplans found 3 shared prefixes and 5 duplicated identifiers. Migration of existing collisions deliberately left for a separate ruling. Co-Authored-By: Claude Opus 5 --- ...kplan-identity-and-repo-worker-topology.md | 158 ++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 canon/architecture/adr-007-workplan-identity-and-repo-worker-topology.md diff --git a/canon/architecture/adr-007-workplan-identity-and-repo-worker-topology.md b/canon/architecture/adr-007-workplan-identity-and-repo-worker-topology.md new file mode 100644 index 0000000..ddf2e08 --- /dev/null +++ b/canon/architecture/adr-007-workplan-identity-and-repo-worker-topology.md @@ -0,0 +1,158 @@ +--- +id: ADR-007 +type: architecture-decision-record +title: "Workplan Identity Uniqueness, Single Registrar, and Repo Worker Topology" +status: proposed +decided_by: Bernd Worsch +date: "2026-08-16" +tags: ["architecture", "workplans", "identity", "state-hub", "repo-manager", "agents", "registrar"] +--- + +# ADR-007: Workplan Identity Uniqueness, Single Registrar, and Repo Worker Topology + +## Status + +Proposed. Remediation of existing collisions (§ Migration) needs a separate +ruling before execution — it is disruptive and touches six repositories. + +## Context + +On 2026-08-16, `STATE-WP-0080` was found registered **twice, in two different +databases**, with two different workplan UUIDs and two disjoint sets of task +UUIDs: + +| Registrar | Workplan UUID | Reachable at `127.0.0.1:8000` | +|---|---|---| +| Workstation hub (`make api`, local postgres) | `03f38314` | yes | +| railiance01 primary, via `custodian-sync@railiance.local` | `bbfce36a` | **404** | + +Both write their IDs into the same git-tracked workplan file, so each sync +overwrites the other's IDs and the file flip-flops on every round trip. The same +commit (`ff909e1`, "renormalize lifecycle state [auto]") also promoted the +workplan `proposed` → `active` without human review. + +A fleet scan of 955 hub workplans (525 with parseable `PREFIX-WP-NNNN` +identifiers) found this is not an isolated incident. Two distinct identity +defects are live: + +**Prefix reuse across repositories:** + +```text +CUST-WP- → state-hub, the-custodian +RAIL-BS-WP- → railiance-bootstrap, railiance-cluster +RAILIANCE-WP- → railiance-apps, railiance-forge, railiance-platform, railiance-telemetry +``` + +`PRJ-WP-` is a latent fourth: `statehub register` derives it from the `prj-` +flavor marker, so every project repository would collide (see `RMGR-WP-0004`). + +**Running-number reuse:** + +```text +CUST-WP-0000 the-custodian ×2 +CUST-WP-0010 the-custodian ×2 +CUST-WP-0045 the-custodian ×2 +RAILIANCE-WP-0015 railiance-platform, railiance-apps +RAILIANCE-WP-0016 railiance-platform ×2, railiance-apps +``` + +`RAILIANCE-WP-0015` is actively cited in operational memory as the cnpg-backup +gate in `railiance-apps`; a second record of the same name in +`railiance-platform` makes that citation ambiguous. + +The `C-26` consistency check already flags prefix nonconformance *within* a repo +against a canonical prefix, but nothing enforces uniqueness *across* repos, and +nothing prevents number reuse. + +## Decision + +**1. A workplan identifier is globally unique.** `PREFIX-WP-NNNN` names exactly +one workplan across the entire fleet, for all time. + +- A workplan prefix is owned by exactly one repository. No two repositories may + use the same prefix. +- A running number is never reused within a prefix, including after a workplan is + cancelled, archived, or deleted. Numbers are allocated forward only. +- Prefixes are derived from the *project or repository identity*, never from a + flavor marker or category (`PRJ-WP-` is invalid by construction). + +**2. Exactly one registrar writes hub identifiers into repository files.** A +single instance is authoritative for registration and ID writeback. Other +instances may read, project, and serve; they must not mint workplan or task +UUIDs into git-tracked files. + +The workstation hub is a development read replica, not a registrar. Running +`fix-consistency` with writeback from a workstation against a repository whose +primary is elsewhere is the mechanism that produced the flip-flop. + +**3. Lifecycle status is not automatically promoted.** An automated +normalization pass may report drift; it may not move a workplan from `proposed` +to `active`. `proposed` means awaiting human review, and an automation that +promotes it destroys the meaning of the review gate. + +**4. Repository manipulation is performed by a worker agent in that +repository.** This is the default topology. + +- A worker acting in repo X owns changes to repo X. +- Multiple independent top-level workers inside a single repository are an + **exception**, requiring an explicit reason, not a routine mode of operation. +- Concurrent independent writers are what turned a two-registrar bug into + repeated git divergence. + +**5. Project (`prj-`) repositories may act across their participating +repositories.** When work is governed by a project repo, its tasks may direct +changes across every repository the project names, through the project's work +agent, where that is more efficient than delegating. + +This is a deliberate, scoped exception to decision 4: the project repo already +owns cross-repo sequencing and its `SCOPE.md` names its participants, so its +authority is declared rather than ad hoc. It does not license a worker in an +arbitrary repository to reach into others. + +## Consequences + +**Positive.** Workplan identifiers become citable without qualification. +Hub IDs stop flip-flopping in git. The `proposed` status regains meaning. +Cross-repo authority becomes something a repository declares rather than +something any session assumes. + +**Negative.** Existing collisions must be remediated (see below), which is +disruptive. Workstation sessions lose the ability to register workplans directly +and must route through the registrar or a worker in the owning repo. Prefix +allocation needs a fleet-level registry, which is new machinery. + +**Enforcement.** Prefix ownership, uniqueness, and forward-only numbering are +repository standards, so they belong to Repo Manager under decision `747011c6` +(`RMGR-WP-0004`), not to a hub. Canon defines the rule; Repo Manager checks it. + +## Migration — needs a separate ruling + +Three prefixes and five identifiers are already colliding. Remediation options, +in increasing cost: + +1. **Freeze and forward-fix.** Accept existing collisions as historical, enforce + uniqueness only for new workplans. Cheapest; leaves `RAILIANCE-WP-0015` + permanently ambiguous. +2. **Renumber the live collisions only.** Fix identifiers that are still cited or + active; leave `finished`/`archived` duplicates alone. +3. **Full renaming.** Give `railiance-apps`, `railiance-forge`, + `railiance-platform`, `railiance-telemetry` distinct prefixes, likewise + `railiance-bootstrap`/`railiance-cluster` and `state-hub`'s legacy `CUST-WP-` + files. Touches six repositories and every inbound reference. + +Recommendation: **option 2**, with option 3's prefix split applied only to repos +that are still creating new workplans under a shared prefix — a shared prefix +that is still growing keeps generating new collisions, while a dormant one does +not. + +All five duplicated identifiers are currently `finished`, so no active work is +blocked by deferring this. + +## References + +- Decision `747011c6` — repository standards belong to Repo Manager +- ADR-001 — workplans originate as repo files; hub is a read model +- `RMGR-WP-0004` — repository standards conformance and governed scaffolding +- `STATE-WP-0080` — register scaffolding handoff +- Fleet scan 2026-08-16: 955 hub workplans, 525 parseable identifiers, + 3 reused prefixes, 5 reused identifiers From 183dd354670ac82ddcc2cda66f0e6d6ede030564 Mon Sep 17 00:00:00 2001 From: codex Date: Mon, 17 Aug 2026 09:46:19 +0200 Subject: [PATCH 2/5] docs(canon): resolve ADR-006 ownership questions R1-R6 R1 Scope -> itc-ident (itc-access keeps narrower ResourceScope). R2 Assurance Level -> itc-ident, distinct from governance AssuranceCase. R3 Evidence + Evidence Source are a general pair (container vs extracted assertion), owned together, not by commerce; itc-gov no longer owns Evidence. R4 Relationship Tuple -> itc-access (already modelled there). R5 Adjudication Outcome follows R3; general, not commerce-owned. assurance_tier splits: general strength dimension vs commerce's named Counterparty Assurance Gradient. R6 Community + Household extend itc-org CollectiveActor; Family rejected as a collective actor and given its own seeded concept area. One open question remains: the home for the evidence pair (dedicated itc-evid model vs itc-gov incumbency). Recommendation: dedicated model. Co-Authored-By: Claude Opus 5 --- ...-006-canon-federation-concept-ownership.md | 127 +++++++++++++++--- 1 file changed, 108 insertions(+), 19 deletions(-) diff --git a/canon/architecture/adr-006-canon-federation-concept-ownership.md b/canon/architecture/adr-006-canon-federation-concept-ownership.md index 733e030..ac0c9ff 100644 --- a/canon/architecture/adr-006-canon-federation-concept-ownership.md +++ b/canon/architecture/adr-006-canon-federation-concept-ownership.md @@ -114,10 +114,13 @@ than identity-owned definitions. `Customer` · `Vendor` · `Commercial Relationship` · `Commercial Commitment` · `Payment Instrument Reference` · `Payment Mandate` · `Pipeline Pursuit` · `Commercial Record` · `Counterparty Assurance Gradient` · `Reputation Signal` · -`Performance Evidence` · `Adjudication Outcome` · `Registry Identifier` · +`Performance Evidence` · `Registry Identifier` · `Proxy Commercial Identifier` · convenience terms `Reputation`, `Customer Account` +*Owned by the evidence model (see Resolution 3):* +`Evidence` · `Evidence Source` · `Adjudication Outcome` + Identifier subtypes demonstrate the intended pattern: `itc-ident` owns `Identifier`; `commerce-canon` owns `Registry Identifier` and `Proxy Commercial Identifier` as specializations of it. @@ -133,26 +136,112 @@ the canon does not push. organizational architecture, human-gated — not commercial vocabulary. If it ever moves, it becomes an InfoTechCanon organization standard, not a CommerceCanon one. -## Open questions +## Resolutions -These are unresolved collisions that must be settled before the affected -concepts move. They are deliberately listed rather than silently decided. +The six collisions listed at draft time, resolved 2026-08-17. Two were settled +by evidence already present in the models rather than by argument. -1. **`Scope`.** identity-canon P3 makes it first-class; `itc-access` uses "access - scope" throughout. Does `itc-ident` own `Scope` with `itc-access` importing, - or the reverse? -2. **`Assurance Level` vs `itc-gov` `Assurance`.** Specialization or distinct - concept? `Counterparty Assurance Gradient` builds on whichever wins. -3. **`Evidence Source` vs `itc-gov` `Evidence`.** Likely an `itc-gov` - specialization rather than an identity-owned concept. -4. **`Relationship Tuple`.** A Zanzibar/OpenFGA-style authorization primitive — - plausibly `itc-access`, not `itc-ident`. -5. **`Adjudication Outcome` vs `itc-access` `AuthorizationDecision` and `itc-gov` - `Decision`.** Three candidate owners. -6. **`Community`, `Family Or Household`.** Social collectives absent from - `itc-org`, which covers enterprise structures (`Team`, `Group`, - `OrganizationalUnit`). Recommend extending `itc-org` rather than placing them - in `itc-ident`. +**R1 — `Scope`: owned by `itc-ident`.** There is no head-on collision: +`itc-access` owns `ResourceScope` (`:717`, "the boundary within which access +applies"), a narrower concept, not a general `Scope`. `itc-ident` owns the +general concept, keeping it with `Tenant` and `Realm` — `Tenant` is defined as +"an administrative or isolation scope", so separating it from its genus would +split a definition from the concept it depends on. `itc-access` keeps +`ResourceScope` as a refinement. + +If `landscape` or `information-space` later need general scoping, promote +`Scope` to the kernel **on that demand signal**, not pre-emptively. + +**R2 — `Assurance Level`: owned by `itc-ident`, distinct from governance +assurance.** A false collision. `itc-gov` owns `AssuranceCase` (`:1178`, a +structured argument that a claim is justified) and `AssuranceConclusion` +(`:1184`). identity's `Assurance Level` is NIST SP 800-63-4 IAL/AAL/FAL — +graded confidence metadata on credentials, bindings, and federation assertions. +They share an English word and nothing else. Both models carry a disambiguation +note, because the word will keep causing this. + +Design principle P12 ("Distinguish Assurance Dimensions") carries over: IAL, +AAL, and FAL must not be collapsed into a single "trust level" on an account. + +**R3 — `Evidence` and `Evidence Source` are a general pair, owned together, and +not by commerce.** They are not competing definitions of one concept: + +- **Evidence Source** — an addressable information container: a document, file, + or other artifact identifiable by URI. +- **Evidence** — a distinct information item, textual or descriptive, drawn from + a source: a quotation, an extracted value, a specific assertion. + +Both may carry commentary. Which evidence is captured from a source depends on +the interest being served. + +Worked example: an invoice PDF is an Evidence Source; the amount, the issuer, +and the due date are separate Evidence items within it. The common electronic- +invoicing pattern of an XML embedding inside a signed PDF is exactly this +structure — evidence pre-extracted and bound to its source so the extraction is +itself tamper-evident. + +The pair is domain-neutral (it extends to criminal, regulatory, and scientific +evidence). Commerce, identity, and governance all **use** it; none owns it. +Consequently `itc-gov` no longer owns `Evidence`; it imports it. + +**R4 — `Relationship Tuple`: owned by `itc-access`.** Already modelled there +(`:549`, under `PolicyEvaluationEntity` beside `AuthorizationRequest`, +`AuthorizationDecision`, `DecisionReason`, `EvaluationContext`). identity-canon's +own entry agrees: "Relationship tuples are not canonical identity roots. They +project from actors, accounts, memberships, and delegations into authorization +domains." `itc-ident` must not define it. + +**R5 — `Adjudication Outcome`: follows R3, owned with the evidence pair.** Not +`itc-access` `AuthorizationDecision` (a PDP allow/deny, `:907`) and not `itc-gov` +`Decision` (a governance choice point). The concept is general rather than +commercial: an arbitration award, court judgment, or regulatory consent order is +evidence in employment, licensing, or compliance disputes as much as in +commercial ones. Commerce is a consumer, not the owner. + +Structurally it is **Evidence** — the outcome asserted — sourced from an +Evidence Source such as the judgment document. + +The `assurance_tier` dimension splits accordingly: the evidence model owns a +general evidence-strength dimension; `commerce-canon` owns the +`Counterparty Assurance Gradient` as its named four-tier application of it. + +**R6 — `Community` and `Household` extend `itc-org`; `Family` is a separate +concept area.** identity-canon defines "Family Or Household" as one entry. That +conflation is rejected. + +`Community` and `Household` are collective actors and slot under `itc-org`'s +existing `CollectiveActor` (`:363`, beside `Person`, `HumanActor`, +`NonHumanActor`), honouring P4 ("Model Collective Actors Without Collapsing +Them"). + +`Family` does not. Family carries substantial structure — kinship, guardianship, +dependency, care, and legal, biological, and social parenthood — which changes +over time and is subject to interpretation. Modelling it as one more collective +actor is the specific mistake most family-oriented software makes, and it is why +such software generally models families badly. It gets its own concept area. + +Scope discipline applies: the family area is **seeded, not authored**. Record the +concept, the privacy sensitivity already flagged in identity-canon ("may have +legal implications outside the canon's scope"), and the open modelling +questions. Do not build it out inside `CFED-WP-0001`; it grows on demand signal +like any other canon content. + +## Open question + +**Where the evidence pair lives.** R3 and R5 establish *what* is owned together +and that commerce does not own it. The remaining choice is the home: + +1. **A dedicated evidence model** (`itc-evid`) owning `Evidence`, + `Evidence Source`, `Adjudication Outcome`, and the evidence-strength + dimension, imported by `itc-gov`, `itc-ident`, and `commerce-canon`. + Three named consumers already exist, which is a genuine demand signal. + Signals correctly that evidence is not a governance sub-topic. +2. **`itc-gov` keeps both**, as the incumbent owner of `Evidence`. Cheapest, and + preserves the locality of the Policy-Control-Evidence chain pattern + (`:1391`) — but forces identity and commerce to import "governance" to + describe an invoice line item, which mis-signals. + +Recommendation: option 1. ## Consequences From 4565bef8191c348de96f9d2dcb96722c9b6c3187 Mon Sep 17 00:00:00 2001 From: codex Date: Mon, 17 Aug 2026 10:03:15 +0200 Subject: [PATCH 3/5] =?UTF-8?q?docs(canon):=20ADR-006=20accepted=20?= =?UTF-8?q?=E2=80=94=20R7=20places=20evidence=20pair=20in=20dedicated=20it?= =?UTF-8?q?c-evid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Evidence, Evidence Source, Adjudication Outcome and the general evidence-strength dimension get a dedicated InfoTechCanon model, imported by itc-gov, itc-ident and commerce-canon. Three named consumers predate the model, which is the required demand signal. itc-gov stops owning Evidence and becomes an importer; it retains AssuranceCase, AssuranceConclusion, Audit and the Policy-Control-Evidence pattern expressed over imported concepts. Co-Authored-By: Claude Opus 5 --- ...-006-canon-federation-concept-ownership.md | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/canon/architecture/adr-006-canon-federation-concept-ownership.md b/canon/architecture/adr-006-canon-federation-concept-ownership.md index ac0c9ff..49c0375 100644 --- a/canon/architecture/adr-006-canon-federation-concept-ownership.md +++ b/canon/architecture/adr-006-canon-federation-concept-ownership.md @@ -2,9 +2,10 @@ id: ADR-006 type: architecture-decision-record title: "Canon Federation and Concept Ownership Across InfoTech and Commerce" -status: proposed +status: accepted decided_by: Bernd Worsch date: "2026-08-16" +accepted: "2026-08-17" tags: ["architecture", "canon", "concept-ownership", "info-tech-canon", "commerce-canon", "identity", "orthogonality"] --- @@ -12,8 +13,8 @@ tags: ["architecture", "canon", "concept-ownership", "info-tech-canon", "commerc ## Status -Proposed. Canon changes are review-gated; this ADR is the review artifact for -the identity/commerce split and must be accepted before content moves. +Accepted 2026-08-17. All seven ownership questions are resolved (see +Resolutions); content may now move under `CFED-WP-0001`. ## Context @@ -118,7 +119,7 @@ than identity-owned definitions. `Proxy Commercial Identifier` · convenience terms `Reputation`, `Customer Account` -*Owned by the evidence model (see Resolution 3):* +*Owned by `itc-evid`, the evidence model (see R3, R5, R7):* `Evidence` · `Evidence Source` · `Adjudication Outcome` Identifier subtypes demonstrate the intended pattern: `itc-ident` owns @@ -226,22 +227,22 @@ legal implications outside the canon's scope"), and the open modelling questions. Do not build it out inside `CFED-WP-0001`; it grows on demand signal like any other canon content. -## Open question +**R7 — the evidence pair lives in a dedicated model, `itc-evid`.** A new +InfoTechCanon model at `infospace/models/evidence/` owns `Evidence`, +`Evidence Source`, `Adjudication Outcome`, and the general evidence-strength +dimension. -**Where the evidence pair lives.** R3 and R5 establish *what* is owned together -and that commerce does not own it. The remaining choice is the home: +`itc-gov`, `itc-ident`, and `commerce-canon` import it. Three named consumers +existed before the model did, which is the demand signal the canon requires. -1. **A dedicated evidence model** (`itc-evid`) owning `Evidence`, - `Evidence Source`, `Adjudication Outcome`, and the evidence-strength - dimension, imported by `itc-gov`, `itc-ident`, and `commerce-canon`. - Three named consumers already exist, which is a genuine demand signal. - Signals correctly that evidence is not a governance sub-topic. -2. **`itc-gov` keeps both**, as the incumbent owner of `Evidence`. Cheapest, and - preserves the locality of the Policy-Control-Evidence chain pattern - (`:1391`) — but forces identity and commerce to import "governance" to - describe an invoice line item, which mis-signals. +Rejected alternative: leaving both with `itc-gov` as incumbent owner of +`Evidence`. That is cheaper and preserves the locality of the +Policy-Control-Evidence chain pattern (`:1391`), but it would force identity and +commerce to import "governance" in order to describe an invoice line item — +mis-signalling evidence as a governance sub-topic when it is domain-neutral. -Recommendation: option 1. +`itc-gov` retains `AssuranceCase`, `AssuranceConclusion`, `Audit`, and the +Policy-Control-Evidence pattern, now expressed over imported evidence concepts. ## Consequences From dd65c91b4fcb1a9c5a7d80afa64553f54e1397d0 Mon Sep 17 00:00:00 2001 From: codex Date: Mon, 17 Aug 2026 10:17:58 +0200 Subject: [PATCH 4/5] =?UTF-8?q?docs(canon):=20ADR-007=20accepted=20?= =?UTF-8?q?=E2=80=94=20deterministic=20hub=20IDs=20(C2)=20with=20single-wr?= =?UTF-8?q?iter=20interim?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Decision 2 reframed: the defect is a database-local key stored in a shared artifact, which also inverts ADR-001. Target is UUIDv5 derived from the globally unique PREFIX-WP-NNNN, making writeback idempotent across any number of hub instances. Prerequisite: decision 1 uniqueness must be enforced first, or derivation from PRJ-WP- style collisions manufactures duplicate UUIDs. Interim: one writer only, the automated production instance. Rejected: collapsing to a shared database, which kills offline capability against STATE-WP-0068. Both land in repo-manager per 747011c6. Migration scope: 758 workplan files carry these fields. Remediation of the 3 shared prefixes and 5 duplicated identifiers stays an open ruling. Co-Authored-By: Claude Opus 5 --- ...kplan-identity-and-repo-worker-topology.md | 60 +++++++++++++++---- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/canon/architecture/adr-007-workplan-identity-and-repo-worker-topology.md b/canon/architecture/adr-007-workplan-identity-and-repo-worker-topology.md index ddf2e08..afffb47 100644 --- a/canon/architecture/adr-007-workplan-identity-and-repo-worker-topology.md +++ b/canon/architecture/adr-007-workplan-identity-and-repo-worker-topology.md @@ -2,9 +2,10 @@ id: ADR-007 type: architecture-decision-record title: "Workplan Identity Uniqueness, Single Registrar, and Repo Worker Topology" -status: proposed +status: accepted decided_by: Bernd Worsch date: "2026-08-16" +accepted: "2026-08-17" tags: ["architecture", "workplans", "identity", "state-hub", "repo-manager", "agents", "registrar"] --- @@ -12,8 +13,12 @@ tags: ["architecture", "workplans", "identity", "state-hub", "repo-manager", "ag ## Status -Proposed. Remediation of existing collisions (§ Migration) needs a separate -ruling before execution — it is disruptive and touches six repositories. +Accepted 2026-08-17. Identifier uniqueness, the registrar model, lifecycle +protection, and worker topology are settled. + +**Remediation of existing collisions (§ Migration) remains an open ruling.** It +is disruptive, touches six repositories, and no active work depends on it — all +five duplicated identifiers are `finished`. ## Context @@ -76,14 +81,49 @@ one workplan across the entire fleet, for all time. - Prefixes are derived from the *project or repository identity*, never from a flavor marker or category (`PRJ-WP-` is invalid by construction). -**2. Exactly one registrar writes hub identifiers into repository files.** A -single instance is authoritative for registration and ID writeback. Other -instances may read, project, and serve; they must not mint workplan or task -UUIDs into git-tracked files. +**2. Hub identifiers stored in repository files must be derivable, not +database-local.** The defect is structural: a database-local key is stored in a +shared artifact, so each database overwrites the other's value on every sync. +It also inverts ADR-001 — a file carrying a hub's private key is the file +holding hub state. -The workstation hub is a development read replica, not a registrar. Running -`fix-consistency` with writeback from a workstation against a repository whose -primary is elsewhere is the mechanism that produced the flip-flop. +*Target state (C2).* `state_hub_workstream_id` and `state_hub_task_id` become +**deterministic**: UUIDv5 derived from the globally unique `PREFIX-WP-NNNN` +identifier. Every instance computes the same value independently, writeback +becomes idempotent, and any number of hub instances may coexist without +coordination. The field shape is unchanged, so consumers keep working; only the +provenance of the value changes. + +This has a hard prerequisite: deterministic derivation from a **non-unique** +identifier would manufacture collisions rather than remove them. Two project +repos sharing `PRJ-WP-` would compute the same UUID for different workplans. +Decision 1 must therefore be enforced before derivation ships. + +*Interim state (A).* Until derivation lands, exactly one instance writes hub +identifiers into repository files. Other instances may read, project, and serve, +but must not mint workplan or task UUIDs into git-tracked files. The interim +registrar is the automated production instance; workstation hubs are development +read replicas. + +The interim is policy, enforced by discipline, and it has a real cost: +registration requires connectivity to the registrar, so disconnected work cannot +register. That cost is accepted only until C2 removes the need for it, at which +point the number of hub instances becomes an availability choice rather than a +correctness constraint. + +*Rejected.* Collapsing to a single shared database (workstation hubs pointing at +the production database) would also make identifiers consistent by construction, +but it eliminates offline capability — cutting directly against `STATE-WP-0068` +(offline write buffer and edge relay) — and couples all local work to tunnel +availability. + +*Ownership.* Both the interim guard and the derivation belong to `repo-manager` +under decision `747011c6`, which already places file-backed record indexing and +reconciliation there. Building either in `state-hub` would invest in a component +being retired under `STATE-WP-0079`. + +Migration scope for C2: **758 workplan files** across the fleet currently carry +these fields. **3. Lifecycle status is not automatically promoted.** An automated normalization pass may report drift; it may not move a workplan from `proposed` From 77e0ac2bca6c55ae01a50498bad56462d015ac47 Mon Sep 17 00:00:00 2001 From: codex Date: Mon, 17 Aug 2026 10:19:03 +0200 Subject: [PATCH 5/5] docs(canon): correct ADR-007 second-instance attribution custodian-sync@railiance.local is a hardcoded default git identity in consistency_check.py, not proof of which machine synced. The real evidence is the timezone split (+0000 and +0200) across sync commits. Co-Authored-By: Claude Opus 5 --- ...r-007-workplan-identity-and-repo-worker-topology.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/canon/architecture/adr-007-workplan-identity-and-repo-worker-topology.md b/canon/architecture/adr-007-workplan-identity-and-repo-worker-topology.md index afffb47..af8c357 100644 --- a/canon/architecture/adr-007-workplan-identity-and-repo-worker-topology.md +++ b/canon/architecture/adr-007-workplan-identity-and-repo-worker-topology.md @@ -29,7 +29,15 @@ UUIDs: | Registrar | Workplan UUID | Reachable at `127.0.0.1:8000` | |---|---|---| | Workstation hub (`make api`, local postgres) | `03f38314` | yes | -| railiance01 primary, via `custodian-sync@railiance.local` | `bbfce36a` | **404** | +| A second instance, over a second database | `bbfce36a` | **404** | + +The second instance is *not* identifiable from the commit author. +`custodian-sync@railiance.local` is a hardcoded default git identity in +`scripts/consistency_check.py:1899` (`GIT_SYNC_USER_NAME` / +`GIT_SYNC_USER_EMAIL`), so every machine running `fix-consistency` commits under +that name. The discriminator is the timezone: sync commits appear under both +`+0000` and `+0200` (the workstation's offset), which is independent evidence of +two machines writing to one repository. Both write their IDs into the same git-tracked workplan file, so each sync overwrites the other's IDs and the file flip-flops on every round trip. The same