role-os 2.0.0 → 2.2.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.
- package/CHANGELOG.md +61 -0
- package/README.es.md +123 -54
- package/README.fr.md +90 -21
- package/README.hi.md +90 -21
- package/README.it.md +130 -61
- package/README.ja.md +91 -22
- package/README.md +72 -16
- package/README.pt-BR.md +90 -21
- package/README.zh.md +160 -88
- package/package.json +2 -2
- package/src/artifacts.mjs +569 -437
- package/src/brainstorm-render.mjs +462 -0
- package/src/brainstorm-roles.mjs +774 -0
- package/src/brainstorm.mjs +778 -0
- package/src/dispatch.mjs +339 -310
- package/src/evidence.mjs +9 -9
- package/src/mission-run.mjs +111 -13
- package/src/mission.mjs +508 -388
- package/src/packs.mjs +430 -359
- package/src/route.mjs +715 -564
- package/src/run.mjs +5 -2
- package/starter-pack/agents/engineering/audit-synthesizer.md +56 -0
- package/starter-pack/agents/engineering/component-auditor.md +46 -0
- package/starter-pack/agents/engineering/seam-auditor.md +46 -0
- package/starter-pack/agents/engineering/test-truth-auditor.md +48 -0
package/src/evidence.mjs
CHANGED
|
@@ -146,7 +146,7 @@ const DEFAULT_REQUIREMENTS = {
|
|
|
146
146
|
* @property {EvidenceItem[]} evidence - Structured evidence items
|
|
147
147
|
* @property {string[]} gaps - What's missing or weak
|
|
148
148
|
* @property {string[]} risks - Identified risks
|
|
149
|
-
* @property {string} [requiredNextArtifact] - What the next role must produce (for non-
|
|
149
|
+
* @property {string} [requiredNextArtifact] - What the next role must produce (for non-accept)
|
|
150
150
|
* @property {string} confidence - One of CONFIDENCE_LEVELS
|
|
151
151
|
*/
|
|
152
152
|
|
|
@@ -182,25 +182,25 @@ export function checkSufficiency(verdict) {
|
|
|
182
182
|
.map(e => `${e.kind}: ${e.claim} (${e.reference})`);
|
|
183
183
|
|
|
184
184
|
if (contradictions.length > 0 && verdict.verdict === "accept") {
|
|
185
|
-
warnings.push("Verdict is '
|
|
185
|
+
warnings.push("Verdict is 'accept' but evidence contains contradictions — review carefully");
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
// Check for missing evidence items on
|
|
188
|
+
// Check for missing evidence items on accept verdicts
|
|
189
189
|
const missingItems = verdict.evidence.filter(e => e.status === "missing");
|
|
190
190
|
if (missingItems.length > 0 && verdict.verdict === "accept") {
|
|
191
|
-
warnings.push("Verdict is '
|
|
191
|
+
warnings.push("Verdict is 'accept' but some evidence items are marked 'missing'");
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
// Non-
|
|
195
|
-
if (verdict.verdict !== "
|
|
194
|
+
// Non-accept verdicts should have gaps or requiredNextArtifact
|
|
195
|
+
if (verdict.verdict !== "accept" && verdict.verdict !== "accept-with-notes") {
|
|
196
196
|
if (verdict.gaps.length === 0 && !verdict.requiredNextArtifact) {
|
|
197
|
-
warnings.push("Non-
|
|
197
|
+
warnings.push("Non-accept verdict should specify gaps or requiredNextArtifact for recovery");
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
// Low confidence +
|
|
201
|
+
// Low confidence + accept is suspicious
|
|
202
202
|
if (verdict.confidence === "low" && verdict.verdict === "accept") {
|
|
203
|
-
warnings.push("Low confidence
|
|
203
|
+
warnings.push("Low confidence accept — consider whether evidence is actually sufficient");
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
const sufficient = missingRequired.length === 0 && contradictions.length === 0;
|
package/src/mission-run.mjs
CHANGED
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { MISSIONS, getMission, validateMission } from "./mission.mjs";
|
|
13
|
-
import {
|
|
14
|
-
import { validateArtifact, ROLE_ARTIFACT_CONTRACTS } from "./artifacts.mjs";
|
|
13
|
+
import { validateArtifact } from "./artifacts.mjs";
|
|
15
14
|
|
|
16
15
|
let _runCounter = 0;
|
|
17
16
|
|
|
@@ -59,7 +58,7 @@ let _runCounter = 0;
|
|
|
59
58
|
* @param {string} taskDescription
|
|
60
59
|
* @returns {MissionRun}
|
|
61
60
|
*/
|
|
62
|
-
export function createRun(missionKey, taskDescription) {
|
|
61
|
+
export function createRun(missionKey, taskDescription, options = {}) {
|
|
63
62
|
const mission = getMission(missionKey);
|
|
64
63
|
if (!mission) {
|
|
65
64
|
throw new Error(`Mission "${missionKey}" not found. Available: ${Object.keys(MISSIONS).join(", ")}`);
|
|
@@ -72,16 +71,26 @@ export function createRun(missionKey, taskDescription) {
|
|
|
72
71
|
|
|
73
72
|
const id = `${missionKey}-${Date.now()}-${++_runCounter}`;
|
|
74
73
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
74
|
+
let steps;
|
|
75
|
+
const dd = mission.dynamicDispatch;
|
|
76
|
+
|
|
77
|
+
if (dd && options.manifest) {
|
|
78
|
+
// Dynamic dispatch — build steps from manifest
|
|
79
|
+
steps = buildDynamicSteps(mission, options.manifest);
|
|
80
|
+
} else {
|
|
81
|
+
// Static dispatch — use artifactFlow as-is
|
|
82
|
+
steps = mission.artifactFlow.map((step) => ({
|
|
83
|
+
role: step.role,
|
|
84
|
+
produces: step.produces,
|
|
85
|
+
consumedBy: step.consumedBy,
|
|
86
|
+
status: "pending",
|
|
87
|
+
artifact: null,
|
|
88
|
+
artifactValidation: null,
|
|
89
|
+
note: null,
|
|
90
|
+
startedAt: null,
|
|
91
|
+
completedAt: null,
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
85
94
|
|
|
86
95
|
return {
|
|
87
96
|
id,
|
|
@@ -93,9 +102,94 @@ export function createRun(missionKey, taskDescription) {
|
|
|
93
102
|
startedAt: new Date().toISOString(),
|
|
94
103
|
completedAt: null,
|
|
95
104
|
completionReport: null,
|
|
105
|
+
dynamicDispatch: dd && options.manifest ? true : false,
|
|
106
|
+
manifest: options.manifest || null,
|
|
96
107
|
};
|
|
97
108
|
}
|
|
98
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Build steps from manifest for dynamic dispatch missions.
|
|
112
|
+
* @param {Object} mission
|
|
113
|
+
* @param {Object} manifest - The audit-manifest.json content
|
|
114
|
+
* @returns {MissionStep[]}
|
|
115
|
+
*/
|
|
116
|
+
function buildDynamicSteps(mission, manifest) {
|
|
117
|
+
const dd = mission.dynamicDispatch;
|
|
118
|
+
const steps = [];
|
|
119
|
+
|
|
120
|
+
// Scaling roles: one step per manifest entry
|
|
121
|
+
const components = manifest[dd.componentAuditorPer] || [];
|
|
122
|
+
const boundaries = manifest[dd.seamAuditorPer] || manifest.boundaries || [];
|
|
123
|
+
|
|
124
|
+
// Component Auditor × N
|
|
125
|
+
for (const comp of components) {
|
|
126
|
+
steps.push({
|
|
127
|
+
role: "Component Auditor",
|
|
128
|
+
produces: "component-audit-report",
|
|
129
|
+
consumedBy: "Audit Synthesizer",
|
|
130
|
+
parcel: comp.id || comp.name,
|
|
131
|
+
status: "pending",
|
|
132
|
+
artifact: null,
|
|
133
|
+
artifactValidation: null,
|
|
134
|
+
note: null,
|
|
135
|
+
startedAt: null,
|
|
136
|
+
completedAt: null,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Test Truth Auditor × M
|
|
141
|
+
for (const comp of components) {
|
|
142
|
+
steps.push({
|
|
143
|
+
role: "Test Truth Auditor",
|
|
144
|
+
produces: "test-truth-report",
|
|
145
|
+
consumedBy: "Audit Synthesizer",
|
|
146
|
+
parcel: comp.id || comp.name,
|
|
147
|
+
status: "pending",
|
|
148
|
+
artifact: null,
|
|
149
|
+
artifactValidation: null,
|
|
150
|
+
note: null,
|
|
151
|
+
startedAt: null,
|
|
152
|
+
completedAt: null,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Seam Auditor × K
|
|
157
|
+
for (const boundary of boundaries) {
|
|
158
|
+
const label = boundary.id || `${boundary.from}-${boundary.to}`;
|
|
159
|
+
steps.push({
|
|
160
|
+
role: "Seam Auditor",
|
|
161
|
+
produces: "seam-audit-report",
|
|
162
|
+
consumedBy: "Audit Synthesizer",
|
|
163
|
+
parcel: label,
|
|
164
|
+
status: "pending",
|
|
165
|
+
artifact: null,
|
|
166
|
+
artifactValidation: null,
|
|
167
|
+
note: null,
|
|
168
|
+
startedAt: null,
|
|
169
|
+
completedAt: null,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Non-scaling roles from artifactFlow (Audit Synthesizer, Critic Reviewer)
|
|
174
|
+
for (const step of mission.artifactFlow) {
|
|
175
|
+
if (!dd.scalingRoles.includes(step.role)) {
|
|
176
|
+
steps.push({
|
|
177
|
+
role: step.role,
|
|
178
|
+
produces: step.produces,
|
|
179
|
+
consumedBy: step.consumedBy,
|
|
180
|
+
status: "pending",
|
|
181
|
+
artifact: null,
|
|
182
|
+
artifactValidation: null,
|
|
183
|
+
note: null,
|
|
184
|
+
startedAt: null,
|
|
185
|
+
completedAt: null,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return steps;
|
|
191
|
+
}
|
|
192
|
+
|
|
99
193
|
// ── Step through a run ──────────────────────────────────────────────────────
|
|
100
194
|
|
|
101
195
|
/**
|
|
@@ -127,6 +221,10 @@ export function completeStep(run, artifact, note) {
|
|
|
127
221
|
throw new Error("No active step to complete");
|
|
128
222
|
}
|
|
129
223
|
|
|
224
|
+
// Validate artifact against role contract (warn, don't block)
|
|
225
|
+
const validation = validateArtifact(active.role, artifact);
|
|
226
|
+
active.artifactValidation = validation;
|
|
227
|
+
|
|
130
228
|
active.status = "completed";
|
|
131
229
|
active.artifact = artifact;
|
|
132
230
|
active.note = note || null;
|