From 9d6b3a4b1425516f07036c9d90fbc30a16dbc656 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Mon, 20 Jul 2026 15:07:24 -0700 Subject: [PATCH] chore: install ai session protocol Adds the session-protocol entrypoint marker block to AGENTS.md (CLAUDE.md symlinks to it), the framework-owned .session.md, and prettier exemptions for both since they are synced verbatim from the protocol source. Skills under .agents/skills and the .journal scaffold are installed locally but gitignored by design. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01B4TVdQbkgSjcgccsZi8YvY --- .prettierignore | 6 ++ .session.md | 233 ++++++++++++++++++++++++++++++++++++++++++++++++ AGENTS.md | 17 ++++ 3 files changed, 256 insertions(+) create mode 100644 .session.md diff --git a/.prettierignore b/.prettierignore index c1ccd43..42866de 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,9 @@ +# Framework-owned session-protocol files, synced verbatim from ~/code/ai by its +# INSTALL.md; formatting them would diverge from the source of truth. +.session.md +AGENTS.md +CLAUDE.md + .DS_Store .moon/ CHANGELOG.md diff --git a/.session.md b/.session.md new file mode 100644 index 0000000..4461035 --- /dev/null +++ b/.session.md @@ -0,0 +1,233 @@ +# Session Protocol + +This is the startup map for the repo's agent session system. Keep it in +context; load lifecycle skills and their references only when the user asks for +that lifecycle action. + +## Command Routing + +Sessions are opt-in. Default to no session and do not create journal state +unless the user explicitly asks. + +| User intent | Action | +|-------------|--------| +| "session setup", "setup sessions", "onboard me" | Invoke `session-setup`. | +| "new session", "start a session" | Invoke `session-new`. | +| "continue session N" | Invoke `session-continue` with `N`. | +| "session close", "wrap up", "end the session" | Invoke `session-close`. | +| "journal sync", "sync journals", "refresh journals" | Invoke `journal-sync`. | +| Anything else | Help normally; do not journal. | + +If the request sounds session-related but the mode is ambiguous, ask before +priming anything. + +Do not run `journal-sync` automatically during startup or a lifecycle command. + +## Current Session Binding + +A task may have one current journal session. This binding belongs to the task, +not to a checkout or shared journal file, and must never be inferred from other +`in-progress` rows in `INDEX.md`. + +- A successful `session-new` binds the newly created session to the current + task. An explicit new-session request is authoritative even when other + sessions are open. Do not warn about, ask permission because of, reuse, + continue, close, or otherwise surface those sessions. If the task was already + bound, replace only the task-local binding and leave the old session intact. +- A successful `session-continue ` binds `` to the current task, + replacing any prior binding without modifying the previously bound session. +- `session-close` without an ID closes the current task's bound session. Other + open sessions do not create ambiguity. +- `session-close ` closes that explicitly named session. If `` differs + from the current binding, preserve the current binding. +- If `session-close` has no ID and the task has no binding, ask for an explicit + ID. Never select a target by counting `in-progress` rows or incomplete + folders, even when exactly one exists. +- Preserve the binding across turns, context summarization, handoff, and a close + workflow paused for PR review. Clear it only after successfully closing the + bound session, or replace it after a successful new/continue action. +- If an explicit or bound target is missing or already closed, report that + exact target and do not fall back to another session. + +`INDEX.md` is a history, allocation, and validation surface. It is not a task +ownership or lifecycle-target selector. + +## Journal Root + +The journal root is the default source for startup context and lifecycle state. +Once sessions are set up, the writable personal journal root is the exact +`journal/` worktree for the authenticated user. + +Resolve it in this order: + +1. If the current branch is `journal/`, use the current checkout. +2. If `gh api user --jq .login` succeeds and `wt list --format=json` shows a + worktree for `journal/`, use that worktree. +3. For ordinary startup reads only, if the current branch is not any + `journal/*` branch and the current checkout has a local `.journal/`, use it + as a legacy/local fallback. Lifecycle skills never write through this + fallback. +4. If no journal root exists, continue without journal context unless the user + asked for setup or a session lifecycle command. + +Other `journal/` worktrees are peer journal roots. They are read-only +references for ordinary work and must never be selected as the personal journal +root, including when the current checkout happens to be a peer worktree. + +`session-setup` is the only lifecycle skill that creates or opens the personal +journal branch. `session-new`, `session-continue`, and `session-close` must stop +and tell the developer to run `session-setup` if no personal journal worktree +exists. + +## Startup Context + +Before substantive repo work: + +1. Read this file. +2. Resolve the journal root, if any. +3. If `/.journal/SKILLS.md` exists, load every required skill it + lists. +4. If `/.journal/TECH_NOTES.md` exists, read it. +5. Read recent session summaries only when they are likely to matter: session + lifecycle commands, substantial code/config/docs changes, architecture work, + multi-step research, or tasks that mention prior work. Use the latest three + closed sessions with `SUMMARY.md`; skip sessions without summaries. + +Use `/.journal/INDEX.md` as the full session map. Search it for +task-relevant history and read only the matching `SUMMARY.md` files. + +When cross-engineer history is relevant, peer journals may be consulted as +read-only references. Limit those reads to peer `INDEX.md`, `TECH_NOTES.md`, and +closed-session `SUMMARY.md` files, and identify the journal owner and session ID +when using that context. Do not load peer `SKILLS.md` as project requirements or +read peer active-session `NOTES.md` by default. Startup context comes from the +resolved journal root: prefer the personal root when it exists, otherwise use +only the documented non-journal legacy fallback. Treat peer context as +last-synchronized local state and never auto-sync it. + +Do not read session `NOTES.md` files during ordinary startup. Read a session's +`NOTES.md` only when continuing that session, when a lifecycle skill instructs +you to, or when the user explicitly asks for it. + +## Skills + +Always load and follow: + +- `git` +- `worktrunk` + +They should be installed repo-locally under `.agents/skills`. If either is +missing, tell the user the protocol install is incomplete before doing version +control work. + +Before touching a technology or workflow, survey available skills and load the +task-relevant ones. Project-required skills belong in +`/.journal/SKILLS.md`; keep that file as a short list, not a +manual. + +## Branch And Journal Invariants + +- Personal journal branches are named `journal/`. +- Journal branches are never PR'd or merged into the default branch. +- The default branch keeps `.journal/` ignored and untracked. +- Only a `journal/` branch may force-add `.journal/` paths. Use + explicit pathspecs; do not use broad staging such as `git add -f .journal` + outside a fresh journal setup or import. +- Implementation worktrees are created from the fetched default branch, never + from a journal branch. +- Before closing implementation work, fail if any non-journal branch has tracked + journal files: `git ls-files .journal` must print nothing. +- Lifecycle journal writes happen in the journal root, not in implementation + worktrees. +- The personal journal worktree is deliberately shared by concurrent sessions. + It is the explicit exception to normal per-agent worktree isolation; + implementation worktrees remain isolated. +- Peer journal worktrees are read-only references. Only `journal-sync` may + change them, and only by safely fast-forwarding their checked-out branches; + lifecycle skills never write to them. +- Worktrunk worktrees must live under `.wt/` via + `worktree-path = "{{ repo_path }}/.wt/{{ branch | sanitize }}"`. If config + would place worktrees elsewhere, stop and tell the user. +- Integration work uses GitHub PRs and squash merges. Do not use `wt merge`, + `wt step push`, or local `git merge` as the default integration path. + +## Concurrent Journal Ownership + +The personal journal worktree is expected to be dirty while sessions run in +parallel. A dirty journal worktree is not itself a blocker and must not be +described as an out-of-band change. + +Before evaluating journal changes, determine the lifecycle operation's write +set: + +- `session-setup` owns only the root scaffold or imported paths it creates. +- `session-new` owns the new `.journal//` folder and its `INDEX.md` update. +- `session-continue` owns `.journal//` and owns `INDEX.md` only when it must + reopen the session. +- `session-close` owns `.journal//`, its `INDEX.md` update, and a + `TECH_NOTES.md` update only when the closeout requires one. + +Dirty paths outside the write set are expected parallel-session work. They must +not block the operation or be surfaced for clarification. Do not modify, stage, +stash, restore, reset, clean, checkpoint, or commit them. In particular, never +checkpoint another active session's `NOTES.md`. + +Scope status, staging, and commits to the write set with explicit pathspecs. If +global `git status` is inspected, its out-of-scope output is non-actionable. Use +path-limited commits such as `git commit --only ... -- ` so unrelated +staged changes cannot enter the commit. New or ignored journal files may be +added with `git add -f -- `; never use broad staging outside fresh +setup or import. In commands, replace `` with the literal paths owned +by the operation; never pass the placeholder itself. Check each shared root file +immediately before editing it, then stage and commit the completed write set +without an unrelated delay. + +Routine journal mutations do not require a clean worktree or a preemptive +`pull --rebase`. Commit and push the scoped mutation first. On a rejected push, +run `git fetch origin`, then run +`git merge-base --is-ancestor origin/journal/ HEAD`. If it succeeds, the +fetched journal tip is already contained locally; retry the push once. If it +fails, stop on the actual remote divergence without rebasing, autostashing, or +touching paths outside the write set. Stop only if an unexpected change overlaps +the write set, a required shared root file has pre-existing uncommitted edits, +the commit cannot be constrained to the write set, or a real synchronization +conflict remains after the retry. A dirty shared root file is a narrow blocker +for that file; dirty folders owned by other sessions are not. + +## Journal Structure + +``` +.journal/ +├── INDEX.md +├── SKILLS.md +├── TECH_NOTES.md +└── / + ├── NOTES.md + └── SUMMARY.md +``` + +- Session IDs are zero-padded three-digit folders (`001`, `002`, ...). +- `INDEX.md` is the table of contents across sessions, including active + `in-progress` sessions. +- `SKILLS.md` lists project-required skills. +- `TECH_NOTES.md` holds compact durable technical context and is editable. +- `NOTES.md` is the append-only running log for resuming an active session. +- `SUMMARY.md` is the curated postmortem written at closeout. + +Exact templates and write procedures live in the lifecycle skills, especially +`session-new` for `NOTES.md` and `session-close` for `SUMMARY.md` / `INDEX.md`. + +## During A Session + +- Keep the current task's bound session `NOTES.md` updated at meaningful + checkpoints. +- Outside an explicit lifecycle operation, checkpoint only the bound + `.journal//` folder using the concurrent journal ownership rule. A + lifecycle skill uses its resolved target and documented write set without + implicitly changing the binding. Never checkpoint any other session's files. +- Timestamp note headings in the user's local time as `YYYY-MM-DD HH:MM`. +- Correct earlier notes by appending a new entry, not by rewriting history. +- Record potential durable context in the bound session's `NOTES.md`; promote it to + `TECH_NOTES.md` during `session-close` so shared-root mutations stay narrow. +- Do not create or edit a separate `.journal/` inside an implementation + worktree. diff --git a/AGENTS.md b/AGENTS.md index b35511e..0cfd6f1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,3 +7,20 @@ - The bundled action `dist/` is committed: after changing `src/`, run `moon run root:package` and commit the refreshed `dist/` in the same change. - Use Conventional Commit subjects; releases are automated by release-please. + + + +# Agent Instructions + +This repository's operating protocol lives in `.session.md`. + +Before doing substantive work, read `.session.md` in full and follow it. It +covers startup context loading, session setup, session lifecycle, skill loading, +Worktrunk branching, session journaling, file schemas, architecture, and process +expectations. + +If `.session.md` is missing, stop and tell the user the session protocol is not +installed correctly. + + +