ARCH-02 — Canonical resource identity and byte-safe Git reference handling #830

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

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

Parents: #820, #828. Depends on: #829 (bindings).

1. Summary / objective

Implement project-independent canonical resource identities (repository, ref, issue, pull_request, creation_namespace, work_item_transport) with an exact, justified Git-ref identity policy and closed identity-component enumerations.

2. Security/correctness problem

If two byte-distinct valid refs collapse to one identity, distinct branches share a lock; if unused identity components vary freely, a second row aliases the same real object; both defeat the mutual exclusion later mutation safety depends on.

3. Threat model / failure modes

NFC collapsing byte-distinct refs; invalid UTF-8/NUL; .lock/dot-component/@{/control-char refs accepted; shorthand vs full-ref ambiguity; unused-field variation minting alias identities; zero object numbers.

4. In-scope behavior

  • Ref identity policy — choose and justify one (recommended: restrict the platform to validated UTF-8 refs and prove every supported transport applies the same rule; alternative: preserve exact validated bytes). Do not silently NFC byte-distinct refs.
  • ref_canon_v1 [TRUSTED-SERVICE]: full-ref construction per kind (refs/heads/…, refs/tags/…, …); apply git check-ref-format rules — reject leading-. component, .., ASCII control, space, ~^:?*[\, component ending .lock, trailing /, //, trailing ., @{, lone @; define invalid-UTF-8 and NUL behavior (reject); canonicalizer input/output encoding + canonicalizer_version; migration behavior. Applied to every create and lookup path.
  • [SCHEMA] storable subset: refs/ prefix, no //, no trailing /, no space, trimmed, no .lock/../leading-./\/@{/~^:?*[ (GLOB + trigger). Rejection, not normalization.
  • Closed enums: object_family ∈ {'','pull_request','issue'}, work_item_kind ∈ {'','issue','pull_request'}; object numbers positive (-1 sentinel; zero invalid). [SCHEMA].
  • Exhaustive per-kind CHECK: every applicable field valued, every inapplicable field at sentinel. Unique key over all six identity columns. [SCHEMA].
  • Canonical-resource and association schemas; identity-component compatibility matrix; sentinel rules; resource status lifecycle.

5. Exclusions

No project authorization/lookup (→ next child), no bindings (→ #829), no workspaces.

6. Schema/operation contracts

canonical_resources, resource_project_associations (schema only; authorization in the lookup child). Operations: ensure_resource_for_project (internal_service), lookup_resource_for_project (read), resolve_pr_head/resolve_pr_base.

7. SQLite behavior

CHECK + GLOB + trigger for ref shape; unique index over identity columns; ON CONFLICT DO NOTHING mint.

8. PostgreSQL behavior

Same constraints; ref_canon_v1 in the service; SERIALIZABLE mint with retry.

9. Concurrency / transaction requirements

Concurrent ensure of one resource yields one row; ref canonicalizer applied identically on create and lookup so a lookup never misses a differently-spelled create.

10. Structured results

RESOURCE_ENSURED, RESOURCE_FOUND, NOT_FOUND, INVALID_IDENTITY_FIELDS, INVALID_REF, UNREGISTERED_SOURCE_REPOSITORY.

11. Enforcement classification

Identity-column uniqueness + per-kind CHECK + storable ref subset [SCHEMA]; full ref grammar [TRUSTED-SERVICE] (ref_canon_v1).

12. Acceptance criteria

  1. Two projects over one repository resolve identical resource ids.
  2. issue #Npull_request #N.
  3. Forked head → source binding, base → target binding.
  4. Varying any inapplicable field cannot mint a second identity.
  5. Equivalent ref spellings map to one row (or exact-bytes policy proven across transports).
  6. .lock/dot-component/control/@{ refs rejected.
  7. Invalid UTF-8/NUL rejected.
  8. Object numbers positive; zero invalid.

13. Named tests

t_shared_repo_resource(+), t_kind_collision(−), t_fork_head_base(+), t_inapplicable_field_variation(− ×kinds), t_ref_spelling_canonical(+), t_ref_prohibited_classes(− per class), t_ref_bad_utf8/t_ref_nul(−), t_object_number_zero(−).

14. Audit events / evidence

resource_minted. Canonicalizer version recorded. Test output evidence.

15. Dependencies / parent

Parents #820, #828; depends #829.

16. Definition of done

Executable SQLite (+PG); ref canonicalizer applied on all paths; ACs pass; bounded PR; no self-review/merge.

17. Known limitations / deferred

Full Git ref grammar lives in ref_canon_v1 [TRUSTED-SERVICE]; the DB enforces only the CHECK-expressible subset (labelled accordingly). Association authorization in the lookup child.

**Candidate architecture requiring executable validation; not yet approved, production-ready, or certified.** Parents: #820, #828. Depends on: #829 (bindings). ## 1. Summary / objective Implement project-independent canonical resource identities (repository, ref, issue, pull_request, creation_namespace, work_item_transport) with an exact, justified Git-ref identity policy and closed identity-component enumerations. ## 2. Security/correctness problem If two byte-distinct valid refs collapse to one identity, distinct branches share a lock; if unused identity components vary freely, a second row aliases the same real object; both defeat the mutual exclusion later mutation safety depends on. ## 3. Threat model / failure modes NFC collapsing byte-distinct refs; invalid UTF-8/NUL; `.lock`/dot-component/`@{`/control-char refs accepted; shorthand vs full-ref ambiguity; unused-field variation minting alias identities; zero object numbers. ## 4. In-scope behavior - **Ref identity policy — choose and justify one** (recommended: restrict the platform to validated UTF-8 refs and prove every supported transport applies the same rule; alternative: preserve exact validated bytes). Do **not** silently NFC byte-distinct refs. - `ref_canon_v1` `[TRUSTED-SERVICE]`: full-ref construction per kind (`refs/heads/…`, `refs/tags/…`, …); apply `git check-ref-format` rules — reject leading-`.` component, `..`, ASCII control, space, `~^:?*[\`, component ending `.lock`, trailing `/`, `//`, trailing `.`, `@{`, lone `@`; define invalid-UTF-8 and NUL behavior (reject); canonicalizer input/output encoding + `canonicalizer_version`; migration behavior. Applied to **every** create and lookup path. - `[SCHEMA]` storable subset: `refs/` prefix, no `//`, no trailing `/`, no space, trimmed, no `.lock`/`..`/leading-`.`/`\`/`@{`/`~^:?*[` (GLOB + trigger). Rejection, not normalization. - Closed enums: `object_family ∈ {'','pull_request','issue'}`, `work_item_kind ∈ {'','issue','pull_request'}`; object numbers positive (`-1` sentinel; zero invalid). `[SCHEMA]`. - Exhaustive per-kind CHECK: every applicable field valued, every inapplicable field at sentinel. Unique key over all six identity columns. `[SCHEMA]`. - Canonical-resource and association schemas; identity-component compatibility matrix; sentinel rules; resource status lifecycle. ## 5. Exclusions No project authorization/lookup (→ next child), no bindings (→ #829), no workspaces. ## 6. Schema/operation contracts `canonical_resources`, `resource_project_associations` (schema only; authorization in the lookup child). Operations: `ensure_resource_for_project` (internal_service), `lookup_resource_for_project` (read), `resolve_pr_head`/`resolve_pr_base`. ## 7. SQLite behavior CHECK + GLOB + trigger for ref shape; unique index over identity columns; `ON CONFLICT DO NOTHING` mint. ## 8. PostgreSQL behavior Same constraints; `ref_canon_v1` in the service; `SERIALIZABLE` mint with retry. ## 9. Concurrency / transaction requirements Concurrent `ensure` of one resource yields one row; ref canonicalizer applied identically on create and lookup so a lookup never misses a differently-spelled create. ## 10. Structured results `RESOURCE_ENSURED`, `RESOURCE_FOUND`, `NOT_FOUND`, `INVALID_IDENTITY_FIELDS`, `INVALID_REF`, `UNREGISTERED_SOURCE_REPOSITORY`. ## 11. Enforcement classification Identity-column uniqueness + per-kind CHECK + storable ref subset `[SCHEMA]`; full ref grammar `[TRUSTED-SERVICE]` (`ref_canon_v1`). ## 12. Acceptance criteria 1. Two projects over one repository resolve identical resource ids. 2. `issue #N` ≠ `pull_request #N`. 3. Forked head → source binding, base → target binding. 4. Varying any inapplicable field cannot mint a second identity. 5. Equivalent ref spellings map to one row (or exact-bytes policy proven across transports). 6. `.lock`/dot-component/control/`@{` refs rejected. 7. Invalid UTF-8/NUL rejected. 8. Object numbers positive; zero invalid. ## 13. Named tests `t_shared_repo_resource`(+), `t_kind_collision`(−), `t_fork_head_base`(+), `t_inapplicable_field_variation`(− ×kinds), `t_ref_spelling_canonical`(+), `t_ref_prohibited_classes`(− per class), `t_ref_bad_utf8`/`t_ref_nul`(−), `t_object_number_zero`(−). ## 14. Audit events / evidence `resource_minted`. Canonicalizer version recorded. Test output evidence. ## 15. Dependencies / parent Parents #820, #828; depends #829. ## 16. Definition of done Executable SQLite (+PG); ref canonicalizer applied on all paths; ACs pass; bounded PR; no self-review/merge. ## 17. Known limitations / deferred Full Git ref grammar lives in `ref_canon_v1` `[TRUSTED-SERVICE]`; the DB enforces only the CHECK-expressible subset (labelled accordingly). Association authorization in the lookup 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#830