# Journaling — Runtime Execution Doc for Dave J (Phase 0b, [[T-732]])

**Full plan:** [`build-plan.md`](build-plan.md) · **Specs:** [shared](spec.md) + [Fitness](../../fitness/fitness-journal/spec.md) + [Relationship](../../relationships/relationship-journal/spec.md) · **Test plans:** [shared](test-plan.md) + 2 deltas

## What this is

Journaling — the "Repeat" half of every page (interview → spec → plan → **journal**). It's V.1 item #4 and now the **sole built-in companion feature in V.1** (the to-do list moved to V.1.1, [[braindrive-repo]] D272). This first build proves the shared pattern on **Fitness** and **Relationships**.

It's spec'd, test-planned, build-planned, and now **live-tested on the offline harness** (16/16 Wave-1 scenarios on GLM-5.2, plus the D285 capture-and-tell verification; recovery/edge coverage in flight). This doc is the Phase 0b work order. If anything below doesn't match how the runtime actually works, that correction is the most valuable thing you can send back.

## The core call: text-first, no code

The journal is **a Markdown file the existing file-ops memory tools manage, driven by authored starter-pack instructions** — **no new product runtime code, UI, or schema** for journaling itself (aside from adding two files to the template contract — your call, [[T-732]]). The offline test-harness work ([[T-731]]) is ours.

**It's flat, like Your Goals / Your Plan (D276).** `journal.md` is a flat page artifact ("Your Journal"), sibling to `spec.md`/`plan.md`; `run-journal.md` is its sibling procedure (like `run-interview.md`/`run-planning.md`) with the preservation + recovery rules at the top. **No nested `journal/` folder, no separate journal `AGENT.md`** — that was the retired child-app app-folder pattern. Each page template gains:

```
projects/templates/<page>/   (all flat siblings)
  run-journal.md      (NEW — the follow-up session; preservation + recovery rules at the TOP)
  journal.md          (NEW — flat "Your Journal" default header; seeded at page setup)
  run-planning.md     (+ the plan→journal handoff appended at the end)
  AGENT.md            (+ minimal journal wiring; reconcile the "don't require daily journaling" line)

runtime owner instance:
  documents/<page>/
    spec.md  plan.md  journal.md   ← flat: Your Goals / Your Plan / Your Journal
    run-interview.md  run-planning.md  run-journal.md   AGENT.md
    (no nested journal/ folder, no separate journal AGENT.md)
```

The append-only / targeted-edit / recovery behavior is **instruction-enforced and gate-verified**, using the file-ops tools (read/write/edit/delete/list/search) you already have. **No new product runtime code, no UI, no schema** for journaling itself (the offline harness work is ours; adding the two template files is your T-732 call). If that's wrong — if any of this genuinely needs runtime/code support — that's the most important thing to flag.

## Phases (full detail in the build plan)

| Phase | What | Verifies |
|---|---|---|
| **0a** | Offline harness journal mode — **[[T-731]]** (ours) | makes the rest testable |
| **0b** | Runtime enablement — **[[T-732]]** (you) | makes the rest buildable |
| **1** | Shared pattern, proven on Fitness | shared gates G-1…G-8 + Fitness gates |
| **2** | Relationship instantiation + deltas | + Relationship gates (privacy, professional-care, no CRM) |
| **3** | Lock the shared source + full regression + ship to live pack | baseline + all release gates |

## The hard part: don't regress the interview

The real difficulty isn't building journaling as Markdown — it's editing the *same* starter-pack files that already produce a good interview → spec → plan, without degrading them. Good news: the risk collapses to **two loaded files — the page `AGENT.md` and `base/AGENT.md`** (the only journal edits loaded *during* the first conversation; `run-journal.md` is follow-up-only, and the PJ-1 handoff fires *after* the plan exists). So the approach:

- Use the **staged wiring snippets verbatim** (`pack-source/snippets/agent-md-journal-wiring.md` + `base-agent-md-wiring.md`) — minimal, post-plan-framed, with the actual procedure in `run-journal.md`. Don't re-author the wording; it's already tuned against G-7.
- **Lock a pre-journal interview baseline** (Katie A/B/C) before any **live-template** edit — especially the page `AGENT.md`. (The pack-source instruction files in this Library have already iterated; the live template is still the pre-journal state B-0 measures.)
- Re-run the alignment smoke after **every** `AGENT.md` change, not just at the end.
- **Two gates block release:** **G-7** if interview quality, spec/plan convergence, or the no-forced-tracker behavior regresses; **G-8 (expert presence, PJ-19)** if follow-up sessions read as a clerk instead of an expert coach — judge-scored like G-6 (confirmed blocking 2026-07-02). Both are on our harness, but they define what "done" means for this build.

## Work order (Phase 0b — [[T-732]])

> **Framing (D277):** journaling is a core fixture handled **exactly like Your Goals and Your Plan** — per-page `run-journal.md` + `journal.md`, same shape as `run-interview.md`/`run-planning.md`. There are essentially **no existing owners** this rollout (team-only dogfood), so there's **no resolver / injection / migration** to build — it just ships in the base pack. That collapses this to plumbing. Reuse mechanism is RESOLVED (D277, DJ-confirmed 2026-07-02): per-page from one canonical source (`pack-source/`); no include mechanism.

### Do now (interface is frozen — none of this depends on final instruction text)

Build against the current staged `pack-source/` files; the instruction text may still get tuned, and the final contents re-copy at freeze — nothing below changes because of it.

- [ ] **Contract + enumeration:** add `journal.md` + `run-journal.md` **everywhere the existing five template files are enumerated** — `layout.contract.json` `default_project_template_files` (+ the finance/fitness/life-area lists), `memory/init.ts:50`, `memory/update-prompting.ts:164`, and the tests. **Confirm needed:** instruction content is only staged for the two proof pages — do the non-proof lists (finance etc.) get generic substituted copies at freeze, or does the contract change scope to fitness/relationships until their content lands? Your call on what the contract tooling tolerates.
- [ ] **Seeding:** seed `journal.md` flat at page setup so "Your Journal" sits beside Your Goals/Your Plan from the start (seed source: `projects/templates/<page>/journal.md`). **Confirm needed:** the seed point — or the earliest one, if a page folder doesn't materialize until the interview writes spec/plan.
- [ ] **Date injection (M-12) — in the repo since 2026-05-27** (`cd16ca2`, `readBootstrapPrompt`; unit-tested), but no longer confirmed done. **Verify it's live in the DEPLOYED container (reopened by DW's live test 2026-07-03):** on DW's dev instance (Docker, localhost:5073) the model dated a journal entry `2026-06-30` on July 3 — it extrapolated from journal history instead of using an injected date, which is exactly what a missing injection looks like (the offline harness injects the date explicitly and its P-8 gate has been consistently green, so the pack rule holds when a date exists). Check: does the running container's bootstrap actually carry `Today's date is …`? If yes, this is instead a live P-8 adherence miss to watch.
- [ ] **Memory classification:** teach `memory/brain-drive-layout.ts:36` that `run-journal.md` = managed procedure, `journal.md` = owner state. Concretely: add `"run-journal.md"` to `PROCEDURE_NAMES` (it currently lists create/compare/run-interview/run-planning/generate-report).
- [ ] **Sidebar (verified live 2026-07-03 — DW's dev-instance test):** with the journal files present, the page sidebar shows **two "Journal" items under a "YOUR FILES" section** instead of **Your Journal** under the PLAN group. Two fixes in `client_web/src/components/layout/`: `sidebar-labels.ts` `sidebarFileLabel` needs a `relativePath === "journal.md" → "Your Journal"` case (spec/plan already have theirs), and `Sidebar.tsx`'s grouping needs `journal.md` in the PLAN group (with `run-journal.md` hidden via the classification fix above, the "YOUR FILES" section disappears).
- [ ] **Lint:** add `journal.md`/`run-journal.md` to `tools/architecture-lint/draft3-memory-lint.ts` (it already carries the `## Preservation Rule` heading the lint expects). Same visit as the M-ID adoption ([[T-712]]/[[T-743]]) — have checks report which contract invariant they enforce. Scope note from memory-arch v4.3 (your review, finding 3): the heading is required only on **state-touching** instructions — don't have the lint demand it on read-only/output-only ones. Also: the entry format has a **floor** — the minimum valid entry is a dated heading + `Entry` text — so don't validate entries against the full field scaffold.
- [ ] **Overlay:** `run-journal-user.md` optional peer overlay, for symmetry with the other two procedures.
- [ ] **Sidebar label:** the item reads **"Your Journal,"** not `journal.md`.
- [ ] **Runtime assumption to confirm (PJ-13 / test-plan H-6):** one approved turn can write both the parent `spec.md`/`plan.md` update **and** the matching `journal.md` change entry — two file writes, one approval. The harness exercises this with real tools; flag it if the live runtime can't do it.
- [ ] **(Recommended, not blocking) a `memory_append` primitive:** the journal is a log (M-8), and appending via find/replace editing is the single highest-risk file operation the models perform — the suite's worst corruption modes all started as append attempts. The pack now works around it with an `<!-- APPEND MARKER: -->` sentinel line in `journal.md` (ships in `journal-md-default.md`; the model replaces the marker with entry+marker). A real append tool would delete the workaround. Your call on timing.
- [ ] **Runtime resilience on partial/empty model turns (new, from DW's live dogfood 2026-07-03):** GLM providers intermittently return truncated or empty content mid-tool-loop (the offline harness measured it at up to 50–70% of runs on a bad provider before mitigation). Live symptom on DW's dev instance: three glued-together false starts, then a mid-sentence cutoff the owner had to nudge past ("looks like you got cut off"). The harness now retries empty turns and blacklists the offending provider per-conversation; the runtime has no equivalent — and the Anthropic-direct fallback doesn't trigger because a 200-with-truncated-content isn't an error. Risk beyond UX: an interrupted tool loop followed by a confident "I logged it" is the fabricated-success path. Recommend: detect empty/no-tool-call completions and retry (with provider exclusion if the router supports it).
- [ ] **Memory-edit must reject ambiguous targets (new, from the 2026-07-02 full-suite runs — G-1-load-bearing):** if the runtime's file-edit tool does silent first-match replacement, an edit anchored on a recurring line (`- Status: captured` appears in *every* journal entry) splices new content into the middle of an OLD entry — this was the dominant owner-data-corruption mode in the matrix (GLM anchors on recurring lines under load). Required behavior: when the find text matches more than once, **return an error naming the count** ("appears N times; add surrounding context") instead of editing — the model then retries with a unique anchor. Our harness sandbox now implements exactly this; please confirm what the live tool does and align it.

### At pack freeze (ours — we make the pack edits and submit the PR)

Per the division of labor (pack/prompting = us, runtime/interface = you — [[T-734]]):

- [x] **DONE 2026-07-03 — [PR #210](https://github.com/BrainDriveAI/BrainDrive/pull/210)** (branch `starter-pack/journaling`, based on dev, pack-source frozen at Library `273b48942`; supersedes the pre-D276 stub from `07fc7d6`). We copied the final file contents into the live template and submitted the starter-pack PR to dev: per page (fitness, relationships): `run-journal.md` (substituted + delta spliced) and `journal.md` seed; append the PJ-1 handoff to `run-planning.md`; insert the AGENT.md wiring section + routing pointer; apply the `base/AGENT.md` wiring — two Project Structure lines **+ the Communication closeout line** (`pack-source/snippets/base-agent-md-wiring.md`). The harness's `build_wired_pack.py` scripts exactly this.
- [ ] **Your part: review the pack PR + any interface/runtime work it surfaces** — then the agreed path: discuss on the Fri call, release.
- [ ] **Dogfood re-provisioning (yours, operational):** existing instances won't auto-gain journaling (init seeding is gated by `preferences/projects-seeded-v1.json`; the update flow preserves existing files) — wipe/re-provision the dogfood instances or apply a manual patch. Operational, not architecture.

**Heads up — the test-harness side is on us, not you.** Teaching the harness to run + score a journaling follow-up session, and to catch any interview → spec → plan regression, is our offline-lane work ([[T-731]]) — you don't need to build journal scenarios. It overlaps your [[T-603]] (existing-owner state) and [[T-602]] (spec-anchored scoring), so we'll fold where they meet. If you want journaling also validated on your canonical/live harness as a final gate, say so and we'll coordinate.

## Two things I already worked through (so you don't have to re-litigate)

- **"Don't require daily journaling" stays.** The live pack tells the model not to force journaling/logging — that's *correct* and stays. The journal is owner-driven follow-up, available but never mandatory. The build reconciles the wording, doesn't contradict it.
- **Your Agent routing is deferred.** Journaling from the Your-Agent front door (spec Success #9) waits for the general-journal router build — out of scope here. In-scope journaling is direct, on the Fitness/Relationship pages.

---

*Everything in "Do now" is executable today; the open confirms are the `journal.md` seed point and the non-proof-page contract scope. Send back any "the runtime doesn't work that way" corrections and we'll fold them into the build plan. The pack-freeze PR (frozen commit hash + final file set) follows from us when the full harness suite is green.*
