Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 93 additions & 7 deletions dag/gunbc/roadmap_authority.dag

Large diffs are not rendered by default.

99 changes: 99 additions & 0 deletions dag/gunbc/roadmap_identity.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
module gunbc.roadmap_identity

import std.types { String, NonEmptyStr, Bool, Int, List }
import gunbc.roadmap_model { RoadmapNode, RoadmapNodeId, RoadmapNodeIdentity }
import gunbc.roadmap_authority { declared_roadmap_nodes }

data roadmap_identity_index_derivation_note: String = "THE INDEX IS DERIVED, NEVER AUTHORED. An earlier cut carried a hand-written list of (identity, slug) rows beside the authority, which created two things that had to be kept in step and could disagree — the DESIGN 3 fork, with a witness standing in for a construction (DESIGN 5). Identity is now a required field on RoadmapNode, so a node without one is unwritable, and everything below is a projection of declared_roadmap_nodes(). There is exactly one place a node's identity can be stated, and the index cannot drift from it because it has no independent existence."

data roadmap_identity_lifecycle_note: String = "PERMANENT NON-REUSE NEEDS A TOMBSTONE, and a base-versus-head diff alone cannot supply it. Without persisted retirement the sequence is: PR A removes node X and its row; a diff gate observes the removal once; after merge X is simply absent from the base registry; PR B mints a new node and reuses X's identity; the next base-versus-head comparison sees an identity that is present in head and absent in base — indistinguishable from a legitimately NEW identity. The reuse passes every check.\\n\\nSo retirement is a state, not a deletion. A Tombstoned row keeps the identity in the registry forever, carries the slug it last wore so historical links still resolve, and names the identity that superseded it when there is one. Retirement is then observable rather than inferred from absence, and 'may never become active again' becomes checkable."

type RoadmapIdentityRecord
= ActiveIdentity {
identity: RoadmapNodeIdentity,
slug: RoadmapNodeId,
}
| TombstonedIdentity {
identity: RoadmapNodeIdentity,
former_slug: RoadmapNodeId,
superseded_by: RoadmapNodeIdentity?,
}

data roadmap_tombstone_roster_note: String = "Empty today, and that is the honest state rather than a placeholder: no roadmap node has yet been retired under this model. The row exists so the first retirement has a home that is not deletion — the failure the 2026-07-27 authority refresh already demonstrated, when a node carrying the only execution contract was removed and nothing noticed. A retirement lands here in the same change that removes the node from declared_roadmap_nodes()."

fn roadmap_tombstoned_identities() -> List<RoadmapIdentityRecord> {
[]
}

fn roadmap_active_identities() -> List<RoadmapIdentityRecord> {
declared_roadmap_nodes() |> map(n => ActiveIdentity {
identity: n.identity,
slug: n.node,
})
}

fn roadmap_identity_registry() -> List<RoadmapIdentityRecord> {
concat(roadmap_active_identities(), roadmap_tombstoned_identities())
}

fn record_identity(r: RoadmapIdentityRecord) -> String {
match r {
ActiveIdentity { identity, slug: _ } => identity as String
TombstonedIdentity { identity, former_slug: _, superseded_by: _ } => identity as String
}
}

fn record_slug(r: RoadmapIdentityRecord) -> String {
match r {
ActiveIdentity { identity: _, slug } => slug as String
TombstonedIdentity { identity: _, former_slug, superseded_by: _ } => former_slug as String
}
}

fn record_is_active(r: RoadmapIdentityRecord) -> Bool {
match r {
ActiveIdentity { identity: _, slug: _ } => true
TombstonedIdentity { identity: _, former_slug: _, superseded_by: _ } => false
}
}

data roadmap_identity_resolution_note: String = "Resolution is EXACTLY-ONE, not first-pick. A filter-map-first lookup answers a duplicate registry with a plausible first row, which is the fabricated-plausible-output arm DESIGN 5 forbids — and it fails at exactly the moment the registry is corrupt, when a confident wrong answer is worst. The three outcomes are distinct because their remedies are: a MISSING identity is an unknown reference; a DUPLICATE is a corrupt registry; found is found. Callers match the sum rather than unwrapping an Optional that cannot tell those apart."

type RoadmapIdentityResolution
= IdentityResolved { identity: RoadmapNodeIdentity }
| IdentityUnknown { slug: String }
| IdentityAmbiguous { slug: String, matches: Int }

fn resolve_slug(slug: String) -> RoadmapIdentityResolution {
let hits = roadmap_identity_registry() |> filter(r => record_slug(r: r) == slug)
if count(hits) == 0 {
IdentityUnknown { slug: slug }
} else if count(hits) > 1 {
IdentityAmbiguous { slug: slug, matches: count(hits) }
} else {
match hits |> map(r => record_identity(r: r)) |> first {
Present { value: i } => IdentityResolved { identity: i as RoadmapNodeIdentity }
Absent => IdentityUnknown { slug: slug }
}
}
}

fn identity_count() -> Int { count(roadmap_identity_registry()) }

fn distinct_count(values: List<String>) -> Int {
count(fold(values, init: [], f: fn(acc, v) {
if any(acc, e => e == v) { acc } else { append(acc, [v]) }
}))
}

fn distinct_identity_count() -> Int {
distinct_count(values: roadmap_identity_registry() |> map(r => record_identity(r: r)))
}

fn distinct_active_slug_count() -> Int {
distinct_count(values: roadmap_active_identities() |> map(r => record_slug(r: r)))
}

fn active_identity_count() -> Int { count(roadmap_active_identities()) }

data roadmap_identity_permanence_gate_note: String = "WHAT A SNAPSHOT CAN AND CANNOT PROVE, stated so the gap is not mistaken for coverage. The claims below are statements about the CURRENT tree: identities unique across active and tombstoned rows, active slugs unique, every declared node carrying one, resolution exactly-one. None can see history, and permanence is historical — an identity silently REPLACED between base and head produces a tree satisfying every one of them.\\n\\nThe missing mechanism is a base-versus-head comparison of this registry, which the CI floor already has the shape for in its merge-base diff observation. ADMITTED: an active identity retained across a slug change; a new identity added; an active identity becoming Tombstoned. REFUSED: an active identity replaced by a different value for the same work; a tombstoned identity returning to active; an identity disappearing from the registry entirely rather than being tombstoned; two records sharing one identity; one active slug resolving to two identities.\\n\\nThe tombstone carrier above is what makes that gate implementable at all — reuse is only detectable because retirement persists. Until the gate runs, permanence rests on review, and this row keeps that fact countable rather than forgotten."
5 changes: 5 additions & 0 deletions dag/gunbc/roadmap_model.dag
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import gunbc.roadmap_execution_contract { WorkItemExecutionContract }

type RoadmapNodeId = NonEmptyStr where brand("RoadmapNodeId")

data roadmap_node_identity_law: String = "A roadmap node's identity is MINTED, never derived. Slug, title, criteria digest, containment position, dependency neighbourhood, declaration order and file position are FORBIDDEN identity inputs — the law std.occurrence_identity states for occurrences, generalized to an entity that must outlive the graph it is read from.\n\nThe law is reused; the TYPE deliberately is not. std.occurrence_identity.OccurrenceId is an ordinal from a per-graph allocator starting at zero, so it is unique only INSIDE one constructed graph: inserting a node at the front renumbers every node after it, and two concurrent branches mint the same next integer. That is positional identity wearing an allocator's clothes — right for occurrences within one parse, wrong for a work item that must survive edits, reordering, regeneration and independent branches. What occurrence identity deliberately does not claim is PERSISTENCE SCOPE, and that is precisely what a roadmap node needs.\n\nIdentity is a REQUIRED FIELD rather than a side registry keyed by slug. A registry beside the authority leaves a node authorable without identity, detectable only by a later witness — validation standing where construction was available (DESIGN 5), and two authorities that must be kept in step (DESIGN 3). As a field, a node without durable identity is unwritable, and the slug index is DERIVED from the nodes rather than independently authored, so the two can never disagree."

type RoadmapNodeIdentity = NonEmptyStr where brand("RoadmapNodeIdentity")

type Pointer { label: String, path: String }

type Intricacy
Expand All @@ -35,6 +39,7 @@ type NodeSizing
| Sized { intricacy: Intricacy, volume: Volume, repo: String, acceptance: Acceptance }

type RoadmapNode {
identity: RoadmapNodeIdentity
node: RoadmapNodeId
line: RoadmapItem
carriers: List<Pointer>
Expand Down
7 changes: 4 additions & 3 deletions dag/test/claim/roadmap_altitude_witness_test.dag
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@ fn doc_html(nodes: List<RoadmapNode>) -> String {
}

fn done_signed_node() -> RoadmapNode {
let base = authored(id: "alt-done", done: true, content: "finished work")
let base = authored(identity: "rnfx_WA4EZDD0ZGMCQMTKQA21", id: "alt-done", done: true, content: "finished work")
RoadmapNode {
identity: "rnfx_2K15QJ1CVZY55K15AHJK" as RoadmapNodeIdentity,
node: base.node,
line: base.line,
carriers: base.carriers,
Expand All @@ -89,7 +90,7 @@ fn done_signed_node() -> RoadmapNode {
}

fn open_node() -> RoadmapNode {
authored(id: "alt-open", done: false, content: "working item")
authored(identity: "rnfx_140ZV0QZTY3R9PTENK99", id: "alt-open", done: false, content: "working item")
}

data fold_by_statuses_note: String = "The fold decision proven over the RENDERED page, not the predicate alone: an all-routine section serializes its details WITHOUT the open attribute (folded — the summary band still carries the counts, so nothing is hidden silently), and adding one working member to the same section flips the SAME serialization to open. The two fixtures differ by exactly that member, so the discrimination is located in the status data — hand-curation has no input to reach. Fixture lesson, kept: a done-but-UNSIGNED node renders review (the sign-off gate), and review is WORKING under the law — the operator's pending gesture holds a section open, which is the attention law agreeing with the sign-off discipline rather than a coincidence. Routine therefore requires the signed fixture."
Expand All @@ -108,7 +109,7 @@ test fn altitude_working_member_holds_section_open() -> Bool {
}

test fn altitude_unsigned_done_holds_section_open() -> Bool {
let unsigned_done = doc_html(nodes: [authored(id: "alt-unsigned", done: true, content: "done but unsigned")])
let unsigned_done = doc_html(nodes: [authored(identity: "rnfx_0A9N7HZG1Q9HRP760WD7", id: "alt-unsigned", done: true, content: "done but unsigned")])
return string_contains(s: unsigned_done, pattern: "<details class=\"section-fold\" open=\"\">")
&& string_contains(s: unsigned_done, pattern: "1 review")
}
Expand Down
1 change: 1 addition & 0 deletions dag/test/claim/roadmap_authority_test.dag
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ fn active_node_admissible(n: RoadmapNode) -> Bool {

fn red_fixture(line: RoadmapItem, signoff: Signoff) -> RoadmapNode {
RoadmapNode {
identity: "rnfx_8E5PG4F7CAZ148VZ8MNY" as RoadmapNodeIdentity,
node: "red-fixture",
line: line,
carriers: [Pointer { label: "authority", path: "DESIGN.md" }],
Expand Down
2 changes: 2 additions & 0 deletions dag/test/claim/roadmap_belt_actuate_witness_test.dag
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ fn nid(s: String) -> RoadmapNodeId { s }

fn ready_node(id: String) -> RoadmapNode {
RoadmapNode {
identity: "rnfx_RWT4XRCGS4GR90YZXK0Y" as RoadmapNodeIdentity,
node: nid(s: id),
line: DerivableLine { prs: [1], title: id, description: "" },
carriers: [],
Expand Down Expand Up @@ -315,6 +316,7 @@ test fn witness_find_node_misses() -> Bool {

fn owned_node(id: String, owner: String) -> RoadmapNode {
RoadmapNode {
identity: "rnfx_F2RWDMNTDKS0ZR1P4VNZ" as RoadmapNodeIdentity,
node: nid(s: id),
line: DerivableLine { prs: [1], title: id, description: "" },
carriers: [],
Expand Down
1 change: 1 addition & 0 deletions dag/test/claim/roadmap_belt_witness_test.dag
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ fn nid(s: String) -> RoadmapNodeId { s }

fn ready_node(id: String) -> RoadmapNode {
RoadmapNode {
identity: "rnfx_P2E65A1P1148Z5Y175QT" as RoadmapNodeIdentity,
node: nid(s: id),
line: DerivableLine { prs: [1], title: id, description: "" },
carriers: [],
Expand Down
3 changes: 2 additions & 1 deletion dag/test/claim/roadmap_dispatch_actuator_witness_test.dag
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ fn nid(s: String) -> RoadmapNodeId { s }

fn sized_derivable(id: String, prs: List<Int>, title: String) -> RoadmapNode {
RoadmapNode {
identity: "rnfx_R2PE6DBK7RVVR2NHNQN0" as RoadmapNodeIdentity,
node: nid(s: id),
line: DerivableLine { prs: prs, title: title, description: "" },
carriers: [],
Expand Down Expand Up @@ -563,7 +564,7 @@ test fn witness_session_lease_shape_reused() -> Bool {
}

fn ticket_fixture_node() -> RoadmapNode {
gunbc.roadmap_authority.ticket_wi(id: "ticket-fixture", done: false, t: TicketFields {
gunbc.roadmap_authority.ticket_wi(identity: "rnfx_QSK1R8XNYS14GRZEVM6C", id: "ticket-fixture", done: false, t: TicketFields {
headline: "Fixture Headline",
brief: "A short brief.",
displaced_cost: "the real displaced cost",
Expand Down
3 changes: 3 additions & 0 deletions dag/test/claim/roadmap_document_test.dag
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ data child_id: RoadmapNodeId = "host-fed-status-bridge"

fn audit_node() -> RoadmapNode {
RoadmapNode {
identity: "rnfx_J19302B1RYEQZVMM6TG9" as RoadmapNodeIdentity,
node: audit_id,
line: AuthoredLine { done: true, content: "**fail-open audit**" },
carriers: [Pointer { label: "plan", path: "docs/plans/fail-closed-lockdown.md" }],
Expand All @@ -28,6 +29,7 @@ fn audit_node() -> RoadmapNode {

fn status_node() -> RoadmapNode {
RoadmapNode {
identity: "rnfx_AJ7G9SDD8FFX86WHFYQB" as RoadmapNodeIdentity,
node: status_id,
line: DerivableLine { prs: [5491], title: "**PR-checkbox status**", description: "" },
carriers: [],
Expand All @@ -39,6 +41,7 @@ fn status_node() -> RoadmapNode {
}
fn child_node() -> RoadmapNode {
RoadmapNode {
identity: "rnfx_ABYCNZ3BDSY98CHYC51T" as RoadmapNodeIdentity,
node: child_id,
line: AuthoredLine { done: false, content: "**host-fed status bridge**" },
carriers: [],
Expand Down
4 changes: 4 additions & 0 deletions dag/test/claim/roadmap_emit_test.dag
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ data child_id: RoadmapNodeId = "pr-checkbox-status"

fn parent_node() -> RoadmapNode {
RoadmapNode {
identity: "rnfx_5E27VQFME81E3RP60RE6" as RoadmapNodeIdentity,
node: parent_id,
line: AuthoredLine { done: false, content: "**invert hand-maintained**" },
carriers: [Pointer { label: "plan", path: "docs/plans/invert-hand-maintained.md" }],
Expand All @@ -27,6 +28,7 @@ fn parent_node() -> RoadmapNode {

fn child_node() -> RoadmapNode {
RoadmapNode {
identity: "rnfx_8P7AJ3QVQCM2E8W3AMR7" as RoadmapNodeIdentity,
node: child_id,
line: DerivableLine { prs: [5491], title: "**PR-checkbox status**", description: "" },
carriers: [],
Expand All @@ -39,6 +41,7 @@ fn child_node() -> RoadmapNode {

fn signed_child_node() -> RoadmapNode {
RoadmapNode {
identity: "rnfx_D1QNZ9290W7D8GPH4XJQ" as RoadmapNodeIdentity,
node: child_id,
line: DerivableLine { prs: [5491], title: "**PR-checkbox status**", description: "" },
carriers: [],
Expand Down Expand Up @@ -110,6 +113,7 @@ test fn witness_multi_parent_dependencies_render_complete_set() -> Bool {

fn superseded_child_node() -> RoadmapNode {
RoadmapNode {
identity: "rnfx_HSDEAR3FG68K530CRD70" as RoadmapNodeIdentity,
node: child_id,
line: SupersededLine { by: "successor-lane", content: "**PR-checkbox status**" },
carriers: [],
Expand Down
5 changes: 5 additions & 0 deletions dag/test/claim/roadmap_frontier_witness_test.dag
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ fn nid(s: String) -> RoadmapNodeId { s }

fn sized_derivable(id: String, prs: List<Int>, title: String) -> RoadmapNode {
RoadmapNode {
identity: "rnfx_JAGJGPTHTYSG1GEDN9BA" as RoadmapNodeIdentity,
node: nid(s: id),
line: DerivableLine { prs: prs, title: title, description: "" },
carriers: [],
Expand All @@ -38,6 +39,7 @@ fn sized_derivable(id: String, prs: List<Int>, title: String) -> RoadmapNode {

fn accepted_node(base: RoadmapNode) -> RoadmapNode {
RoadmapNode {
identity: "rnfx_QBNJEXMAX2KQWS838BE3" as RoadmapNodeIdentity,
node: base.node,
line: base.line,
carriers: base.carriers,
Expand All @@ -50,6 +52,7 @@ fn accepted_node(base: RoadmapNode) -> RoadmapNode {

fn unsized_derivable(id: String, prs: List<Int>, title: String) -> RoadmapNode {
RoadmapNode {
identity: "rnfx_CMY81J4ZCKAVZFQEAEFV" as RoadmapNodeIdentity,
node: nid(s: id),
line: DerivableLine { prs: prs, title: title, description: "" },
carriers: [],
Expand Down Expand Up @@ -177,6 +180,7 @@ test fn witness_page_renders_four_buckets() -> Bool {

fn superseded_node_fixture(id: String, by: String) -> RoadmapNode {
RoadmapNode {
identity: "rnfx_7WGSEGZK2FRN2VY0DWFC" as RoadmapNodeIdentity,
node: nid(s: id),
line: SupersededLine { by: by, content: "Old Row" },
carriers: [],
Expand All @@ -189,6 +193,7 @@ fn superseded_node_fixture(id: String, by: String) -> RoadmapNode {

fn signed_sized_superseded_node_fixture(id: String, by: String) -> RoadmapNode {
RoadmapNode {
identity: "rnfx_2M0H9GXC2H0A5CZ9V7HW" as RoadmapNodeIdentity,
node: nid(s: id),
line: SupersededLine { by: by, content: "Accepted Old Row" },
carriers: [],
Expand Down
Loading
Loading