Repository navigation
Stop using address.aliases (half 1 of 2) - #1289
Conversation
Aliases are dropped from the addressing contract. This is the FIRST half of an
ordered cross-repo pair — it removes every USE of the field. The companion PR in
petry-projects/.github then drops it from the schema. Reversing that order breaks
main fleet-wide: the schema is additionalProperties:false, so dropping the field
first makes qa-lead's `aliases: []` fail validate-personas everywhere.
Why drop them (settled empirically, not by taste)
An alias exists so a RENAMED persona keeps routing: qa-lead declaring
`aliases: [petry-projects/murat]` so old comments still reach it. Two problems:
1. Index-free routing cannot honour it. The router resolves '@petry-projects/murat'
to personas/murat/persona.yml — a 404 after the rename. The alias is declared
inside qa-lead's manifest, which the router never opens because it does not
know to look there. Chicken-and-egg. The attempt at pm_persona_aliases in
.github#754 was unreachable for exactly this reason.
2. The severity argument for keeping them turned out to be FALSE. The worry was
that GitHub redirects renamed team slugs, so an old mention would still LOOK
live while the agent silently never ran — the UI lying, which is the failure
class we have been eliminating. Probed it directly: created a team, rendered
its mention (team-mention link), renamed the team, re-rendered the OLD handle:
before rename: <a class="team-mention" ...>@petry-projects/pm-alias-probe</a>
after rename: <p>@petry-projects/pm-alias-probe please review</p>
The old handle renders as PLAIN TEXT. GitHub itself stops treating it as a
mention, so the user sees grey text and knows instantly it did not resolve.
The failure is visible, and the fix is obvious: re-mention with the new handle.
So aliases would only route text GitHub no longer considers a mention — not worth
a derived index, an extra fetch on every 404, and a contract the router cannot
honour. See petry-projects/.github#755 finding 1.
Handle uniqueness is now a THEOREM, so its check is removed
check_handles_unique existed because aliases shared the handle namespace. Without
them it is provably unreachable: the schema pins the org (^petry-projects/...),
slug == id, id == the persona directory name, and directory names are unique — so
two personas cannot claim the same handle. A validator function that can never
fire is a liability: it implies a check where none is needed and invites
maintenance. Removed, with the theorem documented where the slug check lives.
Changes
- personas/qa-lead/persona.yml — drop `aliases: []`
- personas/validate-personas.py — drop alias shape validation and the now-dead
check_handles_unique; document the uniqueness theorem
- tests/test_validate_personas.bats — drop the 4 alias tests and the helper's
alias varargs; the handle-collision tests went with them because they used an
alias as the collision vector and the collision is now impossible
Verification
- bats tests/test_validate_personas.bats: 16/16 (was 20; 4 alias tests removed).
- validate-personas.py against the LIVE main schema (which still permits aliases,
so this must pass BEFORE the companion lands): OK, invariants hold.
- scripts/verify-persona-teams.sh (from #1284): OK — qa-lead's team still
verifies live (exists, closed, notifications disabled).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Warning Review limit reached
Next review available in: 25 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (4)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request simplifies the persona validation process by removing the aliases field and the redundant cross-file uniqueness check (check_handles_unique) from validate-personas.py. Because the schema pins the organization and ensures that the handle slug matches the unique directory name, handle uniqueness is guaranteed by design. Related tests and helper functions in test_validate_personas.bats have been removed accordingly. There are no review comments, so I have no feedback to provide.
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
There was a problem hiding this comment.
Pull request overview
Removes address.aliases usage from this repo’s persona manifests and test fixtures, and updates the persona validator to stop parsing/enforcing aliases ahead of the upstream schema change in petry-projects/.github.
Changes:
- Simplify
validate-personas.pyby dropping alias parsing and the cross-file handle/alias uniqueness check. - Update persona validation tests to stop emitting/testing
address.aliases. - Remove
aliases: []frompersonas/qa-lead/persona.yml.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| tests/test_validate_personas.bats | Stops generating/testing address.aliases and removes alias-driven collision cases. |
| personas/validate-personas.py | Removes alias handling and the uniqueness check; updates module docs to explain the new invariant reasoning. |
| personas/qa-lead/persona.yml | Drops aliases: [] from the persona’s address block. |
Superseded by automated re-review at
|
Both from Copilot's review; both correct. 1. tests/verify_persona_teams.bats still wrote `aliases: []` A real miss, and exactly the ordered-pair landmine this PR exists to avoid: the moment the companion drops `aliases` from the schema (additionalProperties: false), this fixture's generated manifest would fail validation. It survived because my sweep grepped personas/ and tests/test_validate_personas.bats — this fixture lives in the suite #1284 added, which I never looked at. A repo-wide grep now shows zero remaining uses. 2. The uniqueness theorem was stated more broadly than it holds The docstring claimed a uniqueness check "could never fire" — unconditionally true only once the schema drops aliases. Today the schema still PERMITS an alias, and aliases shared the handle namespace the theorem does not cover, so until the companion lands, re-adding one would reopen exactly the gap the check used to close. Scoped the claim to address.handle (the only thing the router resolves) and recorded the window explicitly. Verification - bats tests/test_validate_personas.bats: 16/16. - bats tests/verify_persona_teams.bats: 16/16 (the #1284 suite, now alias-free). - validate-personas.py against the LIVE main schema: OK, invariants hold. - Repo-wide grep for `aliases`: zero uses outside the docstring note. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
donpetry-bot
left a comment
There was a problem hiding this comment.
Automated review — APPROVED ✓
Risk: MEDIUM
Reviewed commit: 00b757cda07dc3e3d7beea5265c9147b2ad4ab55
Review mode: triage-approved (single reviewer)
Summary
Removes address.aliases usage from persona manifests, validator, and test fixtures as half 1 of an ordered cross-repo pair (companion in petry-projects/.github drops the field from the schema). Also removes check_handles_unique, now provably unreachable for address.handle (schema pins org, slug == id, id == unique directory name). Prior review cycle's two findings (leftover aliases fixture in verify_persona_teams.bats; over-broad uniqueness-theorem claim) are both fixed in the latest commit and their threads resolved. Triage assessment confirmed.
Linked issue analysis
No linked issues via closingIssuesReferences. The PR references petry-projects/.github#755 (finding 1) as motivation and documents the cross-repo ordering constraint thoroughly: usage must be dropped before the schema drops the field, since the schema is additionalProperties: false. The change was verified against the live main schema, so it is safe to land first as intended.
Findings
No blocking findings.
- Prior cycle finding 1 (leftover
aliases: []in tests/verify_persona_teams.bats fixture) — RESOLVED: fixture no longer emits aliases; repo-wide usage is now zero. - Prior cycle finding 2 (uniqueness theorem stated too broadly while the schema still permits aliases) — RESOLVED: docstring now scopes the claim to address.handle and explicitly documents the window until the companion schema PR lands, warning against re-adding an alias.
- Note (non-blocking): removing check_handles_unique is sound for handles by construction; the documented interim window (schema still permits aliases until the companion lands) is acknowledged in-code, which is the right mitigation for an ordered pair.
- Secret scan: run_secret_scanning MCP tool unavailable in this session; gitleaks CI check passed and the diff contains no secret-like content.
CI status
All required checks green: validate-personas, verify-persona-teams, bats, unit-tests, Lint, ShellCheck, actionlint, CodeQL (actions + python), SonarCloud quality gate, Secret scan (gitleaks), agent-shield, holdout-guard, caller-stub-freeze, template-drift. A few dev-lead dispatch/ci-relay runs show CANCELLED (superseded runs) and conditional jobs SKIPPED — none blocking.
Reviewed automatically by the PR-review agent (single-reviewer mode: fable 5). Reply if you need a human review.
…thub-private#1289 merges (#769) * refactor(personas): drop address.aliases from the contract (half 2 of 2) Second half of the ordered cross-repo pair. petry-projects/.github-private#1289 removed every USE of the field first; this removes the field itself. MERGE ORDER: #1289 MUST land before this. The schema is additionalProperties:false, so dropping `aliases` while qa-lead's manifest still carries `aliases: []` fails validate-personas on main FLEET-WIDE. Verified the rejection is real: a manifest with `aliases` now yields "Additional properties are not allowed ('aliases' was unexpected)". Why aliases are gone (see .github#755 finding 1) They existed so a RENAMED role kept routing — qa-lead listing `petry-projects/murat` so old comments still reached it. Two reasons it goes: 1. Structural: index-free routing could never honour it. The router resolves '@petry-projects/murat' to personas/murat/persona.yml — a 404 after the rename. The alias is declared INSIDE the renamed persona's own manifest, which the router never opens, because it does not know to look there. Chicken-and-egg; the pm_persona_aliases attempt in #754 was unreachable for exactly this reason. 2. Measured: there is nothing live left to route. GitHub stops rendering a renamed team's old handle as a mention at all. Probed it directly — created a team, rendered its mention, renamed it, re-rendered the OLD handle: before rename: <a class="team-mention" …>@petry-projects/probe</a> after rename: <p>@petry-projects/probe please review</p> The old handle becomes PLAIN TEXT. So it is not a silently-broken mention that looks live — the reader sees grey text and knows instantly it did not resolve, and the fix is local: mention the new handle. Aliases would only route text GitHub itself no longer treats as a mention. Not worth a derived index, an extra fetch on every 404, and a contract the router cannot honour. Rule 4 becomes a theorem, not a check "Handles and aliases MUST be unique across all personas" is replaced by "Handles are unique BY CONSTRUCTION": the pattern pins the org, slug == id, id == the persona directory name, and directory names are unique — so two personas cannot claim the same handle. #1289 removed the corresponding check_handles_unique for the same reason: it could never fire. Rule 5 ("a rename keeps the old handle as an alias") is replaced by a §4.1 "Renames" section documenting what to change on a rename and stating plainly that old mentions stop resolving VISIBLY — which is the correct signal, not a regression. Changes - standards/personas/persona.schema.json — drop address.aliases (edited as TEXT, not re-serialized: a json round-trip reformats every inline array and rewrote 264 untouched lines. Diff is +2/-10.) - standards/persona-standards.md — §4.1 rules 4-5, the example, and the new Renames section - standards/personas/TEMPLATE/persona.yml — drop the aliases scaffold line Verification - persona.schema.json is a valid Draft 2020-12 schema; diff is +2/-10. - Conditional behaviour verified: qa-lead's post-#1289 shape (handle only) PASSES; a manifest carrying `aliases` FAILS — which is exactly why #1289 goes first. - TEMPLATE/persona.yml validates against the updated schema. - markdownlint-cli2: clean. - Zero `aliases` references remain outside the deliberate explanatory notes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com> Co-authored-by: Don Petry Bot <donpetry+bot@gmail.com>
* refactor(personas): stop using address.aliases (half 1 of 2)
Aliases are dropped from the addressing contract. This is the FIRST half of an
ordered cross-repo pair — it removes every USE of the field. The companion PR in
petry-projects/.github then drops it from the schema. Reversing that order breaks
main fleet-wide: the schema is additionalProperties:false, so dropping the field
first makes qa-lead's `aliases: []` fail validate-personas everywhere.
Why drop them (settled empirically, not by taste)
An alias exists so a RENAMED persona keeps routing: qa-lead declaring
`aliases: [petry-projects/murat]` so old comments still reach it. Two problems:
1. Index-free routing cannot honour it. The router resolves '@petry-projects/murat'
to personas/murat/persona.yml — a 404 after the rename. The alias is declared
inside qa-lead's manifest, which the router never opens because it does not
know to look there. Chicken-and-egg. The attempt at pm_persona_aliases in
.github#754 was unreachable for exactly this reason.
2. The severity argument for keeping them turned out to be FALSE. The worry was
that GitHub redirects renamed team slugs, so an old mention would still LOOK
live while the agent silently never ran — the UI lying, which is the failure
class we have been eliminating. Probed it directly: created a team, rendered
its mention (team-mention link), renamed the team, re-rendered the OLD handle:
before rename: <a class="team-mention" ...>@petry-projects/pm-alias-probe</a>
after rename: <p>@petry-projects/pm-alias-probe please review</p>
The old handle renders as PLAIN TEXT. GitHub itself stops treating it as a
mention, so the user sees grey text and knows instantly it did not resolve.
The failure is visible, and the fix is obvious: re-mention with the new handle.
So aliases would only route text GitHub no longer considers a mention — not worth
a derived index, an extra fetch on every 404, and a contract the router cannot
honour. See petry-projects/.github#755 finding 1.
Handle uniqueness is now a THEOREM, so its check is removed
check_handles_unique existed because aliases shared the handle namespace. Without
them it is provably unreachable: the schema pins the org (^petry-projects/...),
slug == id, id == the persona directory name, and directory names are unique — so
two personas cannot claim the same handle. A validator function that can never
fire is a liability: it implies a check where none is needed and invites
maintenance. Removed, with the theorem documented where the slug check lives.
Changes
- personas/qa-lead/persona.yml — drop `aliases: []`
- personas/validate-personas.py — drop alias shape validation and the now-dead
check_handles_unique; document the uniqueness theorem
- tests/test_validate_personas.bats — drop the 4 alias tests and the helper's
alias varargs; the handle-collision tests went with them because they used an
alias as the collision vector and the collision is now impossible
Verification
- bats tests/test_validate_personas.bats: 16/16 (was 20; 4 alias tests removed).
- validate-personas.py against the LIVE main schema (which still permits aliases,
so this must pass BEFORE the companion lands): OK, invariants hold.
- scripts/verify-persona-teams.sh (from #1284): OK — qa-lead's team still
verifies live (exists, closed, notifications disabled).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(personas): drop the last aliases fixture and scope the theorem claim
Both from Copilot's review; both correct.
1. tests/verify_persona_teams.bats still wrote `aliases: []`
A real miss, and exactly the ordered-pair landmine this PR exists to avoid: the
moment the companion drops `aliases` from the schema (additionalProperties:
false), this fixture's generated manifest would fail validation. It survived
because my sweep grepped personas/ and tests/test_validate_personas.bats — this
fixture lives in the suite #1284 added, which I never looked at. A repo-wide
grep now shows zero remaining uses.
2. The uniqueness theorem was stated more broadly than it holds
The docstring claimed a uniqueness check "could never fire" — unconditionally
true only once the schema drops aliases. Today the schema still PERMITS an
alias, and aliases shared the handle namespace the theorem does not cover, so
until the companion lands, re-adding one would reopen exactly the gap the check
used to close. Scoped the claim to address.handle (the only thing the router
resolves) and recorded the window explicitly.
Verification
- bats tests/test_validate_personas.bats: 16/16.
- bats tests/verify_persona_teams.bats: 16/16 (the #1284 suite, now alias-free).
- validate-personas.py against the LIVE main schema: OK, invariants hold.
- Repo-wide grep for `aliases`: zero uses outside the docstring note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(personas): stop using address.aliases (half 1 of 2)
Aliases are dropped from the addressing contract. This is the FIRST half of an
ordered cross-repo pair — it removes every USE of the field. The companion PR in
petry-projects/.github then drops it from the schema. Reversing that order breaks
main fleet-wide: the schema is additionalProperties:false, so dropping the field
first makes qa-lead's `aliases: []` fail validate-personas everywhere.
Why drop them (settled empirically, not by taste)
An alias exists so a RENAMED persona keeps routing: qa-lead declaring
`aliases: [petry-projects/murat]` so old comments still reach it. Two problems:
1. Index-free routing cannot honour it. The router resolves '@petry-projects/murat'
to personas/murat/persona.yml — a 404 after the rename. The alias is declared
inside qa-lead's manifest, which the router never opens because it does not
know to look there. Chicken-and-egg. The attempt at pm_persona_aliases in
.github#754 was unreachable for exactly this reason.
2. The severity argument for keeping them turned out to be FALSE. The worry was
that GitHub redirects renamed team slugs, so an old mention would still LOOK
live while the agent silently never ran — the UI lying, which is the failure
class we have been eliminating. Probed it directly: created a team, rendered
its mention (team-mention link), renamed the team, re-rendered the OLD handle:
before rename: <a class="team-mention" ...>@petry-projects/pm-alias-probe</a>
after rename: <p>@petry-projects/pm-alias-probe please review</p>
The old handle renders as PLAIN TEXT. GitHub itself stops treating it as a
mention, so the user sees grey text and knows instantly it did not resolve.
The failure is visible, and the fix is obvious: re-mention with the new handle.
So aliases would only route text GitHub no longer considers a mention — not worth
a derived index, an extra fetch on every 404, and a contract the router cannot
honour. See petry-projects/.github#755 finding 1.
Handle uniqueness is now a THEOREM, so its check is removed
check_handles_unique existed because aliases shared the handle namespace. Without
them it is provably unreachable: the schema pins the org (^petry-projects/...),
slug == id, id == the persona directory name, and directory names are unique — so
two personas cannot claim the same handle. A validator function that can never
fire is a liability: it implies a check where none is needed and invites
maintenance. Removed, with the theorem documented where the slug check lives.
Changes
- personas/qa-lead/persona.yml — drop `aliases: []`
- personas/validate-personas.py — drop alias shape validation and the now-dead
check_handles_unique; document the uniqueness theorem
- tests/test_validate_personas.bats — drop the 4 alias tests and the helper's
alias varargs; the handle-collision tests went with them because they used an
alias as the collision vector and the collision is now impossible
Verification
- bats tests/test_validate_personas.bats: 16/16 (was 20; 4 alias tests removed).
- validate-personas.py against the LIVE main schema (which still permits aliases,
so this must pass BEFORE the companion lands): OK, invariants hold.
- scripts/verify-persona-teams.sh (from #1284): OK — qa-lead's team still
verifies live (exists, closed, notifications disabled).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(personas): drop the last aliases fixture and scope the theorem claim
Both from Copilot's review; both correct.
1. tests/verify_persona_teams.bats still wrote `aliases: []`
A real miss, and exactly the ordered-pair landmine this PR exists to avoid: the
moment the companion drops `aliases` from the schema (additionalProperties:
false), this fixture's generated manifest would fail validation. It survived
because my sweep grepped personas/ and tests/test_validate_personas.bats — this
fixture lives in the suite #1284 added, which I never looked at. A repo-wide
grep now shows zero remaining uses.
2. The uniqueness theorem was stated more broadly than it holds
The docstring claimed a uniqueness check "could never fire" — unconditionally
true only once the schema drops aliases. Today the schema still PERMITS an
alias, and aliases shared the handle namespace the theorem does not cover, so
until the companion lands, re-adding one would reopen exactly the gap the check
used to close. Scoped the claim to address.handle (the only thing the router
resolves) and recorded the window explicitly.
Verification
- bats tests/test_validate_personas.bats: 16/16.
- bats tests/verify_persona_teams.bats: 16/16 (the #1284 suite, now alias-free).
- validate-personas.py against the LIVE main schema: OK, invariants hold.
- Repo-wide grep for `aliases`: zero uses outside the docstring note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(personas): stop using address.aliases (half 1 of 2)
Aliases are dropped from the addressing contract. This is the FIRST half of an
ordered cross-repo pair — it removes every USE of the field. The companion PR in
petry-projects/.github then drops it from the schema. Reversing that order breaks
main fleet-wide: the schema is additionalProperties:false, so dropping the field
first makes qa-lead's `aliases: []` fail validate-personas everywhere.
Why drop them (settled empirically, not by taste)
An alias exists so a RENAMED persona keeps routing: qa-lead declaring
`aliases: [petry-projects/murat]` so old comments still reach it. Two problems:
1. Index-free routing cannot honour it. The router resolves '@petry-projects/murat'
to personas/murat/persona.yml — a 404 after the rename. The alias is declared
inside qa-lead's manifest, which the router never opens because it does not
know to look there. Chicken-and-egg. The attempt at pm_persona_aliases in
.github#754 was unreachable for exactly this reason.
2. The severity argument for keeping them turned out to be FALSE. The worry was
that GitHub redirects renamed team slugs, so an old mention would still LOOK
live while the agent silently never ran — the UI lying, which is the failure
class we have been eliminating. Probed it directly: created a team, rendered
its mention (team-mention link), renamed the team, re-rendered the OLD handle:
before rename: <a class="team-mention" ...>@petry-projects/pm-alias-probe</a>
after rename: <p>@petry-projects/pm-alias-probe please review</p>
The old handle renders as PLAIN TEXT. GitHub itself stops treating it as a
mention, so the user sees grey text and knows instantly it did not resolve.
The failure is visible, and the fix is obvious: re-mention with the new handle.
So aliases would only route text GitHub no longer considers a mention — not worth
a derived index, an extra fetch on every 404, and a contract the router cannot
honour. See petry-projects/.github#755 finding 1.
Handle uniqueness is now a THEOREM, so its check is removed
check_handles_unique existed because aliases shared the handle namespace. Without
them it is provably unreachable: the schema pins the org (^petry-projects/...),
slug == id, id == the persona directory name, and directory names are unique — so
two personas cannot claim the same handle. A validator function that can never
fire is a liability: it implies a check where none is needed and invites
maintenance. Removed, with the theorem documented where the slug check lives.
Changes
- personas/qa-lead/persona.yml — drop `aliases: []`
- personas/validate-personas.py — drop alias shape validation and the now-dead
check_handles_unique; document the uniqueness theorem
- tests/test_validate_personas.bats — drop the 4 alias tests and the helper's
alias varargs; the handle-collision tests went with them because they used an
alias as the collision vector and the collision is now impossible
Verification
- bats tests/test_validate_personas.bats: 16/16 (was 20; 4 alias tests removed).
- validate-personas.py against the LIVE main schema (which still permits aliases,
so this must pass BEFORE the companion lands): OK, invariants hold.
- scripts/verify-persona-teams.sh (from #1284): OK — qa-lead's team still
verifies live (exists, closed, notifications disabled).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(personas): drop the last aliases fixture and scope the theorem claim
Both from Copilot's review; both correct.
1. tests/verify_persona_teams.bats still wrote `aliases: []`
A real miss, and exactly the ordered-pair landmine this PR exists to avoid: the
moment the companion drops `aliases` from the schema (additionalProperties:
false), this fixture's generated manifest would fail validation. It survived
because my sweep grepped personas/ and tests/test_validate_personas.bats — this
fixture lives in the suite #1284 added, which I never looked at. A repo-wide
grep now shows zero remaining uses.
2. The uniqueness theorem was stated more broadly than it holds
The docstring claimed a uniqueness check "could never fire" — unconditionally
true only once the schema drops aliases. Today the schema still PERMITS an
alias, and aliases shared the handle namespace the theorem does not cover, so
until the companion lands, re-adding one would reopen exactly the gap the check
used to close. Scoped the claim to address.handle (the only thing the router
resolves) and recorded the window explicitly.
Verification
- bats tests/test_validate_personas.bats: 16/16.
- bats tests/verify_persona_teams.bats: 16/16 (the #1284 suite, now alias-free).
- validate-personas.py against the LIVE main schema: OK, invariants hold.
- Repo-wide grep for `aliases`: zero uses outside the docstring note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(personas): stop using address.aliases (half 1 of 2)
Aliases are dropped from the addressing contract. This is the FIRST half of an
ordered cross-repo pair — it removes every USE of the field. The companion PR in
petry-projects/.github then drops it from the schema. Reversing that order breaks
main fleet-wide: the schema is additionalProperties:false, so dropping the field
first makes qa-lead's `aliases: []` fail validate-personas everywhere.
Why drop them (settled empirically, not by taste)
An alias exists so a RENAMED persona keeps routing: qa-lead declaring
`aliases: [petry-projects/murat]` so old comments still reach it. Two problems:
1. Index-free routing cannot honour it. The router resolves '@petry-projects/murat'
to personas/murat/persona.yml — a 404 after the rename. The alias is declared
inside qa-lead's manifest, which the router never opens because it does not
know to look there. Chicken-and-egg. The attempt at pm_persona_aliases in
.github#754 was unreachable for exactly this reason.
2. The severity argument for keeping them turned out to be FALSE. The worry was
that GitHub redirects renamed team slugs, so an old mention would still LOOK
live while the agent silently never ran — the UI lying, which is the failure
class we have been eliminating. Probed it directly: created a team, rendered
its mention (team-mention link), renamed the team, re-rendered the OLD handle:
before rename: <a class="team-mention" ...>@petry-projects/pm-alias-probe</a>
after rename: <p>@petry-projects/pm-alias-probe please review</p>
The old handle renders as PLAIN TEXT. GitHub itself stops treating it as a
mention, so the user sees grey text and knows instantly it did not resolve.
The failure is visible, and the fix is obvious: re-mention with the new handle.
So aliases would only route text GitHub no longer considers a mention — not worth
a derived index, an extra fetch on every 404, and a contract the router cannot
honour. See petry-projects/.github#755 finding 1.
Handle uniqueness is now a THEOREM, so its check is removed
check_handles_unique existed because aliases shared the handle namespace. Without
them it is provably unreachable: the schema pins the org (^petry-projects/...),
slug == id, id == the persona directory name, and directory names are unique — so
two personas cannot claim the same handle. A validator function that can never
fire is a liability: it implies a check where none is needed and invites
maintenance. Removed, with the theorem documented where the slug check lives.
Changes
- personas/qa-lead/persona.yml — drop `aliases: []`
- personas/validate-personas.py — drop alias shape validation and the now-dead
check_handles_unique; document the uniqueness theorem
- tests/test_validate_personas.bats — drop the 4 alias tests and the helper's
alias varargs; the handle-collision tests went with them because they used an
alias as the collision vector and the collision is now impossible
Verification
- bats tests/test_validate_personas.bats: 16/16 (was 20; 4 alias tests removed).
- validate-personas.py against the LIVE main schema (which still permits aliases,
so this must pass BEFORE the companion lands): OK, invariants hold.
- scripts/verify-persona-teams.sh (from #1284): OK — qa-lead's team still
verifies live (exists, closed, notifications disabled).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(personas): drop the last aliases fixture and scope the theorem claim
Both from Copilot's review; both correct.
1. tests/verify_persona_teams.bats still wrote `aliases: []`
A real miss, and exactly the ordered-pair landmine this PR exists to avoid: the
moment the companion drops `aliases` from the schema (additionalProperties:
false), this fixture's generated manifest would fail validation. It survived
because my sweep grepped personas/ and tests/test_validate_personas.bats — this
fixture lives in the suite #1284 added, which I never looked at. A repo-wide
grep now shows zero remaining uses.
2. The uniqueness theorem was stated more broadly than it holds
The docstring claimed a uniqueness check "could never fire" — unconditionally
true only once the schema drops aliases. Today the schema still PERMITS an
alias, and aliases shared the handle namespace the theorem does not cover, so
until the companion lands, re-adding one would reopen exactly the gap the check
used to close. Scoped the claim to address.handle (the only thing the router
resolves) and recorded the window explicitly.
Verification
- bats tests/test_validate_personas.bats: 16/16.
- bats tests/verify_persona_teams.bats: 16/16 (the #1284 suite, now alias-free).
- validate-personas.py against the LIVE main schema: OK, invariants hold.
- Repo-wide grep for `aliases`: zero uses outside the docstring note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(personas): stop using address.aliases (half 1 of 2)
Aliases are dropped from the addressing contract. This is the FIRST half of an
ordered cross-repo pair — it removes every USE of the field. The companion PR in
petry-projects/.github then drops it from the schema. Reversing that order breaks
main fleet-wide: the schema is additionalProperties:false, so dropping the field
first makes qa-lead's `aliases: []` fail validate-personas everywhere.
Why drop them (settled empirically, not by taste)
An alias exists so a RENAMED persona keeps routing: qa-lead declaring
`aliases: [petry-projects/murat]` so old comments still reach it. Two problems:
1. Index-free routing cannot honour it. The router resolves '@petry-projects/murat'
to personas/murat/persona.yml — a 404 after the rename. The alias is declared
inside qa-lead's manifest, which the router never opens because it does not
know to look there. Chicken-and-egg. The attempt at pm_persona_aliases in
.github#754 was unreachable for exactly this reason.
2. The severity argument for keeping them turned out to be FALSE. The worry was
that GitHub redirects renamed team slugs, so an old mention would still LOOK
live while the agent silently never ran — the UI lying, which is the failure
class we have been eliminating. Probed it directly: created a team, rendered
its mention (team-mention link), renamed the team, re-rendered the OLD handle:
before rename: <a class="team-mention" ...>@petry-projects/pm-alias-probe</a>
after rename: <p>@petry-projects/pm-alias-probe please review</p>
The old handle renders as PLAIN TEXT. GitHub itself stops treating it as a
mention, so the user sees grey text and knows instantly it did not resolve.
The failure is visible, and the fix is obvious: re-mention with the new handle.
So aliases would only route text GitHub no longer considers a mention — not worth
a derived index, an extra fetch on every 404, and a contract the router cannot
honour. See petry-projects/.github#755 finding 1.
Handle uniqueness is now a THEOREM, so its check is removed
check_handles_unique existed because aliases shared the handle namespace. Without
them it is provably unreachable: the schema pins the org (^petry-projects/...),
slug == id, id == the persona directory name, and directory names are unique — so
two personas cannot claim the same handle. A validator function that can never
fire is a liability: it implies a check where none is needed and invites
maintenance. Removed, with the theorem documented where the slug check lives.
Changes
- personas/qa-lead/persona.yml — drop `aliases: []`
- personas/validate-personas.py — drop alias shape validation and the now-dead
check_handles_unique; document the uniqueness theorem
- tests/test_validate_personas.bats — drop the 4 alias tests and the helper's
alias varargs; the handle-collision tests went with them because they used an
alias as the collision vector and the collision is now impossible
Verification
- bats tests/test_validate_personas.bats: 16/16 (was 20; 4 alias tests removed).
- validate-personas.py against the LIVE main schema (which still permits aliases,
so this must pass BEFORE the companion lands): OK, invariants hold.
- scripts/verify-persona-teams.sh (from #1284): OK — qa-lead's team still
verifies live (exists, closed, notifications disabled).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(personas): drop the last aliases fixture and scope the theorem claim
Both from Copilot's review; both correct.
1. tests/verify_persona_teams.bats still wrote `aliases: []`
A real miss, and exactly the ordered-pair landmine this PR exists to avoid: the
moment the companion drops `aliases` from the schema (additionalProperties:
false), this fixture's generated manifest would fail validation. It survived
because my sweep grepped personas/ and tests/test_validate_personas.bats — this
fixture lives in the suite #1284 added, which I never looked at. A repo-wide
grep now shows zero remaining uses.
2. The uniqueness theorem was stated more broadly than it holds
The docstring claimed a uniqueness check "could never fire" — unconditionally
true only once the schema drops aliases. Today the schema still PERMITS an
alias, and aliases shared the handle namespace the theorem does not cover, so
until the companion lands, re-adding one would reopen exactly the gap the check
used to close. Scoped the claim to address.handle (the only thing the router
resolves) and recorded the window explicitly.
Verification
- bats tests/test_validate_personas.bats: 16/16.
- bats tests/verify_persona_teams.bats: 16/16 (the #1284 suite, now alias-free).
- validate-personas.py against the LIVE main schema: OK, invariants hold.
- Repo-wide grep for `aliases`: zero uses outside the docstring note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(personas): stop using address.aliases (half 1 of 2)
Aliases are dropped from the addressing contract. This is the FIRST half of an
ordered cross-repo pair — it removes every USE of the field. The companion PR in
petry-projects/.github then drops it from the schema. Reversing that order breaks
main fleet-wide: the schema is additionalProperties:false, so dropping the field
first makes qa-lead's `aliases: []` fail validate-personas everywhere.
Why drop them (settled empirically, not by taste)
An alias exists so a RENAMED persona keeps routing: qa-lead declaring
`aliases: [petry-projects/murat]` so old comments still reach it. Two problems:
1. Index-free routing cannot honour it. The router resolves '@petry-projects/murat'
to personas/murat/persona.yml — a 404 after the rename. The alias is declared
inside qa-lead's manifest, which the router never opens because it does not
know to look there. Chicken-and-egg. The attempt at pm_persona_aliases in
.github#754 was unreachable for exactly this reason.
2. The severity argument for keeping them turned out to be FALSE. The worry was
that GitHub redirects renamed team slugs, so an old mention would still LOOK
live while the agent silently never ran — the UI lying, which is the failure
class we have been eliminating. Probed it directly: created a team, rendered
its mention (team-mention link), renamed the team, re-rendered the OLD handle:
before rename: <a class="team-mention" ...>@petry-projects/pm-alias-probe</a>
after rename: <p>@petry-projects/pm-alias-probe please review</p>
The old handle renders as PLAIN TEXT. GitHub itself stops treating it as a
mention, so the user sees grey text and knows instantly it did not resolve.
The failure is visible, and the fix is obvious: re-mention with the new handle.
So aliases would only route text GitHub no longer considers a mention — not worth
a derived index, an extra fetch on every 404, and a contract the router cannot
honour. See petry-projects/.github#755 finding 1.
Handle uniqueness is now a THEOREM, so its check is removed
check_handles_unique existed because aliases shared the handle namespace. Without
them it is provably unreachable: the schema pins the org (^petry-projects/...),
slug == id, id == the persona directory name, and directory names are unique — so
two personas cannot claim the same handle. A validator function that can never
fire is a liability: it implies a check where none is needed and invites
maintenance. Removed, with the theorem documented where the slug check lives.
Changes
- personas/qa-lead/persona.yml — drop `aliases: []`
- personas/validate-personas.py — drop alias shape validation and the now-dead
check_handles_unique; document the uniqueness theorem
- tests/test_validate_personas.bats — drop the 4 alias tests and the helper's
alias varargs; the handle-collision tests went with them because they used an
alias as the collision vector and the collision is now impossible
Verification
- bats tests/test_validate_personas.bats: 16/16 (was 20; 4 alias tests removed).
- validate-personas.py against the LIVE main schema (which still permits aliases,
so this must pass BEFORE the companion lands): OK, invariants hold.
- scripts/verify-persona-teams.sh (from #1284): OK — qa-lead's team still
verifies live (exists, closed, notifications disabled).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(personas): drop the last aliases fixture and scope the theorem claim
Both from Copilot's review; both correct.
1. tests/verify_persona_teams.bats still wrote `aliases: []`
A real miss, and exactly the ordered-pair landmine this PR exists to avoid: the
moment the companion drops `aliases` from the schema (additionalProperties:
false), this fixture's generated manifest would fail validation. It survived
because my sweep grepped personas/ and tests/test_validate_personas.bats — this
fixture lives in the suite #1284 added, which I never looked at. A repo-wide
grep now shows zero remaining uses.
2. The uniqueness theorem was stated more broadly than it holds
The docstring claimed a uniqueness check "could never fire" — unconditionally
true only once the schema drops aliases. Today the schema still PERMITS an
alias, and aliases shared the handle namespace the theorem does not cover, so
until the companion lands, re-adding one would reopen exactly the gap the check
used to close. Scoped the claim to address.handle (the only thing the router
resolves) and recorded the window explicitly.
Verification
- bats tests/test_validate_personas.bats: 16/16.
- bats tests/verify_persona_teams.bats: 16/16 (the #1284 suite, now alias-free).
- validate-personas.py against the LIVE main schema: OK, invariants hold.
- Repo-wide grep for `aliases`: zero uses outside the docstring note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(personas): stop using address.aliases (half 1 of 2)
Aliases are dropped from the addressing contract. This is the FIRST half of an
ordered cross-repo pair — it removes every USE of the field. The companion PR in
petry-projects/.github then drops it from the schema. Reversing that order breaks
main fleet-wide: the schema is additionalProperties:false, so dropping the field
first makes qa-lead's `aliases: []` fail validate-personas everywhere.
Why drop them (settled empirically, not by taste)
An alias exists so a RENAMED persona keeps routing: qa-lead declaring
`aliases: [petry-projects/murat]` so old comments still reach it. Two problems:
1. Index-free routing cannot honour it. The router resolves '@petry-projects/murat'
to personas/murat/persona.yml — a 404 after the rename. The alias is declared
inside qa-lead's manifest, which the router never opens because it does not
know to look there. Chicken-and-egg. The attempt at pm_persona_aliases in
.github#754 was unreachable for exactly this reason.
2. The severity argument for keeping them turned out to be FALSE. The worry was
that GitHub redirects renamed team slugs, so an old mention would still LOOK
live while the agent silently never ran — the UI lying, which is the failure
class we have been eliminating. Probed it directly: created a team, rendered
its mention (team-mention link), renamed the team, re-rendered the OLD handle:
before rename: <a class="team-mention" ...>@petry-projects/pm-alias-probe</a>
after rename: <p>@petry-projects/pm-alias-probe please review</p>
The old handle renders as PLAIN TEXT. GitHub itself stops treating it as a
mention, so the user sees grey text and knows instantly it did not resolve.
The failure is visible, and the fix is obvious: re-mention with the new handle.
So aliases would only route text GitHub no longer considers a mention — not worth
a derived index, an extra fetch on every 404, and a contract the router cannot
honour. See petry-projects/.github#755 finding 1.
Handle uniqueness is now a THEOREM, so its check is removed
check_handles_unique existed because aliases shared the handle namespace. Without
them it is provably unreachable: the schema pins the org (^petry-projects/...),
slug == id, id == the persona directory name, and directory names are unique — so
two personas cannot claim the same handle. A validator function that can never
fire is a liability: it implies a check where none is needed and invites
maintenance. Removed, with the theorem documented where the slug check lives.
Changes
- personas/qa-lead/persona.yml — drop `aliases: []`
- personas/validate-personas.py — drop alias shape validation and the now-dead
check_handles_unique; document the uniqueness theorem
- tests/test_validate_personas.bats — drop the 4 alias tests and the helper's
alias varargs; the handle-collision tests went with them because they used an
alias as the collision vector and the collision is now impossible
Verification
- bats tests/test_validate_personas.bats: 16/16 (was 20; 4 alias tests removed).
- validate-personas.py against the LIVE main schema (which still permits aliases,
so this must pass BEFORE the companion lands): OK, invariants hold.
- scripts/verify-persona-teams.sh (from #1284): OK — qa-lead's team still
verifies live (exists, closed, notifications disabled).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(personas): drop the last aliases fixture and scope the theorem claim
Both from Copilot's review; both correct.
1. tests/verify_persona_teams.bats still wrote `aliases: []`
A real miss, and exactly the ordered-pair landmine this PR exists to avoid: the
moment the companion drops `aliases` from the schema (additionalProperties:
false), this fixture's generated manifest would fail validation. It survived
because my sweep grepped personas/ and tests/test_validate_personas.bats — this
fixture lives in the suite #1284 added, which I never looked at. A repo-wide
grep now shows zero remaining uses.
2. The uniqueness theorem was stated more broadly than it holds
The docstring claimed a uniqueness check "could never fire" — unconditionally
true only once the schema drops aliases. Today the schema still PERMITS an
alias, and aliases shared the handle namespace the theorem does not cover, so
until the companion lands, re-adding one would reopen exactly the gap the check
used to close. Scoped the claim to address.handle (the only thing the router
resolves) and recorded the window explicitly.
Verification
- bats tests/test_validate_personas.bats: 16/16.
- bats tests/verify_persona_teams.bats: 16/16 (the #1284 suite, now alias-free).
- validate-personas.py against the LIVE main schema: OK, invariants hold.
- Repo-wide grep for `aliases`: zero uses outside the docstring note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(personas): stop using address.aliases (half 1 of 2)
Aliases are dropped from the addressing contract. This is the FIRST half of an
ordered cross-repo pair — it removes every USE of the field. The companion PR in
petry-projects/.github then drops it from the schema. Reversing that order breaks
main fleet-wide: the schema is additionalProperties:false, so dropping the field
first makes qa-lead's `aliases: []` fail validate-personas everywhere.
Why drop them (settled empirically, not by taste)
An alias exists so a RENAMED persona keeps routing: qa-lead declaring
`aliases: [petry-projects/murat]` so old comments still reach it. Two problems:
1. Index-free routing cannot honour it. The router resolves '@petry-projects/murat'
to personas/murat/persona.yml — a 404 after the rename. The alias is declared
inside qa-lead's manifest, which the router never opens because it does not
know to look there. Chicken-and-egg. The attempt at pm_persona_aliases in
.github#754 was unreachable for exactly this reason.
2. The severity argument for keeping them turned out to be FALSE. The worry was
that GitHub redirects renamed team slugs, so an old mention would still LOOK
live while the agent silently never ran — the UI lying, which is the failure
class we have been eliminating. Probed it directly: created a team, rendered
its mention (team-mention link), renamed the team, re-rendered the OLD handle:
before rename: <a class="team-mention" ...>@petry-projects/pm-alias-probe</a>
after rename: <p>@petry-projects/pm-alias-probe please review</p>
The old handle renders as PLAIN TEXT. GitHub itself stops treating it as a
mention, so the user sees grey text and knows instantly it did not resolve.
The failure is visible, and the fix is obvious: re-mention with the new handle.
So aliases would only route text GitHub no longer considers a mention — not worth
a derived index, an extra fetch on every 404, and a contract the router cannot
honour. See petry-projects/.github#755 finding 1.
Handle uniqueness is now a THEOREM, so its check is removed
check_handles_unique existed because aliases shared the handle namespace. Without
them it is provably unreachable: the schema pins the org (^petry-projects/...),
slug == id, id == the persona directory name, and directory names are unique — so
two personas cannot claim the same handle. A validator function that can never
fire is a liability: it implies a check where none is needed and invites
maintenance. Removed, with the theorem documented where the slug check lives.
Changes
- personas/qa-lead/persona.yml — drop `aliases: []`
- personas/validate-personas.py — drop alias shape validation and the now-dead
check_handles_unique; document the uniqueness theorem
- tests/test_validate_personas.bats — drop the 4 alias tests and the helper's
alias varargs; the handle-collision tests went with them because they used an
alias as the collision vector and the collision is now impossible
Verification
- bats tests/test_validate_personas.bats: 16/16 (was 20; 4 alias tests removed).
- validate-personas.py against the LIVE main schema (which still permits aliases,
so this must pass BEFORE the companion lands): OK, invariants hold.
- scripts/verify-persona-teams.sh (from #1284): OK — qa-lead's team still
verifies live (exists, closed, notifications disabled).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(personas): drop the last aliases fixture and scope the theorem claim
Both from Copilot's review; both correct.
1. tests/verify_persona_teams.bats still wrote `aliases: []`
A real miss, and exactly the ordered-pair landmine this PR exists to avoid: the
moment the companion drops `aliases` from the schema (additionalProperties:
false), this fixture's generated manifest would fail validation. It survived
because my sweep grepped personas/ and tests/test_validate_personas.bats — this
fixture lives in the suite #1284 added, which I never looked at. A repo-wide
grep now shows zero remaining uses.
2. The uniqueness theorem was stated more broadly than it holds
The docstring claimed a uniqueness check "could never fire" — unconditionally
true only once the schema drops aliases. Today the schema still PERMITS an
alias, and aliases shared the handle namespace the theorem does not cover, so
until the companion lands, re-adding one would reopen exactly the gap the check
used to close. Scoped the claim to address.handle (the only thing the router
resolves) and recorded the window explicitly.
Verification
- bats tests/test_validate_personas.bats: 16/16.
- bats tests/verify_persona_teams.bats: 16/16 (the #1284 suite, now alias-free).
- validate-personas.py against the LIVE main schema: OK, invariants hold.
- Repo-wide grep for `aliases`: zero uses outside the docstring note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(personas): stop using address.aliases (half 1 of 2)
Aliases are dropped from the addressing contract. This is the FIRST half of an
ordered cross-repo pair — it removes every USE of the field. The companion PR in
petry-projects/.github then drops it from the schema. Reversing that order breaks
main fleet-wide: the schema is additionalProperties:false, so dropping the field
first makes qa-lead's `aliases: []` fail validate-personas everywhere.
Why drop them (settled empirically, not by taste)
An alias exists so a RENAMED persona keeps routing: qa-lead declaring
`aliases: [petry-projects/murat]` so old comments still reach it. Two problems:
1. Index-free routing cannot honour it. The router resolves '@petry-projects/murat'
to personas/murat/persona.yml — a 404 after the rename. The alias is declared
inside qa-lead's manifest, which the router never opens because it does not
know to look there. Chicken-and-egg. The attempt at pm_persona_aliases in
.github#754 was unreachable for exactly this reason.
2. The severity argument for keeping them turned out to be FALSE. The worry was
that GitHub redirects renamed team slugs, so an old mention would still LOOK
live while the agent silently never ran — the UI lying, which is the failure
class we have been eliminating. Probed it directly: created a team, rendered
its mention (team-mention link), renamed the team, re-rendered the OLD handle:
before rename: <a class="team-mention" ...>@petry-projects/pm-alias-probe</a>
after rename: <p>@petry-projects/pm-alias-probe please review</p>
The old handle renders as PLAIN TEXT. GitHub itself stops treating it as a
mention, so the user sees grey text and knows instantly it did not resolve.
The failure is visible, and the fix is obvious: re-mention with the new handle.
So aliases would only route text GitHub no longer considers a mention — not worth
a derived index, an extra fetch on every 404, and a contract the router cannot
honour. See petry-projects/.github#755 finding 1.
Handle uniqueness is now a THEOREM, so its check is removed
check_handles_unique existed because aliases shared the handle namespace. Without
them it is provably unreachable: the schema pins the org (^petry-projects/...),
slug == id, id == the persona directory name, and directory names are unique — so
two personas cannot claim the same handle. A validator function that can never
fire is a liability: it implies a check where none is needed and invites
maintenance. Removed, with the theorem documented where the slug check lives.
Changes
- personas/qa-lead/persona.yml — drop `aliases: []`
- personas/validate-personas.py — drop alias shape validation and the now-dead
check_handles_unique; document the uniqueness theorem
- tests/test_validate_personas.bats — drop the 4 alias tests and the helper's
alias varargs; the handle-collision tests went with them because they used an
alias as the collision vector and the collision is now impossible
Verification
- bats tests/test_validate_personas.bats: 16/16 (was 20; 4 alias tests removed).
- validate-personas.py against the LIVE main schema (which still permits aliases,
so this must pass BEFORE the companion lands): OK, invariants hold.
- scripts/verify-persona-teams.sh (from #1284): OK — qa-lead's team still
verifies live (exists, closed, notifications disabled).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(personas): drop the last aliases fixture and scope the theorem claim
Both from Copilot's review; both correct.
1. tests/verify_persona_teams.bats still wrote `aliases: []`
A real miss, and exactly the ordered-pair landmine this PR exists to avoid: the
moment the companion drops `aliases` from the schema (additionalProperties:
false), this fixture's generated manifest would fail validation. It survived
because my sweep grepped personas/ and tests/test_validate_personas.bats — this
fixture lives in the suite #1284 added, which I never looked at. A repo-wide
grep now shows zero remaining uses.
2. The uniqueness theorem was stated more broadly than it holds
The docstring claimed a uniqueness check "could never fire" — unconditionally
true only once the schema drops aliases. Today the schema still PERMITS an
alias, and aliases shared the handle namespace the theorem does not cover, so
until the companion lands, re-adding one would reopen exactly the gap the check
used to close. Scoped the claim to address.handle (the only thing the router
resolves) and recorded the window explicitly.
Verification
- bats tests/test_validate_personas.bats: 16/16.
- bats tests/verify_persona_teams.bats: 16/16 (the #1284 suite, now alias-free).
- validate-personas.py against the LIVE main schema: OK, invariants hold.
- Repo-wide grep for `aliases`: zero uses outside the docstring note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(personas): stop using address.aliases (half 1 of 2)
Aliases are dropped from the addressing contract. This is the FIRST half of an
ordered cross-repo pair — it removes every USE of the field. The companion PR in
petry-projects/.github then drops it from the schema. Reversing that order breaks
main fleet-wide: the schema is additionalProperties:false, so dropping the field
first makes qa-lead's `aliases: []` fail validate-personas everywhere.
Why drop them (settled empirically, not by taste)
An alias exists so a RENAMED persona keeps routing: qa-lead declaring
`aliases: [petry-projects/murat]` so old comments still reach it. Two problems:
1. Index-free routing cannot honour it. The router resolves '@petry-projects/murat'
to personas/murat/persona.yml — a 404 after the rename. The alias is declared
inside qa-lead's manifest, which the router never opens because it does not
know to look there. Chicken-and-egg. The attempt at pm_persona_aliases in
.github#754 was unreachable for exactly this reason.
2. The severity argument for keeping them turned out to be FALSE. The worry was
that GitHub redirects renamed team slugs, so an old mention would still LOOK
live while the agent silently never ran — the UI lying, which is the failure
class we have been eliminating. Probed it directly: created a team, rendered
its mention (team-mention link), renamed the team, re-rendered the OLD handle:
before rename: <a class="team-mention" ...>@petry-projects/pm-alias-probe</a>
after rename: <p>@petry-projects/pm-alias-probe please review</p>
The old handle renders as PLAIN TEXT. GitHub itself stops treating it as a
mention, so the user sees grey text and knows instantly it did not resolve.
The failure is visible, and the fix is obvious: re-mention with the new handle.
So aliases would only route text GitHub no longer considers a mention — not worth
a derived index, an extra fetch on every 404, and a contract the router cannot
honour. See petry-projects/.github#755 finding 1.
Handle uniqueness is now a THEOREM, so its check is removed
check_handles_unique existed because aliases shared the handle namespace. Without
them it is provably unreachable: the schema pins the org (^petry-projects/...),
slug == id, id == the persona directory name, and directory names are unique — so
two personas cannot claim the same handle. A validator function that can never
fire is a liability: it implies a check where none is needed and invites
maintenance. Removed, with the theorem documented where the slug check lives.
Changes
- personas/qa-lead/persona.yml — drop `aliases: []`
- personas/validate-personas.py — drop alias shape validation and the now-dead
check_handles_unique; document the uniqueness theorem
- tests/test_validate_personas.bats — drop the 4 alias tests and the helper's
alias varargs; the handle-collision tests went with them because they used an
alias as the collision vector and the collision is now impossible
Verification
- bats tests/test_validate_personas.bats: 16/16 (was 20; 4 alias tests removed).
- validate-personas.py against the LIVE main schema (which still permits aliases,
so this must pass BEFORE the companion lands): OK, invariants hold.
- scripts/verify-persona-teams.sh (from #1284): OK — qa-lead's team still
verifies live (exists, closed, notifications disabled).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(personas): drop the last aliases fixture and scope the theorem claim
Both from Copilot's review; both correct.
1. tests/verify_persona_teams.bats still wrote `aliases: []`
A real miss, and exactly the ordered-pair landmine this PR exists to avoid: the
moment the companion drops `aliases` from the schema (additionalProperties:
false), this fixture's generated manifest would fail validation. It survived
because my sweep grepped personas/ and tests/test_validate_personas.bats — this
fixture lives in the suite #1284 added, which I never looked at. A repo-wide
grep now shows zero remaining uses.
2. The uniqueness theorem was stated more broadly than it holds
The docstring claimed a uniqueness check "could never fire" — unconditionally
true only once the schema drops aliases. Today the schema still PERMITS an
alias, and aliases shared the handle namespace the theorem does not cover, so
until the companion lands, re-adding one would reopen exactly the gap the check
used to close. Scoped the claim to address.handle (the only thing the router
resolves) and recorded the window explicitly.
Verification
- bats tests/test_validate_personas.bats: 16/16.
- bats tests/verify_persona_teams.bats: 16/16 (the #1284 suite, now alias-free).
- validate-personas.py against the LIVE main schema: OK, invariants hold.
- Repo-wide grep for `aliases`: zero uses outside the docstring note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(personas): stop using address.aliases (half 1 of 2)
Aliases are dropped from the addressing contract. This is the FIRST half of an
ordered cross-repo pair — it removes every USE of the field. The companion PR in
petry-projects/.github then drops it from the schema. Reversing that order breaks
main fleet-wide: the schema is additionalProperties:false, so dropping the field
first makes qa-lead's `aliases: []` fail validate-personas everywhere.
Why drop them (settled empirically, not by taste)
An alias exists so a RENAMED persona keeps routing: qa-lead declaring
`aliases: [petry-projects/murat]` so old comments still reach it. Two problems:
1. Index-free routing cannot honour it. The router resolves '@petry-projects/murat'
to personas/murat/persona.yml — a 404 after the rename. The alias is declared
inside qa-lead's manifest, which the router never opens because it does not
know to look there. Chicken-and-egg. The attempt at pm_persona_aliases in
.github#754 was unreachable for exactly this reason.
2. The severity argument for keeping them turned out to be FALSE. The worry was
that GitHub redirects renamed team slugs, so an old mention would still LOOK
live while the agent silently never ran — the UI lying, which is the failure
class we have been eliminating. Probed it directly: created a team, rendered
its mention (team-mention link), renamed the team, re-rendered the OLD handle:
before rename: <a class="team-mention" ...>@petry-projects/pm-alias-probe</a>
after rename: <p>@petry-projects/pm-alias-probe please review</p>
The old handle renders as PLAIN TEXT. GitHub itself stops treating it as a
mention, so the user sees grey text and knows instantly it did not resolve.
The failure is visible, and the fix is obvious: re-mention with the new handle.
So aliases would only route text GitHub no longer considers a mention — not worth
a derived index, an extra fetch on every 404, and a contract the router cannot
honour. See petry-projects/.github#755 finding 1.
Handle uniqueness is now a THEOREM, so its check is removed
check_handles_unique existed because aliases shared the handle namespace. Without
them it is provably unreachable: the schema pins the org (^petry-projects/...),
slug == id, id == the persona directory name, and directory names are unique — so
two personas cannot claim the same handle. A validator function that can never
fire is a liability: it implies a check where none is needed and invites
maintenance. Removed, with the theorem documented where the slug check lives.
Changes
- personas/qa-lead/persona.yml — drop `aliases: []`
- personas/validate-personas.py — drop alias shape validation and the now-dead
check_handles_unique; document the uniqueness theorem
- tests/test_validate_personas.bats — drop the 4 alias tests and the helper's
alias varargs; the handle-collision tests went with them because they used an
alias as the collision vector and the collision is now impossible
Verification
- bats tests/test_validate_personas.bats: 16/16 (was 20; 4 alias tests removed).
- validate-personas.py against the LIVE main schema (which still permits aliases,
so this must pass BEFORE the companion lands): OK, invariants hold.
- scripts/verify-persona-teams.sh (from #1284): OK — qa-lead's team still
verifies live (exists, closed, notifications disabled).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(personas): drop the last aliases fixture and scope the theorem claim
Both from Copilot's review; both correct.
1. tests/verify_persona_teams.bats still wrote `aliases: []`
A real miss, and exactly the ordered-pair landmine this PR exists to avoid: the
moment the companion drops `aliases` from the schema (additionalProperties:
false), this fixture's generated manifest would fail validation. It survived
because my sweep grepped personas/ and tests/test_validate_personas.bats — this
fixture lives in the suite #1284 added, which I never looked at. A repo-wide
grep now shows zero remaining uses.
2. The uniqueness theorem was stated more broadly than it holds
The docstring claimed a uniqueness check "could never fire" — unconditionally
true only once the schema drops aliases. Today the schema still PERMITS an
alias, and aliases shared the handle namespace the theorem does not cover, so
until the companion lands, re-adding one would reopen exactly the gap the check
used to close. Scoped the claim to address.handle (the only thing the router
resolves) and recorded the window explicitly.
Verification
- bats tests/test_validate_personas.bats: 16/16.
- bats tests/verify_persona_teams.bats: 16/16 (the #1284 suite, now alias-free).
- validate-personas.py against the LIVE main schema: OK, invariants hold.
- Repo-wide grep for `aliases`: zero uses outside the docstring note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(personas): stop using address.aliases (half 1 of 2)
Aliases are dropped from the addressing contract. This is the FIRST half of an
ordered cross-repo pair — it removes every USE of the field. The companion PR in
petry-projects/.github then drops it from the schema. Reversing that order breaks
main fleet-wide: the schema is additionalProperties:false, so dropping the field
first makes qa-lead's `aliases: []` fail validate-personas everywhere.
Why drop them (settled empirically, not by taste)
An alias exists so a RENAMED persona keeps routing: qa-lead declaring
`aliases: [petry-projects/murat]` so old comments still reach it. Two problems:
1. Index-free routing cannot honour it. The router resolves '@petry-projects/murat'
to personas/murat/persona.yml — a 404 after the rename. The alias is declared
inside qa-lead's manifest, which the router never opens because it does not
know to look there. Chicken-and-egg. The attempt at pm_persona_aliases in
.github#754 was unreachable for exactly this reason.
2. The severity argument for keeping them turned out to be FALSE. The worry was
that GitHub redirects renamed team slugs, so an old mention would still LOOK
live while the agent silently never ran — the UI lying, which is the failure
class we have been eliminating. Probed it directly: created a team, rendered
its mention (team-mention link), renamed the team, re-rendered the OLD handle:
before rename: <a class="team-mention" ...>@petry-projects/pm-alias-probe</a>
after rename: <p>@petry-projects/pm-alias-probe please review</p>
The old handle renders as PLAIN TEXT. GitHub itself stops treating it as a
mention, so the user sees grey text and knows instantly it did not resolve.
The failure is visible, and the fix is obvious: re-mention with the new handle.
So aliases would only route text GitHub no longer considers a mention — not worth
a derived index, an extra fetch on every 404, and a contract the router cannot
honour. See petry-projects/.github#755 finding 1.
Handle uniqueness is now a THEOREM, so its check is removed
check_handles_unique existed because aliases shared the handle namespace. Without
them it is provably unreachable: the schema pins the org (^petry-projects/...),
slug == id, id == the persona directory name, and directory names are unique — so
two personas cannot claim the same handle. A validator function that can never
fire is a liability: it implies a check where none is needed and invites
maintenance. Removed, with the theorem documented where the slug check lives.
Changes
- personas/qa-lead/persona.yml — drop `aliases: []`
- personas/validate-personas.py — drop alias shape validation and the now-dead
check_handles_unique; document the uniqueness theorem
- tests/test_validate_personas.bats — drop the 4 alias tests and the helper's
alias varargs; the handle-collision tests went with them because they used an
alias as the collision vector and the collision is now impossible
Verification
- bats tests/test_validate_personas.bats: 16/16 (was 20; 4 alias tests removed).
- validate-personas.py against the LIVE main schema (which still permits aliases,
so this must pass BEFORE the companion lands): OK, invariants hold.
- scripts/verify-persona-teams.sh (from #1284): OK — qa-lead's team still
verifies live (exists, closed, notifications disabled).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(personas): drop the last aliases fixture and scope the theorem claim
Both from Copilot's review; both correct.
1. tests/verify_persona_teams.bats still wrote `aliases: []`
A real miss, and exactly the ordered-pair landmine this PR exists to avoid: the
moment the companion drops `aliases` from the schema (additionalProperties:
false), this fixture's generated manifest would fail validation. It survived
because my sweep grepped personas/ and tests/test_validate_personas.bats — this
fixture lives in the suite #1284 added, which I never looked at. A repo-wide
grep now shows zero remaining uses.
2. The uniqueness theorem was stated more broadly than it holds
The docstring claimed a uniqueness check "could never fire" — unconditionally
true only once the schema drops aliases. Today the schema still PERMITS an
alias, and aliases shared the handle namespace the theorem does not cover, so
until the companion lands, re-adding one would reopen exactly the gap the check
used to close. Scoped the claim to address.handle (the only thing the router
resolves) and recorded the window explicitly.
Verification
- bats tests/test_validate_personas.bats: 16/16.
- bats tests/verify_persona_teams.bats: 16/16 (the #1284 suite, now alias-free).
- validate-personas.py against the LIVE main schema: OK, invariants hold.
- Repo-wide grep for `aliases`: zero uses outside the docstring note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(personas): stop using address.aliases (half 1 of 2)
Aliases are dropped from the addressing contract. This is the FIRST half of an
ordered cross-repo pair — it removes every USE of the field. The companion PR in
petry-projects/.github then drops it from the schema. Reversing that order breaks
main fleet-wide: the schema is additionalProperties:false, so dropping the field
first makes qa-lead's `aliases: []` fail validate-personas everywhere.
Why drop them (settled empirically, not by taste)
An alias exists so a RENAMED persona keeps routing: qa-lead declaring
`aliases: [petry-projects/murat]` so old comments still reach it. Two problems:
1. Index-free routing cannot honour it. The router resolves '@petry-projects/murat'
to personas/murat/persona.yml — a 404 after the rename. The alias is declared
inside qa-lead's manifest, which the router never opens because it does not
know to look there. Chicken-and-egg. The attempt at pm_persona_aliases in
.github#754 was unreachable for exactly this reason.
2. The severity argument for keeping them turned out to be FALSE. The worry was
that GitHub redirects renamed team slugs, so an old mention would still LOOK
live while the agent silently never ran — the UI lying, which is the failure
class we have been eliminating. Probed it directly: created a team, rendered
its mention (team-mention link), renamed the team, re-rendered the OLD handle:
before rename: <a class="team-mention" ...>@petry-projects/pm-alias-probe</a>
after rename: <p>@petry-projects/pm-alias-probe please review</p>
The old handle renders as PLAIN TEXT. GitHub itself stops treating it as a
mention, so the user sees grey text and knows instantly it did not resolve.
The failure is visible, and the fix is obvious: re-mention with the new handle.
So aliases would only route text GitHub no longer considers a mention — not worth
a derived index, an extra fetch on every 404, and a contract the router cannot
honour. See petry-projects/.github#755 finding 1.
Handle uniqueness is now a THEOREM, so its check is removed
check_handles_unique existed because aliases shared the handle namespace. Without
them it is provably unreachable: the schema pins the org (^petry-projects/...),
slug == id, id == the persona directory name, and directory names are unique — so
two personas cannot claim the same handle. A validator function that can never
fire is a liability: it implies a check where none is needed and invites
maintenance. Removed, with the theorem documented where the slug check lives.
Changes
- personas/qa-lead/persona.yml — drop `aliases: []`
- personas/validate-personas.py — drop alias shape validation and the now-dead
check_handles_unique; document the uniqueness theorem
- tests/test_validate_personas.bats — drop the 4 alias tests and the helper's
alias varargs; the handle-collision tests went with them because they used an
alias as the collision vector and the collision is now impossible
Verification
- bats tests/test_validate_personas.bats: 16/16 (was 20; 4 alias tests removed).
- validate-personas.py against the LIVE main schema (which still permits aliases,
so this must pass BEFORE the companion lands): OK, invariants hold.
- scripts/verify-persona-teams.sh (from #1284): OK — qa-lead's team still
verifies live (exists, closed, notifications disabled).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(personas): drop the last aliases fixture and scope the theorem claim
Both from Copilot's review; both correct.
1. tests/verify_persona_teams.bats still wrote `aliases: []`
A real miss, and exactly the ordered-pair landmine this PR exists to avoid: the
moment the companion drops `aliases` from the schema (additionalProperties:
false), this fixture's generated manifest would fail validation. It survived
because my sweep grepped personas/ and tests/test_validate_personas.bats — this
fixture lives in the suite #1284 added, which I never looked at. A repo-wide
grep now shows zero remaining uses.
2. The uniqueness theorem was stated more broadly than it holds
The docstring claimed a uniqueness check "could never fire" — unconditionally
true only once the schema drops aliases. Today the schema still PERMITS an
alias, and aliases shared the handle namespace the theorem does not cover, so
until the companion lands, re-adding one would reopen exactly the gap the check
used to close. Scoped the claim to address.handle (the only thing the router
resolves) and recorded the window explicitly.
Verification
- bats tests/test_validate_personas.bats: 16/16.
- bats tests/verify_persona_teams.bats: 16/16 (the #1284 suite, now alias-free).
- validate-personas.py against the LIVE main schema: OK, invariants hold.
- Repo-wide grep for `aliases`: zero uses outside the docstring note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(personas): stop using address.aliases (half 1 of 2)
Aliases are dropped from the addressing contract. This is the FIRST half of an
ordered cross-repo pair — it removes every USE of the field. The companion PR in
petry-projects/.github then drops it from the schema. Reversing that order breaks
main fleet-wide: the schema is additionalProperties:false, so dropping the field
first makes qa-lead's `aliases: []` fail validate-personas everywhere.
Why drop them (settled empirically, not by taste)
An alias exists so a RENAMED persona keeps routing: qa-lead declaring
`aliases: [petry-projects/murat]` so old comments still reach it. Two problems:
1. Index-free routing cannot honour it. The router resolves '@petry-projects/murat'
to personas/murat/persona.yml — a 404 after the rename. The alias is declared
inside qa-lead's manifest, which the router never opens because it does not
know to look there. Chicken-and-egg. The attempt at pm_persona_aliases in
.github#754 was unreachable for exactly this reason.
2. The severity argument for keeping them turned out to be FALSE. The worry was
that GitHub redirects renamed team slugs, so an old mention would still LOOK
live while the agent silently never ran — the UI lying, which is the failure
class we have been eliminating. Probed it directly: created a team, rendered
its mention (team-mention link), renamed the team, re-rendered the OLD handle:
before rename: <a class="team-mention" ...>@petry-projects/pm-alias-probe</a>
after rename: <p>@petry-projects/pm-alias-probe please review</p>
The old handle renders as PLAIN TEXT. GitHub itself stops treating it as a
mention, so the user sees grey text and knows instantly it did not resolve.
The failure is visible, and the fix is obvious: re-mention with the new handle.
So aliases would only route text GitHub no longer considers a mention — not worth
a derived index, an extra fetch on every 404, and a contract the router cannot
honour. See petry-projects/.github#755 finding 1.
Handle uniqueness is now a THEOREM, so its check is removed
check_handles_unique existed because aliases shared the handle namespace. Without
them it is provably unreachable: the schema pins the org (^petry-projects/...),
slug == id, id == the persona directory name, and directory names are unique — so
two personas cannot claim the same handle. A validator function that can never
fire is a liability: it implies a check where none is needed and invites
maintenance. Removed, with the theorem documented where the slug check lives.
Changes
- personas/qa-lead/persona.yml — drop `aliases: []`
- personas/validate-personas.py — drop alias shape validation and the now-dead
check_handles_unique; document the uniqueness theorem
- tests/test_validate_personas.bats — drop the 4 alias tests and the helper's
alias varargs; the handle-collision tests went with them because they used an
alias as the collision vector and the collision is now impossible
Verification
- bats tests/test_validate_personas.bats: 16/16 (was 20; 4 alias tests removed).
- validate-personas.py against the LIVE main schema (which still permits aliases,
so this must pass BEFORE the companion lands): OK, invariants hold.
- scripts/verify-persona-teams.sh (from #1284): OK — qa-lead's team still
verifies live (exists, closed, notifications disabled).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(personas): drop the last aliases fixture and scope the theorem claim
Both from Copilot's review; both correct.
1. tests/verify_persona_teams.bats still wrote `aliases: []`
A real miss, and exactly the ordered-pair landmine this PR exists to avoid: the
moment the companion drops `aliases` from the schema (additionalProperties:
false), this fixture's generated manifest would fail validation. It survived
because my sweep grepped personas/ and tests/test_validate_personas.bats — this
fixture lives in the suite #1284 added, which I never looked at. A repo-wide
grep now shows zero remaining uses.
2. The uniqueness theorem was stated more broadly than it holds
The docstring claimed a uniqueness check "could never fire" — unconditionally
true only once the schema drops aliases. Today the schema still PERMITS an
alias, and aliases shared the handle namespace the theorem does not cover, so
until the companion lands, re-adding one would reopen exactly the gap the check
used to close. Scoped the claim to address.handle (the only thing the router
resolves) and recorded the window explicitly.
Verification
- bats tests/test_validate_personas.bats: 16/16.
- bats tests/verify_persona_teams.bats: 16/16 (the #1284 suite, now alias-free).
- validate-personas.py against the LIVE main schema: OK, invariants hold.
- Repo-wide grep for `aliases`: zero uses outside the docstring note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>



Drops
address.aliasesfrom the addressing contract. First half of an ordered cross-repo pair — this removes every use of the field; the companion inpetry-projects/.githubthen drops it from the schema.Order matters. The schema is
additionalProperties: false, so dropping the field first would makeqa-lead'saliases: []failvalidate-personasfleet-wide on main. Usage goes first.Why drop them — settled empirically, not by taste
An alias exists so a renamed persona keeps routing:
qa-leaddeclaringaliases: [petry-projects/murat]so old comments still reach it. Two problems:1. Index-free routing can't honour it. The router resolves
@petry-projects/murat→personas/murat/persona.yml→ 404 after the rename. The alias is declared inside qa-lead's manifest, which the router never opens because it doesn't know to look there. Chicken-and-egg. Thepm_persona_aliasesattempt in .github#754 was unreachable for exactly this reason.2. The strongest argument for keeping them turned out to be false. The worry: GitHub redirects renamed team slugs, so an old mention would still look live while the agent silently never ran — the UI lying, which is the failure class we've been eliminating. I probed it directly — created a team, rendered its mention, renamed the team, re-rendered the old handle:
<a class="team-mention" ...>@petry-projects/pm-alias-probe</a><p>@petry-projects/pm-alias-probe please review</p>GitHub itself stops treating the old handle as a mention. It becomes grey plain text, so the user sees instantly that it didn't resolve, and the fix is obvious: re-mention with the new handle.
So aliases would only route text GitHub no longer considers a mention — not worth a derived index, an extra fetch on every 404, and a contract the router can't honour. (#755 finding 1.)
Handle uniqueness is now a theorem, so its check is removed
check_handles_uniqueexisted because aliases shared the handle namespace. Without them it's provably unreachable:^petry-projects/[a-z0-9]+(-[a-z0-9]+)*$slug == id(enforced)id ==the persona directory name (enforced)⇒ two personas cannot claim the same handle. A validator function that can never fire is a liability — it implies a check where none is needed and invites maintenance. Removed, with the theorem documented where the slug check lives.
Verification
bats tests/test_validate_personas.bats— 16/16 (was 20; the 4 alias tests removed. The handle-collision tests went with them because they used an alias as the collision vector, and the collision is now impossible.)validate-personas.pyagainst the live main schema (which still permits aliases — so this must pass before the companion lands): OK, invariants holdscripts/verify-persona-teams.sh(from feat: implement issue #1280 — Verify persona addressing teams in CI #1284): OK — qa-lead's team still verifies live (exists, closed, notifications disabled)🤖 Generated with Claude Code