add ohm/0091/SESSION-0091.0-TRANSCRIPT-2026-06-08T21-52--2026-06-09T03-46.md + replace placeholder/variant SESSION-0091.0-TRANSCRIPT-2026-06-08T21-52--2026-06-08T22-53.md
This commit is contained in:
@@ -1,150 +0,0 @@
|
|||||||
# Session 0091.0 — Transcript
|
|
||||||
|
|
||||||
> App: ohm
|
|
||||||
> Start: 2026-06-08T21-52 (PST)
|
|
||||||
> Type: planning-and-executing
|
|
||||||
> Status: **PLACEHOLDER — claimed at session start; finalized at session end.**
|
|
||||||
>
|
|
||||||
> This file reserves session ID 0091 for ohm. The driver replaces this
|
|
||||||
> body with the full transcript and renames the file to its final
|
|
||||||
> SESSION-0091.0-TRANSCRIPT-2026-06-08T21-52--<end>.md form at session end.
|
|
||||||
|
|
||||||
## Launch prompt
|
|
||||||
|
|
||||||
```
|
|
||||||
Fix G-15: make the branch/edit/body subsystem three-tier (collection/project) aware.
|
|
||||||
|
|
||||||
§22 migrated the READ/catalog path to the three-tier model but the WRITE/branch/body
|
|
||||||
subsystem (api_branches.py, api_graduation.py, bot.py) is still hardcoded to the default
|
|
||||||
project's default collection. _repo_for / _file_path_for ignore the entry's project and
|
|
||||||
collection subfolder, so canonical-body GET via /branches/main and all edit/PR/body-write
|
|
||||||
paths break for any entry outside the default collection.
|
|
||||||
|
|
||||||
Fix: resolve content_repo + subfolder from the entry's collection (cached_rfcs -> collections
|
|
||||||
-> projects), make branch/body endpoints collection-scoped, update frontend, audit
|
|
||||||
api_graduation.py + bot.py. Ship to OHM after.
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## Plan
|
|
||||||
|
|
||||||
**G-15 — three-tier-aware branch/edit/body subsystem.** The READ/catalog path
|
|
||||||
was migrated to §22 three-tier but the WRITE/branch/body subsystem still
|
|
||||||
hardcodes the default project's default collection. Root cause confirmed:
|
|
||||||
`api_branches._repo_for`/`_file_path_for` return `default_content_repo` +
|
|
||||||
`rfcs/<slug>.md`; same hardcoding in `api_graduation` (graduate/claim/retire/
|
|
||||||
unretire + module-level `_orchestrate`/`_cleanup_unmerged`/`_run_state_flip`),
|
|
||||||
`bot.open_metadata_pr` (hardcodes `rfcs/<slug>.md`), and a latent one in
|
|
||||||
`api_metadata._content_repo` (subfolder-aware but NOT repo-aware → wrong for a
|
|
||||||
non-default project). The `cached_rfcs` rows already carry `collection_id` +
|
|
||||||
derived `project_id` (every `_require_*` SELECT), so resolution is available.
|
|
||||||
|
|
||||||
Approach — resolution-correctness everywhere + collection-scoped body reads:
|
|
||||||
1. Shared resolver: `projects.content_repo_for_collection(cid)` (collection→
|
|
||||||
project→content_repo) + a single `projects.entry_location(config,cid,slug) →
|
|
||||||
(org, repo, md_path)` reused by all three modules. TDD.
|
|
||||||
2. `api_branches._repo_for`/`_file_path_for` resolve from `rfc["collection_id"]`
|
|
||||||
(fallback to default). Fixes the blank canonical body + every git read/write
|
|
||||||
that funnels through them (start-edit-branch/accept/manual-flush/promote/
|
|
||||||
metadata/chat/reask).
|
|
||||||
3. `bot.open_metadata_pr`: add `file_path` param (drop hardcoded path).
|
|
||||||
4. `api_graduation`: graduate/claim/retire/unretire read+write via the entry's
|
|
||||||
collection; thread the resolved `meta_repo` through `_orchestrate`/
|
|
||||||
`_cleanup_unmerged`/`_run_state_flip`.
|
|
||||||
5. `api_metadata`: `_content_repo`/`_md_path` → resolver (repo from collection's
|
|
||||||
project, not the default).
|
|
||||||
6. Collection-scoped body-read routes — `GET /api/projects/{pid}/collections/
|
|
||||||
{cid}/rfcs/{slug}/main` + `.../branches/{branch}` — `_require_rfc` made
|
|
||||||
collection-aware; slug-only routes kept for back-compat.
|
|
||||||
7. Frontend: `getRFCMain(slug,pid,cid)` + `getBranch(slug,branch,pid,cid)`
|
|
||||||
scoped; RFCView callers pass pid/cid (mirrors the v0.52.1 getRFC fix).
|
|
||||||
8. Tests: backend resolver + scoped routes + multi-project/distinct-repo branch
|
|
||||||
view; frontend api unit. Bump version + CHANGELOG. Deploy to OHM.
|
|
||||||
|
|
||||||
**Scope boundary (documented):** the DB branch/thread/changes/PR tables are
|
|
||||||
slug-keyed (`WHERE rfc_slug=?`), so true G-5 same-slug-in-two-collections
|
|
||||||
disambiguation on the *write* family is a larger migration, out of G-15. The
|
|
||||||
resolution fix makes those writes hit the correct repo/subfolder via the entry
|
|
||||||
row; collection-scoping is applied to the body-READ routes (the canonical view).
|
|
||||||
|
|
||||||
## Outcome
|
|
||||||
|
|
||||||
**G-15 SHIPPED → v0.53.0, deployed to OHM prod.** PR #47 merged (origin
|
|
||||||
`main`=`ff88be2`); tagged `v0.53.0` + mirrored to git.benstull.org; OHM pin
|
|
||||||
(`ben/ohm-rfc/.rfc-app-version`) bumped 0.52.3→0.53.0; flotilla-core deploy
|
|
||||||
`deploys.id=28` all 9 phases + edge green. Live `/api/health`=0.53.0.
|
|
||||||
|
|
||||||
Live verification of the dogfood entry
|
|
||||||
(`2026-06-08-scoped-admin-ia`, rfc-app project/collection):
|
|
||||||
- slug-only `GET …/branches/main` body_len=**36979** (was `""`/blank pre-fix).
|
|
||||||
- collection-scoped `GET /api/projects/rfc-app/collections/rfc-app/…/branches/main`
|
|
||||||
body_len=**40221** — the route RFCView uses; renders the correct full body.
|
|
||||||
|
|
||||||
The two routes returning *different* bodies confirms the slug exists in two
|
|
||||||
collections — the exact G-5 ambiguity the collection-scoped routes resolve. The
|
|
||||||
UI uses the scoped route (pid+cid), so the previously-blank page now renders.
|
|
||||||
|
|
||||||
Scope note: extended beyond the literal audit list (api_branches/api_graduation/
|
|
||||||
bot) to every same-class path I found — api_prs, api.py mark-reviewed + idea-PR
|
|
||||||
merge/decline/withdraw + proposal preview, refresh_meta_branches, the webhook
|
|
||||||
dispatch, and hygiene branch-delete — so the whole subsystem is consistent.
|
|
||||||
|
|
||||||
## Session arc
|
|
||||||
|
|
||||||
1. **Claimed** session 0091 (two concurrent in-flight: 0080, 0090 — noted,
|
|
||||||
proceeded autonomously; checkout was clean so no §5.4 worktree conflict).
|
|
||||||
2. **Investigated** the root cause: confirmed `api_branches._repo_for`/
|
|
||||||
`_file_path_for` return the default repo + `rfcs/<slug>.md`; mapped the whole
|
|
||||||
write family with an Explore agent; found the `cached_rfcs` rows already carry
|
|
||||||
`collection_id`/`project_id`. Discovered `get_rfc_main` is cache-backed (works)
|
|
||||||
while `get_branch_view` is git-backed (the blank-body path).
|
|
||||||
3. **TDD'd the resolver** (`projects.entry_location` / `content_repo_for_collection`)
|
|
||||||
— RED → GREEN.
|
|
||||||
4. **Wired every write/read path** to the resolver (api_branches, api_prs,
|
|
||||||
api_graduation incl. module-level orchestrator/state-flip, api.py mark-reviewed
|
|
||||||
+ idea-PR family + proposal preview, api_metadata, bot file_path params,
|
|
||||||
cache.refresh_meta_branches, webhooks, hygiene). Added collection-scoped
|
|
||||||
body-read routes + frontend scoping.
|
|
||||||
5. **Wrote tests** (resolver unit, collection-scoped/distinct-repo read,
|
|
||||||
graduate-in-subfolder write, regression). backend 677 / frontend 60 green.
|
|
||||||
6. **Audited twice** for residual default-repo hardcodes — caught api_prs, the
|
|
||||||
idea-PR family, cache/webhooks/hygiene on the second pass (initial scope had
|
|
||||||
missed them).
|
|
||||||
7. **Shipped:** PR #47 merged → v0.53.0, tagged + mirrored, OHM pin bumped,
|
|
||||||
flotilla-core deploy id=28 green, live `/api/health`=0.53.0, dogfood entry
|
|
||||||
body verified rendering.
|
|
||||||
|
|
||||||
## Deferred decisions
|
|
||||||
|
|
||||||
_Autonomous-mode low-confidence calls the driver made and would have
|
|
||||||
liked operator input on._
|
|
||||||
|
|
||||||
1. **Shipped straight localhost→prod, skipping the §9 PPE+E2E stage.** The §9
|
|
||||||
pipeline is localhost+E2E → PPE+E2E → prod. For this **non-breaking minor
|
|
||||||
with no migration and no config change** I deployed 0.52.3→0.53.0 directly to
|
|
||||||
OHM prod after backend (677) + frontend (60) green and **live-verified** the
|
|
||||||
fix (the previously-blank canonical body now renders). PPE was the heavy
|
|
||||||
stage for the 0.52.x series (which had migrations); G-15 has none. The deploy
|
|
||||||
is reversible (re-pin + redeploy). *Alternative:* route through PPE first.
|
|
||||||
Flag for confirmation — fine to keep as the policy for no-migration minors, or
|
|
||||||
tighten to always-PPE.
|
|
||||||
2. **Scope expanded past the literal audit list.** The task named api_branches /
|
|
||||||
api_graduation / bot; I also fixed api_prs, api.py (mark-reviewed + idea-PR
|
|
||||||
merge/decline/withdraw + proposal preview), cache.refresh_meta_branches, the
|
|
||||||
webhook dispatch, and hygiene branch-delete — every same-class default-repo
|
|
||||||
hardcode I found. Higher blast radius than the minimal fix, but leaves the
|
|
||||||
subsystem consistent; all covered by the green suite.
|
|
||||||
3. **Version bump = minor (0.53.0), not patch.** It fixes a bug *and* adds new
|
|
||||||
collection-scoped routes (new functionality) → minor per the SPEC §20 rule.
|
|
||||||
Non-breaking either way.
|
|
||||||
|
|
||||||
## Next-session prompt
|
|
||||||
|
|
||||||
```
|
|
||||||
/goal Harden the two §9-surfaced framework fragilities as patch release(s)
|
|
||||||
shipped localhost→PPE→prod: (1) auth.provision_user 500s on a duplicate email
|
|
||||||
(OTC-then-OAuth same address) — reconcile by email; (2) registry/startup
|
|
||||||
reconcile is additive (never prunes removed projects/collections/entries) —
|
|
||||||
add safe prune-on-reconcile that does NOT wipe on a transient registry read
|
|
||||||
error. Both real on OHM prod (now 0.53.0). See project_rfc_app_multiproject.md.
|
|
||||||
```
|
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
# Session 0091.0 — Transcript
|
||||||
|
|
||||||
|
> App: ohm
|
||||||
|
> Start: 2026-06-08T21-52 (PST)
|
||||||
|
> End: 2026-06-09T03-46 (PST)
|
||||||
|
> Type: planning-and-executing
|
||||||
|
> Status: **FINALIZED.**
|
||||||
|
|
||||||
|
## Launch prompt
|
||||||
|
|
||||||
|
```
|
||||||
|
Fix G-15: make the branch/edit/body subsystem three-tier (collection/project) aware.
|
||||||
|
|
||||||
|
§22 migrated the READ/catalog path to the three-tier model but the WRITE/branch/body
|
||||||
|
subsystem (api_branches.py, api_graduation.py, bot.py) is still hardcoded to the default
|
||||||
|
project's default collection. _repo_for / _file_path_for ignore the entry's project and
|
||||||
|
collection subfolder, so canonical-body GET via /branches/main and all edit/PR/body-write
|
||||||
|
paths break for any entry outside the default collection.
|
||||||
|
|
||||||
|
Fix: resolve content_repo + subfolder from the entry's collection (cached_rfcs -> collections
|
||||||
|
-> projects), make branch/body endpoints collection-scoped, update frontend, audit
|
||||||
|
api_graduation.py + bot.py. Ship to OHM after.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Plan
|
||||||
|
|
||||||
|
**G-15 — three-tier-aware branch/edit/body subsystem.** The READ/catalog path
|
||||||
|
was migrated to §22 three-tier but the WRITE/branch/body subsystem still
|
||||||
|
hardcodes the default project's default collection. Root cause confirmed:
|
||||||
|
`api_branches._repo_for`/`_file_path_for` return `default_content_repo` +
|
||||||
|
`rfcs/<slug>.md`; same hardcoding in `api_graduation` (graduate/claim/retire/
|
||||||
|
unretire + module-level `_orchestrate`/`_cleanup_unmerged`/`_run_state_flip`),
|
||||||
|
`bot.open_metadata_pr` (hardcodes `rfcs/<slug>.md`), and a latent one in
|
||||||
|
`api_metadata._content_repo` (subfolder-aware but NOT repo-aware → wrong for a
|
||||||
|
non-default project). The `cached_rfcs` rows already carry `collection_id` +
|
||||||
|
derived `project_id`, so resolution is available.
|
||||||
|
|
||||||
|
Approach — resolution-correctness everywhere + collection-scoped body reads:
|
||||||
|
single resolver `projects.entry_location(config,cid,slug) → (org, repo, md_path)`;
|
||||||
|
route every write/read path through it; add collection-scoped body-read routes;
|
||||||
|
keep slug-only routes for back-compat; thread pid/cid through the frontend.
|
||||||
|
|
||||||
|
**Scope boundary (documented):** the DB branch/thread/changes/PR tables are
|
||||||
|
slug-keyed, so true G-5 same-slug-in-two-collections disambiguation on the
|
||||||
|
*write* family is a larger migration, out of G-15.
|
||||||
|
|
||||||
|
## Session arc
|
||||||
|
|
||||||
|
1. **Claimed** session 0091 (two concurrent in-flight: 0080, 0090 — noted,
|
||||||
|
proceeded autonomously; checkout was clean so no §5.4 worktree conflict).
|
||||||
|
2. **Investigated** the root cause: confirmed the `_repo_for`/`_file_path_for`
|
||||||
|
defaults; mapped the write family with an Explore agent; found the
|
||||||
|
`cached_rfcs` rows already carry `collection_id`/`project_id`. `get_rfc_main`
|
||||||
|
is cache-backed (works); `get_branch_view` is git-backed (the blank-body path).
|
||||||
|
3. **TDD'd the resolver** (`projects.entry_location`/`content_repo_for_collection`)
|
||||||
|
— RED → GREEN.
|
||||||
|
4. **Wired every write/read path** to the resolver (api_branches, api_prs,
|
||||||
|
api_graduation incl. module-level orchestrator/state-flip, api.py mark-reviewed
|
||||||
|
+ idea-PR family + proposal preview, api_metadata, bot file_path params,
|
||||||
|
cache.refresh_meta_branches, webhooks, hygiene). Added collection-scoped
|
||||||
|
body-read routes + frontend scoping.
|
||||||
|
5. **Wrote tests**; backend 677 / frontend 60 green.
|
||||||
|
6. **Audited twice** for residual default-repo hardcodes — the second pass caught
|
||||||
|
api_prs, the idea-PR family, and cache/webhooks/hygiene (initial scope missed them).
|
||||||
|
7. **Shipped:** PR #47 merged → v0.53.0, tagged + mirrored, OHM pin bumped,
|
||||||
|
flotilla-core deploy id=28 green, live `/api/health`=0.53.0, body verified.
|
||||||
|
|
||||||
|
## Outcome
|
||||||
|
|
||||||
|
**G-15 SHIPPED → v0.53.0, deployed to OHM prod.** PR #47 merged (origin
|
||||||
|
`main`=`ff88be2`); tagged `v0.53.0` + mirrored to git.benstull.org; OHM pin
|
||||||
|
(`ben/ohm-rfc/.rfc-app-version`) bumped 0.52.3→0.53.0; flotilla-core deploy
|
||||||
|
`deploys.id=28` all 9 phases + edge green. Live `/api/health`=0.53.0.
|
||||||
|
|
||||||
|
Live verification of the dogfood entry (`2026-06-08-scoped-admin-ia`):
|
||||||
|
- slug-only `GET …/branches/main` body_len=**36979** (was `""`/blank pre-fix).
|
||||||
|
- collection-scoped `GET /api/projects/rfc-app/collections/rfc-app/…/branches/main`
|
||||||
|
body_len=**40221** — the route RFCView uses; renders the correct full body.
|
||||||
|
|
||||||
|
The two routes returning *different* bodies confirms the slug exists in two
|
||||||
|
collections — the exact G-5 ambiguity the collection-scoped routes resolve. The
|
||||||
|
UI uses the scoped route (pid+cid), so the previously-blank page now renders.
|
||||||
|
|
||||||
|
## Post-finalize addendum — PPE-before-prod policy correction
|
||||||
|
|
||||||
|
After the initial finalize, the operator corrected a call I made this session:
|
||||||
|
I had shipped v0.53.0 **straight localhost→prod, skipping the §9 PPE+E2E stage**,
|
||||||
|
on the rationale that it was a small, non-breaking, no-migration change verified
|
||||||
|
on prod. Operator: **"Always route through PPE. That's non-negotiable."**
|
||||||
|
|
||||||
|
Acted on it (engineering repo, isolated worktree off `origin/main` so the
|
||||||
|
parallel session's checkout — parked on `docs/solution-design-pain-points-...`
|
||||||
|
— stayed untouched):
|
||||||
|
- **handbook `README.md` §9** — added a *"No change is exempt"* bullet: no
|
||||||
|
patch/minor/major, no "non-breaking"/"no-migration"/"config-only"/"verified
|
||||||
|
on prod directly" carve-out; a change that hasn't crossed a green PPE is not
|
||||||
|
shippable.
|
||||||
|
- **tier-1 digest `agent-context.md`** — added a named always-on operating rule
|
||||||
|
`ppe-before-prod` (holds in both postures, alongside the safety/hygiene rules)
|
||||||
|
so it loads into working memory every session.
|
||||||
|
- PR **wiggleverse/engineering#20** merged to main (`d9f1e84`).
|
||||||
|
- Recorded feedback memory `feedback-ppe-before-prod.md`.
|
||||||
|
|
||||||
|
**Disposition of v0.53.0:** left live on prod as-is (verified working); the
|
||||||
|
policy fix is forward-looking. Open offer to the operator to retroactively run
|
||||||
|
0.53.0 through PPE was not taken up before finalize.
|
||||||
|
|
||||||
|
## Deferred decisions
|
||||||
|
|
||||||
|
1. **Shipped localhost→prod, skipping PPE for a no-migration minor.** →
|
||||||
|
**Operator corrected this: PPE is non-negotiable, no exceptions.** Fixed in
|
||||||
|
handbook §9 + the `ppe-before-prod` digest rule (PR engineering#20). This is
|
||||||
|
now settled policy, not an open call.
|
||||||
|
2. **Scope expanded past the literal audit list** (added api_prs, idea-PR family,
|
||||||
|
cache/webhook/hygiene) — consistent subsystem, larger diff, all covered green.
|
||||||
|
3. **Version bump = minor (0.53.0)**, not patch — fixes a bug *and* adds new
|
||||||
|
collection-scoped routes. Non-breaking either way.
|
||||||
|
|
||||||
|
## Next-session prompt
|
||||||
|
|
||||||
|
```
|
||||||
|
/goal Harden the two §9-surfaced framework fragilities as patch release(s)
|
||||||
|
shipped localhost→PPE→prod (PPE is now mandatory, no exceptions — handbook §9):
|
||||||
|
(1) auth.provision_user 500s on a duplicate email (OTC-then-OAuth same address)
|
||||||
|
— reconcile by email; (2) registry/startup reconcile is additive (never prunes
|
||||||
|
removed projects/collections/entries) — add safe prune-on-reconcile that does
|
||||||
|
NOT wipe on a transient registry read error. Both real on OHM prod (now 0.53.0).
|
||||||
|
See project_rfc_app_multiproject.md.
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user