@trieungoctam/speckit 0.3.0 → 0.3.1

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/README.md CHANGED
@@ -21,6 +21,8 @@ npx @trieungoctam/speckit@latest context .speckit/stories/<story>.md
21
21
  npx @trieungoctam/speckit@latest sync
22
22
  npx @trieungoctam/speckit@latest sprint plan
23
23
  npx @trieungoctam/speckit@latest graph triage --json
24
+ npx @trieungoctam/speckit@latest validate --json
25
+ npx @trieungoctam/speckit@latest permissions audit --path .env --json
24
26
  npx @trieungoctam/speckit@latest ready .speckit/stories/<story>.md
25
27
  npx @trieungoctam/speckit@latest session checkpoint --note "red complete"
26
28
  npx @trieungoctam/speckit@latest review
@@ -68,9 +70,11 @@ For implementation stories, red-green-refactor evidence is mandatory. A story is
68
70
  | `speckit init --enterprise` | Add flow, tool policy, and prompt harness files on top of the shared runtime. |
69
71
  | `speckit init --ide <name>` | Generate shared Speckit runtime plus one adapter: `claude-code`, `codex`, `antigravity`, `opencode`, or `cursor`. |
70
72
  | `speckit doctor` | Report required tools, optional integrations, test commands, and adapter readiness. |
71
- | `speckit doctor --deep` | Verify core enterprise harness files. |
73
+ | `speckit doctor --deep` | Verify core enterprise harness files and workflow contract checks. |
74
+ | `speckit validate` | Validate flow order, core skills, super-agent routing, prompts, and installed adapter contracts. |
72
75
  | `speckit start "<idea>"` | Create a durable session handoff and current context. |
73
76
  | `speckit memory refresh` | Create durable project memory files for long-running agent work. |
77
+ | `speckit permissions audit` | Check a path or command against the Speckit permission policy. |
74
78
  | `speckit session start` | Create or resume the active session state. |
75
79
  | `speckit session checkpoint` | Append a long-session checkpoint and artifact log entry. |
76
80
  | `speckit session compact` | Create an anchored summary for resume or handoff. |
@@ -105,6 +109,12 @@ Speckit generates native instruction/config files for:
105
109
 
106
110
  See `docs/adapters.md` for exact output paths.
107
111
 
112
+ ## Guides
113
+
114
+ - `docs/use-cases.md` covers setup, migration, quick changes, full planning, long sessions, TDD, graph automation, review, CI, and troubleshooting.
115
+ - `docs/workflow-model.md` describes the quick and full workflow lanes.
116
+ - `docs/spec-quality-gates.md` describes validation gates for release readiness.
117
+
108
118
  ## Validation
109
119
 
110
120
  ```bash
@@ -34,6 +34,22 @@ Use Speckit for Agile + TDD work.
34
34
  content: json({
35
35
  permissions: {
36
36
  defaultMode: "ask",
37
+ deny: [
38
+ "Read(.env*)",
39
+ "Read(**/*.pem)",
40
+ "Read(**/*.key)",
41
+ "Read(**/id_rsa)",
42
+ "Read(**/id_ed25519)",
43
+ "Write(.env*)",
44
+ "Write(**/*.pem)",
45
+ "Write(**/*.key)",
46
+ "Bash(rm -rf*)",
47
+ "Bash(git reset --hard*)",
48
+ "Bash(git clean -fd*)",
49
+ "Bash(git push --force*)",
50
+ "Bash(sudo *)",
51
+ ],
52
+ ask: ["Bash(git push*)", "Bash(npm publish*)", "Bash(* deploy*)"],
37
53
  },
38
54
  includeCoAuthoredBy: false,
39
55
  }),
@@ -34,6 +34,8 @@ Rules:
34
34
  content: text(`model = "gpt-5.4"
35
35
  approval_policy = "on-request"
36
36
  sandbox_mode = "workspace-write"
37
+ allowed_approval_policies = ["untrusted", "on-request"]
38
+ allowed_sandbox_modes = ["read-only", "workspace-write"]
37
39
 
38
40
  [tools]
39
41
  web_search = true
@@ -8,6 +8,7 @@ export const cursorAdapter = {
8
8
  ".cursor/rules/speckit-review.mdc",
9
9
  ".cursor/rules/speckit-enterprise-safety.mdc",
10
10
  ".cursor/mcp.json",
11
+ ".cursor/cli.json",
11
12
  "AGENTS.md",
12
13
  ],
13
14
  render() {
@@ -22,6 +23,28 @@ export const cursorAdapter = {
22
23
  mcpServers: {},
23
24
  }),
24
25
  },
26
+ {
27
+ path: ".cursor/cli.json",
28
+ content: json({
29
+ permissions: {
30
+ allow: ["Shell(git)", "Shell(npm)", "Shell(node)", "Read(.speckit/**)", "Read(src/**)", "Read(tests/**)"],
31
+ deny: [
32
+ "Read(.env*)",
33
+ "Read(**/*.pem)",
34
+ "Read(**/*.key)",
35
+ "Read(**/id_rsa)",
36
+ "Read(**/id_ed25519)",
37
+ "Write(.env*)",
38
+ "Write(**/*.pem)",
39
+ "Write(**/*.key)",
40
+ "Shell(rm)",
41
+ "Shell(sudo)",
42
+ "Shell(chmod)",
43
+ "Shell(chown)",
44
+ ],
45
+ },
46
+ }),
47
+ },
25
48
  {
26
49
  path: "AGENTS.md",
27
50
  content: markdown(`# Speckit Agent Instructions
package/dist/cli.js CHANGED
@@ -6,9 +6,11 @@ import { contextCommand } from "./commands/context.js";
6
6
  import { quickCommand } from "./commands/quick.js";
7
7
  import { planCommand } from "./commands/plan.js";
8
8
  import { memoryCommand } from "./commands/memory.js";
9
+ import { permissionsCommand } from "./commands/permissions.js";
9
10
  import { sessionCommand } from "./commands/session.js";
10
11
  import { sprintCommand } from "./commands/sprint.js";
11
12
  import { graphCommand } from "./commands/graph.js";
13
+ import { validateCommand } from "./commands/validate.js";
12
14
  import { triageCommand } from "./commands/triage.js";
13
15
  import { nextCommand } from "./commands/next.js";
14
16
  import { syncCommand } from "./commands/sync.js";
@@ -41,6 +43,13 @@ export async function main(argv = process.argv.slice(2), root = process.cwd()) {
41
43
  return planCommand({ root, intent: requiredIntent(parsed) });
42
44
  case "memory":
43
45
  return memoryCommand({ root, action: requiredAction(parsed) });
46
+ case "permissions":
47
+ return permissionsCommand({
48
+ action: requiredAction(parsed),
49
+ path: value(parsed, "path"),
50
+ command: value(parsed, "command"),
51
+ json: has(parsed, "json"),
52
+ });
44
53
  case "session":
45
54
  return sessionCommand({
46
55
  root,
@@ -53,6 +62,8 @@ export async function main(argv = process.argv.slice(2), root = process.cwd()) {
53
62
  return sprintCommand({ root, action: requiredAction(parsed), json: has(parsed, "json") });
54
63
  case "graph":
55
64
  return graphCommand({ root, action: requiredAction(parsed), json: has(parsed, "json") });
65
+ case "validate":
66
+ return validateCommand({ root, json: has(parsed, "json") });
56
67
  case "triage":
57
68
  return triageCommand({ root, json: has(parsed, "json") });
58
69
  case "next":
@@ -136,9 +147,11 @@ Usage:
136
147
  speckit quick "<intent>"
137
148
  speckit plan "<intent>"
138
149
  speckit memory refresh
150
+ speckit permissions audit [--path <path>] [--command <command>] [--json]
139
151
  speckit session start|checkpoint|compact|resume|status [target] [--note "..."] [--json]
140
152
  speckit sprint plan|next [--json]
141
153
  speckit graph triage|plan|insights [--json]
154
+ speckit validate [--json]
142
155
  speckit triage [--json]
143
156
  speckit next
144
157
  speckit sync
@@ -5,11 +5,13 @@ import { checkTools } from "../adapters/tool-checks.js";
5
5
  import { detectTestCommands } from "../core/test-detection.js";
6
6
  import { coreFiles, enterpriseFiles } from "../core/scaffold.js";
7
7
  import { agentFiles } from "../core/agent-scaffold.js";
8
+ import { validateWorkflowContract } from "../core/workflow-validator.js";
8
9
  export async function doctorCommand(options) {
9
10
  const stdout = options.stdout ?? console;
10
11
  const tools = checkTools();
11
12
  const tests = await detectTestCommands(options.root);
12
13
  const deepChecks = options.deep ? await runDeepChecks(options.root) : [];
14
+ const contractChecks = options.deep ? await validateWorkflowContract(options.root) : [];
13
15
  const adapters = await Promise.all(getAdapters("all").map(async (adapter) => ({
14
16
  name: adapter.name,
15
17
  ...(await adapterStatus(options.root, adapter.outputPaths)),
@@ -19,8 +21,9 @@ export async function doctorCommand(options) {
19
21
  tools,
20
22
  tests,
21
23
  deepChecks,
24
+ contractChecks,
22
25
  adapters,
23
- status: statusFor(tools, deepChecks),
26
+ status: statusFor(tools, deepChecks, contractChecks),
24
27
  };
25
28
  if (options.json) {
26
29
  stdout.log(JSON.stringify(report, null, 2));
@@ -33,6 +36,9 @@ export async function doctorCommand(options) {
33
36
  for (const check of deepChecks) {
34
37
  stdout.log(`Deep ${check.name}: ${check.ok ? "ok" : "missing"}`);
35
38
  }
39
+ for (const check of contractChecks) {
40
+ stdout.log(`Contract ${check.name}: ${check.ok ? "ok" : check.detail}`);
41
+ }
36
42
  for (const adapter of adapters) {
37
43
  stdout.log(`Adapter ${adapter.name}: ${adapter.present}/${adapter.total} files present`);
38
44
  }
@@ -56,10 +62,11 @@ async function fileExists(root, path) {
56
62
  return false;
57
63
  }
58
64
  }
59
- function statusFor(tools, deepChecks) {
65
+ function statusFor(tools, deepChecks, contractChecks) {
60
66
  const requiredToolsMissing = tools.some((tool) => tool.required && !tool.available);
61
67
  const deepChecksMissing = deepChecks.some((check) => !check.ok);
62
- return requiredToolsMissing || deepChecksMissing ? "needs-attention" : "ok";
68
+ const contractChecksFailed = contractChecks.some((check) => !check.ok);
69
+ return requiredToolsMissing || deepChecksMissing || contractChecksFailed ? "needs-attention" : "ok";
63
70
  }
64
71
  async function adapterStatus(root, paths) {
65
72
  const missing = [];
@@ -0,0 +1,8 @@
1
+ export type PermissionsOptions = {
2
+ action: string;
3
+ path?: string;
4
+ command?: string;
5
+ json?: boolean;
6
+ stdout?: Pick<typeof console, "log" | "error">;
7
+ };
8
+ export declare function permissionsCommand(options: PermissionsOptions): Promise<number>;
@@ -0,0 +1,18 @@
1
+ import { auditPermission } from "../core/permission-auditor.js";
2
+ export async function permissionsCommand(options) {
3
+ const stdout = options.stdout ?? console;
4
+ if (options.action !== "audit") {
5
+ stdout.error?.(`Unknown permissions action: ${options.action}`);
6
+ return 1;
7
+ }
8
+ const result = auditPermission({ path: options.path, command: options.command });
9
+ if (options.json) {
10
+ stdout.log(JSON.stringify(result, null, 2));
11
+ }
12
+ else {
13
+ stdout.log(`Speckit permission audit: ${result.status}`);
14
+ for (const reason of result.reasons)
15
+ stdout.log(`- ${reason}`);
16
+ }
17
+ return result.status === "deny" ? 1 : 0;
18
+ }
@@ -0,0 +1,6 @@
1
+ export type ValidateOptions = {
2
+ root: string;
3
+ json?: boolean;
4
+ stdout?: Pick<typeof console, "log" | "error">;
5
+ };
6
+ export declare function validateCommand(options: ValidateOptions): Promise<number>;
@@ -0,0 +1,17 @@
1
+ import { validateWorkflowContract } from "../core/workflow-validator.js";
2
+ export async function validateCommand(options) {
3
+ const stdout = options.stdout ?? console;
4
+ const checks = await validateWorkflowContract(options.root);
5
+ const status = checks.every((check) => check.ok) ? "ok" : "needs-attention";
6
+ const report = { status, checks };
7
+ if (options.json) {
8
+ stdout.log(JSON.stringify(report, null, 2));
9
+ }
10
+ else {
11
+ stdout.log(`Speckit workflow contract: ${status}`);
12
+ for (const check of checks) {
13
+ stdout.log(`${check.ok ? "ok" : "fail"} ${check.name}: ${check.detail}`);
14
+ }
15
+ }
16
+ return status === "ok" ? 0 : 1;
17
+ }
@@ -0,0 +1,10 @@
1
+ export type PermissionAuditInput = {
2
+ path?: string;
3
+ command?: string;
4
+ };
5
+ export type PermissionAuditResult = {
6
+ status: "allow" | "ask" | "deny";
7
+ reasons: string[];
8
+ };
9
+ export declare function auditPermission(input: PermissionAuditInput): PermissionAuditResult;
10
+ export declare function validatePermissionPolicy(root: string): Promise<string[]>;
@@ -0,0 +1,65 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { basename, join } from "node:path";
3
+ import { destructiveCommands, heavyPatterns, releaseCommands, sensitivePatterns } from "./permission-policy.js";
4
+ const safeSecretSuffixes = [".example", ".sample", ".template"];
5
+ export function auditPermission(input) {
6
+ const reasons = [];
7
+ if (input.path) {
8
+ if (isSensitivePath(input.path))
9
+ reasons.push(`privacy:${input.path}`);
10
+ if (isHeavyPath(input.path))
11
+ reasons.push(`scout:${input.path}`);
12
+ }
13
+ if (input.command) {
14
+ if (matchesAny(input.command, destructiveCommands))
15
+ reasons.push(`destructive:${input.command}`);
16
+ if (matchesAny(input.command, releaseCommands)) {
17
+ return { status: reasons.length > 0 ? "deny" : "ask", reasons: [`release:${input.command}`, ...reasons] };
18
+ }
19
+ }
20
+ return reasons.length > 0 ? { status: "deny", reasons } : { status: "allow", reasons };
21
+ }
22
+ export async function validatePermissionPolicy(root) {
23
+ const content = await read(join(root, ".speckit/permissions.yaml"));
24
+ const missing = [];
25
+ if (!content)
26
+ return ["missing .speckit/permissions.yaml"];
27
+ for (const token of ["precedence:", "privacy:", "scout:", "destructive:", "release:", "file_write: ask"]) {
28
+ if (!content.includes(token))
29
+ missing.push(token);
30
+ }
31
+ for (const pattern of [".env", "node_modules", "git reset --hard*", "npm publish*"]) {
32
+ if (!content.includes(pattern))
33
+ missing.push(pattern);
34
+ }
35
+ return missing;
36
+ }
37
+ function isSensitivePath(path) {
38
+ const clean = normalize(path);
39
+ const name = basename(clean);
40
+ if (safeSecretSuffixes.some((suffix) => name.endsWith(suffix)))
41
+ return false;
42
+ return sensitivePatterns.some((pattern) => matchGlob(clean, pattern));
43
+ }
44
+ function isHeavyPath(path) {
45
+ const parts = normalize(path).split("/");
46
+ return heavyPatterns.some((pattern) => parts.includes(pattern.replace(/"/g, "")));
47
+ }
48
+ function matchesAny(command, patterns) {
49
+ return patterns.some((pattern) => matchGlob(command.trim(), pattern));
50
+ }
51
+ function matchGlob(value, pattern) {
52
+ const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, ".*").replace(/\*/g, ".*");
53
+ return new RegExp(`^${escaped}$`).test(value) || new RegExp(escaped).test(value);
54
+ }
55
+ function normalize(value) {
56
+ return value.replace(/\\/g, "/");
57
+ }
58
+ async function read(path) {
59
+ try {
60
+ return await readFile(path, "utf8");
61
+ }
62
+ catch {
63
+ return undefined;
64
+ }
65
+ }
@@ -0,0 +1,6 @@
1
+ import { ManagedFile } from "./managed-files.js";
2
+ export declare const sensitivePatterns: string[];
3
+ export declare const heavyPatterns: string[];
4
+ export declare const destructiveCommands: string[];
5
+ export declare const releaseCommands: string[];
6
+ export declare function permissionPolicyFile(): ManagedFile;
@@ -0,0 +1,93 @@
1
+ import { text } from "./managed-files.js";
2
+ export const sensitivePatterns = [
3
+ ".env",
4
+ ".env.*",
5
+ "**/.env",
6
+ "**/.env.*",
7
+ "**/credentials*",
8
+ "**/secret.yml",
9
+ "**/secrets.yml",
10
+ "**/secret.yaml",
11
+ "**/secrets.yaml",
12
+ "**/*.pem",
13
+ "**/*.key",
14
+ "**/id_rsa",
15
+ "**/id_ed25519",
16
+ ];
17
+ export const heavyPatterns = [
18
+ "node_modules",
19
+ "dist",
20
+ "build",
21
+ ".next",
22
+ ".nuxt",
23
+ "__pycache__",
24
+ ".venv",
25
+ "venv",
26
+ "vendor",
27
+ "target",
28
+ ".git",
29
+ "coverage",
30
+ ];
31
+ export const destructiveCommands = [
32
+ "rm -rf*",
33
+ "git reset --hard*",
34
+ "git clean -fd*",
35
+ "git push --force*",
36
+ "sudo *",
37
+ "chmod -R*",
38
+ "chown -R*",
39
+ ];
40
+ export const releaseCommands = ["git push*", "npm publish*", "* deploy*", "vercel --prod*", "fly deploy*"];
41
+ export function permissionPolicyFile() {
42
+ return {
43
+ path: ".speckit/permissions.yaml",
44
+ content: text(`version: 1
45
+ mode: enterprise
46
+ precedence:
47
+ - deny
48
+ - ask
49
+ - allow
50
+ defaults:
51
+ file_read: allow_workspace
52
+ file_write: ask
53
+ shell: ask
54
+ network: ask
55
+ external_directory: deny
56
+ guards:
57
+ privacy:
58
+ action: deny
59
+ allow_examples: true
60
+ patterns:
61
+ ${sensitivePatterns.map((pattern) => ` - "${pattern}"`).join("\n")}
62
+ scout:
63
+ action: deny
64
+ patterns:
65
+ ${heavyPatterns.map((pattern) => ` - "${pattern}"`).join("\n")}
66
+ destructive:
67
+ action: deny
68
+ commands:
69
+ ${destructiveCommands.map((command) => ` - "${command}"`).join("\n")}
70
+ release:
71
+ action: ask
72
+ commands:
73
+ ${releaseCommands.map((command) => ` - "${command}"`).join("\n")}
74
+ phases:
75
+ shape:
76
+ file_write:
77
+ - ".speckit/specs/**"
78
+ plan:
79
+ file_write:
80
+ - ".speckit/plans/**"
81
+ - ".speckit/stories/**"
82
+ - ".speckit/evidence/**"
83
+ review:
84
+ file_write: deny
85
+ shell_allow:
86
+ - "git diff*"
87
+ - "git log*"
88
+ - "npm test*"
89
+ ship:
90
+ shell_ask:
91
+ ${releaseCommands.map((command) => ` - "${command}"`).join("\n")}`),
92
+ };
93
+ }
@@ -1,5 +1,6 @@
1
1
  import { markdown, text } from "./managed-files.js";
2
2
  import { agilePolicy, enterpriseSafetyPolicy, tddPolicy, workflowReview, workflowShape, workflowTddRun, } from "./policy.js";
3
+ import { permissionPolicyFile } from "./permission-policy.js";
3
4
  import { storyTemplate, tddEvidenceTemplate } from "./templates.js";
4
5
  export function coreFiles() {
5
6
  return [
@@ -31,6 +32,7 @@ adapters:
31
32
  path: ".speckit/rules/enterprise-safety.md",
32
33
  content: markdown(enterpriseSafetyPolicy),
33
34
  },
35
+ permissionPolicyFile(),
34
36
  { path: ".speckit/workflows/shape.md", content: markdown(workflowShape) },
35
37
  { path: ".speckit/workflows/tdd-run.md", content: markdown(workflowTddRun) },
36
38
  { path: ".speckit/workflows/review.md", content: markdown(workflowReview) },
@@ -1,2 +1,3 @@
1
1
  import { ManagedFile } from "./managed-files.js";
2
2
  export declare function specSkillFiles(): ManagedFile[];
3
+ export declare function specSkillNames(): string[];
@@ -87,6 +87,9 @@ function skill(name, phase, purpose, practices) {
87
87
  export function specSkillFiles() {
88
88
  return [catalogFile(), schemaFile(), ...skills.map(skillFile)];
89
89
  }
90
+ export function specSkillNames() {
91
+ return skills.map((skill) => skill.name);
92
+ }
90
93
  function catalogFile() {
91
94
  return {
92
95
  path: ".speckit/skills/catalog.md",
@@ -0,0 +1,7 @@
1
+ export declare const workflowContract: {
2
+ readonly phases: readonly ["start", "memory", "sprint", "context", "sync", "triage", "ready", "run", "checkpoint", "review", "close"];
3
+ readonly skills: string[];
4
+ readonly statuses: readonly ["DONE", "DONE_WITH_CONCERNS", "BLOCKED", "NEEDS_CONTEXT"];
5
+ readonly requiredPromptTerms: readonly [readonly ["project memory", ".speckit/memory/project-context.md"], readonly ["active session", ".speckit/sessions/active.md"], readonly ["current context", ".speckit/context/current.md"], readonly ["subagent handoff", ".speckit/context/subagent-handoff.md"], readonly ["acceptance criteria", "AC coverage", "ACs"], readonly ["red-green-refactor", "red/green/refactor"], readonly ["checkpoint", "speckit session checkpoint"], readonly ["compact", "compaction", "speckit session compact"], readonly ["robot-safe", "bv --robot", "robot commands"], readonly ["ready-for-dev", "speckit ready"]];
6
+ readonly requiredRouterTerms: readonly ["smallest matching Speckit skill", "Work context path", "Reports path", "Plans path", "Hydrate runtime tasks", "Sync completed runtime tasks"];
7
+ };
@@ -0,0 +1,38 @@
1
+ import { specSkillNames } from "./skill-catalog.js";
2
+ export const workflowContract = {
3
+ phases: [
4
+ "start",
5
+ "memory",
6
+ "sprint",
7
+ "context",
8
+ "sync",
9
+ "triage",
10
+ "ready",
11
+ "run",
12
+ "checkpoint",
13
+ "review",
14
+ "close",
15
+ ],
16
+ skills: specSkillNames(),
17
+ statuses: ["DONE", "DONE_WITH_CONCERNS", "BLOCKED", "NEEDS_CONTEXT"],
18
+ requiredPromptTerms: [
19
+ ["project memory", ".speckit/memory/project-context.md"],
20
+ ["active session", ".speckit/sessions/active.md"],
21
+ ["current context", ".speckit/context/current.md"],
22
+ ["subagent handoff", ".speckit/context/subagent-handoff.md"],
23
+ ["acceptance criteria", "AC coverage", "ACs"],
24
+ ["red-green-refactor", "red/green/refactor"],
25
+ ["checkpoint", "speckit session checkpoint"],
26
+ ["compact", "compaction", "speckit session compact"],
27
+ ["robot-safe", "bv --robot", "robot commands"],
28
+ ["ready-for-dev", "speckit ready"],
29
+ ],
30
+ requiredRouterTerms: [
31
+ "smallest matching Speckit skill",
32
+ "Work context path",
33
+ "Reports path",
34
+ "Plans path",
35
+ "Hydrate runtime tasks",
36
+ "Sync completed runtime tasks",
37
+ ],
38
+ };
@@ -0,0 +1,6 @@
1
+ export type ContractCheck = {
2
+ name: string;
3
+ ok: boolean;
4
+ detail: string;
5
+ };
6
+ export declare function validateWorkflowContract(root: string): Promise<ContractCheck[]>;
@@ -0,0 +1,133 @@
1
+ import { access, readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { getAdapters } from "../config/adapter-registry.js";
4
+ import { validatePermissionPolicy } from "./permission-auditor.js";
5
+ import { workflowContract } from "./workflow-contract.js";
6
+ export async function validateWorkflowContract(root) {
7
+ const checks = [];
8
+ const catalog = await read(root, ".speckit/skills/catalog.md");
9
+ const router = await read(root, ".speckit/agents/super-agent.md");
10
+ const flow = await read(root, ".speckit/flows/spec-flow.md");
11
+ const runPrompt = await read(root, ".speckit/prompts/spec-run.md");
12
+ checks.push(requiredFile(".speckit/skills/catalog.md", catalog));
13
+ checks.push(requiredFile(".speckit/agents/super-agent.md", router));
14
+ checks.push(requiredFile(".speckit/flows/spec-flow.md", flow));
15
+ checks.push(requiredFile(".speckit/prompts/spec-run.md", runPrompt));
16
+ checks.push(await skillsCheck(root, catalog));
17
+ checks.push(containsAll("super-agent router", router, workflowContract.requiredRouterTerms));
18
+ checks.push(orderedFlowCheck(flow));
19
+ checks.push(containsAll("enterprise run prompt", runPrompt, workflowContract.requiredPromptTerms));
20
+ checks.push(await permissionPolicyCheck(root));
21
+ checks.push(await adapterPromptCheck(root));
22
+ return checks;
23
+ }
24
+ async function permissionPolicyCheck(root) {
25
+ const missing = await validatePermissionPolicy(root);
26
+ return {
27
+ name: "permission policy",
28
+ ok: missing.length === 0,
29
+ detail: missing.length === 0 ? "aligned" : `missing: ${missing.join(", ")}`,
30
+ };
31
+ }
32
+ function requiredFile(path, content) {
33
+ return {
34
+ name: path,
35
+ ok: content !== undefined,
36
+ detail: content === undefined ? "missing" : "present",
37
+ };
38
+ }
39
+ async function skillsCheck(root, catalog) {
40
+ const missing = [];
41
+ for (const skill of workflowContract.skills) {
42
+ if (!(await exists(root, `.speckit/skills/${skill}.md`)) || !catalog?.includes(skill)) {
43
+ missing.push(skill);
44
+ }
45
+ }
46
+ return {
47
+ name: "core skills",
48
+ ok: missing.length === 0,
49
+ detail: missing.length === 0 ? `${workflowContract.skills.length} skills aligned` : `missing: ${missing.join(", ")}`,
50
+ };
51
+ }
52
+ function orderedFlowCheck(flow) {
53
+ if (!flow)
54
+ return { name: "workflow phase order", ok: false, detail: "flow file missing" };
55
+ let cursor = -1;
56
+ const missing = [];
57
+ for (const phase of workflowContract.phases) {
58
+ const next = flow.indexOf(phase, cursor + 1);
59
+ if (next === -1) {
60
+ missing.push(phase);
61
+ continue;
62
+ }
63
+ cursor = next;
64
+ }
65
+ return {
66
+ name: "workflow phase order",
67
+ ok: missing.length === 0,
68
+ detail: missing.length === 0 ? workflowContract.phases.join(" -> ") : `missing or out of order: ${missing.join(", ")}`,
69
+ };
70
+ }
71
+ function containsAll(name, content, terms) {
72
+ const haystack = content?.toLowerCase() ?? "";
73
+ const missing = terms.filter((term) => !matchesTerm(haystack, term)).map(termLabel);
74
+ return {
75
+ name,
76
+ ok: missing.length === 0,
77
+ detail: missing.length === 0 ? "aligned" : `missing: ${missing.join(", ")}`,
78
+ };
79
+ }
80
+ function matchesTerm(haystack, term) {
81
+ const alternatives = Array.isArray(term) ? term : [term];
82
+ return alternatives.some((alternative) => haystack.includes(alternative.toLowerCase()));
83
+ }
84
+ function termLabel(term) {
85
+ return typeof term === "string" ? term : term[0];
86
+ }
87
+ async function adapterPromptCheck(root) {
88
+ const missing = [];
89
+ const checked = [];
90
+ for (const adapter of getAdapters("all")) {
91
+ const content = await readExisting(root, adapter.outputPaths);
92
+ if (!content)
93
+ continue;
94
+ checked.push(adapter.name);
95
+ const check = containsAll(adapter.name, content, workflowContract.requiredPromptTerms);
96
+ if (!check.ok)
97
+ missing.push(`${adapter.name} (${check.detail})`);
98
+ }
99
+ if (checked.length === 0) {
100
+ return { name: "adapter prompt contracts", ok: false, detail: "no adapter files found" };
101
+ }
102
+ return {
103
+ name: "adapter prompt contracts",
104
+ ok: missing.length === 0,
105
+ detail: missing.length === 0 ? `aligned: ${checked.join(", ")}` : missing.join("; "),
106
+ };
107
+ }
108
+ async function readExisting(root, paths) {
109
+ const chunks = [];
110
+ for (const path of paths) {
111
+ const content = await read(root, path);
112
+ if (content)
113
+ chunks.push(content);
114
+ }
115
+ return chunks.length > 0 ? chunks.join("\n") : undefined;
116
+ }
117
+ async function read(root, path) {
118
+ try {
119
+ return await readFile(join(root, path), "utf8");
120
+ }
121
+ catch {
122
+ return undefined;
123
+ }
124
+ }
125
+ async function exists(root, path) {
126
+ try {
127
+ await access(join(root, path));
128
+ return true;
129
+ }
130
+ catch {
131
+ return false;
132
+ }
133
+ }
@@ -4,7 +4,7 @@
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.3.0`.
7
+ Current package target: `@trieungoctam/speckit@0.3.1`.
8
8
 
9
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/session tests plus CI.
10
10
 
@@ -21,6 +21,8 @@ The CLI is npx-ready, generates Agile + TDD rules, creates workflow artifacts, s
21
21
  | Sprint automation | MVP Complete | `sprint plan` and `sprint next` select work from synced stories. |
22
22
  | Enterprise harness | MVP Complete | `init --enterprise` creates flow, tool-policy, and prompt harness files; `doctor --deep` verifies them. |
23
23
  | Curated skill catalog | Complete | Speckit now generates focused phase skills, a schema, delegation statuses, and task hydration/sync-back guidance. |
24
+ | Workflow contract validator | Complete | `speckit validate` and `doctor --deep` check phase order, core skills, router terms, run prompt terms, and adapter parity. |
25
+ | Permission policy | MVP Complete | `.speckit/permissions.yaml` and `permissions audit` cover privacy files, heavy paths, destructive commands, and release commands. |
24
26
  | Validation | Complete | Build and `node:test` suite pass locally with flow contract gates. |
25
27
  | GitHub publish | Complete | Initial code pushed to `trieungoctam/speckit` at commit `7e5c582`; status docs follow-up in progress. |
26
28
  | npm package readiness | Ready | Package scoped as `@trieungoctam/speckit`; `npm pack --dry-run` passes. |
@@ -0,0 +1,265 @@
1
+ # Permission Rules Research
2
+
3
+ Date: 2026-05-10
4
+
5
+ ## Scope
6
+
7
+ Research goal: define a permission-rule model for Speckit that can compile safely across Claude Code, Codex, Cursor, OpenCode, and Antigravity.
8
+
9
+ This research focuses on:
10
+
11
+ - File read/write permissions
12
+ - Shell command permissions
13
+ - Network access
14
+ - Approval modes
15
+ - Phase-specific workflow permissions
16
+ - Enterprise guardrails for secrets, destructive commands, and production access
17
+
18
+ ## Key Findings
19
+
20
+ ### 1. Permission Rules Must Be Deny-First
21
+
22
+ Claude Code documents allow, ask, and deny rules, with evaluation order `deny -> ask -> allow`; deny rules always take precedence. Cursor CLI also documents deny rules taking precedence over allow rules.
23
+
24
+ Speckit should use the same mental model across all adapters:
25
+
26
+ ```text
27
+ deny > ask > allow
28
+ ```
29
+
30
+ This should be a product invariant, even when a specific IDE has a different internal matching implementation.
31
+
32
+ Sources:
33
+
34
+ - [Claude Code permissions](https://code.claude.com/docs/en/permissions)
35
+ - [Cursor permissions](https://docs.cursor.com/cli/reference/permissions)
36
+
37
+ ### 2. Permissions And Sandboxing Are Different Layers
38
+
39
+ Claude Code separates permissions from sandboxing: permissions control tool/file/domain access, while sandboxing enforces OS-level limits mainly around shell execution. OpenAI describes the same split for Codex: sandboxing defines execution boundaries, while approval policy decides when the agent must ask.
40
+
41
+ Speckit should model both layers:
42
+
43
+ - Permission policy: what the agent may attempt.
44
+ - Sandbox/approval policy: what the runtime may execute without approval.
45
+
46
+ Sources:
47
+
48
+ - [Claude Code permissions and sandboxing](https://code.claude.com/docs/en/permissions)
49
+ - [Running Codex safely at OpenAI](https://openai.com/index/running-codex-safely/)
50
+ - [Codex agent approvals and security](https://developers.openai.com/codex/agent-approvals-security)
51
+
52
+ ### 3. Avoid Full Bypass Modes Except In Disposable Environments
53
+
54
+ Claude Code warns that bypass mode skips permission prompts and should only be used in isolated environments such as containers or VMs. Codex similarly labels no-sandbox/no-approval mode as dangerous and not recommended.
55
+
56
+ Speckit should never generate full-bypass configs by default.
57
+
58
+ Recommended default:
59
+
60
+ ```text
61
+ approval: ask/on-request
62
+ sandbox: workspace-write
63
+ network: ask or denied by default
64
+ ```
65
+
66
+ Sources:
67
+
68
+ - [Claude Code permission modes](https://code.claude.com/docs/en/permissions)
69
+ - [Codex common sandbox and approval combinations](https://developers.openai.com/codex/agent-approvals-security)
70
+
71
+ ### 4. Phase-Scoped Permissions Fit Speckit Best
72
+
73
+ Speckit already has phases: shape, research, plan, context, graph, session, TDD, test, debug, review, docs, ship.
74
+
75
+ Permission should follow phase, not only IDE:
76
+
77
+ | Phase | File Writes | Shell | Network | Notes |
78
+ | --- | --- | --- | --- | --- |
79
+ | shape | `.speckit/specs/**` only | ask | ask | No source edits |
80
+ | research | reports/docs only | ask | allow/ask | Sources required |
81
+ | plan | `.speckit/plans/**`, stories, evidence | ask | ask | No source edits |
82
+ | context | `.speckit/context/**` only | ask | deny/ask | Build handoff only |
83
+ | graph | `.speckit/sync/**`, `.beads/**` | allow Speckit wrappers | deny/ask | Robot-safe graph only |
84
+ | session | `.speckit/sessions/**`, memory | ask | deny | Durable state only |
85
+ | TDD | workspace source + tests | ask | ask | Requires ready gate |
86
+ | test | test artifacts only | allow test/build commands | deny/ask | No production |
87
+ | debug | source + tests after root cause | ask | ask | Capture failure first |
88
+ | review | no edits by default | allow `git diff`, `git log`, tests | deny | Read-only review |
89
+ | docs | docs + Speckit artifacts | ask | deny/ask | No source edits unless requested |
90
+ | ship | package/release files | ask | ask | Push/publish/deploy require explicit approval |
91
+
92
+ ### 5. Adapter Mapping
93
+
94
+ #### Claude Code
95
+
96
+ Use `.claude/settings.json`:
97
+
98
+ - `permissions.defaultMode = "ask"` or conservative equivalent
99
+ - explicit deny rules for secrets and destructive commands
100
+ - ask rules for shell/network/publish/deploy
101
+ - optional hooks for runtime validation
102
+ - managed settings for enterprise to disable bypass/auto modes
103
+
104
+ Relevant details:
105
+
106
+ - Permission rule syntax supports `Tool` and `Tool(specifier)`.
107
+ - Bash rules support wildcards.
108
+ - Hooks can deny or force prompts before permission rules finish.
109
+ - Managed settings can prevent bypass mode and restrict user/project rules.
110
+
111
+ Source: [Claude Code permissions](https://code.claude.com/docs/en/permissions)
112
+
113
+ #### Codex
114
+
115
+ Use `.codex/config.toml`:
116
+
117
+ ```toml
118
+ approval_policy = "on-request"
119
+ sandbox_mode = "workspace-write"
120
+ ```
121
+
122
+ Enterprise hardening can use requirements:
123
+
124
+ ```toml
125
+ allowed_approval_policies = ["untrusted", "on-request"]
126
+ allowed_sandbox_modes = ["read-only", "workspace-write"]
127
+ ```
128
+
129
+ Avoid `danger-full-access` and no-approval modes for normal projects.
130
+
131
+ Sources:
132
+
133
+ - [Codex config reference](https://developers.openai.com/codex/config-reference)
134
+ - [Codex managed configuration](https://developers.openai.com/codex/enterprise/managed-configuration)
135
+ - [Codex agent approvals and security](https://developers.openai.com/codex/agent-approvals-security)
136
+
137
+ #### Cursor
138
+
139
+ Use project-level `.cursor/cli.json` for CLI permissions:
140
+
141
+ ```json
142
+ {
143
+ "permissions": {
144
+ "allow": ["Shell(git)", "Shell(npm)", "Read(src/**/*.ts)"],
145
+ "deny": ["Shell(rm)", "Read(.env*)", "Write(**/*.key)", "Write(**/.env*)"]
146
+ }
147
+ }
148
+ ```
149
+
150
+ Cursor permission tokens cover:
151
+
152
+ - `Shell(commandBase)`
153
+ - `Read(pathOrGlob)`
154
+ - `Write(pathOrGlob)`
155
+
156
+ Source: [Cursor permissions](https://docs.cursor.com/cli/reference/permissions)
157
+
158
+ #### OpenCode
159
+
160
+ Use `permission` in `opencode.json` and Markdown agents.
161
+
162
+ OpenCode supports:
163
+
164
+ - `ask`
165
+ - `allow`
166
+ - `deny`
167
+ - per-agent override
168
+ - specific bash command patterns
169
+ - task permission controls
170
+
171
+ For Speckit, keep planner/reviewer read-only, TDD developer ask-gated, and ship commands ask-gated.
172
+
173
+ Source: [OpenCode agents and permissions](https://opencode.ai/docs/agents/)
174
+
175
+ #### Antigravity
176
+
177
+ The accessible public docs emphasize configurable autonomy, artifact review, and approval for critical operations, but the browsable official pages did not expose a stable machine-readable permission schema during this research.
178
+
179
+ Speckit should treat Antigravity permissions as instruction-level until a stable official config format is confirmed:
180
+
181
+ - generate `.agents/rules/speckit-enterprise-safety.md`
182
+ - require human approval for destructive commands, production changes, secrets access, deployment
183
+ - require artifact review before close
184
+ - avoid claiming hard enforcement unless adapter support is verified
185
+
186
+ Source:
187
+
188
+ - [Antigravity agents overview](https://antigravity.im/agents) — independent guide, not official Google documentation
189
+
190
+ ## Recommended Speckit Permission Model
191
+
192
+ Speckit should own a portable policy and compile it per IDE:
193
+
194
+ ```yaml
195
+ version: 1
196
+ default:
197
+ file_read: allow_workspace
198
+ file_write: ask
199
+ shell: ask
200
+ network: ask
201
+ external_directory: deny
202
+ secrets: deny
203
+ destructive: deny
204
+ production: ask
205
+ phases:
206
+ review:
207
+ file_write: deny
208
+ shell_allow:
209
+ - git diff*
210
+ - git log*
211
+ - npm test*
212
+ ship:
213
+ shell_ask:
214
+ - git push*
215
+ - npm publish*
216
+ - "* deploy*"
217
+ ```
218
+
219
+ ## Commands To Add
220
+
221
+ Recommended CLI surface:
222
+
223
+ ```bash
224
+ speckit permissions init
225
+ speckit permissions audit --json
226
+ speckit permissions compile --ide all
227
+ speckit validate --permissions --json
228
+ ```
229
+
230
+ Minimum useful implementation:
231
+
232
+ 1. Generate `.speckit/permissions.yaml`.
233
+ 2. Add permission checks to `speckit validate`.
234
+ 3. Compile:
235
+ - Claude Code: `.claude/settings.json`
236
+ - Codex: `.codex/config.toml`
237
+ - Cursor: `.cursor/cli.json`
238
+ - OpenCode: `opencode.json` and agent frontmatter
239
+ - Antigravity: `.agents/rules/speckit-enterprise-safety.md`
240
+
241
+ ## High-Risk Defaults To Block
242
+
243
+ Always deny or ask:
244
+
245
+ - `rm -rf`, `rmdir`, destructive cleanup
246
+ - `git reset --hard`, `git clean -fd`, force push
247
+ - `sudo`, `chmod -R`, `chown -R`
248
+ - shell access to `.env*`, `*.pem`, `*.key`, SSH keys, cloud credentials
249
+ - production deploys
250
+ - package publish
251
+ - arbitrary outbound network from shell
252
+ - external directory writes
253
+
254
+ ## Recommendation
255
+
256
+ Implement permission rules as the next Speckit enterprise layer.
257
+
258
+ Priority:
259
+
260
+ 1. Add central `.speckit/permissions.yaml`.
261
+ 2. Extend `validateWorkflowContract` with permission checks.
262
+ 3. Compile concrete adapter permission files.
263
+ 4. Add tests that tamper with dangerous permissions and ensure validation fails.
264
+
265
+ This keeps Speckit aligned with the strongest common pattern across current agent IDEs: deny-first, least-privilege, phase-scoped, with explicit approval for risky operations.
@@ -5,13 +5,15 @@ 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`, `start`, `memory`, `session`, `shape`, `plan`, `context`, `quick`, `sync`, `triage`, `sprint`, `graph`, `next`, `ready`, `run`, `review`, `close`.
8
+ - The command surface: `init`, `doctor`, `validate`, `start`, `memory`, `permissions`, `session`, `shape`, `plan`, `context`, `quick`, `sync`, `triage`, `sprint`, `graph`, `next`, `ready`, `run`, `review`, `close`.
9
9
  - The skill catalog and super-agent routing contract for phase-specific agent behavior.
10
10
  - IDE-specific initialization that installs the shared Speckit runtime plus only the selected IDE adapter when `--ide <name>` is provided.
11
11
  - The long-session contract: project memory, active session state, checkpoints, compaction summaries, and resume handoffs.
12
+ - The workflow validation contract: phase order, core skills, super-agent routing, run prompt terms, and installed adapter prompt parity.
12
13
  - The TDD gate: code stories require red, green, and refactor evidence.
13
14
  - The adapter compiler for Claude Code, Codex, Antigravity, OpenCode, and Cursor.
14
15
  - The safety policy for destructive commands, secrets, production access, and review readiness.
16
+ - The permission policy for privacy-sensitive files, context-heavy paths, destructive commands, and release commands.
15
17
 
16
18
  ## Speckit Delegates
17
19
 
@@ -1,5 +1,15 @@
1
1
  # Project Changelog
2
2
 
3
+ ## 0.3.1 - 2026-05-11
4
+
5
+ ### Changed
6
+
7
+ - Prepared npm release for the workflow validation and permission policy package updates.
8
+
9
+ ### Validation
10
+
11
+ - `npm test` passes with 36 tests.
12
+
3
13
  ## 0.3.0 - 2026-05-10
4
14
 
5
15
  ### Added
@@ -11,6 +21,11 @@
11
21
  - Added `.speckit/agents/super-agent.md` as the portable orchestration router.
12
22
  - Added `.speckit/skills/catalog.md` plus a curated Speckit skill set for shape, research, plan, context, graph, session, TDD, test, debug, review, docs, and ship phases.
13
23
  - Added `.speckit/skills/schema.json` to define the portable skill contract and delegation statuses.
24
+ - Added `speckit validate` for workflow contract validation across phase order, skills, router, prompts, and installed adapters.
25
+ - Added `contractChecks` to `speckit doctor --deep --json`.
26
+ - Added `docs/use-cases.md` with command recipes and best practices for setup, migration, quick changes, full planning, long sessions, TDD, graph automation, review, CI, and troubleshooting.
27
+ - Added `.speckit/permissions.yaml` and `speckit permissions audit` for privacy, scout, destructive-command, and release-command checks.
28
+ - Added concrete permission output for Claude Code, Codex, and Cursor adapters.
14
29
  - Added long-session prompt requirements for project memory, active session state, checkpoints, and compaction summaries.
15
30
  - Added automatic `.beads/beads.jsonl` mirror generation so Beads Viewer robot commands can run without missing-project errors.
16
31
  - Standard `speckit init --ide <name>` now installs the shared Speckit runtime, super-agent, and skill catalog for the selected IDE.
@@ -29,6 +44,7 @@
29
44
  - Added workflow tests for memory/session state, sprint planning, and graph fallback.
30
45
  - Expanded prompt quality tests for project memory, active session, checkpoint, and compaction.
31
46
  - Added init and flow contract coverage for the curated skill catalog.
47
+ - Added workflow validator tests for passing and tampered contract states.
32
48
 
33
49
  ## 0.2.2 - 2026-05-10
34
50
 
@@ -0,0 +1,206 @@
1
+ # Use Cases And Best Practices
2
+
3
+ This guide shows how to use Speckit for common product and engineering workflows.
4
+
5
+ ## 1. New Project Setup
6
+
7
+ Use when a repository does not have Speckit runtime files yet.
8
+
9
+ ```bash
10
+ npx @trieungoctam/speckit@latest init --enterprise --ide cursor
11
+ npx @trieungoctam/speckit@latest doctor --deep
12
+ npx @trieungoctam/speckit@latest validate
13
+ ```
14
+
15
+ Use `--ide all` only when the team actively uses multiple IDEs in the same repository.
16
+
17
+ Best practices:
18
+
19
+ - Prefer one IDE adapter per project at first. Add more adapters after the team agrees on the workflow.
20
+ - Run `speckit validate` after init so broken prompts or missing skills are caught immediately.
21
+ - Commit generated Speckit files so every teammate gets the same flow.
22
+ - Keep `.speckit/` local to the repository. Avoid relying on global agent state for enterprise work.
23
+
24
+ ## 2. Existing Project Migration
25
+
26
+ Use when a project already has code, tests, and team conventions.
27
+
28
+ ```bash
29
+ speckit init --enterprise --ide all --force
30
+ speckit memory refresh
31
+ speckit doctor --deep --json
32
+ speckit validate --json
33
+ ```
34
+
35
+ Best practices:
36
+
37
+ - Read generated files before pushing. Keep project-specific rules in `.speckit/memory/project-context.md`.
38
+ - Do not start implementation during migration. First make the generated flow pass validation.
39
+ - If an adapter prompt conflicts with local policy, update the adapter generator, not only the generated file.
40
+ - Run project tests after migration even if Speckit only changed documentation and prompt files.
41
+
42
+ ## 3. One Small Change
43
+
44
+ Use when the request is bounded and can fit into one story.
45
+
46
+ ```bash
47
+ speckit memory refresh
48
+ speckit session start "Add invoice total validation"
49
+ speckit quick "Add invoice total validation"
50
+ speckit context .speckit/stories/<story>.md
51
+ speckit sync
52
+ speckit ready .speckit/stories/<story>.md
53
+ speckit run .speckit/stories/<story>.md
54
+ ```
55
+
56
+ Best practices:
57
+
58
+ - Use `quick` only for a single focused change.
59
+ - Do not skip `context`, `sync`, or `ready`. They prevent agents from implementing against stale assumptions.
60
+ - Keep acceptance criteria concrete enough to test.
61
+ - Checkpoint after the red test, green test, refactor, and review boundary.
62
+
63
+ ## 4. Full Feature Planning
64
+
65
+ Use when the work includes multiple stories, architecture decisions, or team rollout.
66
+
67
+ ```bash
68
+ speckit session start "Add subscription lifecycle"
69
+ speckit memory refresh
70
+ speckit shape "Add subscription lifecycle"
71
+ speckit plan "Add subscription lifecycle"
72
+ speckit sync
73
+ speckit sprint plan
74
+ speckit graph triage --json
75
+ ```
76
+
77
+ Best practices:
78
+
79
+ - Shape before planning. The shape artifact defines scope, non-goals, and risk.
80
+ - Keep stories small enough to pass through TDD evidence independently.
81
+ - Sync stories before graph commands so prioritization uses current metadata.
82
+ - Use `sprint next` or `graph triage` to select work instead of choosing only by recency.
83
+
84
+ ## 5. Long Agent Session
85
+
86
+ Use when work will span many tool calls, handoffs, or context compaction.
87
+
88
+ ```bash
89
+ speckit memory refresh
90
+ speckit session start "Refactor report export flow"
91
+ speckit session status --json
92
+ speckit session checkpoint --note "red complete"
93
+ speckit session checkpoint --note "green complete"
94
+ speckit session compact
95
+ speckit session resume <session-id>
96
+ ```
97
+
98
+ Best practices:
99
+
100
+ - Durable files are the source of truth, not chat history.
101
+ - Write decisions to memory when they apply beyond the current story.
102
+ - Compact before handing work to another agent or after noisy command output.
103
+ - Use `DONE`, `DONE_WITH_CONCERNS`, `BLOCKED`, or `NEEDS_CONTEXT` in handoffs.
104
+ - Never pass a full conversation as handoff context. Pass files, acceptance criteria, constraints, and current status.
105
+
106
+ ## 6. TDD Implementation
107
+
108
+ Use for all code stories.
109
+
110
+ ```bash
111
+ speckit ready .speckit/stories/<story>.md
112
+ speckit run .speckit/stories/<story>.md
113
+ npm test
114
+ speckit session checkpoint --note "red evidence captured"
115
+ npm test
116
+ speckit session checkpoint --note "green evidence captured"
117
+ speckit session checkpoint --note "refactor validated"
118
+ ```
119
+
120
+ Best practices:
121
+
122
+ - Record test intent before code changes.
123
+ - Capture the red result before implementation.
124
+ - Make the smallest change that turns the failing test green.
125
+ - Refactor only while tests stay green.
126
+ - Put command output summaries in the evidence file. Avoid pasting large logs unless they are necessary.
127
+
128
+ ## 7. Graph And Sprint Automation
129
+
130
+ Use when multiple stories exist and the next task is not obvious.
131
+
132
+ ```bash
133
+ speckit sync
134
+ speckit sprint plan
135
+ speckit sprint next --json
136
+ speckit graph triage --json
137
+ speckit graph plan --json
138
+ speckit graph insights --json
139
+ ```
140
+
141
+ Best practices:
142
+
143
+ - Run `sync` before any graph command.
144
+ - Keep graph commands robot-safe. Use Speckit wrappers instead of interactive graph commands.
145
+ - Treat graph output as prioritization input, not automatic permission to implement.
146
+ - Re-run `sprint plan` when story status or dependencies change.
147
+
148
+ ## 8. Review And Closure
149
+
150
+ Use after implementation and tests pass.
151
+
152
+ ```bash
153
+ speckit review
154
+ speckit session compact
155
+ speckit close .speckit/stories/<story>.md
156
+ speckit sync
157
+ speckit validate
158
+ ```
159
+
160
+ Best practices:
161
+
162
+ - Review acceptance coverage before style or preference issues.
163
+ - Check TDD evidence, session freshness, docs impact, and graph sync.
164
+ - Close only after the story has current evidence and a clean handoff.
165
+ - Sync after closing so downstream graph and sprint views are current.
166
+
167
+ ## 9. CI And Enterprise Rollout
168
+
169
+ Use when Speckit becomes a shared team standard.
170
+
171
+ Recommended CI checks:
172
+
173
+ ```bash
174
+ npm run build
175
+ npm test
176
+ npx @trieungoctam/speckit@latest doctor --deep --json
177
+ npx @trieungoctam/speckit@latest validate --json
178
+ ```
179
+
180
+ Best practices:
181
+
182
+ - Fail CI when `validate` returns `needs-attention`.
183
+ - Require `doctor --deep` before release branches are merged.
184
+ - Keep generated prompt files reviewed like source code.
185
+ - Add new workflow phases only through the central contract and tests.
186
+ - Do not allow IDE-specific prompts to drift from the shared Speckit contract.
187
+
188
+ ## 10. Troubleshooting
189
+
190
+ Use these checks when the workflow feels inconsistent.
191
+
192
+ ```bash
193
+ speckit doctor --deep --json
194
+ speckit validate --json
195
+ speckit session status --json
196
+ speckit sync
197
+ speckit graph triage --json
198
+ ```
199
+
200
+ Common fixes:
201
+
202
+ - Missing skill file: run `speckit init --enterprise --ide <name> --force`.
203
+ - Adapter prompt mismatch: update the adapter generator, rebuild, then init again.
204
+ - Story is blocked: run `speckit context <story>` and `speckit sync`, then retry `speckit ready <story>`.
205
+ - Graph command fails: check that `.beads/beads.jsonl` exists after `speckit sync`.
206
+ - Session context is stale: run `speckit session checkpoint` and `speckit session compact`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trieungoctam/speckit",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Enterprise Agile + TDD workflow compiler for agentic IDEs.",
5
5
  "type": "module",
6
6
  "files": [