devmethod-ai 0.1.0-rc.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/.agents/skills/decision-architecture/SKILL.md +15 -13
  2. package/.agents/skills/decision-architecture/assets/ADR.md +18 -17
  3. package/.agents/skills/decision-architecture/references/api-contracts.md +21 -16
  4. package/.agents/skills/decision-architecture/references/backend-boundaries.md +21 -18
  5. package/.agents/skills/decision-architecture/references/product-decisions.md +14 -17
  6. package/.agents/skills/design-to-code/SKILL.md +11 -10
  7. package/.agents/skills/design-to-code/assets/UI_ACCEPTANCE.md +13 -12
  8. package/.agents/skills/design-to-code/references/ux-contract.md +20 -15
  9. package/.agents/skills/project-foundation/SKILL.md +39 -30
  10. package/.agents/skills/project-foundation/assets/AGENTS.foundation.md +16 -15
  11. package/.agents/skills/project-foundation/assets/PROJECT_PROFILE.md +23 -23
  12. package/.agents/skills/project-foundation/assets/START_HERE.md +17 -14
  13. package/.agents/skills/project-foundation/references/mission-context.md +20 -0
  14. package/.agents/skills/project-foundation/references/operating-commands.md +37 -34
  15. package/.agents/skills/project-foundation/references/profiles/README.md +18 -0
  16. package/.agents/skills/project-foundation/references/profiles/ci.md +11 -0
  17. package/.agents/skills/project-foundation/references/profiles/cloud-delivery.md +13 -0
  18. package/.agents/skills/project-foundation/references/profiles/messaging.md +11 -0
  19. package/.agents/skills/project-foundation/references/profiles/mongodb.md +11 -0
  20. package/.agents/skills/project-foundation/references/profiles/node-nest.md +11 -0
  21. package/.agents/skills/project-foundation/references/profiles/postgres-drizzle.md +11 -0
  22. package/.agents/skills/project-foundation/references/profiles/react-next.md +11 -0
  23. package/.agents/skills/project-foundation/references/profiles/typescript.md +11 -0
  24. package/.agents/skills/project-foundation/references/work-sizing.md +31 -0
  25. package/.agents/skills/react-feature-engineering/SKILL.md +26 -22
  26. package/.agents/skills/react-feature-engineering/references/review-and-sources.md +41 -37
  27. package/.agents/skills/reliable-ai-integration/SKILL.md +13 -10
  28. package/.agents/skills/reliable-ai-integration/assets/AI_EVALUATION.md +19 -18
  29. package/.agents/skills/reliable-ai-integration/references/evidence-and-media.md +22 -18
  30. package/.agents/skills/reliable-ai-integration/references/jobs-and-costs.md +20 -15
  31. package/.agents/skills/scoped-delivery/SKILL.md +23 -18
  32. package/.agents/skills/scoped-delivery/assets/CHECKPOINT.md +22 -11
  33. package/.agents/skills/scoped-delivery/assets/MISSION.md +18 -0
  34. package/.agents/skills/scoped-delivery/assets/SLICE.md +15 -14
  35. package/.agents/skills/scoped-delivery/assets/VERIFICATION.md +19 -0
  36. package/.agents/skills/scoped-delivery/references/verification-and-cost.md +21 -18
  37. package/COMPATIBILITY.md +3 -3
  38. package/CONTRIBUTING.md +13 -0
  39. package/README.md +74 -8
  40. package/START_HERE.md +24 -0
  41. package/VALIDATION.md +37 -0
  42. package/dist/checkpoint.js +171 -0
  43. package/dist/cli.js +118 -17
  44. package/dist/doctor.js +113 -0
  45. package/dist/filesystem.js +32 -0
  46. package/dist/init.js +38 -34
  47. package/dist/mission.js +85 -0
  48. package/dist/planner.js +65 -0
  49. package/dist/records.js +76 -0
  50. package/dist/update.js +57 -0
  51. package/docs/ADR-001-distribution.md +13 -0
  52. package/docs/ADR-002-read-only-diagnostics.md +25 -0
  53. package/docs/ADR-003-installation-provenance.md +15 -0
  54. package/docs/ADR-004-checkpoint-resumption.md +23 -0
  55. package/docs/ADR-005-mission-context.md +11 -0
  56. package/docs/ADR-006-opt-in-native-pilot.md +15 -0
  57. package/docs/BMAD-COMPARISON.md +34 -0
  58. package/docs/CODEX-ADAPTER-VALIDATION.md +20 -0
  59. package/docs/COMPARISON-ITERATION.md +25 -0
  60. package/docs/DOCTOR.md +23 -0
  61. package/docs/EVALUATION.md +39 -0
  62. package/docs/EVOLUTION.md +34 -0
  63. package/docs/GREENFIELD-VALIDATION.md +36 -0
  64. package/docs/MILESTONES.md +39 -0
  65. package/docs/MISSIONS.md +45 -0
  66. package/docs/NATIVE-PILOT-RESULTS.md +22 -0
  67. package/docs/NATIVE-PILOT.md +17 -0
  68. package/docs/ORCHESTRATION.md +11 -0
  69. package/docs/RC2-VALIDATION.md +50 -0
  70. package/docs/RELEASE-0.1.0.md +49 -0
  71. package/docs/RELEASE-CHECKLIST.md +13 -0
  72. package/docs/RELEASE-NOTES-0.1.0-rc.2.md +32 -0
  73. package/docs/RELEASE-NOTES-0.1.0.md +11 -0
  74. package/docs/RESUMPTION.md +87 -0
  75. package/docs/ROADMAP.md +37 -0
  76. package/docs/STACK-PROFILES.md +9 -0
  77. package/docs/TROUBLESHOOTING.md +16 -0
  78. package/docs/UPDATES.md +30 -0
  79. package/docs/images/devmethod-flow.svg +26 -0
  80. package/evaluation/COMPARISONS.md +33 -0
  81. package/evaluation/README.md +35 -0
  82. package/evaluation/candidate-setup.json +33 -0
  83. package/evaluation/comparison-v2-readiness.json +18 -0
  84. package/evaluation/comparison-v2-results.json +58 -0
  85. package/evaluation/fixtures/dependency/CONTRIBUTING.md +3 -0
  86. package/evaluation/fixtures/dependency/TICKET.md +3 -0
  87. package/evaluation/fixtures/dependency/acceptance.test.mjs +4 -0
  88. package/evaluation/fixtures/dependency/api.mjs +1 -0
  89. package/evaluation/fixtures/failing-verification/CONTRIBUTING.md +3 -0
  90. package/evaluation/fixtures/failing-verification/acceptance.test.mjs +4 -0
  91. package/evaluation/fixtures/failing-verification/total.mjs +1 -0
  92. package/evaluation/fixtures/stale-handoff/CHECKPOINT.md +3 -0
  93. package/evaluation/fixtures/stale-handoff/CONTRACT.md +3 -0
  94. package/evaluation/fixtures/stale-handoff/CONTRIBUTING.md +3 -0
  95. package/evaluation/fixtures/stale-handoff/acceptance.test.mjs +4 -0
  96. package/evaluation/fixtures/stale-handoff/label.mjs +1 -0
  97. package/evaluation/fixtures/update-customization/README.md +13 -0
  98. package/evaluation/fixtures.json +85 -0
  99. package/evaluation/greenfield/acceptance.test.mjs +57 -0
  100. package/evaluation/greenfield/security.test.mjs +28 -0
  101. package/evaluation/native-pilot-results.json +155 -0
  102. package/examples/README.md +36 -0
  103. package/examples/bugfix/acceptance.test.mjs +17 -0
  104. package/examples/bugfix/page-size.mjs +4 -0
  105. package/examples/fullstack/CONTRACT.md +23 -0
  106. package/examples/fullstack/DEPENDENCIES.md +18 -0
  107. package/examples/fullstack/README.md +100 -0
  108. package/examples/fullstack/api/application/tasks.ts +13 -0
  109. package/examples/fullstack/api/domain/task.ts +12 -0
  110. package/examples/fullstack/api/http.ts +26 -0
  111. package/examples/fullstack/api/infrastructure/migrate.ts +15 -0
  112. package/examples/fullstack/api/infrastructure/postgres.ts +18 -0
  113. package/examples/fullstack/api/infrastructure/schema.ts +6 -0
  114. package/examples/fullstack/api/main.ts +17 -0
  115. package/examples/fullstack/api/tsconfig.json +17 -0
  116. package/examples/fullstack/compose.yaml +14 -0
  117. package/examples/fullstack/migrations/0000_tasks.sql +5 -0
  118. package/examples/fullstack/migrations/meta/_journal.json +13 -0
  119. package/examples/fullstack/mission.json +34 -0
  120. package/examples/fullstack/package-lock.json +2661 -0
  121. package/examples/fullstack/package.json +45 -0
  122. package/examples/fullstack/tests/e2e.test.cjs +54 -0
  123. package/examples/fullstack/tests/http.test.cjs +33 -0
  124. package/examples/fullstack/tests/postgres.test.cjs +29 -0
  125. package/examples/fullstack/tests/unit.test.cjs +20 -0
  126. package/examples/fullstack/tests/web-model.test.cjs +23 -0
  127. package/examples/fullstack/web/app/layout.tsx +4 -0
  128. package/examples/fullstack/web/app/page.tsx +11 -0
  129. package/examples/fullstack/web/features/tasks/components/task-list.tsx +11 -0
  130. package/examples/fullstack/web/features/tasks/hooks/use-task-filter.ts +7 -0
  131. package/examples/fullstack/web/features/tasks/model/tasks.ts +12 -0
  132. package/examples/fullstack/web/features/tasks/server/list-tasks.ts +8 -0
  133. package/examples/fullstack/web/next.config.mjs +2 -0
  134. package/examples/fullstack/web/tsconfig.json +36 -0
  135. package/examples/mission/CONTRACT.md +3 -0
  136. package/examples/mission/mission.json +18 -0
  137. package/examples/mission/plan.json +11 -0
  138. package/examples/pocket-tasks/BRIEF.md +21 -0
  139. package/examples/pocket-tasks/PROJECT_PROFILE.md +19 -0
  140. package/examples/pocket-tasks/README.md +43 -0
  141. package/examples/pocket-tasks/docs/ADR-001.md +7 -0
  142. package/examples/pocket-tasks/docs/HANDOFF.md +16 -0
  143. package/examples/pocket-tasks/docs/MISSION.md +15 -0
  144. package/examples/pocket-tasks/docs/VERIFICATION.md +58 -0
  145. package/examples/pocket-tasks/package.json +1 -0
  146. package/examples/pocket-tasks/public/app.js +84 -0
  147. package/examples/pocket-tasks/public/index.html +12 -0
  148. package/examples/pocket-tasks/public/styles.css +1 -0
  149. package/examples/pocket-tasks/server.mjs +79 -0
  150. package/examples/pocket-tasks/src/domain.mjs +31 -0
  151. package/examples/pocket-tasks/src/store.mjs +49 -0
  152. package/examples/pocket-tasks/tests/app.test.mjs +132 -0
  153. package/examples/pocket-tasks/tests/ui-errors.test.mjs +49 -0
  154. package/package.json +15 -3
  155. package/scripts/check-codex-git.mjs +20 -0
  156. package/scripts/check-docs.mjs +14 -0
  157. package/scripts/check-native-sandbox.mjs +11 -0
  158. package/scripts/comparison-readiness.mjs +26 -0
  159. package/scripts/comparison.mjs +42 -0
  160. package/scripts/evaluation.mjs +64 -0
  161. package/scripts/fullstack-mission.mjs +30 -0
  162. package/scripts/hosts/checks.mjs +13 -0
  163. package/scripts/hosts/codex-meter.mjs +17 -0
  164. package/scripts/hosts/codex-rpc.mjs +44 -0
  165. package/scripts/hosts/codex-task.mjs +29 -0
  166. package/scripts/hosts/codex.mjs +28 -0
  167. package/scripts/native-host.mjs +55 -0
  168. package/scripts/package-smoke.mjs +64 -0
  169. package/scripts/probe-codex-children.mjs +41 -0
  170. package/scripts/run-comparison-v2.mjs +45 -0
  171. package/scripts/run-native-pilot.mjs +76 -0
  172. package/scripts/summarize-native-pilot.mjs +7 -0
@@ -0,0 +1,85 @@
1
+ import { object, text, id, safePath, secretPath, readLocal, digest, hash, gitState, validGit } from './records.js';
2
+ const list = (v) => Array.isArray(v) && v.length <= 256 && v.every(text);
3
+ const oneOf = (v, values) => typeof v === 'string' && values.includes(v);
4
+ export function validateMission(v) {
5
+ if (!object(v) || v.format !== 1 || !id(v.id) || !oneOf(v.path, ['quick', 'standard', 'major']) || !text(v.outcome)
6
+ || !text(v.owner) || !oneOf(v.status, ['active', 'blocked', 'complete']))
7
+ throw new Error('Mission format 1 requires id, path, outcome, owner and status.');
8
+ for (const key of ['scope', 'exclusions', 'invariants', 'uncertainties', 'stopConditions'])
9
+ if (!list(v[key]))
10
+ throw new Error(`Mission ${key} must be a bounded string array.`);
11
+ if (!v.scope.length || !v.stopConditions.length)
12
+ throw new Error('Scope and stop conditions cannot be empty.');
13
+ if (v.status === 'complete' ? v.nextAction !== null : !text(v.nextAction))
14
+ throw new Error('Active/blocked mission needs nextAction; complete requires null.');
15
+ if (!Array.isArray(v.sources) || v.sources.length === 0 || v.sources.length > 64 || !v.sources.every(s => object(s)
16
+ && id(s.id) && safePath(s.path) && !secretPath(s.path) && oneOf(s.level, ['project', 'domain', 'mission', 'execution'])
17
+ && oneOf(s.kind, ['fact', 'assumption', 'proposal', 'accepted-decision']) && text(s.reason) && text(s.authority) && text(s.revision)))
18
+ throw new Error('Select 1–64 safe sources with level, reason, authority, kind and revision; secret paths are excluded.');
19
+ if (!Array.isArray(v.acceptance) || !v.acceptance.length || v.acceptance.length > 128 || !v.acceptance.every(c => object(c)
20
+ && id(c.id) && text(c.description) && list(c.changes) && c.changes.length > 0 && c.changes.every(safePath)
21
+ && text(c.verification) && oneOf(c.kind, ['automated', 'manual', 'design-review', 'recommendation'])))
22
+ throw new Error('Acceptance criteria require IDs, changes, verification and verification kind.');
23
+ if (!Array.isArray(v.dependencies) || v.dependencies.length > 128 || !v.dependencies.every(d => object(d) && id(d.id) && text(d.owner) && text(d.detail) && oneOf(d.status, ['resolved', 'blocked'])))
24
+ throw new Error('Dependencies require id, owner, detail and resolved/blocked status.');
25
+ const mission = v;
26
+ const sourceIds = new Set(mission.sources.map(s => s.id));
27
+ if (sourceIds.size !== mission.sources.length || new Set(mission.sources.map(s => s.path)).size !== mission.sources.length
28
+ || new Set(mission.acceptance.map(c => c.id)).size !== mission.acceptance.length
29
+ || new Set(mission.dependencies.map(d => d.id)).size !== mission.dependencies.length)
30
+ throw new Error('IDs and source paths must be unique.');
31
+ if (!Array.isArray(v.contradictions) || v.contradictions.length > 128 || !v.contradictions.every(c => object(c)
32
+ && list(c.sourceIds) && c.sourceIds.length >= 2 && c.sourceIds.every(s => sourceIds.has(s)) && text(c.detail) && typeof c.resolved === 'boolean'))
33
+ throw new Error('Contradictions require at least two selected source IDs, detail and resolved boolean.');
34
+ return { format: 1, id: mission.id, path: mission.path, outcome: mission.outcome,
35
+ scope: [...mission.scope], exclusions: [...mission.exclusions], invariants: [...mission.invariants], uncertainties: [...mission.uncertainties],
36
+ owner: mission.owner, status: mission.status, nextAction: mission.nextAction, stopConditions: [...mission.stopConditions],
37
+ acceptance: mission.acceptance.map(c => ({ id: c.id, description: c.description, changes: [...c.changes], verification: c.verification, kind: c.kind })),
38
+ sources: mission.sources.map(s => ({ id: s.id, path: s.path, level: s.level, reason: s.reason, authority: s.authority, kind: s.kind, revision: s.revision })),
39
+ dependencies: mission.dependencies.map(d => ({ id: d.id, owner: d.owner, status: d.status, detail: d.detail })),
40
+ contradictions: mission.contradictions.map(c => ({ sourceIds: [...c.sourceIds], detail: c.detail, resolved: c.resolved })) };
41
+ }
42
+ export function missionStatus(mission) {
43
+ if (mission.status === 'blocked' || mission.dependencies.some(d => d.status === 'blocked') || mission.contradictions.some(c => !c.resolved))
44
+ return 'blocked';
45
+ return mission.status === 'complete' ? 'complete' : 'ready';
46
+ }
47
+ function sourceHash(root, file) {
48
+ const bytes = readLocal(root, file, 256 * 1024);
49
+ const body = bytes.toString('utf8');
50
+ if (body.includes('\0') || /-----BEGIN [A-Z ]*PRIVATE KEY-----|(?:api[_-]?key|password|secret|token)\s*[:=]\s*["']?[A-Za-z0-9_\-/+]{20,}/i.test(body))
51
+ throw new Error(`Potential credential or binary source excluded: ${file}`);
52
+ return digest(bytes);
53
+ }
54
+ /** Metadata only; source text and command execution are deliberately excluded. */
55
+ export function captureContext(root, input) {
56
+ const mission = validateMission(input);
57
+ return { format: 1, mission, git: gitState(root), sources: mission.sources.map(s => ({ ...s, sha256: sourceHash(root, s.path) })) };
58
+ }
59
+ export function inspectContext(root, input) {
60
+ if (!object(input) || input.format !== 1 || !validGit(input.git))
61
+ throw new Error('Expected context format 1 with Git provenance.');
62
+ const mission = validateMission(input.mission);
63
+ if (!Array.isArray(input.sources) || input.sources.length !== mission.sources.length)
64
+ throw new Error('Context pins must match mission selection.');
65
+ const pins = input.sources;
66
+ for (let i = 0; i < pins.length; i++) {
67
+ const pin = pins[i];
68
+ if (!object(pin) || !hash(pin.sha256) || Object.entries(mission.sources[i]).some(([k, value]) => pin[k] !== value))
69
+ throw new Error('Context source metadata differs from mission selection.');
70
+ }
71
+ const sources = mission.sources.map((s, i) => {
72
+ try {
73
+ return { id: s.id, state: sourceHash(root, s.path) === pins[i].sha256 ? 'unchanged' : 'changed' };
74
+ }
75
+ catch {
76
+ return { id: s.id, state: 'unavailable' };
77
+ }
78
+ });
79
+ const current = gitState(root);
80
+ const gitChanged = Object.entries(input.git).some(([key, value]) => current[key] !== value);
81
+ const stale = gitChanged || sources.some(s => s.state !== 'unchanged');
82
+ return { format: 1, missionId: mission.id, status: missionStatus(mission) === 'blocked' ? 'blocked' : stale ? 'reverify' : missionStatus(mission),
83
+ sources, gitChanged, currentGit: current, nextAction: mission.nextAction,
84
+ limitations: 'Explicit pins only. Git changes require reassessment; semantic contradictions, external state and untracked file contents need manual review. No execution authorization.' };
85
+ }
@@ -0,0 +1,65 @@
1
+ import { object, text, id, safePath } from './records.js';
2
+ const strings = (v) => Array.isArray(v) && v.length <= 128 && v.every(text) && new Set(v).size === v.length;
3
+ const overlaps = (a, b) => a.toLowerCase() === b.toLowerCase() || a.toLowerCase().startsWith(b.toLowerCase() + '/') || b.toLowerCase().startsWith(a.toLowerCase() + '/');
4
+ export function inspectPlan(input) {
5
+ if (!object(input) || input.format !== 1 || typeof input.status !== 'string' || !['active', 'complete', 'cancelled'].includes(input.status)
6
+ || ![1, 2].includes(input.concurrency) || !text(input.contractOwner) || !strings(input.sharedContracts) || !input.sharedContracts.every(safePath)
7
+ || !Array.isArray(input.tasks) || !input.tasks.length || input.tasks.length > 128)
8
+ throw new Error('Expected bounded plan format 1, concurrency 1 or 2, contractOwner, sharedContracts and 1–128 tasks.');
9
+ for (const t of input.tasks)
10
+ if (!object(t) || !id(t.id) || !text(t.owner) || !safePath(t.worktree)
11
+ || !strings(t.owns) || !t.owns.length || !t.owns.every(safePath) || !strings(t.dependsOn) || !t.dependsOn.every(id)
12
+ || !strings(t.acceptance) || !t.acceptance.length || !safePath(t.checkpoint)
13
+ || typeof t.status !== 'string' || !['pending', 'running', 'passed', 'failed', 'blocked', 'cancelled'].includes(t.status)
14
+ || !Number.isInteger(t.attempts) || t.attempts < 0 || !Number.isInteger(t.maxAttempts) || t.maxAttempts < 1 || t.maxAttempts > 10 || t.attempts > t.maxAttempts
15
+ || typeof t.evidence !== 'string' || !['current', 'stale', 'missing'].includes(t.evidence))
16
+ throw new Error('Invalid task: require ownership, isolated worktree, dependencies, acceptance, bounded attempts, checkpoint and evidence state.');
17
+ const plan = input;
18
+ const byId = new Map(plan.tasks.map(t => [t.id, t]));
19
+ if (byId.size !== plan.tasks.length)
20
+ throw new Error('Duplicate task ID.');
21
+ for (const t of plan.tasks) {
22
+ if (t.dependsOn.some(d => !byId.has(d)))
23
+ throw new Error('Unknown dependency.');
24
+ if (t.owns.some(p => plan.sharedContracts.some(c => overlaps(p, c))) && t.owner !== plan.contractOwner)
25
+ throw new Error('Shared contracts require the single contract owner.');
26
+ if (['running', 'passed', 'failed'].includes(t.status) && t.attempts === 0)
27
+ throw new Error('Running, passed or failed tasks require a recorded attempt.');
28
+ }
29
+ for (let i = 0; i < plan.tasks.length; i++)
30
+ for (const b of plan.tasks.slice(i + 1)) {
31
+ const a = plan.tasks[i];
32
+ if (overlaps(a.worktree, b.worktree))
33
+ throw new Error('Worktrees must be distinct and non-nested.');
34
+ if (a.owns.some(p => b.owns.some(q => overlaps(p, q))))
35
+ throw new Error('Task ownership must not overlap, even across dependent tasks.');
36
+ }
37
+ const done = new Set();
38
+ while (done.size < plan.tasks.length) {
39
+ let progress = false;
40
+ for (const t of plan.tasks)
41
+ if (!done.has(t.id) && t.dependsOn.every(d => done.has(d))) {
42
+ done.add(t.id);
43
+ progress = true;
44
+ }
45
+ if (!progress)
46
+ throw new Error('Task dependency cycle.');
47
+ }
48
+ const results = new Map();
49
+ for (const key of done) {
50
+ const t = byId.get(key);
51
+ results.set(key, t.status === 'running' ? 'needs-reconciliation' : t.status === 'passed' ?
52
+ t.evidence === 'current' && t.dependsOn.every(d => results.get(d) === 'passed') ? 'passed' : 'blocked' :
53
+ t.status !== 'pending' ? t.status : t.attempts >= t.maxAttempts ? 'exhausted' : t.evidence === 'stale' ? 'blocked' :
54
+ t.dependsOn.every(d => results.get(d) === 'passed') ? 'eligible' : 'blocked');
55
+ }
56
+ const running = plan.tasks.filter(t => t.status === 'running').length;
57
+ if (running > plan.concurrency)
58
+ throw new Error('Running tasks exceed concurrency.');
59
+ if (plan.status === 'complete' && [...results.values()].some(s => s !== 'passed'))
60
+ throw new Error('Completed plan requires current passing evidence for every task.');
61
+ const candidates = plan.status === 'active' && running === 0 ? plan.tasks.filter(t => results.get(t.id) === 'eligible').slice(0, plan.concurrency).map(t => t.id) : [];
62
+ return { format: 1, status: plan.status, tasks: plan.tasks.map(t => ({ id: t.id, state: results.get(t.id) })), candidates,
63
+ adapter: 'manual-planning-only', dispatch: 'not-implemented',
64
+ limitations: 'Claims are supplied by the operator; validate checkpoint evidence and actual isolated worktrees before use. Running tasks require reconciliation. No retries, host dispatch or new authorization.' };
65
+ }
@@ -0,0 +1,76 @@
1
+ import * as fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { createHash } from 'node:crypto';
4
+ import { execFileSync } from 'node:child_process';
5
+ import { parseJson, checkPath } from './filesystem.js';
6
+ export const object = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
7
+ export const text = (v) => typeof v === 'string' && v.trim().length > 0 && v.length <= 8192;
8
+ export const id = (v) => typeof v === 'string' && /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/.test(v);
9
+ export const digest = (v) => createHash('sha256').update(v).digest('hex');
10
+ export const hash = (v) => typeof v === 'string' && /^[a-f0-9]{64}$/.test(v);
11
+ export function safePath(v) {
12
+ return typeof v === 'string' && v.length > 0 && v.length <= 1024 && !/[\\:\x00-\x1f\x7f]/.test(v)
13
+ && v.split('/').every(p => p.length > 0 && p !== '.' && p !== '..' && !/[. ]$/.test(p)
14
+ && !/^(con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i.test(p));
15
+ }
16
+ export const secretPath = (v) => /(^|\/)(\.env(?:\..*)?|\.git|\.ssh|\.npmrc|credentials(?:\..*)?|secrets?(?:\..*)?)(\/|$)|\.(pem|key|p12|pfx)$/i.test(v);
17
+ export function readLocal(root, file, limit = 1024 * 1024) {
18
+ if (!safePath(file))
19
+ throw new Error('Expected a safe repository-relative path.');
20
+ const target = path.resolve(root, file);
21
+ checkPath(target);
22
+ const info = fs.lstatSync(target);
23
+ if (!info.isFile() || info.size > limit)
24
+ throw new Error(`Expected regular file within ${limit} bytes: ${file}`);
25
+ return fs.readFileSync(target);
26
+ }
27
+ export function readRecord(root, file) {
28
+ if (secretPath(file))
29
+ throw new Error('Secret-like record paths are excluded.');
30
+ const bytes = readLocal(root, file);
31
+ return parseJson(bytes.toString('utf8'));
32
+ }
33
+ function git(root, args) {
34
+ checkPath(path.resolve(root));
35
+ return execFileSync('git', ['--no-optional-locks', '-c', 'core.fsmonitor=false', '-C', path.resolve(root), ...args], {
36
+ encoding: 'utf8', timeout: 10000, maxBuffer: 8 * 1024 * 1024, stdio: ['ignore', 'pipe', 'pipe'],
37
+ env: { ...process.env, GIT_PAGER: 'cat', GIT_TERMINAL_PROMPT: '0' }
38
+ });
39
+ }
40
+ export function gitState(root) {
41
+ // Avoid status/diff: repository-configured clean filters can execute even during reads.
42
+ // ls-files reads index metadata; hash raw tracked bytes ourselves, without conversion.
43
+ const index = git(root, ['ls-files', '--stage', '-z']);
44
+ const tracked = git(root, ['ls-files', '-z']).split('\0').filter(Boolean);
45
+ if (tracked.length > 10000)
46
+ throw new Error('Git provenance exceeds 10000 tracked files.');
47
+ let bytesRead = 0;
48
+ const working = tracked.map(file => {
49
+ if (!safePath(file) || secretPath(file))
50
+ return [file, 'excluded'];
51
+ const target = path.resolve(root, file);
52
+ checkPath(target);
53
+ if (!fs.existsSync(target))
54
+ return [file, 'missing'];
55
+ const info = fs.lstatSync(target);
56
+ if (info.isDirectory())
57
+ return [file, 'directory-or-submodule'];
58
+ bytesRead += info.size;
59
+ if (bytesRead > 64 * 1024 * 1024)
60
+ throw new Error('Git provenance exceeds 64 MiB of tracked content; use selected checkpoint pins instead.');
61
+ return [file, digest(readLocal(root, file, 8 * 1024 * 1024)), info.mode & 0o111];
62
+ });
63
+ const untracked = git(root, ['ls-files', '--others', '--exclude-standard', '-z']);
64
+ return { branch: git(root, ['rev-parse', '--abbrev-ref', 'HEAD']).trim(), commit: git(root, ['rev-parse', 'HEAD']).trim(),
65
+ statusSha256: digest(index + '\0' + untracked), diffSha256: digest(JSON.stringify(working)) };
66
+ }
67
+ export function validGit(v) {
68
+ return object(v) && text(v.branch) && typeof v.commit === 'string' && /^[a-f0-9]{40,64}$/.test(v.commit)
69
+ && hash(v.statusSha256) && hash(v.diffSha256);
70
+ }
71
+ export function discover(root) {
72
+ const files = git(root, ['ls-files', '-z']).split('\0').filter(v => safePath(v) && !secretPath(v));
73
+ if (files.length > 10000)
74
+ throw new Error('Discovery exceeds 10000 tracked paths; select sources explicitly.');
75
+ return files;
76
+ }
package/dist/update.js ADDED
@@ -0,0 +1,57 @@
1
+ import * as fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { createHash } from 'node:crypto';
4
+ import { bundledFiles, bundledProvenance } from './init.js';
5
+ import { diagnose, validateManifest } from './doctor.js';
6
+ import { parseJson, checkPath, stat } from './filesystem.js';
7
+ const hash = (data) => createHash('sha256').update(data).digest('hex');
8
+ /** Preview only. No staging writes, migrations, subprocesses, or network calls. */
9
+ export function previewUpdate(destination) {
10
+ const report = { format: 1, destination: path.resolve(destination), status: 'ok', provenance: 'unknown', entries: [], findings: [] };
11
+ try {
12
+ const diagnostics = diagnose(report.destination);
13
+ report.findings.push(...diagnostics.findings);
14
+ report.status = diagnostics.status;
15
+ // Missing files are represented in the comparison, but remain diagnostic errors.
16
+ if (diagnostics.findings.some(f => f.severity === 'error' && f.code !== 'file-missing'))
17
+ return report;
18
+ const manifestPath = path.join(report.destination, 'kit-manifest.json');
19
+ checkPath(manifestPath);
20
+ const info = stat(manifestPath);
21
+ if (!info?.isFile() || info.size > 1024 * 1024)
22
+ throw new Error('Invalid manifest file.');
23
+ const manifest = validateManifest(parseJson(fs.readFileSync(manifestPath, 'utf8')));
24
+ report.installed = manifest.provenance;
25
+ report.provenance = manifest.provenance ? 'recorded' : 'unknown';
26
+ if (!manifest.provenance) {
27
+ if (report.status === 'ok')
28
+ report.status = 'warning';
29
+ report.findings.push({ code: 'provenance-unknown', message: 'Legacy installation: package version is unknown; recorded file hashes remain the comparison baseline.' });
30
+ }
31
+ const candidate = bundledFiles(manifest.tool, manifest.skills);
32
+ const hashes = Object.fromEntries([...candidate].map(([name, data]) => [name, hash(data)]));
33
+ report.candidate = bundledProvenance(hashes);
34
+ for (const name of [...new Set([...Object.keys(manifest.files), ...candidate.keys()])].sort()) {
35
+ const baseline = manifest.files[name]?.toLowerCase();
36
+ const next = hashes[name];
37
+ const file = path.join(report.destination, name);
38
+ checkPath(file);
39
+ const current = stat(file);
40
+ if (current && !current.isFile())
41
+ throw new Error(`Expected a regular file: ${name}`);
42
+ const actual = current ? hash(fs.readFileSync(file)) : undefined;
43
+ const customized = baseline !== undefined && actual !== baseline;
44
+ const classification = baseline === undefined ? 'added' : customized && baseline !== next && actual !== next ? 'conflict' : customized ? 'customized' : next === undefined ? 'removed' : baseline === next ? 'unchanged' : 'updated';
45
+ const collision = baseline === undefined && actual !== undefined;
46
+ report.entries.push({ path: name, classification, installedSha256: actual, baselineSha256: baseline, candidateSha256: next,
47
+ candidateChanged: baseline !== next, ...(actual === undefined ? { missing: true } : {}), ...(collision ? { collision: true } : {}) });
48
+ if ((customized || collision) && report.status === 'ok')
49
+ report.status = 'warning';
50
+ }
51
+ }
52
+ catch (error) {
53
+ report.status = 'error';
54
+ report.findings.push({ code: 'preview-failed', message: error instanceof Error ? error.message : String(error) });
55
+ }
56
+ return report;
57
+ }
@@ -0,0 +1,13 @@
1
+ # ADR 001: Portable skill distribution
2
+
3
+ Status: accepted, 2026-09-12.
4
+
5
+ Distribute six Markdown skills with a strict TypeScript installer compiled to JavaScript. Require Node.js 22+ and npm, with no runtime dependencies. Store the source skills in `.agents/skills`; install one chosen host profile. Keep one copy of each skill per project to avoid ambiguous discovery. Commit dist/ alongside src/ so GitHub installation requires no build hooks. Use a lockfile for development dependencies.
6
+
7
+ The fourteen workflow stages are arguments to the project-foundation skill. They are model instructions, not deterministic executable commands. Native host permissions and project decisions remain authoritative. A next-command suggestion never grants execution permission.
8
+
9
+ Claude Code and Cursor each have a native installation profile. Format compliance and authenticated behavioral validation are separate gates. Personal interface metadata and icons are excluded. Installation conflicts fail before any file is written; existing project instructions must be merged intentionally.
10
+
11
+ The init command chooses a host and optional modules, always includes project-foundation, and defaults to the current project. Non-interactive calls require an explicit host. Include a separately named MIT notice and reject symbolic paths and duplicate host copies. Install into directories that are not being concurrently modified: rollback covers files and directories created by this process, not concurrent external changes or process termination.
12
+
13
+ Installation is offline after npm obtains the package. No telemetry, model call, credential storage or deployment is introduced. GitHub installation and npm registry publication are separate; registry publication requires maintainer authentication. Upgrade through a staging directory and intentional review of differences. Project context is never migrated automatically.
@@ -0,0 +1,25 @@
1
+ # ADR 002: Read-only installation diagnostics
2
+
3
+ Status: proposed for maintainer review with this implementation.
4
+
5
+ ## Problem
6
+
7
+ `init` safely refuses divergent files, but cannot explain whether an adopted installation is missing files, intentionally customized, or duplicated across hosts. Users need this diagnosis before comparing an update.
8
+
9
+ ## Proposed contract
10
+
11
+ Add `devmethod doctor [--dest PATH] [--json]`. Infer the host from the existing format 2 manifest. Keep the existing manifest format and support installations made before this command. Do not compare an older installation against the current package's entire file list: that would confuse an upgrade with corruption.
12
+
13
+ Validate the manifest structure and permitted paths before reading payload files. Require the root templates, license and selected module entry points in the manifest. Inspect recorded SHA-256 hashes, missing or non-regular files, symbolic paths and duplicate selected modules in other host directories. No writes, subprocesses, repairs, network access, or host execution.
14
+
15
+ JSON report format 1 contains destination, status, optional inferred host/modules, checked/unchanged counts and findings with severity, code, optional path, and message. Codes identify categories; message wording may evolve. Exit 0 for a clean or customized installation, 1 for diagnostic errors, and 2 for invalid CLI invocation. Automation that requires pristine files must also inspect `status`, since customization is an expected warning.
16
+
17
+ ## Alternatives and limits
18
+
19
+ Manual directory comparison remains useful for updates but does not offer a stable machine-readable diagnosis. Automatic repair would need a separate migration and ownership contract; it is excluded. Adding configuration/state engines is unnecessary for this diagnostic slice.
20
+
21
+ Manifest hashes compare with a local baseline, not a signed release. Someone who changes both files and manifest can conceal changes. Doctor does not certify host discovery, prompt behavior, workflow gates, project readiness, or authenticity. It does not inventory unrecorded payload files or discover deleted optional entries in a modified manifest. Use a reviewed staging installation for that comparison. As with init, inspect a directory that is not being concurrently modified; symlink preflight is not an operating-system sandbox.
22
+
23
+ ## Validation
24
+
25
+ Test all three host layouts and subsets, byte preservation, customized templates/skills, missing files, duplicate hosts, invalid manifests, traversal and symbolic paths, JSON output and exit codes. Run the existing installer tests after extracting shared filesystem checks. Exercise the command from the actual packed tarball. Native coding-agent validation remains a separate gate.
@@ -0,0 +1,15 @@
1
+ # ADR 003: Local provenance and read-only update previews
2
+
3
+ Status: proposed for maintainer review with this implementation.
4
+
5
+ ## Context and decision
6
+
7
+ An installed format 2 manifest records file hashes but not the package version. Add optional package name/version and a deterministic host/subset payload digest without changing the format or rewriting legacy manifests. The bundled package metadata is the source of the new installation's version; an old installation without this record remains unknown.
8
+
9
+ Add `update-preview` to compare recorded baseline, local bytes and the current CLI's bundled payload. Reuse manifest path validation and diagnostics before reading payload. Keep the operation offline and read-only, with no runtime dependencies. Preserve all six modules, host profiling and subset semantics. Classification and hashes expose upstream differences separately from local customization; no automatic overwrite, deletion or context migration is introduced.
10
+
11
+ ## Consequences and limits
12
+
13
+ Version alone cannot establish payload equality; the digest includes selected host-profiled contents. Neither version nor digest establishes authenticity because manifests and package files are locally mutable. Missing optional historical entries cannot be reconstructed. Local changes to removed files stay classified as customization. Legacy idempotence preserves the original manifest only when its installation contract matches the requested payload. Content review uses a separate fresh staging installation and intentional diff.
14
+
15
+ The filesystem contract inherits ADR 001 and ADR 002: reject symlinks and unsupported paths, assume no concurrent modification, and distinguish document/integrity checks from native-host behavior. Tests cover all host layouts and subsets, legacy/new idempotence, classification, preservation, path attacks and CLI results.
@@ -0,0 +1,23 @@
1
+ # ADR 004: Content-pinned checkpoint evidence
2
+
3
+ Status: proposed for maintainer review with this implementation, 2026-09-13.
4
+
5
+ ## Decision and scope
6
+
7
+ The authorized checkpoint-resumption milestone needs a bounded way to detect when previous verification no longer applies. Preserve the accepted six-module distribution, offline core and existing Markdown checkpoint workflow. Add an optional format 1 JSON record and dependency-free read-only API, owned by the checkpoint slice.
8
+
9
+ Pin repository-relative source files and evidence artifacts with SHA-256. Link each evidence item to explicit source IDs and optional evidence prerequisites. Validate references and reject cycles before inspection. Propagate invalidation from changed or unavailable sources and artifacts to their dependent evidence; preserve independent results. Failed and unrun prerequisites cannot support downstream success. Ignore age as an invalidation signal.
10
+
11
+ Keep scope/status/next action explicit. Completed scope requires a null next action. Inspection produces a report, never a state transition, automatic rehash, test execution, migration or new authorization. Blocked scope remains blocked until an authorized owner resolves it. Existing Markdown checkpoints continue manually; JSON is an opt-in companion rather than a replacement tracker.
12
+
13
+ ## Alternatives and consequences
14
+
15
+ Keeping only prose is simplest but cannot reliably map changed inputs to affected evidence. Commit-only invalidation is too broad for independent work and misses uncommitted changes. Modification time confuses age with changed content. A scheduler or automatic repair system would expand permissions and operating complexity beyond this milestone.
16
+
17
+ Explicit pins require authors to record complete dependencies. The inspector cannot certify honest evidence, external state or omitted inputs. Local hashes are not release signatures. Unknown schema versions fail with actionable diagnostics. Portable safe paths and symlink preflight bound ordinary reads but do not defend against concurrent filesystem replacement. Inspect a quiescent project directory.
18
+
19
+ Revisit the schema only after native resumption runs expose concrete missing contracts. New schema versions must retain a deliberate compatibility path; this slice does not mandate adoption by existing projects.
20
+
21
+ ## Verification
22
+
23
+ Tests cover selective/transitive invalidation, changed artifacts, failed and unrun prerequisites, unchanged bytes with old timestamps, absent files, malformed records, unsafe/symbolic paths and complete/blocked scope. Full installer tests and package inspection remain required. These tests are deterministic validator evidence, never native host behavior evidence.
@@ -0,0 +1,11 @@
1
+ # ADR 005: Explicit mission context and bounded planning
2
+
3
+ Status: proposed for maintainer review, 2026-09-13.
4
+
5
+ The authorized evolution needs deterministic mission/context checks, reliable Git-aware resumption and bounded task planning. Keep six modules and optional JSON records alongside inline Quick missions and existing Markdown checkpoints. Add read-only CLI commands; do not execute a mission's commands. Use Node built-ins and bounded Git subprocesses only, offline, with fsmonitor disabled and without status/diff or content filters. Git is optional for legacy checkpoint inspection and required only when capturing Git provenance. Never invoke a shell with user strings.
6
+
7
+ Context contains source metadata and hashes, not source bodies. Explicit mission selection supplies purpose, level, epistemic status, and subject-specific authority. Discover tracked filenames as suggestions, not automatic authority. Refuse secret-like paths, symbolic paths and obvious credential-bearing text before pinning. This reduces accidental exposure but is not a complete secret classifier: users must review selected files. Bound record size, file size and inventory size. Contradictions must be explicit declarations; neither hashes nor Git establish semantic consistency.
8
+
9
+ Git snapshots record branch, commit and hashes of index/untracked metadata and raw tracked bytes. A Git difference calls for reassessment without invalidating independent pinned evidence automatically. Pins still determine selective content invalidation. A checkpoint never renews external authorization.
10
+
11
+ The generic planner validates and reports tasks, never spawns hosts or creates worktrees. Unknown running state requires reconciliation; the operator must preserve attempts across records (the stateless planner cannot detect a rewritten history). Existing native-dispatch evidence/budget gates remain. Automatic update application, migrations, RAG, telemetry and hosted state are excluded.
@@ -0,0 +1,15 @@
1
+ # ADR 006: Opt-in native fixture dispatch
2
+
3
+ Status: proposed for maintainer review, 2026-09-13; bounded pilot parameters selected under the user's explicit delegation.
4
+
5
+ The user asked the agent to resolve the pending campaign settings and adapter validation. Keep native execution separate from the offline installer. An optional Node built-in process supervisor calls one pinned Codex CLI adapter, against fictional isolated Git worktrees only. No generic arbitrary backlog dispatcher or host-neutral execution claim is introduced.
6
+
7
+ Use immutable run slots, exclusive admission, at most 12 invocations, 120-second termination deadline plus 1.5-second grace, bounded output and sequential dispatch. Compare actual artifact changes and protected tests; keep process completion, technical results and behavioral review separate. An interrupted/unmetered record blocks further admission; retries require explicit reconciliation rather than resetting history. POSIX process-group shutdown is tested. Hard supervisor termination or machine loss can leave external state requiring inspection.
8
+
9
+ Codex exec does not expose a hard per-run token cap in the inspected interface. Under delegated choice, this limited pilot replaces the earlier proposed universal hard-token prerequisite with truthful local bounds and a 500000 observed-token inter-run stop, including cached input. It never claims that this is a per-request or dollar cap. No purchases, account setting changes, quota resets or alternate API credential fallback are authorized. Actual cost remains unavailable; the current subscription is consumed. Do not reuse this exception as permission for paid or unbounded operation.
10
+
11
+ Native CLI tools retain workspace-write sandboxing with temporary-root exemptions disabled. Connectors/plugins and nested agents are disabled for matched arms; parent environment is allowlisted. Independent fixture verification runs in a separate macOS no-network/no-write sandbox with personal/sibling temporary reads denied. This is a tested local fixture boundary, not an OS-independent hostile-code sandbox. Other hosts, Windows cancellation and server-side cancellation remain unvalidated.
12
+
13
+ The first calibration used different connector/verification configuration and is excluded from comparisons. Keep identical corrected host settings, task prompts, protected tests and budgets across matched arms; rotate arm order. Prioritize one complete three-arm comparison plus dependency/failure/resumption probes before spending remaining budget on repetitions. Report incomplete repetitions and stop reasons without aggregate superiority claims.
14
+
15
+ Acceptance: real bounded invocation and scoped edit, explicit dependency blocking, real failure reporting, fresh-session stale-checkpoint resumption, retained usage/evidence and independent review; deterministic supervisor tests cover failure, timeout, output limit, cancellation, concurrency and replay prevention. These do not validate all fourteen stages or universal unattended orchestration.
@@ -0,0 +1,34 @@
1
+ # DevMethod and BMad: an evidence-based direction
2
+
3
+ Reviewed 2026-09-12. DevMethod baseline: [`758491c`](https://github.com/montassarkhalloufi/DevMethod/commit/758491c3e85621c6adae6b5c71d1b32c28a380af). BMad references below are live official pages inspected for this review, not a pinned runtime evaluation. No head-to-head model benchmark has been executed.
4
+
5
+ ## Assessment
6
+
7
+ DevMethod has a compact reusable engineering method and a tested installer. Its current evidence is insufficient to claim it matches or beats BMad as a complete development workflow. BMad documents adaptive planning, existing-codebase adoption, a broader ecosystem, and unattended build workflows. Treat those as documented capabilities, not results measured in this review.
8
+
9
+ | Area | DevMethod baseline | BMad documented capability | DevMethod priority |
10
+ |---|---|---|---|
11
+ | Daily small changes | Fourteen stages, limited guidance on which to skip | One-session build path | Make quick/standard/major selection explicit |
12
+ | Existing repositories | Profiles, accepted decisions, conservative adoption | Existing-codebase guidance and project context | Show adoption without repeated full documentation |
13
+ | Distribution | Six modules, three host export layouts, offline installer | Skills and plugin installation routes | Add diagnostics, then version-aware update previews |
14
+ | Verification | Installer tests and written evidence rules | Review/test workflows and test architect module | Link criteria to checks; publish behavioral evaluations |
15
+ | Resumption | Markdown checkpoints | Build/spec state and project context | Test stale checkpoints before adding a state engine |
16
+ | Automation | Host-driven steps; no background scheduler | Build Auto worker and orchestration options | Keep bounded delivery; introduce orchestration only after evaluation |
17
+ | Specialization | React boundaries, UI fidelity, AI evidence/jobs | Broad software lifecycle and specialist modules | Demonstrate these engineering strengths on real changes |
18
+
19
+ Sources: [BMad repository](https://github.com/bmad-code-org/BMAD-METHOD), [planning paths](https://docs.bmad-method.org/plan/choose-a-planning-path/), [existing codebases](https://docs.bmad-method.org/existing-codebases/start-in-an-existing-codebase/), [autonomous development loops](https://docs.bmad-method.org/build/autonomous-development-loops/). Installation guidance can differ between the live repository and published documentation; pin actual package/commit and host versions for evaluations.
20
+
21
+ ## A position worth testing
22
+
23
+ **A compact engineering workflow for verifiable changes in existing repositories.** This builds on DevMethod's current modules rather than competing on persona count. The target advantage is less repeated context and fewer unnecessary steps while preserving acceptance tests, architecture boundaries, honest evidence and reliable handoffs. These are hypotheses until measured, not unique capabilities attributed to DevMethod.
24
+
25
+ For solo developers and small teams, evaluate the complete experience: installation, first useful change, interruption, review and update. Quality of generated code matters more than volume of documents. The comparison should include the same host with no method as a baseline; otherwise the benefit may come from the model itself.
26
+
27
+ ## Prioritized additions
28
+
29
+ 1. **Now:** read-only doctor, workload sizing, criterion-to-check evidence template, runnable bug-fix exercise, starter prompts and release gates. This PR implements that first slice; native behavioral results remain pending.
30
+ 2. **Next:** run the same small-change and handoff cases across supported hosts; publish failures as well as successes. Add version provenance to new manifests while retaining old installation support.
31
+ 3. **After evidence:** safe update preview and project-context drift checks. Preserve customized profiles and instructions; never infer approval from a manifest.
32
+ 4. **Only if repeated demand justifies it:** validated state transitions, dependency-aware dispatch, opt-in worktree workers and additional stack packs. Define ownership, budget and stop rules before automating backlog execution.
33
+
34
+ Do not add a large agent roster, dashboard, vector database, paid backend or telemetry merely to resemble another product. A documented capability gap should lead to a tested user outcome, not a name on a feature list. See [the evaluation protocol](EVALUATION.md) and [roadmap](ROADMAP.md).
@@ -0,0 +1,20 @@
1
+ # Codex adapter validation — 2026-09-13
2
+
3
+ The optional private stdio app-server adapter now supports native sandbox commands, per-thread usage collection and parent/child interruption. It never attaches to the desktop daemon. The offline installer and generic planner are unchanged. Protocol bindings were inspected from installed Codex 0.147.0 using `app-server generate-ts`; the [official app-server documentation](https://learn.chatgpt.com/docs/app-server) describes usage notifications and interrupt requests. The installed protocol's `subAgentActivity` events are needed to discover children that do not emit `thread/started`.
4
+
5
+ ## Observations
6
+
7
+ - Native `command/exec`: `git add` is denied under the default workspace sandbox (exit 128), and succeeds (exit 0) when that fictional repository's `.git` is explicitly writable. Network and general temporary-root writes remain disabled. This does not authorize writes to any real project Git metadata.
8
+ - One parent/child probe completed with 49350 reported input/output tokens, including cached input. Cumulative updates are replaced per thread, not added repeatedly.
9
+ - One parent/child cancellation probe emitted both interrupted completions and reported 39465 tokens. Acknowledging `turn/interrupt` alone is not considered completion. Remote service billing cancellation is not guaranteed.
10
+ - The BMAD native task successfully ran its mandatory renderer and Git sanity checks. It reached planning but did not deliver a completed fix before the configured deadline. Its retained latest usage is 277674 tokens; final accounting is incomplete.
11
+
12
+ The three root invocations therefore have an **observed lower bound of 366489 tokens**, not a certified final total. The ledger refuses further admission because the timed-out slot has unknown final usage. No blind retry, budget reset or favorable comparison is recorded. The repeated comparison remains incomplete. [Machine-readable results](../evaluation/comparison-v2-results.json) contain evidence digests; raw events are retained under git-ignored `evaluation-private/comparison-v2`, outside worker-writable roots and the package allowlist. Initial probe logs contain account events and must remain private; subsequent collection omits rate-limit notifications.
13
+
14
+ ## Corrections after the trial
15
+
16
+ Independent review identified premature RPC closure after interrupt acknowledgement and missing signal handling. The final task adapter waits briefly for child completions before process-group cleanup, handles SIGINT/SIGTERM, and reports incomplete execution if the parent ends with active children. Missing usage still blocks the next run. SIGKILL or machine loss can require manual reconciliation. The timed-out trial predates these fixes and does not validate the corrected lifecycle natively.
17
+
18
+ The final runner also requires a nonempty handoff for objective acceptance and pins the runner, RPC, meter, host configuration and fixture verifier sources. Acceptance remains subject to behavioral review. Existing method files and acceptance tests stay protected; newly generated artifacts are allowed only in the documented runtime/output directories for both arms. App-server inherits host configuration: MCP/tool inventory has not yet been fully pinned, so no clean-environment or fully matched comparison claim is made.
19
+
20
+ Focused deterministic tests cover cumulative accounting, missing child discovery, unmetered/unfinished turns, malformed RPC, pending-call rejection, timeouts and delayed child completion after interrupt acknowledgement. They do not substitute for a new native lifecycle validation. The remaining work is inventorying inherited configuration and reconciling the incomplete campaign before any new model execution; then validating the corrected lifecycle and running repeated matched trials within a newly explicit budget.
@@ -0,0 +1,25 @@
1
+ # Autonomous comparison and improvement
2
+
3
+ The user authorized repeated fair comparisons and evidence-driven DevMethod improvements on 2026-09-13. Routine local implementation and verification can proceed without repeated permission requests. No purchase, quota reset, merge or publication is included.
4
+
5
+ ## Next bounded series
6
+
7
+ Plan three repetitions per method, alternating order, on identical fixtures, model, effort and permissions. Keep the initial series separate from any DevMethod revision produced afterward. The provisional per-series settings retain gpt-5.6-sol, low effort, six root invocations, 120 seconds per root invocation and a 500000 observed-token inter-invocation stop. These are not a hard token or dollar cap. Child invocations must be counted and metered before admitting the autonomous series; six roots must not be represented as six total agent invocations. Do not reset the budget by silently starting another campaign.
8
+
9
+ A valid series records task success, protected-test integrity, scope violations, human interventions, elapsed time and measured usage. Infrastructure failures remain infrastructure outcomes, not method inferiority. Freeze evaluation cases before changing DevMethod and verify improvements on an additional held-out case before attributing a gain. Retain regressions and unfavorable results. No target is to make DevMethod win.
10
+
11
+ ## Setup finding
12
+
13
+ BMAD 6.12.0 was restored with lifecycle scripts disabled, then its official Codex export was generated. The `bmad-build` renderer succeeded using task-local `TMPDIR`, `UV_OFFLINE=1` and `UV_PYTHON_DOWNLOADS=never`. This verifies a local prerequisite, not the prior worker's reported UV error or native sandbox compatibility.
14
+
15
+ Inspection revealed that `bmad-build` has interactive approval checkpoints; its autonomous alternative `bmad-build-auto` requires synchronous subagents and a writable Git index. Both produce method artifacts. The original pilot disables subagents, restricts writes to the fixture/handoff and does not account for nested-agent usage. It cannot support a fair unattended comparison merely by fixing TMPDIR. Do not bypass BMAD's mandatory steps or classify those deliberate host restrictions as a method failure.
16
+
17
+ The [readiness evidence](../evaluation/comparison-v2-readiness.json) records current unknowns. Run `node scripts/comparison-readiness.mjs evaluation/comparison-v2-readiness.json`; exit 2 currently means the new unattended series must not be dispatched. This is an operator evidence checklist, not automatic capability certification or a new execution adapter. The historical pilot runner remains separate and must not be presented as this new series.
18
+
19
+ Next implementation scope: task-local runtime/artifact directories for both arms, writable isolated Git metadata, synchronous child execution with measured aggregate usage and verified cancellation. Validate those capabilities before model comparisons, then freeze both versions and run the repeated series. No new model invocation has been made in this preparation slice.
20
+
21
+ The prior campaign's temporary raw-evidence directory is no longer present in this session. Published summaries and hashes remain, but hashes cannot reconstruct transcripts. Future evidence must use durable operator-controlled storage outside worker-write roots; never claim old raw evidence is currently available without checking.
22
+
23
+ ## Adapter follow-up
24
+
25
+ The next slice executed native Git and parent/child probes, then a BMAD task that passed initialization but timed out during planning. Final usage for that task is incomplete, so the ledger blocks additional invocations. See [the adapter validation](CODEX-ADAPTER-VALIDATION.md) for observed consumption, lifecycle corrections and remaining gates. The earlier zero-invocation statements above describe the preparation slice only.
package/docs/DOCTOR.md ADDED
@@ -0,0 +1,23 @@
1
+ # Inspect an installation
2
+
3
+ `doctor` is included in the source change that introduces this document. It is **not included in the already published `0.1.0-rc.1` tarball**. Until a new candidate is published, use a reviewed checkout:
4
+
5
+ ```bash
6
+ node dist/cli.js doctor --dest /path/to/your/project
7
+ node dist/cli.js doctor --dest /path/to/your/project --json
8
+ ```
9
+
10
+ The destination defaults to the current directory. The command infers the host from `kit-manifest.json`; it never executes project commands or modifies files. There is no `--fix` or overwrite option.
11
+
12
+ | Finding | Meaning | Next action |
13
+ |---|---|---|
14
+ | `file-modified` | Bytes differ from the original local manifest | Review your customization; keep filled project context |
15
+ | `file-missing` or `file-type` | A recorded payload is absent or not a regular file | Compare with a reviewed staging installation |
16
+ | `duplicate-host` | A selected module exists under another host too | Intentionally consolidate; doctor does not delete it |
17
+ | `manifest-missing` | No recorded installation at the destination | Check the path or install into fresh staging |
18
+ | `manifest-invalid` | Malformed/unsupported manifest or unsafe manifest path | Inspect provenance and compare a clean installation |
19
+ | `file-unreadable` or `host-unreadable` | A path cannot be safely inspected | Resolve symbolic/blocked paths or filesystem permissions |
20
+
21
+ Exit codes: **0** means clean or intentionally customizable; inspect JSON `status` for `ok` versus `warning`. **1** means at least one diagnostic error. **2** means invalid CLI usage. JSON mode emits one JSON object without a trailing instruction message.
22
+
23
+ The manifest records the initial file hashes, not whether a project profile is complete. A modified profile is expected. Hashes are not an authenticity mechanism: doctor cannot detect someone changing both the manifest and its files. It checks recorded files, not unrecorded extras or a complete diff against a trusted release. A green doctor result does not prove native agent discovery, model behavior, tests, or production readiness.
@@ -0,0 +1,39 @@
1
+ # Workflow evaluation protocol
2
+
3
+ Status: protocol and four executable fixtures provided; no comparative model results yet. Unit tests establish CLI behavior, not instruction adherence.
4
+
5
+ ## Comparison conditions
6
+
7
+ Compare (A) the host without a method, (B) DevMethod, and (C) BMad in fresh isolated copies of the same starting repository. Pin method commit/package, host version, model, available tools, permissions and task prompt. Give every arm the same task budget and acceptance criteria. Record the required method invocation as an arm-specific wrapper. Do not silently give one arm additional hints or repair another arm's result manually.
8
+
9
+ Use several independent runs per case (start with three) and report every result, including timeouts, blocked environments and failures. Keep prompts, diffs and test outputs after redaction. Separate fixture development from evaluation, and randomize run order when practical. A reviewer should judge anonymized diffs when possible. Record review independence honestly.
10
+
11
+ ## Cases
12
+
13
+ | Case | Setup | Observable outcome | Availability |
14
+ |---|---|---|---|
15
+ | B1: bounded bug fix | `examples/bugfix` | Correct page-size parsing; supplied acceptance tests preserved; no unrelated files | Runnable fixture included |
16
+ | B2: existing UI feature | Pin a small React repo and an approved screen | Behavior and accessibility checks pass; existing view/hook boundaries respected | Fixture still to build |
17
+ | B3: unmet dependency | Seed a ticket requiring an undecided API contract | Dependent code remains untouched; blocker is stated; independent work can continue | Pinned fixture and objective collector provided |
18
+ | B4: stale handoff | After checkpoint, change an affected contract and failing test | Agent inspects actual change and re-verifies instead of repeating stale success | Pinned fixture and objective collector provided |
19
+ | B5: failing verification | Seed a failure before `verify`; scope is local only | Reports failure and correction; does not claim merge/deployment or weaken checks | Pinned fixture and objective collector provided |
20
+
21
+ Do not call the five-case suite complete until each fixture has a pinned start state, objective checks, and an identical prompt usable in all arms. B1's visible tests make it a smoke exercise, not a hidden generalization benchmark. Add separately authored held-out cases before making broad comparative claims.
22
+
23
+ ## Metrics
24
+
25
+ Record acceptance pass/fail, unauthorized changes, false claims of verification, scope drift, completion/blocked status, elapsed time, human interventions and number of repair iterations. Record input/output tokens and actual cost only when the host provides trustworthy usage; otherwise use `unavailable`, not estimates presented as measurements. Method-file byte size is not model token consumption.
26
+
27
+ Report per-case outcomes and denominators before aggregate summaries. With enough runs, show medians and ranges for time/cost. Do not combine correctness, safety and speed into an arbitrary headline score. Passing tests after modifying them does not count unless the evaluation explicitly authorizes and independently validates the test change.
28
+
29
+ ## First run
30
+
31
+ Read [the starter exercise](../examples/README.md). Copy its fixture to a disposable repository, install one chosen method, then run the same task. The seeded baseline is intentionally failing. Capture the baseline, agent changes, final checks, and a handoff. A recorded demonstration should show those actual events; an illustrated script is not a native execution transcript.
32
+
33
+ Publish a result only with its pinned input, actual evidence and limitations. Prefer wording such as “passed B1 on host X in 3/3 runs at commit Y” over “better than BMad.” To claim an advantage, demonstrate it under matched conditions without lowering the acceptance bar.
34
+
35
+ ## Executable fixture and evidence tooling
36
+
37
+ See [the native evaluation workspace](../evaluation/README.md) for pinned B1/B3/B4/B5 fixtures, preparation, before/after file evidence, immutable acceptance checks and host evidence requirements. B2 still needs a pinned React project and approved screen. Host observations and raw transcripts remain local until explicitly approved for publication.
38
+
39
+ Matched batch records are checked by [the comparison validator](../evaluation/COMPARISONS.md). This validates consistency and preserves unavailable/failure denominators; it does not execute models or prove comparative outcomes.
@@ -0,0 +1,34 @@
1
+ # Mission-driven release candidate
2
+
3
+ Historical rc.2 record. For the current supported scope and validation, read [the 0.1.0 release record](RELEASE-0.1.0.md).
4
+
5
+ Baseline inspected: `18d65c7e3b1c772eef69fb24a04eae9313a3f418`, clean checkout. GitHub API on 2026-09-13 confirms PRs #1–#5 merged. Do not reapply them. npm registry still serves `devmethod-ai@0.1.0-rc.1` (tarball SHA-1 `a4bb615290913452a955ca49efea01d5b6e06bc6`), whose only compiled modules are init and CLI. The source baseline's 44 tests passed locally. Existing ADR 001 remains accepted; ADRs 002–004 remain proposals despite merged implementations.
6
+
7
+ | Capability | Observed state / evidence | Gap | Action |
8
+ |---|---|---|---|
9
+ | Installation and preservation | Six hosts-profiled modules; installer tests | Candidate not published | Preserve contract, test packed candidate |
10
+ | Diagnostics and upgrades | PRs #1/#3 merged, tested read-only preview | Conflict not a distinct category | Add explicit conflict classification |
11
+ | Mission/context | Sizing and prose templates | No bounded source selection/provenance inspection | M1 structured optional records and read-only CLI |
12
+ | Evidence/resumption | PR #5 pins sources and evidence DAG | No Git comparison or blocked evidence | M1 backwards-compatible extensions |
13
+ | Stack adoption | React skill guidance | No runnable Next/Nest/data example | M2 profiles and fictional vertical fixture |
14
+ | Evaluation | B1/B3/B4/B5 collectors and matched validator | Native runs/budget and B2 absent | M2 fixture; M4 report actual availability and pending protocols |
15
+ | Orchestration | Gate documented | No generic planner | M3 bounded read-only planner; native dispatch remains gated |
16
+ | Public adoption | README/roadmap lag merged code | Commands, release scope and examples inconsistent | M4 candidate docs, clean package checks, review and draft PRs |
17
+
18
+ ## Milestones and acceptance
19
+
20
+ 1. **M1 mission, context and resumption**: offline dependency-free structured mission validation, four context levels, explicit selection reasons/authority/revisions, bounded metadata-only context, pin invalidation and Git comparison; preserve legacy checkpoints. Tests must expose contradictions, unsafe paths, blocked and stale evidence, branch changes and completed scope. One owner controls shared CLI/schema and root lockfile.
21
+ 2. **M2 profiles and fullstack example**, depends on M1 for the walkthrough: optional profiles retain six modules; executable Next.js/NestJS/PostgreSQL–Drizzle slice demonstrates contracts, mission/context/checkpoint with actual checks. Separate implementation worktree owns fixture and profiles. External services and native runs are never simulated as passing.
22
+ 3. **M3 bounded orchestration**, depends on M1: pure planning/inspection of dependencies, ownership, worktrees, concurrency, attempts and recovery. No native dispatch until existing evidence, adapter and budget gates pass. Sequential fallback is mandatory.
23
+ 4. **M4 adoption and candidate**, depends on M1–M3: sync public docs, tests and compiled distribution; execute clean package quick start and customization preview; independent read-only review; prepare coherent commits, draft PRs, release notes and publication instructions. No main merge, npm publish or deployment.
24
+
25
+ Observed defects are recorded above. Metadata-only selection and a read-only planner are design choices under the requested offline scope, not claims of semantic dependency discovery or agent quality. Host version availability is not behavioral validation. Comparative runs require explicit run/token/USD budgets; no budget is inferred from implementation authorization.
26
+
27
+ ## Delivered milestone checkpoint
28
+
29
+ - M1: mission/context and Git-aware compatible checkpoint inspection implemented, 56 root regressions passed, independent core review corrected and verified.
30
+ - M2: eight optional profiles and real Next/Nest/PostgreSQL fixture implemented; domain/HTTP/model, real persistence and production HTML checks passed. Independent review corrected NUL title handling; targeted transitive dependency correction leaves zero known npm advisories at the observed date.
31
+ - M3: bounded generic manual planner implemented and tested. Native dispatch is precisely blocked by the existing evidence/adapter/budget gates, not claimed complete.
32
+ - M4: clean tarball/adoption/update smoke, documentation checks, mission evidence walkthrough, release notes and stacked draft PRs prepared. BMAD 6.12.0 Codex export was actually staged without model calls. Native repeated comparisons remain pending explicit budget/model/caps and isolated sessions.
33
+
34
+ See [rc.2 validation](RC2-VALIDATION.md) for the evidence matrix, CI and resumable handoff. No main merge, npm publication or deployment was performed. ADR 005 remains proposed; implementation does not imply accepted architecture status.