# Project Context

## Meta-Protocol Principles

- `Constraint-Driven Evolution`: Add structure when real scheduler, ownership, or packaging constraints justify it
- `Single Source of Truth`: Keep durable protocol in `AGENTS.md`, open work in `BACKLOG.md`, completed delivery in `CHANGELOG.md`, and technical details in `/docs`
- `Boundary Clarity`: README is the human entrypoint, `WAKEUP.md` is runtime state, `locks.json` is ownership state, and code comments/docs should not duplicate those state files
- `Runtime Safety`: Prefer explicit ownership, quiet degradation, and predictable schedule mutation over clever automatic takeover behavior
- `Context Hygiene`: Keep project context compact because extension behavior already flows into the agent prompt through tool guidance

## Concept

`pi-wakeup` is a pi extension that lets one explicitly selected pi instance deliver scheduled follow-up prompts from a durable Markdown schedule.

## Topology

- `/index.ts`: Small namespace-import composition root; wires paths, runtime, slash commands, and the `wakeup` tool without owning domain behavior
- `/lib/*.ts`: Flat Domain DAG modules for cohesive scheduler behavior; `paths` resolves state paths, `schedule` owns `WAKEUP.md` input/entry/plan logic, `storage` owns schedule file IO, `locks` owns singleton storage and ownership policy, `delivery` owns timers and fired-task transitions, `watcher` owns schedule file watching, `status` owns footer rendering, `runtime` coordinates domains across session/start/stop flows, `reports` owns check output, `commands` owns `/wakeup-*` handlers, `tools` owns the pi tool definition and LLM-facing guidance, and `time` owns date/duration formatting
- `/tests/*.test.ts`: Domain-mirrored regression tests for schedule, locks, delivery, status, tools, plus architecture invariants for namespace imports, entrypoint boundaries, import acyclicity, and source responsibility headers
- `/README.md`: Human-facing install, usage, schedule format, and runtime overview
- `/docs/README.md`: Documentation index
- `/docs/architecture.md`: Runtime and Domain DAG overview
- `/docs/locks.md`: Shared `locks.json` singleton ownership standard used by this extension and sibling singleton extensions
- `/AGENTS.md`: Durable project protocol and architectural memory
- `/BACKLOG.md`: Canonical open work
- `/CHANGELOG.md`: Completed delivery history

## Operating Principles

- Keep wake-up delivery opt-in: `/wakeup-start` chooses the active pi instance, and `/wakeup-stop` releases ownership
- Treat `WAKEUP.md` as user-editable state; preserve readable Markdown, stable indexes, and compact status output
- Treat `locks.json` as shared registry state; mutate only the `@llblab/pi-wakeup` key and preserve all other extension keys exactly
- Keep normal tool output actionable and compact because it is injected directly into agent context
- Use relative scheduling for user-facing delays unless an absolute UTC timestamp is explicitly needed
- Keep published docs portable: use `~/.pi/...`, `<repo>/...`, or relative paths instead of machine-local absolute paths

## Durable Conventions

- `Schedule source`: `~/.pi/agent/WAKEUP.md` is the durable schedule | Trigger: Any scheduling, parsing, cleanup, or docs change | Action: Preserve the Markdown template, human-edited order, UTC timestamps, and monotonic next-index header
- `Task line contract`: Active entries use `N. [status] YYYY-MM-DDTHH:MM:SSZ | action` | Trigger: Changing parser, writer, README examples, or tool output | Action: Keep `N`, `[ ]`/`[x]`/`[~]`, UTC timestamp, and action semantics aligned everywhere
- `Sequential firing`: Only one `[~]` task should be active at a time | Trigger: Changing timer dispatch, overdue handling, or `done` behavior | Action: Let overdue pending tasks fire after current work is closed instead of stacking concurrent follow-ups
- `Completion reset`: Completed entries are retained while work remains, then the schedule resets to the empty template when all entries are done | Trigger: Changing normalization or `done` behavior | Action: Preserve next-index monotonicity across reset
- `Singleton ownership`: `~/.pi/agent/locks.json` key `@llblab/pi-wakeup` selects the delivery owner | Trigger: Changing lock acquisition, release, status, or watcher behavior | Action: Mutate only this key, preserve other keys, and report state as active here, active elsewhere, stale, or inactive
- `Explicit acquisition`: Startup may resume an existing own lock or stale same-`cwd` lock, but must not create inactive ownership or silently take over a live external owner | Trigger: Changing `session_start`, `/wakeup-start`, or takeover prompts | Action: Keep `/wakeup-start` or confirmed interactive takeover as the ownership boundary
- `Mutation guard`: Schedule mutations must reject when another live pi instance owns delivery | Trigger: Changing `wakeup schedule`, `wakeup done`, or direct write helpers | Action: Check live external ownership before writing schedule state
- `Timer discipline`: Runtime delivery is local `setTimeout` scheduling from `WAKEUP.md`; no cron, daemon, or external process should be introduced casually | Trigger: Changing delivery architecture | Action: Rebuild timers from schedule state and stop local runtime on lock mismatch
- `Session replacement safety`: Long-lived timers/watchers must use snapshotted primitive identity such as `cwd`, not stale live pi context objects | Trigger: Changing watchers, timers, status updates, or session lifecycle hooks | Action: Stop local runtime on ownership mismatch and catch stale-context UI update failures
- `Context sync`: Meaningful implementation or public docs changes must reconcile `BACKLOG.md`, `CHANGELOG.md`, README, and docs navigation | Trigger: Closing, narrowing, or discovering work | Action: Run the context validator before final status when practical
- `Entrypoint boundary`: `index.ts` must remain a small composition root using namespace imports from `/lib` domains | Trigger: Adding command/tool/runtime behavior | Action: Put reusable behavior in the owning flat domain and keep architecture invariant tests passing
- `Domain cohesion`: Split files by independent ownership, not by helper category | Trigger: A domain is split into tiny entry/input/plan/storage/policy facades without independent runtime or testing value | Action: Collapse back into the cohesive domain, following the `schedule` and `locks` shape
- `Typebox independence`: Tool schemas are plain JSON schema objects | Trigger: Changing pi tool definitions | Action: Do not reintroduce a runtime `typebox` dependency unless the validation harness and package peer contract are updated deliberately

## Validation

- `npm run check`: Extension import sanity check
- `npm test`: Focused schedule, lock, delivery, status, tool, and architecture invariant tests
- `npm run pack:dry`: Verify package contents and npm metadata
- `bash ~/.pi/agent/skills/evolve-context/scripts/validate-context.sh`: Validate context split, links, and README/docs reachability

## Pre-Task Preparation

1. Read `AGENTS.md`, `BACKLOG.md`, `README.md`, and the relevant `/docs` file before changing behavior or docs
2. Inspect `index.ts` around the touched schedule, lock, timer, command, or tool path
3. Preserve the explicit singleton acquisition boundary unless the user asks for a behavior change
4. Prefer targeted edits over broad rewrites

## Task Completion Protocol

1. Run the smallest validation set that covers the touched scope
2. Reconcile `BACKLOG.md` by closing, narrowing, splitting, deferring, or gating items explicitly
3. Update README and `/docs` when public behavior, setup, package contents, or navigation changes
4. Record meaningful delivered slices in `CHANGELOG.md`
