theslopmachine 0.6.2 → 0.7.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.
Files changed (77) hide show
  1. package/MANUAL.md +21 -6
  2. package/README.md +55 -7
  3. package/RELEASE.md +16 -1
  4. package/assets/agents/developer.md +41 -1
  5. package/assets/agents/slopmachine-claude.md +101 -60
  6. package/assets/agents/slopmachine.md +40 -17
  7. package/assets/claude/agents/developer.md +42 -5
  8. package/assets/skills/clarification-gate/SKILL.md +25 -5
  9. package/assets/skills/claude-worker-management/SKILL.md +290 -57
  10. package/assets/skills/developer-session-lifecycle/SKILL.md +83 -38
  11. package/assets/skills/development-guidance/SKILL.md +21 -1
  12. package/assets/skills/evaluation-triage/SKILL.md +34 -23
  13. package/assets/skills/final-evaluation-orchestration/SKILL.md +88 -50
  14. package/assets/skills/hardening-gate/SKILL.md +17 -3
  15. package/assets/skills/integrated-verification/SKILL.md +3 -3
  16. package/assets/skills/planning-gate/SKILL.md +32 -3
  17. package/assets/skills/planning-guidance/SKILL.md +72 -13
  18. package/assets/skills/retrospective-analysis/SKILL.md +2 -2
  19. package/assets/skills/scaffold-guidance/SKILL.md +129 -124
  20. package/assets/skills/submission-packaging/SKILL.md +33 -27
  21. package/assets/skills/verification-gates/SKILL.md +44 -14
  22. package/assets/slopmachine/backend-evaluation-prompt.md +1 -1
  23. package/assets/slopmachine/frontend-evaluation-prompt.md +5 -5
  24. package/assets/slopmachine/scaffold-playbooks/android-kotlin-compose.md +81 -0
  25. package/assets/slopmachine/scaffold-playbooks/android-kotlin-views.md +191 -0
  26. package/assets/slopmachine/scaffold-playbooks/android-native-java.md +203 -0
  27. package/assets/slopmachine/scaffold-playbooks/angular-default.md +181 -0
  28. package/assets/slopmachine/scaffold-playbooks/backend-baseline.md +142 -0
  29. package/assets/slopmachine/scaffold-playbooks/backend-family-matrix.md +80 -0
  30. package/assets/slopmachine/scaffold-playbooks/database-module-matrix.md +80 -0
  31. package/assets/slopmachine/scaffold-playbooks/django-default.md +166 -0
  32. package/assets/slopmachine/scaffold-playbooks/docker-baseline.md +189 -0
  33. package/assets/slopmachine/scaffold-playbooks/docker-shared-contract.md +334 -0
  34. package/assets/slopmachine/scaffold-playbooks/electron-vite-default.md +124 -0
  35. package/assets/slopmachine/scaffold-playbooks/expo-react-native-default.md +73 -0
  36. package/assets/slopmachine/scaffold-playbooks/fastapi-default.md +134 -0
  37. package/assets/slopmachine/scaffold-playbooks/frontend-baseline.md +160 -0
  38. package/assets/slopmachine/scaffold-playbooks/frontend-family-matrix.md +134 -0
  39. package/assets/slopmachine/scaffold-playbooks/generic-unknown-tech-guide.md +136 -0
  40. package/assets/slopmachine/scaffold-playbooks/go-chi-default.md +160 -0
  41. package/assets/slopmachine/scaffold-playbooks/ios-linux-portable.md +93 -0
  42. package/assets/slopmachine/scaffold-playbooks/ios-native-objective-c.md +151 -0
  43. package/assets/slopmachine/scaffold-playbooks/ios-native-swift.md +188 -0
  44. package/assets/slopmachine/scaffold-playbooks/laravel-default.md +216 -0
  45. package/assets/slopmachine/scaffold-playbooks/livewire-default.md +265 -0
  46. package/assets/slopmachine/scaffold-playbooks/overlay-module-matrix.md +130 -0
  47. package/assets/slopmachine/scaffold-playbooks/platform-family-matrix.md +79 -0
  48. package/assets/slopmachine/scaffold-playbooks/selection-matrix.md +72 -0
  49. package/assets/slopmachine/scaffold-playbooks/spring-boot-default.md +182 -0
  50. package/assets/slopmachine/scaffold-playbooks/tauri-default.md +80 -0
  51. package/assets/slopmachine/scaffold-playbooks/vue-vite-default.md +162 -0
  52. package/assets/slopmachine/scaffold-playbooks/web-default.md +96 -0
  53. package/assets/slopmachine/templates/AGENTS.md +41 -3
  54. package/assets/slopmachine/templates/CLAUDE.md +111 -0
  55. package/assets/slopmachine/test-coverage-prompt.md +561 -0
  56. package/assets/slopmachine/utils/claude_create_session.mjs +3 -2
  57. package/assets/slopmachine/utils/claude_live_channel.mjs +188 -0
  58. package/assets/slopmachine/utils/claude_live_common.mjs +411 -0
  59. package/assets/slopmachine/utils/claude_live_hook.py +47 -0
  60. package/assets/slopmachine/utils/claude_live_launch.mjs +187 -0
  61. package/assets/slopmachine/utils/claude_live_status.mjs +25 -0
  62. package/assets/slopmachine/utils/claude_live_stop.mjs +46 -0
  63. package/assets/slopmachine/utils/claude_live_turn.mjs +277 -0
  64. package/assets/slopmachine/utils/claude_resume_session.mjs +3 -2
  65. package/assets/slopmachine/utils/claude_wait_for_rate_limit_reset.mjs +23 -0
  66. package/assets/slopmachine/utils/claude_wait_for_rate_limit_reset.sh +5 -0
  67. package/assets/slopmachine/utils/claude_worker_common.mjs +361 -4
  68. package/assets/slopmachine/utils/cleanup_delivery_artifacts.py +4 -0
  69. package/assets/slopmachine/utils/export_ai_session.mjs +1 -1
  70. package/assets/slopmachine/utils/normalize_claude_session.py +153 -0
  71. package/assets/slopmachine/utils/package_claude_session.mjs +123 -0
  72. package/assets/slopmachine/utils/prepare_strict_audit_workspace.mjs +65 -0
  73. package/package.json +1 -1
  74. package/src/constants.js +42 -3
  75. package/src/init.js +173 -28
  76. package/src/install.js +156 -8
  77. package/src/send-data.js +56 -57
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'node:fs/promises'
4
+ import os from 'node:os'
5
+ import path from 'node:path'
6
+ import { spawn } from 'node:child_process'
7
+
8
+ import { parseArgs, emitFailure, emitSuccess, resolveClaudeSessionPath } from './claude_worker_common.mjs'
9
+
10
+ const argv = parseArgs(process.argv.slice(2))
11
+
12
+ async function pathExists(targetPath) {
13
+ try {
14
+ await fs.access(targetPath)
15
+ return true
16
+ } catch {
17
+ return false
18
+ }
19
+ }
20
+
21
+ async function run(command, args, cwd) {
22
+ return new Promise((resolve, reject) => {
23
+ const child = spawn(command, args, { cwd, stdio: ['ignore', 'pipe', 'pipe'], env: process.env })
24
+ let stdout = ''
25
+ let stderr = ''
26
+ child.stdout.on('data', (chunk) => { stdout += chunk.toString() })
27
+ child.stderr.on('data', (chunk) => { stderr += chunk.toString() })
28
+ child.on('error', reject)
29
+ child.on('close', (code) => resolve({ code: code ?? 1, stdout, stderr }))
30
+ })
31
+ }
32
+
33
+ async function createZipArchive(sourceDir, outputPath) {
34
+ await fs.mkdir(path.dirname(outputPath), { recursive: true })
35
+
36
+ if (process.platform === 'win32') {
37
+ const script = [
38
+ `$src = ${JSON.stringify(path.join(sourceDir, '*'))}`,
39
+ `$dest = ${JSON.stringify(outputPath)}`,
40
+ 'if (Test-Path $dest) { Remove-Item -Force $dest }',
41
+ 'Compress-Archive -Path $src -DestinationPath $dest -Force',
42
+ ].join('; ')
43
+
44
+ let lastError = null
45
+ for (const shell of ['pwsh', 'powershell']) {
46
+ try {
47
+ const result = await run(shell, [
48
+ '-NoProfile',
49
+ '-ExecutionPolicy', 'Bypass',
50
+ '-Command',
51
+ script,
52
+ ], sourceDir)
53
+
54
+ if (result.code === 0) {
55
+ return
56
+ }
57
+
58
+ lastError = new Error((result.stderr || result.stdout).trim() || `zip failed with exit ${result.code}`)
59
+ } catch (error) {
60
+ lastError = error
61
+ }
62
+ }
63
+
64
+ throw lastError || new Error('No usable PowerShell shell was found for zip creation')
65
+ }
66
+
67
+ try {
68
+ const result = await run('zip', ['-9', '-q', '-r', outputPath, '.'], sourceDir)
69
+ if (result.code !== 0) {
70
+ throw new Error((result.stderr || result.stdout).trim() || `zip failed with exit ${result.code}`)
71
+ }
72
+ } catch (error) {
73
+ throw new Error(error instanceof Error ? error.message : 'zip command is required to package Claude sessions')
74
+ }
75
+ }
76
+
77
+ async function normalizeClaudeJsonlFiles(projectDir) {
78
+ const normalizerScript = path.join(path.dirname(new URL(import.meta.url).pathname), 'normalize_claude_session.py')
79
+ const entries = await fs.readdir(projectDir, { withFileTypes: true }).catch(() => [])
80
+ const jsonlFiles = entries
81
+ .filter((entry) => entry.isFile() && entry.name.endsWith('.jsonl'))
82
+ .map((entry) => path.join(projectDir, entry.name))
83
+
84
+ for (const filePath of jsonlFiles) {
85
+ const tempOutputPath = `${filePath}.normalized`
86
+ const result = await run('python3', [normalizerScript, filePath, '--output', tempOutputPath], projectDir)
87
+ if (result.code !== 0) {
88
+ throw new Error(`Failed to normalize Claude session file ${path.basename(filePath)}: ${(result.stderr || result.stdout).trim()}`)
89
+ }
90
+ await fs.rename(tempOutputPath, filePath)
91
+ }
92
+ }
93
+
94
+ try {
95
+ const sessionId = argv['session-id']
96
+ const transcriptPath = await resolveClaudeSessionPath(sessionId, argv.cwd)
97
+ if (!(await pathExists(transcriptPath))) {
98
+ throw new Error(`Claude transcript not found for session ${sessionId}`)
99
+ }
100
+
101
+ const sourceProjectDir = path.dirname(transcriptPath)
102
+ const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'slopmachine-claude-project-'))
103
+ const projectDir = path.join(tempRoot, path.basename(sourceProjectDir))
104
+ await fs.cp(sourceProjectDir, projectDir, { recursive: true })
105
+ await normalizeClaudeJsonlFiles(projectDir)
106
+ const included = (await fs.readdir(projectDir).catch(() => [])).sort((left, right) => left.localeCompare(right))
107
+
108
+ try {
109
+ await createZipArchive(projectDir, argv.output)
110
+ emitSuccess(sessionId, {
111
+ output: argv.output,
112
+ project_dir: sourceProjectDir,
113
+ label: argv.label || null,
114
+ included,
115
+ normalized: true,
116
+ })
117
+ } finally {
118
+ await fs.rm(tempRoot, { recursive: true, force: true }).catch(() => {})
119
+ }
120
+ } catch (error) {
121
+ emitFailure('package_claude_session_failed', error instanceof Error ? error.message : String(error))
122
+ process.exitCode = 1
123
+ }
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'node:fs/promises'
4
+ import path from 'node:path'
5
+
6
+ import { emitFailure, emitSuccess, parseArgs } from './claude_worker_common.mjs'
7
+
8
+ const argv = parseArgs(process.argv.slice(2))
9
+
10
+ function resolveLinkType(targetPath) {
11
+ return process.platform === 'win32' ? 'junction' : 'dir'
12
+ }
13
+
14
+ async function pathExists(targetPath) {
15
+ try {
16
+ await fs.access(targetPath)
17
+ return true
18
+ } catch {
19
+ return false
20
+ }
21
+ }
22
+
23
+ async function ensureLinkedDir(targetPath, linkPath) {
24
+ await fs.mkdir(path.dirname(linkPath), { recursive: true })
25
+ await fs.symlink(targetPath, linkPath, resolveLinkType(targetPath))
26
+ }
27
+
28
+ try {
29
+ const workspaceRoot = argv['workspace-root'] ? path.resolve(argv['workspace-root']) : null
30
+ const name = argv.name || 'strict-audit'
31
+ const auditRoot = argv['output-dir']
32
+ ? path.resolve(argv['output-dir'])
33
+ : path.join(workspaceRoot || '', '.ai', 'audit-workspaces', name)
34
+
35
+ if (!workspaceRoot) {
36
+ throw new Error('Missing --workspace-root')
37
+ }
38
+
39
+ const repoDir = path.join(workspaceRoot, 'repo')
40
+ const tmpDir = path.join(workspaceRoot, '.tmp')
41
+ if (!(await pathExists(repoDir))) {
42
+ throw new Error(`Missing repo directory at ${repoDir}`)
43
+ }
44
+ if (!(await pathExists(tmpDir))) {
45
+ throw new Error(`Missing .tmp directory at ${tmpDir}`)
46
+ }
47
+
48
+ await fs.rm(auditRoot, { recursive: true, force: true })
49
+ const runDir = path.join(auditRoot, 'run')
50
+ await fs.mkdir(runDir, { recursive: true })
51
+
52
+ await ensureLinkedDir(repoDir, path.join(runDir, 'repo'))
53
+ await ensureLinkedDir(tmpDir, path.join(auditRoot, '.tmp'))
54
+
55
+ emitSuccess(null, {
56
+ workspace_root: workspaceRoot,
57
+ audit_root: auditRoot,
58
+ run_dir: runDir,
59
+ repo_path: path.join(runDir, 'repo'),
60
+ tmp_path: path.join(auditRoot, '.tmp'),
61
+ })
62
+ } catch (error) {
63
+ emitFailure('prepare_strict_audit_workspace_failed', error instanceof Error ? error.message : String(error))
64
+ process.exitCode = 1
65
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "theslopmachine",
3
- "version": "0.6.2",
3
+ "version": "0.7.1",
4
4
  "description": "SlopMachine installer and project bootstrap CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/constants.js CHANGED
@@ -62,17 +62,56 @@ export const CLAUDE_REQUIRED_AGENT_FILES = ["developer.md"];
62
62
  export const REQUIRED_SLOPMACHINE_FILES = [
63
63
  "backend-evaluation-prompt.md",
64
64
  "frontend-evaluation-prompt.md",
65
+ "test-coverage-prompt.md",
65
66
  "workflow-init.js",
66
67
  "templates/AGENTS.md",
68
+ "templates/CLAUDE.md",
67
69
  "utils/claude_worker_common.mjs",
70
+ "utils/claude_live_common.mjs",
71
+ "utils/claude_live_channel.mjs",
72
+ "utils/claude_live_hook.py",
73
+ "utils/claude_live_launch.mjs",
74
+ "utils/claude_live_turn.mjs",
75
+ "utils/claude_live_status.mjs",
76
+ "utils/claude_live_stop.mjs",
68
77
  "utils/claude_create_session.mjs",
69
78
  "utils/claude_resume_session.mjs",
70
79
  "utils/claude_export_session.mjs",
71
80
  "utils/export_ai_session.mjs",
72
- "utils/prepare_ai_session_for_convert.mjs",
73
- "utils/convert_exported_ai_session.mjs",
81
+ "utils/package_claude_session.mjs",
82
+ "utils/prepare_strict_audit_workspace.mjs",
83
+ "utils/claude_wait_for_rate_limit_reset.mjs",
84
+ "utils/claude_wait_for_rate_limit_reset.sh",
85
+ "utils/normalize_claude_session.py",
86
+ "scaffold-playbooks/docker-shared-contract.md",
87
+ "scaffold-playbooks/generic-unknown-tech-guide.md",
88
+ "scaffold-playbooks/frontend-family-matrix.md",
89
+ "scaffold-playbooks/backend-family-matrix.md",
90
+ "scaffold-playbooks/database-module-matrix.md",
91
+ "scaffold-playbooks/platform-family-matrix.md",
92
+ "scaffold-playbooks/overlay-module-matrix.md",
93
+ "scaffold-playbooks/selection-matrix.md",
94
+ "scaffold-playbooks/docker-baseline.md",
95
+ "scaffold-playbooks/frontend-baseline.md",
96
+ "scaffold-playbooks/backend-baseline.md",
97
+ "scaffold-playbooks/vue-vite-default.md",
98
+ "scaffold-playbooks/angular-default.md",
99
+ "scaffold-playbooks/fastapi-default.md",
100
+ "scaffold-playbooks/spring-boot-default.md",
101
+ "scaffold-playbooks/django-default.md",
102
+ "scaffold-playbooks/laravel-default.md",
103
+ "scaffold-playbooks/livewire-default.md",
104
+ "scaffold-playbooks/go-chi-default.md",
105
+ "scaffold-playbooks/web-default.md",
106
+ "scaffold-playbooks/android-native-java.md",
107
+ "scaffold-playbooks/android-kotlin-compose.md",
108
+ "scaffold-playbooks/expo-react-native-default.md",
109
+ "scaffold-playbooks/electron-vite-default.md",
110
+ "scaffold-playbooks/tauri-default.md",
111
+ "scaffold-playbooks/ios-linux-portable.md",
112
+ "scaffold-playbooks/ios-native-swift.md",
113
+ "scaffold-playbooks/ios-native-objective-c.md",
74
114
  "utils/strip_session_parent.py",
75
- "utils/convert_ai_session.py",
76
115
  "utils/cleanup_delivery_artifacts.py",
77
116
  ];
78
117
 
package/src/init.js CHANGED
@@ -25,11 +25,12 @@ const GITIGNORE_ENTRIES = [
25
25
  ]
26
26
 
27
27
  const ALLOWED_EXISTING_ENTRIES = new Set(['.DS_Store', '.git'])
28
- const INITIAL_COMMIT_PATHS = ['.gitignore', 'docs', 'metadata.json', 'repo', 'self_test_reports', 'sessions']
28
+ const INITIAL_COMMIT_PATHS = ['.gitignore', '.tmp', 'docs', 'metadata.json', 'repo', 'sessions']
29
29
  const ADOPTION_ROOT_KEEP = new Set([
30
30
  '.DS_Store',
31
31
  '.git',
32
32
  '.gitignore',
33
+ '.tmp',
33
34
  '.ai',
34
35
  '.beads',
35
36
  'docs',
@@ -37,7 +38,19 @@ const ADOPTION_ROOT_KEEP = new Set([
37
38
  'metadata.json',
38
39
  'repo',
39
40
  ])
40
- const VALID_START_PHASES = new Set(['P0', 'P1', 'P2', 'P3', 'P4', 'P5', 'P6', 'P7', 'P8', 'P9', 'P10'])
41
+ const VALID_START_PHASES = new Set(['P1', 'P2', 'P3', 'P4', 'P5', 'P6', 'P7', 'P8', 'P9', 'P10'])
42
+ const PHASE_LABELS = {
43
+ P1: 'P1 Clarification',
44
+ P2: 'P2 Planning',
45
+ P3: 'P3 Scaffold',
46
+ P4: 'P4 Development',
47
+ P5: 'P5 Integrated Verification',
48
+ P6: 'P6 Hardening',
49
+ P7: 'P7 Evaluation and Fix Verification',
50
+ P8: 'P8 Final Human Decision',
51
+ P9: 'P9 Submission Packaging',
52
+ P10: 'P10 Retrospective',
53
+ }
41
54
 
42
55
  function getUnixBrCommandCandidates(paths) {
43
56
  return [
@@ -281,7 +294,24 @@ async function createInitialPhaseArtifacts(targetPath, options) {
281
294
  `Capture the planning-critical project shape here before real planning begins.\n\n` +
282
295
  `## Bootstrap Notes\n\n` +
283
296
  `${options.adoptExisting ? '- This workspace was adopted from an existing project. Inspect the current codebase state before assuming a clean-slate build.\n' : '- This workspace started from a clean slopmachine bootstrap.\n'}` +
284
- `${options.requestedStartPhase ? `- Requested start phase: ${options.requestedStartPhase}.\n` : ''}`
297
+ `${options.requestedStartPhase ? `- Requested start phase: ${options.requestedStartPhase}.\n` : ''}` +
298
+ `\n## Intake Shape\n\n` +
299
+ `Fill this file with concise but concrete planning inputs:\n\n` +
300
+ `- prompt-critical requirements\n` +
301
+ `- actors and path-to-success summaries\n` +
302
+ `- required surfaces\n` +
303
+ `- explicit out-of-scope items\n` +
304
+ `- locked defaults\n` +
305
+ `- major risks\n` +
306
+ `- shared prerequisites and likely parallel work packages\n` +
307
+ `\n## Gap Sweep\n\n` +
308
+ `Before planning, note the important unresolved gaps in these categories when relevant:\n\n` +
309
+ `- business rules\n` +
310
+ `- workflows\n` +
311
+ `- data model\n` +
312
+ `- security and compliance\n` +
313
+ `- reliability / offline / retries\n` +
314
+ `- reporting / exports / analytics\n`
285
315
 
286
316
  const clarificationOptionsContent = `# Clarification Options\n\n` +
287
317
  `## Original Prompt\n\n` +
@@ -293,32 +323,128 @@ async function createInitialPhaseArtifacts(targetPath, options) {
293
323
  `Build the developer-facing clarification prompt here once P1 resolves the material ambiguities.\n`
294
324
 
295
325
  const designContent = `# Design\n\n` +
296
- `This document is the owner-maintained external design reference for the project.\n\n` +
326
+ `This document is the owner-maintained external design reference for the project. Treat it as the authoritative detailed planning and design contract once planning begins.\n\n` +
297
327
  `## Bootstrap Notes\n\n` +
298
328
  `${options.adoptExisting ? '- This workspace was adopted from an existing project. Update this design reference to match the real codebase state before planning deeply.\n' : '- This workspace started from a clean slopmachine bootstrap. Update this file as clarification and planning progress.\n'}` +
299
- `${options.requestedStartPhase ? `- Requested start phase: ${options.requestedStartPhase}.\n` : ''}`
329
+ `${options.requestedStartPhase ? `- Requested start phase: ${options.requestedStartPhase}.\n` : ''}` +
330
+ `\n## How To Use This File\n\n` +
331
+ `- Replace placeholders with concrete implementation decisions.\n` +
332
+ `- Do not leave major sections vague, empty, or deferred without an explicit reason.\n` +
333
+ `- Prefer explicit tables, bullet lists, and subsections over broad narrative.\n` +
334
+ `- Make this detailed enough that scaffold and development can mostly execute by following the accepted plan.\n` +
335
+ `\n## Tech Stack Summary\n\n` +
336
+ `State the concrete backend, frontend, persistence, auth/security, jobs/async, runtime, and other major stack choices here. If something is intentionally not fixed yet, say so explicitly and explain why.\n` +
337
+ `\n## Product Overview\n\n` +
338
+ `Describe what is being built, for whom, and the core business objective in implementation-relevant language.\n` +
339
+ `\n## System Overview\n\n` +
340
+ `- What is being built\n` +
341
+ `- Core business objective\n` +
342
+ `- Primary technical shape\n` +
343
+ `\n## In-Scope Domains\n\n` +
344
+ `List the major domains or modules that are part of delivery.\n` +
345
+ `\n## Explicit Out-Of-Scope\n\n` +
346
+ `List what is intentionally not being built so implementation does not overreach.\n` +
347
+ `\n## Actors And Roles\n\n` +
348
+ `Define the user types, admins, operators, and other actors.\n` +
349
+ `\n## Actor Success Paths\n\n` +
350
+ `For each important actor, define the concrete path to success for the prompt-critical workflows.\n` +
351
+ `\n## Architecture And Module Boundaries\n\n` +
352
+ `Describe the major components, boundaries, and why this structure was chosen.\n` +
353
+ `\n## Domain Model And Data Model\n\n` +
354
+ `List the important entities, relationships, supporting records, and persistence constraints.\n` +
355
+ `\n## Authoritative Business Rules\n\n` +
356
+ `Define defaults, limits, formulas, uniqueness rules, conflicts, retries, reversals, ownership rules, and other critical domain rules.\n` +
357
+ `\n## State Machines And Lifecycles\n\n` +
358
+ `Define the allowed states, transitions, triggers, and illegal transitions where workflow state matters.\n` +
359
+ `\n## Permissions And Authorization Model\n\n` +
360
+ `Define roles, scopes, route-level checks, object-level checks, and privileged actions.\n` +
361
+ `\n## Validation And Error Handling\n\n` +
362
+ `Define the important validations, normalized errors, and failure behavior.\n` +
363
+ `\n## Security, Compliance, And Data Governance\n\n` +
364
+ `Describe authentication, session or token rules, audit expectations, masking, retention, deletion, export restrictions, and other sensitive-data controls when relevant.\n` +
365
+ `\n## Offline, Queueing, Reliability, And Background Jobs\n\n` +
366
+ `When relevant, define queue behavior, retries, resumability, conflict handling, job states, observability, and maintenance behavior.\n` +
367
+ `\n## Reporting, Analytics, Search, And Exports\n\n` +
368
+ `When relevant, describe KPIs, source of truth, calculations, indexing or search behavior, export rules, and report job lifecycles.\n` +
369
+ `\n## Runtime, Config, And Ops Contract\n\n` +
370
+ `Define runtime entrypoints, config flow, environment handling, jobs, observability, and operational expectations.\n` +
371
+ `\n## Interface Contracts\n\n` +
372
+ `Describe important APIs, frontend/backend contracts, payload shapes, and user-visible interaction expectations.\n` +
373
+ `\n## Non-Functional Requirements\n\n` +
374
+ `Describe performance, deterministic behavior, restart recovery, availability, timezone, backup, and other cross-cutting quality requirements when relevant.\n` +
375
+ `\n## Verification Strategy\n\n` +
376
+ `Describe the local verification model, broad-gate verification, and the major risk-to-test expectations.\n` +
377
+ `\n## Dependency And Parallelism Plan\n\n` +
378
+ `Identify which work must stay serial because of shared foundations, and which 2 or 3 work packages can safely proceed in parallel once those foundations are settled.\n` +
379
+ `\n## Implementation Phases\n\n` +
380
+ `Break the work into realistic phases or major chunks with dependencies and usable outcomes.\n` +
381
+ `\n## Phase Checkpoints\n\n` +
382
+ `For each phase, define required artifacts, required working flows, required tests, exit criteria, and what is not allowed to defer past that phase.\n` +
383
+ `\n## Definition Of Done\n\n` +
384
+ `Define the hard completion standard that should block fake-complete or scaffold-only delivery.\n` +
385
+ `\n## Deliverables\n\n` +
386
+ `List the concrete outputs delivery must produce, such as working application, scripts, tests, docs, bootstrap assets, exports, or admin tools when relevant.\n` +
387
+ `\n## Assumptions, Dispositions, And Open Items\n\n` +
388
+ `Keep unresolved items rare. Each section should be either concrete or explicitly marked not applicable with a reason. If something is still open, name it explicitly, explain why it is still open, and state what evidence or decision is needed to close it.\n`
300
389
 
301
390
  const apiSpecContent = `# API Spec\n\n` +
302
391
  `Use this owner-maintained external document when API or interface contracts are material to the project.\n\n` +
303
392
  `If the project has no meaningful API surface, mark this file as not applicable rather than deleting it silently.\n`
304
393
 
305
394
  const testCoverageContent = `# Test Coverage\n\n` +
306
- `Map prompt-critical requirements and risks to concrete tests here as the project evolves.\n\n` +
307
- `## Expected Shape\n\n` +
395
+ `Map prompt-critical requirements, endpoint coverage, and audit-facing test evidence here as the project evolves.\n\n` +
396
+ `## Requirement And Risk Matrix\n\n` +
308
397
  `- Requirement or risk\n` +
309
398
  `- Test file or layer\n` +
310
399
  `- Key assertion\n` +
311
400
  `- Coverage status\n` +
401
+ `- Remaining gap\n\n` +
402
+ `## Backend Endpoint Inventory\n\n` +
403
+ `Use this when the project exposes backend or fullstack API endpoints.\n\n` +
404
+ `- Method\n` +
405
+ `- Resolved path\n` +
406
+ `- Notes\n\n` +
407
+ `## API Test Mapping Table\n\n` +
408
+ `- Endpoint\n` +
409
+ `- Covered: yes/no\n` +
410
+ `- Test type: true no-mock HTTP / HTTP with mocking / unit-only or indirect\n` +
411
+ `- Test file\n` +
412
+ `- Evidence\n\n` +
413
+ `## Unit Test Summary\n\n` +
414
+ `- Module family\n` +
415
+ `- Covered by\n` +
416
+ `- Important modules not tested\n\n` +
417
+ `## Coverage Summary\n\n` +
418
+ `- Total endpoints\n` +
419
+ `- Endpoints with HTTP tests\n` +
420
+ `- Endpoints with true no-mock HTTP tests\n` +
421
+ `- Coverage threshold target\n` +
312
422
  `- Remaining gap\n`
313
423
 
314
424
  const repoReadmeContent = `# Project\n\n` +
315
425
  `This README is the primary in-repo documentation surface.\n\n` +
316
- `Fill in:\n\n` +
317
- `- what the project does\n` +
318
- `- how to run it\n` +
319
- `- how to test it\n` +
320
- `- the main repo contents\n` +
321
- `- important information a new developer needs immediately\n`
426
+ `## Project Type\n\n` +
427
+ `State one of: backend, fullstack, web, android, ios, desktop.\n\n` +
428
+ `## Overview\n\n` +
429
+ `Explain what the project does and who it is for.\n\n` +
430
+ `## Tech Stack\n\n` +
431
+ `List the main frameworks, languages, and runtime pieces.\n\n` +
432
+ `## Startup Instructions\n\n` +
433
+ `Document the canonical startup path and any audit-compatibility or platform-specific launch notes.\n\n` +
434
+ `## Access Method\n\n` +
435
+ `Explain how a reviewer reaches the system after startup.\n\n` +
436
+ `## Verification Method\n\n` +
437
+ `Explain how to confirm the main flows actually work.\n\n` +
438
+ `## Authentication\n\n` +
439
+ `Provide demo credentials for every role, or state exactly: No authentication required\n\n` +
440
+ `## Roles And Workflows\n\n` +
441
+ `Summarize the important roles, main workflows, and any security-relevant behavior a reviewer should know.\n\n` +
442
+ `## Main Repo Contents\n\n` +
443
+ `List the main directories, entry points, and scripts.\n\n` +
444
+ `## Architecture\n\n` +
445
+ `Summarize the delivered architecture and major implementation structure.\n\n` +
446
+ `## Important Notes\n\n` +
447
+ `Document feature flags, mock/default behavior, setup boundaries, and important new-developer information.\n`
322
448
 
323
449
  const startupContextContent = `# Startup Context\n\n` +
324
450
  `- Bootstrap mode: ${options.adoptExisting ? 'adopt-existing-project' : 'new-workspace'}\n` +
@@ -338,14 +464,17 @@ async function createInitialPhaseArtifacts(targetPath, options) {
338
464
  }
339
465
 
340
466
  async function createRepoStructure(targetPath, agentsTemplate, options) {
467
+ const initialPhase = options.requestedStartPhase ? PHASE_LABELS[options.requestedStartPhase] : 'P1 Clarification'
468
+
341
469
  log('Creating parent workflow directories')
470
+ await ensureDir(path.join(targetPath, '.tmp'))
342
471
  await ensureDir(path.join(targetPath, 'docs'))
343
472
  await ensureDir(path.join(targetPath, 'sessions'))
344
- await ensureDir(path.join(targetPath, 'self_test_reports'))
345
- await ensureDir(path.join(targetPath, '.ai', 'claude-traces'))
473
+ await ensureDir(path.join(targetPath, '.ai', 'claude-live'))
346
474
 
347
475
  log('Creating repo/ working directory')
348
476
  await ensureDir(path.join(targetPath, 'repo'))
477
+ await ensureDir(path.join(targetPath, 'repo', '.claude'))
349
478
 
350
479
  log('Copying AGENTS template into repo/')
351
480
  const repoAgentsPath = path.join(targetPath, 'repo', 'AGENTS.md')
@@ -354,6 +483,17 @@ async function createRepoStructure(targetPath, agentsTemplate, options) {
354
483
  }
355
484
  await fs.copyFile(agentsTemplate, repoAgentsPath)
356
485
 
486
+ await writeFileIfMissing(
487
+ path.join(targetPath, 'repo', '.claude', 'settings.json'),
488
+ `${JSON.stringify({
489
+ $schema: 'https://json.schemastore.org/claude-code-settings.json',
490
+ agent: 'developer',
491
+ env: {
492
+ CLAUDE_CODE_SUBAGENT_MODEL: 'sonnet',
493
+ },
494
+ }, null, 2)}\n`,
495
+ )
496
+
357
497
  const projectMetadataPath = path.join(targetPath, 'metadata.json')
358
498
  if (!(await pathExists(projectMetadataPath))) {
359
499
  log('Creating parent metadata.json')
@@ -373,35 +513,40 @@ async function createRepoStructure(targetPath, agentsTemplate, options) {
373
513
 
374
514
  const workflowMetadataPath = path.join(targetPath, '.ai', 'metadata.json')
375
515
  if (!(await pathExists(workflowMetadataPath))) {
376
- log('Creating .ai/metadata.json')
377
- await fs.writeFile(workflowMetadataPath, `${JSON.stringify({
378
- run_id: randomUUID(),
379
- current_phase: 'P1 Clarification',
380
- awaiting_human: false,
516
+ log('Creating .ai/metadata.json')
517
+ await fs.writeFile(workflowMetadataPath, `${JSON.stringify({
518
+ run_id: randomUUID(),
519
+ current_phase: initialPhase,
520
+ awaiting_human: false,
381
521
  clarification_approved: false,
382
522
  clarification_validator_session_id: null,
383
523
  evaluation_prompt_kind: null,
384
524
  active_evaluator_session_id: null,
385
- self_test_reports_root: 'self_test_reports',
386
- self_test_successful_cycle_count: 0,
387
- self_test_cycles: [],
388
- failed_audit_count: 0,
389
- failed_audits: [],
525
+ evaluation_reports_root: '.tmp',
526
+ evaluation_audit_count: 0,
527
+ evaluation_runs: [],
528
+ completed_bugfix_session_count: 0,
529
+ required_bugfix_session_count: 2,
530
+ coverage_readme_audit_completed: false,
531
+ coverage_readme_audit_report_path: null,
390
532
  developer_sessions: [],
533
+ developer_rulebook_file: null,
391
534
  current_developer_lane: null,
392
535
  active_developer_session_id: null,
536
+ primary_develop_session_id: null,
537
+ latest_develop_session_id: null,
393
538
  next_develop_session_number: 1,
394
539
  next_bugfix_session_number: 1,
395
540
  packaging_completed: false,
396
- claude_trace_root: '.ai/claude-traces',
541
+ claude_live_root: '.ai/claude-live',
397
542
  bootstrap_mode: options.adoptExisting ? 'adopt' : 'new',
398
543
  requested_start_phase: options.requestedStartPhase,
399
544
  }, null, 2)}\n`, 'utf8')
400
545
  }
401
546
 
402
547
  await fs.writeFile(path.join(targetPath, '.ai', 'artifacts', '.gitkeep'), '', 'utf8')
403
- await fs.writeFile(path.join(targetPath, '.ai', 'claude-traces', '.gitkeep'), '', 'utf8')
404
- await fs.writeFile(path.join(targetPath, 'self_test_reports', '.gitkeep'), '', 'utf8')
548
+ await fs.writeFile(path.join(targetPath, '.ai', 'claude-live', '.gitkeep'), '', 'utf8')
549
+ await fs.writeFile(path.join(targetPath, '.tmp', '.gitkeep'), '', 'utf8')
405
550
  await fs.writeFile(path.join(targetPath, 'sessions', '.gitkeep'), '', 'utf8')
406
551
 
407
552
  await createInitialPhaseArtifacts(targetPath, options)