oxe-cc 1.0.0 → 1.2.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/.cursor/commands/oxe-ask.md +1 -1
- package/.cursor/commands/oxe-capabilities.md +1 -1
- package/.cursor/commands/oxe-checkpoint.md +1 -1
- package/.cursor/commands/oxe-compact.md +1 -1
- package/.cursor/commands/oxe-dashboard.md +1 -1
- package/.cursor/commands/oxe-debug.md +1 -1
- package/.cursor/commands/oxe-discuss.md +1 -1
- package/.cursor/commands/oxe-execute.md +2 -2
- package/.cursor/commands/oxe-forensics.md +1 -1
- package/.cursor/commands/oxe-help.md +1 -1
- package/.cursor/commands/oxe-loop.md +1 -1
- package/.cursor/commands/oxe-milestone.md +1 -1
- package/.cursor/commands/oxe-next.md +1 -1
- package/.cursor/commands/oxe-obs.md +1 -1
- package/.cursor/commands/oxe-plan-agent.md +1 -1
- package/.cursor/commands/oxe-plan.md +1 -1
- package/.cursor/commands/oxe-project.md +1 -1
- package/.cursor/commands/oxe-quick.md +1 -1
- package/.cursor/commands/oxe-research.md +1 -1
- package/.cursor/commands/oxe-retro.md +1 -1
- package/.cursor/commands/oxe-review-pr.md +1 -1
- package/.cursor/commands/oxe-route.md +1 -1
- package/.cursor/commands/oxe-scan.md +1 -1
- package/.cursor/commands/oxe-security.md +1 -1
- package/.cursor/commands/oxe-session.md +2 -2
- package/.cursor/commands/oxe-ship.md +45 -0
- package/.cursor/commands/oxe-skill.md +1 -1
- package/.cursor/commands/oxe-spec.md +1 -1
- package/.cursor/commands/oxe-ui-review.md +1 -1
- package/.cursor/commands/oxe-ui-spec.md +1 -1
- package/.cursor/commands/oxe-update.md +1 -1
- package/.cursor/commands/oxe-validate-gaps.md +1 -1
- package/.cursor/commands/oxe-verify.md +1 -1
- package/.cursor/commands/oxe-workstream.md +1 -1
- package/.cursor/commands/oxe.md +4 -4
- package/.github/copilot-instructions.md +91 -1
- package/.github/prompts/oxe-ask.prompt.md +1 -1
- package/.github/prompts/oxe-capabilities.prompt.md +1 -1
- package/.github/prompts/oxe-checkpoint.prompt.md +1 -1
- package/.github/prompts/oxe-compact.prompt.md +1 -1
- package/.github/prompts/oxe-dashboard.prompt.md +1 -1
- package/.github/prompts/oxe-debug.prompt.md +1 -1
- package/.github/prompts/oxe-discuss.prompt.md +1 -1
- package/.github/prompts/oxe-execute.prompt.md +2 -2
- package/.github/prompts/oxe-forensics.prompt.md +1 -1
- package/.github/prompts/oxe-help.prompt.md +1 -1
- package/.github/prompts/oxe-loop.prompt.md +1 -1
- package/.github/prompts/oxe-milestone.prompt.md +1 -1
- package/.github/prompts/oxe-next.prompt.md +1 -1
- package/.github/prompts/oxe-obs.prompt.md +1 -1
- package/.github/prompts/oxe-plan-agent.prompt.md +1 -1
- package/.github/prompts/oxe-plan.prompt.md +1 -1
- package/.github/prompts/oxe-project.prompt.md +1 -1
- package/.github/prompts/oxe-quick.prompt.md +1 -1
- package/.github/prompts/oxe-research.prompt.md +1 -1
- package/.github/prompts/oxe-retro.prompt.md +1 -1
- package/.github/prompts/oxe-review-pr.prompt.md +1 -1
- package/.github/prompts/oxe-route.prompt.md +1 -1
- package/.github/prompts/oxe-scan.prompt.md +1 -1
- package/.github/prompts/oxe-security.prompt.md +1 -1
- package/.github/prompts/oxe-session.prompt.md +2 -2
- package/.github/prompts/oxe-ship.prompt.md +45 -0
- package/.github/prompts/oxe-skill.prompt.md +1 -1
- package/.github/prompts/oxe-spec.prompt.md +1 -1
- package/.github/prompts/oxe-ui-review.prompt.md +1 -1
- package/.github/prompts/oxe-ui-spec.prompt.md +1 -1
- package/.github/prompts/oxe-update.prompt.md +1 -1
- package/.github/prompts/oxe-validate-gaps.prompt.md +1 -1
- package/.github/prompts/oxe-verify.prompt.md +1 -1
- package/.github/prompts/oxe-workstream.prompt.md +1 -1
- package/.github/prompts/oxe.prompt.md +3 -3
- package/AGENTS.md +43 -28
- package/CHANGELOG.md +158 -0
- package/README.md +72 -50
- package/bin/banner.txt +1 -1
- package/bin/lib/oxe-project-health.cjs +1 -1
- package/commands/oxe/ask.md +5 -1
- package/commands/oxe/checkpoint.md +1 -1
- package/commands/oxe/compact.md +1 -1
- package/commands/oxe/debug.md +1 -1
- package/commands/oxe/execute.md +2 -2
- package/commands/oxe/forensics.md +1 -1
- package/commands/oxe/loop.md +1 -1
- package/commands/oxe/milestone.md +1 -1
- package/commands/oxe/next.md +1 -1
- package/commands/oxe/obs.md +1 -1
- package/commands/oxe/oxe.md +3 -3
- package/commands/oxe/project.md +1 -1
- package/commands/oxe/research.md +1 -1
- package/commands/oxe/retro.md +1 -1
- package/commands/oxe/review-pr.md +1 -1
- package/commands/oxe/route.md +1 -1
- package/commands/oxe/scan.md +1 -1
- package/commands/oxe/security.md +1 -1
- package/commands/oxe/session.md +2 -2
- package/commands/oxe/ship.md +49 -0
- package/commands/oxe/spec.md +2 -2
- package/commands/oxe/ui-review.md +1 -1
- package/commands/oxe/ui-spec.md +1 -1
- package/commands/oxe/validate-gaps.md +1 -1
- package/commands/oxe/verify.md +2 -2
- package/commands/oxe/workstream.md +1 -1
- package/lib/runtime/audit/audit-trail.d.ts +71 -0
- package/lib/runtime/audit/audit-trail.js +154 -0
- package/lib/runtime/audit/index.d.ts +2 -0
- package/lib/runtime/audit/index.js +18 -0
- package/lib/runtime/audit/policy-pack.d.ts +15 -0
- package/lib/runtime/audit/policy-pack.js +57 -0
- package/lib/runtime/context/context-pack-builder.d.ts +15 -0
- package/lib/runtime/context/context-pack-builder.js +42 -0
- package/lib/runtime/context/context-pack-store.d.ts +38 -0
- package/lib/runtime/context/context-pack-store.js +142 -0
- package/lib/runtime/context/context-profiles.d.ts +11 -0
- package/lib/runtime/context/context-profiles.js +51 -0
- package/lib/runtime/context/index.d.ts +2 -0
- package/lib/runtime/context/index.js +2 -0
- package/lib/runtime/decision/decision-engine.d.ts +43 -0
- package/lib/runtime/decision/decision-engine.js +127 -0
- package/lib/runtime/decision/decision-memo.d.ts +53 -0
- package/lib/runtime/decision/decision-memo.js +173 -0
- package/lib/runtime/decision/index.d.ts +2 -0
- package/lib/runtime/decision/index.js +18 -0
- package/lib/runtime/delivery/index.d.ts +1 -0
- package/lib/runtime/delivery/index.js +1 -0
- package/lib/runtime/delivery/promotion-pipeline.d.ts +39 -0
- package/lib/runtime/delivery/promotion-pipeline.js +127 -0
- package/lib/runtime/index.d.ts +3 -0
- package/lib/runtime/index.js +4 -0
- package/lib/runtime/plugins/capability-matrix.d.ts +20 -0
- package/lib/runtime/plugins/capability-matrix.js +59 -0
- package/lib/runtime/plugins/index.d.ts +2 -0
- package/lib/runtime/plugins/index.js +2 -0
- package/lib/runtime/plugins/plugin-manifest.d.ts +22 -0
- package/lib/runtime/plugins/plugin-manifest.js +91 -0
- package/lib/runtime/plugins/plugin-registry.js +5 -0
- package/lib/runtime/policy/policy-engine.d.ts +28 -1
- package/lib/runtime/policy/policy-engine.js +96 -5
- package/lib/runtime/reducers/run-state-reducer.d.ts +26 -0
- package/lib/runtime/reducers/run-state-reducer.js +117 -1
- package/lib/runtime/scheduler/agent-registry.d.ts +44 -0
- package/lib/runtime/scheduler/agent-registry.js +96 -0
- package/lib/runtime/scheduler/agent-roles.d.ts +54 -0
- package/lib/runtime/scheduler/agent-roles.js +62 -0
- package/lib/runtime/scheduler/index.d.ts +3 -0
- package/lib/runtime/scheduler/index.js +3 -0
- package/lib/runtime/scheduler/multi-agent-coordinator.d.ts +2 -0
- package/lib/runtime/scheduler/multi-agent-coordinator.js +91 -4
- package/lib/runtime/scheduler/run-journal.d.ts +18 -0
- package/lib/runtime/scheduler/run-journal.js +54 -0
- package/lib/runtime/scheduler/scheduler.d.ts +11 -1
- package/lib/runtime/scheduler/scheduler.js +135 -7
- package/lib/runtime/verification/index.d.ts +1 -0
- package/lib/runtime/verification/index.js +1 -0
- package/lib/runtime/verification/verification-manifest.d.ts +58 -0
- package/lib/runtime/verification/verification-manifest.js +129 -0
- package/oxe/workflows/ask.md +4 -0
- package/oxe/workflows/checkpoint.md +14 -10
- package/oxe/workflows/debug.md +19 -15
- package/oxe/workflows/execute.md +30 -2
- package/oxe/workflows/forensics.md +13 -9
- package/oxe/workflows/help.md +97 -49
- package/oxe/workflows/loop.md +17 -13
- package/oxe/workflows/obs.md +4 -0
- package/oxe/workflows/oxe.md +64 -31
- package/oxe/workflows/project.md +6 -1
- package/oxe/workflows/references/workflow-runtime-contracts.json +23 -0
- package/oxe/workflows/research.md +32 -28
- package/oxe/workflows/retro.md +4 -0
- package/oxe/workflows/review-pr.md +15 -11
- package/oxe/workflows/scan.md +4 -0
- package/oxe/workflows/security.md +14 -10
- package/oxe/workflows/session.md +17 -1
- package/oxe/workflows/ship.md +142 -0
- package/oxe/workflows/spec.md +15 -0
- package/oxe/workflows/ui-review.md +20 -16
- package/oxe/workflows/ui-spec.md +7 -3
- package/oxe/workflows/validate-gaps.md +13 -9
- package/oxe/workflows/verify.md +42 -3
- package/package.json +1 -1
- package/packages/runtime/src/audit/audit-trail.ts +243 -0
- package/packages/runtime/src/audit/index.ts +2 -0
- package/packages/runtime/src/audit/policy-pack.ts +62 -0
- package/packages/runtime/src/context/context-pack-builder.ts +66 -0
- package/packages/runtime/src/context/context-pack-store.ts +197 -0
- package/packages/runtime/src/context/context-profiles.ts +60 -0
- package/packages/runtime/src/context/index.ts +2 -0
- package/packages/runtime/src/decision/decision-engine.ts +174 -0
- package/packages/runtime/src/decision/decision-memo.ts +211 -0
- package/packages/runtime/src/decision/index.ts +2 -0
- package/packages/runtime/src/delivery/index.ts +1 -0
- package/packages/runtime/src/delivery/promotion-pipeline.ts +180 -0
- package/packages/runtime/src/index.ts +5 -0
- package/packages/runtime/src/plugins/capability-matrix.ts +83 -0
- package/packages/runtime/src/plugins/index.ts +2 -0
- package/packages/runtime/src/plugins/plugin-manifest.ts +113 -0
- package/packages/runtime/src/plugins/plugin-registry.ts +5 -0
- package/packages/runtime/src/policy/policy-engine.ts +138 -7
- package/packages/runtime/src/reducers/run-state-reducer.ts +143 -1
- package/packages/runtime/src/scheduler/agent-registry.ts +132 -0
- package/packages/runtime/src/scheduler/agent-roles.ts +109 -0
- package/packages/runtime/src/scheduler/index.ts +3 -0
- package/packages/runtime/src/scheduler/multi-agent-coordinator.ts +106 -4
- package/packages/runtime/src/scheduler/run-journal.ts +62 -0
- package/packages/runtime/src/scheduler/scheduler.ts +168 -8
- package/packages/runtime/src/verification/index.ts +1 -0
- package/packages/runtime/src/verification/verification-manifest.ts +192 -0
- package/vscode-extension/oxe-agents-1.0.0.vsix +0 -0
|
@@ -2,25 +2,47 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Scheduler = void 0;
|
|
4
4
|
const bus_1 = require("../events/bus");
|
|
5
|
+
const run_journal_1 = require("./run-journal");
|
|
5
6
|
class Scheduler {
|
|
6
7
|
constructor() {
|
|
7
8
|
this.cancelled = false;
|
|
8
9
|
this.paused = false;
|
|
10
|
+
this.journal = null;
|
|
11
|
+
this.ctx = null;
|
|
9
12
|
}
|
|
10
13
|
async run(graph, ctx) {
|
|
11
14
|
this.cancelled = false;
|
|
12
15
|
this.paused = false;
|
|
16
|
+
this.ctx = ctx;
|
|
13
17
|
const status = new Map();
|
|
14
18
|
for (const id of graph.nodes.keys())
|
|
15
19
|
status.set(id, 'pending');
|
|
16
20
|
const completed = [];
|
|
17
21
|
const failed = [];
|
|
18
22
|
const blocked = [];
|
|
23
|
+
this.journal = (0, run_journal_1.createJournal)(ctx.runId);
|
|
24
|
+
(0, run_journal_1.saveJournal)(ctx.projectRoot, ctx.runId, this.journal);
|
|
19
25
|
this.emit(ctx, { type: 'RunStarted', payload: { run_id: ctx.runId } });
|
|
20
26
|
for (const wave of graph.waves) {
|
|
21
27
|
if (this.cancelled)
|
|
22
28
|
break;
|
|
29
|
+
// Respect pause: persist journal and return paused result
|
|
30
|
+
if (this.paused) {
|
|
31
|
+
this.journal.scheduler_state = 'paused';
|
|
32
|
+
this.journal.paused_at = new Date().toISOString();
|
|
33
|
+
this.journal.completed_work_items = completed.slice();
|
|
34
|
+
this.journal.failed_work_items = failed.slice();
|
|
35
|
+
this.journal.blocked_work_items = blocked.slice();
|
|
36
|
+
this.journal.partial_result = { run_id: ctx.runId, completed, failed, blocked };
|
|
37
|
+
(0, run_journal_1.saveJournal)(ctx.projectRoot, ctx.runId, this.journal);
|
|
38
|
+
return { run_id: ctx.runId, status: 'paused', completed, failed, blocked };
|
|
39
|
+
}
|
|
23
40
|
const waveFailed = await this.runWave(wave.node_ids, graph, ctx, status, completed, failed, blocked);
|
|
41
|
+
// Sync journal after each wave
|
|
42
|
+
this.journal.completed_work_items = completed.slice();
|
|
43
|
+
this.journal.failed_work_items = failed.slice();
|
|
44
|
+
this.journal.blocked_work_items = blocked.slice();
|
|
45
|
+
(0, run_journal_1.saveJournal)(ctx.projectRoot, ctx.runId, this.journal);
|
|
24
46
|
if (waveFailed)
|
|
25
47
|
break;
|
|
26
48
|
}
|
|
@@ -45,13 +67,104 @@ class Scheduler {
|
|
|
45
67
|
type: 'RunCompleted',
|
|
46
68
|
payload: { run_id: ctx.runId, status: finalStatus },
|
|
47
69
|
});
|
|
70
|
+
this.journal.scheduler_state = this.cancelled ? 'cancelled' : 'completed';
|
|
71
|
+
this.journal.completed_work_items = completed.slice();
|
|
72
|
+
this.journal.failed_work_items = failed.slice();
|
|
73
|
+
this.journal.blocked_work_items = blocked.slice();
|
|
74
|
+
(0, run_journal_1.saveJournal)(ctx.projectRoot, ctx.runId, this.journal);
|
|
75
|
+
return { run_id: ctx.runId, status: finalStatus, completed, failed, blocked };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Recover a previously paused run by loading its journal and re-running
|
|
79
|
+
* only the work items that haven't completed yet.
|
|
80
|
+
*/
|
|
81
|
+
async recover(runId, ctx, graph) {
|
|
82
|
+
const journal = (0, run_journal_1.loadJournal)(ctx.projectRoot, runId);
|
|
83
|
+
if (!journal || journal.scheduler_state !== 'paused')
|
|
84
|
+
return null;
|
|
85
|
+
// Restore state from journal
|
|
86
|
+
this.cancelled = false;
|
|
87
|
+
this.paused = false;
|
|
88
|
+
this.ctx = ctx;
|
|
89
|
+
this.journal = { ...journal, scheduler_state: 'running', paused_at: null };
|
|
90
|
+
const restoredCompleted = new Set(journal.completed_work_items);
|
|
91
|
+
const restoredFailed = new Set(journal.failed_work_items);
|
|
92
|
+
const restoredBlocked = new Set(journal.blocked_work_items);
|
|
93
|
+
const status = new Map();
|
|
94
|
+
for (const id of graph.nodes.keys()) {
|
|
95
|
+
if (restoredCompleted.has(id))
|
|
96
|
+
status.set(id, 'completed');
|
|
97
|
+
else if (restoredFailed.has(id))
|
|
98
|
+
status.set(id, 'failed');
|
|
99
|
+
else if (restoredBlocked.has(id))
|
|
100
|
+
status.set(id, 'blocked');
|
|
101
|
+
else
|
|
102
|
+
status.set(id, 'pending');
|
|
103
|
+
}
|
|
104
|
+
const completed = [...restoredCompleted];
|
|
105
|
+
const failed = [...restoredFailed];
|
|
106
|
+
const blocked = [...restoredBlocked];
|
|
107
|
+
(0, run_journal_1.saveJournal)(ctx.projectRoot, runId, this.journal);
|
|
108
|
+
this.emit(ctx, { type: 'RunStarted', payload: { run_id: ctx.runId, recovered: true } });
|
|
109
|
+
for (const wave of graph.waves) {
|
|
110
|
+
if (this.cancelled)
|
|
111
|
+
break;
|
|
112
|
+
if (this.paused) {
|
|
113
|
+
this.journal.scheduler_state = 'paused';
|
|
114
|
+
this.journal.paused_at = new Date().toISOString();
|
|
115
|
+
this.journal.completed_work_items = completed.slice();
|
|
116
|
+
this.journal.failed_work_items = failed.slice();
|
|
117
|
+
this.journal.blocked_work_items = blocked.slice();
|
|
118
|
+
this.journal.partial_result = { run_id: ctx.runId, completed, failed, blocked };
|
|
119
|
+
(0, run_journal_1.saveJournal)(ctx.projectRoot, ctx.runId, this.journal);
|
|
120
|
+
return { run_id: ctx.runId, status: 'paused', completed, failed, blocked };
|
|
121
|
+
}
|
|
122
|
+
// Skip waves fully completed
|
|
123
|
+
const allDone = wave.node_ids.every((id) => restoredCompleted.has(id) || restoredFailed.has(id) || restoredBlocked.has(id));
|
|
124
|
+
if (allDone)
|
|
125
|
+
continue;
|
|
126
|
+
const waveFailed = await this.runWave(wave.node_ids, graph, ctx, status, completed, failed, blocked);
|
|
127
|
+
this.journal.completed_work_items = completed.slice();
|
|
128
|
+
this.journal.failed_work_items = failed.slice();
|
|
129
|
+
this.journal.blocked_work_items = blocked.slice();
|
|
130
|
+
(0, run_journal_1.saveJournal)(ctx.projectRoot, ctx.runId, this.journal);
|
|
131
|
+
if (waveFailed)
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
for (const [id, s] of status) {
|
|
135
|
+
if (s === 'pending') {
|
|
136
|
+
status.set(id, 'blocked');
|
|
137
|
+
blocked.push(id);
|
|
138
|
+
this.emit(ctx, {
|
|
139
|
+
type: 'WorkItemBlocked',
|
|
140
|
+
work_item_id: id,
|
|
141
|
+
payload: { reason: 'upstream_wave_failed' },
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const finalStatus = this.cancelled
|
|
146
|
+
? 'cancelled'
|
|
147
|
+
: failed.length > 0
|
|
148
|
+
? 'failed'
|
|
149
|
+
: 'completed';
|
|
150
|
+
this.emit(ctx, {
|
|
151
|
+
type: 'RunCompleted',
|
|
152
|
+
payload: { run_id: ctx.runId, status: finalStatus, recovered: true },
|
|
153
|
+
});
|
|
154
|
+
this.journal.scheduler_state = this.cancelled ? 'cancelled' : 'completed';
|
|
155
|
+
this.journal.completed_work_items = completed.slice();
|
|
156
|
+
this.journal.failed_work_items = failed.slice();
|
|
157
|
+
this.journal.blocked_work_items = blocked.slice();
|
|
158
|
+
(0, run_journal_1.saveJournal)(ctx.projectRoot, ctx.runId, this.journal);
|
|
159
|
+
(0, run_journal_1.deleteJournal)(ctx.projectRoot, ctx.runId);
|
|
48
160
|
return { run_id: ctx.runId, status: finalStatus, completed, failed, blocked };
|
|
49
161
|
}
|
|
50
162
|
async runWave(nodeIds, graph, ctx, status, completed, failed, blocked) {
|
|
51
|
-
// Partition: eligible vs blocked-by-dep
|
|
52
163
|
const eligible = [];
|
|
53
164
|
const depsNotMet = [];
|
|
54
165
|
for (const id of nodeIds) {
|
|
166
|
+
if (status.get(id) === 'completed')
|
|
167
|
+
continue; // already done in recovery
|
|
55
168
|
const node = graph.nodes.get(id);
|
|
56
169
|
const depsMet = node.depends_on.every((dep) => status.get(dep) === 'completed');
|
|
57
170
|
if (depsMet) {
|
|
@@ -61,7 +174,6 @@ class Scheduler {
|
|
|
61
174
|
depsNotMet.push(id);
|
|
62
175
|
}
|
|
63
176
|
}
|
|
64
|
-
// Nodes whose deps weren't met in this wave → blocked
|
|
65
177
|
for (const id of depsNotMet) {
|
|
66
178
|
status.set(id, 'blocked');
|
|
67
179
|
blocked.push(id);
|
|
@@ -71,17 +183,14 @@ class Scheduler {
|
|
|
71
183
|
payload: { reason: 'dependency_not_met' },
|
|
72
184
|
});
|
|
73
185
|
}
|
|
74
|
-
// Separate read-only (no mutation_scope) from mutation nodes
|
|
75
186
|
const readOnly = eligible.filter((id) => {
|
|
76
187
|
const node = graph.nodes.get(id);
|
|
77
188
|
return node.mutation_scope.length === 0;
|
|
78
189
|
});
|
|
79
190
|
const mutations = eligible.filter((id) => !readOnly.includes(id));
|
|
80
|
-
// Run read-only nodes in parallel
|
|
81
191
|
if (readOnly.length > 0) {
|
|
82
192
|
await Promise.all(readOnly.map((id) => this.runNode(id, graph, ctx, status, completed, failed)));
|
|
83
193
|
}
|
|
84
|
-
// Run mutation nodes sequentially to avoid scope conflicts
|
|
85
194
|
for (const id of mutations) {
|
|
86
195
|
if (this.cancelled)
|
|
87
196
|
break;
|
|
@@ -134,7 +243,6 @@ class Scheduler {
|
|
|
134
243
|
completed.push(nodeId);
|
|
135
244
|
return;
|
|
136
245
|
}
|
|
137
|
-
// Policy failures never retry
|
|
138
246
|
if (lastResult.failure_class === 'policy')
|
|
139
247
|
break;
|
|
140
248
|
if (attempt < maxAttempts) {
|
|
@@ -167,7 +275,6 @@ class Scheduler {
|
|
|
167
275
|
}
|
|
168
276
|
}
|
|
169
277
|
}
|
|
170
|
-
// All attempts exhausted
|
|
171
278
|
this.emit(ctx, {
|
|
172
279
|
type: 'WorkItemBlocked',
|
|
173
280
|
work_item_id: nodeId,
|
|
@@ -178,12 +285,33 @@ class Scheduler {
|
|
|
178
285
|
}
|
|
179
286
|
pause() {
|
|
180
287
|
this.paused = true;
|
|
288
|
+
if (this.journal && this.ctx) {
|
|
289
|
+
this.journal.scheduler_state = 'paused';
|
|
290
|
+
this.journal.paused_at = new Date().toISOString();
|
|
291
|
+
(0, run_journal_1.saveJournal)(this.ctx.projectRoot, this.ctx.runId, this.journal);
|
|
292
|
+
}
|
|
181
293
|
}
|
|
182
294
|
resume() {
|
|
183
295
|
this.paused = false;
|
|
296
|
+
if (this.journal && this.ctx) {
|
|
297
|
+
this.journal.scheduler_state = 'running';
|
|
298
|
+
this.journal.paused_at = null;
|
|
299
|
+
(0, run_journal_1.saveJournal)(this.ctx.projectRoot, this.ctx.runId, this.journal);
|
|
300
|
+
}
|
|
184
301
|
}
|
|
185
302
|
cancel() {
|
|
186
303
|
this.cancelled = true;
|
|
304
|
+
if (this.journal && this.ctx) {
|
|
305
|
+
this.journal.cancelled = true;
|
|
306
|
+
this.journal.scheduler_state = 'cancelled';
|
|
307
|
+
(0, run_journal_1.saveJournal)(this.ctx.projectRoot, this.ctx.runId, this.journal);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
getJournal() {
|
|
311
|
+
return this.journal;
|
|
312
|
+
}
|
|
313
|
+
static loadJournal(projectRoot, runId) {
|
|
314
|
+
return (0, run_journal_1.loadJournal)(projectRoot, runId);
|
|
187
315
|
}
|
|
188
316
|
emit(ctx, input) {
|
|
189
317
|
const event = (0, bus_1.appendEvent)(ctx.projectRoot, ctx.sessionId, {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { VerificationStatus } from '../models/verification-result';
|
|
2
|
+
import type { CheckResult } from './verification-compiler';
|
|
3
|
+
export type VerificationProfile = 'quick' | 'standard' | 'critical';
|
|
4
|
+
export type FailureClass = 'deterministic' | 'flaky' | 'timeout' | 'env_setup' | 'policy_failure' | 'evidence_missing';
|
|
5
|
+
export type VerificationGranularity = 'work_item' | 'wave' | 'run';
|
|
6
|
+
export interface ManifestCheck {
|
|
7
|
+
check_id: string;
|
|
8
|
+
acceptance_ref: string | null;
|
|
9
|
+
status: VerificationStatus;
|
|
10
|
+
failure_class: FailureClass | null;
|
|
11
|
+
evidence_refs: string[];
|
|
12
|
+
duration_ms: number;
|
|
13
|
+
}
|
|
14
|
+
export interface VerificationManifest {
|
|
15
|
+
manifest_id: string;
|
|
16
|
+
run_id: string;
|
|
17
|
+
work_item_id: string | null;
|
|
18
|
+
wave: number | null;
|
|
19
|
+
granularity: VerificationGranularity;
|
|
20
|
+
profile: VerificationProfile;
|
|
21
|
+
compiled_at: string;
|
|
22
|
+
checks: ManifestCheck[];
|
|
23
|
+
summary: {
|
|
24
|
+
total: number;
|
|
25
|
+
pass: number;
|
|
26
|
+
fail: number;
|
|
27
|
+
skip: number;
|
|
28
|
+
error: number;
|
|
29
|
+
all_passed: boolean;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export interface ResidualRisk {
|
|
33
|
+
risk_id: string;
|
|
34
|
+
work_item_id: string | null;
|
|
35
|
+
check_id: string | null;
|
|
36
|
+
failure_class: FailureClass;
|
|
37
|
+
description: string;
|
|
38
|
+
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
39
|
+
mitigation: string | null;
|
|
40
|
+
}
|
|
41
|
+
export interface ResidualRiskLedger {
|
|
42
|
+
run_id: string;
|
|
43
|
+
generated_at: string;
|
|
44
|
+
risks: ResidualRisk[];
|
|
45
|
+
}
|
|
46
|
+
export declare function classifyFailure(result: CheckResult): FailureClass | null;
|
|
47
|
+
export declare function buildManifest(runId: string, results: CheckResult[], options?: {
|
|
48
|
+
workItemId?: string;
|
|
49
|
+
wave?: number;
|
|
50
|
+
granularity?: VerificationGranularity;
|
|
51
|
+
profile?: VerificationProfile;
|
|
52
|
+
evidenceRefs?: Map<string, string[]>;
|
|
53
|
+
}): VerificationManifest;
|
|
54
|
+
export declare function buildRiskLedger(runId: string, manifest: VerificationManifest): ResidualRiskLedger;
|
|
55
|
+
export declare function saveManifest(projectRoot: string, runId: string, manifest: VerificationManifest): void;
|
|
56
|
+
export declare function loadManifest(projectRoot: string, runId: string): VerificationManifest | null;
|
|
57
|
+
export declare function saveRiskLedger(projectRoot: string, runId: string, ledger: ResidualRiskLedger): void;
|
|
58
|
+
export declare function loadRiskLedger(projectRoot: string, runId: string): ResidualRiskLedger | null;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.classifyFailure = classifyFailure;
|
|
7
|
+
exports.buildManifest = buildManifest;
|
|
8
|
+
exports.buildRiskLedger = buildRiskLedger;
|
|
9
|
+
exports.saveManifest = saveManifest;
|
|
10
|
+
exports.loadManifest = loadManifest;
|
|
11
|
+
exports.saveRiskLedger = saveRiskLedger;
|
|
12
|
+
exports.loadRiskLedger = loadRiskLedger;
|
|
13
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
14
|
+
const path_1 = __importDefault(require("path"));
|
|
15
|
+
const fs_1 = __importDefault(require("fs"));
|
|
16
|
+
const PROFILE_REQUIRED_CHECKS = {
|
|
17
|
+
quick: ['deterministic'],
|
|
18
|
+
standard: ['deterministic', 'policy_failure'],
|
|
19
|
+
critical: ['deterministic', 'policy_failure', 'evidence_missing', 'flaky'],
|
|
20
|
+
};
|
|
21
|
+
function classifyFailure(result) {
|
|
22
|
+
if (result.status === 'pass' || result.status === 'skip')
|
|
23
|
+
return null;
|
|
24
|
+
if (result.error && (result.error.toLowerCase().includes('timeout') || result.error.toLowerCase().includes('timed out')))
|
|
25
|
+
return 'timeout';
|
|
26
|
+
if (result.exit_code === null && result.error)
|
|
27
|
+
return 'env_setup';
|
|
28
|
+
if (result.stderr.toLowerCase().includes('policy') || result.stderr.toLowerCase().includes('denied')) {
|
|
29
|
+
return 'policy_failure';
|
|
30
|
+
}
|
|
31
|
+
if (result.exit_code !== 0 && result.stderr === '' && result.stdout === '')
|
|
32
|
+
return 'evidence_missing';
|
|
33
|
+
// Default: non-deterministic signals (no reliable exit code pattern)
|
|
34
|
+
return 'deterministic';
|
|
35
|
+
}
|
|
36
|
+
function buildManifest(runId, results, options = {}) {
|
|
37
|
+
const profile = options.profile ?? 'standard';
|
|
38
|
+
const granularity = options.granularity ?? 'run';
|
|
39
|
+
const evidenceRefs = options.evidenceRefs ?? new Map();
|
|
40
|
+
const checks = results.map((r) => ({
|
|
41
|
+
check_id: r.check_id,
|
|
42
|
+
acceptance_ref: r.acceptance_ref,
|
|
43
|
+
status: r.status,
|
|
44
|
+
failure_class: classifyFailure(r),
|
|
45
|
+
evidence_refs: evidenceRefs.get(r.check_id) ?? [],
|
|
46
|
+
duration_ms: r.duration_ms,
|
|
47
|
+
}));
|
|
48
|
+
const summary = {
|
|
49
|
+
total: checks.length,
|
|
50
|
+
pass: checks.filter((c) => c.status === 'pass').length,
|
|
51
|
+
fail: checks.filter((c) => c.status === 'fail').length,
|
|
52
|
+
skip: checks.filter((c) => c.status === 'skip').length,
|
|
53
|
+
error: checks.filter((c) => c.status === 'error').length,
|
|
54
|
+
all_passed: checks.every((c) => c.status === 'pass' || c.status === 'skip'),
|
|
55
|
+
};
|
|
56
|
+
return {
|
|
57
|
+
manifest_id: `vm-${crypto_1.default.randomBytes(4).toString('hex')}`,
|
|
58
|
+
run_id: runId,
|
|
59
|
+
work_item_id: options.workItemId ?? null,
|
|
60
|
+
wave: options.wave ?? null,
|
|
61
|
+
granularity,
|
|
62
|
+
profile,
|
|
63
|
+
compiled_at: new Date().toISOString(),
|
|
64
|
+
checks,
|
|
65
|
+
summary,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function buildRiskLedger(runId, manifest) {
|
|
69
|
+
const risks = [];
|
|
70
|
+
for (const check of manifest.checks) {
|
|
71
|
+
if (check.status === 'pass' || check.status === 'skip')
|
|
72
|
+
continue;
|
|
73
|
+
if (!check.failure_class)
|
|
74
|
+
continue;
|
|
75
|
+
const required = PROFILE_REQUIRED_CHECKS[manifest.profile];
|
|
76
|
+
if (!required.includes(check.failure_class))
|
|
77
|
+
continue;
|
|
78
|
+
risks.push({
|
|
79
|
+
risk_id: `risk-${crypto_1.default.randomBytes(3).toString('hex')}`,
|
|
80
|
+
work_item_id: manifest.work_item_id,
|
|
81
|
+
check_id: check.check_id,
|
|
82
|
+
failure_class: check.failure_class,
|
|
83
|
+
description: `Check ${check.check_id} ${check.status}: ${check.failure_class}`,
|
|
84
|
+
severity: check.failure_class === 'policy_failure' || check.failure_class === 'deterministic'
|
|
85
|
+
? 'high'
|
|
86
|
+
: check.failure_class === 'evidence_missing'
|
|
87
|
+
? 'medium'
|
|
88
|
+
: 'low',
|
|
89
|
+
mitigation: null,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
run_id: runId,
|
|
94
|
+
generated_at: new Date().toISOString(),
|
|
95
|
+
risks,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function saveManifest(projectRoot, runId, manifest) {
|
|
99
|
+
const p = path_1.default.join(projectRoot, '.oxe', 'runs', runId, 'verification-manifest.json');
|
|
100
|
+
fs_1.default.mkdirSync(path_1.default.dirname(p), { recursive: true });
|
|
101
|
+
fs_1.default.writeFileSync(p, JSON.stringify(manifest, null, 2), 'utf8');
|
|
102
|
+
}
|
|
103
|
+
function loadManifest(projectRoot, runId) {
|
|
104
|
+
const p = path_1.default.join(projectRoot, '.oxe', 'runs', runId, 'verification-manifest.json');
|
|
105
|
+
if (!fs_1.default.existsSync(p))
|
|
106
|
+
return null;
|
|
107
|
+
try {
|
|
108
|
+
return JSON.parse(fs_1.default.readFileSync(p, 'utf8'));
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function saveRiskLedger(projectRoot, runId, ledger) {
|
|
115
|
+
const p = path_1.default.join(projectRoot, '.oxe', 'runs', runId, 'residual-risks.json');
|
|
116
|
+
fs_1.default.mkdirSync(path_1.default.dirname(p), { recursive: true });
|
|
117
|
+
fs_1.default.writeFileSync(p, JSON.stringify(ledger, null, 2), 'utf8');
|
|
118
|
+
}
|
|
119
|
+
function loadRiskLedger(projectRoot, runId) {
|
|
120
|
+
const p = path_1.default.join(projectRoot, '.oxe', 'runs', runId, 'residual-risks.json');
|
|
121
|
+
if (!fs_1.default.existsSync(p))
|
|
122
|
+
return null;
|
|
123
|
+
try {
|
|
124
|
+
return JSON.parse(fs_1.default.readFileSync(p, 'utf8'));
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
}
|
package/oxe/workflows/ask.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# OXE — Workflow: ask
|
|
2
2
|
|
|
3
|
+
> **[DEPRECATED v1.1.0]** Este comando foi incorporado por `/oxe`.
|
|
4
|
+
> Use: `/oxe "sua pergunta"` ou simplesmente `/oxe` para o próximo passo.
|
|
5
|
+
> Este alias continuará funcionando nesta versão por compatibilidade.
|
|
6
|
+
|
|
3
7
|
<objective>
|
|
4
8
|
Responder perguntas sobre a situação atual do trabalho OXE com máxima robustez, usando o contexto real do repositório, a sessão ativa quando existir, e os artefatos mais recentes da trilha.
|
|
5
9
|
</objective>
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
# OXE — Workflow: checkpoint
|
|
2
2
|
|
|
3
|
+
> **[DEPRECATED v1.1.0]** Este comando foi incorporado por `/oxe-execute`.
|
|
4
|
+
> Use: `/oxe-execute --checkpoint "<nome>"` para criar snapshot nomeado da sessão.
|
|
5
|
+
> Este alias continuará funcionando nesta versão por compatibilidade.
|
|
6
|
+
|
|
3
7
|
<objective>
|
|
4
|
-
Criar um **marco nomeado em disco** em `checkpoints/YYYY-MM-DD-HHmm-<slug>.md` do escopo resolvido e atualizar `CHECKPOINTS.md` correspondente (índice): **snapshot da sessão / trilha corrente** para pausar e retomar sem apagar SPEC/PLAN.
|
|
8
|
+
Criar um **marco nomeado em disco** em `checkpoints/YYYY-MM-DD-HHmm-<slug>.md` do escopo resolvido e atualizar `CHECKPOINTS.md` correspondente (índice): **snapshot da sessão / trilha corrente** para pausar e retomar sem apagar SPEC/PLAN.
|
|
5
9
|
|
|
6
10
|
**Não** duplica o papel de `git commit` nem de `verify`; é **registo explícito** para humanos e agentes. Para **atualizar o mapa do projeto inteiro** e alinhar `.oxe/codebase/` ao código, usar **`compact.md`** (`/oxe-compact`), não este passo.
|
|
7
11
|
</objective>
|
|
@@ -9,25 +13,25 @@ Criar um **marco nomeado em disco** em `checkpoints/YYYY-MM-DD-HHmm-<slug>.md` d
|
|
|
9
13
|
<context>
|
|
10
14
|
- **Checkpoint vs compact** e **momentos chave** da rotina: tabelas canónicas em **`help.md`** (secções *Checkpoint vs compact* e *Momentos chave*) — evitar divergência; este ficheiro descreve só a execução do checkpoint.
|
|
11
15
|
|
|
12
|
-
- Entrada: texto do utilizador = **slug** e/ou **nota** (ex.: `antes-refactor-auth` + “estado estável, falta T4”).
|
|
13
|
-
- Nome do ficheiro: **`YYYY-MM-DD-HHmm-<slug-kebab>.md`** (hora 24h local ou UTC — documentar na nota se misturar fusos).
|
|
14
|
-
- Frontmatter YAML no checkpoint (ver `oxe/templates/CHECKPOINT.template.md`): `created`, `slug`, `linked` (lista de paths relativos à raiz do repo, tipicamente `.oxe/STATE.md`, `.oxe/SPEC.md`, …).
|
|
15
|
-
- Resolver `active_session` conforme `oxe/workflows/references/session-path-resolution.md`. Com sessão ativa, checkpoints vivem em `.oxe/<active_session>/checkpoints/`; sem sessão ativa, usar `.oxe/checkpoints/`.
|
|
16
|
-
- **Índice** `CHECKPOINTS.md` do mesmo escopo: tabela **mais recente primeiro** com colunas **Data** | **Ficheiro** | **Slug** | **Nota (1 linha)**.
|
|
16
|
+
- Entrada: texto do utilizador = **slug** e/ou **nota** (ex.: `antes-refactor-auth` + “estado estável, falta T4”).
|
|
17
|
+
- Nome do ficheiro: **`YYYY-MM-DD-HHmm-<slug-kebab>.md`** (hora 24h local ou UTC — documentar na nota se misturar fusos).
|
|
18
|
+
- Frontmatter YAML no checkpoint (ver `oxe/templates/CHECKPOINT.template.md`): `created`, `slug`, `linked` (lista de paths relativos à raiz do repo, tipicamente `.oxe/STATE.md`, `.oxe/SPEC.md`, …).
|
|
19
|
+
- Resolver `active_session` conforme `oxe/workflows/references/session-path-resolution.md`. Com sessão ativa, checkpoints vivem em `.oxe/<active_session>/checkpoints/`; sem sessão ativa, usar `.oxe/checkpoints/`.
|
|
20
|
+
- **Índice** `CHECKPOINTS.md` do mesmo escopo: tabela **mais recente primeiro** com colunas **Data** | **Ficheiro** | **Slug** | **Nota (1 linha)**.
|
|
17
21
|
- Não mover nem apagar artefactos canónicos; o checkpoint é **documento adicional**.
|
|
18
22
|
</context>
|
|
19
23
|
|
|
20
24
|
<process>
|
|
21
|
-
1. Garantir pasta `checkpoints/` do escopo resolvido.
|
|
25
|
+
1. Garantir pasta `checkpoints/` do escopo resolvido.
|
|
22
26
|
2. Normalizar slug a partir dos argumentos do utilizador (kebab-case, ASCII; se vazio, usar `checkpoint`).
|
|
23
27
|
3. Escolher nome único; se colisão, acrescentar sufixo `-b`, `-c`, …
|
|
24
28
|
4. Escrever o ficheiro de checkpoint a partir do template: preencher frontmatter `linked` com os `.oxe/*.md` relevantes que **existem**; corpo com nota do utilizador e **snapshot** (trecho de STATE, uma linha de objetivo SPEC, resumo PLAN).
|
|
25
|
-
5. Se `CHECKPOINTS.md` do escopo resolvido não existir, criar com título `# OXE — Índice de checkpoints` e tabela com cabeçalho; senão, **inserir linha no topo** da tabela.
|
|
29
|
+
5. Se `CHECKPOINTS.md` do escopo resolvido não existir, criar com título `# OXE — Índice de checkpoints` e tabela com cabeçalho; senão, **inserir linha no topo** da tabela.
|
|
26
30
|
6. Responder no chat: caminho do ficheiro novo + como usar na retomada (ler checkpoint + `linked` + próximo `oxe:*`).
|
|
27
31
|
</process>
|
|
28
32
|
|
|
29
33
|
<success_criteria>
|
|
30
|
-
- [ ] Novo ficheiro em `checkpoints/` do escopo correto com frontmatter e corpo úteis.
|
|
31
|
-
- [ ] `CHECKPOINTS.md` do mesmo escopo atualizado com entrada correspondente.
|
|
34
|
+
- [ ] Novo ficheiro em `checkpoints/` do escopo correto com frontmatter e corpo úteis.
|
|
35
|
+
- [ ] `CHECKPOINTS.md` do mesmo escopo atualizado com entrada correspondente.
|
|
32
36
|
- [ ] SPEC/PLAN/VERIFY intocados salvo o utilizador pedir outra coisa explicitamente.
|
|
33
37
|
</success_criteria>
|
package/oxe/workflows/debug.md
CHANGED
|
@@ -1,37 +1,41 @@
|
|
|
1
1
|
# OXE — Workflow: debug
|
|
2
2
|
|
|
3
|
+
> **[DEPRECATED v1.1.0]** Este comando foi incorporado por `/oxe-execute`.
|
|
4
|
+
> Use: `/oxe-execute --debug` para ativar diagnóstico técnico explícito.
|
|
5
|
+
> Este alias continuará funcionando nesta versão por compatibilidade.
|
|
6
|
+
|
|
3
7
|
<objective>
|
|
4
8
|
Orientar **investigação técnica** de um sintoma (teste a falhar, erro em runtime, flake, regressão) **durante** a execução de tarefas do `PLAN.md` ou passos do `QUICK.md`: ciclo **hipótese → experiência mínima → evidência → próximo passo**.
|
|
5
9
|
|
|
6
10
|
Diferente de **`verify`**, que audita **aceite** contra SPEC/PLAN. Depois de estabilizar com debug, a trilha continua com **`execute`** e, no fecho, **`verify`**.
|
|
7
11
|
</objective>
|
|
8
12
|
|
|
9
|
-
<context>
|
|
10
|
-
- Aplicar `oxe/workflows/references/reasoning-execution.md`. O debug deve partir de evidência real, testar hipóteses pequenas e fechar com próximo passo único.
|
|
11
|
-
- Pré-requisito: sintoma reproduzível ou descrição clara (mensagem de erro, Tn em falha).
|
|
12
|
-
- Preferir ancorar ao identificador de tarefa **`Tn`** do `PLAN.md` do escopo resolvido quando existir.
|
|
13
|
-
- Resolver `active_session` conforme `oxe/workflows/references/session-path-resolution.md`. Com sessão ativa, usar `.oxe/<active_session>/execution/DEBUG.md`; sem sessão ativa, usar `.oxe/DEBUG.md`.
|
|
14
|
-
- Artefato: **`DEBUG.md`** no escopo correto — ficheiro único com **sessões** datadas (append); não dispersar em vários ficheiros sem convenção.
|
|
13
|
+
<context>
|
|
14
|
+
- Aplicar `oxe/workflows/references/reasoning-execution.md`. O debug deve partir de evidência real, testar hipóteses pequenas e fechar com próximo passo único.
|
|
15
|
+
- Pré-requisito: sintoma reproduzível ou descrição clara (mensagem de erro, Tn em falha).
|
|
16
|
+
- Preferir ancorar ao identificador de tarefa **`Tn`** do `PLAN.md` do escopo resolvido quando existir.
|
|
17
|
+
- Resolver `active_session` conforme `oxe/workflows/references/session-path-resolution.md`. Com sessão ativa, usar `.oxe/<active_session>/execution/DEBUG.md`; sem sessão ativa, usar `.oxe/DEBUG.md`.
|
|
18
|
+
- Artefato: **`DEBUG.md`** no escopo correto — ficheiro único com **sessões** datadas (append); não dispersar em vários ficheiros sem convenção.
|
|
15
19
|
</context>
|
|
16
20
|
|
|
17
21
|
<process>
|
|
18
|
-
1. Ler `PLAN.md` do escopo resolvido e `.oxe/STATE.md`; se o foco for uma tarefa, localizar **Tn** e o bloco **Verificar**.
|
|
19
|
-
2. Registar em **`DEBUG.md`** do escopo resolvido uma nova sessão:
|
|
22
|
+
1. Ler `PLAN.md` do escopo resolvido e `.oxe/STATE.md`; se o foco for uma tarefa, localizar **Tn** e o bloco **Verificar**.
|
|
23
|
+
2. Registar em **`DEBUG.md`** do escopo resolvido uma nova sessão:
|
|
20
24
|
- **Data** / **Sintoma** (com stack ou comando que falhou).
|
|
21
25
|
- **Hipóteses** (ordenadas por plausibilidade).
|
|
22
26
|
- **Experiências** — o que foi tentado e resultado (uma linha cada).
|
|
23
27
|
- **Evidência atual** — ficheiros, linhas, conclusão parcial.
|
|
24
28
|
- **Próximo passo:** `execute` (continuar correção) | `discuss` (decisão técnica em grupo) | `spec` ou `plan` (requisito ambíguo ou impossível como escrito).
|
|
25
29
|
3. Se a causa for **requisito errado**, documentar em DEBUG e recomendar **`/oxe-spec`** ou **`/oxe-plan`** (e opcionalmente **`/oxe-discuss`**).
|
|
26
|
-
4. Resumo no chat em ≤8 linhas, nesta ordem:
|
|
27
|
-
- **Contexto lido**
|
|
28
|
-
- **Hipótese principal**
|
|
29
|
-
- **Evidência atual**
|
|
30
|
-
- **Próximo passo**
|
|
31
|
-
</process>
|
|
30
|
+
4. Resumo no chat em ≤8 linhas, nesta ordem:
|
|
31
|
+
- **Contexto lido**
|
|
32
|
+
- **Hipótese principal**
|
|
33
|
+
- **Evidência atual**
|
|
34
|
+
- **Próximo passo**
|
|
35
|
+
</process>
|
|
32
36
|
|
|
33
37
|
<success_criteria>
|
|
34
|
-
- [ ] `DEBUG.md` no escopo correto contém sessão datada com sintoma e **Próximo passo** explícito.
|
|
38
|
+
- [ ] `DEBUG.md` no escopo correto contém sessão datada com sintoma e **Próximo passo** explícito.
|
|
35
39
|
- [ ] Quando aplicável, a sessão referencia **Tn** do PLAN.
|
|
36
40
|
- [ ] Não se confunde com verify: não se declara “entrega aprovada” só com debug.
|
|
37
41
|
</success_criteria>
|
package/oxe/workflows/execute.md
CHANGED
|
@@ -1,8 +1,36 @@
|
|
|
1
1
|
# OXE — Workflow: execute
|
|
2
2
|
|
|
3
3
|
<objective>
|
|
4
|
-
Guiar a **implementação** de um plano OXE com dois modos possíveis
|
|
4
|
+
Guiar a **implementação** de um plano OXE com dois modos possíveis.
|
|
5
5
|
|
|
6
|
+
**Flags suportadas:**
|
|
7
|
+
- `--note "texto"` — registrar observação contextual em `OBSERVATIONS.md` antes de iniciar a execução (equivalente a `/oxe-obs`). Pode ser usado com qualquer outro argumento.
|
|
8
|
+
- `--debug` — ativar diagnóstico técnico explícito ao primeiro sinal de falha em vez de esperar 2 tentativas (equivalente a `/oxe-debug`). Fornece stack trace detalhado, hipóteses e fix.
|
|
9
|
+
- `--deep-diagnosis` — iniciar diretamente em modo de diagnóstico pós-falha persistente (equivalente a `/oxe-forensics`). Usar quando a execução já falhou repetidamente e o estado está corrompido ou inconsistente.
|
|
10
|
+
- `--checkpoint "<nome>"` — criar snapshot nomeado do estado da sessão antes de iniciar ou após concluir (equivalente a `/oxe-checkpoint`). Útil antes de experimentos ou ondas arriscadas.
|
|
11
|
+
- `--iterative` — ativar modo B com loop automático até verify passar, com retry controlado por `loop_max` (equivalente a `/oxe-loop`).
|
|
12
|
+
|
|
13
|
+
**Nota de compatibilidade v1.1.0:** `/oxe-obs`, `/oxe-debug`, `/oxe-forensics`, `/oxe-checkpoint` e `/oxe-loop` foram incorporados por este comando. Esses comandos legados continuam funcionando mas exibem aviso de migração.
|
|
14
|
+
|
|
15
|
+
</objective>
|
|
16
|
+
|
|
17
|
+
<flags_processing>
|
|
18
|
+
## Processamento de flags (executar antes do step 1)
|
|
19
|
+
|
|
20
|
+
Ao receber qualquer argumento, verificar flags antes de iniciar o fluxo principal:
|
|
21
|
+
|
|
22
|
+
1. **`--note "texto"`**: escrever entrada em `OBSERVATIONS.md` do escopo resolvido com status `pendente`, impacto `execute`, severidade `info`. Marcar como `incorporada → execute (data)` imediatamente após registrar. Continuar com o fluxo normal.
|
|
23
|
+
|
|
24
|
+
2. **`--checkpoint "<nome>"`**: executar a lógica de `oxe/workflows/checkpoint.md` com o slug fornecido antes de iniciar a onda. Reportar confirmação do snapshot. Continuar.
|
|
25
|
+
|
|
26
|
+
3. **`--deep-diagnosis`**: saltar diretamente para o fluxo de `oxe/workflows/forensics.md` com o contexto atual do `EXECUTION-RUNTIME.md` e `STATE.md`. Não iniciar nova onda sem resolução explícita.
|
|
27
|
+
|
|
28
|
+
4. **`--debug`**: ajustar `<failure_mode>` para acionar diagnóstico imediato na primeira falha (sem 2 tentativas antes). Reportar hipóteses, evidências e fix com mais detalhe.
|
|
29
|
+
|
|
30
|
+
5. **`--iterative`**: registrar em STATE.md: `execute_mode: por_onda` e `loop_max: 3` (ou o valor de config). Informar ao usuário que o modo iterativo está ativo.
|
|
31
|
+
</flags_processing>
|
|
32
|
+
|
|
33
|
+
<execution_modes>
|
|
6
34
|
**Modo Solo (padrão):** seguir `PLAN.md` do escopo resolvido da sessão onda a onda sem `plan-agents.json`. O agente implementa diretamente cada tarefa Tn da onda atual, roda a verificação e avança. Não exige nenhum artefato além do PLAN.md.
|
|
7
35
|
|
|
8
36
|
**Modo com Agentes (extensão):** quando existe `plan-agents.json` válido no escopo resolvido (schema 2+, lifecycle ativo, runId alinhado ao STATE), adotar roles e personas por agente conforme o blueprint.
|
|
@@ -10,7 +38,7 @@ Guiar a **implementação** de um plano OXE com dois modos possíveis:
|
|
|
10
38
|
**Seleção de execução (redução de requisições):** quando o plano tem 2+ ondas, o usuário escolhe entre Completo (1 sessão), Por onda (N sessões) ou Por tarefa (N tarefas). A escolha é feita **uma vez** no início.
|
|
11
39
|
|
|
12
40
|
Se existir apenas **`QUICK.md`** no escopo resolvido: tratar passos numerados como onda única (modo sempre Completo).
|
|
13
|
-
</
|
|
41
|
+
</execution_modes>
|
|
14
42
|
|
|
15
43
|
<modo_solo>
|
|
16
44
|
## Modo Solo — Execução direta do PLAN.md
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
# OXE — Workflow: forensics
|
|
2
2
|
|
|
3
|
+
> **[DEPRECATED v1.1.0]** Este comando foi incorporado por `/oxe-execute`.
|
|
4
|
+
> Use: `/oxe-execute --deep-diagnosis` para diagnóstico pós-falha persistente.
|
|
5
|
+
> Este alias continuará funcionando nesta versão por compatibilidade.
|
|
6
|
+
|
|
3
7
|
<objective>
|
|
4
8
|
Diagnosticar **incidentes de fluxo** após falha ou incoerência entre artefatos `.oxe/`, Git e saída de `oxe-cc doctor`: produzir **`FORENSICS.md`** no escopo resolvido com linha do tempo, hipótese de causa e **exatamente um** próximo passo canónico OXE (`scan`, `plan` ou `execute` — incluindo ações como reinstalar workflows ou correr verify como parte do movimento **execute**).
|
|
5
9
|
|
|
6
10
|
Não reescrever `SPEC.md` nem apagar `PLAN.md`; apenas **recomendar** o reingresso na trilha.
|
|
7
11
|
</objective>
|
|
8
12
|
|
|
9
|
-
<context>
|
|
10
|
-
- Aplicar `oxe/workflows/references/reasoning-execution.md` para montar a linha do tempo e `oxe/workflows/references/reasoning-status.md` para devolver um único reingresso recomendado.
|
|
11
|
-
- Usar quando: `VERIFY.md` com falhas ou gaps não explicados, `oxe-cc doctor` com **FALHA**, `STATE.md` contradiz ficheiros presentes (ex.: “onda concluída” sem `VERIFY.md`), ou o utilizador indica estar **preso** após várias tentativas de replan.
|
|
13
|
+
<context>
|
|
14
|
+
- Aplicar `oxe/workflows/references/reasoning-execution.md` para montar a linha do tempo e `oxe/workflows/references/reasoning-status.md` para devolver um único reingresso recomendado.
|
|
15
|
+
- Usar quando: `VERIFY.md` com falhas ou gaps não explicados, `oxe-cc doctor` com **FALHA**, `STATE.md` contradiz ficheiros presentes (ex.: “onda concluída” sem `VERIFY.md`), ou o utilizador indica estar **preso** após várias tentativas de replan.
|
|
12
16
|
- Resolver `active_session` conforme `oxe/workflows/references/session-path-resolution.md`; ler `.oxe/STATE.md` global e os artefatos de sessão (`VERIFY.md`, `PLAN.md`, `SPEC.md`, `QUICK.md`) no escopo resolvido.
|
|
13
17
|
- **Git é opcional:** em sandbox sem Git ou sem permissão de terminal, **não** falhar o workflow; registar em `FORENSICS.md` que Git não foi avaliado.
|
|
14
18
|
- Opcional: saída resumida de `npx oxe-cc doctor` no diretório do projeto.
|
|
@@ -33,12 +37,12 @@ Não reescrever `SPEC.md` nem apagar `PLAN.md`; apenas **recomendar** o reingres
|
|
|
33
37
|
- **Próximo passo OXE recomendado:** **um único** valor entre `scan` | `plan` | `execute` e o **comando** correspondente (`/oxe-scan`, `/oxe-plan`, `/oxe-execute` ou `npx oxe-cc@latest` / `npx oxe-cc doctor` quando a causa for tooling).
|
|
34
38
|
- **Justificativa** — uma frase que liga evidência ao passo escolhido.
|
|
35
39
|
4. Atualizar **`.oxe/STATE.md`** global com uma linha opcional sob decisões ou contexto: referência a `FORENSICS.md` e fase sugerida (ex.: `forensics_complete` → próximo conforme passo recomendado).
|
|
36
|
-
5. Responder no chat em ≤8 linhas, nesta ordem:
|
|
37
|
-
- **Leitura atual**
|
|
38
|
-
- **Hipótese de causa**
|
|
39
|
-
- **Próximo passo**
|
|
40
|
-
- **Motivo**
|
|
41
|
-
</process>
|
|
40
|
+
5. Responder no chat em ≤8 linhas, nesta ordem:
|
|
41
|
+
- **Leitura atual**
|
|
42
|
+
- **Hipótese de causa**
|
|
43
|
+
- **Próximo passo**
|
|
44
|
+
- **Motivo**
|
|
45
|
+
</process>
|
|
42
46
|
|
|
43
47
|
<success_criteria>
|
|
44
48
|
- [ ] `FORENSICS.md` existe no escopo correto com **Próximo passo OXE recomendado** igual a **um** entre `scan`, `plan`, `execute`.
|