oh-my-codex 0.18.1 → 0.18.2
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/Cargo.lock +6 -6
- package/Cargo.toml +1 -1
- package/README.md +4 -2
- package/dist/agents/__tests__/definitions.test.js +14 -0
- package/dist/agents/__tests__/definitions.test.js.map +1 -1
- package/dist/agents/__tests__/native-config.test.js +19 -0
- package/dist/agents/__tests__/native-config.test.js.map +1 -1
- package/dist/agents/definitions.d.ts.map +1 -1
- package/dist/agents/definitions.js +30 -0
- package/dist/agents/definitions.js.map +1 -1
- package/dist/agents/native-config.d.ts +1 -0
- package/dist/agents/native-config.d.ts.map +1 -1
- package/dist/agents/native-config.js +4 -0
- package/dist/agents/native-config.js.map +1 -1
- package/dist/catalog/__tests__/generator.test.js +4 -0
- package/dist/catalog/__tests__/generator.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-warning-copy.test.js +61 -5
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +161 -21
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +51 -3
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/question.test.js +2 -2
- package/dist/cli/__tests__/question.test.js.map +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +178 -7
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.d.ts +7 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +143 -43
- package/dist/cli/index.js.map +1 -1
- package/dist/config/__tests__/codex-hooks.test.js +3 -3
- package/dist/config/__tests__/codex-hooks.test.js.map +1 -1
- package/dist/config/codex-hooks.d.ts +1 -0
- package/dist/config/codex-hooks.d.ts.map +1 -1
- package/dist/config/codex-hooks.js +2 -4
- package/dist/config/codex-hooks.js.map +1 -1
- package/dist/config/generator.d.ts +14 -0
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +100 -1
- package/dist/config/generator.js.map +1 -1
- package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js +21 -0
- package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js.map +1 -1
- package/dist/goal-workflows/codex-goal-snapshot.d.ts +3 -0
- package/dist/goal-workflows/codex-goal-snapshot.d.ts.map +1 -1
- package/dist/goal-workflows/codex-goal-snapshot.js +45 -2
- package/dist/goal-workflows/codex-goal-snapshot.js.map +1 -1
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js +17 -0
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +170 -15
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/prometheus-strict-contract.test.d.ts +2 -0
- package/dist/hooks/__tests__/prometheus-strict-contract.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/prometheus-strict-contract.test.js +320 -0
- package/dist/hooks/__tests__/prometheus-strict-contract.test.js.map +1 -0
- package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js +12 -0
- package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js.map +1 -1
- package/dist/hooks/__tests__/research-workflow-boundaries.test.d.ts +2 -0
- package/dist/hooks/__tests__/research-workflow-boundaries.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/research-workflow-boundaries.test.js +35 -0
- package/dist/hooks/__tests__/research-workflow-boundaries.test.js.map +1 -0
- package/dist/hooks/keyword-detector.d.ts +1 -1
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +28 -6
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/keyword-registry.d.ts.map +1 -1
- package/dist/hooks/keyword-registry.js +1 -0
- package/dist/hooks/keyword-registry.js.map +1 -1
- package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
- package/dist/hooks/prompt-guidance-contract.js +11 -0
- package/dist/hooks/prompt-guidance-contract.js.map +1 -1
- package/dist/hud/__tests__/hud-tmux-injection.test.js +22 -0
- package/dist/hud/__tests__/hud-tmux-injection.test.js.map +1 -1
- package/dist/hud/__tests__/reconcile.test.js +121 -10
- package/dist/hud/__tests__/reconcile.test.js.map +1 -1
- package/dist/hud/__tests__/render.test.js +84 -0
- package/dist/hud/__tests__/render.test.js.map +1 -1
- package/dist/hud/__tests__/state.test.js +51 -1
- package/dist/hud/__tests__/state.test.js.map +1 -1
- package/dist/hud/__tests__/tmux.test.js +69 -23
- package/dist/hud/__tests__/tmux.test.js.map +1 -1
- package/dist/hud/index.d.ts +1 -1
- package/dist/hud/index.d.ts.map +1 -1
- package/dist/hud/index.js +8 -3
- package/dist/hud/index.js.map +1 -1
- package/dist/hud/reconcile.d.ts.map +1 -1
- package/dist/hud/reconcile.js +6 -3
- package/dist/hud/reconcile.js.map +1 -1
- package/dist/hud/render.d.ts.map +1 -1
- package/dist/hud/render.js +26 -0
- package/dist/hud/render.js.map +1 -1
- package/dist/hud/state.d.ts +2 -1
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +62 -1
- package/dist/hud/state.js.map +1 -1
- package/dist/hud/tmux.d.ts +10 -3
- package/dist/hud/tmux.d.ts.map +1 -1
- package/dist/hud/tmux.js +59 -10
- package/dist/hud/tmux.js.map +1 -1
- package/dist/hud/types.d.ts +22 -0
- package/dist/hud/types.d.ts.map +1 -1
- package/dist/hud/types.js.map +1 -1
- package/dist/pipeline/__tests__/orchestrator.test.js +63 -1
- package/dist/pipeline/__tests__/orchestrator.test.js.map +1 -1
- package/dist/pipeline/__tests__/stages.test.js +410 -4
- package/dist/pipeline/__tests__/stages.test.js.map +1 -1
- package/dist/pipeline/orchestrator.d.ts.map +1 -1
- package/dist/pipeline/orchestrator.js +29 -2
- package/dist/pipeline/orchestrator.js.map +1 -1
- package/dist/pipeline/stages/ralplan.d.ts.map +1 -1
- package/dist/pipeline/stages/ralplan.js +41 -6
- package/dist/pipeline/stages/ralplan.js.map +1 -1
- package/dist/question/__tests__/ui.test.js +43 -10
- package/dist/question/__tests__/ui.test.js.map +1 -1
- package/dist/question/ui.d.ts +12 -0
- package/dist/question/ui.d.ts.map +1 -1
- package/dist/question/ui.js +83 -46
- package/dist/question/ui.js.map +1 -1
- package/dist/ralplan/__tests__/runtime.test.js +200 -10
- package/dist/ralplan/__tests__/runtime.test.js.map +1 -1
- package/dist/ralplan/consensus-gate.d.ts +23 -0
- package/dist/ralplan/consensus-gate.d.ts.map +1 -0
- package/dist/ralplan/consensus-gate.js +212 -0
- package/dist/ralplan/consensus-gate.js.map +1 -0
- package/dist/ralplan/runtime.d.ts +25 -0
- package/dist/ralplan/runtime.d.ts.map +1 -1
- package/dist/ralplan/runtime.js +144 -8
- package/dist/ralplan/runtime.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +626 -7
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/__tests__/docs-site-contract.test.d.ts +2 -0
- package/dist/scripts/__tests__/docs-site-contract.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/docs-site-contract.test.js +42 -0
- package/dist/scripts/__tests__/docs-site-contract.test.js.map +1 -0
- package/dist/scripts/__tests__/notify-dispatcher.test.js +115 -2
- package/dist/scripts/__tests__/notify-dispatcher.test.js.map +1 -1
- package/dist/scripts/__tests__/run-test-files.test.js +57 -0
- package/dist/scripts/__tests__/run-test-files.test.js.map +1 -1
- package/dist/scripts/__tests__/verify-native-agents.test.js +2 -2
- package/dist/scripts/__tests__/verify-native-agents.test.js.map +1 -1
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +214 -34
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/notify-dispatcher.js +188 -4
- package/dist/scripts/notify-dispatcher.js.map +1 -1
- package/dist/scripts/run-test-files.js +13 -0
- package/dist/scripts/run-test-files.js.map +1 -1
- package/dist/state/__tests__/workflow-transition.test.js +6 -0
- package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
- package/dist/state/workflow-transition.d.ts +1 -1
- package/dist/state/workflow-transition.d.ts.map +1 -1
- package/dist/state/workflow-transition.js +7 -0
- package/dist/state/workflow-transition.js.map +1 -1
- package/dist/subagents/tracker.d.ts.map +1 -1
- package/dist/subagents/tracker.js +4 -3
- package/dist/subagents/tracker.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +36 -44
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +58 -18
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +10 -20
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +15 -6
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/ultragoal/__tests__/artifacts.test.js +50 -0
- package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
- package/dist/ultragoal/artifacts.d.ts.map +1 -1
- package/dist/ultragoal/artifacts.js +28 -2
- package/dist/ultragoal/artifacts.js.map +1 -1
- package/package.json +1 -1
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/oh-my-codex/skills/autopilot/SKILL.md +16 -4
- package/plugins/oh-my-codex/skills/autoresearch/SKILL.md +4 -0
- package/plugins/oh-my-codex/skills/autoresearch-goal/SKILL.md +1 -1
- package/plugins/oh-my-codex/skills/best-practice-research/SKILL.md +1 -1
- package/plugins/oh-my-codex/skills/pipeline/SKILL.md +1 -1
- package/plugins/oh-my-codex/skills/plan/SKILL.md +1 -1
- package/plugins/oh-my-codex/skills/prometheus-strict/README.md +35 -0
- package/plugins/oh-my-codex/skills/prometheus-strict/SKILL.md +219 -0
- package/plugins/oh-my-codex/skills/ralplan/SKILL.md +18 -3
- package/prompts/prometheus-strict-metis.md +274 -0
- package/prompts/prometheus-strict-momus.md +82 -0
- package/prompts/prometheus-strict-oracle.md +107 -0
- package/prompts/researcher.md +22 -3
- package/skills/autopilot/SKILL.md +16 -4
- package/skills/autoresearch/SKILL.md +4 -0
- package/skills/autoresearch-goal/SKILL.md +1 -1
- package/skills/best-practice-research/SKILL.md +1 -1
- package/skills/pipeline/SKILL.md +1 -1
- package/skills/plan/SKILL.md +1 -1
- package/skills/prometheus-strict/README.md +35 -0
- package/skills/prometheus-strict/SKILL.md +219 -0
- package/skills/ralplan/SKILL.md +18 -3
- package/src/scripts/__tests__/codex-native-hook.test.ts +769 -8
- package/src/scripts/__tests__/docs-site-contract.test.ts +47 -0
- package/src/scripts/__tests__/notify-dispatcher.test.ts +132 -3
- package/src/scripts/__tests__/run-test-files.test.ts +67 -0
- package/src/scripts/__tests__/verify-native-agents.test.ts +2 -2
- package/src/scripts/codex-native-hook.ts +237 -30
- package/src/scripts/notify-dispatcher.ts +202 -4
- package/src/scripts/run-test-files.ts +13 -0
- package/templates/catalog-manifest.json +22 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { describe, it } from 'node:test';
|
|
5
|
+
import { AGENT_DEFINITIONS } from '../../agents/definitions.js';
|
|
6
|
+
import { KEYWORD_TRIGGER_DEFINITIONS } from '../keyword-registry.js';
|
|
7
|
+
const repoRoot = new URL('../../..', import.meta.url).pathname;
|
|
8
|
+
const skillDir = join(repoRoot, 'skills', 'prometheus-strict');
|
|
9
|
+
const skillPath = join(skillDir, 'SKILL.md');
|
|
10
|
+
const readmePath = join(skillDir, 'README.md');
|
|
11
|
+
const promptNames = [
|
|
12
|
+
'prometheus-strict-metis',
|
|
13
|
+
'prometheus-strict-momus',
|
|
14
|
+
'prometheus-strict-oracle',
|
|
15
|
+
];
|
|
16
|
+
const promptRoles = {
|
|
17
|
+
'prometheus-strict-metis': 'METIS',
|
|
18
|
+
'prometheus-strict-momus': 'MOMUS',
|
|
19
|
+
'prometheus-strict-oracle': 'ORACLE',
|
|
20
|
+
};
|
|
21
|
+
function readRepoFile(path) {
|
|
22
|
+
return readFileSync(path, 'utf8');
|
|
23
|
+
}
|
|
24
|
+
describe('prometheus-strict clean-room contract', () => {
|
|
25
|
+
it('does not add a prometheus-strict hook runtime or Sisyphus/start-work port', () => {
|
|
26
|
+
const hookRegistry = readRepoFile(join(repoRoot, 'src', 'hooks', 'keyword-registry.ts'));
|
|
27
|
+
assert.doesNotMatch(hookRegistry, /start-work|Sisyphus/i, 'keyword wiring must not port start-work or Sisyphus behavior');
|
|
28
|
+
for (const hookPath of [
|
|
29
|
+
join(repoRoot, 'src', 'hooks', 'prometheus-strict.ts'),
|
|
30
|
+
join(repoRoot, 'src', 'scripts', 'prometheus-strict-hook.ts'),
|
|
31
|
+
]) {
|
|
32
|
+
assert.equal(existsSync(hookPath), false, `${hookPath} must not exist`);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
it('keeps the skill planning-only, OMX-native, and clean-room credited', () => {
|
|
36
|
+
assert.ok(existsSync(skillPath), 'prometheus-strict skill must exist');
|
|
37
|
+
assert.ok(existsSync(readmePath), 'prometheus-strict README must exist');
|
|
38
|
+
const skill = readRepoFile(skillPath);
|
|
39
|
+
const readme = readRepoFile(readmePath);
|
|
40
|
+
for (const [label, content] of [
|
|
41
|
+
['skill', skill],
|
|
42
|
+
['readme', readme],
|
|
43
|
+
]) {
|
|
44
|
+
assert.match(content, /clean-room/i, `${label} must state the clean-room boundary`);
|
|
45
|
+
assert.match(content, /OMO Prometheus[\s\S]*`code-yeongyu\/oh-my-openagent`[\s\S]*reimplemented from concept under MIT/i, `${label} must preserve concept-only credit`);
|
|
46
|
+
assert.match(content, /Metis/i, `${label} must include the Metis interview role`);
|
|
47
|
+
assert.match(content, /Momus/i, `${label} must include the Momus critique role`);
|
|
48
|
+
assert.match(content, /Oracle/i, `${label} must include the Oracle synthesis role`);
|
|
49
|
+
assert.match(content, /\$ultragoal/i, `${label} must hand off through OMX ultragoal`);
|
|
50
|
+
assert.match(content, /\$team/i, `${label} must mention team only as a warranted handoff`);
|
|
51
|
+
assert.match(content, /No hook implementation/i, `${label} must keep hook work out of scope`);
|
|
52
|
+
assert.match(content, /No Sisyphus|No Sisyphus\/start-work port/i, `${label} must reject Sisyphus ports`);
|
|
53
|
+
assert.match(content, /start-work/i, `${label} must explicitly reject start-work ports`);
|
|
54
|
+
assert.match(content, /planning-only|Planning and interview only|planning skill/i, `${label} must stay planning-only`);
|
|
55
|
+
assert.match(content, /\.omx\/plans\/prometheus-strict\//i, `${label} must document the durable prometheus-strict plan path`);
|
|
56
|
+
assert.doesNotMatch(content, /@opencode-ai\/plugin|bun:sqlite|\.sisyphus/i, `${label} must not leak OMO runtime details`);
|
|
57
|
+
}
|
|
58
|
+
for (const section of [
|
|
59
|
+
'Purpose',
|
|
60
|
+
'Use_When',
|
|
61
|
+
'Do_Not_Use_When',
|
|
62
|
+
'Why_This_Exists',
|
|
63
|
+
'Execution_Policy',
|
|
64
|
+
'Turn_Termination_Rules',
|
|
65
|
+
'Steps',
|
|
66
|
+
'Tool_Usage',
|
|
67
|
+
'Final_Checklist',
|
|
68
|
+
'Advanced',
|
|
69
|
+
]) {
|
|
70
|
+
assert.match(skill, new RegExp(`<${section}>`), `skill must include <${section}>`);
|
|
71
|
+
assert.match(skill, new RegExp(`</${section}>`), `skill must close </${section}>`);
|
|
72
|
+
}
|
|
73
|
+
assert.match(skill, /## State Management/, 'skill must include state management section');
|
|
74
|
+
assert.match(skill, /Original task:\n\{\{PROMPT\}\}\s*$/, 'skill must end with the canonical prompt footer');
|
|
75
|
+
});
|
|
76
|
+
it('ships the Metis, Momus, and Oracle prompts with distinct planning contracts', () => {
|
|
77
|
+
assert.ok(existsSync(skillPath), 'prometheus-strict skill must exist');
|
|
78
|
+
for (const promptName of promptNames) {
|
|
79
|
+
const promptPath = join(repoRoot, 'prompts', `${promptName}.md`);
|
|
80
|
+
assert.ok(existsSync(promptPath), `${promptName} prompt must exist`);
|
|
81
|
+
const content = readRepoFile(promptPath);
|
|
82
|
+
assert.match(content, /clean-room/i, `${promptName} must preserve clean-room guidance`);
|
|
83
|
+
assert.match(content, /Do not copy or imitate OMO wording, source, prompts, or runtime behavior/i, `${promptName} must block source copying`);
|
|
84
|
+
assert.match(content, /do not implement code|do not implement|Produce a plan, not implementation/i, `${promptName} must not implement`);
|
|
85
|
+
assert.match(content, /output_contract/i, `${promptName} must define an output contract`);
|
|
86
|
+
for (const section of [
|
|
87
|
+
'identity',
|
|
88
|
+
'goal',
|
|
89
|
+
'constraints',
|
|
90
|
+
'scope_guard',
|
|
91
|
+
'ask_gate',
|
|
92
|
+
'execution_loop',
|
|
93
|
+
'success_criteria',
|
|
94
|
+
'tools',
|
|
95
|
+
'style',
|
|
96
|
+
'output_contract',
|
|
97
|
+
]) {
|
|
98
|
+
assert.match(content, new RegExp(`<${section}>`), `${promptName} must include <${section}>`);
|
|
99
|
+
assert.match(content, new RegExp(`</${section}>`), `${promptName} must close </${section}>`);
|
|
100
|
+
}
|
|
101
|
+
const role = promptRoles[promptName];
|
|
102
|
+
assert.match(content, new RegExp(`OMX:GUIDANCE:${role}:CONSTRAINTS:START`), `${promptName} must include constraints guidance start marker`);
|
|
103
|
+
assert.match(content, new RegExp(`OMX:GUIDANCE:${role}:CONSTRAINTS:END`), `${promptName} must include constraints guidance end marker`);
|
|
104
|
+
assert.match(content, new RegExp(`OMX:GUIDANCE:${role}:OUTPUT:START`), `${promptName} must include output guidance start marker`);
|
|
105
|
+
assert.match(content, new RegExp(`OMX:GUIDANCE:${role}:OUTPUT:END`), `${promptName} must include output guidance end marker`);
|
|
106
|
+
}
|
|
107
|
+
assert.match(readRepoFile(join(repoRoot, 'prompts', 'prometheus-strict-metis.md')), /Metis Clarification/i);
|
|
108
|
+
assert.match(readRepoFile(join(repoRoot, 'prompts', 'prometheus-strict-momus.md')), /Momus Critique/i);
|
|
109
|
+
assert.match(readRepoFile(join(repoRoot, 'prompts', 'prometheus-strict-oracle.md')), /Prometheus Strict Plan/i);
|
|
110
|
+
});
|
|
111
|
+
it('routes interview questions through the OMX structured question surface with documented fallbacks', () => {
|
|
112
|
+
const skill = readRepoFile(skillPath);
|
|
113
|
+
assert.match(skill, /omx question/, 'skill must name `omx question` as the structured question surface');
|
|
114
|
+
assert.match(skill, /native structured input/i, 'skill must document the outside-tmux native structured input fallback');
|
|
115
|
+
assert.match(skill, /plain[-\s]?text|numbered prose/i, 'skill must document the plain-text/numbered-prose last-resort fallback');
|
|
116
|
+
assert.match(skill, /attached[-\s]?tmux/i, 'skill must name the attached-tmux precondition for `omx question`');
|
|
117
|
+
assert.match(skill, /batch[\s\S]{0,80}independent[\s\S]{0,200}questions\[\]/i, 'skill must require batching independent questions into a single questions[] call');
|
|
118
|
+
assert.match(skill, /Codex CLI|non-tmux|piped runs|CI/i, 'skill must call out the non-tmux Codex CLI / piped / CI fallback path');
|
|
119
|
+
for (const promptName of promptNames) {
|
|
120
|
+
const promptPath = join(repoRoot, 'prompts', `${promptName}.md`);
|
|
121
|
+
const content = readRepoFile(promptPath);
|
|
122
|
+
assert.match(content, /omx question/, `${promptName} must reference the OMX structured question surface (omx question)`);
|
|
123
|
+
assert.match(content, /native structured input|plain[-\s]?text|numbered prose/i, `${promptName} must reference at least one documented question fallback`);
|
|
124
|
+
assert.match(content, /batch[\s\S]{0,120}independent|independent[\s\S]{0,80}batch/i, `${promptName} must require batching independent questions through questions[]`);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
it('enforces the Metis background research fan-out contract', () => {
|
|
128
|
+
const metis = readRepoFile(join(repoRoot, 'prompts', 'prometheus-strict-metis.md'));
|
|
129
|
+
assert.match(metis, /<research_fan_out>[\s\S]+<\/research_fan_out>/, 'metis must include a research_fan_out block');
|
|
130
|
+
assert.match(metis, /subagent_type="researcher"/, 'metis research_fan_out must name the researcher subagent');
|
|
131
|
+
assert.match(metis, /subagent_type="explore"/, 'metis research_fan_out must name the explore subagent');
|
|
132
|
+
assert.match(metis, /run_in_background=true/, 'metis research_fan_out must require background dispatch');
|
|
133
|
+
assert.match(metis, /Max\s*\*\*2 explore \+ 4 researcher\*\*/, 'metis research_fan_out must cap the parallel budget at 2 explore + 4 researcher');
|
|
134
|
+
for (const marker of ['\\[CONTEXT\\]', '\\[GOAL\\]', '\\[DOWNSTREAM\\]', '\\[REQUEST\\]']) {
|
|
135
|
+
assert.match(metis, new RegExp(marker), `metis research_fan_out must require the ${marker.replace(/\\\[|\\\]/g, '')} prompt section`);
|
|
136
|
+
}
|
|
137
|
+
assert.match(metis, /gpt-5\.4-mini[\s\S]{0,120}researcher/i, 'metis research_fan_out must document researcher as the exact cheap mini lane');
|
|
138
|
+
assert.match(metis, /official docs[\s\S]{0,120}release notes\/changelog[\s\S]{0,160}OSS reference implementations[\s\S]{0,120}pitfalls\/migration notes/i, 'metis research_fan_out must split multiple researcher requests by evidence lane');
|
|
139
|
+
assert.match(metis, /Wait for every dispatched agent to complete/i, 'metis research_fan_out must block on agent completion before generating questions');
|
|
140
|
+
assert.match(metis, /Re-run `<spec_prefill>`/i, 'metis research_fan_out must feed results back into spec_prefill');
|
|
141
|
+
assert.match(metis, /trivial[\s\S]{0,40}skip fan-out/i, 'metis research_fan_out must skip for trivial intent');
|
|
142
|
+
assert.match(metis, /research[\s\S]{0,120}(?:minimum|REQUIRES)[\s\S]{0,80}2 researcher/i, 'metis research_fan_out must require at least 2 researcher lanes for research intent');
|
|
143
|
+
assert.match(metis, /STRONGLY PREFER/i, 'metis research_fan_out must STRONGLY PREFER for build-from-scratch and architecture intents');
|
|
144
|
+
assert.match(metis, /3\.\s*\*\*Run\s*`<research_fan_out>`\*\*[\s\S]{0,260}budget 2 explore \+ 4 researcher max/i, 'metis execution_loop must invoke research_fan_out as step 3 with the 2 explore + 4 researcher budget');
|
|
145
|
+
assert.doesNotMatch(metis, /2 \+ 2 max|2 explore \+ 2 researcher/i, 'metis must not retain stale 2+2 fan-out budget wording');
|
|
146
|
+
});
|
|
147
|
+
it('researcher subagent referenced by Metis fan-out absorbs OMO librarian-shape capability', () => {
|
|
148
|
+
const researcher = readRepoFile(join(repoRoot, 'prompts', 'researcher.md'));
|
|
149
|
+
const metis = readRepoFile(join(repoRoot, 'prompts', 'prometheus-strict-metis.md'));
|
|
150
|
+
assert.match(researcher, /<repo_research>[\s\S]+<\/repo_research>/, 'researcher must declare a <repo_research> block to back metis cross-repo OSS lookups');
|
|
151
|
+
assert.match(researcher, /gh search code/i, 'researcher must enumerate gh search code for cross-repo OSS discovery');
|
|
152
|
+
assert.match(researcher, /raw\.githubusercontent\.com|gh api repos\/<org>\/<repo>/i, 'researcher must allow pinned-SHA OSS file fetches');
|
|
153
|
+
assert.match(researcher, /Context7 MCP/i, 'researcher must reference Context7 MCP with a graceful web fallback');
|
|
154
|
+
assert.match(researcher, /org\/repo@sha:path/i, 'researcher must specify the org/repo@sha:path:line citation format');
|
|
155
|
+
assert.match(researcher, /OSS Reference Implementations/, 'researcher output_contract must include the OSS Reference Implementations section');
|
|
156
|
+
assert.match(metis, /org\/repo@sha:file:line/, 'metis research_fan_out must declare the org/repo@sha:file:line citation form, coupling researcher OSS contract to prometheus fan-out');
|
|
157
|
+
});
|
|
158
|
+
it('enforces the Metis intent-classification, spec-prefill, self-review, and stale-rule cleanup contract', () => {
|
|
159
|
+
const metis = readRepoFile(join(repoRoot, 'prompts', 'prometheus-strict-metis.md'));
|
|
160
|
+
assert.match(metis, /<intent_classification>[\s\S]+<\/intent_classification>/, 'metis must include an intent_classification block');
|
|
161
|
+
for (const family of ['trivial', 'simple', 'refactor', 'build-from-scratch', 'research', 'spec-driven', 'test-infra', 'architecture', 'collaboration']) {
|
|
162
|
+
assert.match(metis, new RegExp(`\\*\\*${family.replace('-', '[-\\s]')}\\*\\*`, 'i'), `metis intent_classification must declare the ${family} family`);
|
|
163
|
+
}
|
|
164
|
+
assert.match(metis, /No interview at all|skip the interview entirely/i, 'metis must explicitly skip the interview for trivial tasks');
|
|
165
|
+
assert.match(metis, /at most 1-2|1-2 targeted questions/i, 'metis must cap simple-intent interviews at 1-2 questions');
|
|
166
|
+
assert.match(metis, /<spec_prefill>[\s\S]+<\/spec_prefill>/, 'metis must include a spec_prefill block');
|
|
167
|
+
for (const signal of ['PRD', 'RFC', 'issue', 'package\\.json', 'Cargo\\.toml']) {
|
|
168
|
+
assert.match(metis, new RegExp(signal, 'i'), `metis spec_prefill must recognise ${signal} as a spec signal`);
|
|
169
|
+
}
|
|
170
|
+
assert.match(metis, /docs\/specs|docs\/rfcs/, 'metis spec_prefill must mention the canonical repo-local spec directories');
|
|
171
|
+
assert.match(metis, /<self_review>[\s\S]+<\/self_review>/, 'metis must include a self_review block');
|
|
172
|
+
assert.match(metis, /seven gates of <question_quality>|all seven gates/i, 'metis self_review must re-check the seven question_quality gates');
|
|
173
|
+
assert.match(metis, /Self-review is a hard prerequisite/i, 'metis self_review must declare itself a hard prerequisite for emitting a round');
|
|
174
|
+
assert.doesNotMatch(metis, /Blocking questions are limited to one at a time/i, 'metis success_criteria must drop the stale single-question rule that contradicted the batch + multi-round contract');
|
|
175
|
+
assert.match(metis, /Intent family is declared and the round's question slate matches that family/i, 'metis success_criteria must reflect the intent-classification gate');
|
|
176
|
+
assert.match(metis, /never by subjective[\s\S]{0,30}feels enough/i, 'metis success_criteria must explicitly reject subjective termination');
|
|
177
|
+
});
|
|
178
|
+
it('removes the three concrete over-asking contradictions observed in the 2026-05-22 prometheus-strict trace', () => {
|
|
179
|
+
const metis = readRepoFile(join(repoRoot, 'prompts', 'prometheus-strict-metis.md'));
|
|
180
|
+
assert.match(metis, /<tools>[\s\S]*?subagent_type[\s\S]*?<\/tools>/, 'metis <tools> block must explicitly grant task(subagent_type=...) dispatch permission so the research_fan_out block is reachable');
|
|
181
|
+
assert.match(metis, /<tools>[\s\S]*?(?:explore|researcher)[\s\S]*?<\/tools>/i, 'metis <tools> block must enumerate the explore/researcher subagent dispatch path');
|
|
182
|
+
assert.doesNotMatch(metis, /###\s*Open Question[\s\S]{0,80}Ask one question only/i, 'metis <output_contract> must drop the stale "Ask one question only" line that contradicted the batch + multi-round ask_gate');
|
|
183
|
+
assert.match(metis, /###\s*Questions Emitted This Round|Questions This Round|Round Questions|0\s*-\s*N questions|zero or more questions/i, 'metis <output_contract> must replace the single-question section with a multi-question round section');
|
|
184
|
+
assert.match(metis, /vague[\s\S]{0,60}verb|short[\s\S]{0,40}ambiguous|under[\s\S]{0,20}\d+\s*words/i, 'metis <intent_classification> must declare an anti-over-classification rule for short/vague task inputs');
|
|
185
|
+
assert.match(metis, /(?:improve|develop|fix it|디벨롭|디베롭|개선)[\s\S]{0,200}(?:simple|trivial|explore first)/i, 'metis <intent_classification> must call out vague Korean/English verbs and route them to simple/trivial or explore-first');
|
|
186
|
+
assert.match(metis, /(?:explicit[\s\S]{0,20}(?:new feature|from scratch|greenfield)|name a new module|require[\s\S]{0,40}explicit)/i, 'metis <intent_classification> must require explicit greenfield keywords before classifying as build-from-scratch');
|
|
187
|
+
});
|
|
188
|
+
it('enforces checklist clearance and turn termination quality gates', () => {
|
|
189
|
+
const skill = readRepoFile(skillPath);
|
|
190
|
+
const metis = readRepoFile(join(repoRoot, 'prompts', 'prometheus-strict-metis.md'));
|
|
191
|
+
const momus = readRepoFile(join(repoRoot, 'prompts', 'prometheus-strict-momus.md'));
|
|
192
|
+
const oracle = readRepoFile(join(repoRoot, 'prompts', 'prometheus-strict-oracle.md'));
|
|
193
|
+
assert.match(skill, /<Turn_Termination_Rules>[\s\S]+<\/Turn_Termination_Rules>/, 'skill must include turn termination block');
|
|
194
|
+
assert.match(skill, /EXACTLY ONE of/i, 'termination must choose exactly one path');
|
|
195
|
+
assert.match(skill, /\(a\)[\s\S]{0,120}omx question[\s\S]{0,80}batch/i, 'option a must name omx question batch');
|
|
196
|
+
assert.match(skill, /\(b\)[\s\S]{0,120}explicit handoff/i, 'option b must name explicit handoff');
|
|
197
|
+
assert.match(skill, /\(c\)[\s\S]{0,120}stop-blocker/i, 'option c must name stop-blocker');
|
|
198
|
+
assert.doesNotMatch(skill, /answered_high_leverage_question_count\s*>=\s*3/i, 'count rule removed from skill');
|
|
199
|
+
assert.doesNotMatch(metis, /answered_high_leverage_question_count\s*>=\s*3/i, 'count rule removed from metis');
|
|
200
|
+
assert.match(metis, /6[- ]item checklist|six[- ]item checklist/i, 'metis must name 6-item checklist');
|
|
201
|
+
assert.match(metis, /objective[\s\S]{0,300}scope IN\+OUT[\s\S]{0,300}acceptance[\s\S]{0,300}test strategy[\s\S]{0,300}handoff target[\s\S]{0,300}no outstanding CRITICAL/i, 'metis must list checklist items in order');
|
|
202
|
+
assert.match(metis, /ALL[\s\S]{0,120}YES[\s\S]{0,180}ANY[\s\S]{0,120}(?:NO|UNKNOWN)[\s\S]{0,180}(?:ask|question)/i, 'metis must lock YES/NO transition');
|
|
203
|
+
assert.match(metis, /two-pass gap-fill minimum|two gap-fill passes|BOTH gap-fill passes/i, 'metis must require at least two gap-fill passes after answers before handoff or another question');
|
|
204
|
+
assert.match(metis, /Pass 1[\s\S]{0,120}answer assimilation[\s\S]{0,240}Pass 2[\s\S]{0,160}residual adversarial scan/i, 'metis must name gap-fill Pass 1 and Pass 2 responsibilities');
|
|
205
|
+
assert.match(metis, /do not hand off after only one gap-fill pass|mandatory even when Pass 1 appears/i, 'metis must forbid single-pass handoff after receiving answers');
|
|
206
|
+
assert.match(metis, /minimum two emitted question rounds|two emitted rounds|Round 2 has been emitted and processed/i, 'metis must forbid one-round handoff when any user-question round was emitted');
|
|
207
|
+
assert.match(metis, /zero-question(?:s)?[- ]but[- ]complete|zero-question handoff|no questions were emitted[\s\S]{0,160}(?:handoff|allowed|option \(b\))/i, 'metis must preserve zero-question handoff for trivial/spec-complete cases');
|
|
208
|
+
assert.match(metis, /Between Round 1 and Round 2|between-round planning[\s\S]{0,260}(?:research_fan_out|researcher|explore)/i, 'metis must require researcher/explore-assisted planning between emitted rounds');
|
|
209
|
+
assert.match(metis, /Round 2[\s\S]{0,220}residual CRITICAL|residual CRITICAL[\s\S]{0,220}Round 2/i, 'metis Round 2 must be limited to residual CRITICAL gaps, not filler');
|
|
210
|
+
assert.match(skill, /minimum two emitted question rounds|two emitted rounds|Round 2 has been emitted and processed/i, 'skill must expose the minimum two emitted rounds contract');
|
|
211
|
+
assert.match(skill, /between-round planning[\s\S]{0,240}(?:research_fan_out|researcher|explore)/i, 'skill must expose researcher-assisted between-round planning');
|
|
212
|
+
assert.match(skill, /at least \*\*two gap-fill passes\*\*|BOTH gap-fill passes/i, 'skill must expose the mandatory two-pass gap-fill contract');
|
|
213
|
+
assert.match(metis, /Plan-A[\s\S]{0,200}Plan-B[\s\S]{0,240}(?:identical|same)[\s\S]{0,120}(?:DROP|absorb)/i, 'metis must drop identical Plan-A Plan-B');
|
|
214
|
+
assert.match(metis, /WHEN IN DOUBT|DO NOT ask unless[\s\S]{0,120}structurally different plans/i, 'metis must default to absorb');
|
|
215
|
+
assert.match(metis, /MUST[\s\S]{0,80}absorbed[\s\S]{0,80}(?:exceed|>=|≥)/i, 'metis absorbed ratio must be MUST');
|
|
216
|
+
assert.match(`${skill}
|
|
217
|
+
${metis}`, /USER_ANSWERED[\s\S]+ABSORBED_WITH_CITATION[\s\S]+INFERRED_FROM_SPEC/, 'tri-state checklist YES must be named');
|
|
218
|
+
assert.match(`${momus}
|
|
219
|
+
${oracle}`, /Default-absorb prior[\s\S]+Plan-A-vs-Plan-B[\s\S]+scope boundary[\s\S]+acceptance criterion[\s\S]+rollback contract[\s\S]+lane assignment[\s\S]+handoff target/i, 'momus and oracle must share default absorb prior');
|
|
220
|
+
});
|
|
221
|
+
it('imports the OMO Prometheus judge-absorption pattern: gap triage, silent absorption, and single-decision test-strategy', () => {
|
|
222
|
+
const metis = readRepoFile(join(repoRoot, 'prompts', 'prometheus-strict-metis.md'));
|
|
223
|
+
assert.match(metis, /<gap_triage>[\s\S]+<\/gap_triage>|gap[\s\S]{0,40}triage|CRITICAL[\s\S]{0,200}MINOR[\s\S]{0,200}AMBIGUOUS/i, 'metis must declare a gap-triage classification (CRITICAL / MINOR / AMBIGUOUS) for self_review');
|
|
224
|
+
assert.match(metis, /CRITICAL[\s\S]{0,300}(?:emit|ask|user question|surfaces)/i, 'metis gap triage must route CRITICAL gaps to the user question slate');
|
|
225
|
+
assert.match(metis, /MINOR[\s\S]{0,300}(?:self[-\s]?(?:fix|resolve|absorb)|stated assumption|safe assumption|continue)/i, 'metis gap triage must route MINOR gaps to a stated assumption and continue, NOT to a user question');
|
|
226
|
+
assert.match(metis, /AMBIGUOUS[\s\S]{0,300}(?:default|safe default|industry default|conservative default)/i, 'metis gap triage must route AMBIGUOUS gaps to a default with explicit annotation');
|
|
227
|
+
assert.match(metis, /<silent_absorption>[\s\S]+<\/silent_absorption>|silent[\s\S]{0,30}absorption|do not ask additional/i, 'metis must declare a silent-absorption rule: low-leverage gaps must be answered by Metis itself, not emitted as user questions');
|
|
228
|
+
assert.match(metis, /(?:repo[\s\S]{0,30}context|prior turn|industry default|sensible default)[\s\S]{0,400}(?:assumption|continue|absorb)/i, 'metis silent_absorption must list the inference sources (repo context, prior turns, industry defaults) that replace user questions');
|
|
229
|
+
assert.match(metis, /(?:single (?:bundled|combined|consolidated) test[\s-]?strategy|one test[\s-]?strategy decision|test[\s-]?infra[\s\S]{0,80}single decision)/i, 'metis intent_classification for build/refactor/test-infra must consolidate test strategy into a single bundled decision instead of three separate questions');
|
|
230
|
+
assert.match(metis, /(?:TDD|test[\s-]?first)[\s\S]{0,300}(?:after[\s-]?implementation|post[\s-]?implementation|agent[\s-]?QA|none)/i, 'metis test-strategy decision must offer the canonical option set (TDD / test-after-implementation / agent-QA only / no automated tests)');
|
|
231
|
+
});
|
|
232
|
+
it('fan-out defaults to ON for non-trivial intents with per-intent mandatory minimums, matching OMO interview-mode-by-default', () => {
|
|
233
|
+
const metis = readRepoFile(join(repoRoot, 'prompts', 'prometheus-strict-metis.md'));
|
|
234
|
+
assert.match(metis, /(?:default[\s-]?on|interview[\s-]?mode[\s-]?by[\s-]?default|Before (?:your |the )?first question|fan[\s-]?out is the default)/i, 'metis research_fan_out must declare default-on dispatch (OMO interview-mode-by-default), not trigger-conditional');
|
|
235
|
+
assert.match(metis, /(?:per[\s-]?intent mandatory minimum|mandatory minimum dispatch|minimum per[\s-]?intent)/i, 'metis must declare per-intent mandatory minimum dispatch counts');
|
|
236
|
+
assert.match(metis, /refactor[\s\S]{0,200}(?:1[\s\S]{0,10}explore|>=\s*1\s*explore|min(?:imum)?[\s\S]{0,20}1\s*explore)/i, 'metis must require minimum 1 explore for refactor intent (preservation surface map)');
|
|
237
|
+
assert.match(metis, /build[\s-]?from[\s-]?scratch[\s\S]{0,240}1[\s\S]{0,10}explore[\s\S]{0,120}2[\s\S]{0,10}researcher/i, 'metis must require minimum 1 explore + 2 researcher for build-from-scratch');
|
|
238
|
+
assert.match(metis, /architecture[\s\S]{0,240}1[\s\S]{0,10}explore[\s\S]{0,120}2[\s\S]{0,10}researcher/i, 'metis must require minimum 1 explore + 2 researcher for architecture');
|
|
239
|
+
assert.match(metis, /test[\s-]?infra[\s\S]{0,240}1[\s\S]{0,10}explore[\s\S]{0,120}2[\s\S]{0,10}researcher/i, 'metis must require minimum 1 explore + 2 researcher for test-infra');
|
|
240
|
+
assert.match(metis, /(?:skip[\s\S]{0,30}only when|skip[\s-]?out rule|skip rule)[\s\S]{0,300}trivial/i, 'metis must declare skip-out rules (trivial is the only universal skip)');
|
|
241
|
+
assert.doesNotMatch(metis, /when triggers fire/i, 'metis must not preserve trigger-conditional fan-out wording; non-trivial planning dispatch is default-on');
|
|
242
|
+
assert.doesNotMatch(metis, /simple` intent -> fan-out only when one specific signal is unfamiliar/i, 'simple intent must still run the baseline explore fan-out instead of skipping until unfamiliarity is detected');
|
|
243
|
+
assert.match(metis, /simple` intent -> keep the mandatory baseline at exactly 1 `explore` agent/i, 'simple intent must keep one mandatory explore baseline before user questions');
|
|
244
|
+
assert.match(readRepoFile(skillPath), /gpt-5\.4-mini[\s\S]{0,160}researcher[\s\S]{0,220}2 explore \+ 4 researcher/i, 'skill must expose exact mini researcher plus wider cheap fan-out');
|
|
245
|
+
});
|
|
246
|
+
it('detects user hostility or non-answer responses and exits the interview instead of incrementing the clearance count', () => {
|
|
247
|
+
const metis = readRepoFile(join(repoRoot, 'prompts', 'prometheus-strict-metis.md'));
|
|
248
|
+
const skill = readRepoFile(skillPath);
|
|
249
|
+
assert.match(metis, /<hostility_detection>[\s\S]+<\/hostility_detection>|hostil[\s\S]{0,40}detection|non[\s-]?answer[\s\S]{0,40}detection/i, 'metis must declare a hostility / non-answer detection block to exit the interview cleanly instead of consuming clearance budget');
|
|
250
|
+
assert.match(metis, /(?:1[\s\-]?2 char|single character|one[\s-]?character|trivially short)[\s\S]{0,300}(?:answer|response|reply)/i, 'metis hostility detection must flag 1-2 character / trivially short responses as non-answers');
|
|
251
|
+
assert.match(metis, /(?:알아서|figure it out|you decide|whatever)[\s\S]{0,200}(?:non[\s-]?answer|refusal|hostil|exit|escalate)/i, 'metis hostility detection must recognise dismissive "you decide / figure it out / 알아서" patterns as non-answers');
|
|
252
|
+
assert.match(metis, /(?:profanit|시발|fuck|swear|insult|f-word)[\s\S]{0,200}(?:non[\s-]?answer|refusal|hostil|exit|escalate)/i, 'metis hostility detection must recognise profanity-laden responses as hostility signals');
|
|
253
|
+
assert.match(metis, /(?:exit|terminate|abort|stop)[\s\S]{0,200}(?:interview|loop|round)/i, 'metis hostility detection must exit the interview loop, not continue asking');
|
|
254
|
+
assert.match(metis, /(?:escalate|hand off|return control|surface the [hH]ostility)[\s\S]{0,300}(?:user|caller|Oracle|carry[-\s]?forward)/i, 'metis hostility detection must escalate the unresolved decision back to the user or carry it forward, not silently swallow it');
|
|
255
|
+
assert.match(metis, /(?:do not increment|must not increment|does not count|invalidates? the (?:round|answer)|do NOT advance[\s\S]{0,80}checklist item)/i, 'metis hostile responses must not advance checklist YES');
|
|
256
|
+
assert.match(skill, /(?:hostil|non[\s-]?answer|user (?:refus|reject|abort))[\s\S]{0,300}(?:exit|escalate|terminate|invalidate)/i, 'skill Rule-Based Clearance section must reflect the hostility exit path so the user sees the rule at the workflow level');
|
|
257
|
+
});
|
|
258
|
+
it('enforces the strengthened operator contract: iterative interview, rule-clearance, post-plan Metis, Momus bounded retry, and Oracle 2-pass', () => {
|
|
259
|
+
const skill = readRepoFile(skillPath);
|
|
260
|
+
const metis = readRepoFile(join(repoRoot, 'prompts', 'prometheus-strict-metis.md'));
|
|
261
|
+
const momus = readRepoFile(join(repoRoot, 'prompts', 'prometheus-strict-momus.md'));
|
|
262
|
+
const oracle = readRepoFile(join(repoRoot, 'prompts', 'prometheus-strict-oracle.md'));
|
|
263
|
+
assert.match(skill, /pre-question research fan-out[\s\S]{0,300}non-trivial intent[\s\S]{0,300}`explore`[\s\S]{0,120}`researcher`/i, 'skill must make active explore/researcher fan-out a planning-stage contract before user questions');
|
|
264
|
+
// Gate 1: Metis interview is iterative with multiple rounds capped at 5
|
|
265
|
+
assert.match(skill, /Iterative|iterative loop|multiple interview rounds|interview rounds ARE expected/i, 'skill Steps §2 must declare an iterative Metis interview');
|
|
266
|
+
assert.match(skill, /5 rounds|cap[\s\S]{0,40}5|round 5/i, 'skill must cap Metis interview rounds at 5');
|
|
267
|
+
assert.match(metis, /multiple interview rounds|Run multiple interview rounds|next round/i, 'metis prompt must declare multi-round operation');
|
|
268
|
+
assert.match(metis, /5 rounds|round[s]?[\s\S]{0,20}cap|cap[\s\S]{0,40}5/i, 'metis prompt must cap rounds at 5');
|
|
269
|
+
// Gate 2: Rule-based clearance is deterministic, not subjective
|
|
270
|
+
const clearanceRule = /6[- ]item checklist[\s\S]{0,800}objective[\s\S]{0,800}scope IN\+OUT[\s\S]{0,800}acceptance[\s\S]{0,800}test strategy[\s\S]{0,800}handoff target[\s\S]{0,800}no outstanding CRITICAL/i;
|
|
271
|
+
assert.match(skill, clearanceRule, 'skill must declare the 6-item checklist clearance gate');
|
|
272
|
+
assert.match(metis, clearanceRule, 'metis prompt must declare the 6-item checklist gate');
|
|
273
|
+
// Gate 3: Post-plan Metis gap check before handoff
|
|
274
|
+
assert.match(skill, /Post-Plan Gap Check|post-plan Metis gap check|Metis Re-Invocation|post-plan re-invocation/i, 'skill must include a post-plan Metis gap check before handoff');
|
|
275
|
+
assert.match(metis, /post-plan re-invocation|Post-plan re-invocation|post-plan gap check|finalized plan|finalized Oracle plan/i, 'metis prompt must document its post-plan re-invocation mode');
|
|
276
|
+
// Gate 4: Momus bounded retry after Oracle synthesis, capped at 3 cycles
|
|
277
|
+
assert.match(skill, /Bounded Retry|bounded retry|Momus\s*→\s*Oracle re-synthesis|3 (times|cycles)/i, 'skill Steps §3 must declare a bounded Momus retry contract');
|
|
278
|
+
assert.match(skill, /3 (times|cycles) total|up to[\s\S]{0,30}3 times|cycles at[\s\S]{0,10}3/i, 'skill must cap Momus → Oracle re-synthesis at 3 cycles');
|
|
279
|
+
assert.match(momus, /bounded[-\s]?retry|re-invocation after Oracle synthesis|Oracle's resolutions did not introduce new risks/i, 'momus prompt must declare the bounded-retry re-invocation contract');
|
|
280
|
+
assert.match(momus, /3 (times|cycles)|cycle 3/i, 'momus prompt must cap retry cycles at 3');
|
|
281
|
+
// Gate 5: Oracle 2-pass (synthesis + self-verification) with 3-cycle cap
|
|
282
|
+
assert.match(skill, /Two-?Pass|Pass 1[\s\S]{0,30}Synthesis[\s\S]{0,500}Pass 2/i, 'skill Steps §4 must declare an Oracle 2-pass (synthesis + self-verification) loop');
|
|
283
|
+
assert.match(skill, /Self-?Verification|self-verification|machine-checkable acceptance contract/i, 'skill must name Oracle Pass 2 as machine-checkable self-verification');
|
|
284
|
+
assert.match(skill, /Pass 1[\s\S]{0,20}↔[\s\S]{0,20}Pass 2[\s\S]{0,80}3|cycles? at[\s\S]{0,10}3/i, 'skill must cap Pass 1 ↔ Pass 2 cycles at 3');
|
|
285
|
+
assert.match(oracle, /Pass 1[\s\S]{0,30}Synthesis[\s\S]{0,800}Pass 2[\s\S]{0,80}Self-?Verification/i, 'oracle prompt must split execution into Pass 1 (Synthesis) and Pass 2 (Self-Verification)');
|
|
286
|
+
assert.match(oracle, /machine-checkable acceptance contract/i, 'oracle prompt must label Pass 2 as the machine-checkable acceptance contract');
|
|
287
|
+
assert.match(oracle, /verification matrix has an explicit evidence source/i, 'oracle Pass 2 must require explicit evidence sources for every verification-matrix claim');
|
|
288
|
+
assert.match(oracle, /shared-file conflicts between parallel lanes/i, 'oracle Pass 2 must guard against shared-file conflicts between parallel lanes');
|
|
289
|
+
assert.match(oracle, /mutually consistent|acceptance criterion is satisfied by a state that also triggers rollback/i, 'oracle Pass 2 must require stop/rollback/acceptance mutual consistency');
|
|
290
|
+
assert.match(oracle, /cap[\s\S]{0,40}3|cycles? at[\s\S]{0,10}3/i, 'oracle prompt must cap Pass 1 ↔ Pass 2 cycles at 3');
|
|
291
|
+
// Gate 6: Final_Checklist reflects the strengthened gates
|
|
292
|
+
assert.match(skill, /checklist clearance/i, 'Final_Checklist must reference checklist clearance');
|
|
293
|
+
assert.match(skill, /Oracle Pass 2 self-verification/i, 'Final_Checklist must reference Oracle Pass 2 self-verification');
|
|
294
|
+
assert.match(skill, /Post-plan Metis gap check/i, 'Final_Checklist must reference the post-plan Metis gap check');
|
|
295
|
+
});
|
|
296
|
+
it('pins the public docs entry for the skill handoff path', () => {
|
|
297
|
+
assert.ok(existsSync(skillPath), 'prometheus-strict skill must exist');
|
|
298
|
+
const docs = readRepoFile(join(repoRoot, 'docs', 'skills.html'));
|
|
299
|
+
assert.match(docs, /\$prometheus-strict/i, 'docs must advertise the explicit prometheus-strict skill token');
|
|
300
|
+
assert.match(docs, /Metis/i, 'docs must mention the Metis role');
|
|
301
|
+
assert.match(docs, /Momus/i, 'docs must mention the Momus role');
|
|
302
|
+
assert.match(docs, /Oracle/i, 'docs must mention the Oracle role');
|
|
303
|
+
assert.match(docs, /\$ultragoal/i, 'docs must preserve the OMX-native ultragoal handoff');
|
|
304
|
+
assert.match(docs, /\.omx\/plans\/prometheus-strict\//i, 'docs must preserve the durable plan artifact path');
|
|
305
|
+
assert.match(docs, /Inspired by OMO Prometheus[\s\S]*code-yeongyu\/oh-my-openagent[\s\S]*reimplemented from concept under MIT/i, 'docs must preserve clean-room concept credit');
|
|
306
|
+
});
|
|
307
|
+
it('wires catalog, agent definitions, and explicit keyword activation', () => {
|
|
308
|
+
assert.ok(existsSync(skillPath), 'prometheus-strict skill must exist');
|
|
309
|
+
const manifest = JSON.parse(readRepoFile(join(repoRoot, 'src', 'catalog', 'manifest.json')));
|
|
310
|
+
assert.ok(manifest.skills.some((skill) => skill.name === 'prometheus-strict' && skill.status === 'active' && skill.category === 'planning'), 'catalog manifest must expose prometheus-strict as an active planning skill');
|
|
311
|
+
for (const promptName of promptNames) {
|
|
312
|
+
assert.ok(manifest.agents.some((agent) => agent.name === promptName && agent.status === 'active'), `catalog manifest must expose ${promptName}`);
|
|
313
|
+
assert.ok(AGENT_DEFINITIONS[promptName], `agent definition must include ${promptName}`);
|
|
314
|
+
assert.equal(AGENT_DEFINITIONS[promptName]?.tools, 'analysis', `${promptName} should stay in planning/analysis mode`);
|
|
315
|
+
}
|
|
316
|
+
const prometheusTriggers = KEYWORD_TRIGGER_DEFINITIONS.filter((entry) => entry.skill === 'prometheus-strict');
|
|
317
|
+
assert.deepEqual(prometheusTriggers.map((entry) => entry.keyword), ['$prometheus-strict'], 'prometheus-strict should be explicit-only to avoid accidental concept-word routing');
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
//# sourceMappingURL=prometheus-strict-contract.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prometheus-strict-contract.test.js","sourceRoot":"","sources":["../../../src/hooks/__tests__/prometheus-strict-contract.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -28,6 +28,18 @@ describe('prompt guidance wave two contract', () => {
|
|
|
28
28
|
assert.match(researcher, /Current best-practice research/i);
|
|
29
29
|
assert.match(researcher, /official\/upstream recommendations/i);
|
|
30
30
|
});
|
|
31
|
+
it('researcher exposes cross-repo OSS research capability with structured citation format', () => {
|
|
32
|
+
const researcher = loadSurface('prompts/researcher.md');
|
|
33
|
+
assert.match(researcher, /<repo_research>[\s\S]+<\/repo_research>/, 'researcher must declare an explicit <repo_research> block for OSS evidence');
|
|
34
|
+
assert.match(researcher, /gh search code/i, 'researcher must enumerate gh search code for cross-repo OSS discovery');
|
|
35
|
+
assert.match(researcher, /raw\.githubusercontent\.com|gh api repos\/<org>\/<repo>/i, 'researcher must allow pinned-SHA OSS file fetches via gh api or raw.githubusercontent.com');
|
|
36
|
+
assert.match(researcher, /Context7 MCP/i, 'researcher must reference Context7 MCP with a graceful web fallback');
|
|
37
|
+
assert.match(researcher, /org\/repo@sha:path/i, 'researcher must specify the org/repo@sha:path:line citation format');
|
|
38
|
+
assert.match(researcher, /OSS Reference Implementations/, 'researcher output_contract must include the OSS Reference Implementations section');
|
|
39
|
+
assert.match(researcher, /Never (?:use|cite)[\s\S]{0,30}HEAD|moving branch reference/i, 'researcher must forbid moving-branch citations in OSS evidence');
|
|
40
|
+
assert.match(researcher, /already chosen technology/i, 'researcher must keep the already-chosen-technology scope guard');
|
|
41
|
+
assert.match(researcher, /local repo usage[\s\S]{0,30}`explore`/i, 'researcher must explicitly route local-repo inspection to explore while keeping external OSS repos in scope');
|
|
42
|
+
});
|
|
31
43
|
it('research specialists keep explicit output-contract fixtures for source preference and boundary discipline', () => {
|
|
32
44
|
const researcher = loadSurface('prompts/researcher.md');
|
|
33
45
|
const dependencyExpert = loadSurface('prompts/dependency-expert.md');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-guidance-wave-two.test.js","sourceRoot":"","sources":["../../../src/hooks/__tests__/prompt-guidance-wave-two.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"prompt-guidance-wave-two.test.js","sourceRoot":"","sources":["../../../src/hooks/__tests__/prompt-guidance-wave-two.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"research-workflow-boundaries.test.d.ts","sourceRoot":"","sources":["../../../src/hooks/__tests__/research-workflow-boundaries.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { describe, it } from 'node:test';
|
|
5
|
+
const root = process.cwd();
|
|
6
|
+
function read(path) {
|
|
7
|
+
return readFileSync(join(root, path), 'utf-8');
|
|
8
|
+
}
|
|
9
|
+
describe('research workflow boundary guidance', () => {
|
|
10
|
+
it('keeps best-practice research positioned as pre-planning evidence, not architecture', () => {
|
|
11
|
+
const skill = read('skills/best-practice-research/SKILL.md');
|
|
12
|
+
assert.match(skill, /ordinary first research wrapper/i);
|
|
13
|
+
assert.match(skill, /hand it to `\$ralplan` or the caller as planning input/i);
|
|
14
|
+
assert.match(skill, /Do not present `\$best-practice-research` as a final architecture component/i);
|
|
15
|
+
});
|
|
16
|
+
it('keeps autoresearch scoped to validator-gated deliverables feeding ralplan evidence', () => {
|
|
17
|
+
const skill = read('skills/autoresearch/SKILL.md');
|
|
18
|
+
assert.match(skill, /bounded deliverable that must pass an explicit validator/i);
|
|
19
|
+
assert.match(skill, /Do not recommend it for ordinary pre-planning docs lookup/i);
|
|
20
|
+
assert.match(skill, /approved artifact should feed evidence into `\$ralplan`/i);
|
|
21
|
+
assert.match(skill, /should not become a final architecture\/component unless the user explicitly asks/i);
|
|
22
|
+
});
|
|
23
|
+
it('keeps autoresearch-goal limited to goal-mode research missions', () => {
|
|
24
|
+
const skill = read('skills/autoresearch-goal/SKILL.md');
|
|
25
|
+
assert.match(skill, /Codex goal-mode management plus professor\/critic-style validation/i);
|
|
26
|
+
assert.match(skill, /not the default answer for ordinary pre-planning best-practice lookup/i);
|
|
27
|
+
});
|
|
28
|
+
it('requires ralplan to synthesize prior research instead of embedding research automation by default', () => {
|
|
29
|
+
const skill = read('skills/ralplan/SKILL.md');
|
|
30
|
+
assert.match(skill, /treat its approved artifact as evidence for the plan/i);
|
|
31
|
+
assert.match(skill, /Do not include Autoresearch as a final architecture or runtime component/i);
|
|
32
|
+
assert.match(skill, /synthesize the evidence into the `\$ralplan` ADR, risks, and verification steps/i);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=research-workflow-boundaries.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"research-workflow-boundaries.test.js","sourceRoot":"","sources":["../../../src/hooks/__tests__/research-workflow-boundaries.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AAE3B,SAAS,IAAI,CAAC,IAAY;IACxB,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC;AAED,QAAQ,CAAC,qCAAqC,EAAE,GAAG,EAAE;IACnD,EAAE,CAAC,oFAAoF,EAAE,GAAG,EAAE;QAC5F,MAAM,KAAK,GAAG,IAAI,CAAC,wCAAwC,CAAC,CAAC;QAC7D,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,kCAAkC,CAAC,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,yDAAyD,CAAC,CAAC;QAC/E,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,8EAA8E,CAAC,CAAC;IACtG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oFAAoF,EAAE,GAAG,EAAE;QAC5F,MAAM,KAAK,GAAG,IAAI,CAAC,8BAA8B,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,2DAA2D,CAAC,CAAC;QACjF,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,4DAA4D,CAAC,CAAC;QAClF,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,0DAA0D,CAAC,CAAC;QAChF,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,oFAAoF,CAAC,CAAC;IAC5G,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,MAAM,KAAK,GAAG,IAAI,CAAC,mCAAmC,CAAC,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,qEAAqE,CAAC,CAAC;QAC3F,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,wEAAwE,CAAC,CAAC;IAChG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mGAAmG,EAAE,GAAG,EAAE;QAC3G,MAAM,KAAK,GAAG,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,uDAAuD,CAAC,CAAC;QAC7E,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,2EAA2E,CAAC,CAAC;QACjG,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,kFAAkF,CAAC,CAAC;IAC1G,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -17,7 +17,7 @@ export interface KeywordMatch {
|
|
|
17
17
|
skill: string;
|
|
18
18
|
priority: number;
|
|
19
19
|
}
|
|
20
|
-
export type SkillActivePhase = 'planning' | 'executing' | 'reviewing' | 'completing' | 'ralplan';
|
|
20
|
+
export type SkillActivePhase = 'planning' | 'executing' | 'reviewing' | 'completing' | 'ralplan' | 'deep-interview';
|
|
21
21
|
export interface DeepInterviewInputLock {
|
|
22
22
|
active: boolean;
|
|
23
23
|
scope: 'deep-interview-auto-approval';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyword-detector.d.ts","sourceRoot":"","sources":["../../src/hooks/keyword-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAAiC,KAAK,cAAc,EAA2B,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"keyword-detector.d.ts","sourceRoot":"","sources":["../../src/hooks/keyword-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,7 @@ import { dirname, join } from 'node:path';
|
|
|
15
15
|
import { classifyTaskSize, isHeavyMode } from './task-size-detector.js';
|
|
16
16
|
import { isApprovedExecutionFollowupShortcut } from '../team/followup-planner.js';
|
|
17
17
|
import { isPlanningComplete, readPlanningArtifacts } from '../planning/artifacts.js';
|
|
18
|
+
import { hasDurableRalplanConsensusEvidenceForCwd } from '../ralplan/consensus-gate.js';
|
|
18
19
|
import { KEYWORD_TRIGGER_DEFINITIONS, compareKeywordMatches } from './keyword-registry.js';
|
|
19
20
|
import { SKILL_ACTIVE_STATE_FILE, listActiveSkills, writeSkillActiveStateCopiesForStateDir, } from '../state/skill-active.js';
|
|
20
21
|
import { buildWorkflowTransitionError, evaluateWorkflowTransition, isTrackedWorkflowMode, } from '../state/workflow-transition.js';
|
|
@@ -40,6 +41,7 @@ const EXECUTION_LIKE_WORKFLOW_SKILLS = new Set([
|
|
|
40
41
|
'autoresearch',
|
|
41
42
|
'ralph',
|
|
42
43
|
'team',
|
|
44
|
+
'ultragoal',
|
|
43
45
|
'ultrawork',
|
|
44
46
|
'ultraqa',
|
|
45
47
|
]);
|
|
@@ -50,6 +52,7 @@ const STATEFUL_SKILL_SEED_CONFIG = {
|
|
|
50
52
|
ralph: { mode: 'ralph', initialPhase: 'starting', includeIteration: true },
|
|
51
53
|
ralplan: { mode: 'ralplan', initialPhase: 'planning' },
|
|
52
54
|
team: { mode: 'team', initialPhase: 'starting', scope: 'root' },
|
|
55
|
+
ultragoal: { mode: 'ultragoal', initialPhase: 'planning' },
|
|
53
56
|
ultrawork: { mode: 'ultrawork', initialPhase: 'planning' },
|
|
54
57
|
ultraqa: { mode: 'ultraqa', initialPhase: 'planning' },
|
|
55
58
|
};
|
|
@@ -235,6 +238,15 @@ async function persistStatefulSkillSeedState(stateDir, nextSkill, nowIso, previo
|
|
|
235
238
|
handoff_artifacts: {
|
|
236
239
|
deep_interview: null,
|
|
237
240
|
ralplan: null,
|
|
241
|
+
ralplan_consensus_gate: {
|
|
242
|
+
required: true,
|
|
243
|
+
sequence: ['architect-review', 'critic-review'],
|
|
244
|
+
planning_artifacts_are_not_consensus: true,
|
|
245
|
+
required_review_roles: ['architect', 'critic'],
|
|
246
|
+
ralplan_architect_review: null,
|
|
247
|
+
ralplan_critic_review: null,
|
|
248
|
+
complete: false,
|
|
249
|
+
},
|
|
238
250
|
ultragoal: null,
|
|
239
251
|
code_review: null,
|
|
240
252
|
ultraqa: null,
|
|
@@ -249,6 +261,13 @@ async function persistStatefulSkillSeedState(stateDir, nextSkill, nowIso, previo
|
|
|
249
261
|
return_to_ralplan_reason: Object.prototype.hasOwnProperty.call(existingState, 'return_to_ralplan_reason')
|
|
250
262
|
? existingState.return_to_ralplan_reason
|
|
251
263
|
: null,
|
|
264
|
+
deep_interview_gate: (existingState.deep_interview_gate && typeof existingState.deep_interview_gate === 'object')
|
|
265
|
+
? existingState.deep_interview_gate
|
|
266
|
+
: {
|
|
267
|
+
status: 'required',
|
|
268
|
+
skip_reason: null,
|
|
269
|
+
rationale: 'Autopilot starts at the deep-interview gate by default; clear bounded tasks may skip only with an explicit persisted skip reason.',
|
|
270
|
+
},
|
|
252
271
|
};
|
|
253
272
|
}
|
|
254
273
|
await mkdir(dirname(absolutePath), { recursive: true });
|
|
@@ -409,10 +428,12 @@ function parseExplicitSkillInvocations(text) {
|
|
|
409
428
|
}
|
|
410
429
|
function hasIntentContextForKeyword(text, keyword) {
|
|
411
430
|
const k = keyword.toLowerCase();
|
|
412
|
-
if (
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
431
|
+
if (k === 'deep interview' || k === 'interview') {
|
|
432
|
+
if (DEEP_INTERVIEW_MANAGEMENT_MENTION_PATTERN.test(text)
|
|
433
|
+
&& !DEEP_INTERVIEW_ACTIVATION_PATTERNS.some((pattern) => pattern.test(text))) {
|
|
434
|
+
return false;
|
|
435
|
+
}
|
|
436
|
+
return DEEP_INTERVIEW_ACTIVATION_PATTERNS.some((pattern) => pattern.test(text));
|
|
416
437
|
}
|
|
417
438
|
if (!KEYWORDS_REQUIRING_INTENT.has(k))
|
|
418
439
|
return true;
|
|
@@ -507,7 +528,7 @@ function initialWorkflowPhaseForMode(mode) {
|
|
|
507
528
|
if (mode === 'autoresearch')
|
|
508
529
|
return 'executing';
|
|
509
530
|
if (mode === 'autopilot')
|
|
510
|
-
return '
|
|
531
|
+
return 'deep-interview';
|
|
511
532
|
return 'planning';
|
|
512
533
|
}
|
|
513
534
|
function resolveRequestedWorkflowSkills(requestedWorkflowSkills) {
|
|
@@ -849,11 +870,12 @@ export function applyRalplanGate(keywords, text, options = {}) {
|
|
|
849
870
|
return { keywords, gateApplied: false, gatedKeywords: [] };
|
|
850
871
|
}
|
|
851
872
|
const planningComplete = isPlanningComplete(readPlanningArtifacts(options.cwd ?? process.cwd()));
|
|
873
|
+
const consensusComplete = hasDurableRalplanConsensusEvidenceForCwd(options.cwd ?? process.cwd());
|
|
852
874
|
const shortFollowupBypasses = executionKeywords.filter((keyword) => {
|
|
853
875
|
if (keyword !== 'team' && keyword !== 'ralph')
|
|
854
876
|
return false;
|
|
855
877
|
return isApprovedExecutionFollowupShortcut(keyword, text, {
|
|
856
|
-
planningComplete,
|
|
878
|
+
planningComplete: planningComplete && consensusComplete,
|
|
857
879
|
priorSkill: options.priorSkill,
|
|
858
880
|
});
|
|
859
881
|
});
|