Skip to content

Latest commit

 

History

History
233 lines (191 loc) · 11.2 KB

File metadata and controls

233 lines (191 loc) · 11.2 KB

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 <ID> binds <ID> 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 <ID> closes that explicitly named session. If <ID> 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/<github-login> worktree for the authenticated user.

Resolve it in this order:

  1. If the current branch is journal/<github-login>, use the current checkout.
  2. If gh api user --jq .login succeeds and wt list --format=json shows a worktree for journal/<github-login>, 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/<login> 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-root>/.journal/SKILLS.md exists, load every required skill it lists.
  4. If <journal-root>/.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-root>/.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-root>/.journal/SKILLS.md; keep that file as a short list, not a manual.

Branch And Journal Invariants

  • Personal journal branches are named journal/<github-login>.
  • Journal branches are never PR'd or merged into the default branch.
  • The default branch keeps .journal/ ignored and untracked.
  • Only a journal/<github-login> 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/<ID>/ folder and its INDEX.md update.
  • session-continue owns .journal/<ID>/ and owns INDEX.md only when it must reopen the session.
  • session-close owns .journal/<ID>/, 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 ... -- <write-set> so unrelated staged changes cannot enter the commit. New or ignored journal files may be added with git add -f -- <write-set>; never use broad staging outside fresh setup or import. In commands, replace <write-set> 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/<login> 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
└── <ID>/
    ├── 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/<ID>/ 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.