Skip to content

feat(content): identity age_hint column, migration, Bible backfill (T-012) - #15

Merged
BrandanBurgess merged 40 commits into
mainfrom
integration
Jul 16, 2026
Merged

feat(content): identity age_hint column, migration, Bible backfill (T-012)#15
BrandanBurgess merged 40 commits into
mainfrom
integration

Conversation

@BrandanBurgess

Copy link
Copy Markdown
Owner

T-012: Founder decision 3 (2026-07-16) — identities carry age_hint

Migration 0005 (re-pointed from 0004 after T-043 merged first; chain 0001-0005 proven from zero) adds identities.age_hint NOT NULL. All 27 identities backfilled (6 archetypes, 15 reference teams, 6 cult corner); validator now requires the field; seed loader upserts it onto existing rows idempotently. Identity page details panel renders an Age hint row (e2e asserts content and DOM position); backend test asserts every identity returns a non-empty hint.

Note for founder QA: Bible 8.2.4 states the age-suitability rule with two examples rather than a per-card table, so the per-identity hints are editorial (U9+/U11+/U13+/U15+ scale consistent with the existing library hints). Full table is in the T-012 agent report; review alongside your planned post-deploy content QA.

Coverage

  • make verify green on integration post-merge (pytest 142+2 skipped, playwright 90 both viewports, seed validator 132 items with the new required field)
  • Fresh-DB proof: migrate from zero, seed, API returns all 27 identities with non-empty age_hint

🤖 Generated with Claude Code

BrandanBurgess and others added 30 commits July 16, 2026 02:39
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…T-030)

Whiteboard page (Brief step 16, PNG 01-05/14/34): toolbar, view menu
(zones + thresholds), record/replay, and save into My Patterns, all
persisted through the scoped query layer (backend/app/routers/whiteboard.py)
into the boards and saved_patterns rows (doc 03 4.2/4.3). Delete is
coach-only, enforced server-side (403 for players), and every saved
pattern is author-stamped from the caller's own membership, never a
client-supplied field.

Fixes a real reload bug: the view menu's settings popover floated above
the toolbar and, left open, could visually sit on top of a token (e.g.
the ball's default spot, or any token near the toolbar on a phone-width
board). A drag or click landing there hit the popover instead of the
token, and for a checkbox's label that silently flipped a zone toggle
the user never touched, which then persisted to the boards row on
reload. Fixed by closing the view menu when recording starts (a
deliberate mode switch) and, for phone-width boards where the popover
has no gap in the pitch it can occupy without covering some token,
pinning it to the viewport's top edge instead of floating over the
pitch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Systematic permission test suite covering every Brief section 3 table
row in both roles, API and UI: backend/tests/test_permissions.py names
each test after its table row (whiteboard, delete-a-pattern, library/
formations/identity, roster/fit-warnings, plus the additive-only and
player-token-gets-403 principles), and e2e/permissions.spec.ts sweeps a
player-role visit across all five pages asserting coach-only controls
and data are absent from the DOM, not merely hidden.

Audit result: no enforcement gaps found. Whiteboard delete, roster CRUD,
and fit_warnings exclusion were already API-enforced from their own
tickets (T-030, T-033); this suite pins that behavior explicitly against
the table rather than leaving it implicit across five separate files.

Two table rows (Suggest own playstyle, Sessions) have no API surface yet
in this codebase state, only their models: marked as named, skipped
tests with a reason, for T-041/T-042 to turn into real assertions rather
than silently omitted.

One known ambiguity is pinned, not changed, per this ticket's own
instruction: the API returns join_code to any team member while the UI
shows it to coaches only (docs/agent/STATE.md open founder question 2).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Player submits a free-text playstyle suggestion on their own roster
profile, sees it pending; coach reviews from a team-wide queue with a
gold badge and an Approve/Dismiss card; approve merges the text into
players.playstyle_note (visible both roles), dismiss clears it with no
merge. New backend/app/routers/suggestions.py enforces every direction
at the API: only a player may submit, and only against their own linked
roster row; only a coach may list the pending queue, approve, or
dismiss (403 otherwise). No new migration: playstyle_suggestions already
exists in the 0002 schema migration.

Player-row linkage (needed for "own profile") did not exist yet before
this ticket; app/routers/roster.py adds a minimal, UI-free claim: on a
player's own GET /api/roster, an unclaimed row whose name uniquely
matches their display_name becomes theirs.
BrandanBurgess and others added 10 commits July 16, 2026 13:04
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…-012)

Founder decision 2026-07-16: doc 03's identities schema had no age_hint
when T-010 shipped, so Bible 8.2.4's age-suitability rule only covered
library_items. Adds migration 0004 (down_revision 0003), the age_hint
column on Identity/IdentityOut, backfills all 27 identity cards from the
Bible, makes age_hint required in the seed validator, and renders it on
the Identity page's details panel.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@BrandanBurgess
BrandanBurgess merged commit 26092fa into main Jul 16, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant