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
10 changes: 7 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Purpose

3Notch is a local-first CLI and MCP server for moving project context across boundaries that built-in AI tooling cannot cross — across repos, across AI work surfaces, web chats, and into new projects. V3 is the current shipped surface: packet transfer with artifact bundles, private context seeding, targeted briefs, self-addressed marks, typed packet replies, web-chat stdin intake, relationship indexing, deterministic corpus checks, and `.notchpkt` pack/unpack for cross-machine transport. Supporting commands: `onboard`, `status`, `doctor`, `mcp serve`.
3Notch is a local-first CLI and MCP server for automated agentic workflows: agents save and resume working state without a human in the loop, and they move selected context across repos, AI work surfaces, web chats, and new projects. V3 remains the packet-transfer surface. Same-repo continuity is in scope: wrap-up is `notch save`, session start is `notch resume`. Cross-boundary packets stay; they are not the only loop. Supporting commands: `onboard`, `status`, `doctor`, `mcp serve`.

## Read First

Expand Down Expand Up @@ -32,6 +32,8 @@ During an active implementation run, append concise progress entries to the acti

CLI commands:
- `notch onboard`
- `notch save`
- `notch resume`
- `notch mark`
- `notch reply <id>`
- `notch brief`, `notch brief create`, `notch brief list`, `notch brief show <id>`
Expand All @@ -50,14 +52,15 @@ CLI commands:
MCP tools:
- `get_brief`, `create_brief`, `list_briefs`, `get_targeted_brief`
- `create_packet`, `import_packet`, `list_packets`, `get_packet`
- `save_working_state`, `resume_working_state`
- `create_seed_packet`, `import_seed_packet`
- `create_mark`, `create_reply`, `check_store`
- `get_status`, `run_doctor`
- `inbox_init`, `send_packet`, `list_inbox`, `pull_inbox_packet`, `ack_inbox_delivery`

## Deferred (do not implement)

These are deliberately out of scope. Same-repo same-tool continuity is solved by CLAUDE.md, native tool memory, and `git commit`. 3Notch's wedge is cross-boundary transport.
These are deliberately out of scope. Cross-boundary packets stay; they are not the only loop. Same-repo agent save/resume is in scope — do not defer it to git or CLAUDE.md.

- `notch pass`, MCP `create_pass`/`get_latest_pass`/`get_recent_passes`
- `notch decision *`, MCP `record_decision`/`get_decisions`
Expand All @@ -70,7 +73,8 @@ A regression-guard test (`tests/unit/no-deferred-commands.test.ts`) prevents acc
## Boundaries

- When the user presents a product idea or asks "is this the right path?", discuss and pressure-test it before changing specs, plans, or repo files.
- Treat cross-repo packets, cross-tool handoff, and private context seeding as the core product loops.
- Treat same-repo agent save/resume, cross-repo packets, cross-tool handoff, and private context seeding as the core product loops.
- Wrap-up is `notch save`; session start is `notch resume`. Do not ask a human to confirm loading a continuation in the happy path. Codex, Grok, and Cursor should run those two commands. Do not invent a daemon.
- No telemetry, cloud sync, hosted service, dashboard, vector database, or SQLite/native DB.
- Durable inbox remains a dependency-free local filesystem spool. Do not turn it into chat, a daemon, hosted identity, background sync, or model invocation.
- Do not build hidden chat or project scraping. MCP tools write selected or summarized context the user or agent explicitly supplies during a session.
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

## [Unreleased]

### Added
- `notch save` / `notch resume` and MCP `save_working_state` / `resume_working_state` persist and load working state for agentic loops without a human confirm step.
- Claude Code SessionStart injects the latest continuation body into `additionalContext`.

### Changed
- Same-repo continuity is in scope. Wrap-up is `notch save`; session start is `notch resume`.

## [0.7.2] - 2026-08-11

### Changed
Expand Down
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,18 @@ Agent prompt (optional):

## Common flows

### Resume after a failed session
### Save and resume working state

With [continuation checkpoints](docs/guides/continuation-checkpoints.md) enabled for Claude Code, 3Notch can write a fallback from task state and git when the session hits a rate limit, model-down failure, or compaction. The next session may offer that checkpoint once; you approve before it is loaded.
Wrap-up: `notch save`. Session start: `notch resume`. No confirmation prompt. Codex, Grok, and Cursor should run those two commands; there is no 3Notch daemon.

```bash
notch packet list
notch packet preview <id>
notch save --summary "Auth validation done" --next-steps "Implement session store"
notch resume
notch resume --json
```

Claude Code SessionStart injects the latest checkpoint body so the next agent can continue without calling `get_packet` after a human yes. Private packets stay hidden unless you pass `--include-private`. See [Continuation checkpoints](docs/guides/continuation-checkpoints.md).

### Hand off between tools

```bash
Expand Down Expand Up @@ -133,6 +136,8 @@ Targeting fields (`--to-agent`, `--to-repo`) are intent metadata. Bytes move via

```text
notch onboard initialize .notch/ and MCP setup
notch save write a continuation from git snapshot + summary
notch resume print the latest continuation (no prompt)
notch packet create create a packet (--file, --ref, --next-steps)
notch packet import <path> import into .notch/inbox/
notch packet preview <id> show what an agent will read
Expand Down Expand Up @@ -160,8 +165,8 @@ notch mcp serve local stdio MCP server

| | Tools |
| --- | --- |
| **Read** | `get_brief`, `list_briefs`, `get_targeted_brief`, `get_packet`, `list_packets`, `list_inbox`, `get_inbox_delivery`, `get_status`, `check_store`, `run_doctor` |
| **Write** | `create_brief`, `create_packet`, `create_mark`, `create_reply`, `create_seed_packet`, `import_packet`, `import_seed_packet`, `inbox_init`, `send_packet`, `pull_inbox_packet`, `ack_inbox_delivery` |
| **Read** | `get_brief`, `list_briefs`, `get_targeted_brief`, `get_packet`, `list_packets`, `resume_working_state`, `list_inbox`, `get_inbox_delivery`, `get_status`, `check_store`, `run_doctor` |
| **Write** | `create_brief`, `create_packet`, `save_working_state`, `create_mark`, `create_reply`, `create_seed_packet`, `import_packet`, `import_seed_packet`, `inbox_init`, `send_packet`, `pull_inbox_packet`, `ack_inbox_delivery` |

Private records under `.notch/private/` stay hidden unless the server starts with `--include-private`. Client setup: [docs/guides/mcp-setup.md](docs/guides/mcp-setup.md).

Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Task-shaped how-tos for the main flows.
- [Private context seeding](guides/private-context-seeding.md) — carrying reviewed preferences into a new repo.
- [Targeted brief workflow](guides/targeted-brief-workflow.md) — scoped task briefs vs cross-boundary packets.
- [MCP setup](guides/mcp-setup.md) — server flags, available tools, agent instruction packs.
- [Continuation checkpoints](guides/continuation-checkpoints.md) — opt-in Claude task aggregation, compaction fallback, model-down StopFailure recovery, and resume confirmation.
- [Continuation checkpoints](guides/continuation-checkpoints.md) — `notch save` / `notch resume`, opt-in Claude task aggregation, compaction fallback, and model-down StopFailure recovery.
- [Release](guides/release.md) — maintainer version surfaces, publish recipe, and release-check.

## Reference
Expand Down
4 changes: 4 additions & 0 deletions docs/active-plans/v4/v4-implementation-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
- Final review hardened malformed-input handling, Stop removal, per-stream state isolation, concurrent checkpoint serialization and IDs, long branch names, high-volume predecessor lookup, ignored local settings/backups, task-description preservation, and private MCP resume access.
- Verification passed: lint, type-check, build, 194 unit/integration tests, 20 e2e tests, built-CLI help/version/hook smoke, a packed tarball installation exercising onboarding plus real task/post-compaction stdin events, zero installed-package audit findings, and Claude Code `doctor` against the generated project configuration.

## 2026-09-06

- **Issue #18:** `notch save` / `notch resume` and MCP `save_working_state` / `resume_working_state`. SessionStart injects the checkpoint body. No confirm prompt on the happy path. Same-repo continuity is in scope.

## 2026-08-09

- **PR #14 (0.7.1):** widened default StopFailure matcher and runtime gate to recoverable model-down errors: `rate_limit|overloaded|server_error|max_output_tokens|unknown`. Auth/billing failures still excluded. Legacy `rate_limit`-only matchers rewritten on onboard resync. Source tags avoid secret-scanner false positives (`max-output` not `max-output-tokens` in titles).
Expand Down
25 changes: 22 additions & 3 deletions docs/guides/continuation-checkpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,25 @@

Continuation checkpoints preserve enough selected project state to resume after a rate limit, context compaction, or an intentional agent switch. They are ordinary immutable packets, not transcripts or hidden memory.

## Agent save and resume

Wrap-up:

```bash
notch save --summary "Auth validation done" --next-steps "Implement session store"
```

Session start:

```bash
notch resume
notch resume --json
```

No confirmation prompt. Empty store is a quiet success; `--json` returns `"checkpoint": null`. Codex, Grok, and Cursor should run those two commands. There is no 3Notch daemon. Claude Code SessionStart puts the latest checkpoint body in `additionalContext` so the next agent continues without calling `get_packet` after a human yes.

`--summary` and `--next-steps` are optional (stdin is accepted). Secret scan still blocks dirty writes. Private packets stay hidden from `notch resume` and MCP `resume_working_state` unless `--include-private` is set.

## Enable Claude Code Checkpoints

```bash
Expand Down Expand Up @@ -49,17 +68,17 @@ The default triggers are a meaningful milestone, an intentional agent/model swit

## Streams and Resume

The stream is the configured override, current Git branch, detached commit, or `default` for a non-Git project. Continuations use tags such as `continuation`, `stream-feature-auth`, and `source-post-compact`.
The stream is the configured override, current Git branch, detached commit, or `default` for a non-Git project. Continuations use tags such as `continuation`, `stream-feature-auth`, and `source-save` or `source-post-compact`.

At the next session start, 3Notch offers the latest matching checkpoint once. It supplies only packet metadata. Claude must not call `get_packet` or load the packet body until you confirm.
`notch save` / `save_working_state` write a continuation tagged for the current stream and supersede the latest same-stream checkpoint. `notch resume` / `resume_working_state` print the latest continuation for this store. Claude Code SessionStart injects that body automatically.

## Privacy Boundary

- Hook scripts never open `transcript_path`.
- Onboarding adds `.claude/settings.local.json` to the project `.gitignore`; backups are kept under ignored `.notch/index/` state.
- `.notch/index/continuation/` is local derived state and gitignored.
- Project checkpoints land in `.notch/outbox/` and may appear in Git; choose `private` sensitivity to use ignored `.notch/private/outbox/`.
- Private mode intentionally adds `--include-private` to this project's 3Notch MCP server so the agent can list and load a checkpoint after you confirm. That server can read other private packets in the same local store through approved MCP calls.
- Private mode intentionally adds `--include-private` to this project's 3Notch MCP server so `resume_working_state` can return a private checkpoint. That server can read other private packets in the same local store through approved MCP calls.
- A model-down StopFailure fallback cannot recover reasoning that was never reflected in a task, Git state, compact summary, final assistant message, or prior curated checkpoint.
- Existing projects with a legacy `StopFailure` matcher of only `rate_limit` should rerun `notch onboard --yes --mcp claude-code --checkpoints <mode>` so Claude Code wires the full recoverable matcher.
- 3Notch never commits, pushes, imports, or transports a checkpoint automatically.
3 changes: 2 additions & 1 deletion docs/guides/mcp-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ notch mcp serve --default-actor "Claude Desktop"
Read-only:

- `get_brief`, `list_briefs`, `get_targeted_brief`
- `get_packet`, `list_packets`
- `get_packet`, `list_packets`, `resume_working_state`
- `get_status`, `check_store`, `run_doctor`
- `list_inbox` — list pending or retained durable deliveries
- `get_inbox_delivery` — read pending, pulled, acknowledged, or rejected status for one delivery
Expand All @@ -51,6 +51,7 @@ Write tools (require client tool-permission grant):

- `create_brief`
- `create_packet` (accepts `files`, `refs`, `nextSteps`, `tags`, and `supersedes`)
- `save_working_state` — wrap-up continuation from git snapshot plus optional summary/nextSteps
- `create_mark` — self-addressed private capture
- `create_reply` — typed packet reply
- `create_seed_packet`
Expand Down
6 changes: 4 additions & 2 deletions site/public/docs/guides/continuation-checkpoints/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,10 @@ <h2>What the recovery layer records</h2>
</ul>
<p>Fallbacks include branch, short commit, dirty state, and changed-file names. They do not copy file contents or artifacts automatically.</p>

<h2>Resume safely</h2>
<p>At the next session start, 3Notch offers the latest matching checkpoint once. The agent must not load the packet body until you confirm. Every automatic or agent-authored checkpoint is <code>unreviewed</code> and targets <code>next-agent</code>.</p>
<h2>Agent save and resume</h2>
<pre><code><span class="prompt">$</span> <span class="cmd">notch save</span> <span class="flag">--summary</span> <span class="arg">"Auth validation done"</span> <span class="flag">--next-steps</span> <span class="arg">"Implement session store"</span>
<span class="prompt">$</span> <span class="cmd">notch resume</span></code></pre>
<p>No confirmation prompt. Codex, Grok, and Cursor should run those two commands; there is no 3Notch daemon. Claude Code SessionStart injects the latest checkpoint body so the next agent continues without calling <code>get_packet</code> after a human yes. Private packets stay hidden unless <code>--include-private</code> is set.</p>
<p>Streams resolve from an explicit override, the current Git branch, a detached commit, or <code>default</code>. Each new checkpoint explicitly supersedes the latest checkpoint in that stream.</p>

<h2>Privacy boundary</h2>
Expand Down
2 changes: 1 addition & 1 deletion site/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1249,7 +1249,7 @@ <h2 class="s-title">Common questions<span class="accent">.</span></h2>
<span class="faq-icon" aria-hidden="true">+</span>
</button>
<div class="faq-a">
<p>With Claude Code continuation checkpoints enabled, 3Notch can write a fallback on rate limits, model-down failures (overload, server error, and related cases), and compaction. The next session may offer that checkpoint once; you approve before anything is loaded.</p>
<p>With Claude Code continuation checkpoints enabled, 3Notch writes a fallback on rate limits, model-down failures, and compaction. The next session injects that checkpoint automatically. Private continuations stay hidden unless the store is configured for private sensitivity or you pass --include-private.</p>
</div>
</div>
<div class="faq-item">
Expand Down
3 changes: 2 additions & 1 deletion src/cli/commands/onboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ function defaultConfig(projectName: string, projectRoot: string): NotchConfig {
'send_packet',
'pull_inbox_packet',
'ack_inbox_delivery',
'save_working_state',
],
},
};
Expand Down Expand Up @@ -486,7 +487,7 @@ This project uses 3Notch for explicit, reviewable context handoffs between AI to

## Continuation Checkpoints

Claude Code checkpoints are opt-in through \`notch onboard --mcp claude-code --checkpoints <mode>\`. Script hooks aggregate structured task events and repository state without reading session transcripts. \`prompt\` asks before an agent drafts a semantic checkpoint; \`auto\` drafts it automatically. On resume, 3Notch offers a matching checkpoint but never loads it without user confirmation.
Claude Code checkpoints are opt-in through \`notch onboard --mcp claude-code --checkpoints <mode>\`. Script hooks aggregate structured task events and repository state without reading session transcripts. \`prompt\` asks before an agent drafts a semantic checkpoint; \`auto\` drafts it automatically. On SessionStart, 3Notch injects the latest matching continuation into additionalContext with no human confirm. Private continuations load only when continuation.sensitivity is private (or \`notch resume --include-private\` / MCP \`--include-private\`).

## Boundaries

Expand Down
36 changes: 36 additions & 0 deletions src/cli/commands/resume.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { Command } from 'commander';

import { getCliContext } from '../context.js';
import { printJson } from '../output.js';
import { loadConfig } from '../../core/config-service.js';
import { resumeWorkingState } from '../../core/continuation-service.js';

type ResumeOptions = {
includePrivate?: boolean;
};

export function registerResumeCommand(program: Command): void {
program
.command('resume')
.description('print the latest continuation for this store without prompting')
.option('--include-private', 'include private continuation packets')
.action(async (options: ResumeOptions, command: Command) => {
const context = getCliContext(command);
const loaded = await loadConfig({
...(context.cwd ? { cwd: context.cwd } : {}),
...(context.store ? { store: context.store } : {}),
});
const result = await resumeWorkingState(loaded, {
includePrivate: Boolean(options.includePrivate),
});

if (context.output.json) {
printJson(result);
return;
}

if (result.checkpoint) {
process.stdout.write(`${result.checkpoint.markdown}\n`);
}
});
}
Loading
Loading