---
name: save
description: Auto-manage project documentation and persist task resume context from conversation
---

# Save

Auto-manage project documentation from conversation context, and fan out conversation signals to the canonical project system (`prj_tasks.resume_context`, `prj_notes`) via the `elevasis-sdk` CLI.

## Canonical Sources of Truth

- **Task resume context (DB):** `prj_tasks.resume_context` is canonical. Agents write it via `elevasis-sdk project:task:save`. Humans edit it via the inline task editor in Command Center. **Never** stash resume context into task-doc frontmatter.
- **Task-doc frontmatter:** ONLY `title`, `description`, `status`. No `resume_context`, no files-modified, no next-steps arrays -- those belong in the DB.
- **Project notes (DB):** `prj_notes` via `elevasis-sdk project:note:create`. Typed notes (`status_update` / `issue` / `blocker` / `call_note`) are the durable record of conversation signals.

## Process

### Step 1: Resolve Project + Task Context

Before doing anything else, determine the active project / task:

1. Look for an active task-doc frontmatter in the current conversation or the most recently edited file. Expected frontmatter:

   ```yaml
   ---
   title: Short title
   description: One-line summary
   status: planned | in-progress | blocked | complete
   ---
   ```

2. If the task doc references a project/task UUID anywhere in its body (link, callout, or prior save output), capture those IDs.
3. If no task / project context is resolvable, PROMPT the user:
   - "Which project is this work under?" (accepts slug or UUID)
   - "Is there an existing task I should attach this to? (task UUID, or 'new')"

   Do not guess. Without a task ID, skip Step 4 (DB resume-context save) but still perform Steps 2, 3, 5, 6, 7.

### Step 2: Analyze Conversation

Review the current conversation to identify:

1. **New knowledge** -- architecture decisions, feature implementations, bug fixes, discoveries
2. **Changed state** -- what was in-progress that is now complete, what new work started
3. **Stale docs** -- information in existing docs that is now outdated
4. **Signal events** -- blocker hit, status update worth recording, issue uncovered, call outcome
5. **OS contract paths touched** -- scan files read/written/edited for any of these signals:
   - `core/config/organization-model.ts` -> Foundations layer, Organization Model
   - `core/types/index.ts` -> Foundations layer, Workflow Contracts
   - `ui/src/routes/__root.tsx` -> UI Shell Runtime composition
   - `ui/src/features/**/manifest.ts` or any file defining a `SystemModule` -> Systems layer
   - `operations/src/index.ts` or `operations/elevasis.config.ts` -> core/Deployment (DeploymentSpec)
   - Any file inside `ui/src/features/<feature>/` combined with manifest, nav, or sidebar changes -> Features + Toolkit layers

   Record which OS layers were touched: `foundations`, `systems`, `shell-runtime`, `toolkit`, `deployment`. If none matched, OS awareness stays dormant for the rest of this run.

### Step 3: Update Knowledge Docs

Scan for unindexed or stale knowledge docs and draft creates / updates / moves. This template does not have a `docs/` tree — look for any local knowledge files (`.claude/rules/`, `operations/src/README.md`, `core/`, or project-specific docs the user has created). All edits are on knowledge/architecture/feature docs -- NOT on task resume state (that flows to the DB in Step 4).

Determine what needs to happen:

- **Create** new docs for significant new knowledge (new features, architecture decisions)
- **Update** existing docs with corrections, completions, or new details
- **Move** docs between directories (e.g., `ui/` to `operations/` when ownership shifts)
- **Delete** docs that are fully obsolete (rare -- prefer updating)

**Frontmatter requirement (all docs in `docs/`):**

```markdown
---
title: Short descriptive title
description: One-line summary of what this doc covers
---
```

In-progress task docs additionally require `status`:

```markdown
---
title: Feature Name
description: What this task is about
status: planned | in-progress | blocked | complete
---
```

No other fields. Do NOT add `resume_context`, `files_modified`, or `next_steps` to frontmatter -- those flow to the DB via Step 4.

**Doc structure rules:**

- All docs are `.md` (not .mdx)
- Keep docs focused -- one topic per file
- Use markdown tables for structured data
- Include "Last Updated: YYYY-MM-DD" at the bottom of modified docs

**OS layer annotation:** If OS contract paths were touched (Step 2), include an `## Organization OS Impact` section in any newly created architecture doc:

```markdown
## Organization OS Impact

Touched contracts: [list files]
Affected layers: [list of layers]
Cross-reference: `node_modules/@elevasis/sdk/reference/scaffold/reference/glossary.md`
Downstream: template consumer adapters may need review.
```

Dispatch a `general-purpose` subagent with the plan, conversation context, and these rules. The subagent must read each target file before editing.

### Step 4: Persist Task Resume Context to DB

If Step 1 resolved a task ID, save the current state to `prj_tasks.resume_context` via the SDK CLI. This is the canonical persistence step and must run every `/save` invocation that has a task in scope:

```bash
pnpm elevasis-sdk project:task:save <task-uuid> \
  --current-state "<concise prose summary of where we are>" \
  --next-steps "<concise prose of the next concrete action>" \
  --files-modified '["path/one.ts","path/two.tsx"]' \
  --key-docs '["operations/src/foo/index.ts","core/config/organization-model.ts"]' \
  --tools '["project:task:save","project:note:create"]'
```

Arg rules:

- `--current-state` (required) -- terse, present-tense "what is true right now". Prefer latest state over accumulated history.
- `--next-steps` -- single next concrete action another agent could execute without re-deriving intent.
- `--files-modified` -- JSON array of uncommitted / just-changed file paths (relative to project root).
- `--key-docs` -- JSON array of doc paths an agent should re-read to resume.
- `--tools` -- JSON array of tool / CLI names used this session that are worth flagging.

The endpoint is `PATCH /api/external/tasks/<id>/resume-context` and merges (does not replace) provided fields. Omit any arg that has nothing meaningful to record.

### Step 5: Create Typed Project Notes on Signal Events

For each signal event identified in Step 2, create a typed `prj_note`. One CLI call per note:

```bash
pnpm elevasis-sdk project:note:create \
  --project <project-uuid> \
  --task <task-uuid>          # optional, omit if not scoped to a task \
  --type <note-type> \
  --content "<what happened, why it matters, any next action>"
```

Note-type mapping (use the first type that matches, in this order):

- **`blocker`** -- work cannot proceed without external action (decision, credential, fix elsewhere, upstream change). Always create if detected. Trigger phrases: "I'm stuck", "blocked on", "can't proceed until", "waiting on <X>". When detected AND a task ID is in scope, ALSO fire a status transition -- see Step 5a below.
- **`issue`** -- bug, regression, unexpected failure, contract mismatch. Include reproduction context in `--content`.
- **`status_update`** -- milestone-level progress worth flagging to the human operator (phase complete, substantial deliverable landed, direction change). Keep it substantive -- `/save` runs shouldn't emit a status_update every turn.
- **`call_note`** -- only if the conversation is transcribing a live client / stakeholder call.

If no signal rises to note-worthy, skip this step entirely. Do not create filler notes.

### Step 5a: Blocker Signal -> Task Status Transition

Run this ONLY when Step 5 created a `blocker` note AND Step 1 resolved a task ID. It's the second half of the "I'm stuck" fanout: the note captures the why, this call flips the task's lifecycle state so it surfaces as blocked in portfolio views.

```bash
pnpm elevasis-sdk project:task:update <task-uuid> --status blocked
```

Rules:

- **Explicit task ID only** -- use the UUID resolved in Step 1. Do not re-derive or guess. If no task is in scope, skip this step (the blocker note still ships without it).
- **Best-effort** -- if the CLI returns non-2xx, surface a single warning line in Step 7 ("Warning: could not transition task <id> to blocked: <reason>") and continue. Do not retry, do not block the rest of `/save`.
- **Idempotent** -- if the task is already `blocked`, the update is a no-op. Fire it anyway; do not pre-check.
- **Order** -- the `blocker` note (Step 5) creates first; this transition follows. Keeps the note attached to the task even if the status update later fails.

### Step 6: Report

Summarize:

- Knowledge docs created / updated / moved / deleted
- Task ID written to (Step 4): `resume_context.last_saved` timestamp from the CLI response
- Notes created (Step 5): count, types, IDs
- OS classification (if applicable): layers detected, contracts touched
- Any files skipped due to missing frontmatter (Step 3 subagent should have added it)
- Any follow-ups for the human operator

## Failure Modes

- **No task in scope + user declines to provide one:** proceed with Steps 2, 3, 6, 7; skip Step 4; still allow Step 5 if a `--project` UUID is available.
- **`project:task:save` returns non-2xx:** surface the error in the report, do not retry silently; Step 5 and Step 6 still run.
- **Knowledge doc edits fail to write:** surface the error; any edits already applied are on disk and not lost.
