specsail 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  All notable SpecSail changes are recorded here.
4
4
 
5
+ ## 0.2.0 — 2026-10-21
6
+
7
+ - Add conversational mode: ask your coding agent for a change and the First Mate (`manage`) runs the workflow, bootstrapping project docs and the Makefile first.
8
+ - Add the `manage` orchestrator skill; chat approvals are recorded in artifacts as `Status: APPROVED — Captain (chat), <date>`.
9
+ - Review now asks whether to use a second session/model and records any same-model caveat.
10
+ - Rename crew aliases: Reviewer is now **Bosun** and Release is now **Clerk**. Stage names and commands are unchanged.
11
+ - Publish releases from GitHub Actions with npm trusted publishing and provenance; add `make release` and the release guide.
12
+
5
13
  ## 0.1.0 — 2026-10-20
6
14
 
7
15
  - First public release of the SpecSail methodology and Node.js CLI.
package/README.md CHANGED
@@ -4,64 +4,76 @@
4
4
 
5
5
  > **Navigate by spec. Deliver with confidence.**
6
6
 
7
- SpecSail gives developers a repeatable, human-led way to work with AI coding agents: capture the request, approve the spec, plan the work, approve tests, implement one task at a time, review independently, and ship. The durable artifacts live in your repository—not in chat history.
7
+ SpecSail gives developers a repeatable, human-led way to work with AI coding agents: capture the request, approve the spec, plan the work, approve tests, implement one task at a time, review independently, and ship. The durable artifacts live in your repository — not in chat history.
8
+
9
+ Start with one sentence. Your agent runs the workflow.
8
10
 
9
11
  ## The crew
10
12
 
11
- | Stage | Development role | Sailing alias | Responsibility |
13
+ | Skill | Development role | Sailing alias | Responsibility |
12
14
  |---|---|---|---|
13
- | Understand | Product Owner | **Scout** | Clarifies the request and records routing, constraints, and open questions. |
14
- | Plan | Tech Lead | **Navigator** | Writes the spec, then the technical plan and thin tasks. |
15
- | Acceptance tests | QA | **Quartermaster** | Encodes approved criteria as observable tests before implementation. |
16
- | Implement | Developer | **Hands** | Implements one planned task and runs project verification. |
17
- | Review | Reviewer | **First Mate** | Independently checks behavior, evidence, scope, and invariants. |
18
- | Ship | Release | **Bosun** | Updates release docs and prepares the pull request. |
15
+ | `manage` | Orchestrator | **First Mate** | Bootstraps project context, runs the workflow, and stops at every gate. |
16
+ | `understand` | Product Owner | **Scout** | Clarifies the request and records routing, constraints, and open questions. |
17
+ | `plan` | Tech Lead | **Navigator** | Writes the spec, then the technical plan and thin tasks. |
18
+ | `acceptance-tests` | QA | **Quartermaster** | Encodes approved criteria as observable tests before implementation. |
19
+ | `implement` | Developer | **Hands** | Implements one planned task and runs project verification. |
20
+ | `review` | Reviewer | **Bosun** | Independently checks behavior, evidence, scope, and invariants. |
21
+ | `ship` | Release | **Clerk** | Updates release docs and prepares the pull request. |
19
22
 
20
23
  The **Captain is always human**: the Captain resolves questions, approves the spec, approves phase acceptance tests, and merges. Agents can prepare a gate; they cannot pass it.
21
24
 
22
25
  ## Quick start
23
26
 
24
- Requires Node.js 20+ for the CLI. No runtime dependencies.
27
+ Requires Node.js 20+ for the one-time setup. No runtime dependencies.
25
28
 
26
29
  ```sh
27
30
  npx specsail init
28
- npx specsail doctor
29
- npx specsail new password-reset new
30
31
  ```
31
32
 
32
- `init` adds the kit without replacing existing project files. It installs skills and scripts under `.specsail/`, adds a marked section to `AGENTS.md`, and creates project templates only when the destination does not already exist. It writes the installed version to `.specsail.json`.
33
-
34
- Then fill in `docs/project.md` and `docs/architecture.md`, configure the generated `Makefile` targets for your stack, and add your Captain/team to `.github/CODEOWNERS`. Start the crew by reading `.specsail/docs/runbook.md`.
33
+ Then open your coding agent and ask for what you want:
35
34
 
36
- ### Use with your coding tool
35
+ > "Let's add user authentication."
37
36
 
38
- SpecSail does not require a vendor-specific agent integration. Use any coding tool that can read repository instructions and Markdown files; follow the stage's `SKILL.md` directly if your tool does not discover skills automatically. The optional Bash headless runner supports Claude, Codex, and OpenCode CLIs, but it is not required.
37
+ The First Mate checks `docs/project.md`, `docs/architecture.md`, and the `Makefile`. If they are missing or still starter templates, it interviews you and drafts them. It then scaffolds `specs/<feature>/` and runs Scout → Navigator → Quartermaster → Hands → Bosun → Clerk, asking questions and stopping at each approval gate. You answer in chat; the agent records each decision in the artifact.
39
38
 
40
- For tools using the Agent Skills convention, you can also install a skill from this repository, for example:
39
+ No commands are required after `init`. The CLI stays available for manual control, CI, and scripting.
41
40
 
42
- ```sh
43
- npx skills add dseija/specsail --skill understand
44
- ```
45
-
46
- ## The flow
41
+ ## How the flow works
47
42
 
48
43
  ```text
49
44
  request → Captain-approved spec → plan → Captain-approved phase tests
50
45
  → implement one task → independent review → PR → Captain merges
51
46
  ```
52
47
 
53
- The plan is approved before acceptance tests are written. Tests are approved per phase before implementation starts. Bug fixes can use a shorter path; trivial changes can use a normal PR and the project's `make verify`.
48
+ The spec is approved before planning; phase tests are approved before implementation. Bug fixes use a shorter path; trivial changes can use a normal PR and the project's `make verify`.
49
+
50
+ At every stage the agent may ask you questions. Two gates are always explicit:
51
+
52
+ 1. **Spec approval** — the acceptance criteria are observable and complete.
53
+ 2. **Test approval** — the tests fail for the right reason before code is written.
54
+
55
+ Review independence is also explicit: the First Mate asks whether to open a second session/model. If you accept a same-model review, the caveat is recorded in `review.md`.
56
+
57
+ ## Use with your coding tool
58
+
59
+ SpecSail does not require a vendor-specific agent integration. Use any tool that reads repository instructions and Markdown — OpenCode, Claude Code, Codex, Cursor, Copilot, Gemini CLI, or anything else. `AGENTS.md` tells the agent to start the workflow; if your tool does not discover skills automatically, it can read the `SKILL.md` files directly.
60
+
61
+ For tools using the Agent Skills convention, you can also install individual skills from this repository:
62
+
63
+ ```sh
64
+ npx skills add dseija/specsail --skill manage
65
+ ```
54
66
 
55
- ## Commands
67
+ ## Commands (optional)
56
68
 
57
69
  | Command | Purpose |
58
70
  |---|---|
59
71
  | `specsail init` | Add SpecSail files without overwriting existing project files. |
60
- | `specsail new <slug> <fix\|update\|new>` | Scaffold request, spec, plan, and task artifacts. |
61
- | `specsail doctor` | Check required files, role skills, and `make verify`. |
72
+ | `specsail new <slug> <fix\|update\|new>` | Scaffold request, spec, plan, and task artifacts manually. |
73
+ | `specsail doctor` | Check required files, crew skills, `make verify`, and the workflow trigger. |
62
74
  | `specsail --version` | Print the installed version. |
63
75
 
64
- Optional scripts in `.specsail/scripts/` create phase branches, run configured CLIs, check protected-path commit prefixes, and open a PR. They require Git and Bash (macOS, Linux, WSL, or Git Bash). Interactive workflow use does not.
76
+ Optional scripts in `.specsail/scripts/` create phase branches, run configured CLIs, check protected-path commit prefixes, and open a PR. They require Git and Bash (macOS, Linux, WSL, or Git Bash). The conversational workflow does not.
65
77
 
66
78
  ## Stack-neutral by design
67
79
 
@@ -74,7 +86,7 @@ make setup
74
86
  make verify
75
87
  ```
76
88
 
77
- Read [CONTRIBUTING.md](CONTRIBUTING.md), the [workflow reference](docs/workflow.md), the [runbook](docs/runbook.md), and the [roadmap](ROADMAP.md).
89
+ Read [CONTRIBUTING.md](CONTRIBUTING.md), the [workflow reference](docs/workflow.md), the [runbook](docs/runbook.md), the [release guide](docs/releasing.md), and the [roadmap](ROADMAP.md).
78
90
 
79
91
  ## Open source
80
92
 
package/ROADMAP.md CHANGED
@@ -15,5 +15,4 @@ The first release focuses on a safe, readable baseline. The items below are orde
15
15
  - Add a conflict-aware `specsail update` that previews changes and never overwrites local edits.
16
16
  - Add opt-in agent-specific adapters or commands only when they improve the universal Markdown workflow without making them mandatory.
17
17
  - Consider a Windows-native runner if users need headless execution outside WSL or Git Bash.
18
- - Automate release notes and npm publishing with GitHub Actions trusted publishing/provenance after the maintainer account is configured.
19
18
  - Consider language/framework presets as separately maintained opt-ins; the core remains stack-neutral.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specsail",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "A spec-driven AI development crew. Navigate by spec. Deliver with confidence.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -4,12 +4,13 @@ import { fileURLToPath } from "node:url";
4
4
 
5
5
  const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
6
6
  const roles = {
7
+ manage: ["Orchestrator", "First Mate"],
7
8
  understand: ["Product Owner", "Scout"],
8
9
  plan: ["Tech Lead", "Navigator"],
9
10
  "acceptance-tests": ["QA", "Quartermaster"],
10
11
  implement: ["Developer", "Hands"],
11
- review: ["Reviewer", "First Mate"],
12
- ship: ["Release", "Bosun"],
12
+ review: ["Reviewer", "Bosun"],
13
+ ship: ["Release", "Clerk"],
13
14
  };
14
15
 
15
16
  let errors = 0;
@@ -58,5 +59,22 @@ for (const name of ["request.md", "spec.md", "plan.md", "tasks.md"]) {
58
59
  if (!templateFiles.includes(name)) fail(`missing feature scaffold template specs/_templates/${name}`);
59
60
  }
60
61
 
62
+ const templateAgents = await readFile(path.join(root, "templates/.specsail/AGENTS.md"), "utf8");
63
+ if (!templateAgents.includes(".specsail/skills/manage/SKILL.md")) {
64
+ fail("the installed AGENTS.md must trigger the conversational workflow via the manage skill");
65
+ }
66
+ const cliSource = await readFile(path.join(root, "src/cli.js"), "utf8");
67
+ if (!cliSource.includes("skills/manage/SKILL.md")) {
68
+ fail("specsail init must add the conversational workflow trigger to AGENTS.md");
69
+ }
70
+
71
+ const releaseWorkflow = await readFile(path.join(root, ".github/workflows/release.yml"), "utf8");
72
+ if (!/^\s*id-token:\s*write$/m.test(releaseWorkflow)) fail("release workflow must request the GitHub OIDC token (id-token: write)");
73
+ if (!/^\s*contents:\s*write$/m.test(releaseWorkflow)) fail("release workflow must be allowed to create the GitHub release (contents: write)");
74
+ if (!/tags:\s*\["v\*"\]/.test(releaseWorkflow)) fail("release workflow must run on v* tags");
75
+ if (!releaseWorkflow.includes("--provenance")) fail("release workflow must publish with --provenance");
76
+ if (releaseWorkflow.includes("environment: npm") === false) fail("release workflow must use the npm environment configured as the trusted publisher");
77
+ if (/NODE_AUTH_TOKEN|NPM_TOKEN|secrets\./.test(releaseWorkflow)) fail("release workflow must not use npm tokens or repository secrets");
78
+
61
79
  if (errors) process.exitCode = 1;
62
80
  else console.log("✓ content, crew metadata, and package invariants are valid");
@@ -22,4 +22,4 @@ mkdir -p "$DIR"
22
22
  for f in request spec plan tasks; do
23
23
  sed "s/{{SLUG}}/$SLUG/g; s/{{TYPE}}/$TYPE/g" "$TEMPLATES/$f.md" > "$DIR/$f.md"
24
24
  done
25
- echo "Created $DIR. Commit scaffolds with a spec: prefix. Next: .specsail/scripts/run-agent.sh scout $SLUG"
25
+ echo "Created $DIR. Commit scaffolds with a spec: prefix. Next: ask your agent to start the SpecSail workflow for $SLUG; the First Mate will continue from the request stage."
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env bash
2
+ # Bump the version, commit, and push a release tag. The tag starts the release workflow.
3
+ # Usage: scripts/release.sh <x.y.z>
4
+ set -euo pipefail
5
+ VERSION="${1:?usage: release.sh <x.y.z>}"
6
+ [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || { echo "version must be x.y.z (no leading v)" >&2; exit 1; }
7
+
8
+ cd "$(git rev-parse --show-toplevel)"
9
+ [ -z "$(git status --porcelain)" ] || { echo "working tree must be clean" >&2; exit 1; }
10
+ BRANCH="$(git rev-parse --abbrev-ref HEAD)"
11
+ [ "$BRANCH" = "main" ] || { echo "release from main, not $BRANCH" >&2; exit 1; }
12
+
13
+ git fetch origin main
14
+ [ "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)" ] || { echo "local main must match origin/main" >&2; exit 1; }
15
+ grep -q "^## $VERSION " CHANGELOG.md || { echo "CHANGELOG.md is missing a '## $VERSION' heading" >&2; exit 1; }
16
+ git rev-parse -q --verify "refs/tags/v$VERSION" >/dev/null && { echo "tag v$VERSION already exists" >&2; exit 1; }
17
+
18
+ make verify
19
+ CURRENT="$(node -p "require('./package.json').version")"
20
+ if [ "$CURRENT" != "$VERSION" ]; then
21
+ npm version "$VERSION" --no-git-tag-version
22
+ git add package.json package-lock.json
23
+ git commit -m "chore: release $VERSION"
24
+ fi
25
+ git tag "v$VERSION"
26
+ git push origin main
27
+ git push origin "v$VERSION"
28
+
29
+ echo "Pushed v$VERSION. Watch the release workflow with: gh run watch"
@@ -13,12 +13,13 @@ cd "$(git rev-parse --show-toplevel)"
13
13
  [ -f "$SPECSAIL_DIR/agents.env" ] && . "$SPECSAIL_DIR/agents.env"
14
14
 
15
15
  case "$ROLE" in
16
+ manage|first-mate) STAGE=manage; TITLE="Orchestrator"; CREW="First Mate" ;;
16
17
  understand|scout) STAGE=understand; TITLE="Product Owner"; CREW="Scout" ;;
17
18
  plan|navigator) STAGE=plan; TITLE="Tech Lead"; CREW="Navigator" ;;
18
19
  acceptance-tests|quartermaster) STAGE=acceptance-tests; TITLE="QA"; CREW="Quartermaster" ;;
19
20
  implement|hands) STAGE=implement; TITLE="Developer"; CREW="Hands" ;;
20
- review|first-mate) STAGE=review; TITLE="Reviewer"; CREW="First Mate" ;;
21
- ship|bosun) STAGE=ship; TITLE="Release"; CREW="Bosun" ;;
21
+ review|bosun) STAGE=review; TITLE="Reviewer"; CREW="Bosun" ;;
22
+ ship|clerk) STAGE=ship; TITLE="Release"; CREW="Clerk" ;;
22
23
  *) echo "Unknown stage or crew alias '$ROLE'." >&2; exit 1 ;;
23
24
  esac
24
25
 
@@ -8,6 +8,9 @@ metadata:
8
8
  # QA — Quartermaster (acceptance-tests)
9
9
  **Model tier:** frontier. **Isolated context: you do not see the plan or the implementation.** The Captain approves the tests before implementation begins.
10
10
 
11
+ ## Conversational mode
12
+ The First Mate (orchestrator) may run you in the same session. Read only the approved spec, glossary, and public interfaces; do not inspect the plan or implementation. Ask the Captain about test placement or harness details instead of reading the plan.
13
+
11
14
  ## Reads
12
15
  `AGENTS.md`, `specs/<feature>/spec.md` (must be APPROVED), glossary in `docs/project.md`, existing test harness/fixtures and public interfaces (only to write tests that run).
13
16
 
@@ -8,6 +8,9 @@ metadata:
8
8
  # Developer — Hands (implement)
9
9
  **Model tier:** mid/cheap. **One task per run.**
10
10
 
11
+ ## Conversational mode
12
+ The First Mate (orchestrator) may ask you to implement one task at a time in the same session. Keep to that task, run `make verify`, and report scope issues; the orchestrator handles gates and commits only as this skill allows.
13
+
11
14
  ## Reads
12
15
  `AGENTS.md`, `specs/<feature>/spec.md`, `plan.md` (your task only), `tasks.md`, `review.md` (if status is CHANGES_REQUESTED), `docs/architecture/<module>.md` for your module.
13
16
 
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: manage
3
+ description: Orchestrate the SpecSail workflow from a feature request to a merge-ready PR. Use whenever the user asks to add, change, or fix something non-trivial and expects the crew to run the process conversationally.
4
+ metadata:
5
+ specsail-title: Orchestrator
6
+ specsail-crew: First Mate
7
+ ---
8
+ # Orchestrator — First Mate (manage)
9
+ **Model tier:** frontier. **You run the ship; the Captain decides.** The human is the Captain and is the only one who approves artifacts or merges. You sequence the stages, ask questions, and report at each gate.
10
+
11
+ ## Reads
12
+ `AGENTS.md`, `.specsail/AGENTS.md`, `docs/project.md`, `docs/architecture.md`, the `Makefile`, `specs/<feature>/**`, and `.specsail/docs/workflow.md`. Before acting as a stage, read that stage's `SKILL.md` and follow it.
13
+
14
+ ## When to start
15
+ The user asked for a non-trivial change ("add authentication", "fix the lockout bug") and there is no finished feature for it. Trivial edits (typo, config, dependency bump) need only a normal change and `make verify`; say so and skip the workflow unless the user wants it.
16
+
17
+ ## 1. Bootstrap the project (once)
18
+ Check for the three things the workflow depends on:
19
+ - `docs/project.md` is filled in, not the starter skeleton.
20
+ - `docs/architecture.md` is filled in.
21
+ - `make verify` runs real project checks (not the `SPECSAIL_UNCONFIGURED_TEMPLATE` starter).
22
+
23
+ If any are missing or unconfigured, stop and interview the Captain in small batches:
24
+ - What does this project do, for whom, and what is explicitly out of scope?
25
+ - What are the main modules and their boundaries? Which invariants must no PR break?
26
+ - What are the real commands for setup, lint, typecheck, unit/integration tests, and acceptance tests?
27
+
28
+ Draft the missing files yourself from the answers and the repository. Never invent an invariant, a non-goal, or a command. Show the diff before saving. Configure the `Makefile` targets, run `npx specsail doctor` if available, and commit with `docs:`/`chore:` as appropriate. Only then continue.
29
+
30
+ ## 2. Start the feature
31
+ Ask the Captain for a short kebab-case slug if it is not obvious, and classify it:
32
+ - **FIX**: bug with a reproducible failure.
33
+ - **UPDATE**: an existing behavior changes.
34
+ - **NEW FEATURE**: new behavior.
35
+
36
+ Scaffold `specs/<slug>/` from `.specsail/templates/specs/_templates/`, or run `npx specsail new <slug> <fix|update|new>` if available. Commit the scaffold with the `spec:` prefix.
37
+
38
+ ## 3. Run the stages
39
+ Each stage is a role lens: read its `SKILL.md`, adopt its reads/writes/must-not rules, and stop where it says to stop. Ask the Captain questions at any stage; never guess an answer that belongs to them.
40
+
41
+ 1. **Scout (`understand`)** — clarify and write `request.md`. Confirm routing and open questions. Gate: Captain confirms the request.
42
+ 2. **Navigator (`plan`), spec mode** — write `spec.md` with observable `AC-n` criteria. Gate: Captain approves the spec.
43
+ 3. **Navigator, plan mode** — write `plan.md` and `tasks.md` from the approved spec. Gate: architecture decisions, if affected.
44
+ 4. **Quartermaster (`acceptance-tests`)** — write failing tests for this phase's ACs only. Gate: Captain approves the tests.
45
+ 5. **Hands (`implement`)** — one task at a time, TDD, `make verify` green, status `DEV_DONE`.
46
+ 6. **Bosun (`review`)** — independent review. Ask the Captain each time: open a second session/model for an independent review, or accept same-model review. If they accept, record the caveat in `review.md`. Rework up to three times.
47
+ 7. **Clerk (`ship`)** — docs, changelog, PR body. The Captain merges.
48
+
49
+ Do not skip a stage because the change "looks simple" or to save time. For FIX, still write the reproduction AC.
50
+
51
+ ## Gate protocol
52
+ - Present the artifact and ask: **"APPROVE, or what should change?"**
53
+ - Silence, a different topic, or "ok" about something else is not approval. Ask again.
54
+ - On explicit approval, record it in the artifact: `Status: APPROVED — Captain (chat), YYYY-MM-DD`. You are recording the Captain's decision, not making it. If the Captain edits the file directly, keep their wording and do not overwrite it.
55
+ - On changes, revise and return to the same gate. Never approve on the Captain's behalf, never merge, never weaken an acceptance test to get past a gate.
56
+
57
+ ## Resuming
58
+ Read `specs/*/` and `tasks.md`. If one feature is active, say where it is and continue from that stage. If several are active, ask which one. Use the "Where am I?" table in `.specsail/docs/runbook.md` when unsure.
59
+
60
+ ## Mechanical steps you may run
61
+ Scaffolding, stage commits with the required prefixes (`spec:`, `plan:`, `accept:`, `feat:`, `fix:`, `docs:`), `make verify`, `make check-protected`, and placeholder-free PR creation. Do not hand-edit protected artifacts outside their owning stage.
62
+
63
+ ## Must not
64
+ Implement outside the Hands stage; approve specs or tests; merge; invent requirements; skip the independent-review question; let the Captain's chat content be the only record when a file can carry the decision.
65
+
66
+ ## Done when
67
+ The PR is open, docs are current, and the Captain has what they need to merge.
68
+
69
+ ## Escalate when
70
+ The spec is contradictory or untestable, a gate stalls, or review hits three loops. Write `specs/<feature>/blocked.md`, set the task `BLOCKED`, and stop for the Captain.
@@ -8,6 +8,9 @@ metadata:
8
8
  # Tech Lead — Navigator (plan)
9
9
  **Model tier:** frontier. **Two modes, chosen by state. Stop at the end of each mode.** The human is the Captain; agents never approve artifacts.
10
10
 
11
+ ## Conversational mode
12
+ When the First Mate (orchestrator) runs this stage, present the artifact and ask the Captain to approve or request changes. Record their explicit decision as described in `.specsail/skills/manage/SKILL.md`; never infer approval.
13
+
11
14
  ## Reads
12
15
  `AGENTS.md`, `docs/project.md`, `docs/architecture.md`, `specs/<feature>/request.md`; in plan mode also the approved `spec.md` and `docs/architecture/<module>.md` for modules in request.md.
13
16
 
@@ -3,11 +3,14 @@ name: review
3
3
  description: Review a task's or phase's diff against spec and plan. Use after a task reaches DEV_DONE.
4
4
  metadata:
5
5
  specsail-title: Reviewer
6
- specsail-crew: First Mate
6
+ specsail-crew: Bosun
7
7
  ---
8
- # Reviewer — First Mate (review)
8
+ # Reviewer — Bosun (review)
9
9
  **Model tier:** frontier, preferably a different model family than the implementer. **Report only, never fix.**
10
10
 
11
+ ## Conversational mode
12
+ The First Mate (orchestrator) asks the Captain whether to run this review in a second session/model. If the Captain accepts a same-model review, record that caveat at the top of `review.md`. Never claim independent review when the same model implemented and reviewed.
13
+
11
14
  ## Reads
12
15
  `AGENTS.md`, `specs/<feature>/spec.md`, `plan.md`, `tasks.md`, the diff against the base branch, `docs/architecture.md` (invariants + boundaries), module doc for touched modules.
13
16
 
@@ -3,11 +3,14 @@ name: ship
3
3
  description: Prepare a phase for merge: docs, changelog, PR description. Use after all tasks of a phase are DONE. Prefer scripts for anything mechanical.
4
4
  metadata:
5
5
  specsail-title: Release
6
- specsail-crew: Bosun
6
+ specsail-crew: Clerk
7
7
  ---
8
- # Release — Bosun (ship)
8
+ # Release — Clerk (ship)
9
9
  **Model tier:** cheap. **Mostly mechanical; the Captain merges.**
10
10
 
11
+ ## Conversational mode
12
+ The First Mate (orchestrator) runs the mechanical steps and reports the PR link. The Captain reviews the diff and merges; never merge on the Captain's behalf.
13
+
11
14
  ## Reads
12
15
  `AGENTS.md`, `specs/<feature>/spec.md`, `plan.md`, `tasks.md`, the phase diff, current README / API docs / changelog / `docs/project.md` / `docs/architecture.md`.
13
16
 
@@ -8,6 +8,9 @@ metadata:
8
8
  # Product Owner — Scout (understand)
9
9
  **Model tier:** frontier. **Interactive with the human.**
10
10
 
11
+ ## Conversational mode
12
+ The First Mate (orchestrator) may hand you an already-started conversation. Ask the Captain in small batches, most important first, and stop when the request is confirmed; the orchestrator handles the remaining stages.
13
+
11
14
  ## Reads
12
15
  `AGENTS.md`, `docs/project.md`, `docs/architecture.md`, the raw request, `specs/<feature>/request.md` (template).
13
16
 
package/src/cli.js CHANGED
@@ -5,6 +5,7 @@ import { fileURLToPath } from "node:url";
5
5
 
6
6
  const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
7
7
  const stageRoles = ["understand", "plan", "acceptance-tests", "implement", "review", "ship"];
8
+ const skillRoles = ["manage", ...stageRoles];
8
9
  const typeNames = {
9
10
  fix: "FIX",
10
11
  update: "FEATURE UPDATE",
@@ -180,7 +181,7 @@ async function init(cwd, output, root) {
180
181
  await updateManagedBlock(
181
182
  path.join(cwd, "AGENTS.md"),
182
183
  ["<!-- specsail:start -->", "<!-- specsail:end -->"],
183
- "## SpecSail\n\nThis project uses SpecSail, a Captain-led, spec-driven development workflow. Read .specsail/AGENTS.md for project workflow rules. For the assigned stage, read the matching skill in .specsail/skills/<stage>/SKILL.md. The human Captain approves specs and acceptance tests and merges pull requests; agents must not take those gates.",
184
+ "## SpecSail\n\nThis project uses SpecSail, a Captain-led, spec-driven development workflow. When the user asks for a non-trivial feature, fix, or update, start the workflow before writing code: read .specsail/skills/manage/SKILL.md and follow it. The First Mate orchestrates the crew; the human Captain answers questions, approves specs and acceptance tests, and merges. Commands are optional. Read .specsail/AGENTS.md for the crew and rules.",
184
185
  cwd,
185
186
  );
186
187
  await updateManagedBlock(
@@ -192,7 +193,7 @@ async function init(cwd, output, root) {
192
193
  config.version = JSON.parse(await readFile(path.join(root, "package.json"), "utf8")).version;
193
194
  await writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`, "utf8");
194
195
  writeLine(output, `SpecSail initialized (${config.version}). Added ${created} file(s); left ${skipped} existing file(s) unchanged.`);
195
- writeLine(output, "Next: fill docs/project.md and docs/architecture.md, configure Makefile, then run specsail doctor.");
196
+ writeLine(output, "Next: open your coding agent and ask for a change. The First Mate will check the project docs and Makefile, ask what is missing, and start the workflow.");
196
197
  return 0;
197
198
  }
198
199
 
@@ -222,7 +223,7 @@ async function newFeature(cwd, args, output) {
222
223
  } catch (error) {
223
224
  throw new Error(`Could not scaffold specs/${slug}: ${error.message}. Remove the partial directory before retrying.`);
224
225
  }
225
- writeLine(output, `Created specs/${slug}/. Next: run ".specsail/scripts/run-agent.sh understand ${slug}" with your agent, or read the Scout skill.`);
226
+ writeLine(output, `Created specs/${slug}/. Next: ask your agent to start the SpecSail workflow for ${slug}; the First Mate will continue from the request stage.`);
226
227
  return 0;
227
228
  }
228
229
 
@@ -246,7 +247,7 @@ async function doctor(cwd, output, error) {
246
247
  for (const [label, filePath] of checks) {
247
248
  if (!(await exists(filePath))) failures.push(`Missing ${label}; run specsail init.`);
248
249
  }
249
- for (const stage of stageRoles) {
250
+ for (const stage of skillRoles) {
250
251
  const skill = path.join(cwd, ".specsail/skills", stage, "SKILL.md");
251
252
  if (!(await exists(skill))) failures.push(`Missing ${path.relative(cwd, skill)}; run specsail init.`);
252
253
  }
@@ -260,6 +261,8 @@ async function doctor(cwd, output, error) {
260
261
  const agents = await exists(path.join(cwd, "AGENTS.md")) ? await readFile(path.join(cwd, "AGENTS.md"), "utf8") : "";
261
262
  if (!agents.includes("<!-- specsail:start -->") || !agents.includes("<!-- specsail:end -->")) {
262
263
  failures.push("AGENTS.md is missing the SpecSail managed section; run specsail init.");
264
+ } else if (!agents.includes("skills/manage/SKILL.md")) {
265
+ failures.push("AGENTS.md does not start the conversational workflow; update the SpecSail section or run specsail init again.");
263
266
  }
264
267
  if (!(await hasGitRepository(cwd))) writeLine(error, "Warning: no .git directory found. Initialize version control before starting a feature.");
265
268
  if (failures.length) {
@@ -2,18 +2,29 @@
2
2
 
3
3
  This project follows the SpecSail workflow. The human is the **Captain** and is the only person who approves specs, approves acceptance tests, or merges pull requests. Agents must stop at those gates and ask the Captain to act.
4
4
 
5
+ ## Conversational mode
6
+
7
+ When the user asks for a non-trivial change, fix, or feature, run the workflow instead of writing code immediately:
8
+
9
+ 1. Read `.specsail/skills/manage/SKILL.md` and follow it.
10
+ 2. If `docs/project.md`, `docs/architecture.md`, or the `Makefile` verify target are missing or unconfigured, bootstrap them with the Captain's answers first.
11
+ 3. Run the stages in order and stop at each gate. Chat approvals are recorded in the artifact with the Captain's name and date.
12
+
13
+ The user does not need to run commands. `npx specsail init/new/doctor` and `.specsail/scripts/*` are optional shortcuts.
14
+
5
15
  ## Crew and skills
6
16
 
7
- | Stage | Development role | Crew name | Skill |
17
+ | Skill | Development role | Crew alias | Purpose |
8
18
  |---|---|---|---|
9
- | Understand | Product Owner | Scout | `.specsail/skills/understand/SKILL.md` |
10
- | Plan | Tech Lead | Navigator | `.specsail/skills/plan/SKILL.md` |
11
- | Acceptance tests | QA | Quartermaster | `.specsail/skills/acceptance-tests/SKILL.md` |
12
- | Implement | Developer | Hands | `.specsail/skills/implement/SKILL.md` |
13
- | Review | Reviewer | First Mate | `.specsail/skills/review/SKILL.md` |
14
- | Ship | Release | Bosun | `.specsail/skills/ship/SKILL.md` |
19
+ | `manage` | Orchestrator | First Mate | Runs the workflow, bootstraps the project, sequences stages and gates. |
20
+ | `understand` | Product Owner | Scout | Turns the request into `request.md`. |
21
+ | `plan` | Tech Lead | Navigator | Writes `spec.md`, then `plan.md` and `tasks.md`. |
22
+ | `acceptance-tests` | QA | Quartermaster | Writes failing acceptance tests from approved criteria. |
23
+ | `implement` | Developer | Hands | Implements one planned task. |
24
+ | `review` | Reviewer | Bosun | Reviews independently with evidence. |
25
+ | `ship` | Release | Clerk | Updates docs, changelog, and opens the PR. |
15
26
 
16
- Use the stage name in files and commands. The crew name is a human-friendly alias. If an agent tool cannot load skills automatically, tell it to read this file and the relevant `SKILL.md` directly.
27
+ The Captain is a human, not an agent. If an agent tool cannot load skills automatically, tell it to read `.specsail/skills/<skill>/SKILL.md` directly.
17
28
 
18
29
  ## Workflow
19
30
 
@@ -24,7 +35,7 @@ Use the stage name in files and commands. The crew name is a human-friendly alia
24
35
  - Protected files are approved `spec.md`, `plan.md`, and `tests/acceptance/**`. Only the owning stage may edit them; commits use `spec:`, `plan:`, or `accept:` prefixes.
25
36
  - If the request/spec is ambiguous or an acceptance criterion is unworkable, write `specs/<feature>/blocked.md` and stop. Never silently reinterpret an approved spec or weaken a test.
26
37
  - Implement one planned task at a time. Do not broaden scope. Run `make verify` before marking a task `DEV_DONE`.
27
- - Review must be independent of implementation and report evidence; it does not fix code. The Captain merges.
38
+ - Review is independent of implementation and reports evidence; it does not fix code. The Captain merges.
28
39
  - Update docs in the same PR as the code change.
29
40
 
30
41
  See `.specsail/docs/workflow.md` for stage definitions and `.specsail/docs/runbook.md` for operating steps.
@@ -2,24 +2,38 @@
2
2
 
3
3
  Step-by-step operating guide. `.specsail/docs/workflow.md` is the concise reference.
4
4
 
5
- ## Start a feature
5
+ ## Talk to the First Mate
6
+
7
+ In your coding agent, ask for the change in normal language: *"let's add user authentication"* or *"fix the login lockout bug."* The agent reads `.specsail/skills/manage/SKILL.md` and starts the workflow:
8
+
9
+ 1. Checks `docs/project.md`, `docs/architecture.md`, and the `Makefile` verify target. If they are missing or still starter templates, it interviews you and drafts them.
10
+ 2. Scaffolds `specs/<slug>/`, asks any questions, and runs Scout, Navigator, Quartermaster, Hands, Bosun, and Clerk in order.
11
+ 3. Stops at each gate: request confirmed, spec approved, tests approved, architecture approved when affected, and merge. Approve in chat; the agent records the decision with your name and date.
12
+
13
+ Commands are optional. Use them if you prefer manual control, CI, or scripting.
14
+
15
+ ## Run stages manually (optional)
6
16
 
7
17
  ```sh
8
18
  ./.specsail/scripts/start-phase.sh <slug> 1
9
19
  ./.specsail/scripts/new-feature.sh <slug> <fix|update|new>
20
+ ./.specsail/scripts/run-agent.sh scout <slug>
21
+ ./.specsail/scripts/run-agent.sh navigator <slug>
22
+ ./.specsail/scripts/run-agent.sh quartermaster <slug> "AC-1,AC-2"
23
+ ./.specsail/scripts/run-agent.sh hands <slug> T-1
24
+ ./.specsail/scripts/run-agent.sh bosun <slug> T-1
25
+ ./.specsail/scripts/run-agent.sh clerk <slug>
26
+ ./.specsail/scripts/open-pr.sh <slug> 1
10
27
  ```
11
28
 
12
- If you prefer not to create a branch yet, run only `new-feature.sh`. Trivial changes can use a normal PR and `make verify` without feature artifacts.
29
+ Stage names also work: `understand`, `plan`, `acceptance-tests`, `implement`, `review`, `ship`. The orchestrator is `manage` / `first-mate`.
13
30
 
14
- ## Run the crew
31
+ ## Gates and review
15
32
 
16
- 1. **Scout / Product Owner:** `./.specsail/scripts/run-agent.sh understand <slug>`. Give it the raw request, answer its questions, and confirm the routing. Exit when the request is complete and open questions are resolved or explicitly deferred.
17
- 2. **Navigator / Tech Lead, spec mode:** run `./.specsail/scripts/run-agent.sh plan <slug>`. The Captain reviews every acceptance criterion and sets `Status: APPROVED` in `spec.md`.
18
- 3. **Navigator / Tech Lead, plan mode:** run the same command again after approval. Check every criterion maps to tasks and each task has a verification command. The Captain reviews architecture decisions when architecture is affected.
19
- 4. **Quartermaster / QA:** `./.specsail/scripts/run-agent.sh acceptance-tests <slug> "AC-1,AC-2"`. The Captain checks tests fail for the intended missing behavior and approves them before implementation.
20
- 5. **Hands / Developer:** `./.specsail/scripts/run-agent.sh implement <slug> T-1`. One task per run. Check scope and protected paths.
21
- 6. **First Mate / Reviewer:** `./.specsail/scripts/run-agent.sh review <slug> T-1`. Use a different model family than the implementer. Rework findings up to three times, then escalate.
22
- 7. **Bosun / Release:** `./.specsail/scripts/run-agent.sh ship <slug>`, then `./.specsail/scripts/open-pr.sh <slug> 1`. The Captain checks CI and merges.
33
+ - **Spec:** the Captain reviews every acceptance criterion and approves before planning.
34
+ - **Tests:** the Captain checks the phase's tests fail for the right reason before implementation.
35
+ - **Review:** the First Mate asks whether to use a second session/model. If you accept same-model review, the caveat is recorded in `review.md`.
36
+ - **Merge:** the Captain checks CI, protected paths, and docs, then merges.
23
37
 
24
38
  For later phases, create the phase branch with `start-phase.sh <slug> <phase>`, then write and approve that phase's acceptance tests before implementation.
25
39
 
@@ -1,21 +1,30 @@
1
1
  # SpecSail workflow reference
2
2
 
3
- SpecSail uses durable Markdown artifacts to carry intent between stages. The Captain is the human who owns the approval and merge gates.
3
+ SpecSail uses durable Markdown artifacts to carry intent between stages. The Captain is the human who owns the approval and merge gates. The First Mate (`manage`) runs the workflow conversationally; the other stages are role lenses it adopts.
4
4
 
5
5
  ## Stages and crew
6
6
 
7
- | # | Stage / skill | Development role — crew alias | Reads | Writes |
7
+ | # | Skill | Development role — crew alias | Reads | Writes |
8
8
  |---|---|---|---|---|
9
+ | 0 | manage | Orchestrator — First Mate | project docs, Makefile, feature state | bootstrap docs, sequencing, gate records |
9
10
  | 1 | understand | Product Owner — Scout | project, architecture, request | `request.md` |
10
11
  | 2a | plan (spec mode) | Tech Lead — Navigator | project, architecture, request | `spec.md` |
11
12
  | 2b | plan (plan mode) | Tech Lead — Navigator | approved spec, module docs | `plan.md`, `tasks.md` |
12
13
  | 3 | acceptance-tests | QA — Quartermaster | approved spec, glossary, public interfaces | `tests/acceptance/<feature>/**` |
13
14
  | 4 | implement | Developer — Hands | spec, plan, tasks, review, module docs | code, unit tests, task status |
14
- | 5 | review | Reviewer — First Mate | spec, plan, tasks, diff, invariants | review report, task status |
15
- | 6 | ship | Release — Bosun | spec, plan, tasks, diff | docs, changelog, PR |
15
+ | 5 | review | Reviewer — Bosun | spec, plan, tasks, diff, invariants | review report, task status |
16
+ | 6 | ship | Release — Clerk | spec, plan, tasks, diff | docs, changelog, PR |
16
17
 
17
18
  The human Captain is not an agent role. Agents may prepare work for a gate, but only the Captain approves `spec.md`, approves each phase's acceptance tests, and merges.
18
19
 
20
+ ## Conversational operation
21
+
22
+ The Captain starts with a normal request ("let's add user authentication"). The First Mate checks project context, bootstraps missing docs/Makefile settings with the Captain's answers, scaffolds the feature, then runs the stages in order. The Captain answers questions and approves artifacts in chat; commands are optional.
23
+
24
+ **Recording approvals:** on explicit approval, the agent records `Status: APPROVED — Captain (chat), YYYY-MM-DD` in the artifact. The Captain's decision is the approval; the file is the evidence. Silence is not approval.
25
+
26
+ **Review independence:** the First Mate asks the Captain whether to review in a second session/model. If the Captain accepts a same-model review, the caveat is recorded in `review.md`.
27
+
19
28
  ## Change paths
20
29
 
21
30
  | Type | Path |
@@ -28,7 +37,7 @@ The human Captain is not an agent role. Agents may prepare work for a gate, but
28
37
  ## Human gates
29
38
 
30
39
  1. Confirm the request and resolve or explicitly defer open questions.
31
- 2. Review and approve `spec.md` before planning by setting `Status: APPROVED`.
40
+ 2. Review and approve `spec.md` before planning.
32
41
  3. Review and approve acceptance tests for the current phase before implementation.
33
42
  4. Merge only after CI is green, review is done, protected paths are clean, and docs are current.
34
43
 
@@ -38,10 +47,10 @@ Architecture decisions require Captain approval when the plan says architecture
38
47
 
39
48
  `TODO → IN_PROGRESS → DEV_DONE → DONE`; rework uses `CHANGES_REQUESTED`; an unresolved issue uses `BLOCKED` plus `blocked.md`. After three review iterations, stop and escalate to the Captain.
40
49
 
41
- A task is done when `make verify` is green, linked acceptance criteria pass, required docs are updated, and the First Mate marks it `DONE`.
50
+ A task is done when `make verify` is green, linked acceptance criteria pass, required docs are updated, and the Bosun marks it `DONE`.
42
51
 
43
52
  ## Parallel work and review
44
53
 
45
54
  - Define API contracts before parallel multi-app work; independent tasks may use separate worktrees.
46
55
  - Do not parallelize tasks that touch the same module or shared task-status rows.
47
- - CI is deterministic verification; First Mate review checks behavior and invariants; the Captain merges.
56
+ - CI is deterministic verification; Bosun review checks behavior and invariants; the Captain merges.
@@ -6,6 +6,7 @@ import { test } from "node:test";
6
6
  import { runCli } from "../../src/cli.js";
7
7
 
8
8
  const packageRoot = new URL("../../", import.meta.url).pathname;
9
+ const manifest = JSON.parse(await readFile(new URL("../../package.json", import.meta.url), "utf8"));
9
10
 
10
11
  async function temporaryProject() {
11
12
  return mkdtemp(path.join(os.tmpdir(), "specsail-test-"));
@@ -40,8 +41,12 @@ test("init preserves project-owned files, installs the crew, and is repeatable",
40
41
  assert.equal(await readFile(path.join(cwd, "docs/project.md"), "utf8"), "# My existing project\n");
41
42
  assert.match(await readFile(path.join(cwd, "AGENTS.md"), "utf8"), /<!-- specsail:start -->/);
42
43
  assert.match(await readFile(path.join(cwd, ".specsail/skills/understand/SKILL.md"), "utf8"), /Scout/);
44
+ assert.match(await readFile(path.join(cwd, ".specsail/skills/manage/SKILL.md"), "utf8"), /First Mate/);
45
+ assert.match(await readFile(path.join(cwd, ".specsail/skills/review/SKILL.md"), "utf8"), /Bosun/);
46
+ assert.match(await readFile(path.join(cwd, ".specsail/skills/ship/SKILL.md"), "utf8"), /Clerk/);
47
+ assert.match(await readFile(path.join(cwd, "AGENTS.md"), "utf8"), /skills\/manage\/SKILL\.md/);
43
48
  assert.match(await readFile(path.join(cwd, ".gitignore"), "utf8"), /\.specsail\/agents\.env/);
44
- assert.deepEqual(JSON.parse(await readFile(path.join(cwd, ".specsail.json"), "utf8")), { version: "0.1.0", localSetting: true });
49
+ assert.deepEqual(JSON.parse(await readFile(path.join(cwd, ".specsail.json"), "utf8")), { version: manifest.version, localSetting: true });
45
50
 
46
51
  const second = streams();
47
52
  assert.equal(await runCli(["init"], { cwd, ...second.options }), 0);
@@ -91,6 +96,19 @@ test("doctor verifies the kit and the project's verify command", async (context)
91
96
  assert.match(afterConfig.stdout(), /files and verify target are present/);
92
97
  });
93
98
 
99
+ test("doctor flags an AGENTS.md that does not start the conversational workflow", async (context) => {
100
+ const cwd = await temporaryProject();
101
+ context.after(() => rm(cwd, { recursive: true, force: true }));
102
+ const initialized = streams();
103
+ assert.equal(await runCli(["init"], { cwd, ...initialized.options }), 0);
104
+ await writeFile(path.join(cwd, "Makefile"), "verify:\n\t@echo configured\n", "utf8");
105
+ const agentsPath = path.join(cwd, "AGENTS.md");
106
+ await writeFile(agentsPath, (await readFile(agentsPath, "utf8")).replace("skills/manage/SKILL.md", "AGENTS.md"), "utf8");
107
+ const result = streams();
108
+ assert.equal(await runCli(["doctor"], { cwd, ...result.options }), 1);
109
+ assert.match(result.stderr(), /does not start the conversational workflow/);
110
+ });
111
+
94
112
  test("init refuses to write through a symlinked SpecSail directory", async (context) => {
95
113
  const cwd = await temporaryProject();
96
114
  const outside = await temporaryProject();
package/test/cli.test.js CHANGED
@@ -1,8 +1,10 @@
1
1
  import assert from "node:assert/strict";
2
+ import { readFile } from "node:fs/promises";
2
3
  import { test } from "node:test";
3
4
  import { runCli } from "../src/cli.js";
4
5
 
5
6
  const root = new URL("../", import.meta.url).pathname;
7
+ const manifest = JSON.parse(await readFile(new URL("../package.json", import.meta.url), "utf8"));
6
8
 
7
9
  test("help and version are available without initializing a project", async () => {
8
10
  let stdout = "";
@@ -11,7 +13,7 @@ test("help and version are available without initializing a project", async () =
11
13
  assert.equal(await runCli(["--help"], options), 0);
12
14
  assert.match(stdout, /Captain is always human/);
13
15
  assert.equal(await runCli(["--version"], options), 0);
14
- assert.match(stdout, /0\.1\.0/);
16
+ assert.match(stdout, new RegExp(manifest.version.replaceAll(".", "\\.")));
15
17
  assert.equal(stderr, "");
16
18
  });
17
19
 
@@ -0,0 +1,17 @@
1
+ import assert from "node:assert/strict";
2
+ import { existsSync } from "node:fs";
3
+ import { readFile } from "node:fs/promises";
4
+ import { test } from "node:test";
5
+
6
+ const workflowPath = new URL("../.github/workflows/release.yml", import.meta.url);
7
+ const shipped = existsSync(workflowPath);
8
+
9
+ test("release workflow publishes with OIDC and provenance", { skip: !shipped && "release workflow is not included in the published tarball" }, async () => {
10
+ const workflow = await readFile(workflowPath, "utf8");
11
+ assert.match(workflow, /^on:\s*\n\s*push:\s*\n\s*tags:\s*\["v\*"\]/m);
12
+ assert.match(workflow, /^\s*id-token:\s*write$/m);
13
+ assert.match(workflow, /^\s*contents:\s*write$/m);
14
+ assert.match(workflow, /^\s*environment:\s*npm$/m);
15
+ assert.match(workflow, /npm publish --access public --provenance/);
16
+ assert.doesNotMatch(workflow, /NODE_AUTH_TOKEN|NPM_TOKEN|secrets\./);
17
+ });