agentleFS
matshoppenbrouwersmatshoppenbrouwers/session-flow/skills/session-init/SKILL.md

session-init

Skill3 starsChanged 5 months agoMITView on GitHub

Bootstrap the project documentation structure for session-flow skills. Creates the work root with its namespace, plus research/, plans/, testing/, and architecture/ directories. Run once when adopting session-flow in a new project. Triggers on "/session-init" or when user says "initialize project", "setup docs structure", or "bootstrap project".

2 other projects use a version of this.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

34 rules. About 0 are common, 16 are distinctive, and 18 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈16

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 18

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    When other session-flow skills fail because they cannot find the docs root

    line 16
  2. Very specific:

    Every record session-flow creates is written by the helper at <package-root>/scripts/session-flow.py.

    line 24
  3. Very specific:

    Ask the user one question: "Where should I create the documentation root?

    line 60
  4. Distinctive:

    Ask: "Does this repo share a work root with a parent folder?

    line 66
  5. Distinctive:

    When the answer is yes:

    line 68
  6. Distinctive:

    Verify the shared owner's canonical runtime project root, physical work root and namespace.

    line 70
  7. Very specific:

    Create no second work root and no second namespace.

    line 71
  8. Distinctive:

    Use the shared sequence path when you substitute into the CLAUDE.md block in Step 5b, so the wired instruction names the file that will …

    line 73
  9. Distinctive:

    Do not dump a list of options.

    line 75
  10. Very specific:

    When gh is missing, unauthenticated, or the remote is not GitHub, ask with no default and say why there is none.

    line 93
  11. Distinctive:

    Use Canonical state, views and backup to record the layout in the project runbook: canonical runtime project root, physical state root, …

    line 111
  12. Distinctive:

    Create these directories under the chosen root:

    line 133
  13. Very specific:

    If yes and no file exists: create {root}/PRD.md (inside the docs root, e.g.

    line 151
  14. Very specific:

    If the user already has a PRD/direction file: don't create one -- just record its path in paths.direction (Step 5).

    line 152
  15. Distinctive:

    If the user declines: skip it.

    line 153
  16. Very specific:

    If yes and no file exists: create {root}/conventions.md with a heading, a one-line format note, and no invented rules -- the user or a …

    line 161
  17. Very specific:

    If the user already has a conventions/house-rules file: don't create one -- just record its path in paths.conventions (Step 5).

    line 162
  18. Distinctive:

    If the user declines: skip it.

    line 163
  19. Very specific:

    Create {root}/INDEX.md with a minimal map of the structure:

    line 179
  20. Distinctive:

    Keep it under 20 lines of content.

    line 205
  21. Very specific:

    Create .session-flow.json in the project root:

    line 209
  22. Distinctive:

    When Step 2 configured a shared work root, bind this repository into that root instead of creating a second namespace.

    line 248
  23. Very specific:

    Only repositories gains an entry.

    line 258
  24. Very specific:

    Create no SEQUENCE.md here.

    line 260
  25. Distinctive:

    Use these exact delimiters so re-running updates the block in place instead of duplicating it:

    line 266
  26. Distinctive:

    After creation, suggest the logical next step based on the user's intent:

    line 297
  27. Distinctive:

    Non-destructive: Never overwrite existing files or directories.

    line 305
  28. Distinctive:

    User gate: Always confirm with the user before creating anything.

    line 306
  29. Very specific:

    The sequence is generated: Never hand-write or hand-edit paths.sequence.

    line 311
  30. Distinctive:

    No local work root beside a shared one: Never create a local work root or sequence when a shared one is configured, because a stale local …

    line 313
  31. Very specific:

    All session-flow skills should resolve the docs root using this priority:

    line 317
  32. Very specific:

    Read .session-flow.json from project root

    line 319
  33. Very specific:

    If missing, glob for common directories (_devdocs/, docs/)

    line 320
  34. Very specific:

    If nothing found, suggest running /session-init

    line 321

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Session Init

Bootstrap the documentation structure that all other session-flow skills depend on.

Open with one sentence saying what you are about to do and what it will produce.

When to Use

  • First time adopting session-flow in a project
  • Setting up a new repository that will use session-flow skills
  • When other session-flow skills fail because they cannot find the docs root

This is step 0 of the session-flow chain. Run it once, then never again.

Workflow

Step 0: Resolve the Runtime

Every record session-flow creates is written by the helper at <package-root>/scripts/session-flow.py. Resolve it before creating anything, by the one rule for this host (references/runtime-integration.md):

  • Native Claude plugin: the plugin root the host supplies in ${CLAUDE_PLUGIN_ROOT}.
  • Codex: the discovered installed skill and package location.
  • Standalone copy: the session-flow-runtime.json descriptor beside this SKILL.md; resolve its entrypoint against the descriptor's own directory.

Then confirm it answers, with absolute paths for both the interpreter and the entrypoint:

python3 -B "$ENTRYPOINT" --project-root "$PROJECT_ROOT" doctor

Read result.protocol, result.record_format, and result.runtime; Step 5a binds the namespace through the same entrypoint. When the interpreter is too old, report error.detail.install and stop; when the descriptor, the entrypoint, or a named support file is missing, report what is missing and where it was expected, and stop. Never scan the filesystem for another copy, and never fall back to writing records by hand -- there is no hand-editing path.

Step 1: Detect Existing Structure

Glob for common documentation directories:

_devdocs/
docs/
doc/
documentation/

Also check for an existing .session-flow.json in the project root. If it exists, read it and report the current configuration -- do not re-initialize. Check the same way for a namespace.json under the configured paths.work: a work root that already carries a namespace is initialized, so report its namespace and stop.

If legacy sequence/task files exist but the configured work root or namespace is missing, route to /session-repair. Repair includes namespace and Git setup in its approved migration plan; the user does not need to run init first. Missing namespaces alongside existing records require restoration, never re-initialization.

Step 2: Ask User Preference

If no existing structure found: Propose a default root directory. Common choices:

  • _devdocs/ (recommended -- keeps docs out of deployed artifacts)
  • docs/

Ask the user one question: "Where should I create the documentation root? Suggested: _devdocs/"

If existing structure found: Report what was found and confirm: "Found docs/ with existing content. Use this as the session-flow root?"

Then, once the root is settled: Ask: "Does this repo share a work root with a parent folder? If so, give the path to that folder's work root."

When the answer is yes:

  • Set paths.work and paths.sequence in Step 5 to the shared locations, written as ../ paths relative to the repo root. Leave the other keys pointing inside this repo.
  • Verify the shared owner's canonical runtime project root, physical work root and namespace. A copied config or record directory in a task worktree is not a new live backlog. Use Task workspaces and Git handoff for every session's source/runtime context.
  • Create no second work root and no second namespace. In Step 5a, bind this repository into the shared root instead: bind-namespace adds it under repositories and leaves the root's format and namespace untouched.
  • Skip Step 2b: the shared root's owner already answered the visibility question for it.
  • Use the shared sequence path when you substitute into the CLAUDE.md block in Step 5b, so the wired instruction names the file that will actually be read.

Do not dump a list of options. One question, one answer.

Step 2b: Ask the Work-Root Visibility Question -- Once

The work root is a Git repository in every supported configuration: history, backup and restore come from Git rather than from the helper. Ask this once, act on the answer, and never re-ask it per directory. The answer decides a capability, not only privacy.

Find the default before asking:

gh repo view --json isPrivate --jq .isPrivate
AnswerSetup you runConsequence you state
Repository is private -- the default when the command reports trueTrack the work root in this repository. If .gitignore matches it, remove that line and only that line.History uses the enclosing repository and reaches its remote through owned integration and authorized publication. Restore can use that published history; hosted ops can read the committed backlog.
Repository is public, work docs stay privateKeep the work root ignored by the outer repository and give it its own private repository, with the setup below.Hosted ops cannot see this backlog and execution stays local: both ops workflow templates hardcode OPS_TODO and OPS_SEQUENCE, and a GitHub Actions job can only read committed files.
Repository is public, work docs public tooTrack it in this repository, as for a private repository.Same mechanics; the records are published.

When gh is missing, unauthenticated, or the remote is not GitHub, ask with no default and say why there is none.

For the private-work-root answer, offer to run the setup rather than describing it, and run it only once the user agrees:

git -C "$WORK_ROOT" init -b main
git -C "$WORK_ROOT" add -A && git -C "$WORK_ROOT" commit -m "Initialize work records"
gh repo create "$REPO_NAME-devdocs" --private --source="$WORK_ROOT" --push

A Git repository inside an ignored directory is invisible to the outer one, so there is no submodule interaction.

Visibility and history placement are separate choices. An own-repository work root can separate runtime commits from application history for either visibility choice. Preserve the answer above: inspect hosted ops consumers before moving their records or views, and agree a deliberate snapshot publication path if they still need committed access. Existing tracked records require a reviewed migration that preserves namespace, history, bindings and pinned references, not re-initialization.

Use Canonical state, views and backup to record the layout in the project runbook: canonical runtime project root, physical state root, clean integration checkout, generated sequence location, visibility/publication owner, and backup repository, remote/branch, owner and cadence. A sequence outside the work root is written by render but excluded from runtime commits; keep it out of the clean integration checkout and account for its publication separately. Records in an enclosing source repository advance that branch, so their publication must use the owned integration path.

Automatic local commits are not remote backup. A no-remote root needs an agreed destination and push authority; do not create or publish a remote merely because doctor reports one missing. Routine post-handoff backup applies only to a work root with its own state repository, after confirming storage.own_repository and the intended state branch/remote. The command pushes the containing repository's current branch; never use it to publish the coordination checkout's enclosing application branch. Hand that state history to the integration owner for canonical publication and report anything still awaiting publication. Backup reports incomplete coverage and omits application worktrees, ignored journals, other branches and uncommitted views outside the root. Record these limits and who handles them; do not describe it as a whole-workspace snapshot.

Declining every option is allowed. Leave the work root unversioned and say plainly that backup and restore are unavailable, that applied transitions keep no history and will report there was nothing to commit, and that hosted ops cannot see the backlog. Take that from Step 5c's doctor rather than asserting it: storage.versioned is false for a root ignored by the enclosing repository, storage.enclosing_repository names that repository, and storage.own_repository separates a root with its own repository from one the enclosing repository tracks.

Step 3: Create Subdirectories

Create these directories under the chosen root:

DirectoryPurposeUsed By
research/Research and design documentssession-research-design
plans/Implementation plans from researchsession-research-design
work/The work root: one directory per work item, plus namespace.jsonthe runtime, through paths.work
testing/Manual test plans and test resultssession-post-implementation
architecture/Architecture documentationupdate-architecture

Important: create no todo/ directory. Work items live in the work root, one directory per item, and the backlog is generated from them. An existing todo/ in a repository adopting session-flow is history: leave it in place, keep paths.todo and paths.tasks pointing at it so those files stay findable, and write no new task file there.

Step 3c: Offer a Direction Doc (optional)

session-gatekeeper grounds its triage in a product-direction doc. Offer -- do not force -- to scaffold one:

"Want me to create a PRD.md stub for product direction in the docs root ({root}/PRD.md)? (Used by /session-gatekeeper. You can also point at an existing file instead.)"

  • If yes and no file exists: create {root}/PRD.md (inside the docs root, e.g. _devdocs/PRD.md) with a minimal stub (vision, scope, non-goals headings).
  • If the user already has a PRD/direction file: don't create one -- just record its path in paths.direction (Step 5).
  • If the user declines: skip it; gatekeeper degrades gracefully when no direction doc exists.

Step 3d: Offer a Conventions File (optional)

session-research-design designs against the project's house rules and code-reviewer enforces them. Offer -- do not force -- to scaffold one:

"Want me to create a conventions.md stub for house rules in the docs root ({root}/conventions.md)? (Read by /session-research-design and code-reviewer. You can also point at an existing file instead.)"

  • If yes and no file exists: create {root}/conventions.md with a heading, a one-line format note, and no invented rules -- the user or a later codebase-researcher pass fills it in.
  • If the user already has a conventions/house-rules file: don't create one -- just record its path in paths.conventions (Step 5).
  • If the user declines: skip it; the design and review steps degrade gracefully and say so when no conventions file is configured.

Format for entries, stated in the stub:

# Conventions

One rule per line, `rule — reason`, ~140 characters. The reason is mandatory: without it,
design either treats the rule as gospel or ignores it. If a rule needs more than one line,
it is an architecture decision -- record it in `architecture/decisions.md` instead.

lessons.md (conclusions drawn from past work, same one-line format) uses the same offer only if the user asks for it. Otherwise just leave paths.lessons pointing at the default location and let the file appear when there is something to write in it.

Step 4: Create INDEX.md

Create {root}/INDEX.md with a minimal map of the structure:

# Documentation Index

Project documentation root for session-flow skills.

## Structure

| Directory | Purpose |
|-----------|---------|
| `research/` | Research documents and design explorations |
| `plans/` | Implementation plans derived from research |
| `work/` | Work items: one directory per SEQ, `intent.md` and whatever the work needs |
| `SEQUENCE.md` | Generated backlog view -- written by session-flow, never edited by hand |
| `testing/` | Manual test plans and test results |
| `architecture/` | Architecture docs (one per system layer) |

## Quick Navigation

- Task backlog: `SEQUENCE.md` (generated; say "implement the next task")
- Work items: `work/`
- Architecture overview: `architecture/`
- Active research: `research/`

Keep it under 20 lines of content. This is a signpost, not a novel.

Step 5: Write .session-flow.json

Create .session-flow.json in the project root:

{
  "root": "<chosen-root>",
  "paths": {
    "research": "<chosen-root>/research",
    "plans": "<chosen-root>/plans",
    "work": "<chosen-root>/work",
    "sequence": "<chosen-root>/SEQUENCE.md",
    "testing": "<chosen-root>/testing",
    "architecture": "<chosen-root>/architecture",
    "direction": "<chosen-root>/PRD.md",
    "conventions": "<chosen-root>/conventions.md",
    "lessons": "<chosen-root>/lessons.md"
  }
}

paths.work is where the runtime writes records and paths.sequence is the generated view of them; every session-flow command resolves both from this file through --project-root. Write no todo or tasks key for a new project -- there is no todo/ directory. Add them only for a repository that already has those directories, where they address pre-existing historical files and nothing new is written to them.

This config file allows all other session-flow skills to auto-discover the documentation root without hardcoding paths. paths.direction points at the product-direction doc used by /session-gatekeeper -- it defaults to <chosen-root>/PRD.md (inside the docs root), or set it to the user's existing PRD/direction file anywhere in the repo.

paths.conventions and paths.lessons are optional file paths, defaulting to <chosen-root>/conventions.md and <chosen-root>/lessons.md. Write them whether or not the files exist yet -- their consumers (session-research-design, session-delegation, code-reviewer) check for the file and say so when it is missing. Point either key at the user's existing file instead if they have one. Drop the key entirely only if the user asks you to.

paths.runbook is optional, and the config block above does not write it. It points at the file that says how this project commits, pushes and deploys. /session-next reads it when the user asks to deliver, and offers to record it when the user supplies the answer. Add it only when the project has such a file.

Step 5a: Bind the Namespace

The work root carries namespace.json: format version, namespace UUID, and repository bindings. It is coordination configuration created with the root, not a second status registry, and every record's identity depends on it. Its contract is references/work-item-contract.md.

The runtime writes that file, resolving the work root from the configuration Step 5 just wrote. Run it here, and never hand-write the file:

python3 -B "$ENTRYPOINT" --project-root "$PROJECT_ROOT" bind-namespace

bind-namespace creates the work root if Step 3 has not, allocates the namespace UUID, and stamps the record format this runtime reads instead of a number that silently becomes unsupported-format after an upgrade. Report result.namespace. A root that already carries one answers created: false and keeps its UUID: the command never reallocates a namespace, because a second one orphans every record already under that root.

When Step 2 configured a shared work root, bind this repository into that root instead of creating a second namespace. Write the binding to a JSON file and pass it:

{"repository": {"name": "<repo name>", "path": "<path to this repo, relative to the work root>"}}
python3 -B "$ENTRYPOINT" --project-root "$PROJECT_ROOT" bind-namespace --input "$BINDING_FILE"

Only repositories gains an entry; the shared root keeps its format and namespace. Binding the same name and path twice changes nothing, and a name already bound to another path fails with invalid-identity rather than overwriting it.

Create no SEQUENCE.md here. The sequence is generated from the work root, in Step 5c.

Step 5b: Wire the Sequence into CLAUDE.md and AGENTS.md

So agents consult the backlog first, insert an idempotent marked block into the project's CLAUDE.md and AGENTS.md (create either file if absent). Confirm with the user before writing, per the non-destructive rule.

Use these exact delimiters so re-running updates the block in place instead of duplicating it:

<!-- session-flow:sequence -->
## Task Sequence

Before starting unprompted work, consult the backlog at `<sequence path>`. It is generated
output: read it to find work, and never edit it. When asked to "implement the next task",
run `/session-next`, which selects one open item, claims it, and records the outcome against
its identity. Use `/session-add-task` to capture new work, `/session-groom` to fill in missing
breakdowns, and `/session-gatekeeper` to triage incoming issues.
<!-- /session-flow:sequence -->

If the block already exists (matched by the <!-- session-flow:sequence --> markers), replace its contents; otherwise append it. Substitute <sequence path> with the resolved sequence path -- the shared one when a shared work root was configured, so the instruction names the file that will actually be read. Never disturb content outside the marked block.

Step 5c: Confirm the Root and Generate the Sequence

The runtime resolves paths.work and paths.sequence from .session-flow.json, so run these only after Step 5 has written it:

python3 -B "$ENTRYPOINT" --project-root "$PROJECT_ROOT" doctor
python3 -B "$ENTRYPOINT" --project-root "$PROJECT_ROOT" render

doctor must report the namespace from Step 5a under storage.namespace; a named error there means the file is malformed, so correct it and re-run rather than proceeding. Report storage.versioned and any storage.limitations alongside the Step 2b outcome, so the user sees the versioning decision as the runtime now sees it.

render writes paths.sequence from the work root and reports items: 0 for a fresh project. That file is generated output: the runtime writes it, no skill appends to it, and a change made only there is lost at the next render.

Step 6: Suggest Next Step

After creation, suggest the logical next step based on the user's intent:

  • Starting a new feature: "Run /session-research-design to explore and plan."
  • Have a plan already: "Run /session-task-planning to break it into tasks."
  • Just organizing: "Documentation structure is ready. Run any session-flow skill when needed."

Constraints

  • Non-destructive: Never overwrite existing files or directories. If a directory already exists, skip it and report that it was preserved.
  • User gate: Always confirm with the user before creating anything.
  • Minimal INDEX.md: Under 20 lines of content. Add detail later via update-architecture, not here.
  • Runtime first: Resolve the helper and get an answer from doctor before creating anything. If it cannot answer, report what is missing and stop -- nothing falls back to hand-written records.
  • .gitignore changes only follow the answered question: Touch .gitignore only to act on the Step 2b answer, and only the line matching the work root.
  • namespace.json belongs to the runtime: bind-namespace creates it and adds bindings; never hand-write or edit it. A new namespace orphans every record already under that root.
  • The sequence is generated: Never hand-write or hand-edit paths.sequence; render writes it from the work root.
  • Config is source of truth: Other skills read .session-flow.json to find paths. If this file is missing, they should suggest running /session-init.
  • No local work root beside a shared one: Never create a local work root or sequence when a shared one is configured, because a stale local copy is what a session finds first.

Path Resolution Pattern

All session-flow skills should resolve the docs root using this priority:

  1. Read .session-flow.json from project root
  2. If missing, glob for common directories (_devdocs/, docs/)
  3. If nothing found, suggest running /session-init

This skill creates the config that makes step 1 work for all other skills.

Anti-Patterns

  • Creating directories without asking -- Always confirm with the user first
  • Overwriting existing content -- Existing files and directories are preserved unconditionally
  • Bloated INDEX.md -- This is a signpost, not documentation. Keep it minimal.
  • Hardcoded paths in other skills -- Other skills must read .session-flow.json, not assume _devdocs/
  • Running session-init repeatedly -- If .session-flow.json exists, report the current config and stop
  • Creating a todo/ directory -- Work items live in the work root; the backlog is generated, not a directory of task files
  • Hand-writing the sequence -- render produces it; anything typed there is lost at the next render
  • Asking the visibility question twice -- One question, one answer, acted on; a shared work root inherits the owner's answer
  • Creating sample/template files -- Only create the structure; content comes from the skills that use each directory
  • Duplicating the CLAUDE.md/AGENTS.md block -- Match the <!-- session-flow:sequence --> markers and replace in place; never append a second copy
  • Forcing a PRD.md or conventions.md -- Both are optional; offer them, and respect an existing file via paths.direction / paths.conventions
  • Seeding conventions.md with invented rules -- The stub carries the format note and nothing else; rules come from the project, not from you

Chain context: see references/workflow-overview.md.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.