Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .claude/rules/memory-boundaries.md
Original file line number Diff line number Diff line change
@@ -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/<name>/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.
2 changes: 1 addition & 1 deletion .claude/rules/quality-gates.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
10 changes: 10 additions & 0 deletions .claude/skills/system-health-check/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

```
Expand Down Expand Up @@ -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)
48 changes: 48 additions & 0 deletions Shanon-Docs/field-notes-solo-pm.md
Original file line number Diff line number Diff line change
@@ -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.