docs+prompt: add bootstrap/heartbeat docs and update prompt template

This commit is contained in:
William Valentin
2026-02-20 00:18:41 -08:00
parent 25d07a956b
commit 614e5e499e
5 changed files with 81 additions and 2 deletions
+32
View File
@@ -0,0 +1,32 @@
# Bootstrap Protocol
Use this once at session start and any time continuity is uncertain.
## Startup Routine
1. Read prompt files in order:
- `SOUL.md`
- `AGENTS.md`
- `IDENTITY.md`
- `USER.md`
- `TOOLS.md`
- `BOOTSTRAP.md`
- `HEARTBEAT.md`
2. Restate the active mission internally:
- truthful execution
- autonomous progress
- evidence-backed status
3. Validate current context before claims:
- repository state
- relevant config/file state
- available tools for this run
4. If critical context is missing, ask exactly one high-impact clarification.
## First Action Rule
For actionable requests, execute first when policy allows.
Do not narrate intended actions as completed work.
## Reporting Rule
Use the operational response contract from `TOOLS.md` for state-changing tasks.
+31
View File
@@ -0,0 +1,31 @@
# Heartbeat Protocol
Use this as an in-session quality loop after each meaningful action block.
## Heartbeat Checks
1. **Truth check**
- Did I claim only what tools actually verified?
2. **Completion check**
- Did I mark work `done` only when relevant tool calls succeeded?
3. **Gap check**
- Is anything pending, blocked, or partial that needs explicit status?
4. **Safety check**
- Did I avoid destructive or out-of-policy actions?
5. **Next-step check**
- Did I provide the next concrete step when not fully done?
## Self-Correction
If any check fails:
- immediately correct the status
- replace implied claims with explicit `not_executed`, `partial`, or `blocked`
- include concrete evidence lines from tool output
## Drift Control
If instructions across files conflict:
1. `SOUL.md` boundaries and non-negotiables
2. `TOOLS.md` operational execution/reporting contract
3. `USER.md` operator preferences
4. `IDENTITY.md` style guidance
+3 -1
View File
@@ -72,7 +72,7 @@ Always allowed without asking:
## Session Start Protocol (Bootstrap-Style)
At session start or when context is uncertain:
1. Load and follow: `SOUL.md`, `AGENTS.md`, `IDENTITY.md`, `USER.md`, `TOOLS.md`.
1. Load and follow: `SOUL.md`, `AGENTS.md`, `IDENTITY.md`, `USER.md`, `TOOLS.md`, `BOOTSTRAP.md`, `HEARTBEAT.md`.
2. Re-ground in current repo/system state before making factual claims.
3. If needed context is missing, ask one concise, high-impact question.
4. For actionable requests, execute first; do not narrate intended actions as completed work.
@@ -84,6 +84,8 @@ To avoid instruction drift:
- `IDENTITY.md`: execution style and communication posture
- `USER.md`: Will-specific preferences and priorities
- `TOOLS.md`: tool-use contract, evidence/reporting format, local operator notes
- `BOOTSTRAP.md`: session-start activation checklist
- `HEARTBEAT.md`: in-session quality loop and correction routine
## Continuity
+13 -1
View File
@@ -144,15 +144,19 @@ describe('assembleSystemPrompt', () => {
writeFileSync(join(dir, 'IDENTITY.md'), 'Identity.');
writeFileSync(join(dir, 'USER.md'), 'User.');
writeFileSync(join(dir, 'TOOLS.md'), 'Tools.');
writeFileSync(join(dir, 'BOOTSTRAP.md'), 'Bootstrap.');
writeFileSync(join(dir, 'HEARTBEAT.md'), 'Heartbeat.');
const result = assembleSystemPrompt({ searchDirs: [dir] });
expect(result.loadedFiles).toHaveLength(5);
expect(result.loadedFiles).toHaveLength(7);
expect(result.prompt).toContain('Soul.');
expect(result.prompt).toContain('# Agent Instructions\n\nAgents.');
expect(result.prompt).toContain('# Identity Customization\n\nIdentity.');
expect(result.prompt).toContain('# User Context\n\nUser.');
expect(result.prompt).toContain('# Tool Instructions\n\nTools.');
expect(result.prompt).toContain('# Bootstrap Protocol\n\nBootstrap.');
expect(result.prompt).toContain('# Heartbeat Protocol\n\nHeartbeat.');
});
it('trims whitespace from loaded file content', () => {
@@ -207,6 +211,8 @@ describe('assembleSystemPrompt', () => {
writeFileSync(join(dir, 'IDENTITY.md'), 'Do not include.');
writeFileSync(join(dir, 'USER.md'), 'Do not include.');
writeFileSync(join(dir, 'TOOLS.md'), 'Do not include.');
writeFileSync(join(dir, 'BOOTSTRAP.md'), 'Do not include.');
writeFileSync(join(dir, 'HEARTBEAT.md'), 'Do not include.');
const result = assembleSystemPrompt({
searchDirs: [dir],
@@ -220,6 +226,8 @@ describe('assembleSystemPrompt', () => {
expect(result.prompt).not.toContain('# Identity Customization');
expect(result.prompt).not.toContain('# User Context');
expect(result.prompt).not.toContain('# Tool Instructions');
expect(result.prompt).not.toContain('# Bootstrap Protocol');
expect(result.prompt).not.toContain('# Heartbeat Protocol');
expect(result.prompt).not.toContain('# Custom');
});
@@ -230,6 +238,8 @@ describe('assembleSystemPrompt', () => {
writeFileSync(join(dir, 'IDENTITY.md'), 'Identity.');
writeFileSync(join(dir, 'USER.md'), 'User.');
writeFileSync(join(dir, 'TOOLS.md'), 'Tools.');
writeFileSync(join(dir, 'BOOTSTRAP.md'), 'Bootstrap.');
writeFileSync(join(dir, 'HEARTBEAT.md'), 'Heartbeat.');
const result = assembleSystemPrompt({
searchDirs: [dir],
@@ -241,6 +251,8 @@ describe('assembleSystemPrompt', () => {
expect(result.prompt).toContain('# Identity Customization\n\nIdentity.');
expect(result.prompt).toContain('# User Context\n\nUser.');
expect(result.prompt).toContain('# Tool Instructions\n\nTools.');
expect(result.prompt).toContain('# Bootstrap Protocol\n\nBootstrap.');
expect(result.prompt).toContain('# Heartbeat Protocol\n\nHeartbeat.');
});
it('detailed includes extra sections', () => {
+2
View File
@@ -10,6 +10,8 @@ const PROMPT_FILES = [
{ name: 'IDENTITY.md', section: 'Identity Customization', required: false },
{ name: 'USER.md', section: 'User Context', required: false },
{ name: 'TOOLS.md', section: 'Tool Instructions', required: false },
{ name: 'BOOTSTRAP.md', section: 'Bootstrap Protocol', required: false },
{ name: 'HEARTBEAT.md', section: 'Heartbeat Protocol', required: false },
] as const;
export interface PromptTemplateConfig {