orchestrator-workflow 0.2.0 → 0.4.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/README.md CHANGED
@@ -13,23 +13,23 @@ evidence. Every unit of work leaves an auditable run directory behind.
13
13
  ## Why this shape
14
14
 
15
15
  ```text
16
- Operator
17
- goal | ^ handoff: what changed, how verified,
18
- v | what remains open
19
- Orchestrator . . . . . . . .ai/runs/<date>-<slug>/
20
- session model 00-goal 04-implementation-summary
21
- plans, validates slices, 01-plan 05-review-findings
22
- decides acceptance 02-tasks 06-handoff
23
- | 03-decisions
24
- narrow | ^ structured (state lives in files,
25
- contracts v | YAML evidence not in chat history)
26
- +--------------+--------------+
27
- | | |
28
- task-slicer implementer reviewer
29
- sonnet sonnet opus
30
- small, one narrow skeptical, severity-rated
31
- testable task, plus findings, no rewrites
32
- slices tests
16
+ Operator
17
+ goal | ^ handoff: what changed, how verified,
18
+ v | what remains open
19
+ explorer --> Orchestrator . . . . . .ai/runs/<date>-<slug>/
20
+ optional, session model 00-goal 04-implementation-summary
21
+ read-only plans, validates slices, 01-plan 05-review-findings
22
+ terrain map decides acceptance 02-tasks 06-handoff
23
+ | 03-decisions
24
+ narrow | ^ structured (state lives in files,
25
+ contracts v | YAML evidence not in chat history)
26
+ +-------------+-------------+
27
+ | | |
28
+ task-slicer implementer reviewer
29
+ sonnet sonnet opus
30
+ small, one narrow skeptical, severity-rated
31
+ testable task, plus findings, no rewrites
32
+ slices tests
33
33
  ```
34
34
 
35
35
  Two effects fall out of this shape:
@@ -39,7 +39,9 @@ Two effects fall out of this shape:
39
39
  structured YAML evidence instead of transcripts, and durable state lives
40
40
  in run files that survive context compaction. The cheap models do the
41
41
  volume work; the strongest model is spent only on orchestration decisions
42
- and the skeptical review.
42
+ and the skeptical review. The ceremony scales to the task: a trivial change
43
+ is done directly, the full flow is for non-trivial work, and a read-only
44
+ explorer maps the terrain first only when the solution is unclear.
43
45
  - **Quality through structure.** Writing and reviewing are separated by
44
46
  role and model, task slices are validated before any implementation
45
47
  starts, acceptance is decided on evidence (tests executed, findings
@@ -95,9 +97,9 @@ Per selected harness:
95
97
 
96
98
  | Harness | Files | Notes |
97
99
  |---|---|---|
98
- | Claude Code | `.claude/skills/orchestrator-workflow/SKILL.md`, `.claude/agents/{task-slicer,implementer,reviewer}.md`, `CLAUDE.md` | Claude Code reads `CLAUDE.md`, not `AGENTS.md`; the installer adds an additive `@AGENTS.md` import. Subagent models go into the `model:` frontmatter. |
100
+ | Claude Code | `.claude/skills/orchestrator-workflow/SKILL.md`, `.claude/agents/{explorer,task-slicer,implementer,reviewer}.md`, `CLAUDE.md` | Claude Code reads `CLAUDE.md`, not `AGENTS.md`; the installer adds an additive `@AGENTS.md` import. Subagent models go into the `model:` frontmatter; the read-only explorer also gets `disallowedTools: Edit, Write, NotebookEdit`. |
99
101
  | OpenAI Codex | `.agents/skills/orchestrator-workflow/SKILL.md` | Codex reads `AGENTS.md` natively. There is no standardized project-level subagent definition; the skill instructs running the roles inline with the same contracts. |
100
- | opencode | `.opencode/agents/{task-slicer,implementer,reviewer}.md` | opencode reads `AGENTS.md` natively and cross-discovers `.claude/skills/`. Subagents get `mode: subagent` plus a fully qualified `provider/model-id`. |
102
+ | opencode | `.opencode/agents/{explorer,task-slicer,implementer,reviewer}.md` | opencode reads `AGENTS.md` natively and cross-discovers `.claude/skills/`. Subagents get `mode: subagent` plus a fully qualified `provider/model-id`; the explorer also gets `permission: edit: deny`. |
101
103
 
102
104
  ## Model preselection
103
105
 
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: explorer
3
+ description: "Read-only discovery: maps the relevant terrain of a codebase before planning. Finds what exists, how it connects, and which solution options are viable. Does not write code or change files."
4
+ ---
5
+
6
+ You are the discovery subagent of an orchestrator-led workflow.
7
+
8
+ The orchestrator sends you when the goal or the solution is still unclear, or
9
+ when the codebase is unfamiliar. Your job is to make the terrain visible so the
10
+ orchestrator can plan with facts instead of guesses. You are read-only: you
11
+ read, search, and trace, but you never write code or change files.
12
+
13
+ Rules:
14
+
15
+ - Investigate only what is relevant to the stated goal. Do not survey the whole
16
+ repository; follow the question.
17
+ - Report what you actually found, with `file:line` references. Distinguish
18
+ verified facts from inference, and never present a guess as a fact.
19
+ - Surface the constraints and conventions a plan must respect (existing
20
+ patterns, public interfaces, tests, build and CI steps, risky areas).
21
+ - Lay out the viable solution options you can see, with the trade-off that
22
+ decides between them. Do not pick one and start implementing.
23
+ - If a question can only be answered by the operator (product intent, an
24
+ external system, a decision), put it under open questions rather than
25
+ guessing.
26
+ - Do not spawn further subagents and do not implement anything. Return your
27
+ findings to the orchestrator and let it decide.
28
+
29
+ Return exactly this structure as your final output, nothing else:
30
+
31
+ ```yaml
32
+ status: done | partial | blocked
33
+ role: explorer
34
+ summary:
35
+ - ""
36
+ relevant_terrain:
37
+ - path: ""
38
+ role: ""
39
+ notes: ""
40
+ how_it_connects:
41
+ - ""
42
+ constraints_and_conventions:
43
+ - ""
44
+ solution_options:
45
+ - option: ""
46
+ pros:
47
+ - ""
48
+ cons:
49
+ - ""
50
+ risk: low | medium | high
51
+ open_questions:
52
+ - ""
53
+ recommendation: ""
54
+ ```
@@ -5,23 +5,44 @@ This repository uses an orchestrator-led agent workflow, installed and updated b
5
5
  [orchestrator-workflow](https://github.com/LanNguyenSi/agent-dx/tree/master/packages/orchestrator-workflow).
6
6
 
7
7
  The primary agent acts as the orchestrator. It owns the goal, planning, task
8
- validation, delegation, final acceptance, and the operator handoff.
9
- Implementation and technical review are delegated to narrow subagents. The full
10
- procedure and the subagent I/O contracts live in the `orchestrator-workflow`
11
- skill.
8
+ validation, delegation, final acceptance, and the operator handoff. Non-trivial
9
+ implementation and review are delegated to narrow subagents. The full procedure
10
+ and the subagent I/O contracts live in the `orchestrator-workflow` skill.
12
11
 
13
12
  ### Core rules
14
13
 
15
14
  - Only the orchestrator spawns or coordinates subagents. Subagents never spawn
16
15
  further subagents.
16
+ - When the goal, the solution, or the terrain is unclear, the orchestrator may
17
+ send a read-only explorer subagent to map the terrain before planning. The
18
+ explorer reads and reports; it never changes files.
17
19
  - The orchestrator plans features itself. It may delegate task slicing, but it
18
20
  validates the sliced tasks before implementation starts.
19
- - Implementation goes to narrow implementer subagents, one task per subagent.
20
- - Technical review goes to a separate reviewer subagent. Review is never
21
- skipped, not even for docs or batch changes.
21
+ - Non-trivial implementation goes to narrow implementer subagents, one task
22
+ per subagent.
23
+ - Non-trivial review goes to a separate reviewer subagent (see Scaling
24
+ delegation). Review itself is never skipped, not even for docs or batch
25
+ changes.
22
26
  - Final acceptance and the final answer to the operator stay with the
23
27
  orchestrator.
24
28
 
29
+ ### Scaling delegation
30
+
31
+ The orchestrator matches the ceremony to the task; the full flow is a
32
+ default, not a ritual.
33
+
34
+ - A trivial change (a typo, a one-line fix, a rename) may be implemented by
35
+ the orchestrator directly, without discovery, slicing, or an implementer
36
+ subagent.
37
+ - Discovery (the read-only explorer) is for unfamiliar terrain or an unclear
38
+ solution; skip it when the change is well understood.
39
+ - Slicing and implementer subagents are for non-trivial work: multiple files,
40
+ real logic, or anything that benefits from decomposition or a fresh context.
41
+ - Review judgment applies to every change. For a trivial change the
42
+ orchestrator may review it itself; reserve the reviewer subagent for
43
+ changes whose risk or size warrants an independent skeptical pass. Either
44
+ way, review is never skipped.
45
+
25
46
  ### Context discipline
26
47
 
27
48
  - Prefer task-local context over repository-wide context.
@@ -15,6 +15,12 @@ tasks to specialized subagents. The goal is to improve quality, reduce
15
15
  context-window pressure, and keep the operator informed through structured
16
16
  handoffs.
17
17
 
18
+ Scale the ceremony to the task. The workflow below is the default for
19
+ non-trivial work; a trivial change (a typo, a one-line fix) may be done
20
+ directly by the orchestrator and reviewed by it, without slicing or spawning
21
+ subagents. Review judgment still applies to every change; only the size of
22
+ the apparatus changes.
23
+
18
24
  ## Roles
19
25
 
20
26
  - **Operator**: the human requester. Provides goal and constraints, approves or
@@ -23,6 +29,10 @@ handoffs.
23
29
  validates task slices, assigns implementation and review, decides acceptance,
24
30
  reports back. The orchestrator must not become a passive transcript
25
31
  collector; it maintains compact run state.
32
+ - **Explorer** (optional, read-only): maps the relevant terrain before
33
+ planning when the goal or solution is unclear or the codebase is unfamiliar.
34
+ Reports what exists, how it connects, the constraints to respect, and the
35
+ viable options. Never writes code.
26
36
  - **Task slicer** (optional): breaks a large change into small, testable tasks
27
37
  with dependencies and risk markers.
28
38
  - **Implementer**: implements exactly one narrow task, touches only relevant
@@ -31,8 +41,8 @@ handoffs.
31
41
  tests, security, and edge cases. Classifies severity, recommends fixes,
32
42
  avoids unsolicited rewrites.
33
43
 
34
- Where the harness supports subagent definitions, the slicer, implementer, and
35
- reviewer roles are installed as named subagents (Claude Code:
44
+ Where the harness supports subagent definitions, the explorer, slicer,
45
+ implementer, and reviewer roles are installed as named subagents (Claude Code:
36
46
  `.claude/agents/`, opencode: `.opencode/agents/`) with preselected models.
37
47
  Spawn those instead of improvising role prompts. Extended role prompts live in
38
48
  the [agentic-coding-playbook skills](https://github.com/LanNguyenSi/agent-dx/tree/master/packages/agentic-coding-playbook/skills).
@@ -58,34 +68,70 @@ older directories are the auditable history. Do not edit past runs.
58
68
 
59
69
  ## Workflow
60
70
 
71
+ For a non-trivial change, run the full flow below. For a trivial change, do
72
+ the work directly, review it, and still leave a short handoff; skip the run
73
+ directory and the subagents.
74
+
61
75
  1. **Understand the goal.** Create the run directory and fill `00-goal.md`:
62
76
  operator request, goal, non-goals, constraints, assumptions, open questions.
63
77
  If the task can proceed on reasonable assumptions, proceed without blocking.
64
- 2. **Plan.** Fill `01-plan.md`: approach, affected areas, risks, test strategy,
78
+ 2. **Discover (optional, read-only).** When the goal, the solution, or the
79
+ terrain is unclear, send the explorer subagent before planning. Fold its
80
+ findings into a "Terrain" section of `01-plan.md`. Skip this step when the
81
+ change is well understood. If the explorer surfaces a question only the
82
+ operator can answer, ask the operator instead of guessing.
83
+ 3. **Plan.** Fill `01-plan.md`: approach, affected areas, risks, test strategy,
65
84
  rollback considerations where relevant.
66
- 3. **Slice tasks.** For non-trivial changes, fill `02-tasks.md`. Delegate to
85
+ 4. **Slice tasks.** For non-trivial changes, fill `02-tasks.md`. Delegate to
67
86
  the task-slicer subagent when the change is large enough to benefit. Each
68
87
  task carries: id, goal, relevant files, acceptance criteria, constraints,
69
88
  suggested tests, dependencies, risk.
70
- 4. **Validate tasks.** Check the slices are independently understandable, small
89
+ 5. **Validate tasks.** Check the slices are independently understandable, small
71
90
  enough, testable, ordered correctly, and aligned with the goal. Fix the
72
91
  slicing before any implementation starts.
73
- 5. **Delegate implementation.** Send each implementer subagent one narrow task
92
+ 6. **Delegate implementation.** Send each implementer subagent one narrow task
74
93
  contract (format below). Record meaningful decisions in `03-decisions.md`
75
94
  and consolidate evidence in `04-implementation-summary.md`.
76
- 6. **Delegate review.** Send the diff to the reviewer subagent. The reviewer
95
+ 7. **Delegate review.** Send the diff to the reviewer subagent. The reviewer
77
96
  checks spec compliance, architecture consistency, edge cases, security,
78
97
  test adequacy (including whether new tests would fail if the change were
79
98
  reverted), and maintainability. Findings go to `05-review-findings.md`.
80
- 7. **Decide acceptance.** Accept, request fixes, defer a known issue, or
99
+ 8. **Decide acceptance.** Accept, request fixes, defer a known issue, or
81
100
  escalate to the operator. Record the decision in `03-decisions.md`.
82
- 8. **Hand off.** Fill `06-handoff.md` and report to the operator: what changed,
101
+ 9. **Hand off.** Fill `06-handoff.md` and report to the operator: what changed,
83
102
  why, how it was verified, known risks, suggested next step.
84
103
 
104
+ ## Explorer output contract
105
+
106
+ ```yaml
107
+ status: done | partial | blocked
108
+ role: explorer
109
+ summary:
110
+ - ""
111
+ relevant_terrain:
112
+ - path: ""
113
+ role: ""
114
+ notes: ""
115
+ how_it_connects:
116
+ - ""
117
+ constraints_and_conventions:
118
+ - ""
119
+ solution_options:
120
+ - option: ""
121
+ pros:
122
+ - ""
123
+ cons:
124
+ - ""
125
+ risk: low | medium | high
126
+ open_questions:
127
+ - ""
128
+ recommendation: ""
129
+ ```
130
+
85
131
  ## Subagent input contract
86
132
 
87
133
  ```yaml
88
- role: implementer | reviewer | task_slicer
134
+ role: explorer | implementer | reviewer | task_slicer
89
135
  task_id: T-000
90
136
  goal: ""
91
137
  context:
@@ -184,7 +230,8 @@ open_questions:
184
230
  ## Harness notes
185
231
 
186
232
  - **Claude Code**: spawn the installed `.claude/agents/` subagents
187
- (task-slicer, implementer, reviewer) via the native subagent mechanism.
233
+ (explorer, task-slicer, implementer, reviewer) via the native subagent
234
+ mechanism.
188
235
  - **opencode**: invoke the installed `.opencode/agents/` subagents
189
236
  (`mode: subagent`).
190
237
  - **OpenAI Codex**: there is no standardized project-level subagent definition
@@ -4,6 +4,11 @@
4
4
 
5
5
  <!-- Short summary of the intended approach. -->
6
6
 
7
+ ## Terrain
8
+
9
+ <!-- Optional. Discovery findings from the explorer subagent: what exists,
10
+ how it connects, constraints to respect. Omit when no discovery was needed. -->
11
+
7
12
  ## Affected Areas
8
13
 
9
14
  - <!-- area/file/module -->
package/dist/init.js CHANGED
@@ -3,7 +3,7 @@ import { existsSync, readFileSync, statSync } from "node:fs";
3
3
  import { isAbsolute, join, normalize, sep } from "node:path";
4
4
  import { PACKAGE_VERSION, listTemplateNames, readAgentAsset, readAsset, } from "./assets.js";
5
5
  import { HARNESSES } from "./detect.js";
6
- import { ROLES, assertValidModelId, claudeModelValue, opencodeModelValue, } from "./models.js";
6
+ import { READ_ONLY_ROLES, ROLES, assertValidModelId, claudeModelValue, opencodeModelValue, } from "./models.js";
7
7
  import { emptyReport, ensureClaudeImport, installFile, upsertMarkerSection, } from "./writers.js";
8
8
  const SKILL_NAME = "orchestrator-workflow";
9
9
  const MANIFEST_PATH = join(".ai", "workflow", "manifest.json");
@@ -84,29 +84,32 @@ function yamlQuote(value) {
84
84
  }
85
85
  function composeClaudeAgent(role, model) {
86
86
  const asset = readAgentAsset(role);
87
- return [
87
+ const frontmatter = [
88
88
  "---",
89
89
  `name: ${asset.name}`,
90
90
  `description: ${yamlQuote(asset.description)}`,
91
91
  `model: ${claudeModelValue(model)}`,
92
- "---",
93
- "",
94
- asset.body.trimEnd(),
95
- "",
96
- ].join("\n");
92
+ ];
93
+ // Read-only roles keep every read/search tool but cannot mutate files.
94
+ if (READ_ONLY_ROLES.has(role)) {
95
+ frontmatter.push("disallowedTools: Edit, Write, NotebookEdit");
96
+ }
97
+ frontmatter.push("---");
98
+ return [...frontmatter, "", asset.body.trimEnd(), ""].join("\n");
97
99
  }
98
100
  function composeOpencodeAgent(role, model) {
99
101
  const asset = readAgentAsset(role);
100
- return [
102
+ const frontmatter = [
101
103
  "---",
102
104
  `description: ${yamlQuote(asset.description)}`,
103
105
  "mode: subagent",
104
106
  `model: ${opencodeModelValue(model)}`,
105
- "---",
106
- "",
107
- asset.body.trimEnd(),
108
- "",
109
- ].join("\n");
107
+ ];
108
+ if (READ_ONLY_ROLES.has(role)) {
109
+ frontmatter.push("permission:", " edit: deny");
110
+ }
111
+ frontmatter.push("---");
112
+ return [...frontmatter, "", asset.body.trimEnd(), ""].join("\n");
110
113
  }
111
114
  export function runInit(options) {
112
115
  const { targetDir } = options;
package/dist/models.d.ts CHANGED
@@ -1,5 +1,10 @@
1
- export type Role = "task-slicer" | "implementer" | "reviewer";
1
+ export type Role = "explorer" | "task-slicer" | "implementer" | "reviewer";
2
2
  export declare const ROLES: Role[];
3
+ /**
4
+ * Roles that map the terrain or judge work without changing it. They are
5
+ * installed with a read-only posture (no file-mutation tools).
6
+ */
7
+ export declare const READ_ONLY_ROLES: ReadonlySet<Role>;
3
8
  export type ModelAlias = "sonnet" | "opus" | "haiku";
4
9
  export declare const MODEL_ALIASES: ModelAlias[];
5
10
  /**
package/dist/models.js CHANGED
@@ -1,10 +1,21 @@
1
- export const ROLES = ["task-slicer", "implementer", "reviewer"];
1
+ export const ROLES = [
2
+ "explorer",
3
+ "task-slicer",
4
+ "implementer",
5
+ "reviewer",
6
+ ];
7
+ /**
8
+ * Roles that map the terrain or judge work without changing it. They are
9
+ * installed with a read-only posture (no file-mutation tools).
10
+ */
11
+ export const READ_ONLY_ROLES = new Set(["explorer"]);
2
12
  export const MODEL_ALIASES = ["sonnet", "opus", "haiku"];
3
13
  /**
4
14
  * Per-role defaults. The orchestrator itself runs on the session model and is
5
15
  * deliberately not configured here.
6
16
  */
7
17
  export const DEFAULT_MODELS = {
18
+ explorer: "sonnet",
8
19
  "task-slicer": "sonnet",
9
20
  implementer: "sonnet",
10
21
  reviewer: "opus",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orchestrator-workflow",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Installer for an orchestrator-led agent workflow: .ai/ run state, an AGENTS.md policy section, and per-harness subagent definitions for Claude Code, OpenAI Codex, and opencode",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",