2026-08-16 18:54:39 +02:00
|
|
|
|
---
|
2026-08-19 01:09:18 +02:00
|
|
|
|
id: CUST-ADR-007
|
2026-08-16 18:54:39 +02:00
|
|
|
|
type: architecture-decision-record
|
|
|
|
|
|
title: "Workplan Identity Uniqueness, Single Registrar, and Repo Worker Topology"
|
2026-08-17 10:17:58 +02:00
|
|
|
|
status: accepted
|
2026-08-19 01:09:18 +02:00
|
|
|
|
owner: the-custodian
|
2026-08-31 21:17:38 +02:00
|
|
|
|
revision: "accepted-2"
|
|
|
|
|
|
last_reviewed: "2026-08-31"
|
2026-08-19 01:09:18 +02:00
|
|
|
|
review_interval: 6m
|
2026-08-16 18:54:39 +02:00
|
|
|
|
decided_by: Bernd Worsch
|
|
|
|
|
|
date: "2026-08-16"
|
2026-08-17 10:17:58 +02:00
|
|
|
|
accepted: "2026-08-17"
|
2026-08-16 18:54:39 +02:00
|
|
|
|
tags: ["architecture", "workplans", "identity", "state-hub", "repo-manager", "agents", "registrar"]
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# ADR-007: Workplan Identity Uniqueness, Single Registrar, and Repo Worker Topology
|
|
|
|
|
|
|
|
|
|
|
|
## Status
|
|
|
|
|
|
|
2026-08-17 10:17:58 +02:00
|
|
|
|
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`.
|
2026-08-16 18:54:39 +02:00
|
|
|
|
|
|
|
|
|
|
## 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 |
|
2026-08-17 10:19:03 +02:00
|
|
|
|
| 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.
|
2026-08-16 18:54:39 +02:00
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
2026-08-17 13:04:04 +02:00
|
|
|
|
> **Amended 2026-08-17 by `ADR-011` decision 2.** Uniqueness and forward-only
|
2026-08-17 12:47:12 +02:00
|
|
|
|
> allocation are **namespace-scoped**, not global; global identity is the pair
|
|
|
|
|
|
> `(namespace, identifier)`, written `PREFIX-WP-NNNN@namespace` when foreign.
|
|
|
|
|
|
> Global sequential allocation would require a central coordinator — the exact
|
|
|
|
|
|
> dependency federation must survive. Everything below holds unchanged **within**
|
|
|
|
|
|
> a namespace, which is where all current work sits.
|
|
|
|
|
|
|
2026-08-16 18:54:39 +02:00
|
|
|
|
- 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).
|
|
|
|
|
|
|
2026-08-17 10:17:58 +02:00
|
|
|
|
**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.
|
|
|
|
|
|
|
|
|
|
|
|
*Target state (C2).* `state_hub_workstream_id` and `state_hub_task_id` become
|
2026-08-17 13:04:04 +02:00
|
|
|
|
**deterministic**: UUIDv5 derived from the workplan identifier. Per `ADR-011`
|
2026-08-17 12:47:12 +02:00
|
|
|
|
decision 3 the derivation input is the pair `(namespace, identifier)`, not the
|
|
|
|
|
|
identifier alone — deriving from the identifier alone would make two forks
|
|
|
|
|
|
holding unrelated work under the same number compute the same UUID. Every instance computes the same value independently, writeback
|
2026-08-17 10:17:58 +02:00
|
|
|
|
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,
|
2026-08-17 12:18:01 +02:00
|
|
|
|
but must not mint workplan or task UUIDs into git-tracked files.
|
|
|
|
|
|
|
2026-08-17 13:04:04 +02:00
|
|
|
|
> **Corrected 2026-08-17, superseded by `ADR-010` decisions 1–3.** This decision
|
2026-08-17 12:18:01 +02:00
|
|
|
|
> originally described workstation hubs as "development read replicas". That was
|
|
|
|
|
|
> wrong on both counts: the workstation instance was not a replica, and it was
|
|
|
|
|
|
> the *larger* of the two, holding 306 more workplans than the primary. The two
|
2026-08-17 13:04:04 +02:00
|
|
|
|
> instances were peer databases. `ADR-010` establishes the central hub as
|
2026-08-17 12:18:01 +02:00
|
|
|
|
> authoritative and local instances as rebuildable caches, which is what makes
|
|
|
|
|
|
> this interim rule coherent.
|
2026-08-17 10:17:58 +02:00
|
|
|
|
|
|
|
|
|
|
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.
|
2026-08-16 18:54:39 +02:00
|
|
|
|
|
2026-08-21 06:36:06 +02:00
|
|
|
|
> **Amended 2026-08-21 — derivation scope for C2.** `ADR-011` decision 7 keys
|
|
|
|
|
|
> derivation on `(namespace, identifier)`, which separates *forks*. It does not
|
|
|
|
|
|
> separate collisions inside one namespace, and the ecosystem's posture is `N1`
|
|
|
|
|
|
> — a single implied namespace. A fleet scan on 2026-08-21 found **20 reused
|
|
|
|
|
|
> identifiers across 48 files**, all within that one namespace, so the
|
|
|
|
|
|
> prerequisite above is not satisfied by `ADR-011` alone.
|
|
|
|
|
|
>
|
|
|
|
|
|
> Ruled: **C2 derives only for live records; archived records keep their minted
|
|
|
|
|
|
> identifiers, frozen.** This is what reconciles § Migration option 2 — under
|
|
|
|
|
|
> which historical files keep colliding identifiers — with the uniqueness
|
|
|
|
|
|
> derivation requires. Of the 20, only **five** collide among live files, so the
|
|
|
|
|
|
> remediation surface is 11 files rather than 48.
|
|
|
|
|
|
>
|
|
|
|
|
|
> Two consequences follow, and both are load-bearing:
|
|
|
|
|
|
>
|
|
|
|
|
|
> 1. **Un-archiving a record with a frozen identifier is a collision hazard.**
|
|
|
|
|
|
> A record returning to live status must be checked against the live
|
|
|
|
|
|
> namespace before it is re-derived, and renumbered if it clashes.
|
|
|
|
|
|
> 2. **Derivation is not retroactive.** Existing live records keep their minted
|
|
|
|
|
|
> UUIDs until they are re-derived deliberately; C2 changes provenance for new
|
|
|
|
|
|
> and re-registered records, not the whole corpus at once.
|
|
|
|
|
|
>
|
|
|
|
|
|
> Rejected: treating a *repository* as the namespace. That would make the
|
|
|
|
|
|
> collisions vanish by construction, but it redefines the term `ADR-011`
|
|
|
|
|
|
> decision 1 fixes as "a fleet instance, a client deployment, an autonomous
|
|
|
|
|
|
> domain", and `ADR-011` decision 9 warns specifically against reading N-plane
|
|
|
|
|
|
> movement into claims it does not support.
|
|
|
|
|
|
|
2026-08-16 18:54:39 +02:00
|
|
|
|
**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.
|
|
|
|
|
|
|
2026-08-17 10:24:15 +02:00
|
|
|
|
**Ruled 2026-08-17: option 2.** Renumber live collisions; leave
|
|
|
|
|
|
`finished`/`archived` duplicates as historical record.
|
2026-08-16 18:54:39 +02:00
|
|
|
|
|
2026-08-17 10:24:15 +02:00
|
|
|
|
### The live renumber list is empty
|
|
|
|
|
|
|
|
|
|
|
|
Verified against the fleet scan. All five duplicated identifiers are `finished`:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
CUST-WP-0000 the-custodian ×2 finished
|
|
|
|
|
|
CUST-WP-0010 the-custodian ×2 finished
|
|
|
|
|
|
CUST-WP-0045 the-custodian ×2 finished
|
|
|
|
|
|
RAILIANCE-WP-0015 apps, platform finished
|
|
|
|
|
|
RAILIANCE-WP-0016 apps, platform ×2 finished
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
No workplan in a `proposed`, `ready`, `active`, `blocked`, or `backlog` state
|
|
|
|
|
|
shares an identifier with another. **Option 2 therefore requires no renumbering
|
|
|
|
|
|
today.** Historical duplicates stay, including the `RAILIANCE-WP-0015` ambiguity
|
|
|
|
|
|
between `railiance-apps` and `railiance-platform`; citations of it must name the
|
|
|
|
|
|
repository.
|
|
|
|
|
|
|
|
|
|
|
|
### The structural cause is not historical
|
|
|
|
|
|
|
|
|
|
|
|
Option 2 governs *remediation*. It does not exempt anything from decision 1,
|
|
|
|
|
|
which is accepted canon: one prefix, one repository, forward-only numbering.
|
|
|
|
|
|
|
|
|
|
|
|
Three shared prefixes are still in use across seven repositories, and each is a
|
|
|
|
|
|
**single number line being allocated from concurrently**:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
RAIL-BS-WP- bootstrap 8, 9
|
|
|
|
|
|
cluster 7, 10, 11, 12, 13, 14
|
|
|
|
|
|
|
|
|
|
|
|
RAILIANCE-WP- platform 5, 8-17 (16 twice — an internal duplicate)
|
|
|
|
|
|
apps 15, 16 <- already collided with platform
|
|
|
|
|
|
forge 2
|
|
|
|
|
|
telemetry 1
|
|
|
|
|
|
|
|
|
|
|
|
CUST-WP- the-custodian 50 plans
|
|
|
|
|
|
state-hub 4 legacy plans (canonical prefix is STATE-WP)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
`RAIL-BS-` and `RAILIANCE-` are actively growing — `RAIL-BS-WP-0014` (`ready`),
|
|
|
|
|
|
`RAILIANCE-WP-0002` (`ready`), `RAILIANCE-WP-0001` (`proposed`), all created
|
|
|
|
|
|
2026-08-11 or later. The `RAILIANCE-WP-0015`/`0016` collisions were not a
|
|
|
|
|
|
historical accident; they are what concurrent allocation from a shared sequence
|
|
|
|
|
|
produces, and it will recur at the next concurrent allocation.
|
|
|
|
|
|
|
|
|
|
|
|
`CUST-` is dormant on the `state-hub` side — four legacy plans, one in
|
|
|
|
|
|
`backlog` — and needs no split, only a prefix-ownership assertion.
|
|
|
|
|
|
|
2026-08-17 10:41:03 +02:00
|
|
|
|
### Prefix assignments
|
|
|
|
|
|
|
|
|
|
|
|
`RAIL-BS-WP-` is **retired** (2026-08-17). Neither repository keeps it:
|
|
|
|
|
|
`railiance-cluster` adopts `RCLUSTER-WP-` for active and future plans;
|
|
|
|
|
|
`railiance-bootstrap` adopts `RBS-WP-` for future plans. Finished and archived
|
|
|
|
|
|
files keep `RAIL-BS-WP-` as historical record, consistent with option 2.
|
|
|
|
|
|
|
|
|
|
|
|
Migrating plans keep their running numbers — the prefix changes, the number does
|
|
|
|
|
|
not. This preserves traceability and cannot violate forward-only allocation,
|
|
|
|
|
|
because neither new prefix has prior history. `railiance-bootstrap` begins at
|
|
|
|
|
|
`RBS-WP-0010`, above its historical maximum, leaving the lower range free should
|
|
|
|
|
|
its finished plans ever be adopted into the new prefix.
|
|
|
|
|
|
|
|
|
|
|
|
`RAILIANCE-WP-` should follow the same pattern — retired rather than awarded to
|
|
|
|
|
|
one repository, since it names a family rather than a repository and so fails
|
|
|
|
|
|
decision 1 for the same reason `PRJ-WP-` does. Assignment of the four successor
|
|
|
|
|
|
prefixes is outstanding.
|
|
|
|
|
|
|
|
|
|
|
|
Execution of each rename belongs to a worker in the owning repository under
|
|
|
|
|
|
decision 4. `RMGR-WP-0004-T09` records assignments and the numbering rule; it
|
|
|
|
|
|
does not perform renames.
|
|
|
|
|
|
|
2026-08-17 10:24:15 +02:00
|
|
|
|
**Consequence.** Prefix ownership must be assigned for all three shared prefixes
|
|
|
|
|
|
before the next workplan is created in the affected repositories. This is
|
|
|
|
|
|
forward conformance under decision 1, not migration, and is tracked as
|
|
|
|
|
|
`RMGR-WP-0004-T09`. Renaming the *historical* files is explicitly not required —
|
|
|
|
|
|
that would be option 3, which was rejected.
|
2026-08-16 18:54:39 +02:00
|
|
|
|
|
|
|
|
|
|
## 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
|