@jterrats/open-orchestra 0.1.0 → 0.3.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/AGENTS.md +90 -0
- package/CHANGELOG.md +104 -0
- package/CLAUDE.md +103 -0
- package/README.md +173 -22
- package/dist/assets/web-console.js +743 -0
- package/dist/autonomous-workflow.d.ts +45 -0
- package/dist/autonomous-workflow.js +386 -0
- package/dist/autonomous-workflow.js.map +1 -0
- package/dist/benchmark.d.ts +8 -0
- package/dist/benchmark.js +193 -0
- package/dist/benchmark.js.map +1 -0
- package/dist/burndown.d.ts +3 -0
- package/dist/burndown.js +141 -0
- package/dist/burndown.js.map +1 -0
- package/dist/clarification.d.ts +6 -0
- package/dist/clarification.js +88 -0
- package/dist/clarification.js.map +1 -0
- package/dist/cli.js +221 -4
- package/dist/cli.js.map +1 -1
- package/dist/collaboration-flows.d.ts +5 -0
- package/dist/collaboration-flows.js +256 -0
- package/dist/collaboration-flows.js.map +1 -0
- package/dist/command-manifest.d.ts +11 -0
- package/dist/command-manifest.js +52 -0
- package/dist/command-manifest.js.map +1 -0
- package/dist/commands.d.ts +39 -0
- package/dist/commands.js +1069 -2
- package/dist/commands.js.map +1 -1
- package/dist/constants.d.ts +4 -0
- package/dist/constants.js +22 -0
- package/dist/constants.js.map +1 -1
- package/dist/defaults.d.ts +7 -11
- package/dist/defaults.js +7 -625
- package/dist/defaults.js.map +1 -1
- package/dist/delegation-decision.d.ts +14 -0
- package/dist/delegation-decision.js +391 -0
- package/dist/delegation-decision.js.map +1 -0
- package/dist/detect-commands.d.ts +3 -0
- package/dist/detect-commands.js +28 -0
- package/dist/detect-commands.js.map +1 -0
- package/dist/diagram-validation.d.ts +36 -0
- package/dist/diagram-validation.js +118 -0
- package/dist/diagram-validation.js.map +1 -0
- package/dist/fs-utils.d.ts +2 -0
- package/dist/fs-utils.js +75 -6
- package/dist/fs-utils.js.map +1 -1
- package/dist/github.d.ts +11 -0
- package/dist/github.js +48 -0
- package/dist/github.js.map +1 -0
- package/dist/health-checks.d.ts +28 -0
- package/dist/health-checks.js +219 -0
- package/dist/health-checks.js.map +1 -0
- package/dist/health-commands.d.ts +2 -0
- package/dist/health-commands.js +18 -0
- package/dist/health-commands.js.map +1 -0
- package/dist/instruction-apply.d.ts +34 -0
- package/dist/instruction-apply.js +150 -0
- package/dist/instruction-apply.js.map +1 -0
- package/dist/instruction-blocks.d.ts +22 -0
- package/dist/instruction-blocks.js +120 -0
- package/dist/instruction-blocks.js.map +1 -0
- package/dist/instruction-imports.d.ts +12 -0
- package/dist/instruction-imports.js +45 -0
- package/dist/instruction-imports.js.map +1 -0
- package/dist/instruction-stale.d.ts +9 -0
- package/dist/instruction-stale.js +106 -0
- package/dist/instruction-stale.js.map +1 -0
- package/dist/instruction-types.d.ts +66 -0
- package/dist/instruction-types.js +2 -0
- package/dist/instruction-types.js.map +1 -0
- package/dist/instruction-updates.d.ts +4 -0
- package/dist/instruction-updates.js +5 -0
- package/dist/instruction-updates.js.map +1 -0
- package/dist/knowledge-base.d.ts +10 -0
- package/dist/knowledge-base.js +117 -0
- package/dist/knowledge-base.js.map +1 -0
- package/dist/mcp-oauth-proxy.d.ts +39 -0
- package/dist/mcp-oauth-proxy.js +80 -0
- package/dist/mcp-oauth-proxy.js.map +1 -0
- package/dist/pr-review.d.ts +20 -0
- package/dist/pr-review.js +142 -0
- package/dist/pr-review.js.map +1 -0
- package/dist/project-detection.d.ts +22 -0
- package/dist/project-detection.js +174 -0
- package/dist/project-detection.js.map +1 -0
- package/dist/prompt-registry.d.ts +56 -0
- package/dist/prompt-registry.js +163 -0
- package/dist/prompt-registry.js.map +1 -0
- package/dist/release-candidate.d.ts +41 -0
- package/dist/release-candidate.js +196 -0
- package/dist/release-candidate.js.map +1 -0
- package/dist/release-commands.d.ts +4 -0
- package/dist/release-commands.js +50 -0
- package/dist/release-commands.js.map +1 -0
- package/dist/roles/ai-support-roles.d.ts +11 -0
- package/dist/roles/ai-support-roles.js +67 -0
- package/dist/roles/ai-support-roles.js.map +1 -0
- package/dist/roles/core-roles.d.ts +11 -0
- package/dist/roles/core-roles.js +144 -0
- package/dist/roles/core-roles.js.map +1 -0
- package/dist/roles/engineering-roles.d.ts +11 -0
- package/dist/roles/engineering-roles.js +176 -0
- package/dist/roles/engineering-roles.js.map +1 -0
- package/dist/roles/governance-roles.d.ts +11 -0
- package/dist/roles/governance-roles.js +117 -0
- package/dist/roles/governance-roles.js.map +1 -0
- package/dist/roles/index.d.ts +11 -0
- package/dist/roles/index.js +17 -0
- package/dist/roles/index.js.map +1 -0
- package/dist/roles/platform-ops-roles.d.ts +11 -0
- package/dist/roles/platform-ops-roles.js +158 -0
- package/dist/roles/platform-ops-roles.js.map +1 -0
- package/dist/roles/qa-ux-roles.d.ts +11 -0
- package/dist/roles/qa-ux-roles.js +193 -0
- package/dist/roles/qa-ux-roles.js.map +1 -0
- package/dist/roles/release-ops-roles.d.ts +11 -0
- package/dist/roles/release-ops-roles.js +109 -0
- package/dist/roles/release-ops-roles.js.map +1 -0
- package/dist/runtime-adapters.d.ts +6 -0
- package/dist/runtime-adapters.js +88 -0
- package/dist/runtime-adapters.js.map +1 -0
- package/dist/runtime-bootstrap.d.ts +12 -0
- package/dist/runtime-bootstrap.js +136 -0
- package/dist/runtime-bootstrap.js.map +1 -0
- package/dist/skills.d.ts +36 -0
- package/dist/skills.js +665 -0
- package/dist/skills.js.map +1 -0
- package/dist/subagent-protocol.d.ts +41 -0
- package/dist/subagent-protocol.js +179 -0
- package/dist/subagent-protocol.js.map +1 -0
- package/dist/telemetry-consent.d.ts +24 -0
- package/dist/telemetry-consent.js +95 -0
- package/dist/telemetry-consent.js.map +1 -0
- package/dist/telemetry-export.d.ts +14 -0
- package/dist/telemetry-export.js +126 -0
- package/dist/telemetry-export.js.map +1 -0
- package/dist/telemetry-records.d.ts +3 -0
- package/dist/telemetry-records.js +96 -0
- package/dist/telemetry-records.js.map +1 -0
- package/dist/telemetry-redaction.d.ts +9 -0
- package/dist/telemetry-redaction.js +55 -0
- package/dist/telemetry-redaction.js.map +1 -0
- package/dist/telemetry-types.d.ts +52 -0
- package/dist/telemetry-types.js +2 -0
- package/dist/telemetry-types.js.map +1 -0
- package/dist/telemetry.d.ts +4 -0
- package/dist/telemetry.js +4 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/types.d.ts +304 -1
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/dist/validation.d.ts +3 -1
- package/dist/validation.js +28 -5
- package/dist/validation.js.map +1 -1
- package/dist/web-api.js +167 -3
- package/dist/web-api.js.map +1 -1
- package/dist/web-console.js +6 -160
- package/dist/web-console.js.map +1 -1
- package/dist/workflow-gates.js +4 -2
- package/dist/workflow-gates.js.map +1 -1
- package/dist/workflow-services.js +143 -67
- package/dist/workflow-services.js.map +1 -1
- package/dist/workflow-templates.d.ts +10 -0
- package/dist/workflow-templates.js +141 -0
- package/dist/workflow-templates.js.map +1 -0
- package/dist/workspace-classification.d.ts +5 -0
- package/dist/workspace-classification.js +127 -0
- package/dist/workspace-classification.js.map +1 -0
- package/dist/workspace-validator.js +11 -1
- package/dist/workspace-validator.js.map +1 -1
- package/dist/workspace.d.ts +8 -4
- package/dist/workspace.js +111 -4
- package/dist/workspace.js.map +1 -1
- package/docs/autonomous-workflow.md +165 -0
- package/docs/benchmark.md +219 -0
- package/docs/dev-team-specialist-role-profiles.md +171 -0
- package/docs/mcp-oauth-proxy-evaluation.md +44 -0
- package/docs/multi-agent-orchestrator-backlog.md +413 -1
- package/docs/open-orchestra-dogfooding-findings.md +66 -0
- package/docs/orchestra-mvp.md +161 -3
- package/docs/runtime-adapters.md +86 -0
- package/docs/runtime-llm-flow.md +124 -0
- package/docs/setup-agents-dogfooding-findings.md +101 -0
- package/docs/skill-loading-strategy.md +114 -0
- package/docs/source-of-truth-and-agent-learning.md +83 -0
- package/package.json +9 -5
- package/rules/agent-roles.mdc +30 -0
- package/rules/ai-assisted-development.mdc +22 -0
- package/skills/agent-learning/SKILL.md +24 -0
- package/skills/agent-learning/manifest.json +40 -0
- package/skills/backlog-sync/SKILL.md +24 -0
- package/skills/backlog-sync/manifest.json +41 -0
- package/skills/diagram-export/SKILL.md +35 -0
- package/skills/diagram-export/manifest.json +40 -0
- package/skills/model-evaluation/SKILL.md +25 -0
- package/skills/model-evaluation/manifest.json +41 -0
- package/skills/playwright-evidence/SKILL.md +28 -0
- package/skills/playwright-evidence/manifest.json +46 -0
- package/skills/pr-review/SKILL.md +23 -0
- package/skills/pr-review/manifest.json +43 -0
- package/skills/prompt-registry/SKILL.md +24 -0
- package/skills/prompt-registry/manifest.json +45 -0
- package/skills/release-readiness/SKILL.md +25 -0
- package/skills/release-readiness/manifest.json +45 -0
- package/skills/source-of-truth/SKILL.md +24 -0
- package/skills/source-of-truth/manifest.json +47 -0
- package/skills/static-analysis/SKILL.md +26 -0
- package/skills/static-analysis/manifest.json +46 -0
package/dist/workspace.js
CHANGED
|
@@ -2,12 +2,19 @@ import path from "node:path";
|
|
|
2
2
|
import { readFile, writeFile } from "node:fs/promises";
|
|
3
3
|
import { DIRECTORIES, FILES, WORKFLOW_DIR } from "./constants.js";
|
|
4
4
|
import { defaultConfig, defaultRoles } from "./defaults.js";
|
|
5
|
+
import { defaultSourceOfTruthCatalog } from "./knowledge-base.js";
|
|
6
|
+
import { initPromptRegistry, PROMPT_REGISTRY_DIR } from "./prompt-registry.js";
|
|
7
|
+
import { getRuntimeAdapter } from "./runtime-adapters.js";
|
|
8
|
+
import { renderRuntimeBootstrap, upsertRuntimeBootstrapBlock, } from "./runtime-bootstrap.js";
|
|
9
|
+
import { classifyWorkspace } from "./workspace-classification.js";
|
|
5
10
|
import { appendJsonLine, ensureDir, exists, readJson, resolveWorkflowPath, writeJson, } from "./fs-utils.js";
|
|
6
11
|
import { validateRoles, validateTasks } from "./validation.js";
|
|
7
12
|
export function workflowRoot(root = process.cwd()) {
|
|
8
13
|
return path.join(root, WORKFLOW_DIR);
|
|
9
14
|
}
|
|
10
|
-
export async function initWorkspace({ root = process.cwd(), force = false, } = {}) {
|
|
15
|
+
export async function initWorkspace({ root = process.cwd(), force = false, advisory = false, confirmUnknown = false, bootstrapTargetFile, runtimeTargets, } = {}) {
|
|
16
|
+
const classification = await classifyWorkspace({ root, advisory });
|
|
17
|
+
assertInitAllowed(classification, confirmUnknown);
|
|
11
18
|
const base = workflowRoot(root);
|
|
12
19
|
if ((await exists(base)) && !force) {
|
|
13
20
|
throw new Error(`${WORKFLOW_DIR} already exists. Use --force to overwrite generated files.`);
|
|
@@ -16,19 +23,119 @@ export async function initWorkspace({ root = process.cwd(), force = false, } = {
|
|
|
16
23
|
for (const directory of DIRECTORIES) {
|
|
17
24
|
await ensureDir(path.join(base, directory));
|
|
18
25
|
}
|
|
19
|
-
await writeJson(path.join(base, FILES.config),
|
|
26
|
+
await writeJson(path.join(base, FILES.config), {
|
|
27
|
+
...defaultConfig,
|
|
28
|
+
mode: advisory ? "advisory" : "project",
|
|
29
|
+
workspaceClassification: classification,
|
|
30
|
+
});
|
|
20
31
|
await writeJson(path.join(base, FILES.roles), defaultRoles);
|
|
21
32
|
await writeJson(path.join(base, FILES.tasks), []);
|
|
22
33
|
await writeJson(path.join(base, FILES.locks), []);
|
|
23
34
|
await writeFile(path.join(base, FILES.events), "", "utf8");
|
|
35
|
+
await writeJson(path.join(base, FILES.sourceOfTruth), defaultSourceOfTruthCatalog());
|
|
36
|
+
await writeFile(path.join(base, FILES.agentLessons), "", "utf8");
|
|
37
|
+
const promptRegistry = advisory
|
|
38
|
+
? { mode: "advisory", skipped: true }
|
|
39
|
+
: await initPromptRegistry({ root, force });
|
|
40
|
+
const runtimeBootstrap = advisory
|
|
41
|
+
? await initAdvisoryRuntimeBootstrapFiles({
|
|
42
|
+
root,
|
|
43
|
+
...(bootstrapTargetFile ? { bootstrapTargetFile } : {}),
|
|
44
|
+
...(runtimeTargets ? { runtimeTargets } : {}),
|
|
45
|
+
})
|
|
46
|
+
: await initRuntimeBootstrapFiles(root, initBootstrapTargets(runtimeTargets));
|
|
24
47
|
await appendEvent(root, {
|
|
25
48
|
type: "WORKFLOW_INITIALIZED",
|
|
26
49
|
actor: "parent",
|
|
27
|
-
summary:
|
|
28
|
-
|
|
50
|
+
summary: advisory
|
|
51
|
+
? "Initialized advisory agent workflow workspace"
|
|
52
|
+
: "Initialized agent workflow workspace",
|
|
53
|
+
artifacts: [
|
|
54
|
+
WORKFLOW_DIR,
|
|
55
|
+
...(advisory ? [] : [PROMPT_REGISTRY_DIR]),
|
|
56
|
+
path.join(WORKFLOW_DIR, FILES.sourceOfTruth),
|
|
57
|
+
path.join(WORKFLOW_DIR, FILES.agentLessons),
|
|
58
|
+
],
|
|
59
|
+
metadata: {
|
|
60
|
+
mode: advisory ? "advisory" : "project",
|
|
61
|
+
promptRegistry,
|
|
62
|
+
runtimeBootstrap,
|
|
63
|
+
workspaceClassification: classification,
|
|
64
|
+
},
|
|
29
65
|
});
|
|
30
66
|
return base;
|
|
31
67
|
}
|
|
68
|
+
function assertInitAllowed(classification, confirmUnknown) {
|
|
69
|
+
if (classification.writePolicy === "blocked") {
|
|
70
|
+
throw new Error(`workspace is unsafe for init: ${classification.reasons.join(", ")}. ${classification.recommendedAction}`);
|
|
71
|
+
}
|
|
72
|
+
if (classification.writePolicy === "confirm_required" && !confirmUnknown) {
|
|
73
|
+
throw new Error(`workspace requires explicit confirmation: ${classification.reasons.join(", ")}. ${classification.recommendedAction}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function initAdvisoryRuntimeBootstrapFile(root, bootstrapTargetFile) {
|
|
77
|
+
const target = targetFromBootstrapFile(bootstrapTargetFile);
|
|
78
|
+
return initRuntimeBootstrapFiles(root, [
|
|
79
|
+
{ file: bootstrapTargetFile, target },
|
|
80
|
+
]);
|
|
81
|
+
}
|
|
82
|
+
async function initAdvisoryRuntimeBootstrapFiles({ root, bootstrapTargetFile, runtimeTargets, }) {
|
|
83
|
+
const targets = initBootstrapTargets(runtimeTargets, false);
|
|
84
|
+
if (bootstrapTargetFile) {
|
|
85
|
+
return [
|
|
86
|
+
...(await initAdvisoryRuntimeBootstrapFile(root, bootstrapTargetFile)),
|
|
87
|
+
...(await initRuntimeBootstrapFiles(root, targets)),
|
|
88
|
+
];
|
|
89
|
+
}
|
|
90
|
+
return initRuntimeBootstrapFiles(root, targets);
|
|
91
|
+
}
|
|
92
|
+
async function initRuntimeBootstrapFiles(root, targets = [
|
|
93
|
+
{ file: "ORCHESTRA.md", target: "generic" },
|
|
94
|
+
{ file: "AGENTS.md", target: "codex" },
|
|
95
|
+
]) {
|
|
96
|
+
const changed = [];
|
|
97
|
+
for (const item of targets) {
|
|
98
|
+
const filePath = path.join(root, item.file);
|
|
99
|
+
const existing = await readFile(filePath, "utf8").catch(() => "");
|
|
100
|
+
const result = upsertRuntimeBootstrapBlock(existing, renderRuntimeBootstrap(item.target));
|
|
101
|
+
if (result.changed && !result.drift) {
|
|
102
|
+
await ensureDir(path.dirname(filePath));
|
|
103
|
+
await writeFile(filePath, result.content, "utf8");
|
|
104
|
+
changed.push(item.file);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return changed;
|
|
108
|
+
}
|
|
109
|
+
function initBootstrapTargets(runtimeTargets, useProjectDefaults = true) {
|
|
110
|
+
if (!runtimeTargets || runtimeTargets.length === 0) {
|
|
111
|
+
return useProjectDefaults
|
|
112
|
+
? [
|
|
113
|
+
{ file: "ORCHESTRA.md", target: "generic" },
|
|
114
|
+
{ file: "AGENTS.md", target: "codex" },
|
|
115
|
+
]
|
|
116
|
+
: [];
|
|
117
|
+
}
|
|
118
|
+
return runtimeTargets.flatMap((target) => getRuntimeAdapter(target).defaultInstructionFiles.map((file) => ({
|
|
119
|
+
file,
|
|
120
|
+
target,
|
|
121
|
+
})));
|
|
122
|
+
}
|
|
123
|
+
function targetFromBootstrapFile(filePath) {
|
|
124
|
+
const baseName = path.basename(filePath).toLowerCase();
|
|
125
|
+
if (baseName === "claude.md") {
|
|
126
|
+
return "claude";
|
|
127
|
+
}
|
|
128
|
+
if (baseName.includes("cursor")) {
|
|
129
|
+
return "cursor";
|
|
130
|
+
}
|
|
131
|
+
if (baseName.includes("windsurf")) {
|
|
132
|
+
return "windsurf";
|
|
133
|
+
}
|
|
134
|
+
if (baseName === "agents.md") {
|
|
135
|
+
return "codex";
|
|
136
|
+
}
|
|
137
|
+
return "generic";
|
|
138
|
+
}
|
|
32
139
|
export async function loadWorkspace(root = process.cwd()) {
|
|
33
140
|
const base = workflowRoot(root);
|
|
34
141
|
if (!(await exists(base))) {
|
package/dist/workspace.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EACL,cAAc,EACd,SAAS,EACT,MAAM,EACN,QAAQ,EACR,mBAAmB,EACnB,SAAS,GACV,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Autonomous Workflow
|
|
2
|
+
|
|
3
|
+
`orchestra workflow run` executes a full story lifecycle as a governed multi-phase sequence without requiring manual step-by-step commands. Each phase creates a sub-task, generates handoff artifacts, and persists state in an append-only run log at `.agent-workflow/workflow-runs.jsonl`.
|
|
4
|
+
|
|
5
|
+
## Phase Graph
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
PM → PO [gate] → Architect [sizing gate] → Developer → QA [gate] → Release
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
| Phase | Role | Summary |
|
|
12
|
+
|-------|------|---------|
|
|
13
|
+
| `pm` | product_manager | Product framing, prioritization, and success metrics |
|
|
14
|
+
| `po` | product_owner | Backlog refinement, story sizing, and acceptance criteria |
|
|
15
|
+
| `architect` | architect | Technical tasking, design decisions, and size estimation |
|
|
16
|
+
| `developer` | developer | Implementation against acceptance criteria |
|
|
17
|
+
| `qa` | qa | Verification against acceptance criteria and edge cases |
|
|
18
|
+
| `release` | release_manager | Release candidate validation and PR creation |
|
|
19
|
+
|
|
20
|
+
## Gate Modes
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
orchestra workflow run --task <id> --gates none # fully autonomous
|
|
24
|
+
orchestra workflow run --task <id> --gates phase # gates at po→architect and qa→release
|
|
25
|
+
orchestra workflow run --task <id> --gates all # gate at every transition
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
| Mode | Pauses at |
|
|
29
|
+
|------|-----------|
|
|
30
|
+
| `none` | Never — fully autonomous |
|
|
31
|
+
| `phase` | `po→architect` and `qa→release` |
|
|
32
|
+
| `all` | Every phase transition |
|
|
33
|
+
|
|
34
|
+
When a gate is reached, the run writes a review artifact to `.agent-workflow/approvals/` and prints the exact `--resume` command. The run resumes when a human approves and runs that command.
|
|
35
|
+
|
|
36
|
+
## Architect Sizing Gate
|
|
37
|
+
|
|
38
|
+
Regardless of `--gates` mode, the architect phase always requires a sizing decision before the developer phase starts. If no sizing decision is found, the run stops with the exact command to resolve it:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
orchestra decision add \
|
|
42
|
+
--task <id> \
|
|
43
|
+
--owner architect \
|
|
44
|
+
--title "Story sizing" \
|
|
45
|
+
--decision "m [5 points]" \
|
|
46
|
+
--context "Authentication story, moderate complexity" \
|
|
47
|
+
--consequences "Fits in a two-day sprint slot" \
|
|
48
|
+
--status accepted
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Valid sizing labels: `xs`, `s`, `m`, `l`, `xl`. An optional numeric point estimate can be appended to the decision text.
|
|
52
|
+
|
|
53
|
+
## Usage
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Inspect the phase graph without persisting state
|
|
57
|
+
orchestra workflow run --task FEAT-001 --dry-run --gates phase
|
|
58
|
+
|
|
59
|
+
# Fully autonomous run
|
|
60
|
+
orchestra workflow run --task FEAT-001 --gates none
|
|
61
|
+
|
|
62
|
+
# Run with human approval gates
|
|
63
|
+
orchestra workflow run --task FEAT-001 --gates phase
|
|
64
|
+
|
|
65
|
+
# Resume a paused run after approving a gate
|
|
66
|
+
orchestra workflow run --task FEAT-001 --resume <run-id>
|
|
67
|
+
|
|
68
|
+
# Cap the number of QA→developer retry iterations (default: 5)
|
|
69
|
+
orchestra workflow run --task FEAT-001 --gates none --max-iterations 3
|
|
70
|
+
|
|
71
|
+
# List all runs
|
|
72
|
+
orchestra workflow runs
|
|
73
|
+
orchestra workflow runs --json
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Clarification Loop
|
|
77
|
+
|
|
78
|
+
Developers or QA engineers can surface blocking questions to the PO or architect mid-phase. The active phase is suspended until the answer is recorded, then resumed normally.
|
|
79
|
+
|
|
80
|
+
Clarification is only allowed from `developer` and `qa` phases. Questions can be directed to `po` (product_owner) or `architect`.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Open a clarification — suspends the active developer or qa phase
|
|
84
|
+
orchestra workflow clarify \
|
|
85
|
+
--run <run-id> \
|
|
86
|
+
--from developer \
|
|
87
|
+
--to po \
|
|
88
|
+
--question "Should empty input return null or throw a validation error?"
|
|
89
|
+
|
|
90
|
+
# The PO or architect answers
|
|
91
|
+
orchestra workflow clarify-respond \
|
|
92
|
+
--run <run-id> \
|
|
93
|
+
--clarification <clarification-id> \
|
|
94
|
+
--answer "Return null — downstream code handles it with a friendly message."
|
|
95
|
+
|
|
96
|
+
# Resume execution — picks up exactly where the phase left off
|
|
97
|
+
orchestra workflow run --task FEAT-001 --resume <run-id>
|
|
98
|
+
|
|
99
|
+
# List all clarifications for a run (open and answered)
|
|
100
|
+
orchestra workflow clarify-list --run <run-id>
|
|
101
|
+
orchestra workflow clarify-list --run <run-id> --json
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Clarification records are persisted in `.agent-workflow/clarifications.jsonl` and are visible in `orchestra context --task <id>`.
|
|
105
|
+
|
|
106
|
+
## Run States
|
|
107
|
+
|
|
108
|
+
| Status | Meaning |
|
|
109
|
+
|--------|---------|
|
|
110
|
+
| `running` | Execution in progress |
|
|
111
|
+
| `paused` | Waiting for human gate approval or clarification answer |
|
|
112
|
+
| `done` | All phases completed successfully |
|
|
113
|
+
| `failed` | Run stopped due to a missing prerequisite (e.g. sizing decision) |
|
|
114
|
+
|
|
115
|
+
## Phase States
|
|
116
|
+
|
|
117
|
+
| Status | Meaning |
|
|
118
|
+
|--------|---------|
|
|
119
|
+
| `pending` | Not yet started |
|
|
120
|
+
| `running` | Currently executing |
|
|
121
|
+
| `done` | Completed and handed off |
|
|
122
|
+
| `gate_paused` | Completed; waiting for human gate approval before next phase |
|
|
123
|
+
| `awaiting_clarification` | Suspended; waiting for a clarification answer |
|
|
124
|
+
| `qa_failed` | QA found issues; developer phase will retry |
|
|
125
|
+
| `blocked` | Blocked by an unresolvable condition |
|
|
126
|
+
|
|
127
|
+
## Persistent Files
|
|
128
|
+
|
|
129
|
+
```text
|
|
130
|
+
.agent-workflow/
|
|
131
|
+
workflow-runs.jsonl ← one JSON line per run state snapshot (append-only)
|
|
132
|
+
clarifications.jsonl ← one JSON line per clarification state snapshot (append-only)
|
|
133
|
+
approvals/ ← gate review artifacts (Markdown)
|
|
134
|
+
handoffs/ ← inter-phase handoff artifacts (Markdown)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Example: Full Lifecycle with gates=phase
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
$ orchestra workflow run --task FEAT-001 --gates phase
|
|
141
|
+
Started autonomous workflow wfrun-... for task FEAT-001 [gates=phase]
|
|
142
|
+
→ pm (product_manager) task=FEAT-001-pm
|
|
143
|
+
✓ handoff → product_owner (...)
|
|
144
|
+
→ po (product_owner) task=FEAT-001-po
|
|
145
|
+
✓ handoff → architect (...)
|
|
146
|
+
⏸ gate po→architect — review: .agent-workflow/approvals/FEAT-001-gate-po-to-architect-....md
|
|
147
|
+
Approve: orchestra workflow run --task FEAT-001 --resume wfrun-...
|
|
148
|
+
|
|
149
|
+
$ orchestra workflow run --task FEAT-001 --resume wfrun-...
|
|
150
|
+
Resuming run wfrun-... from phase architect
|
|
151
|
+
→ architect (architect) task=FEAT-001-architect
|
|
152
|
+
✓ sizing=m (5 pts)
|
|
153
|
+
✓ handoff → developer (...)
|
|
154
|
+
→ developer (developer) task=FEAT-001-developer
|
|
155
|
+
✓ handoff → qa (...)
|
|
156
|
+
→ qa (qa) task=FEAT-001-qa
|
|
157
|
+
✓ handoff → release_manager (...)
|
|
158
|
+
⏸ gate qa→release — review: .agent-workflow/approvals/FEAT-001-gate-qa-to-release-....md
|
|
159
|
+
Approve: orchestra workflow run --task FEAT-001 --resume wfrun-...
|
|
160
|
+
|
|
161
|
+
$ orchestra workflow run --task FEAT-001 --resume wfrun-...
|
|
162
|
+
Resuming run wfrun-... from phase release
|
|
163
|
+
→ release (release_manager) task=FEAT-001-release
|
|
164
|
+
Workflow complete [run=wfrun-...]
|
|
165
|
+
```
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# Benchmark & Sprint Burndown
|
|
2
|
+
|
|
3
|
+
Open Orchestra measures the effectiveness of AI-assisted development across three modes and generates a sprint burndown from story point estimates. All cycle time and quality data is computed automatically from the event log — no manual input is required after the initial estimate declaration.
|
|
4
|
+
|
|
5
|
+
## Three Modes
|
|
6
|
+
|
|
7
|
+
| Mode | How measured |
|
|
8
|
+
|------|-------------|
|
|
9
|
+
| **Solo (no LLM)** | Declared by PM or architect at story start — contrafactual estimate |
|
|
10
|
+
| **AI-unguided** | Declared at story start — how long with a general LLM but no roles, gates, or skills |
|
|
11
|
+
| **AI + Orchestra (actual)** | Measured automatically from `AUTONOMOUS_PHASE_DONE` timestamps in the event log |
|
|
12
|
+
|
|
13
|
+
The first two are self-reported. Orchestra only measures the third. The comparison is meaningful even with declared baselines because it creates a consistent, auditable record across many stories.
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### 1. Declare baselines at story start
|
|
18
|
+
|
|
19
|
+
Record the three-mode estimate before work begins — ideally during the architect phase.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
orchestra estimate \
|
|
23
|
+
--task FEAT-001 \
|
|
24
|
+
--sizing m \
|
|
25
|
+
--solo-days 5 \
|
|
26
|
+
--ai-unguided-days 3 \
|
|
27
|
+
--confidence high \
|
|
28
|
+
--declared-by pm
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Options:
|
|
32
|
+
|
|
33
|
+
| Flag | Required | Default | Description |
|
|
34
|
+
|------|----------|---------|-------------|
|
|
35
|
+
| `--task` | Yes | — | Task ID |
|
|
36
|
+
| `--sizing` | Yes | — | `xs`, `s`, `m`, `l`, `xl` |
|
|
37
|
+
| `--solo-days` | Yes | — | Estimated days without any AI |
|
|
38
|
+
| `--ai-unguided-days` | Yes | — | Estimated days with a general LLM, no Orchestra |
|
|
39
|
+
| `--confidence` | No | `medium` | `low`, `medium`, `high` |
|
|
40
|
+
| `--declared-by` | No | `pm` | Role recording the estimate |
|
|
41
|
+
| `--json` | No | — | Structured output |
|
|
42
|
+
|
|
43
|
+
### 2. Run the story autonomously
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
orchestra workflow run --task FEAT-001 --gates phase
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The autonomous engine records all necessary data automatically as phases complete.
|
|
50
|
+
|
|
51
|
+
### 3. View the benchmark
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Per-story
|
|
55
|
+
orchestra benchmark --task FEAT-001
|
|
56
|
+
|
|
57
|
+
# All stories with estimates
|
|
58
|
+
orchestra benchmark --summary
|
|
59
|
+
orchestra benchmark --summary --json
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Example per-story output:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
Benchmark: FEAT-001 [complete]
|
|
66
|
+
Sizing: m
|
|
67
|
+
Solo: 5d (declared)
|
|
68
|
+
AI-unguided: 3d (declared)
|
|
69
|
+
Actual: 1.4d
|
|
70
|
+
vs Solo: -72%
|
|
71
|
+
vs AI: -53%
|
|
72
|
+
QA loops: 1
|
|
73
|
+
Reviews: 3 (0 blocking)
|
|
74
|
+
Evidence: 5 artifacts
|
|
75
|
+
Gate blocks: 0
|
|
76
|
+
Lessons: 2
|
|
77
|
+
Tokens: 17500in / 5000out
|
|
78
|
+
Cost: $0.0257
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Example summary table:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
Story Size Solo AI Actual vs Solo vs AI QA Rev Blk Ev Les
|
|
85
|
+
────────────────────────────────────────────────────────────────────────────────────
|
|
86
|
+
TASK-042 m 5d 3d 1.4d -72% -53% 1 3 0 5 2
|
|
87
|
+
TASK-089 l 8d 5d 2.1d -74% -58% 2 4 1 7 3
|
|
88
|
+
TASK-101 s 2d 1.5d 0.6d -70% -60% 0 2 0 3 1
|
|
89
|
+
|
|
90
|
+
Avg savings vs solo: -72%
|
|
91
|
+
Avg savings vs AI-unguided: -57%
|
|
92
|
+
Stories with actuals: 3/3
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Quality Signals
|
|
96
|
+
|
|
97
|
+
All quality signals are computed automatically from the event log for the task. No additional commands are needed.
|
|
98
|
+
|
|
99
|
+
| Signal | Source event | What it means |
|
|
100
|
+
|--------|-------------|---------------|
|
|
101
|
+
| `reviewCount` | `REVIEW_RECORDED` | Total reviews across all roles |
|
|
102
|
+
| `blockingReviews` | `REVIEW_RECORDED` with `result=block` or `severity=high/critical` | Reviews that blocked progress |
|
|
103
|
+
| `evidenceCount` | `EVIDENCE_ADDED` | Artifacts attached (commands, files, screenshots, traces) |
|
|
104
|
+
| `gateBlockCount` | `GATE_BLOCKED` | Times a workflow gate evaluation failed |
|
|
105
|
+
| `lessonCount` | `LESSON_RECORDED` | Lessons generated during the story |
|
|
106
|
+
| `totalInputTokens` | `MODEL_PROVENANCE_RECORDED` | Input tokens across all LLM calls |
|
|
107
|
+
| `totalOutputTokens` | `MODEL_PROVENANCE_RECORDED` | Output tokens across all LLM calls |
|
|
108
|
+
| `estimatedCostUsd` | `MODEL_PROVENANCE_RECORDED` | Estimated cost of all LLM calls |
|
|
109
|
+
|
|
110
|
+
Token and cost signals appear automatically once the autonomous engine makes real LLM calls. No changes to the benchmark layer are needed.
|
|
111
|
+
|
|
112
|
+
## Sprint Burndown
|
|
113
|
+
|
|
114
|
+
The burndown uses story points from `DECISION_RECORDED` events. Developer points take priority over architect sizing when both exist.
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# ASCII chart with ideal and actual lines
|
|
118
|
+
orchestra burndown --sprint FEAT-001,FEAT-002,FEAT-003
|
|
119
|
+
|
|
120
|
+
# JSON series for dashboards or external tools
|
|
121
|
+
orchestra burndown --sprint FEAT-001,FEAT-002,FEAT-003 --json
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Example output:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
Sprint burndown total=18 pts tasks=3
|
|
128
|
+
|
|
129
|
+
18 │*
|
|
130
|
+
16 │
|
|
131
|
+
14 │ ·
|
|
132
|
+
12 │ *
|
|
133
|
+
10 │
|
|
134
|
+
8 │ ·
|
|
135
|
+
6 │ *
|
|
136
|
+
4 │
|
|
137
|
+
2 │
|
|
138
|
+
0 │ ·
|
|
139
|
+
└───────────────────────────────────────────────────
|
|
140
|
+
Day 0 Day 3
|
|
141
|
+
· ideal * actual
|
|
142
|
+
|
|
143
|
+
Task breakdown:
|
|
144
|
+
FEAT-001 arch=5 dev=8 resolved=8 done 2026-05-06
|
|
145
|
+
FEAT-002 arch=5 dev=— resolved=5 done 2026-05-06
|
|
146
|
+
FEAT-003 arch=5 dev=— resolved=5 pending
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Developer Story Point Estimation
|
|
150
|
+
|
|
151
|
+
Architect sizing (`xs/s/m/l/xl` + optional points) reflects technical scope. Developer points reflect implementation effort from the developer's perspective. When both exist, the burndown uses developer points — the divergence between the two is a calibration signal worth tracking.
|
|
152
|
+
|
|
153
|
+
Developer records their estimate with:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
orchestra decision add \
|
|
157
|
+
--task FEAT-001 \
|
|
158
|
+
--owner developer \
|
|
159
|
+
--title "Dev estimate" \
|
|
160
|
+
--decision "M / 8 points" \
|
|
161
|
+
--context "Familiar codebase area, clean interfaces" \
|
|
162
|
+
--consequences "Fits in one sprint slot" \
|
|
163
|
+
--status accepted
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
The `metadata.points` value is extracted automatically from `DECISION_RECORDED` events where `actor=developer`.
|
|
167
|
+
|
|
168
|
+
## JSON Output
|
|
169
|
+
|
|
170
|
+
All benchmark and burndown commands support `--json` for structured output.
|
|
171
|
+
|
|
172
|
+
`orchestra benchmark --task <id> --json`:
|
|
173
|
+
```json
|
|
174
|
+
{
|
|
175
|
+
"taskId": "FEAT-001",
|
|
176
|
+
"sizingLabel": "m",
|
|
177
|
+
"soloEstimateDays": 5,
|
|
178
|
+
"aiUnguidedEstimateDays": 3,
|
|
179
|
+
"actualDays": 1.4,
|
|
180
|
+
"vsSoloPct": -72,
|
|
181
|
+
"vsAiUnguidedPct": -53,
|
|
182
|
+
"qaIterations": 1,
|
|
183
|
+
"quality": {
|
|
184
|
+
"reviewCount": 3,
|
|
185
|
+
"blockingReviews": 0,
|
|
186
|
+
"evidenceCount": 5,
|
|
187
|
+
"gateBlockCount": 0,
|
|
188
|
+
"lessonCount": 2,
|
|
189
|
+
"totalInputTokens": 17500,
|
|
190
|
+
"totalOutputTokens": 5000,
|
|
191
|
+
"estimatedCostUsd": 0.0257
|
|
192
|
+
},
|
|
193
|
+
"status": "complete"
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
`orchestra burndown --sprint ... --json`:
|
|
198
|
+
```json
|
|
199
|
+
{
|
|
200
|
+
"sprintTaskIds": ["FEAT-001", "FEAT-002"],
|
|
201
|
+
"totalPoints": 13,
|
|
202
|
+
"idealLine": [{ "day": 0, "remaining": 13 }, { "day": 1, "remaining": 7 }, { "day": 2, "remaining": 0 }],
|
|
203
|
+
"actualLine": [{ "day": 0, "remaining": 13, "completedTaskIds": [] }, { "day": 1, "remaining": 5, "completedTaskIds": ["FEAT-001"] }],
|
|
204
|
+
"taskBreakdown": [
|
|
205
|
+
{ "taskId": "FEAT-001", "architectPoints": 5, "developerPoints": 8, "resolvedPoints": 8, "completedAt": "2026-05-06T..." },
|
|
206
|
+
{ "taskId": "FEAT-002", "architectPoints": 5, "developerPoints": null, "resolvedPoints": 5, "completedAt": null }
|
|
207
|
+
],
|
|
208
|
+
"warnings": []
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Persistent Files
|
|
213
|
+
|
|
214
|
+
```text
|
|
215
|
+
.agent-workflow/
|
|
216
|
+
estimates.jsonl ← one JSON line per estimate (append-only, latest-per-task wins)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Estimates are append-only. Recording a new estimate for the same task replaces the previous one in reads (latest-wins by taskId).
|