ARCH-02 — Transport identity authorities, external bindings, and reconciliation lifecycle #829

Open
opened 2026-07-22 19:45:52 -05:00 by jcwalker3 · 0 comments
Owner

Candidate architecture requiring executable validation; not yet approved, production-ready, or certified.

Parents: #820, #828. Depends on: #822 (principals/actor context), #826 (evidence stores for external-id proof).

1. Summary / objective

Implement transport identity authorities, external-id repository bindings, and the archival/re-encounter/reconciliation lifecycle, with canonical host/locator handling.

2. Security/correctness problem

A repository binding must have stable identity under rename/transfer only when the transport proves an external id; otherwise it is a local record with no continuity claim. Without an explicit transport→identity-store relationship, external_id_transport_bound cannot be checked.

3. Threat model / failure modes

External id bound to the wrong transport; malformed host/port; case/Unicode ambiguity aliasing repos; archived external id re-encountered (repo recreated); locator collision across binding modes; identity-authority rotation losing prior proofs.

4. In-scope behavior

  • transport_identity_authorities(transport_id PK, store_id, status) — explicit relationship; lifecycle + one active authority per transport. [SCHEMA].
  • Endpoint identity + authority rotation; transport retirement blocked while active bindings exist; transport replacement = new transport id.
  • Host canonicalization host_canon_v1 [TRUSTED-SERVICE]: strip scheme, remove default port, bracket+lowercase IPv6, IDNA→A-label, reject malformed colon/port; storable shape enforced by CHECK [SCHEMA]. Valid IPv4/IPv6/hostname handled; reject malformed combinations.
  • Unicode/ASCII policy stated without contradiction: hosts are A-label ASCII after IDNA; owner/name canonical lowercase ASCII (Gitea policy) — case normalization authoritative only under the bound transport identity.
  • External-id binding creation requires an evidence record (repository_external_id subject) whose store = the transport's active identity authority store. [SCHEMA].
  • Archival, re-encounter (ARCHIVED_EXTERNAL_ID_REENCOUNTER → reconciliation), locator conflict, reconciliation dispositions (same_object_confirmed/distinct_object/refused) with typed canonical prior/new values. [SCHEMA] CHECKs.
  • registered_by enforced via the authorized operation + actor context, not merely stored. [TRUSTED-SERVICE] + [SCHEMA] actor trigger.
  • Whether identifiers may be reused across configuration generations: define (recommended: UNIQUE(store,ref) prohibits reuse for the store lifetime).

5. Exclusions

No canonical resources/refs (→ next child), no project associations (→ lookup child), no workspaces.

6. Schema/operation contracts

transports, transport_identity_authorities, repository_bindings, binding_reconciliations. Operations: register_transport, bind_transport_identity_authority, register_repository_binding, record_locator_change, archive_binding, decide_binding_reconciliation, resolve_binding.

7. SQLite behavior

Partial unique indexes: rb_ext_id (real external ids unique per transport, NULLs allowed), rb_active_locator (one active binding per (transport,owner,name) across modes). Host/locator CHECKs.

8. PostgreSQL behavior

Same constraints; canonicalizers in the service; parity tested.

9. Concurrency / transaction requirements

Concurrent bindings on one locator: one active survives; re-encounter routes to reconciliation rather than silently reactivating.

10. Structured results

BINDING_REGISTERED, AMBIGUOUS_LOCATOR, EXTERNAL_ID_PROOF_REQUIRED, ARCHIVED_EXTERNAL_ID_REENCOUNTER, RECONCILIATION_REQUIRED, TRANSPORT_HAS_ACTIVE_BINDINGS, RETIRED_AUTHORITY.

11. Enforcement classification

Uniqueness/CHECK/immutability/external-id binding [SCHEMA]; host/locator canonicalization [TRUSTED-SERVICE]; external-id issuance proof [RUNTIME-ADAPTER] (via #826).

12. Acceptance criteria

  1. External-id binding requires a proof whose store = the transport's active identity authority.
  2. One active binding per locator across both modes.
  3. Real external ids unique per transport; NULLs allowed.
  4. Malformed host/port rejected; IPv6 handled.
  5. Continuity/binding-mode immutable.
  6. Archived external-id re-encounter → reconciliation.
  7. Transport retire blocked while active bindings exist.
  8. registered_by = authenticated caller.

13. Named tests

t_extid_wrong_store(−), t_locator_collision_cross_mode(−), t_extid_unique(−), t_host_ipv6(+), t_host_bad_port(−), t_continuity_immutable(raw-bypass), t_archived_reencounter(−), t_transport_retire_guard(−), t_registered_by_foreign(−).

14. Audit events / evidence

transport_registered, identity_authority_bound, binding_registered, binding_reconciled. Test output evidence.

15. Dependencies / parent

Parents #820, #828; depends #822, #826.

16. Definition of done

Executable SQLite (+PG section); ACs pass incl. raw-bypass; bounded PR; no self-review/merge.

17. Known limitations / deferred

local_record_only bindings remain unattended-ineligible (no upgrade path in this program). Ref/resource identity in the next child.

**Candidate architecture requiring executable validation; not yet approved, production-ready, or certified.** Parents: #820, #828. Depends on: #822 (principals/actor context), #826 (evidence stores for external-id proof). ## 1. Summary / objective Implement transport identity authorities, external-id repository bindings, and the archival/re-encounter/reconciliation lifecycle, with canonical host/locator handling. ## 2. Security/correctness problem A repository binding must have stable identity under rename/transfer only when the transport proves an external id; otherwise it is a local record with no continuity claim. Without an explicit transport→identity-store relationship, `external_id_transport_bound` cannot be checked. ## 3. Threat model / failure modes External id bound to the wrong transport; malformed host/port; case/Unicode ambiguity aliasing repos; archived external id re-encountered (repo recreated); locator collision across binding modes; identity-authority rotation losing prior proofs. ## 4. In-scope behavior - `transport_identity_authorities(transport_id PK, store_id, status)` — explicit relationship; lifecycle + one active authority per transport. `[SCHEMA]`. - Endpoint identity + authority rotation; transport retirement blocked while active bindings exist; transport replacement = new transport id. - Host canonicalization `host_canon_v1` `[TRUSTED-SERVICE]`: strip scheme, remove default port, bracket+lowercase IPv6, IDNA→A-label, reject malformed colon/port; storable shape enforced by CHECK `[SCHEMA]`. Valid IPv4/IPv6/hostname handled; reject malformed combinations. - Unicode/ASCII policy stated without contradiction: hosts are A-label ASCII after IDNA; owner/name canonical lowercase ASCII (Gitea policy) — case normalization authoritative only under the bound transport identity. - External-id binding creation requires an evidence record (`repository_external_id` subject) whose store = the transport's active identity authority store. `[SCHEMA]`. - Archival, re-encounter (`ARCHIVED_EXTERNAL_ID_REENCOUNTER` → reconciliation), locator conflict, reconciliation dispositions (`same_object_confirmed`/`distinct_object`/`refused`) with typed canonical prior/new values. `[SCHEMA]` CHECKs. - `registered_by` enforced via the authorized operation + actor context, not merely stored. `[TRUSTED-SERVICE]` + `[SCHEMA]` actor trigger. - Whether identifiers may be reused across configuration generations: define (recommended: `UNIQUE(store,ref)` prohibits reuse for the store lifetime). ## 5. Exclusions No canonical resources/refs (→ next child), no project associations (→ lookup child), no workspaces. ## 6. Schema/operation contracts `transports`, `transport_identity_authorities`, `repository_bindings`, `binding_reconciliations`. Operations: `register_transport`, `bind_transport_identity_authority`, `register_repository_binding`, `record_locator_change`, `archive_binding`, `decide_binding_reconciliation`, `resolve_binding`. ## 7. SQLite behavior Partial unique indexes: `rb_ext_id` (real external ids unique per transport, NULLs allowed), `rb_active_locator` (one active binding per `(transport,owner,name)` across modes). Host/locator CHECKs. ## 8. PostgreSQL behavior Same constraints; canonicalizers in the service; parity tested. ## 9. Concurrency / transaction requirements Concurrent bindings on one locator: one active survives; re-encounter routes to reconciliation rather than silently reactivating. ## 10. Structured results `BINDING_REGISTERED`, `AMBIGUOUS_LOCATOR`, `EXTERNAL_ID_PROOF_REQUIRED`, `ARCHIVED_EXTERNAL_ID_REENCOUNTER`, `RECONCILIATION_REQUIRED`, `TRANSPORT_HAS_ACTIVE_BINDINGS`, `RETIRED_AUTHORITY`. ## 11. Enforcement classification Uniqueness/CHECK/immutability/external-id binding `[SCHEMA]`; host/locator canonicalization `[TRUSTED-SERVICE]`; external-id issuance proof `[RUNTIME-ADAPTER]` (via #826). ## 12. Acceptance criteria 1. External-id binding requires a proof whose store = the transport's active identity authority. 2. One active binding per locator across both modes. 3. Real external ids unique per transport; NULLs allowed. 4. Malformed host/port rejected; IPv6 handled. 5. Continuity/binding-mode immutable. 6. Archived external-id re-encounter → reconciliation. 7. Transport retire blocked while active bindings exist. 8. `registered_by` = authenticated caller. ## 13. Named tests `t_extid_wrong_store`(−), `t_locator_collision_cross_mode`(−), `t_extid_unique`(−), `t_host_ipv6`(+), `t_host_bad_port`(−), `t_continuity_immutable`(raw-bypass), `t_archived_reencounter`(−), `t_transport_retire_guard`(−), `t_registered_by_foreign`(−). ## 14. Audit events / evidence `transport_registered`, `identity_authority_bound`, `binding_registered`, `binding_reconciled`. Test output evidence. ## 15. Dependencies / parent Parents #820, #828; depends #822, #826. ## 16. Definition of done Executable SQLite (+PG section); ACs pass incl. raw-bypass; bounded PR; no self-review/merge. ## 17. Known limitations / deferred `local_record_only` bindings remain unattended-ineligible (no upgrade path in this program). Ref/resource identity in the next child.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Scaled-Tech-Consulting/Gitea-Tools#829