update ohm/0074/SESSION-0074.0-TRANSCRIPT-2026-06-05T07-35--INPROGRESS.md

This commit is contained in:
2026-06-05 08:36:20 -07:00
parent 470686cd36
commit 9f8fc1796f
@@ -2,19 +2,129 @@
> App: ohm > App: ohm
> Start: 2026-06-05T07-35 (PST) > Start: 2026-06-05T07-35 (PST)
> End: 2026-06-05T08-35 (PST)
> Type: coding > Type: coding
> Status: **PLACEHOLDER — claimed at session start; finalized at session end.** > Status: **FINALIZED.**
> > Branch: `feat/s1-collection-grain` → PR #19 (merged to `main`). Released **v0.40.0**.
> This file reserves session ID 0074 for ohm. The driver replaces this
> body with the full transcript and renames the file to its final
> SESSION-0074.0-TRANSCRIPT-2026-06-05T07-35--<end>.md form at session end.
## Launch prompt ## Launch prompt
_(launch prompt not captured at claim time)_ > `/goal` Write + execute the S1 plan for the §22 three-tier refactor: migration 029
> (add `collections` table, move per-corpus fields down from `projects`, one default
> collection per project, re-key entry-scoped tables (project_id,slug)→(collection_id,
> slug) via the 028 rebuild pattern, project_members→memberships) + thread collection_id
> through app/auth.py·projects.py·cache.py·api_* + 308 /p/<project>/e/<slug>→
> /p/<project>/c/<default>/e/<slug>. Acceptance: @S1 scenarios green; N=1 unchanged.
> Read docs/design/2026-06-05-three-tier-projects-collections.md (Part E / §A.6) first.
> Review/merge PR #18 first if approved.
## Plan
Coding session executing slice **S1** of the §22 three-tier refactor (design doc
spec'd in session 0072). Write a written implementation plan, then execute it via
TDD against the full backend suite as the "N=1 unchanged" regression net. Gate:
review/merge the spec PR #18 first.
## Pre-state
- Clean, pushed `main` @ **v0.39.0** (two-tier deployment→project model shipped).
- The three-tier design doc was on branch `spec/three-tier-projects-collections`,
open as **PR #18 (unmerged)** on `git.wiggleverse.org/ben.stull/rfc-app`.
- Memory flagged PR #18 as open and "NEXT = write+execute the S1 plan."
## The arc (turn-by-turn)
1. **Session gate / init.** Classified as a **coding** session; claimed ID **0074**
(`--type coding`), no concurrent sessions, clean `main` baseline.
2. **PR #18 triage.** The memory's "PR #18" wasn't on the `benstull` remote
(`git.benstull.org`) — found it on the canonical `origin`
(`git.wiggleverse.org/ben.stull/rfc-app`, PR #18 open + mergeable). Reviewed the
637-line design doc in full: internally consistent, stale-memory premise corrected
(two-tier shipped @ v0.39.0), migration-029 strategy decided, slices `@S1`-tagged.
**Verdict: approved** → merged PR #18 to `main` (the design doc is now on main; the
SPEC.md merge itself rides S6).
3. **Codebase exploration.** Read migration 028 (the rebuild pattern to replicate),
026/027 (current `projects`/`project_members` schema; `type`/`initial_state` live on
`projects`), `projects.py`/`auth.py`/`cache.py`/`api_deployment.py`/`App.jsx`. Three
parallel Explore agents mapped the `project_id` blast radius, the routing/308
surface, and the test/migration tooling (key finding: **no Gherkin runner**`@S1`
is realised as pytest verticals; the full suite is the N=1 net).
4. **Decision: default collection id = literal `'default'`.** Established that a stable
literal (not the project id) keeps the collection id identical across fresh-vs-
upgraded deploy histories, matches the spec's `/c/default/` URLs, and lets the
existing `restamp` keep renaming only the *project* grain. The re-key maps each
entry to its project's default collection via a JOIN (robust to project_id values).
5. **Wrote the S1 plan** (`docs/superpowers/plans/2026-06-05-s1-three-tier-collection-grain.md`)
via the writing-plans skill — phased: migration 029 → backend threading → API surface
→ redirects → `@S1` acceptance → release.
6. **Executed (TDD, branch `feat/s1-collection-grain`).**
- **Migration 029** (`029_collections.sql`): `collections` table; `type`/
`initial_state` moved down off `projects`; one default collection per project
(`id='default'`, repo root); the 13 entry-corpus tables re-keyed
`(project_id,slug)``(collection_id,slug)` via the 028 rebuild pattern;
`project_members``memberships(scope_type∈{project,collection},…)`, role enum
collapsed to `{owner,contributor}`. Shape test green first.
- **Threading.** Renaming the column broke the whole suite (the intended TDD signal).
Fixed module-by-module against the regression net: `collections.py` helpers; the
registry mirror (writes project group-fields + collection corpus-fields, type
immutability on the collection); `auth.project_of_rfc` (collections join);
`auth.project_member_role` (reads memberships, maps back to legacy role strings);
`cache`/`api.py`/`api_prs`/`api_branches`/`api_notifications`/`api_contributions`/
`api_invitations`/`api_graduation`/`api_discussion`/`funder` (13-table reads/writes
`collection_id`; `cached_prs` + denormalised `project_id` tags left unchanged);
`projects.py` restamp + initial_state; `api_deployment` reads type/initial_state
from the default collection. A missed `project_of_rfc` edit (500 on every entry
read) was the single biggest fix — caught by the suite.
- **Redirects.** Backend `/rfc/`+`/proposals/` 308s now target `/c/default/`. Frontend:
`/c/:collectionId/` route layer; `DefaultCollectionRedirect` (C3.7); `LegacyCorpusRedirect`
(v0.35.0 `/p/<p>/e/<slug>` bookmarks → `/c/default/`, query preserved); path builders
carry the segment (serving stays project-scoped — collection=default; S2 owns
collection-aware serving).
- **Tests.** Added `test_migration_029_collections.py`, `test_s1_collection_grain_vertical.py`
(`@S1`), `entryPaths.test.js`. Updated the fixtures/assertions that seeded the dropped
columns (`test_api_deployment`, `test_registry`, `test_registry_wiring`, `test_migration_027`,
`test_initial_state_landing`, `test_restamp_default_project`, the multi-project + project-scoped
verticals). **Retired `test_migration_028`** (its keying is superseded by 029; invariants now
covered at the collection grain).
7. **Verification + release.** Backend **458 passed**, frontend **18 passed**, build green
(the N=1-unchanged gate + `@S1`). Bumped **VERSION/package.json → 0.40.0** (parity checked),
wrote the CHANGELOG entry with a breaking-URL upgrade-steps block. Pushed; opened **PR #19**;
self-reviewed (fully tested) and merged to `main`; deleted the branch.
## Cut state
- `main` @ **v0.40.0**, clean and pushed. Migration `029_collections.sql` on `main`.
- Slice **S1 shipped**: the collection grain exists as the invisible default; N=1 deployments
run unchanged with one extra `/c/<collection>/` path segment.
- Full backend suite 458 green; frontend 18 green + build green.
## Operator plate (what shipped)
- The three-tier model (deployment → project → RFC collection) now has its collection grain
in code. A deployment upgrading 0.39.0 → 0.40.0 runs migration 029 automatically (no config
change); existing entries re-key into the default collection with no data loss; old
`/p/<project>/e/<slug>`, `/rfc/<slug>`, `/proposals/<n>` links keep working.
## Deferred decisions ## Deferred decisions
_Autonomous-mode low-confidence calls the driver made and would have - **Default collection id = literal `'default'`** (not the project id): chosen for
liked operator input on. Appended as the session runs; surfaced at cross-deploy-history stability + spec-URL fidelity; the multi-project-at-migration case
finalize. Empty if none._ uses a `CASE` fallback to the project id to avoid a PK collision (non-standard pre-S5).
Worth a glance from the spec author, but it honors the spec's structural invariants.
- **`test_migration_028` retired** rather than rewritten — its `(project_id,slug)` keying is
overwritten by 029, so the test asserted a state the runner can no longer reach; the
collection-grain invariants live in `test_migration_029`.
- Denormalised `project_id` tags (`cached_prs`/`threads`/`changes`/`notifications`/`actions`/
`pr_resolution_branches`) intentionally left as `project_id` (project grain) for S1.
## Next-session prompt
```
/goal Execute slice S2 of the §22 three-tier refactor (create & navigate a second
collection): teach the registry mirror to read `.collection.yaml` manifests; add the
bot-commit-wrapped create-collection endpoint (authorized by existing deployment
owner/admin for now); the project collection-directory at /p/<project>/; and
collection-scoped propose/serve under /p/<project>/c/<collection>/. Acceptance: @S2
scenario (C3.6, anonymous reader of an empty collection catalog) green; N=1 unchanged.
Read docs/design/2026-06-05-three-tier-projects-collections.md (Part E "S2") first.
```