89 lines
5.1 KiB
Markdown
89 lines
5.1 KiB
Markdown
# M0 — Implementation Log
|
||
|
||
Running record of decisions, deviations, and out-of-scope follow-ups discovered
|
||
during M0 execution. Plan: `docs/m0/plan.md` (18 steps). History → git; this file
|
||
captures only what the commit messages cannot.
|
||
|
||
## Session 4 — Steps 14–18 (2026-06-18)
|
||
|
||
### Step 14 GATE outcome — the D3 convention works; edit count is ~1:1, not reduced
|
||
|
||
Prototyped `references/data-path-convention.md` on the voice-readers family:
|
||
**38 refs across 19 files repointed** — exactly the plan's prediction. The measured
|
||
answer to brief D3's open question (*can a convention reduce edits, or do commands
|
||
need literal paths for Claude to act on?*): command/agent prose that tells Claude to
|
||
**read** a file needs a resolvable path **on the line**. A "the data dir's
|
||
`voice-samples/` (see convention doc)" reference adds a lookup hop and is not directly
|
||
actionable. The inline `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/…`
|
||
token is both self-resolving **and** points at the doc. So the convention does **not**
|
||
cut edit count below ~1 per ref — it makes every edit a **uniform mechanical token
|
||
swap** (vs bespoke per-line decisions), with the doc as single source of truth.
|
||
**GATE = proceed** (convention confirmed working); Step 15 applies the same uniform
|
||
token to the remaining families. This is D3 realized as one token — NOT a re-decision
|
||
to literal-edit (alt. a). Applied via an ordered swap (prefixed `${CLAUDE_PLUGIN_ROOT}/
|
||
assets/voice-samples/` form before bare `assets/voice-samples/`, so the bare pass can't
|
||
corrupt the prefixed one).
|
||
|
||
### Designed inter-step red lint (Step 14 → Step 16)
|
||
|
||
After Step 14 the structure lint is **Failed: 1** — `references/*.md: 26 (expected 25)`,
|
||
the new convention doc as the 26th ref file. `EXPECT_REFS` bumps to 26 in **Step 16**
|
||
(plan Session-4 scope forbids touching tests). This session lands 14→18 in one go, so
|
||
the lint is restored to green at Step 16 — no red is left at session end. The only
|
||
surviving bare `assets/voice-samples/` is inside the convention doc itself (it documents
|
||
the in-plugin placeholder-scaffold location for the fallback rule) — Step 16's
|
||
no-bare-path assertion must exempt `references/data-path-convention.md`.
|
||
|
||
## Session 3 — Steps 11–13 (2026-06-18)
|
||
|
||
### Environment reality vs. plan assumptions
|
||
|
||
The plan was authored assuming the operator's **real `.local.md` runtime data**
|
||
sat in the plugin tree (227-line voice profile, analytics exports, draft queue).
|
||
On this machine that data is **absent** — it is a clean clone:
|
||
|
||
- `assets/voice-samples/`: only the PII-free placeholder `authentic-voice-samples.md`
|
||
(+ `.template.md`). No `.local.md` source.
|
||
- `assets/drafts/`: only `.gitkeep`. `assets/analytics/`: only `README.md` + empty `ab-tests/`.
|
||
- The 4 tracked D2 scaffold instances DO exist (`high-engagement-posts.md`,
|
||
`demographics.md`, `engagement-patterns.md`, `my-post-templates.md`).
|
||
|
||
**Consequence for Step 12 (live migration):** every `MOVE_FILES` / `MOVE_DIRS`
|
||
entry resolved to an absent source → clean no-op. Only the 4 `COPY_FILES`
|
||
scaffolds were relocated. Result: `migrated — moved 0, copied 4, skipped 0`;
|
||
`.migrated` marker written; idempotent re-run confirmed `already-migrated`.
|
||
|
||
**Step 12 verify adapted:** the plan's literal check
|
||
(`test -f .../voice-samples/authentic-voice-samples.md`) cannot pass without a
|
||
`.local.md` source to move, so it was replaced with the achievable post-condition:
|
||
`.migrated` marker present + 4 scaffolds external + `migrateData` wired into
|
||
`session-start.mjs` + idempotency. The voice MOVE correctly no-op'd. (Operator
|
||
pre-approved this adaptation before the run.)
|
||
|
||
### OUT OF M0 SCOPE — git-history scrub of the leaked post (FOLLOW-UP)
|
||
|
||
`assets/examples/high-engagement-posts.md` held the operator's **real** LinkedIn
|
||
post at HEAD (the "Ralph Wiggum / vibe-coding" post — real names, real engagement
|
||
metrics, real personal narrative). Step 13 scrubbed the **working-tree** content
|
||
to a generic placeholder (0 `## Post N` sections → personalization score 0, no
|
||
PII). **This does not remove the post from git history.** A history rewrite
|
||
(`git filter-repo` / BFG) on `assets/examples/high-engagement-posts.md` is a
|
||
separate, explicit operation — **deferred, not done here** (brief §13: out of M0
|
||
scope). Track until the repo is published.
|
||
|
||
### Note — external instance retains pre-scrub content (by design)
|
||
|
||
The Step-12 migration copied `high-engagement-posts.md` to
|
||
`~/.claude/linkedin-studio/examples/high-engagement-posts.md` **before** Step 13
|
||
scrubbed the in-plugin file (B3 ordering). The external copy therefore still holds
|
||
the migrated content. That is the operator's private data dir (outside any repo) —
|
||
the operator may curate it; not an M0 concern.
|
||
|
||
### D2 scaffolds completed
|
||
|
||
All 6 scaffolds now have a read-only `*-template.*` seed: `case-study-template.md`
|
||
and `framework-template.md` already shipped; Step 13 added the 4 missing ones
|
||
(`high-engagement-posts-template.md`, `demographics-template.md`,
|
||
`engagement-patterns-template.md`, `my-post-templates-template.md`). The 3
|
||
already-generic instances seeded their templates verbatim; the high-engagement
|
||
template is a freshly-authored generic seed (the old instance was the leak).
|