Development record
Personas Come From the Registry; the Role Picks the Name
Rule
Every persona in a user story, press-release quote, worked example, or scenario comes from the registry at .abcd/development/personas.json — the single source of truth for the roster. Selection is by role, never by name: the scenario's audience determines the role, and the role's registered name is used. Names form a fixed alphabetical sequence (Alice, Bob, Carol, Dave, …); when the roster grows, new personas continue the sequence. No invented names, no real people's names as stand-ins. Every persona is referred to as they/them; the real user, when referred to at all, is also they/them.
The name half of the rule is mechanically enforced: the persona_registry record-lint rule (blocker) flags any quote attribution of the form said <Name>, — Unicode-wide, including compound names — whose name is not in the registry. Attributions phrased any other way, the role-match, and the pronoun halves are review-enforced.
Why
Persona names are load-bearing noise: a bespoke name per document makes readers wonder whether the name carries meaning, and a real-sounding name risks colliding with an actual person or project. Binding names to roles makes them carry exactly one bit of meaning — the audience — consistently across the whole corpus: Frank is always the DevOps voice, Kira always the maintainer's, Iris the product thinker's. The alphabetical sequence keeps the roster auditable and extension mechanical.
The 2026-07-08 dependency sweep demonstrated the failure mode this kills: twenty quote attributions had drifted to invented names (Theo, Mara, Priya, Fatima, "Dev") or role-mismatched roster names, hand-corrected in one pass. A registry with a lint gate prevents the drift from re-accumulating.
What's In Scope
- The registry file (
personas.json: roster, role hints, selection convention) as the roster's single source of truth. - The
persona_registryrecord-lint rule: quote-attribution names must be registry members; blocker severity; historical record (superseded/,research/) exempt via the standard content-drift exemption. - Role-first selection and they/them reference as review-enforced convention wherever the mechanical gate cannot reach (role fit, pronouns, non-attribution mentions).
What's Out of Scope
- Mechanical role-match enforcement (requires semantic judgement of the stated role against
role_hints). - Pronoun linting (they/them violations are a review concern; a pronoun regex cannot see referents).
- Real-name/PII detection generally — that is the itd-74 banlist family's job.
Acceptance Criteria
BDD format, per the itd-1 discipline.
- Given an intent whose press-release quote is attributed to a name not in
personas.json, when record-lint runs, then apersona_registryblocker finding names the file, line, and offending name. - Given a quote attributed to a registry persona, when record-lint runs, then no persona finding is raised for that line.
- Given a file under an exempt path (historical record), when record-lint runs, then persona attributions in it are not flagged.
- Given the registry gains a persona (continuing the alphabetical sequence), when a new intent quotes that persona, then the lint passes without any lint-config change — the roster file is the only thing edited.
References
- Registry:
.abcd/development/personas.json(schema_version 2 — role-first selection convention). - Gate:
persona_registryrule in.abcd/record-lint.json, implemented ininternal/core/lint/persona.go. - Lineage: promoted from the
principles/layer per the promotion path recorded inprinciples/README.md; decision lines of 2026-07-08: dcn-2607080000000002, dcn-2607080000000003, dcn-2607080000000004, dcn-2607080000000005. - Convention prior art: controlled-vocabulary field binding (DITA subject-scheme pattern) — see
ACKNOWLEDGEMENTS.md.
Frontmatter
| id | itd-79 |
|---|---|
| type | intent |
| lifecycle | disciplines |
| kind | discipline |
| severity | minor |
.abcd/development/intents/disciplines/itd-79-persona-registry.md
open on GitHub ↗ · commit history ↗
Referenced by2
- iss-2610262043159613itd-79 requires every press-release quote's persona to be the role's registered name; itd-198 attributes its quote to an unnamed role.related
- iss-2610262043268358itd-79 requires they/them for every persona; itd-2610180912189125 refers to its persona Alice as 'her'related
mentions23
- dcn-26070800000000022026-07-08 — Personas in any scenario are always Alice, Bob, Carol (in that
- dcn-26070800000000032026-07-08 — Consume-model interview: `spec_id` is SCALAR (never a list) —
- dcn-26070800000000042026-07-08 — persona_registry lint shipped (record-lint blocker: quote
- dcn-26070800000000052026-07-08 — Persona SSOTs reconciled: `personas.json` is the single registry
- dcn-26072900000000012026-07-29 — privacy-leak follow-up: illustrative machine identifiers in anything committed or published always come from reserved documentation ranges (RFC 5737 IPv4, RFC 3849 IPv6, RFC 2606 domains, RFC 7042 MACs; hostnames derived from the persona registry, e.g. alice-laptop) — the itd-79 persona rule applied to infrastructure. Recorded as principle `examples-use-reserved-identifiers`; enforcement is the iss-154 allowlist-inversion lint (flag any identifier OUTSIDE the reserved ranges), whose shipping promotes the principle to a discipline. No new intent: real private identifiers are itd-74's banlist territory — the incident evidence extends itd-74's scope to machine identifiers (iss-158) rather than founding a second primitive. Incident issue text deliberately names no repo and no values (shape only), so the ledger itself cannot re-leak.
- dcn-26082000000000012026-08-20 — bughunt round 2 (branch bughunt-a/round-2): captured iss-331..iss-343 and fixed (ids 339-343 re-minted from an initial 326-330 after main concurrently took those numbers in the v0.6.1 cut)
- examples-use-reserved-identifiersExamples use reserved identifiers
- facilitator-default-thinker-optionalFacilitator by default, thinker optionally
- iss-154privacy-hygiene detects only absolute home paths — no network-identifier patterns (IPv4 incl. CGNAT/tailnet 100.64/10, hostnames, device names, ports-in-context). Field incident: an agent committed a Tailscale investigation (tailnet IP, two device hostnames, firewall posture, service port, presence/away patterns) into a public repo's committed tier and audit passed it silently. The v1 deferral note names only emails and private-repo names; network identifiers are not even recorded as deferred.
- iss-300The persona glossary (brief/glossary/core/persona.md) and brief/01-product/05-personas.md say the persona picker 'chooses at random', contradicting personas.json and itd-79 whose rule is 'selection is by role, never by name'; the glossary's worked examples also assign off-role names (Carol as product lead, Alice as developer)
- iss-321persona pronoun discipline itd-79 is violated by gendered pronouns in seven intent records including a shipped intent
- iss-338Seven registry personas are given he/she/his/her pronouns across intents/drafts (itd-92,97,98,108,126,128) and intents/shipped (itd-100), violating the they/them persona discipline (itd-79); review-enforced convention with no mechanical gate, concentrated in one 2026-08 authoring batch — a cosmetics-batch cleanup
- iss-351the three-disciplines roster itd-1 itd-5 itd-37 is hand-enumerated at six sites while intents/disciplines/ holds six active disciplines, dropping itd-79 itd-81 itd-84 from the mental model, scope, roadmap dashboard and phase-0 acceptance
- iss-371The persona_registry lint checks names, not roles: itd-114 shipped 'Bob, a maintainer' (Bob is registered staff engineer; the maintainer role is Kira's) and itd-115 has 'Carol, a facilitator' (Nia's role) — both passed lint. The selection-by-role rule (personas.json, itd-79) has no detector for role-name agreement
- iss-390the pre-decided promotion of examples-use-reserved-identifiers to a discipline-kind intent never happened — the iss-154 lint shipped, the principles README contract says a mechanical gate promotes the principle, and no discipline intent exists
- iss-2608211849581263brief 05-personas.md says the persona picker chooses at random, contradicting personas.json and itd-79 (selection is by role, never by name); a live residual of resolved iss-300
- iss-2608261041210476The principle spec-moves-with-the-surface names a promotion trigger that is already armed, yet sits unpromoted in the not-yet-enforced layer. The principle says a record-lint cross-check (every entry under commands/ and skills/ resolves to a brief surface row) WOULD promote it to a discipline; that is exactly surface_coverage Direction B, armed at blocker (lint.go, record-lint.json), documented live. principles/README.md makes promotion unconditional once any mechanical gate lands (the file is then retired to a discipline-kind intent, as itd-79 personas did), but no discipline intent exists for this principle and the file was never retired. The conditional 'would promote' predates the gate and was left stale — the inverse of the phantom-gate family (it understates its own enforcement). RECORDED NOT FIXED this round: the correct remedy is a governance act (mint a discipline-kind intent and retire the principle file, per the itd-79 precedent), which needs the maintainer rather than an autonomous edit. Proposed: promote per principles/README, or if promotion is deliberately deferred, record why on the principle.
- iss-2608261338035835the-record-lands-with-the-act names an armed rung in present tense and its promotion never fired. The principle's Promotion paragraph states 'The armed rung is make lint-issues, a CI step and a pre-push gate' — verified true: RS001-RS003 live in scripts/check-issue-resolution.sh, wired at Makefile lint-issues and included in preflight. Per the principles README promotion contract (enforced principle -> discipline-kind intent), the gate shipping should have minted a discipline; none exists. Third instance of the promotion-pipeline class alongside iss-390 (examples-use-reserved-identifiers) and iss-2608261041210476 (spec-moves-with-the-surface), and the only one with no ledger record until now. The class evidence is now three: the promotion ritual that only a human can perform is the step that gets skipped, which is the-record-lands-with-the-act applied to its own pipeline.
- iss-2609261039134673principle_claims judges only the **The rule.** paragraph while the projection sends the H1 title above it and verifyPrincipleItem scans both, so a typed principle whose title cites a record (# Title citing itd-79) passes record-lint and then refuses the whole reading assembly: the two readers of a principle's statement disagree about what it is.
- itd-1Every Intent Has Acceptance Criteria; Every Audit Verifies Them
- itd-74abcd Keeps the Names You Ban Out of Everything You Publish
- itd-84An Intent Is Decomposed Before It Is Filed, And A Reversal Is Only Ever Flagged
- spc-20name-banlist