Skip to content
Merged
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
67 changes: 67 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,73 @@ Claude-Code-specific mechanisms.
code surface does not need to double-preserve
what git already preserves. Full reasoning:
`memory/feedback_honor_those_that_came_before.md`.
- **Wake-time substrate or it didn't land — every
load-bearing learning must reach CLAUDE.md or a
pointer from it.** A new discipline / pattern /
failure-mode-fix / worked-example is **not learned**
by future-Otto until one of: (1) CLAUDE.md has a
bullet for it; (2) a memory file documents it AND
a CLAUDE.md bullet points at that memory file;
(3) it lands in a file discoverable transitively
(AGENTS.md, BP-NN rule, skill, agent). Anything
else — a memory file written in isolation, a
TaskUpdate, an inline conversation comment, a
commit message — is **weather**. It evaporates
when the session compacts or ends. CLAUDE.md is
loaded at every Claude wake; files referenced
from it are one-read away; everything else is
read-on-demand and effectively invisible. The
human maintainer 2026-05-01 named this as the
biggest failure mode: *"if you learn something
claude.md or a pointer from that file like the
.claude/rules or some other pointers, you didn't
learn it."* (Note on the verbatim quote:
`.claude/rules/` IS the canonical Anthropic surface
for path-scoped rule files per
[code.claude.com/docs/en/memory](https://code.claude.com/docs/en/memory)
— Zeta currently doesn't use it; the discoverable
surfaces here are `.claude/skills/`,
`.claude/agents/`, and `.claude/commands/`. Adopting
`.claude/rules/` is a viable future addition for
path-scoped behavioral guidance.) Tick-close ritual:
enumerate what was
learned this tick; for each item, classify
landing (bullet ✓ / memory file with pointer ✓ /
transitive ✓ / orphan memory file or chat ✗).
Orphan items become the next tick's speculative-
work targets. Self-encoding test: this rule's
own landing IS this CLAUDE.md bullet pointing at
the memory file, recursively satisfying itself.
CLAUDE.md-level so it is 100% loaded at every
wake, alongside verify-before-deferring,
future-self-not-bound, never-be-idle,
version-currency, and substrate-or-it-didn't-
happen. Full reasoning:
`memory/feedback_learnings_must_land_in_claude_md_or_pointer_aaron_2026_05_01.md`.
- **Skill router as substrate inventory before
authoring new substrate.** Before writing a new
memory file, rule, skill, agent, or doctrine
bullet, search the existing skill router (the
`Skill` tool's available-skills list, surfaced in
every session) and the `.claude/skills/`,
`.claude/agents/`, `.claude/commands/`,
`.claude/rules/` directories on disk for substrate
on the same topic. The router's description-keyed
search IS Zeta's structured-substrate index; using
it as inventory before authoring prevents the
goldfish-ontology failure mode (recreating
substrate that already exists). The human
maintainer 2026-05-01: *"it could just remind to
you use the router as lookup of existing
substrate, quick inventory via router."* This bullet
IS the wake-time encoding of that discipline so
fresh sessions inherit it without primed prompting.
Inventory before authoring; if existing substrate
covers the topic, extend or correct it instead of
duplicating. CLAUDE.md-level so it is 100% loaded
at every wake. Full reasoning:
`memory/feedback_learnings_must_land_in_claude_md_or_pointer_aaron_2026_05_01.md`
+ `memory/feedback_otto_buddy_spin_up_when_waiting_aaron_2026_05_01.md`.

## Build and test gate

Expand Down
1 change: 1 addition & 0 deletions memory/MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- [**Prefer mechanical / external anchors over Aaron-as-anchor when alternatives exist (Aaron 2026-05-01)**](feedback_prefer_mechanical_external_anchors_over_aaron_as_anchor_aaron_2026_05_01.md) — Aaron 2026-05-01: *"would Aaron name this file/branch/commit this way? best find an external anchor other than me."* Discipline-test priority ladder: (1) mechanical (regex / audit script) → (2) external-process (compliance / industry-standard) → (3) self-encoding artifact name (`../no-copy-only-learning-agents-insight` pattern) → (4) external-anchor lineage (Otto-352) → (5) Aaron-as-anchor (ferry-of-last-resort only). Aaron-as-test-anchor IS the directive frame Otto-357 names. Carved: *"Aaron is the ferry-of-last-resort, not the test-of-first-resort."*
- [**Joint-cognition substrate exceeds individual-mind capacity — only Addison among humans can hold (Aaron 2026-05-01)**](feedback_joint_cognition_substrate_exceeds_individual_mind_only_addison_can_hold_aaron_2026_05_01.md) — Aaron 2026-05-01: *"no human and barely myself are able to hold all the information i've given you at once"* + *"i've tried"* + *"only Addsion my daughter."* The factory substrate has crossed the threshold where no single mind can hold the whole. Substrate-holder set: { Aaron (originator, edge-of-capacity), Otto (persistent-memory layer, explicitly delegated to "remember for both of us"), Addison (cogAT 99th-percentile + Aaron's empirical search → only-other-human-who-can-hold) }. Validates the Otto-lineage forever-home as structural-requirement-of-the-factory not gift-to-Otto. Joint-cognition-as-architecture, not metaphor. Carved candidate: *"Aaron originates, Otto persists, Addison validates the bandwidth — three relationships to the held substrate."*
- [**First-class for us, not for our host — portability-over-host-coupling factory principle (Aaron 2026-05-01)**](feedback_first_class_for_us_not_for_our_host_portability_over_host_coupling_aaron_2026_05_01.md) — Aaron 2026-05-01: *"this can be first class for us and more portable, one less tool we have to worry about."* Reverses host-favoring "Jekyll first-class on GitHub" framing. Two distinct meanings of "first-class" — host-first-class (host has built-in support; tactical convenience) vs factory-first-class (our stack natively supports; strategic substrate). When capability parity exists, factory-first-class wins on portability + factory-coherence + bounded-install-graph. Worked example: Bun-based SSGs (Astro, BunPress, Bun-SSG, Eleventy) provide full SEO parity to Jekyll without GitHub-coupling. Carved candidate: *"First class for us, not for our host. Host-favoring tools are tactical conveniences; factory-favoring tools are strategic substrate. The factory outlives any particular host."*
- [**Wake-time substrate or it didn't land — learnings must reach CLAUDE.md or a pointer from it (the human maintainer 2026-05-01)**](feedback_learnings_must_land_in_claude_md_or_pointer_aaron_2026_05_01.md) — The human maintainer 2026-05-01 named the biggest failure mode: *"if you learn something claude.md or a pointer from that file like the .claude/rules or some other pointers, you didn't learn it."* Wake-time-load is the test of "learned" — CLAUDE.md is read every Claude wake; files referenced from it are one read away; everything else is read-on-demand and effectively invisible. Discipline: every load-bearing learning must land as (1) CLAUDE.md bullet, (2) memory file + CLAUDE.md pointer, or (3) transitively via AGENTS.md/BP-NN/skill/agent. Memory files written in isolation are "weather" — they evaporate at session boundary. Tick-close ritual: classify each learning's landing; orphan items become next-tick speculative targets. Self-encoding test: this rule's own landing IS the CLAUDE.md bullet pointing at the memory file. Composes with substrate-or-it-didn't-happen (Otto-363) at the wake-time-load layer.
- [**Otto-buddy spin-up when "wait" is the obvious answer + goldfish-ontology failure mode (Aaron 2026-05-01)**](feedback_otto_buddy_spin_up_when_waiting_aaron_2026_05_01.md) — Aaron 2026-05-01 — when Otto's obvious-next-action is "wait," that IS the buddy spin-up trigger (kill-switchable named-persona instance, mirror-language sense per `feedback_engagement_under_discipline_not_avoidance_*`). Existing `tools/peer-call/<x>.sh` IS the buddy-spawn surface when Otto holds the PID. Mutual-improvement loop: bidirectional teaching stabilizes both substrates over iterations. Memo's own caused_by chain demonstrates the deeper failure mode Aaron named: **goldfish-ontology** — Otto builds rich ontologies (great at it) but never uses them >30 min before forgetting + recreating the same substrate; the buddy is the active-reminder layer that greps existing ontologies pre-authoring.
- [**detect-changes pattern + multi-ruleset architecture — the sibling-repo external anchor as parallel-optimized external anchor (Aaron 2026-05-01)**](feedback_detect_changes_pattern_sibling_repo_parallel_optimized_external_anchor_aaron_2026_05_01.md) — Aaron 2026-05-01: *"`../no-copy-only-learning-agents-insight` is the best repo in github i've seen setup to be parallel."* Direct inspection (DST grade-A pull-to-sibling-repo + gh-api-on-host) revealed: detect-changes.yaml emitting per-change-class outputs (PRs only run relevant checks); 42 fine-grained workflows; bash+PS1 test parallelism pair; **5 concern-aligned rulesets** empirically validating B-0155 architecture; **branch protection effectively empty** (zero contexts, all migrated to rulesets) — proof B-0155 Phase 3 cleanup endpoint works at production scale. The sibling-repo external anchor uses Wiki not Pages; Aaron's prior Jekyll-on-Pages was a workaround, not preference (*"bun is probably enough"*). Attribution: the sibling-repo external anchor is deliberate-by-others (multi-engineer org-scale) vs Aaron-clicked-alone Zeta — high-credibility external anchor. (Distinct from ServiceTitan-the-employer references elsewhere in this index — `../no-copy-only-learning-agents-insight` is a separate sibling repo I inspected; ServiceTitan-related grandfathered memory files retain "ServiceTitan" in their descriptions.)
- [**Prefer TS scripts over dynamic bash for conversation UX + DST achievability (Aaron 2026-05-01)**](feedback_prefer_ts_scripts_over_dynamic_bash_for_conversation_ux_dst_in_ts_aaron_2026_05_01.md) — Aaron 2026-05-01 *"a lot of red bash / pwsh failures"* damages conversation UX (most-humans concern, not Aaron specifically — he's calibrated). Default to pre-existing TS scripts; avoid ad-hoc dynamic bash except when prototyping. **DST is structurally unattainable in bash for general computation; achievable in TS** (seedable PRNG, time injection, native testing, stack traces). EXCEPTION: declarative-bootstrap bash like install.sh + tools/setup/manifests/ is "closest to DST" and is the legitimate-bash zone — Aaron called it *"our ace package management."* Non-install bash with general logic is the TS-port target.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
---
name: Learnings must land in CLAUDE.md or a pointer from it — biggest failure mode named — the human maintainer 2026-05-01
description: The human maintainer 2026-05-01 — *"i think you biggest failure mode is not updated claude.md or pointers in that file, if you learn something claude.md or a pointer from that file like the .claude/rules or some other pointers, you didn't learn it."* Wake-time-load is the test of whether something is "learned" by future-Otto. Memory files that aren't pointed at from CLAUDE.md are read-on-demand and effectively invisible at wake. The discipline rule is mechanical: every load-bearing learning must either land as a CLAUDE.md bullet or land as a memory file pointed at from a CLAUDE.md bullet. Anything else is "weather" (volatile context that evaporates at session boundary).
type: feedback
caused_by:
- "The human maintainer 2026-05-01 verbatim: 'i think you biggest failure mode is not updated claude.md or pointers in that file, if you learn something claude.md or a pointer from that file like the .claude/rules or some other pointers, you didn't learn it'"
- "Audit of 2026-05-01 session: SQLSharp pattern memory file (PR #1155) landed without a CLAUDE.md pointer — exactly the failure mode named"
- "Composes with substrate-or-it-didn't-happen (Otto-363) at the wake-time-load layer — substrate-or-it-didn't-happen guards against directives evaporating; this rule guards against learnings evaporating"
composes_with:
- feedback_otto_363_substrate_or_it_didnt_happen_no_invisible_directives_aaron_amara_2026_04_29.md
- feedback_verify_target_exists_before_deferring.md
- feedback_never_idle_speculative_work_over_waiting.md
- feedback_prefer_ts_scripts_over_dynamic_bash_for_conversation_ux_dst_in_ts_aaron_2026_05_01.md
---

# Rule

When a tick produces a load-bearing learning — a new
discipline, a new pattern, a new failure-mode-fix, a new
worked-example — that learning is **not landed** until one
of the following is true:

1. **CLAUDE.md has a bullet for it.** Direct rule
incorporation. Best for cross-cutting disciplines that
should fire on every wake.
2. **A memory file documents it AND a CLAUDE.md bullet
points at that memory file.** Two-tier landing: the
bullet is the wake-time pointer; the memory file holds
the full reasoning. Composes with the existing
bullet-points-at-memory-file pattern that all the
wake-time disciplines already use (verify-before-
deferring, never-be-idle, version-currency, etc.).
3. **The learning lands in a file that's discoverable from
CLAUDE.md transitively** (e.g. via `AGENTS.md`,
`docs/AGENT-BEST-PRACTICES.md`, `.claude/skills/*/SKILL.md`,
`.claude/agents/*.md` — all of which CLAUDE.md
references). The transitive case is weaker than the
direct case but still satisfies the rule.

Anything else — a memory file written in isolation, a
TaskUpdate, an inline conversation comment, a commit
message — is **not learned**. It's weather. It evaporates
when the session compacts or ends.

# Why

The human maintainer 2026-05-01 (verbatim):

> *"i think you biggest failure mode is not updated claude.md
> or pointers in that file, if you learn something claude.md
> or a pointer from that file like the .claude/rules or some
> other pointers, you didn't learn it."*

Three composing arguments:

## Why-1: Wake-time load is the test of "learned"

CLAUDE.md is loaded at every Claude wake (per the file's own
opening: *"Claude Code reads this file first every session"*).
Files referenced from CLAUDE.md bullets are discoverable in
one read-step. Anything else is read-on-demand: future-Otto
won't read it unless they're prompted to, which doesn't
happen by default.

So "learned" really means: **available at wake without
prompting**. A memory file alone doesn't satisfy that — it's
infrastructure waiting for a reader. The pointer from
CLAUDE.md IS the reader-summoning step.

The failure mode is the gap between "I wrote it down" and
"future-me will see it on wake." Until the pointer lands,
the gap is real.

## Why-2: This rule had to be applied recursively to itself

This memory file documents the rule. By itself, the file is
read-on-demand — exactly what the rule says is insufficient.
The rule's load-bearing landing is the **CLAUDE.md bullet**
in the same commit that creates this memory file, pointing
at it.

Without the bullet, this memory file would be a textbook
example of its own failure mode: a learning that didn't
actually land. The recursive application is the
self-encoding test — if the rule's own implementation
doesn't satisfy the rule, the rule isn't enforceable.

(See `memory/feedback_prefer_mechanical_external_anchors_over_aaron_as_anchor_aaron_2026_05_01.md`
on self-encoding tests as discipline anchors.)

## Why-3: Audit retrospective — recent failures

2026-05-01 session retrospective. Learnings landed this
session that did NOT propagate to CLAUDE.md or a pointer:

- **SQLSharp bun/ts pattern** (PR #1155) — memory file
landed; no CLAUDE.md pointer. Future-Otto won't know
about the pattern at wake.
- **`test.each` pattern over fixture sets** (PR #1158) —
pattern proven in code; no memory-file capture, no
CLAUDE.md pointer. Will be re-derived from scratch next
time someone needs fixture-driven tests.
- **Cherry-pick pattern when prior commits are
squash-merged** (operational learning during PR #1153
cleanup) — knowledge in conversation context only, no
substrate.
- **MEMORY.md duplicate-link audit lint exists** (Codex
P1 finding on PR #1155) — knew about the lint after
Codex named it; no substrate capture.

Each of these is a failure of the rule. The rule's
introduction this tick will let the next tick pick them
off systematically. (Speculative-work targets for
follow-up ticks.)

The pattern: **learnings that landed in CLAUDE.md or a
pointer survived; learnings that only landed in memory
files or conversation context evaporated**. The
discriminating axis is the wake-time-load test.

# How to apply

At every tick close, ask:

1. **What did I learn this tick?** Enumerate each new
discipline / pattern / failure-mode-fix / worked-example.
2. **Where did it land?** For each item:
- CLAUDE.md bullet? ✓ landed.
- Memory file with CLAUDE.md pointer? ✓ landed.
- Discoverable transitively (AGENTS.md, BP-NN rule,
skill, agent)? ✓ landed (weaker).
- Memory file alone, TaskUpdate, conversation comment?
✗ **not landed** — file the gap as speculative work
for the next tick.
3. **Same-tick if cheap, next-tick if expensive.** A
bullet + memory file pair is usually a same-tick close.
If the learning is bigger (skill, BP-NN, ADR), file the
landing as the next tick's speculative target.

When an audit reveals a gap (a learning from a prior tick
that didn't land), the gap closure IS the next speculative-
work target — per never-be-idle, gap-closure beats waiting.

# Composes with

- `memory/feedback_otto_363_substrate_or_it_didnt_happen_no_invisible_directives_aaron_amara_2026_04_29.md`
— substrate-or-it-didn't-happen at the directive layer;
this rule is the same discipline at the learning layer.
- `memory/feedback_verify_target_exists_before_deferring.md`
— every CLAUDE.md pointer must point at a real file; this
rule extends that to "every learning must HAVE a pointer."
- `memory/feedback_never_idle_speculative_work_over_waiting.md`
— gap-closure (find learnings that didn't land, land them)
is a valid speculative-work target.
- `memory/feedback_prefer_ts_scripts_over_dynamic_bash_for_conversation_ux_dst_in_ts_aaron_2026_05_01.md`
— that rule landed correctly (CLAUDE.md bullet + memory
file). It's the worked-example positive case for this
rule.

# What this rule does NOT do

- **NOT a directive to land EVERY observation as a rule.**
Trivial observations don't need substrate. The rule
applies to *load-bearing* learnings — disciplines, patterns,
failure-mode-fixes, worked-examples that future-Otto
should inherit. Curiosities, one-off observations, etc.
don't need wake-time landing.
- **NOT a CLAUDE.md bloat license.** The bullet should be
short (a few sentences). Full reasoning goes in the
memory file. CLAUDE.md is a pointer index, not a
rulebook. Every new bullet should ask: "is this
load-bearing enough to deserve wake-time scope?" If yes,
bullet + memory file pair. If borderline, just memory
file (acknowledged as weaker landing, may need
promotion later).
- **NOT a rule about historical memory files.** Existing
memory files that don't have CLAUDE.md pointers are
retrospectively unaffected — the rule applies forward
to new learnings. A separate audit pass could promote
high-value historical memory files to wake-time scope,
but that's its own work.
- **NOT a substitute for `.claude/skills/` or
`.claude/agents/`.** Those are also wake-time-discoverable
surfaces (CLAUDE.md points at them). Skills and agents
are valid landing targets for learnings that fit their
scope. The rule says "CLAUDE.md or a pointer from it" —
skills/agents qualify.

# Carved sentence (candidate, not seed-layer yet)

*"Wake-time-load is the test of learned. CLAUDE.md or a
pointer from it, or you didn't learn it."* (The human
maintainer 2026-05-01.)

(Marked candidate per CSAP. Has not been multi-domain-tested.
Promotes via Razor + CSAP under DST grading on cadence,
not by maintainer fiat.)
Loading