From 841d2a9e798c8716c28d81feeb7d0396576f9983 Mon Sep 17 00:00:00 2001 From: DanielGameiro Date: Thu, 9 Jul 2026 22:44:46 +0100 Subject: [PATCH] Add memory-boundaries rule, drift checks, and a solo-PM field report Contributes learnings from four months running Shannon: - New rule .claude/rules/memory-boundaries.md: the single-source-of-truth principle (one home per fact, pointers not copies) with a layer-ownership table and a tie-break rule. Prevents the always-loaded files from drifting out of sync with agent-maintained Brains. - system-health-check: add a memory-boundary drift check (template artifacts, duplicated facts across files, stale personal config, rule echo). - quality-gates Gate 0: add a "duplicated fact" red flag. - Shanon-Docs/field-notes-solo-pm.md: an honest field report (what worked, the struggles, how these improvements came about). All additive and generic. No proprietary or organization-specific content. Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/rules/memory-boundaries.md | 34 +++++++++++++++ .claude/rules/quality-gates.md | 2 +- .claude/skills/system-health-check/SKILL.md | 10 +++++ Shanon-Docs/field-notes-solo-pm.md | 48 +++++++++++++++++++++ 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 .claude/rules/memory-boundaries.md create mode 100644 Shanon-Docs/field-notes-solo-pm.md diff --git a/.claude/rules/memory-boundaries.md b/.claude/rules/memory-boundaries.md new file mode 100644 index 0000000..2e715d4 --- /dev/null +++ b/.claude/rules/memory-boundaries.md @@ -0,0 +1,34 @@ +# Memory Boundaries + +One principle: **each fact has exactly one home; every other place that needs it stores a pointer, not a copy.** Never copy a volatile fact into a second file. + +This is the rule that keeps a long-lived harness from rotting. The layered memory hierarchy answers *when* something loads (always-on vs conditional). This answers *who owns it*. They are different axes, and getting the layering right while getting ownership wrong still causes silent decay. + +## Why this exists + +The always-loaded, hand-maintained files (`CLAUDE.md`, `CLAUDE.local.md`) drift from the files an agent keeps current every session (a Brain's `CLAUDE.md`). When the same fact (a date, a status, a stakeholder list) lives in both, the copies fall out of sync. The model then reads two conflicting "truths" and picks between them unpredictably. You debug bad output before realizing a stale copy is the cause. Duplication is a slow leak. + +## Layer ownership + +Assign every class of fact exactly one owner: + +| Fact class | Single home | Everywhere else | +|-----------|-------------|-----------------| +| Who the user is, how they work | `CLAUDE.local.md` | Nothing else states it | +| An initiative's status, decisions, dates, stakeholders | That initiative's Brain (`Brains//CLAUDE.md`) | A pointer to the Brain | +| Goals / objectives and progress evidence | A dedicated goals or roll-up Brain | Pointer; source Brains state only their own slice | +| The relationship graph between Brains | `Brains/INDEX.md` | Each Brain links to the index, does not re-describe every edge | +| How to work with a specific person | That person's persona file | Skills reference the persona, never restate it | +| Published, canonical docs | The external system of record | Pointer by ID/URL, never a pasted copy | +| A behavioral invariant | One rule file in `.claude/rules/` | Not echoed in `CLAUDE.md` or a skill | + +## Rules of thumb + +- **Product/initiative facts** (status, dates, decisions) live in the owning Brain. `CLAUDE.local.md` and `CLAUDE.md` give a pointer, not a copy. +- **Tie-break, decided in advance:** when two files disagree, the Brain an agent keeps current wins over a hand-maintained file. State it where the conflict could arise. +- **De-duplicate by pointing, never by deleting.** Replace the copy with a pointer; keep the original and its history in its one home. Never drop a decision or log entry to resolve a duplication. +- **Extend it to teams:** private nuance in a Brain, shared decisions in one team-visible home, org-wide facts in an org home. Same rule, wider scope. + +## Enforcement + +Do not rely on memory to stay clean. The `system-health-check` skill greps the always-loaded files for the signs of drift (unfilled `[bracket]` template placeholders, a fact duplicated across files, a `CLAUDE.local.md` older than the newest Brain). The principle is a rule; the health check is how it stays honest. diff --git a/.claude/rules/quality-gates.md b/.claude/rules/quality-gates.md index fa263cc..e318c33 100644 --- a/.claude/rules/quality-gates.md +++ b/.claude/rules/quality-gates.md @@ -6,7 +6,7 @@ - [ ] If skill exists, read the SKILL.md before responding? - [ ] Applying framework, not generic LLM patterns? -Red flags: offering multiple tone variations, generic advice without framework, not asking clarifying questions specified in skill protocol. +Red flags: offering multiple tone variations, generic advice without framework, not asking clarifying questions specified in skill protocol, copying a volatile fact into a second file instead of pointing to its one home (see `.claude/rules/memory-boundaries.md`). ## Gate 1: Purpose diff --git a/.claude/skills/system-health-check/SKILL.md b/.claude/skills/system-health-check/SKILL.md index 953c1f0..e5c56c5 100644 --- a/.claude/skills/system-health-check/SKILL.md +++ b/.claude/skills/system-health-check/SKILL.md @@ -76,6 +76,15 @@ Check if `CLAUDE.local.md` exists: - If missing: flag as "Onboarding not complete" - If exists: check for key sections (name, role, preferences) +### 8. Memory Boundary Drift + +Enforce the single-source-of-truth principle in `.claude/rules/memory-boundaries.md`. Report as warnings (never auto-fix; de-duplication is the user's call). + +- **Template artifacts**: grep `CLAUDE.local.md` and `CLAUDE.md` for `[bracket]` placeholders (e.g. `[DATE]`, `[Your name]`, `[role]`). Any left means the file was never filled in. +- **Duplicated facts**: flag when the always-loaded files restate something a Brain owns instead of pointing to it. Heuristics: a stakeholder roster beyond the user's own reporting line, hard dates (milestone/launch dates), a status value, or a goals table that also appears in a Brain. These belong in the owning Brain; the always-loaded file should hold a pointer. +- **Staleness**: compare the `Last Updated` date in `CLAUDE.local.md` against the newest `Last Updated` across `Brains/*/CLAUDE.md`. If the personal config is older and still carries volatile facts, flag it as likely drifting. +- **Rule echo**: flag any rule text that appears in more than one of `CLAUDE.md`, a rule file, or a skill. Define each rule once, in the narrowest scope that covers it. + ## Output Format ``` @@ -116,3 +125,4 @@ Never silently fix issues. Transparency is a core Shannon principle. - All Brains have valid CLAUDE.md - No broken path references - CLAUDE.local.md exists with user context +- No memory-boundary drift (no template artifacts, duplicated facts, or stale copies across always-loaded files) diff --git a/Shanon-Docs/field-notes-solo-pm.md b/Shanon-Docs/field-notes-solo-pm.md new file mode 100644 index 0000000..ccbe8e4 --- /dev/null +++ b/Shanon-Docs/field-notes-solo-pm.md @@ -0,0 +1,48 @@ +# Field Notes: Four Months Running Shannon as a Solo PM + +These are one contributor's notes from adopting Shannon in March and running it daily since. They are meant as an honest field report, not a tutorial: what worked, where it hurt, and the changes that came out of the pain. The improvements in the accompanying pull request came directly from these notes. + +Thanks to the maintainers for building Shannon in the open and inviting contributions. Everything below is generic PM practice, with no proprietary or organization-specific detail. + +## How I used it + +I run a single-player setup: one PM, no team sharing the harness. I used Shannon for two very different jobs at once, which turned out to be a good stress test: + +1. A zero-to-one product discovery and definition effort (lots of interviews, evolving problem framing, many decisions to remember across months). +2. A public writing initiative (a recurring content series with its own voice rules and pipeline). + +Running both through the same harness is where most of the lessons came from. The system had to hold two unrelated bodies of context without bleeding one into the other. + +## What worked, quickly + +- **Knowledge contexts (Brains) are the core value.** A per-initiative living doc that accumulates decisions with rationale meant I stopped re-explaining background every session. By month two, starting a session in a context felt like resuming a conversation with someone who had read everything. This is the feature I would keep if I could keep only one. +- **Auto-activating skills beat remembering to invoke methodology.** Encoding a framework once and having it trigger on intent removed the "I forgot I had a process for this" failure mode. +- **Personas paid off in an unexpected way.** I built them to remember how specific people communicate, but the higher-value use was pre-mortem: having the model critique a draft as that person before the real meeting. It found the objection every time. +- **Hooks made the good behavior automatic.** The onboarding check and session logging ran whether or not I remembered them. Determinism in shell beat hoping the model would self-remind. + +## Where it hurt (the honest part) + +- **Skill bloat crept in fast.** New methodology felt cheap to add, so I added a lot. Past a point, intent-matching got less reliable because descriptions overlapped. Curation is not a one-time setup step; it is ongoing maintenance. Archiving (not deleting) unused skills fixed the matching quality. +- **The always-loaded files drifted, and this was the worst one.** I put project status, dates, and a stakeholder list into my always-loaded personal config because it was convenient. I also kept those facts in the initiative's knowledge context, which got updated every session. Months later the two disagreed. The model read both and picked between them unpredictably. I spent real time debugging bad output before realizing a stale copy I had forgotten about was the cause. Duplication is a slow leak. +- **The CLAUDE.md wanted to become a monolith.** Everything is easiest to put in the always-loaded file, so it kept growing. Every line there is context spent on every session, relevant or not. I had to keep pushing methodology out into skills and reference docs. + +## What I changed + +The drift problem was the one that cost me the most, so it drove the biggest change: + +- **One home per fact.** I adopted a strict rule: every volatile fact lives in exactly one place, and everywhere else stores a pointer, not a copy. My personal config went from holding status, dates, and rosters to holding pointers to the context that owns them, plus a tie-break rule (if two files disagree, the context an agent keeps current wins). The drift stopped. This is the `memory-boundaries.md` rule in the accompanying PR. +- **Made drift detectable, not just avoidable.** I extended the health check to grep for the tell-tale signs: unfilled template placeholders, the same fact appearing in two files, and a personal config older than the newest context. Turning the principle into an automated check is what keeps it honest over time. +- **Curation as a habit.** I let usage data tell me which skills were dead rather than guessing, and archived aggressively. Fewer, sharper skills matched better. +- **Budget discipline on always-loaded files.** I kept moving stable, occasional material out of the always-loaded layer into conditionally-loaded skills and reference docs. Smaller always-on context, richer on-demand context. + +## The one lesson if you only take one + +Getting the layering right (what loads when) is necessary but not sufficient. The failure that actually rots a long-lived harness is duplication: the same fact in two files that slowly disagree. Give every fact one home and point everywhere else. It is boring, and it is the difference between a harness that compounds and one that quietly starts lying to you. + +## What this PR contributes back + +- A new `memory-boundaries.md` rule encoding the one-home-per-fact principle, with a layer-ownership table and a tie-break rule. +- Memory-boundary drift checks added to the existing `system-health-check` skill. +- A "duplicated fact" red flag added to Gate 0 in `quality-gates.md`. + +All additive, all generic. Offered in the spirit of the CONTRIBUTING guide: share your learnings, build on each other's work.