codex-workflow-v2 2.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -0
- package/dist/src/artifacts.d.ts +4 -0
- package/dist/src/artifacts.js +106 -0
- package/dist/src/artifacts.js.map +1 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +356 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/contracts.d.ts +313 -0
- package/dist/src/contracts.js +3 -0
- package/dist/src/contracts.js.map +1 -0
- package/dist/src/diagnostics.d.ts +19 -0
- package/dist/src/diagnostics.js +25 -0
- package/dist/src/diagnostics.js.map +1 -0
- package/dist/src/domain/discovery.d.ts +8 -0
- package/dist/src/domain/discovery.js +25 -0
- package/dist/src/domain/discovery.js.map +1 -0
- package/dist/src/domain/validation.d.ts +3 -0
- package/dist/src/domain/validation.js +96 -0
- package/dist/src/domain/validation.js.map +1 -0
- package/dist/src/errors.d.ts +6 -0
- package/dist/src/errors.js +11 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/fs-utils.d.ts +4 -0
- package/dist/src/fs-utils.js +52 -0
- package/dist/src/fs-utils.js.map +1 -0
- package/dist/src/git.d.ts +19 -0
- package/dist/src/git.js +115 -0
- package/dist/src/git.js.map +1 -0
- package/dist/src/graph.d.ts +28 -0
- package/dist/src/graph.js +263 -0
- package/dist/src/graph.js.map +1 -0
- package/dist/src/index.d.ts +12 -0
- package/dist/src/index.js +13 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/memory.d.ts +9 -0
- package/dist/src/memory.js +242 -0
- package/dist/src/memory.js.map +1 -0
- package/dist/src/migration.d.ts +46 -0
- package/dist/src/migration.js +112 -0
- package/dist/src/migration.js.map +1 -0
- package/dist/src/repository.d.ts +12 -0
- package/dist/src/repository.js +69 -0
- package/dist/src/repository.js.map +1 -0
- package/dist/src/reviewer.d.ts +82 -0
- package/dist/src/reviewer.js +184 -0
- package/dist/src/reviewer.js.map +1 -0
- package/dist/src/state/lock.d.ts +13 -0
- package/dist/src/state/lock.js +100 -0
- package/dist/src/state/lock.js.map +1 -0
- package/dist/src/state/store.d.ts +45 -0
- package/dist/src/state/store.js +185 -0
- package/dist/src/state/store.js.map +1 -0
- package/dist/src/ulid.d.ts +2 -0
- package/dist/src/ulid.js +22 -0
- package/dist/src/ulid.js.map +1 -0
- package/dist/src/version.d.ts +2 -0
- package/dist/src/version.js +3 -0
- package/dist/src/version.js.map +1 -0
- package/dist/src/workflow.d.ts +93 -0
- package/dist/src/workflow.js +1276 -0
- package/dist/src/workflow.js.map +1 -0
- package/docs/decisions.md +38 -0
- package/docs/development-flow.md +69 -0
- package/docs/project-memory.md +38 -0
- package/docs/release.md +26 -0
- package/docs/validation-report.md +19 -0
- package/package.json +56 -0
- package/plugins/codex-workflow-gateway/.codex-plugin/plugin.json +25 -0
- package/plugins/codex-workflow-gateway/references/protocol.md +66 -0
- package/plugins/codex-workflow-gateway/scripts/install-or-update.sh +26 -0
- package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +72 -0
- package/references/discovery.md +12 -0
- package/references/git-policy.md +7 -0
- package/references/state-machine.md +11 -0
- package/references/validation-and-review.md +13 -0
- package/roles/delivery-coordinator.md +10 -0
- package/roles/independent-reviewer.md +10 -0
- package/roles/scope-lead.md +11 -0
- package/roles/technical-planner.md +10 -0
- package/roles/worker.md +10 -0
- package/schemas/context-envelope.schema.json +58 -0
- package/schemas/discovery.schema.json +19 -0
- package/schemas/graph-binding.schema.json +30 -0
- package/schemas/milestone.schema.json +58 -0
- package/schemas/project-knowledge-map.schema.json +37 -0
- package/schemas/review-result.schema.json +30 -0
- package/schemas/task.schema.json +39 -0
- package/templates/brief.md +21 -0
- package/templates/plan.md +17 -0
- package/templates/result.md +13 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
export declare const STATE_SCHEMA_VERSION: 1;
|
|
2
|
+
export declare const PROTOCOL_VERSION: 1;
|
|
3
|
+
export type DiscoveryStatus = 'needs_discovery' | 'needs_clarification' | 'ready_to_materialize' | 'materialized' | 'abandoned';
|
|
4
|
+
export type TaskStatus = 'planning' | 'awaiting_execution_authorization' | 'ready' | 'in_progress' | 'validating' | 'needs_fix' | 'awaiting_final_acceptance' | 'merging' | 'ready_to_merge' | 'merged' | 'blocked' | 'cancelled';
|
|
5
|
+
export type MilestoneStatus = 'planning' | 'awaiting_execution_authorization' | 'active' | 'validating' | 'awaiting_final_acceptance' | 'accepted' | 'blocked' | 'cancelled';
|
|
6
|
+
export type StepStatus = 'planned' | 'in_progress' | 'completed' | 'failed' | 'blocked' | 'skipped';
|
|
7
|
+
export type WorkspaceOwner = 'local' | 'external';
|
|
8
|
+
export type ReviewStatus = 'pending' | 'passed' | 'failed' | 'unverified';
|
|
9
|
+
export type AuthorizationKind = 'execution' | 'final_acceptance' | 'exception';
|
|
10
|
+
export type KnowledgeImpact = 'none' | 'update' | 'create' | 'retire';
|
|
11
|
+
export type GraphUse = 'code-aware' | 'not-applicable';
|
|
12
|
+
export type GraphKind = 'product' | 'workflow';
|
|
13
|
+
export type GraphMode = 'moderate' | 'full';
|
|
14
|
+
export type GraphBindingStatus = 'ready' | 'stale' | 'unavailable' | 'fallback';
|
|
15
|
+
export type KnowledgeCategory = 'agent-guidance' | 'onboarding' | 'architecture' | 'decisions' | 'commands' | 'ownership' | 'testing' | 'operations' | 'domain';
|
|
16
|
+
export type KnowledgeAuthority = 'canonical' | 'supporting';
|
|
17
|
+
export type KnowledgeMapStatus = 'draft' | 'awaiting_approval' | 'active' | 'stale' | 'conflicted';
|
|
18
|
+
export type WorkflowRole = 'scope-lead' | 'technical-planner' | 'delivery-coordinator' | 'worker' | 'independent-reviewer';
|
|
19
|
+
export interface RevisionedRecord {
|
|
20
|
+
schemaVersion: typeof STATE_SCHEMA_VERSION;
|
|
21
|
+
revision: number;
|
|
22
|
+
id: string;
|
|
23
|
+
projectId: string;
|
|
24
|
+
createdAt: string;
|
|
25
|
+
updatedAt: string;
|
|
26
|
+
}
|
|
27
|
+
export interface DiscoveryState extends RevisionedRecord {
|
|
28
|
+
kind: 'discovery';
|
|
29
|
+
status: DiscoveryStatus;
|
|
30
|
+
goal: string;
|
|
31
|
+
outcome: string | null;
|
|
32
|
+
facts: string[];
|
|
33
|
+
decisions: string[];
|
|
34
|
+
assumptions: string[];
|
|
35
|
+
unknowns: string[];
|
|
36
|
+
blockingUnknowns: string[];
|
|
37
|
+
scope: string[];
|
|
38
|
+
outOfScope: string[];
|
|
39
|
+
constraints: string[];
|
|
40
|
+
acceptance: string[];
|
|
41
|
+
materializedEntityId: string | null;
|
|
42
|
+
}
|
|
43
|
+
export interface PlanStepInput {
|
|
44
|
+
id: string;
|
|
45
|
+
title: string;
|
|
46
|
+
objective: string;
|
|
47
|
+
requirements: string[];
|
|
48
|
+
dependencies: string[];
|
|
49
|
+
expectedOutputs: string[];
|
|
50
|
+
allowedWrites: string[];
|
|
51
|
+
forbiddenScope: string[];
|
|
52
|
+
checks: string[];
|
|
53
|
+
}
|
|
54
|
+
export interface TaskPlanInput {
|
|
55
|
+
objective: string;
|
|
56
|
+
requirements: string[];
|
|
57
|
+
acceptance: string[];
|
|
58
|
+
risks: string[];
|
|
59
|
+
knowledgeImpact: KnowledgeImpact;
|
|
60
|
+
knowledgeImpactReason: string;
|
|
61
|
+
knowledgeTargets: KnowledgeTarget[];
|
|
62
|
+
knowledgeMapRevision: number;
|
|
63
|
+
knowledgeMapHash: string;
|
|
64
|
+
graphUse: GraphUse;
|
|
65
|
+
steps: PlanStepInput[];
|
|
66
|
+
}
|
|
67
|
+
export interface KnowledgeTarget {
|
|
68
|
+
category: KnowledgeCategory;
|
|
69
|
+
path: string;
|
|
70
|
+
reason: string;
|
|
71
|
+
requirementIds: string[];
|
|
72
|
+
}
|
|
73
|
+
export interface KnowledgeSource {
|
|
74
|
+
id: string;
|
|
75
|
+
category: KnowledgeCategory;
|
|
76
|
+
path: string;
|
|
77
|
+
scope: string;
|
|
78
|
+
authority: KnowledgeAuthority;
|
|
79
|
+
contentHash: string;
|
|
80
|
+
discoveredBy: string;
|
|
81
|
+
lastVerifiedAt: string;
|
|
82
|
+
}
|
|
83
|
+
export interface KnowledgeGap {
|
|
84
|
+
category: KnowledgeCategory;
|
|
85
|
+
scope: string;
|
|
86
|
+
reason: string;
|
|
87
|
+
}
|
|
88
|
+
export interface KnowledgeConflict {
|
|
89
|
+
category: KnowledgeCategory;
|
|
90
|
+
scope: string;
|
|
91
|
+
sourceIds: string[];
|
|
92
|
+
reason: string;
|
|
93
|
+
}
|
|
94
|
+
export interface KnowledgeMapApproval {
|
|
95
|
+
mapHash: string;
|
|
96
|
+
actor: string;
|
|
97
|
+
approvedAt: string;
|
|
98
|
+
}
|
|
99
|
+
export interface ProjectKnowledgeMap extends RevisionedRecord {
|
|
100
|
+
kind: 'knowledge-map';
|
|
101
|
+
status: KnowledgeMapStatus;
|
|
102
|
+
entries: KnowledgeSource[];
|
|
103
|
+
gaps: KnowledgeGap[];
|
|
104
|
+
conflicts: KnowledgeConflict[];
|
|
105
|
+
approval: KnowledgeMapApproval | null;
|
|
106
|
+
}
|
|
107
|
+
export interface GraphBindingSnapshot {
|
|
108
|
+
projectKey: string | null;
|
|
109
|
+
rootFingerprint: string;
|
|
110
|
+
indexedHead: string | null;
|
|
111
|
+
packageVersion: string | null;
|
|
112
|
+
manifestHash: string | null;
|
|
113
|
+
mode: GraphMode;
|
|
114
|
+
status: GraphBindingStatus;
|
|
115
|
+
nodeCount: number | null;
|
|
116
|
+
edgeCount: number | null;
|
|
117
|
+
observedAt: string;
|
|
118
|
+
evidenceHash: string;
|
|
119
|
+
fallbackReason: string | null;
|
|
120
|
+
}
|
|
121
|
+
export interface GraphBinding extends RevisionedRecord, GraphBindingSnapshot {
|
|
122
|
+
kind: 'graph-binding';
|
|
123
|
+
graphKind: GraphKind;
|
|
124
|
+
provider: 'codebase-memory-mcp';
|
|
125
|
+
previous: GraphBindingSnapshot | null;
|
|
126
|
+
}
|
|
127
|
+
export interface GraphRefreshRequest {
|
|
128
|
+
protocolVersion: typeof PROTOCOL_VERSION;
|
|
129
|
+
requestId: string;
|
|
130
|
+
projectId: string;
|
|
131
|
+
graphKind: GraphKind;
|
|
132
|
+
sourceRoot: string;
|
|
133
|
+
rootFingerprint: string;
|
|
134
|
+
indexedHead: string | null;
|
|
135
|
+
packageVersion: string | null;
|
|
136
|
+
manifestHash: string | null;
|
|
137
|
+
mode: GraphMode;
|
|
138
|
+
persistence: false;
|
|
139
|
+
issuedAt: string;
|
|
140
|
+
}
|
|
141
|
+
export interface GraphRefreshEvidence {
|
|
142
|
+
requestId: string;
|
|
143
|
+
provider: 'codebase-memory-mcp';
|
|
144
|
+
projectKey: string;
|
|
145
|
+
rootFingerprint: string;
|
|
146
|
+
indexedHead: string | null;
|
|
147
|
+
packageVersion: string | null;
|
|
148
|
+
manifestHash: string | null;
|
|
149
|
+
mode: GraphMode;
|
|
150
|
+
status: 'ready' | 'stale' | 'unavailable';
|
|
151
|
+
nodeCount: number | null;
|
|
152
|
+
edgeCount: number | null;
|
|
153
|
+
observedAt: string;
|
|
154
|
+
}
|
|
155
|
+
export interface KnowledgeSelection {
|
|
156
|
+
sourceId: string;
|
|
157
|
+
authority: KnowledgeAuthority;
|
|
158
|
+
}
|
|
159
|
+
export interface StepEvidence {
|
|
160
|
+
recordedAt: string;
|
|
161
|
+
commitSha: string;
|
|
162
|
+
changedFiles: string[];
|
|
163
|
+
checks: Array<{
|
|
164
|
+
command: string;
|
|
165
|
+
passed: boolean;
|
|
166
|
+
exitCode: number;
|
|
167
|
+
output: string;
|
|
168
|
+
}>;
|
|
169
|
+
notes: string[];
|
|
170
|
+
}
|
|
171
|
+
export interface TaskStep extends PlanStepInput {
|
|
172
|
+
status: StepStatus;
|
|
173
|
+
evidence: StepEvidence | null;
|
|
174
|
+
}
|
|
175
|
+
export interface AuthorizationEvent {
|
|
176
|
+
kind: AuthorizationKind;
|
|
177
|
+
decision: 'approved' | 'rejected' | 'waived' | 'superseded';
|
|
178
|
+
actor: string;
|
|
179
|
+
recordedAt: string;
|
|
180
|
+
briefHash: string | null;
|
|
181
|
+
planHash: string | null;
|
|
182
|
+
resultHash: string | null;
|
|
183
|
+
evidenceHash: string | null;
|
|
184
|
+
headCommit: string | null;
|
|
185
|
+
reason: string;
|
|
186
|
+
}
|
|
187
|
+
export interface ReviewRecord {
|
|
188
|
+
status: ReviewStatus;
|
|
189
|
+
reviewer: string;
|
|
190
|
+
recordedAt: string | null;
|
|
191
|
+
headCommit: string | null;
|
|
192
|
+
briefHash: string | null;
|
|
193
|
+
planHash: string | null;
|
|
194
|
+
evidenceHash: string | null;
|
|
195
|
+
summary: string;
|
|
196
|
+
findings: Array<{
|
|
197
|
+
id: string;
|
|
198
|
+
severity: 'critical' | 'major' | 'minor';
|
|
199
|
+
requirement: string | null;
|
|
200
|
+
summary: string;
|
|
201
|
+
evidence: string;
|
|
202
|
+
requiredAction: string;
|
|
203
|
+
}>;
|
|
204
|
+
}
|
|
205
|
+
export type ReviewInput = Pick<ReviewRecord, 'status' | 'reviewer' | 'summary' | 'findings'>;
|
|
206
|
+
export interface TaskState extends RevisionedRecord {
|
|
207
|
+
kind: 'task';
|
|
208
|
+
status: TaskStatus;
|
|
209
|
+
title: string;
|
|
210
|
+
slug: string;
|
|
211
|
+
discoveryId: string;
|
|
212
|
+
milestoneId: string | null;
|
|
213
|
+
repositoryRoot: string;
|
|
214
|
+
baseBranch: string;
|
|
215
|
+
baseCommit: string | null;
|
|
216
|
+
taskBranch: string | null;
|
|
217
|
+
workspaceOwner: WorkspaceOwner | null;
|
|
218
|
+
briefHash: string;
|
|
219
|
+
planHash: string | null;
|
|
220
|
+
resultHash: string | null;
|
|
221
|
+
evidenceHash: string | null;
|
|
222
|
+
requirements: string[];
|
|
223
|
+
acceptance: string[];
|
|
224
|
+
risks: string[];
|
|
225
|
+
knowledgeImpact: KnowledgeImpact | null;
|
|
226
|
+
knowledgeImpactReason: string | null;
|
|
227
|
+
knowledgeTargets: KnowledgeTarget[];
|
|
228
|
+
knowledgeMapRevision: number | null;
|
|
229
|
+
knowledgeMapHash: string | null;
|
|
230
|
+
graphUse: GraphUse | null;
|
|
231
|
+
steps: TaskStep[];
|
|
232
|
+
authorizations: AuthorizationEvent[];
|
|
233
|
+
review: ReviewRecord;
|
|
234
|
+
blockReason: string | null;
|
|
235
|
+
mergedCommit: string | null;
|
|
236
|
+
systemCommits: string[];
|
|
237
|
+
}
|
|
238
|
+
export interface MilestoneState extends RevisionedRecord {
|
|
239
|
+
kind: 'milestone';
|
|
240
|
+
status: MilestoneStatus;
|
|
241
|
+
title: string;
|
|
242
|
+
discoveryId: string;
|
|
243
|
+
outcome: string;
|
|
244
|
+
successSignal: string;
|
|
245
|
+
acceptance: string[];
|
|
246
|
+
baseBranch: string;
|
|
247
|
+
taskIds: string[];
|
|
248
|
+
memberships: MilestoneMembership[];
|
|
249
|
+
checks: string[];
|
|
250
|
+
membershipRevision: number;
|
|
251
|
+
authorizations: AuthorizationEvent[];
|
|
252
|
+
planHash: string | null;
|
|
253
|
+
resultHash: string | null;
|
|
254
|
+
evidenceHash: string | null;
|
|
255
|
+
acceptedHead: string | null;
|
|
256
|
+
cancellationReason: string | null;
|
|
257
|
+
}
|
|
258
|
+
export interface MilestoneMembership {
|
|
259
|
+
taskId: string;
|
|
260
|
+
disposition: 'required' | 'waived' | 'cancelled';
|
|
261
|
+
reason: string;
|
|
262
|
+
}
|
|
263
|
+
export interface MilestonePlanInput {
|
|
264
|
+
outcome: string;
|
|
265
|
+
successSignal: string;
|
|
266
|
+
acceptance: string[];
|
|
267
|
+
memberships: MilestoneMembership[];
|
|
268
|
+
checks: string[];
|
|
269
|
+
}
|
|
270
|
+
export interface ProjectRecord {
|
|
271
|
+
schemaVersion: typeof STATE_SCHEMA_VERSION;
|
|
272
|
+
projectId: string;
|
|
273
|
+
gitCommonDir: string;
|
|
274
|
+
repositoryRoots: string[];
|
|
275
|
+
createdAt: string;
|
|
276
|
+
updatedAt: string;
|
|
277
|
+
}
|
|
278
|
+
export interface WriterLease {
|
|
279
|
+
schemaVersion: typeof STATE_SCHEMA_VERSION;
|
|
280
|
+
entityId: string;
|
|
281
|
+
token: string;
|
|
282
|
+
owner: string;
|
|
283
|
+
pid: number;
|
|
284
|
+
hostname: string;
|
|
285
|
+
acquiredAt: string;
|
|
286
|
+
heartbeatAt: string;
|
|
287
|
+
expiresAt: string;
|
|
288
|
+
}
|
|
289
|
+
export interface ContextEnvelope {
|
|
290
|
+
protocolVersion: typeof PROTOCOL_VERSION;
|
|
291
|
+
packageVersion: string;
|
|
292
|
+
role: WorkflowRole;
|
|
293
|
+
objective: string;
|
|
294
|
+
inputs: string[];
|
|
295
|
+
allowedReads: string[];
|
|
296
|
+
allowedWrites: string[];
|
|
297
|
+
commands: string[];
|
|
298
|
+
forbiddenScope: string[];
|
|
299
|
+
resultSchema: Record<string, unknown>;
|
|
300
|
+
stopConditions: string[];
|
|
301
|
+
contextBudget: 'small' | 'medium' | 'large';
|
|
302
|
+
taskId: string;
|
|
303
|
+
stepId: string;
|
|
304
|
+
expectedRevision: number;
|
|
305
|
+
writerToken: string | null;
|
|
306
|
+
knowledgeMap: {
|
|
307
|
+
revision: number;
|
|
308
|
+
hash: string;
|
|
309
|
+
status: KnowledgeMapStatus;
|
|
310
|
+
};
|
|
311
|
+
knowledgeSources: string[];
|
|
312
|
+
}
|
|
313
|
+
export type EntityState = DiscoveryState | TaskState | MilestoneState | ProjectKnowledgeMap | GraphBinding;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../src/contracts.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAU,CAAC;AAC/C,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAU,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface DependencyDiagnostic {
|
|
2
|
+
packageFile: string;
|
|
3
|
+
declared: string | null;
|
|
4
|
+
exact: boolean;
|
|
5
|
+
current: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function inspectLocalDependency(repositoryRoot: string): DependencyDiagnostic;
|
|
8
|
+
export declare function integrationDiagnostics(repositoryRoot: string): {
|
|
9
|
+
package: {
|
|
10
|
+
name: string;
|
|
11
|
+
version: string;
|
|
12
|
+
};
|
|
13
|
+
localDependency: DependencyDiagnostic;
|
|
14
|
+
graphView: {
|
|
15
|
+
present: boolean;
|
|
16
|
+
current: boolean;
|
|
17
|
+
root: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { inspectGraphView } from './graph.js';
|
|
4
|
+
import { PACKAGE_NAME, PACKAGE_VERSION } from './version.js';
|
|
5
|
+
export function inspectLocalDependency(repositoryRoot) {
|
|
6
|
+
const packageFile = path.join(repositoryRoot, 'package.json');
|
|
7
|
+
if (!existsSync(packageFile))
|
|
8
|
+
return { packageFile, declared: null, exact: false, current: false };
|
|
9
|
+
const manifest = JSON.parse(readFileSync(packageFile, 'utf8'));
|
|
10
|
+
const declared = manifest.devDependencies?.[PACKAGE_NAME] ?? manifest.dependencies?.[PACKAGE_NAME] ?? null;
|
|
11
|
+
return {
|
|
12
|
+
packageFile,
|
|
13
|
+
declared,
|
|
14
|
+
exact: declared === PACKAGE_VERSION,
|
|
15
|
+
current: declared === PACKAGE_VERSION,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function integrationDiagnostics(repositoryRoot) {
|
|
19
|
+
return {
|
|
20
|
+
package: { name: PACKAGE_NAME, version: PACKAGE_VERSION },
|
|
21
|
+
localDependency: inspectLocalDependency(repositoryRoot),
|
|
22
|
+
graphView: inspectGraphView(),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAS7D,MAAM,UAAU,sBAAsB,CAAC,cAAsB;IAC3D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;IAC9D,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IACnG,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAG5D,CAAC;IACF,MAAM,QAAQ,GAAG,QAAQ,CAAC,eAAe,EAAE,CAAC,YAAY,CAAC,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC;IAC3G,OAAO;QACL,WAAW;QACX,QAAQ;QACR,KAAK,EAAE,QAAQ,KAAK,eAAe;QACnC,OAAO,EAAE,QAAQ,KAAK,eAAe;KACtC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,cAAsB;IAC3D,OAAO;QACL,OAAO,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE;QACzD,eAAe,EAAE,sBAAsB,CAAC,cAAc,CAAC;QACvD,SAAS,EAAE,gBAAgB,EAAE;KAC9B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DiscoveryState } from '../contracts.js';
|
|
2
|
+
export interface DiscoveryReadiness {
|
|
3
|
+
ready: boolean;
|
|
4
|
+
status: 'needs_discovery' | 'needs_clarification' | 'ready_to_materialize';
|
|
5
|
+
missing: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare function assessDiscovery(discovery: DiscoveryState): DiscoveryReadiness;
|
|
8
|
+
export declare function mergeUnique(current: string[], additions: string[]): string[];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function assessDiscovery(discovery) {
|
|
2
|
+
const missing = [];
|
|
3
|
+
if (!discovery.goal.trim())
|
|
4
|
+
missing.push('goal');
|
|
5
|
+
if (!discovery.outcome?.trim())
|
|
6
|
+
missing.push('observable outcome');
|
|
7
|
+
if (discovery.scope.length === 0)
|
|
8
|
+
missing.push('scope');
|
|
9
|
+
if (discovery.acceptance.length === 0)
|
|
10
|
+
missing.push('acceptance scenario');
|
|
11
|
+
if (discovery.blockingUnknowns.length > 0)
|
|
12
|
+
missing.push('resolved blocking unknowns');
|
|
13
|
+
if (missing.length === 0)
|
|
14
|
+
return { ready: true, status: 'ready_to_materialize', missing };
|
|
15
|
+
const hasInitialUnderstanding = Boolean(discovery.goal.trim() && (discovery.outcome || discovery.scope.length > 0));
|
|
16
|
+
return {
|
|
17
|
+
ready: false,
|
|
18
|
+
status: hasInitialUnderstanding ? 'needs_clarification' : 'needs_discovery',
|
|
19
|
+
missing,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function mergeUnique(current, additions) {
|
|
23
|
+
return [...new Set([...current, ...additions].map((value) => value.trim()).filter(Boolean))];
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../../src/domain/discovery.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,eAAe,CAAC,SAAyB;IACvD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE;QAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE;QAAE,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACnE,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxD,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAC3E,IAAI,SAAS,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IACtF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,sBAAsB,EAAE,OAAO,EAAE,CAAC;IAC1F,MAAM,uBAAuB,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IACpH,OAAO;QACL,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,uBAAuB,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,iBAAiB;QAC3E,OAAO;KACR,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAiB,EAAE,SAAmB;IAChE,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC/F,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { WorkflowError } from '../errors.js';
|
|
2
|
+
export function validatePlan(plan) {
|
|
3
|
+
const issues = [];
|
|
4
|
+
if (!plan.objective.trim())
|
|
5
|
+
issues.push('Plan objective is required.');
|
|
6
|
+
if (plan.requirements.length === 0)
|
|
7
|
+
issues.push('At least one requirement is required.');
|
|
8
|
+
if (plan.acceptance.length === 0)
|
|
9
|
+
issues.push('At least one acceptance scenario is required.');
|
|
10
|
+
if (plan.steps.length === 0)
|
|
11
|
+
issues.push('At least one STEP-* is required.');
|
|
12
|
+
if (!plan.knowledgeImpactReason.trim())
|
|
13
|
+
issues.push('knowledgeImpactReason is required.');
|
|
14
|
+
if (!Number.isInteger(plan.knowledgeMapRevision) || plan.knowledgeMapRevision < 1) {
|
|
15
|
+
issues.push('knowledgeMapRevision must be a positive integer.');
|
|
16
|
+
}
|
|
17
|
+
if (!/^[a-f0-9]{64}$/.test(plan.knowledgeMapHash))
|
|
18
|
+
issues.push('knowledgeMapHash must be a SHA-256 hash.');
|
|
19
|
+
if (plan.knowledgeImpact === 'none' && plan.knowledgeTargets.length > 0) {
|
|
20
|
+
issues.push('knowledgeImpact none cannot declare knowledgeTargets.');
|
|
21
|
+
}
|
|
22
|
+
if (plan.knowledgeImpact !== 'none' && plan.knowledgeTargets.length === 0) {
|
|
23
|
+
issues.push(`knowledgeImpact ${plan.knowledgeImpact} requires at least one knowledgeTarget.`);
|
|
24
|
+
}
|
|
25
|
+
for (const target of plan.knowledgeTargets) {
|
|
26
|
+
if (!target.reason.trim())
|
|
27
|
+
issues.push(`Knowledge target ${target.path} requires a reason.`);
|
|
28
|
+
if (target.requirementIds.length === 0)
|
|
29
|
+
issues.push(`Knowledge target ${target.path} requires requirementIds.`);
|
|
30
|
+
}
|
|
31
|
+
const ids = new Set();
|
|
32
|
+
for (const step of plan.steps) {
|
|
33
|
+
if (!/^STEP-[0-9]{3}(?:-[A-Z0-9-]+)?$/.test(step.id))
|
|
34
|
+
issues.push(`Invalid Step id: ${step.id}`);
|
|
35
|
+
if (ids.has(step.id))
|
|
36
|
+
issues.push(`Duplicate Step id: ${step.id}`);
|
|
37
|
+
ids.add(step.id);
|
|
38
|
+
if (!step.title.trim() || !step.objective.trim())
|
|
39
|
+
issues.push(`${step.id} requires title and objective.`);
|
|
40
|
+
if (step.requirements.length === 0)
|
|
41
|
+
issues.push(`${step.id} must cover at least one requirement.`);
|
|
42
|
+
if (step.allowedWrites.length === 0)
|
|
43
|
+
issues.push(`${step.id} must declare allowedWrites.`);
|
|
44
|
+
if (step.expectedOutputs.length === 0)
|
|
45
|
+
issues.push(`${step.id} must declare expectedOutputs.`);
|
|
46
|
+
if (step.checks.length === 0)
|
|
47
|
+
issues.push(`${step.id} must declare at least one executable check.`);
|
|
48
|
+
}
|
|
49
|
+
for (const step of plan.steps) {
|
|
50
|
+
for (const dependency of step.dependencies) {
|
|
51
|
+
if (!ids.has(dependency))
|
|
52
|
+
issues.push(`${step.id} depends on missing ${dependency}.`);
|
|
53
|
+
if (dependency === step.id)
|
|
54
|
+
issues.push(`${step.id} cannot depend on itself.`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const covered = new Set(plan.steps.flatMap((step) => step.requirements));
|
|
58
|
+
for (const requirement of plan.requirements) {
|
|
59
|
+
if (!covered.has(requirement))
|
|
60
|
+
issues.push(`Requirement is not covered by any Step: ${requirement}`);
|
|
61
|
+
}
|
|
62
|
+
const visiting = new Set();
|
|
63
|
+
const visited = new Set();
|
|
64
|
+
const byId = new Map(plan.steps.map((step) => [step.id, step]));
|
|
65
|
+
const visit = (stepId) => {
|
|
66
|
+
if (visited.has(stepId))
|
|
67
|
+
return;
|
|
68
|
+
if (visiting.has(stepId)) {
|
|
69
|
+
issues.push(`Step dependency cycle includes ${stepId}.`);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
visiting.add(stepId);
|
|
73
|
+
for (const dependency of byId.get(stepId)?.dependencies ?? [])
|
|
74
|
+
visit(dependency);
|
|
75
|
+
visiting.delete(stepId);
|
|
76
|
+
visited.add(stepId);
|
|
77
|
+
};
|
|
78
|
+
for (const step of plan.steps)
|
|
79
|
+
visit(step.id);
|
|
80
|
+
if (issues.length > 0)
|
|
81
|
+
throw new WorkflowError('TRANSITION_BLOCKED', 'Plan is not execution-ready.', { issues });
|
|
82
|
+
}
|
|
83
|
+
export function pathAllowed(file, patterns) {
|
|
84
|
+
const normalized = file.replaceAll('\\', '/').replace(/^\.\//, '');
|
|
85
|
+
return patterns.some((pattern) => {
|
|
86
|
+
const candidate = pattern.replaceAll('\\', '/').replace(/^\.\//, '');
|
|
87
|
+
if (candidate.endsWith('/**'))
|
|
88
|
+
return normalized === candidate.slice(0, -3) || normalized.startsWith(candidate.slice(0, -2));
|
|
89
|
+
if (candidate.endsWith('/*')) {
|
|
90
|
+
const prefix = candidate.slice(0, -1);
|
|
91
|
+
return normalized.startsWith(prefix) && !normalized.slice(prefix.length).includes('/');
|
|
92
|
+
}
|
|
93
|
+
return normalized === candidate;
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/domain/validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type WorkflowErrorCode = 'INVALID_ARGUMENT' | 'NOT_FOUND' | 'STATE_CONFLICT' | 'STATE_CORRUPT' | 'LOCKED' | 'LOCK_TOKEN_INVALID' | 'TRANSITION_BLOCKED' | 'GIT_PRECONDITION_FAILED' | 'COMMAND_FAILED';
|
|
2
|
+
export declare class WorkflowError extends Error {
|
|
3
|
+
readonly code: WorkflowErrorCode;
|
|
4
|
+
readonly details: Record<string, unknown>;
|
|
5
|
+
constructor(code: WorkflowErrorCode, message: string, details?: Record<string, unknown>);
|
|
6
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAWA,MAAM,OAAO,aAAc,SAAQ,KAAK;IAC7B,IAAI,CAAoB;IACxB,OAAO,CAA0B;IAE1C,YAAY,IAAuB,EAAE,OAAe,EAAE,UAAmC,EAAE;QACzF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function ensureDirectory(directory: string): void;
|
|
2
|
+
export declare function readJson<T>(file: string): T;
|
|
3
|
+
export declare function writeJsonAtomic(file: string, value: unknown): void;
|
|
4
|
+
export declare function writeTextAtomic(file: string, content: string): void;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { chmodSync, existsSync, lstatSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync, } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
import { WorkflowError } from './errors.js';
|
|
5
|
+
export function ensureDirectory(directory) {
|
|
6
|
+
mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
7
|
+
if (lstatSync(directory).isSymbolicLink()) {
|
|
8
|
+
throw new WorkflowError('STATE_CORRUPT', `State directory must not be a symlink: ${directory}`);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function readJson(file) {
|
|
12
|
+
try {
|
|
13
|
+
return JSON.parse(readFileSync(file, 'utf8'));
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
throw new WorkflowError('STATE_CORRUPT', `Cannot read JSON state: ${file}`, {
|
|
17
|
+
cause: error instanceof Error ? error.message : String(error),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function writeJsonAtomic(file, value) {
|
|
22
|
+
const directory = path.dirname(file);
|
|
23
|
+
ensureDirectory(directory);
|
|
24
|
+
if (existsSync(file) && lstatSync(file).isSymbolicLink()) {
|
|
25
|
+
throw new WorkflowError('STATE_CORRUPT', `Refusing to replace state symlink: ${file}`);
|
|
26
|
+
}
|
|
27
|
+
const temporary = path.join(directory, `.${path.basename(file)}.${randomUUID()}.tmp`);
|
|
28
|
+
try {
|
|
29
|
+
writeFileSync(temporary, `${JSON.stringify(value, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 });
|
|
30
|
+
chmodSync(temporary, 0o600);
|
|
31
|
+
renameSync(temporary, file);
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
rmSync(temporary, { force: true });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function writeTextAtomic(file, content) {
|
|
38
|
+
const directory = path.dirname(file);
|
|
39
|
+
ensureDirectory(directory);
|
|
40
|
+
const temporary = path.join(directory, `.${path.basename(file)}.${randomUUID()}.tmp`);
|
|
41
|
+
try {
|
|
42
|
+
writeFileSync(temporary, content.endsWith('\n') ? content : `${content}\n`, {
|
|
43
|
+
encoding: 'utf8',
|
|
44
|
+
mode: 0o600,
|
|
45
|
+
});
|
|
46
|
+
renameSync(temporary, file);
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
rmSync(temporary, { force: true });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=fs-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-utils.js","sourceRoot":"","sources":["../../src/fs-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { TaskState } from './contracts.js';
|
|
2
|
+
export declare function startLocalTaskBranch(repositoryRoot: string, branch: string, baseBranch: string): string;
|
|
3
|
+
export interface CheckResult {
|
|
4
|
+
command: string;
|
|
5
|
+
passed: boolean;
|
|
6
|
+
exitCode: number;
|
|
7
|
+
output: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function runChecks(repositoryRoot: string, commands: string[]): CheckResult[];
|
|
10
|
+
export declare function commitStep(repositoryRoot: string, taskId: string, stepId: string, title: string, allowedWrites: string[]): {
|
|
11
|
+
commitSha: string;
|
|
12
|
+
files: string[];
|
|
13
|
+
};
|
|
14
|
+
export declare function mergeTaskBranch(repositoryRoot: string, taskBranch: string, baseBranch: string): string;
|
|
15
|
+
export declare function syncBaseIntoTask(repositoryRoot: string, taskBranch: string, baseBranch: string): {
|
|
16
|
+
baseCommit: string;
|
|
17
|
+
syncCommit: string;
|
|
18
|
+
};
|
|
19
|
+
export declare function validateTaskHistory(repositoryRoot: string, task: TaskState): void;
|