docs(implplan): create SPRINT_20260422_005 for Authority default-tenant bootstrap gap
Two parallel QA agents (fe-qa-006-relsec, fe-qa-007-evidops) independently
hit the same bootstrap bug on 2026-04-22: fresh Authority DBs lack the
`default` tenant row, so setup-wizard Admin creation fails with
users_tenant_id_fkey and admin/connect/token returns invalid_grant.
The gap appeared because SPRINT_20260422_003 (Authority §2.7 compliance,
archived) correctly trimmed 04-authority-schema.sql to "seeds only" — but
the guarded tenant seed runs only when the schema exists at init-script
time, which it doesn't for migration-owned schemas.
Both agents worked around it in-session by manually inserting `default` +
`installation` tenants and calling POST /api/v1/setup/sessions/{id}/
steps/admin/execute. This sprint puts the seed on the migration path so
the fix converges automatically.
Three tasks: add seed migration (AUTH-SEED-001), verify fresh-volume
bootstrap works without manual SQL (AUTH-SEED-002), document the contract
(AUTH-SEED-003).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,75 @@
|
|||||||
|
# Sprint 20260422-005 — Authority default-tenant bootstrap
|
||||||
|
|
||||||
|
## Topic & Scope
|
||||||
|
- Close the bootstrap gap that forces setup-wizard Admin creation to fail with `users_tenant_id_fkey (tenant_id)=(default)` on any fresh Authority DB.
|
||||||
|
- The previous Authority §2.7 compliance sprint (`SPRINT_20260422_003_Authority_auto_migration_compliance`, archived) trimmed `devops/compose/postgres-init/04-authority-schema.sql` to "seeds only". In doing so, the guarded `default` tenant seed now runs only when the schema exists at init-script time — which, for migration-owned schemas, it doesn't. Result: freshly-migrated Authority DBs have zero tenants, the setup wizard fails, admin login returns `invalid_grant`.
|
||||||
|
- Two parallel QA agents (`fe-qa-006-relsec` and `fe-qa-007-evidops` in SPRINT_20260421_006/007 closeouts on 2026-04-22) independently hit this bug and worked around it by manually inserting the `default` + `installation` tenant rows and calling `POST /api/v1/setup/sessions/{id}/steps/admin/execute`.
|
||||||
|
- Working directory: `src/Authority/` (primary); `devops/compose/postgres-init/04-authority-schema.sql` + `04b-authority-dedicated-schema.sql` only if the seed fallback needs tightening.
|
||||||
|
- Expected evidence: fresh-volume bring-up (`docker compose down -v && docker compose up -d`) produces a working Authority with `default` tenant present and setup-wizard Admin bootstrap succeeding without manual intervention.
|
||||||
|
|
||||||
|
## Dependencies & Concurrency
|
||||||
|
- Follow-up to `SPRINT_20260422_003_Authority_auto_migration_compliance` (archived). Migration wiring and schema ownership contract established there are the baseline.
|
||||||
|
- No cross-module dependencies; safe to run alongside any non-Authority sprint.
|
||||||
|
|
||||||
|
## Documentation Prerequisites
|
||||||
|
- `CLAUDE.md` §2.7 — auto-migration + init script contract.
|
||||||
|
- `docs-archived/implplan/SPRINT_20260422_003_Authority_auto_migration_compliance.md` — the Decisions & Risks from the prior sprint explain why the init script was trimmed.
|
||||||
|
- `src/Authority/__Libraries/StellaOps.Authority.Persistence/Migrations/001_initial_schema.sql` — where a seed migration could live.
|
||||||
|
- `src/Authority/__Libraries/StellaOps.Authority.Persistence/Migrations/S001_demo_seed.sql` (if present) — pattern reference for seed-category migrations.
|
||||||
|
|
||||||
|
## Delivery Tracker
|
||||||
|
|
||||||
|
### AUTH-SEED-001 — Seed `default` tenant through the migration path
|
||||||
|
Status: TODO
|
||||||
|
Dependency: none
|
||||||
|
Owners: Developer (backend)
|
||||||
|
Task description:
|
||||||
|
- Add the `default` (and `installation`, if the setup wizard expects both) tenant rows as an embedded seed migration under `src/Authority/__Libraries/StellaOps.Authority.Persistence/Migrations/`. Seed-category filename so it runs after the DDL migrations and is idempotent (`INSERT ... ON CONFLICT (id) DO NOTHING` or equivalent).
|
||||||
|
- The migration runner established in AUTH-MIGRATE-002 applies all embedded SQL resources on startup; placing the seed here means both fresh-volume and already-provisioned environments converge to the same state.
|
||||||
|
- Do NOT add the seed to `04-authority-schema.sql` — that script stays pure-fallback per the prior sprint's Decision.
|
||||||
|
|
||||||
|
Completion criteria:
|
||||||
|
- [ ] Seed migration is an embedded resource in the persistence assembly.
|
||||||
|
- [ ] `default` tenant row exists after Authority startup on any fresh DB.
|
||||||
|
- [ ] Migration is idempotent — re-running against an already-seeded DB is a no-op.
|
||||||
|
- [ ] Migration applies cleanly after `001_initial_schema.sql` + `002_drop_deprecated_audit_tables.sql`.
|
||||||
|
|
||||||
|
### AUTH-SEED-002 — Verify setup-wizard admin bootstrap succeeds without manual intervention
|
||||||
|
Status: TODO
|
||||||
|
Dependency: AUTH-SEED-001
|
||||||
|
Owners: Developer (backend), QA
|
||||||
|
Task description:
|
||||||
|
- On a fresh volume (`docker compose down -v && docker compose up -d`), drive the setup-wizard admin-creation flow end-to-end using the documented credentials (`admin / Admin@Stella2026!`). Capture the happy path: first-run wizard → admin execute step → `POST /connect/token` succeeds.
|
||||||
|
- Regression test: `docker compose stop authority && docker compose rm -f authority && docker compose up -d authority` (recreate against existing volume) — must remain healthy with no tenant FK violations.
|
||||||
|
|
||||||
|
Completion criteria:
|
||||||
|
- [ ] Fresh-volume `docker compose up -d` produces a working admin login with zero manual SQL inserts.
|
||||||
|
- [ ] Authority startup logs show the seed migration applied once; restart shows "up to date".
|
||||||
|
- [ ] Integration or targeted test captures this path (or at minimum a run evidence document in `docs/qa/`).
|
||||||
|
|
||||||
|
### AUTH-SEED-003 — Document the bootstrap contract
|
||||||
|
Status: TODO
|
||||||
|
Dependency: AUTH-SEED-002
|
||||||
|
Owners: Documentation author
|
||||||
|
Task description:
|
||||||
|
- Update Authority's module dossier or operations guide to document that the `default` tenant is a migration-owned seed, not a user-modifiable row; note the relationship between `authority.tenants` and the setup-wizard admin flow.
|
||||||
|
- If the `installation` tenant was previously a migration-owned seed, explain its meaning too.
|
||||||
|
|
||||||
|
Completion criteria:
|
||||||
|
- [ ] Dossier or operations guide describes the seeded tenants and their purpose.
|
||||||
|
- [ ] Cross-link from `docs-archived/implplan/SPRINT_20260422_003` Decisions & Risks so the follow-up lineage is obvious.
|
||||||
|
|
||||||
|
## Execution Log
|
||||||
|
| Date (UTC) | Update | Owner |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 2026-04-22 | Sprint created to unpark the bootstrap gap surfaced independently by two FE QA agents during SPRINT_20260421_006/007 closeouts. The `default` tenant seed disappeared when §2.7 compliance trimmed the init scripts; it needs to come back as a migration-owned seed. | Claude |
|
||||||
|
|
||||||
|
## Decisions & Risks
|
||||||
|
- **Decision**: the seed belongs in the migration path, not the init scripts. This matches the §2.7 contract established in SPRINT_20260422_003 (migrations own schema + canonical seeds; init scripts are pure fallbacks).
|
||||||
|
- **Risk**: if an operator had already customized the `default` tenant row, an idempotent INSERT-on-conflict is safe; but if they've renamed or deleted it, the wizard will still fail on a different constraint. Mitigation: the seed is additive and conservative; it does not reconcile existing operator modifications.
|
||||||
|
- **Risk**: the setup wizard may expect additional bootstrap rows (e.g., default roles, default OIDC client) that are similarly missing after the init-script trim. If AUTH-SEED-002 surfaces more FK violations, extend the seed migration rather than reverting to init-script DDL.
|
||||||
|
|
||||||
|
## Next Checkpoints
|
||||||
|
- AUTH-SEED-001 DONE: fresh-DB `\dt authority.tenants` + `SELECT * FROM authority.tenants` shows the seeded rows.
|
||||||
|
- AUTH-SEED-002 DONE: fresh-volume stack brings up and `admin / Admin@Stella2026!` logs in without manual SQL.
|
||||||
|
- AUTH-SEED-003 DONE: dossier updated, sprint archivable.
|
||||||
Reference in New Issue
Block a user