@trieungoctam/speckit 0.1.0 → 0.2.2

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.
Files changed (40) hide show
  1. package/README.md +16 -1
  2. package/dist/adapters/antigravity-adapter.js +5 -5
  3. package/dist/adapters/claude-code-adapter.js +8 -5
  4. package/dist/adapters/codex-adapter.js +5 -3
  5. package/dist/adapters/cursor-adapter.js +6 -3
  6. package/dist/adapters/opencode-adapter.js +1 -0
  7. package/dist/adapters/tool-checks.js +0 -1
  8. package/dist/cli.js +24 -2
  9. package/dist/commands/close.d.ts +6 -0
  10. package/dist/commands/close.js +34 -0
  11. package/dist/commands/context.d.ts +6 -0
  12. package/dist/commands/context.js +87 -0
  13. package/dist/commands/doctor.d.ts +1 -0
  14. package/dist/commands/doctor.js +29 -1
  15. package/dist/commands/init.d.ts +1 -0
  16. package/dist/commands/init.js +5 -3
  17. package/dist/commands/plan.js +19 -2
  18. package/dist/commands/quick.js +20 -2
  19. package/dist/commands/ready.d.ts +7 -0
  20. package/dist/commands/ready.js +20 -0
  21. package/dist/commands/run.js +19 -24
  22. package/dist/commands/start.d.ts +6 -0
  23. package/dist/commands/start.js +47 -0
  24. package/dist/commands/sync.js +2 -8
  25. package/dist/commands/triage.d.ts +6 -0
  26. package/dist/commands/triage.js +33 -0
  27. package/dist/core/readiness.d.ts +13 -0
  28. package/dist/core/readiness.js +120 -0
  29. package/dist/core/scaffold.d.ts +1 -0
  30. package/dist/core/scaffold.js +107 -2
  31. package/dist/core/story.d.ts +13 -0
  32. package/dist/core/story.js +67 -0
  33. package/docs/development-roadmap.md +8 -7
  34. package/docs/product-contract.md +5 -5
  35. package/docs/project-changelog.md +67 -1
  36. package/docs/release-checklist.md +2 -2
  37. package/docs/spec-enterprise-harness-plan.md +68 -0
  38. package/docs/spec-quality-gates.md +70 -0
  39. package/docs/system-architecture.md +1 -1
  40. package/package.json +1 -1
@@ -1,42 +1,37 @@
1
- import { access } from "node:fs/promises";
2
- import { join } from "node:path";
1
+ import { resolveStory } from "../core/story.js";
2
+ import { evaluateReadiness } from "../core/readiness.js";
3
3
  export async function runCommand(options) {
4
4
  const stdout = options.stdout ?? console;
5
- const storyPath = await resolveStory(options.root, options.target);
6
- if (!storyPath) {
5
+ const story = await resolveStory(options.root, options.target);
6
+ if (!story) {
7
7
  stdout.error(`Story not found: ${options.target}`);
8
8
  return 1;
9
9
  }
10
+ const readiness = await evaluateReadiness(options.root, options.target);
11
+ if (readiness.status !== "ready") {
12
+ stdout.error(`Story is not ready for implementation: ${story.path}`);
13
+ for (const check of readiness.checks.filter((item) => !item.ok)) {
14
+ stdout.error(`- ${check.name}: ${check.detail}`);
15
+ }
16
+ stdout.error(`Run \`speckit ready ${story.id}\` after preparing context and sync.`);
17
+ return 1;
18
+ }
10
19
  stdout.log(`# Speckit TDD Run
11
20
 
12
- Story: ${storyPath}
21
+ Story: ${story.path}
22
+
23
+ Status: ready-for-dev
13
24
 
14
- 1. Read the story and acceptance criteria.
25
+ 1. Read \`.speckit/context/current.md\`, story, acceptance criteria, and subagent handoff.
15
26
  2. Identify the smallest executable test that should fail.
16
- 3. Record red evidence in the matching \`.speckit/evidence/*tdd-evidence.md\` file.
27
+ 3. Record red evidence in the linked TDD evidence file.
17
28
  4. Implement the minimal behavior.
18
29
  5. Record green evidence.
19
30
  6. Refactor only after tests are green, then record validation.
31
+ 7. Continue until all acceptance criteria are satisfied or a stop condition is hit.
20
32
 
21
33
  Recommended handoff:
22
34
  \`speckit review\` before commit or PR.
23
35
  `);
24
36
  return 0;
25
37
  }
26
- async function resolveStory(root, target) {
27
- const candidates = [
28
- target,
29
- `.speckit/stories/${target}`,
30
- `.speckit/stories/${target}.md`,
31
- ];
32
- for (const candidate of candidates) {
33
- try {
34
- await access(join(root, candidate));
35
- return candidate;
36
- }
37
- catch {
38
- // Try the next candidate.
39
- }
40
- }
41
- return undefined;
42
- }
@@ -0,0 +1,6 @@
1
+ export type StartOptions = {
2
+ root: string;
3
+ intent: string;
4
+ stdout?: Pick<typeof console, "log">;
5
+ };
6
+ export declare function startCommand(options: StartOptions): Promise<number>;
@@ -0,0 +1,47 @@
1
+ import { markdown, writeManagedFiles } from "../core/managed-files.js";
2
+ import { slugify, timestamp } from "../core/slug.js";
3
+ export async function startCommand(options) {
4
+ const stdout = options.stdout ?? console;
5
+ const sessionId = `${timestamp()}-${slugify(options.intent)}`;
6
+ const handoffPath = `.speckit/sessions/${sessionId}/handoff.md`;
7
+ const contextPath = ".speckit/context/current.md";
8
+ await writeManagedFiles(options.root, [
9
+ {
10
+ path: handoffPath,
11
+ content: markdown(`# Spec Session: ${sessionId}
12
+
13
+ ## Idea
14
+ ${options.intent}
15
+
16
+ ## Current Phase
17
+ shape
18
+
19
+ ## Linked Artifacts
20
+ - Context: \`${contextPath}\`
21
+
22
+ ## Next Command
23
+ \`speckit shape "${options.intent}"\`
24
+ `),
25
+ },
26
+ {
27
+ path: contextPath,
28
+ content: markdown(`# Current Spec Context
29
+
30
+ ## Session
31
+ ${sessionId}
32
+
33
+ ## Idea
34
+ ${options.intent}
35
+
36
+ ## Active Artifact
37
+ \`${handoffPath}\`
38
+
39
+ ## Next Command
40
+ \`speckit shape "${options.intent}"\`
41
+ `),
42
+ },
43
+ ], true);
44
+ stdout.log(sessionId);
45
+ stdout.log(handoffPath);
46
+ return 0;
47
+ }
@@ -1,6 +1,7 @@
1
1
  import { readdir, readFile } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
  import { markdown, writeManagedFiles } from "../core/managed-files.js";
4
+ import { firstHeading, frontmatterValue } from "../core/story.js";
4
5
  export async function syncCommand(options) {
5
6
  const stdout = options.stdout ?? console;
6
7
  const storiesDir = join(options.root, ".speckit", "stories");
@@ -19,7 +20,7 @@ export async function syncCommand(options) {
19
20
  id: entry.replace(/\.md$/, ""),
20
21
  path: `.speckit/stories/${entry}`,
21
22
  title: firstHeading(content) ?? entry.replace(/\.md$/, ""),
22
- status: content.includes("- [ ]") ? "open" : "ready-for-review",
23
+ status: frontmatterValue(content, "status") ?? (content.includes("- [ ]") ? "open" : "ready-for-review"),
23
24
  });
24
25
  }
25
26
  const jsonl = stories.map((story) => JSON.stringify(story)).join("\n");
@@ -45,10 +46,3 @@ bv --robot-next --format json
45
46
  stdout.log(`Synced ${stories.length} stories to .speckit/sync/beads-sync.jsonl`);
46
47
  return 0;
47
48
  }
48
- function firstHeading(content) {
49
- return content
50
- .split("\n")
51
- .find((line) => line.startsWith("# "))
52
- ?.replace(/^#\s+/, "")
53
- .trim();
54
- }
@@ -0,0 +1,6 @@
1
+ export type TriageOptions = {
2
+ root: string;
3
+ json?: boolean;
4
+ stdout?: Pick<typeof console, "log" | "error">;
5
+ };
6
+ export declare function triageCommand(options: TriageOptions): Promise<number>;
@@ -0,0 +1,33 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ export async function triageCommand(options) {
4
+ const stdout = options.stdout ?? console;
5
+ const stories = await readSyncedStories(options.root);
6
+ const open = stories.filter((story) => ["open", "ready-for-dev", "in-progress"].includes(story.status));
7
+ const ready = stories.filter((story) => story.status !== "open");
8
+ const report = {
9
+ source: ".speckit/sync/beads-sync.jsonl",
10
+ open: open.length,
11
+ ready: ready.length,
12
+ next: open[0] ?? null,
13
+ };
14
+ if (options.json) {
15
+ stdout.log(JSON.stringify(report, null, 2));
16
+ return 0;
17
+ }
18
+ stdout.log(`Spec triage: ${open.length} open, ${ready.length} ready`);
19
+ stdout.log(open[0] ? `Next: ${open[0].id} (${open[0].path})` : "Next: none");
20
+ return 0;
21
+ }
22
+ async function readSyncedStories(root) {
23
+ try {
24
+ const content = await readFile(join(root, ".speckit", "sync", "beads-sync.jsonl"), "utf8");
25
+ return content
26
+ .split("\n")
27
+ .filter(Boolean)
28
+ .map((line) => JSON.parse(line));
29
+ }
30
+ catch {
31
+ return [];
32
+ }
33
+ }
@@ -0,0 +1,13 @@
1
+ import { StoryResolution } from "./story.js";
2
+ export type ReadinessCheck = {
3
+ name: string;
4
+ ok: boolean;
5
+ detail: string;
6
+ };
7
+ export type ReadinessReport = {
8
+ story?: Pick<StoryResolution, "id" | "path" | "title" | "status" | "evidencePath">;
9
+ checks: ReadinessCheck[];
10
+ status: "ready" | "blocked";
11
+ };
12
+ export declare function evaluateReadiness(root: string, target: string): Promise<ReadinessReport>;
13
+ export declare function evidenceStatus(root: string, evidencePath: string | undefined): Promise<string | undefined>;
@@ -0,0 +1,120 @@
1
+ import { access, readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { extractSection, frontmatterValue, resolveStory } from "./story.js";
4
+ export async function evaluateReadiness(root, target) {
5
+ const story = await resolveStory(root, target);
6
+ if (!story) {
7
+ return {
8
+ checks: [{ name: "story", ok: false, detail: `Story not found: ${target}` }],
9
+ status: "blocked",
10
+ };
11
+ }
12
+ const evidencePath = story.evidencePath;
13
+ const checks = [
14
+ {
15
+ name: "story-status",
16
+ ok: story.status === "ready-for-dev",
17
+ detail: story.status ? `status=${story.status}` : "status missing",
18
+ },
19
+ {
20
+ name: "acceptance-criteria",
21
+ ok: hasActionableAcceptanceCriteria(story.content),
22
+ detail: "story has testable acceptance criteria",
23
+ },
24
+ {
25
+ name: "evidence-link",
26
+ ok: Boolean(evidencePath),
27
+ detail: evidencePath ?? "missing TDD evidence reference",
28
+ },
29
+ {
30
+ name: "evidence-file",
31
+ ok: evidencePath ? await fileExists(root, evidencePath) : false,
32
+ detail: evidencePath ?? "missing TDD evidence reference",
33
+ },
34
+ {
35
+ name: "context",
36
+ ok: await contextIsFreshForStory(root, story.path),
37
+ detail: ".speckit/context/current.md links this story and is fresh",
38
+ },
39
+ {
40
+ name: "graph-sync",
41
+ ok: await graphContainsStory(root, story.path),
42
+ detail: ".speckit/sync/beads-sync.jsonl contains this story",
43
+ },
44
+ {
45
+ name: "tool-policy",
46
+ ok: await fileExists(root, ".speckit/tool-policy.yaml"),
47
+ detail: ".speckit/tool-policy.yaml",
48
+ },
49
+ {
50
+ name: "safety-policy",
51
+ ok: await fileExists(root, ".speckit/rules/enterprise-safety.md"),
52
+ detail: ".speckit/rules/enterprise-safety.md",
53
+ },
54
+ ];
55
+ return {
56
+ story: {
57
+ id: story.id,
58
+ path: story.path,
59
+ title: story.title,
60
+ status: story.status,
61
+ evidencePath,
62
+ },
63
+ checks,
64
+ status: checks.every((check) => check.ok) ? "ready" : "blocked",
65
+ };
66
+ }
67
+ function hasActionableAcceptanceCriteria(content) {
68
+ const criteria = extractSection(content, "Acceptance Criteria");
69
+ if (!criteria)
70
+ return false;
71
+ return /Given .+|When .+|Then .+|\d+\./i.test(criteria) && !criteria.includes("...");
72
+ }
73
+ async function contextIsFreshForStory(root, storyPath) {
74
+ try {
75
+ const content = await readFile(join(root, ".speckit", "context", "current.md"), "utf8");
76
+ return content.includes("status: fresh") && content.includes(storyPath);
77
+ }
78
+ catch {
79
+ return false;
80
+ }
81
+ }
82
+ async function graphContainsStory(root, storyPath) {
83
+ try {
84
+ const content = await readFile(join(root, ".speckit", "sync", "beads-sync.jsonl"), "utf8");
85
+ return content
86
+ .split("\n")
87
+ .filter(Boolean)
88
+ .some((line) => {
89
+ try {
90
+ return JSON.parse(line).path === storyPath;
91
+ }
92
+ catch {
93
+ return false;
94
+ }
95
+ });
96
+ }
97
+ catch {
98
+ return false;
99
+ }
100
+ }
101
+ async function fileExists(root, path) {
102
+ try {
103
+ await access(join(root, path));
104
+ return true;
105
+ }
106
+ catch {
107
+ return false;
108
+ }
109
+ }
110
+ export async function evidenceStatus(root, evidencePath) {
111
+ if (!evidencePath)
112
+ return undefined;
113
+ try {
114
+ const content = await readFile(join(root, evidencePath), "utf8");
115
+ return frontmatterValue(content, "status");
116
+ }
117
+ catch {
118
+ return undefined;
119
+ }
120
+ }
@@ -1,2 +1,3 @@
1
1
  import { ManagedFile } from "./managed-files.js";
2
2
  export declare function coreFiles(): ManagedFile[];
3
+ export declare function enterpriseFiles(): ManagedFile[];
@@ -27,7 +27,13 @@ adapters:
27
27
  { path: ".speckit/workflows/review.md", content: markdown(workflowReview) },
28
28
  {
29
29
  path: ".speckit/templates/story.md",
30
- content: markdown(`# Story: {{title}}
30
+ content: markdown(`---
31
+ status: draft
32
+ evidence: .speckit/evidence/{{slug}}-tdd-evidence.md
33
+ context: pending
34
+ ---
35
+
36
+ # Story: {{title}}
31
37
 
32
38
  ## Intent
33
39
  {{intent}}
@@ -46,11 +52,23 @@ adapters:
46
52
  ## Notes
47
53
  - Risks:
48
54
  - Dependencies:
55
+
56
+ ## Spec Anti-Mistake Checklist
57
+ - Reuse existing project patterns before adding new files.
58
+ - Verify file locations before editing.
59
+ - Do not introduce new libraries without explicit need.
60
+ - Preserve existing behavior unless an acceptance criterion requires change.
61
+ - Capture previous-story learnings if this continues prior work.
49
62
  `),
50
63
  },
51
64
  {
52
65
  path: ".speckit/templates/tdd-evidence.md",
53
- content: markdown(`# TDD Evidence: {{story}}
66
+ content: markdown(`---
67
+ status: missing
68
+ story: {{story}}
69
+ ---
70
+
71
+ # TDD Evidence: {{story}}
54
72
 
55
73
  ## Test Intent
56
74
 
@@ -69,3 +87,90 @@ adapters:
69
87
  },
70
88
  ];
71
89
  }
90
+ export function enterpriseFiles() {
91
+ return [
92
+ {
93
+ path: ".speckit/flows/spec-flow.md",
94
+ content: markdown(`# Spec Flow
95
+
96
+ ## Order
97
+ start -> shape -> plan -> context -> sync -> triage -> run -> review -> close
98
+
99
+ ## Traceability
100
+ - A session links the original idea to every downstream artifact.
101
+ - A story links acceptance criteria to TDD evidence.
102
+ - Sync links stories to graph-ready JSONL.
103
+ - Close links review output back to story and graph sync.
104
+ `),
105
+ },
106
+ {
107
+ path: ".speckit/tool-policy.yaml",
108
+ content: text(`version: 1
109
+ phases:
110
+ shape:
111
+ may_edit_code: false
112
+ plan:
113
+ may_edit_code: false
114
+ run:
115
+ may_edit_code: true
116
+ requires_tdd_evidence: true
117
+ review:
118
+ may_edit_code: false
119
+ graph:
120
+ robot_only: true`),
121
+ },
122
+ {
123
+ path: ".speckit/prompts/spec-run.md",
124
+ content: markdown(`# Spec Run Prompt
125
+
126
+ ## Required Inputs
127
+
128
+ - Current context: \`.speckit/context/current.md\`
129
+ - Subagent handoff: \`.speckit/context/subagent-handoff.md\`
130
+ - Story with acceptance criteria
131
+ - Matching TDD evidence file
132
+ - Tool policy: \`.speckit/tool-policy.yaml\`
133
+
134
+ ## Status Preconditions
135
+
136
+ - Story status is \`ready-for-dev\`.
137
+ - Context status is \`fresh\`.
138
+ - \`speckit ready <story>\` returns ready.
139
+
140
+ ## Allowed Edits
141
+
142
+ - Implementation files needed for the story.
143
+ - Matching tests.
144
+ - Linked TDD evidence file.
145
+ - Story completion checkboxes and implementation notes.
146
+
147
+ ## Execution Contract
148
+
149
+ Use the red-green-refactor loop.
150
+
151
+ 1. Read the current context before touching code.
152
+ 2. Confirm the story path, acceptance criteria, and evidence path.
153
+ 3. Write or run the smallest failing test first.
154
+ 4. Record red evidence before implementation.
155
+ 5. Implement the smallest change that satisfies the failing test.
156
+ 6. Record green evidence after tests pass.
157
+ 7. Refactor only while tests stay green, then record validation.
158
+ 8. Use graph commands only through robot-safe flags such as \`bv --robot-next --format json\`.
159
+ 9. Run \`speckit review\` before handoff.
160
+
161
+ ## Stop Conditions
162
+
163
+ - Stop if acceptance criteria are missing.
164
+ - Stop if the evidence file cannot be identified.
165
+ - Stop if \`speckit ready <story>\` reports blocked.
166
+ - Stop before destructive commands, production changes, or secret access.
167
+
168
+ ## Completion Signal
169
+
170
+ - All acceptance criteria satisfied.
171
+ - TDD evidence status can be advanced through red, green, and refactor.
172
+ - Review handoff is ready.
173
+ `),
174
+ },
175
+ ];
176
+ }
@@ -0,0 +1,13 @@
1
+ export type StoryResolution = {
2
+ path: string;
3
+ content: string;
4
+ id: string;
5
+ title: string;
6
+ status?: string;
7
+ evidencePath?: string;
8
+ };
9
+ export declare function resolveStory(root: string, target: string): Promise<StoryResolution | undefined>;
10
+ export declare function frontmatterValue(content: string, key: string): string | undefined;
11
+ export declare function extractEvidenceReference(content: string): string | undefined;
12
+ export declare function extractSection(content: string, heading: string): string | undefined;
13
+ export declare function firstHeading(content: string): string | undefined;
@@ -0,0 +1,67 @@
1
+ import { access, readFile } from "node:fs/promises";
2
+ import { basename, join } from "node:path";
3
+ export async function resolveStory(root, target) {
4
+ const candidates = [
5
+ target,
6
+ `.speckit/stories/${target}`,
7
+ `.speckit/stories/${target}.md`,
8
+ ];
9
+ for (const candidate of candidates) {
10
+ try {
11
+ const fullPath = join(root, candidate);
12
+ await access(fullPath);
13
+ const content = await readFile(fullPath, "utf8");
14
+ return {
15
+ path: candidate,
16
+ content,
17
+ id: basename(candidate).replace(/\.md$/, ""),
18
+ title: firstHeading(content) ?? basename(candidate).replace(/\.md$/, ""),
19
+ status: frontmatterValue(content, "status"),
20
+ evidencePath: frontmatterValue(content, "evidence") ?? extractEvidenceReference(content),
21
+ };
22
+ }
23
+ catch {
24
+ // Try the next candidate.
25
+ }
26
+ }
27
+ return undefined;
28
+ }
29
+ export function frontmatterValue(content, key) {
30
+ const lines = content.split("\n");
31
+ const start = lines.findIndex((line) => line.trim() === "---");
32
+ if (start === -1)
33
+ return undefined;
34
+ const end = lines.findIndex((line, index) => index > start && line.trim() === "---");
35
+ if (end === -1)
36
+ return undefined;
37
+ const prefix = `${key}:`;
38
+ const found = lines
39
+ .slice(start + 1, end)
40
+ .find((line) => line.trim().toLowerCase().startsWith(prefix.toLowerCase()));
41
+ return found?.slice(found.indexOf(":") + 1).trim().replace(/^["']|["']$/g, "");
42
+ }
43
+ export function extractEvidenceReference(content) {
44
+ const match = content.match(/`([^`]*tdd-evidence\.md)`/i);
45
+ return match?.[1];
46
+ }
47
+ export function extractSection(content, heading) {
48
+ const lines = content.split("\n");
49
+ const start = lines.findIndex((line) => line.trim().toLowerCase() === `## ${heading}`.toLowerCase());
50
+ if (start === -1)
51
+ return undefined;
52
+ const collected = [];
53
+ for (const line of lines.slice(start + 1)) {
54
+ if (line.startsWith("## "))
55
+ break;
56
+ if (line.trim())
57
+ collected.push(line);
58
+ }
59
+ return collected.length > 0 ? collected.join("\n") : undefined;
60
+ }
61
+ export function firstHeading(content) {
62
+ return content
63
+ .split("\n")
64
+ .find((line) => line.startsWith("# "))
65
+ ?.replace(/^#\s+/, "")
66
+ .trim();
67
+ }
@@ -4,9 +4,9 @@
4
4
 
5
5
  Speckit MVP is implemented and pushed to `git@github.com:trieungoctam/speckit.git` on `main`.
6
6
 
7
- Current package target: `@trieungoctam/speckit@0.1.0`.
7
+ Current package target: `@trieungoctam/speckit@0.2.2`.
8
8
 
9
- The CLI is npx-ready, generates Agile + TDD rules, creates workflow artifacts, supports five IDE adapters, wraps Beads Viewer safely, and has automated tests plus CI.
9
+ The CLI is npx-ready, generates Agile + TDD rules, creates workflow artifacts, supports five IDE adapters, wraps Beads Viewer safely, includes an enterprise harness, and has automated prompt/readiness tests plus CI.
10
10
 
11
11
  ## Milestones
12
12
 
@@ -14,17 +14,18 @@ The CLI is npx-ready, generates Agile + TDD rules, creates workflow artifacts, s
14
14
  | --- | --- | --- |
15
15
  | Product contract | Complete | Contract, workflow model, and command surface documented. |
16
16
  | CLI scaffold | Complete | `bin/speckit`, TypeScript build, command router, managed file writer. |
17
- | Workflow engine | MVP Complete | `shape`, `plan`, `quick`, `run`, and `review` generate usable artifacts. |
17
+ | Workflow engine | Complete | `start`, `shape`, `plan`, `context`, `quick`, `sync`, `triage`, `ready`, `run`, `review`, and `close` generate linked artifacts. |
18
18
  | IDE adapters | Complete | Claude Code, Codex, Antigravity, OpenCode, Cursor. |
19
19
  | Beads integration | MVP Complete | `next` wraps BV robot mode; `sync` exports story metadata JSONL. |
20
- | Validation | Complete | Build and `node:test` suite pass locally. |
20
+ | Enterprise harness | MVP Complete | `init --enterprise` creates flow, tool-policy, and prompt harness files; `doctor --deep` verifies them. |
21
+ | Validation | Complete | Build and `node:test` suite pass locally with flow contract gates. |
21
22
  | GitHub publish | Complete | Initial code pushed to `trieungoctam/speckit` at commit `7e5c582`; status docs follow-up in progress. |
22
23
  | npm package readiness | Ready | Package scoped as `@trieungoctam/speckit`; `npm pack --dry-run` passes. |
23
24
 
24
25
  ## Next Roadmap
25
26
 
26
- - Publish `@trieungoctam/speckit` to npm.
27
+ - Expand Speckit Enterprise Harness with richer profile and context-pack layers.
28
+ - Add `review --deep` with blind, edge-case, and acceptance audit prompts.
29
+ - Add graph commands: `graph-plan`, `insights`, and `drift`.
27
30
  - Add GitHub trusted publishing for npm releases.
28
- - Add richer config loading from `.speckit/config.yaml`.
29
- - Add optional direct `br`/`bd` import once command compatibility is pinned.
30
31
  - Add snapshot tests for full adapter file contents.
@@ -5,7 +5,7 @@ Speckit owns the workflow contract for enterprise Agile + TDD development with a
5
5
  ## Speckit Owns
6
6
 
7
7
  - The `.speckit/` source of truth: config, rules, workflows, templates, generated artifacts.
8
- - The command surface: `init`, `doctor`, `shape`, `plan`, `quick`, `next`, `sync`, `run`, `review`.
8
+ - The command surface: `init`, `doctor`, `start`, `shape`, `plan`, `context`, `quick`, `sync`, `triage`, `next`, `ready`, `run`, `review`, `close`.
9
9
  - The TDD gate: code stories require red, green, and refactor evidence.
10
10
  - The adapter compiler for Claude Code, Codex, Antigravity, OpenCode, and Cursor.
11
11
  - The safety policy for destructive commands, secrets, production access, and review readiness.
@@ -13,15 +13,15 @@ Speckit owns the workflow contract for enterprise Agile + TDD development with a
13
13
  ## Speckit Delegates
14
14
 
15
15
  - Implementation to the selected IDE and agent runtime.
16
- - Product lifecycle inspiration to BMad-style phases, without copying BMad personas or branding.
17
- - Execution orchestration inspiration to ClaudeKit-style plan/cook/test/review flows.
16
+ - Product lifecycle, story readiness, and quality gates to Speckit-native phases.
17
+ - Execution orchestration to Speckit-native plan/run/test/review flows.
18
18
  - Task graph prioritization to beads and Beads Viewer robot commands.
19
19
  - Git, tests, CI, and deployment to project-local tooling.
20
20
 
21
21
  ## State Model
22
22
 
23
23
  ```text
24
- intake -> shaped -> planned -> sliced -> spec-ready -> tests-red -> running -> tests-green -> refactor -> review-ready -> closed
24
+ intake -> session -> shaped -> planned -> context-ready -> synced -> triaged -> ready-for-dev -> tests-red -> running -> tests-green -> refactor -> review-ready -> closed
25
25
  ```
26
26
 
27
- Implementation starts only after a story is spec-ready. Review starts only after test evidence exists.
27
+ Implementation starts only after `speckit ready <story>` passes. Review starts only after test evidence exists.