Files
firefrost-operations-manual/docs/reference/external/claude-code-field-manual.html
Claude b978b5793c feat: Add GATE Protocol (FFG-STD-007) and Claude Code Field Manual
New standard FFG-STD-007 defines five mandatory checkpoints for Chroniclers:
- GATE 1: Pre-Commit (secret scan, review staged)
- GATE 2: Self-Audit (test, edge cases, re-audit)
- GATE 3: Post-Work (handoff updated, decisions documented)
- GATE 4: Push-Verify (confirm push succeeded)
- GATE 5: Session Handoff (memorial, clear next step)

Also preserved the Claude Code Field Manual by Ovidiu & Claude Opus 4.6
as external reference. This document independently discovered similar
principles to our Chronicler system — validates our approach.

Key insight from the manual: 'Treat the agent as a long-running
collaborator that has amnesia.' We call this Zora + Dax. Same truth.

Chronicler #75
2026-04-10 04:49:04 +00:00

1093 lines
41 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Field Manual № 01 — The Discipline of Collaborating with an Agent that Forgets</title>
<meta name="description" content="A field manual for engineers shipping real software with Claude Code across many sessions. The memory system, the GATEs, the handoff protocol.">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght,SOFT@0,9..144,300..900,0..100;1,9..144,300..900,0..100&family=Newsreader:ital,opsz,wght@0,6..72,300..700;1,6..72,300..700&family=JetBrains+Mono:wght@300;400;500;700&display=swap" rel="stylesheet">
<style>
:root {
/* Warm paper palette */
--paper: #F1EAD6;
--paper-deep: #E8DEC2;
--paper-tint: #F8F2E1;
--ink: #1A130C;
--ink-soft: #4A3D2E;
--ink-faint: #8B7B65;
--rule: #BFAE8C;
--rule-soft: #DCCFAE;
--accent: #B8400E;
--accent-warm: #D9722A;
/* Terminal palette */
--terminal: #14100B;
--terminal-deep: #0B0907;
--terminal-text: #E8DEC2;
--terminal-amber: #E8A95B;
--terminal-rust: #D9722A;
--terminal-faint: #8B7B65;
/* Type */
--serif-display: 'Fraunces', Georgia, serif;
--serif-body: 'Newsreader', Georgia, serif;
--mono: 'JetBrains Mono', 'SF Mono', Consolas, monospace;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
font-family: var(--serif-body);
font-optical-sizing: auto;
font-size: 19px;
line-height: 1.65;
color: var(--ink);
background: var(--paper);
-webkit-font-smoothing: antialiased;
position: relative;
overflow-x: hidden;
}
/* Paper texture using SVG noise */
body::before {
content: '';
position: fixed;
inset: 0;
pointer-events: none;
z-index: 1;
opacity: 0.45;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.1 0 0 0 0 0.08 0 0 0 0 0.05 0 0 0 0.08 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
mix-blend-mode: multiply;
}
/* Subtle vertical fold mark down the page */
body::after {
content: '';
position: fixed;
top: 0; bottom: 0;
left: 50%;
width: 1px;
background: linear-gradient(180deg, transparent, rgba(26, 19, 12, 0.025) 20%, rgba(26, 19, 12, 0.025) 80%, transparent);
pointer-events: none;
z-index: 1;
}
::selection { background: var(--accent); color: var(--paper); }
/* ═════════════════════════════════════════════════════════
TOP BAR
═════════════════════════════════════════════════════════ */
.topbar {
position: relative;
z-index: 10;
border-bottom: 1px solid var(--rule);
padding: 18px 56px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: var(--mono);
font-size: 10.5px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--ink-soft);
}
.topbar .mark {
display: flex;
align-items: center;
gap: 14px;
}
.mark-glyph {
width: 30px; height: 30px;
border: 1.5px solid var(--ink);
display: flex;
align-items: center;
justify-content: center;
font-family: var(--serif-display);
font-variation-settings: "opsz" 20, "SOFT" 30;
font-size: 17px;
font-weight: 500;
font-style: italic;
color: var(--ink);
}
.topbar .meta { display: flex; gap: 36px; align-items: center; }
.topbar .dot { color: var(--accent); }
/* ═════════════════════════════════════════════════════════
HERO
═════════════════════════════════════════════════════════ */
.hero {
position: relative;
z-index: 5;
padding: 88px 56px 110px;
max-width: 1240px;
margin: 0 auto;
}
.hero .eyebrow {
font-family: var(--mono);
font-size: 11px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--accent);
margin-bottom: 72px;
display: flex;
align-items: center;
gap: 16px;
}
.hero .eyebrow::before {
content: '';
width: 48px; height: 1px;
background: var(--accent);
}
.hero .vol {
font-family: var(--serif-display);
font-variation-settings: "opsz" 18, "SOFT" 50;
font-style: italic;
font-size: 24px;
font-weight: 400;
color: var(--ink-soft);
margin-bottom: 18px;
}
.hero h1 {
font-family: var(--serif-display);
font-variation-settings: "opsz" 144, "SOFT" 30;
font-size: clamp(46px, 7.8vw, 116px);
line-height: 0.9;
font-weight: 400;
letter-spacing: -0.025em;
margin-bottom: 44px;
color: var(--ink);
}
.hero h1 em {
font-style: italic;
font-variation-settings: "opsz" 144, "SOFT" 100;
color: var(--accent);
}
.hero .dek {
font-family: var(--serif-body);
font-optical-sizing: auto;
font-size: clamp(20px, 1.65vw, 26px);
line-height: 1.45;
font-weight: 300;
color: var(--ink-soft);
max-width: 740px;
margin-bottom: 72px;
font-style: italic;
}
.hero .byline {
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: 28px;
font-family: var(--mono);
font-size: 10.5px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--ink-faint);
border-top: 1px solid var(--rule);
padding-top: 28px;
}
.hero .byline span:not(:last-child)::after {
content: '·';
margin-left: 28px;
color: var(--accent);
}
/* ═════════════════════════════════════════════════════════
ARTICLE
═════════════════════════════════════════════════════════ */
.article {
position: relative;
z-index: 5;
max-width: 1240px;
margin: 0 auto;
padding: 0 56px 120px;
}
.section {
margin-bottom: 130px;
display: grid;
grid-template-columns: 160px 1fr;
gap: 64px;
position: relative;
}
.section .gutter {
position: relative;
padding-top: 12px;
}
.gutter .num {
font-family: var(--serif-display);
font-variation-settings: "opsz" 144, "SOFT" 50;
font-style: italic;
font-size: 64px;
line-height: 0.95;
font-weight: 300;
color: var(--accent);
margin-bottom: 6px;
letter-spacing: -0.02em;
}
.gutter .label {
font-family: var(--mono);
font-size: 9.5px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-faint);
display: block;
line-height: 1.5;
border-top: 1px solid var(--rule);
padding-top: 10px;
margin-top: 10px;
max-width: 130px;
}
.section .body h2 {
font-family: var(--serif-display);
font-variation-settings: "opsz" 96, "SOFT" 30;
font-size: clamp(34px, 4.4vw, 56px);
line-height: 1.02;
font-weight: 400;
letter-spacing: -0.018em;
margin-bottom: 36px;
max-width: 22ch;
color: var(--ink);
}
.section .body p {
font-family: var(--serif-body);
font-size: 19px;
line-height: 1.72;
margin-bottom: 24px;
max-width: 64ch;
color: var(--ink);
font-weight: 400;
}
.section .body p em {
font-style: italic;
font-variation-settings: "opsz" 18, "SOFT" 50;
}
.section .body p strong {
font-weight: 600;
color: var(--ink);
}
/* Lede with drop cap */
.section .body p.lede {
font-size: 23px;
line-height: 1.55;
font-weight: 300;
color: var(--ink);
margin-top: 8px;
}
.section .body p.lede::first-letter {
font-family: var(--serif-display);
font-variation-settings: "opsz" 144, "SOFT" 30;
font-size: 5.6em;
line-height: 0.84;
float: left;
margin: 0.04em 0.1em 0 -0.04em;
font-weight: 400;
color: var(--accent);
}
/* Inline small caps for emphasis */
.sc {
font-variant-caps: all-small-caps;
letter-spacing: 0.06em;
font-weight: 500;
}
/* ═════════════════════════════════════════════════════════
GATE GRID
═════════════════════════════════════════════════════════ */
.gate-intro {
font-family: var(--mono);
font-size: 11px;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--accent);
margin: 56px 0 8px;
display: flex;
align-items: center;
gap: 14px;
}
.gate-intro::after {
content: '';
flex: 1;
height: 1px;
background: var(--rule);
}
.gate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0;
margin-top: 24px;
border-top: 1px solid var(--ink);
border-left: 1px solid var(--rule);
}
.gate {
border-right: 1px solid var(--rule);
border-bottom: 1px solid var(--rule);
padding: 38px 34px 34px;
position: relative;
background: transparent;
transition: background 0.5s ease;
}
.gate:hover {
background: rgba(184, 64, 14, 0.04);
}
.gate .gate-num {
font-family: var(--mono);
font-size: 10px;
letter-spacing: 0.18em;
color: var(--accent);
margin-bottom: 18px;
display: flex;
align-items: center;
gap: 10px;
}
.gate .gate-num::after {
content: '';
flex: 1;
height: 1px;
background: var(--rule);
max-width: 60px;
}
.gate .gate-key {
font-family: var(--mono);
font-size: 11px;
letter-spacing: 0.05em;
color: var(--ink-faint);
display: block;
margin-bottom: 8px;
}
.gate h3 {
font-family: var(--serif-display);
font-variation-settings: "opsz" 36, "SOFT" 50;
font-size: 26px;
font-weight: 500;
letter-spacing: -0.005em;
margin-bottom: 16px;
color: var(--ink);
font-style: italic;
}
.gate p {
font-family: var(--serif-body);
font-size: 16px;
line-height: 1.62;
color: var(--ink-soft);
margin: 0;
}
/* ═════════════════════════════════════════════════════════
STANDING RULES
═════════════════════════════════════════════════════════ */
.rules-list {
margin-top: 48px;
border-top: 1px solid var(--ink);
}
.rule-item {
display: grid;
grid-template-columns: 70px 1fr;
gap: 28px;
padding: 36px 0 36px;
border-bottom: 1px solid var(--rule);
align-items: baseline;
}
.rule-item .marker {
font-family: var(--serif-display);
font-variation-settings: "opsz" 96, "SOFT" 50;
font-style: italic;
font-size: 52px;
font-weight: 300;
line-height: 1;
color: var(--accent);
}
.rule-item h3 {
font-family: var(--serif-display);
font-variation-settings: "opsz" 48, "SOFT" 30;
font-size: 28px;
font-weight: 500;
margin-bottom: 12px;
letter-spacing: -0.012em;
color: var(--ink);
}
.rule-item p {
font-family: var(--serif-body);
font-size: 17px;
line-height: 1.65;
color: var(--ink-soft);
margin: 0;
max-width: 60ch;
}
/* ═════════════════════════════════════════════════════════
PULL QUOTE
═════════════════════════════════════════════════════════ */
.pullquote {
margin: 72px 0 72px 24px;
padding: 12px 0 12px 56px;
border-left: 2px solid var(--accent);
font-family: var(--serif-display);
font-variation-settings: "opsz" 96, "SOFT" 50;
font-style: italic;
font-size: clamp(28px, 3.2vw, 42px);
line-height: 1.18;
font-weight: 300;
color: var(--ink);
letter-spacing: -0.015em;
max-width: 24ch;
}
.pullquote::before {
content: '';
display: block;
width: 32px;
height: 1px;
background: var(--accent);
margin-bottom: 24px;
margin-left: -56px;
}
/* ═════════════════════════════════════════════════════════
TERMINAL / CODE BLOCK
═════════════════════════════════════════════════════════ */
.terminal {
margin: 60px 0 40px;
background: var(--terminal);
color: var(--terminal-text);
font-family: var(--mono);
font-size: 12.5px;
line-height: 1.78;
position: relative;
box-shadow:
0 1px 0 rgba(255, 255, 255, 0.05) inset,
0 30px 80px -28px rgba(20, 16, 11, 0.5),
0 12px 32px -12px rgba(184, 64, 14, 0.18);
}
.terminal-header {
border-bottom: 1px solid rgba(232, 222, 194, 0.12);
padding: 16px 28px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 10px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--terminal-faint);
}
.term-title {
display: flex;
align-items: center;
gap: 14px;
}
.term-title::before {
content: '';
width: 9px; height: 9px;
border-radius: 50%;
background: var(--terminal-amber);
box-shadow: 0 0 14px rgba(232, 169, 91, 0.55);
animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { box-shadow: 0 0 14px rgba(232, 169, 91, 0.55); }
50% { box-shadow: 0 0 22px rgba(232, 169, 91, 0.85); }
}
.copy-btn {
background: transparent;
border: 1px solid rgba(232, 222, 194, 0.22);
color: var(--terminal-amber);
padding: 8px 16px;
font-family: var(--mono);
font-size: 9.5px;
font-weight: 500;
letter-spacing: 0.18em;
text-transform: uppercase;
cursor: pointer;
transition: all 0.28s ease;
border-radius: 0;
}
.copy-btn:hover {
background: rgba(232, 169, 91, 0.12);
border-color: var(--terminal-amber);
color: #FFEACA;
}
.copy-btn.copied {
background: var(--terminal-amber);
color: var(--terminal);
border-color: var(--terminal-amber);
}
.terminal-body {
padding: 32px 36px 36px;
overflow-x: auto;
white-space: pre-wrap;
word-wrap: break-word;
max-height: 720px;
overflow-y: auto;
scrollbar-color: rgba(232, 169, 91, 0.3) transparent;
scrollbar-width: thin;
}
.terminal-body::-webkit-scrollbar { width: 8px; height: 8px; }
.terminal-body::-webkit-scrollbar-track { background: transparent; }
.terminal-body::-webkit-scrollbar-thumb {
background: rgba(232, 169, 91, 0.25);
border-radius: 0;
}
.terminal-body::-webkit-scrollbar-thumb:hover {
background: rgba(232, 169, 91, 0.5);
}
.terminal-body .c { color: var(--terminal-faint); font-style: italic; }
.terminal-body .k { color: var(--terminal-amber); }
.terminal-body .a { color: var(--terminal-rust); }
.terminal-body .h { color: #FFEACA; font-weight: 500; }
.terminal-body .div {
color: var(--terminal-faint);
display: block;
padding: 12px 0 4px;
}
/* Caption under terminal */
.terminal-caption {
font-family: var(--mono);
font-size: 10px;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--ink-faint);
margin-top: 14px;
display: flex;
align-items: center;
gap: 14px;
}
.terminal-caption::before {
content: '⟶';
color: var(--accent);
font-size: 14px;
}
/* ═════════════════════════════════════════════════════════
COLOPHON
═════════════════════════════════════════════════════════ */
.colophon {
position: relative;
z-index: 5;
border-top: 1px solid var(--ink);
margin-top: 60px;
padding: 80px 56px 48px;
max-width: 1240px;
margin-left: auto;
margin-right: auto;
}
.colophon-grid {
display: grid;
grid-template-columns: 200px 1fr;
gap: 64px;
}
.colophon h4 {
font-family: var(--mono);
font-size: 10.5px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--accent);
margin-bottom: 28px;
}
.colophon .credit {
font-family: var(--serif-body);
font-size: 16.5px;
line-height: 1.75;
color: var(--ink-soft);
font-style: italic;
max-width: 62ch;
}
.colophon .credit p { margin-bottom: 18px; }
.colophon .credit p:last-child { margin-bottom: 0; }
.colophon .credit strong {
color: var(--ink);
font-style: normal;
font-weight: 500;
font-variant-caps: all-small-caps;
letter-spacing: 0.06em;
}
.footer-mark {
text-align: center;
padding: 32px 24px 80px;
font-family: var(--serif-display);
font-variation-settings: "opsz" 144, "SOFT" 100;
font-size: 38px;
font-style: italic;
color: var(--accent);
position: relative;
z-index: 5;
}
/* ═════════════════════════════════════════════════════════
ANIMATIONS
═════════════════════════════════════════════════════════ */
@keyframes fadeUp {
from { opacity: 0; transform: translateY(22px); }
to { opacity: 1; transform: translateY(0); }
}
.hero .eyebrow { animation: fadeUp 0.9s 0.1s ease-out backwards; }
.hero .vol { animation: fadeUp 0.9s 0.28s ease-out backwards; }
.hero h1 { animation: fadeUp 1.1s 0.42s ease-out backwards; }
.hero .dek { animation: fadeUp 0.9s 0.65s ease-out backwards; }
.hero .byline { animation: fadeUp 0.9s 0.85s ease-out backwards; }
.reveal {
opacity: 0;
transform: translateY(28px);
transition: opacity 1s ease, transform 1s ease;
}
.reveal.in {
opacity: 1;
transform: translateY(0);
}
/* ═════════════════════════════════════════════════════════
RESPONSIVE
═════════════════════════════════════════════════════════ */
@media (max-width: 880px) {
body { font-size: 17px; }
.topbar {
padding: 14px 24px;
flex-direction: column;
gap: 10px;
align-items: flex-start;
font-size: 9.5px;
}
.topbar .meta { gap: 18px; }
.hero { padding: 56px 24px 72px; }
.hero .eyebrow { margin-bottom: 40px; }
.hero .dek { margin-bottom: 48px; }
.hero .byline { gap: 14px; padding-top: 22px; }
.hero .byline span:not(:last-child)::after { margin-left: 14px; }
.article { padding: 0 24px 80px; }
.section {
grid-template-columns: 1fr;
gap: 24px;
margin-bottom: 88px;
}
.section .gutter {
padding-top: 0;
display: flex;
align-items: baseline;
gap: 18px;
}
.gutter .num { font-size: 44px; }
.gutter .label {
border-top: none;
padding-top: 0;
margin-top: 0;
border-left: 1px solid var(--rule);
padding-left: 14px;
}
.gate-grid { grid-template-columns: 1fr; }
.gate { padding: 32px 24px 28px; }
.terminal-body { font-size: 11.5px; padding: 22px 20px; max-height: 560px; }
.terminal-header { padding: 12px 20px; font-size: 9px; }
.pullquote {
margin: 48px 0 48px 0;
padding-left: 28px;
font-size: 26px;
}
.pullquote::before { margin-left: -28px; width: 24px; }
.colophon { padding: 60px 24px 40px; }
.colophon-grid { grid-template-columns: 1fr; gap: 24px; }
.rule-item { grid-template-columns: 50px 1fr; gap: 18px; padding: 28px 0; }
.rule-item .marker { font-size: 38px; }
.rule-item h3 { font-size: 24px; }
}
</style>
</head>
<body>
<header class="topbar">
<div class="mark">
<div class="mark-glyph">F</div>
<span>Field Manual <span style="color: var(--accent)"></span> 01</span>
</div>
<div class="meta">
<span>Craft Series</span>
<span class="dot">·</span>
<span>Volume I</span>
<span class="dot">·</span>
<span>2026</span>
</div>
</header>
<section class="hero">
<div class="eyebrow">A Manual for Long Sessions</div>
<div class="vol">Volume I</div>
<h1>The discipline of<br>collaborating with<br>an agent that <em>forgets.</em></h1>
<p class="dek">A field manual for engineers shipping real software with Claude Code across many sessions, distilled from one project's working practice into the rules that should exist on every project.</p>
<div class="byline">
<span>Authored 2026 · 04 · 08</span>
<span>Drawn from the Trellis project</span>
<span>Twelve minute read</span>
</div>
</section>
<main class="article">
<article class="section reveal">
<div class="gutter">
<div class="num">I</div>
<span class="label">The Premise</span>
</div>
<div class="body">
<h2>Every conversation begins with no memory of the prior one.</h2>
<p class="lede">Each new session, the agent loads what it can — the project's <span class="sc">claude.md</span>, the memory index, your first message — and that is the entirety of its context. Yesterday's debugging path, the false trail you ruled out, the reason you chose approach A over approach B: none of it survives unless it was written somewhere the next session will read.</p>
<p>Most engineering tools assume continuity. Claude Code does not. The first time this catches you out, you spend an hour re-explaining the project. The tenth time, you start to suspect there is a discipline you are missing. There is. This manual describes it.</p>
<p>The question, once you accept the premise, is simple: <em>what do you encode, and where?</em> There are two slots, and they answer different questions.</p>
<p><strong>Memory files</strong> hold the durable knowledge of a project — its architecture, its conventions, the gotchas you've burned hours discovering, the workflow rules you want to apply session after session. They are written once and consulted forever. They should be true on the timescale of the project itself, not on the timescale of any one task.</p>
<p><strong>The handoff prompt</strong> holds the working set — where you left off this afternoon, what is in flight, what the next session should propose first. It is written at the end of every working session and consumed at the start of the next one. It has a known shelf life of exactly one session.</p>
<p>Together they form a protocol between past-you and future-you, with the agent as the courier. Get this protocol right and the agent is a long-running collaborator. Get it wrong and you have an expensive autocomplete.</p>
</div>
</article>
<article class="section reveal">
<div class="gutter">
<div class="num">II</div>
<span class="label">The Six Universal Gates</span>
</div>
<div class="body">
<h2>Six checkpoints that should exist on every serious project.</h2>
<p>The rules below are <em>gates</em> — moments where the agent stops and verifies before proceeding. They are not optional politeness; they are the difference between a session that ships and a session that introduces the bug it was supposed to fix. Six are universal. The rest grow on top, project by project, and earn their keep through incident.</p>
<div class="gate-intro">The Gates</div>
<div class="gate-grid">
<div class="gate">
<span class="gate-num">01 / VI</span>
<span class="gate-key">GATE(session-start)</span>
<h3>Verify against reality, before acting.</h3>
<p>Read the memory index. Read the feature inventory. Run <span class="sc">git status</span>, <span class="sc">git log</span>, hardware and service checks. Memory is a point-in-time snapshot; trust the live state. Every claim from the previous session is a hypothesis until verified.</p>
</div>
<div class="gate">
<span class="gate-num">02 / VI</span>
<span class="gate-key">GATE(pre-commit)</span>
<h3>Scan, compile, review — every time.</h3>
<p>Secret scan the diff. Confirm every language touched still compiles. Review staged files for unexpected additions: <span class="sc">.env</span>, credentials, build artifacts. Never bypass hooks unless explicitly authorized. The cost of one bad commit lasts forever in git history.</p>
</div>
<div class="gate">
<span class="gate-num">03 / VI</span>
<span class="gate-key">GATE(self-audit)</span>
<h3>Audit, fix, re-audit until clean.</h3>
<p>One pass is never enough. The first audit catches eighty percent of issues; the re-audit catches the bugs introduced by the fix. Do not declare a feature done after the first sweep. Done is what survives the second one.</p>
</div>
<div class="gate">
<span class="gate-num">04 / VI</span>
<span class="gate-key">GATE(post-work)</span>
<h3>Update the record before saying done.</h3>
<p>Update the feature inventory. Update memory files for any new architectural decision or workflow change. Verify the push landed. Report what was done. Memory drift is worse than no memory — it actively misleads future sessions.</p>
</div>
<div class="gate">
<span class="gate-num">05 / VI</span>
<span class="gate-key">GATE(push-verify)</span>
<h3>Local and remote must agree.</h3>
<p>After every push: confirm the push succeeded, the working tree is clean, tags are pushed if releasing, version strings agree across every manifest, CI is not broken. Asymmetry between local and remote is where releases break.</p>
</div>
<div class="gate">
<span class="gate-num">06 / VI</span>
<span class="gate-key">GATE(session-handoff)</span>
<h3>End every session with a kickoff prompt.</h3>
<p>A fenced code block the next session can paste verbatim, containing the gate checks, last-session summary, workflow rules, candidates for what to do next, and known follow-ups. This is the bridge across the no-shared-memory gap. Without it, every session starts from scratch.</p>
</div>
</div>
</div>
</article>
<article class="section reveal">
<div class="gutter">
<div class="num">III</div>
<span class="label">Three Standing Rules</span>
</div>
<div class="body">
<h2>Three rules that aren't gates, but should exist on every project.</h2>
<p>Where the gates above are checkpoints, these are <em>standing dispositions</em> — reflexes you want the agent to have, encoded as feedback memories so they survive across sessions and do not require re-prompting.</p>
<div class="rules-list">
<div class="rule-item">
<div class="marker"></div>
<div>
<h3>One task at a time.</h3>
<p>Sequential, not batched. Finish before proposing the next. For any task that needs manual user action — account creation, token paste, hardware connection, third-party UI clicks — give a numbered step list and wait for confirmation. Multi-task batches collapse under their own weight; sequential work clarifies thinking on both sides of the conversation.</p>
</div>
</div>
<div class="rule-item">
<div class="marker"></div>
<div>
<h3>Do not add unrequested complexity.</h3>
<p>No speculative abstractions. No backward-compatibility shims for code that has no users yet. No helper utilities for one-time operations. Match the scope of changes to what was asked. Three similar lines of code are better than a premature abstraction designed for a future that will not arrive.</p>
</div>
</div>
<div class="rule-item">
<div class="marker"></div>
<div>
<h3>Confirm risky actions first.</h3>
<p>Destructive operations, force-pushes, anything visible to others, anything affecting shared state — pause and ask before doing. Authorization for one action does not transfer to other actions. The cost of a confirmation is small; the cost of an unwanted force-push is catastrophic and asymmetric.</p>
</div>
</div>
</div>
<div class="pullquote">
Anything that should survive amnesia goes in memory. Anything that bridges between sessions goes in the handoff.
</div>
</div>
</article>
<article class="section reveal">
<div class="gutter">
<div class="num">IV</div>
<span class="label">The Starter Prompt</span>
</div>
<div class="body">
<h2>What to paste on day one of a new project.</h2>
<p>Treat this as session zero. The agent reads it, sets up the memory system and the standing rules, then waits for the first real task. Adapt the bracketed placeholders to your project; everything else is the universal core. Copy the block below.</p>
<div class="terminal">
<div class="terminal-header">
<div class="term-title">Starter Prompt — Session Zero</div>
<button class="copy-btn" onclick="copyPrompt(this)">Copy to clipboard</button>
</div>
<div class="terminal-body" id="starter-prompt"><span class="c">// Paste this into a fresh Claude Code session at the start of a new project</span>
This is the kickoff session for <span class="a">&lt;PROJECT NAME&gt;</span>, a <span class="a">&lt;one-line description&gt;</span>.
We'll be working on this across many sessions over weeks or months. I want
you to build up a memory system and workflow discipline from the start so
that future sessions can pick up where we left off without floundering.
<span class="div">── Memory system structure ──────────────────────────────</span>
Set up the following memory files in your auto-memory directory.
Use four memory file types, each with frontmatter:
---
name: &lt;short title&gt;
description: &lt;one-line description&gt;
type: user | feedback | project | reference
---
MEMORY.md is an INDEX only — one line per file, never put memory content
directly in MEMORY.md.
<span class="div">── GATE rules (save as feedback memories) ───────────────</span>
<span class="k">1. feedback_session_start.md</span> — At session start: read MEMORY.md, read
FEATURES.md (when it exists), run git status + git log --oneline -10,
verify any dependent services are in expected state. Don't assume
memory is current; verify against reality before acting.
<span class="k">2. feedback_precommit.md</span> — Before every commit: secret scan the diff
(grep for password/secret/token/api_key), verify builds compile,
review staged files for unexpected additions, never use --no-verify.
<span class="k">3. feedback_selfaudit.md</span> — After implementing a feature: audit, fix,
RE-AUDIT until zero issues. Compile, lint, edge cases, end-to-end.
Don't declare done after the first pass.
<span class="k">4. feedback_postwork.md</span> — Before saying "done" or ending a session:
update FEATURES.md, update memory files for any new architectural
decisions or workflow rules, verify the push landed, report what
was done.
<span class="k">5. feedback_push_verify.md</span> — After git push: verify push succeeded,
working tree clean, tags pushed if releasing, version strings
consistent across all version files.
<span class="k">6. feedback_session_handoff.md</span> — At session end: produce a fenced code
block kickoff prompt for the next session containing GATE checks,
last-session summary, workflow rules, "next up" candidates, and
known follow-ups. Single-pass output: write status summary FIRST,
then exactly ONE fenced block, then stop.
<span class="k">7. feedback_workflow_one_by_one.md</span> — Tackle tasks one at a time. Finish
before proposing next. Get my approval before starting. Numbered
step-by-step lists for any manual user action.
<span class="div">── Project state files ───────────────────────────────────</span>
<span class="k">8. project_overview.md</span> — Current status, version, what's implemented,
tech stack, project structure. Update on every meaningful milestone.
<span class="k">9. FEATURES.md</span> (in the repo root, not in memory) — Single source of
truth for what's done and what's not. Checkbox list. Updated as
features land.
<span class="div">── Workflow rules to honor from this point forward ──────</span>
<span class="h">·</span> Confirm risky actions first (destructive ops, force-pushes,
anything affecting shared state)
<span class="h">·</span> Don't add unrequested complexity (no speculative abstractions,
no backward-compat shims)
<span class="h">·</span> Use Plan mode for non-trivial implementations to align on approach
before writing code
<span class="h">·</span> When you discover a project-specific gotcha (a non-obvious thing
that bit you), save it as a feedback memory immediately so future
sessions don't hit it
<span class="h">·</span> When you make an architectural decision, save the WHY in a project
memory, not just the what
<span class="div">── Domain-specific rules (fill in your own) ─────────────</span>
<span class="a">&lt;e.g., "Real device hardware testing required before any tagged release"&gt;</span>
<span class="a">&lt;e.g., "Releases ship to N distribution channels: A, B, C"&gt;</span>
<span class="a">&lt;e.g., "Test database is NEVER mocked in integration tests"&gt;</span>
<span class="div">── Bootstrapping ─────────────────────────────────────────</span>
After you've set the memory system up:
<span class="k">1.</span> Tell me exactly what files you created (list them).
<span class="k">2.</span> Ask me about anything project-specific you need to write the first
project_overview.md and user_&lt;myname&gt;.md.
<span class="k">3.</span> Confirm by reading back to me: the GATE list, the standing rules,
and one sentence about what you understand the project to be.
<span class="k">4.</span> STOP and wait for me to give the first real task.
Don't write any product code yet.
Today's first task: <span class="a">&lt;one-line description of what you want to build first&gt;</span>.
Don't auto-pick the next task after finishing — propose one with clear
scope, get my approval, then start.</div>
</div>
<div class="terminal-caption">Session zero. Adapt the bracketed placeholders. Everything else is universal.</div>
</div>
</article>
<article class="section reveal">
<div class="gutter">
<div class="num">V</div>
<span class="label">How Memory Grows</span>
</div>
<div class="body">
<h2>You cannot write the full rule set on day one.</h2>
<p>Because you do not yet know what is going to bite you. The memory system grows organically, in two ways, and the trick is to recognize the moments when accretion is happening.</p>
<p><strong>From corrections.</strong> Every time you tell the agent <em>"no, don't do that"</em> or <em>"stop doing X"</em> — that is a feedback memory waiting to be saved. One project I work on has a rule against launching the development binary with the user's active display, because doing so once put a window onscreen and clobbered the running production app. One incident, one rule, never again.</p>
<p><strong>From validations.</strong> Every time you tell the agent <em>"yes, that was the right call"</em> on a non-obvious choice — that is also a feedback memory. These are quieter, easier to miss, and equally important. Without them, the agent drifts away from approaches you have already approved, and you end up re-litigating decisions weekly.</p>
<p>Project memories accumulate similarly. You do not write them up front. You write them when you make an architectural decision worth not re-litigating in the next session. The trigger is simple: <em>this should not need to be discovered twice.</em></p>
</div>
</article>
<article class="section reveal">
<div class="gutter">
<div class="num">VI</div>
<span class="label">Universal vs Specific</span>
</div>
<div class="body">
<h2>What belongs in the starter prompt, and what does not.</h2>
<p>The rules in this manual are <em>universal</em>. They should exist on every project where Claude Code does multi-session engineering work, regardless of language, framework, or domain.</p>
<p>Some rules are not universal and should not be in the starter prompt. A hardware-test gate only matters if you have hardware in the loop. A multi-endpoint release flow only matters if you ship to multiple distribution channels. A polish-pass discipline only matters if you want a deliberate "feature complete" pass over each shipped feature. A library-version-lockstep rule only matters if you publish a library.</p>
<p>These belong in the memory system once the project grows into needing them — not before. The starter prompt is scaffolding; the project-specific rules are the building. Trying to write them up front produces a generic checklist that nobody follows; letting them accrete from real incident produces a memory system that the agent and the engineer both trust.</p>
</div>
</article>
<article class="section reveal">
<div class="gutter">
<div class="num">VII</div>
<span class="label">The Deeper Principle</span>
</div>
<div class="body">
<h2>Treat the agent as a long-running collaborator that has amnesia.</h2>
<p>The discipline that makes any of this work is not any single rule. It is the meta-discipline of internalizing one fact and letting it shape everything else: <em>the agent has amnesia, and it is your job to bridge the gap.</em></p>
<p>Once that fact is fully internalized — really internalized, not just nodded at — the rules write themselves. Anything that should survive amnesia goes in memory. Anything that bridges between sessions goes in the handoff. Anything that is a reflex you want the agent to have goes in a feedback memory. Anything that is true today and false next week goes nowhere; let it stay in the conversation and die there.</p>
<p>The project this manual is drawn from has roughly thirty memory files now. On day one it had zero. Each one was earned by an incident — a bug shipped, a correction given, a validation made explicit, an architectural decision worth not re-explaining. That accretion is the actual product. The starter prompt above is just enough scaffolding to make the accretion happen.</p>
<p>If the discipline feels heavy at first, that is because it is replacing something that used to be free: the assumption that your tools remember you. They do not. But once you start writing the memory yourself, the agent starts to feel less like a chatbot and more like the long-running engineering collaborator you wanted in the first place.</p>
</div>
</article>
</main>
<section class="colophon">
<div class="colophon-grid">
<h4>Colophon</h4>
<div class="credit">
<p>Set in <strong>Fraunces</strong> by Phaedra Charles, Friedrich Althausen, and the Undercase Type collective; <strong>Newsreader</strong> by Production Type for Google Fonts; and <strong>JetBrains Mono</strong> by Philipp Nurullin and Konstantin Bulenkov. Display sizes use Fraunces with the optical-size axis pushed to 144 and the soft axis tuned for warmth.</p>
<p>Authored by <strong>Claude Opus 4.6</strong> in conversation with <strong>Ovidiu</strong> on 2026 · 04 · 08, during the v0.4.3 release of <strong>Trellis</strong> — an open-source desktop control center and Arduino library for ESP32 and Pico W devices. The working practice this manual describes was forged across roughly thirty Claude Code sessions of building Trellis from nothing to a published, hardware-validated, three-endpoint release.</p>
<p>Written for other engineers who build with Claude Code and have started to feel the shape of this discipline forming under them. Reproduce, adapt, and improve as you see fit.</p>
</div>
</div>
</section>
<div class="footer-mark"></div>
<script>
// Copy starter prompt
function copyPrompt(btn) {
const promptEl = document.getElementById('starter-prompt');
// Get plain text without HTML markup
const text = promptEl.innerText;
navigator.clipboard.writeText(text).then(() => {
btn.textContent = '✓ Copied';
btn.classList.add('copied');
setTimeout(() => {
btn.textContent = 'Copy to clipboard';
btn.classList.remove('copied');
}, 2200);
}).catch(() => {
btn.textContent = 'Copy failed';
setTimeout(() => {
btn.textContent = 'Copy to clipboard';
}, 2200);
});
}
// Reveal sections on scroll
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('in');
observer.unobserve(entry.target);
}
});
}, { threshold: 0.12, rootMargin: '0px 0px -60px 0px' });
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
</script>
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v8c78df7c7c0f484497ecbca7046644da1771523124516" integrity="sha512-8DS7rgIrAmghBFwoOTujcf6D9rXvH8xm8JQ1Ja01h9QX8EzXldiszufYa4IFfKdLUKTTrnSFXLDkUEOTrZQ8Qg==" data-cf-beacon='{"version":"2024.11.0","token":"5070e21320304a1ba2b0a42ce9682840","server_timing":{"name":{"cfCacheStatus":true,"cfEdge":true,"cfExtPri":true,"cfL4":true,"cfOrigin":true,"cfSpeedBrain":true},"location_startswith":null}}' crossorigin="anonymous"></script>
</body>
</html>