symphony-orchestrator 0.1.3 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,69 +1,24 @@
1
- # Personal Symphony
1
+ # Symphony Orchestrator
2
2
 
3
- Personal Symphony is an installable `symphony` CLI for the Symphony service described in
4
- [Symphony SPEC](https://github.com/openai/symphony/blob/main/SPEC.md). The product repository keeps
5
- the OCaml backend, the ReScript React dashboard, and the npm launcher; each workspace repository gets
6
- its own repository-owned runtime contract under `.symphony/`.
7
-
8
- This implementation variant targets GitHub Issues plus GitHub Projects for issue tracking.
9
-
10
- ## Repository Layout
11
-
12
- - `apps/backend`: OCaml service, workflow loader, GitHub tracker boundary, workspace manager, HTTP
13
- state API, CLI, and tests.
14
- - `apps/frontend`: ReScript React/Vite dashboard that consumes the backend state API.
15
- - `.github/ISSUE_TEMPLATE`: issue template for work items Symphony can dispatch.
16
- - `.github/project-tracking.md`: required GitHub Project setup and workflow notes.
17
- - `WORKFLOW.example.md`: legacy/developer fixture for the earlier root workflow format.
18
- - `bin/symphony.js`: npm `bin` launcher that runs a packaged platform binary or the local dune
19
- executable in product-repository development.
3
+ Symphony Orchestrator is an installable `symphony` CLI for the Symphony service described in
4
+ [Symphony SPEC](https://github.com/openai/symphony/blob/main/SPEC.md). The Product Repository keeps
5
+ the OCaml backend, the ReScript React dashboard, and the npm launcher; each Workspace Repository gets
6
+ its own repository-owned Runtime Contract under `.symphony/`.
20
7
 
21
8
  ## Prerequisites
22
9
 
23
- - `pnpm` 10.x
24
- - OCaml toolchain with `opam`, `dune`, `cmdliner`, `yojson`, and `alcotest` for product-repository
25
- development only
26
10
  - GitHub CLI: `gh`
27
11
  - A GitHub personal access token available as `GITHUB_TOKEN` or `GH_TOKEN`
28
12
  - `codex` CLI available on `PATH` when running real agent sessions
29
13
 
30
- The local scripts run OCaml commands through `opam exec`, so make sure the active opam switch has
31
- the required packages installed.
32
-
33
14
  ## Install
34
15
 
35
16
  The npm package exposes a global `symphony` command:
36
17
 
37
18
  ```sh
38
- npm install -g symphony-orchestrator
39
- ```
40
-
41
- Published packages should include platform-specific binaries for Linux, macOS, and Windows:
42
-
43
- - `vendor/symphony-linux-x64`
44
- - `vendor/symphony-darwin-x64`
45
- - `vendor/symphony-darwin-arm64`
46
- - `vendor/symphony-win32-x64.exe`
47
-
48
- When running from this product repository, the Node launcher falls back to:
49
-
50
- ```sh
51
- opam exec -- dune exec symphony --
52
- ```
53
-
54
- Before publishing, run:
55
-
56
- ```sh
57
- pnpm npm:validate:release
19
+ npm i -g symphony-orchestrator
58
20
  ```
59
21
 
60
- The GitHub Actions `Export npm package` workflow builds those binaries on Linux, macOS, and Windows,
61
- assembles the npm tarball, uploads the tarball and binaries as a GitHub workflow artifact, and publishes
62
- the same files to a GitHub Release with the npm package URL. A `v*` tag uses that tag for the release;
63
- manual runs publish a `v<package.json version>` release when `publish_npm` is enabled and the repository
64
- has an `NPM_TOKEN` secret. The npm package is available at
65
- https://www.npmjs.com/package/symphony-orchestrator.
66
-
67
22
  ## Set Up In A Workspace Repository
68
23
 
69
24
  Run the command from the root of a Git repository:
@@ -73,8 +28,9 @@ symphony init
73
28
  symphony
74
29
  ```
75
30
 
76
- `symphony init` and the first `symphony` run are idempotent. They create missing runtime files under
77
- `.symphony/` without overwriting user-edited files:
31
+ `symphony init` and the first `symphony` run perform an Idempotent Bootstrap. They create missing
32
+ Runtime Home files under `.symphony/` without overwriting user-edited Runtime Contract or Local
33
+ Environment files:
78
34
 
79
35
  - `.symphony/settings.json`
80
36
  - `.symphony/prompt.md`
@@ -92,8 +48,9 @@ symphony
92
48
  /workspaces/
93
49
  ```
94
50
 
95
- Edit `.symphony/settings.json` to set the GitHub owner, repository, project number, project states,
96
- and runtime commands. Secrets are referenced by environment variable name, not stored in settings:
51
+ Edit `.symphony/settings.json` to set the GitHub owner, Workspace Repository name, GitHub Project
52
+ number, GitHub Project states, and runtime commands. Runtime Settings reference secrets by environment
53
+ variable name; secret values belong only in the Local Environment:
97
54
 
98
55
  ```json
99
56
  {
@@ -174,6 +131,7 @@ Configure or disable this in `.symphony/settings.json`:
174
131
  {
175
132
  "states": ["Backlog"],
176
133
  "agent": "planner",
134
+ "maxConcurrentAgents": 1,
177
135
  "skills": [],
178
136
  "successStatus": "To-Do",
179
137
  "retryStatus": "Backlog",
@@ -190,6 +148,7 @@ Configure or disable this in `.symphony/settings.json`:
190
148
  {
191
149
  "states": ["Todo", "To-Do", "In progress", "In Progress"],
192
150
  "agent": "engineer",
151
+ "maxConcurrentAgents": 2,
193
152
  "skills": [],
194
153
  "startStatus": "In progress",
195
154
  "successStatus": "In review",
@@ -207,6 +166,7 @@ Configure or disable this in `.symphony/settings.json`:
207
166
  {
208
167
  "states": ["In review", "In Review"],
209
168
  "agent": "reviewer",
169
+ "maxConcurrentAgents": 2,
210
170
  "skills": [],
211
171
  "successStatus": "Done",
212
172
  "retryStatus": "In progress",
@@ -227,6 +187,13 @@ Configure or disable this in `.symphony/settings.json`:
227
187
 
228
188
  Set `"enabled": false` to use the single base `.symphony/prompt.md` for every issue.
229
189
 
190
+ Set `maxConcurrentAgents` on a stage to configure a Stage Concurrency Policy for that Stage Agent.
191
+ The value is an optional positive integer. When omitted, that stage keeps global-only dispatch
192
+ admission. Stage caps share the global `agent.maxConcurrentAgents` ceiling, so the scheduler never
193
+ runs more total agents than the global cap permits. Stage caps are capacity limits only: Symphony
194
+ does not keep idle agents alive, and a stage with one dispatchable issue launches one agent even if
195
+ its stage cap is higher.
196
+
230
197
  Set `skills` to an ordered list of skill identifiers when a stage requires reusable Codex workflows.
231
198
  Runtime Settings store identifiers without `$`, for example `"to-prd"` or `"github:gh-fix-ci"`.
232
199
  When a matching Stage Agent runs, Symphony renders those as `$to-prd` style references in the normal
@@ -235,11 +202,13 @@ skill files and does not include Stage Skill Load in Stage Goal Context. Missing
235
202
  duplicate skill identifiers are Readiness Gaps; Symphony checks all configured stages before
236
203
  dispatch, resolving Workspace Repository skills before Codex Home skills.
237
204
 
205
+ Rendered Agent Prompts include GitHub issue comments as issue context in addition to the issue body.
206
+
238
207
  Set `goal.enabled` to `true` on a specific stage to enable Stage Goal Handoff for that stage only.
239
208
  When enabled, Symphony sends `/goal` with deterministic Stage Goal Context before the normal Agent
240
- Prompt. Stage Goal Context includes issue identifier, title, description, URL, current project
241
- status, labels, priority when present, blocker references when present, attempt, and stage agent
242
- name. It omits issue creation and update timestamps.
209
+ Prompt. Stage Goal Context includes issue identifier, title, description, comments, URL, current
210
+ GitHub Project status, labels, priority when present, blocker references when present, attempt, and
211
+ stage agent name. It omits issue creation and update timestamps.
243
212
 
244
213
  Stage Goal Handoff requires Codex goals in `~/.codex/config.toml`:
245
214
 
@@ -260,6 +229,31 @@ template supports `<type>`, `<generated_message_max_90char>`, `<issue_identifier
260
229
  branch after a successful stage commit and before the status transition; omitted values default to
261
230
  `false`.
262
231
 
232
+ ## Git Policy
233
+
234
+ The Git Policy controls Task Branch naming, Protected Trunk Branches, auto-merge behavior, the Human
235
+ Attention Status used for merge problems, and cleanup of merged Agent Worktrees:
236
+
237
+ ```json
238
+ {
239
+ "git": {
240
+ "taskBranchPrefix": "symphony/task-",
241
+ "protectedTrunkBranches": ["main", "master"],
242
+ "autoMerge": true,
243
+ "mergeAttentionStatus": "Human attention",
244
+ "cleanup": {
245
+ "removeWorktreeAfterMerge": true,
246
+ "keepTaskBranch": true
247
+ }
248
+ }
249
+ }
250
+ ```
251
+
252
+ Each dispatched issue runs in an Agent Worktree under `.symphony/workspaces/` on a Task Branch
253
+ created from the Loop-Start Branch. Symphony may fast-forward a completed Task Branch into the
254
+ Loop-Start Branch only when the Loop-Start Branch is not a Protected Trunk Branch. It never
255
+ force-pushes, and Stage Push is disabled unless a stage sets `commit.push` to `true`.
256
+
263
257
  ## Batch Pull Requests
264
258
 
265
259
  Symphony can optionally open one Batch Pull Request after Orchestration Idle, using the Loop-Start
@@ -269,6 +263,7 @@ Branch as the PR head. Automatic PR creation is disabled by default:
269
263
  {
270
264
  "pullRequest": {
271
265
  "enabled": false,
266
+ "openOnReview": false,
272
267
  "baseBranch": "main",
273
268
  "title": "Symphony batch from <head_branch>",
274
269
  "body": "Opened automatically by Symphony after orchestration became idle."
@@ -283,26 +278,31 @@ Failed pushes or PR creation attempts are recorded in Runtime State as retryable
283
278
  are retried on later idle polls. Symphony does not attempt a Batch Pull Request while any issue is in
284
279
  the configured Merge Attention Status or has unresolved orchestration attention.
285
280
 
281
+ Set `pullRequest.openOnReview` to `true` to open the same Batch Pull Request immediately after a
282
+ successful agent run has been committed, integrated into the Loop-Start Branch, and moved to the
283
+ configured review status. Later task integrations continue updating the same Loop-Start Branch and
284
+ the existing PR is reused.
285
+
286
286
  The `title` and `body` fields are deterministic templates. They support `<head_branch>` and
287
287
  `<base_branch>`; Symphony does not generate PR prose with an agent.
288
288
 
289
289
  ## GitHub Token Permissions
290
290
 
291
- Personal Symphony reads GitHub Issues and GitHub Projects. Use a **personal access token (classic)**
291
+ Symphony Orchestrator reads GitHub Issues and GitHub Projects. Use a **personal access token (classic)**
292
292
  when the GitHub Project is owned by a user account, such as `@your-user's Kanban`. GitHub
293
293
  fine-grained personal access tokens currently cannot access Projects owned by a user account.
294
294
 
295
295
  Recommended classic PAT scopes:
296
296
 
297
297
  - `repo`: required for private Workspace Repositories and repository Issues.
298
- - `read:project`: enough for readiness checks and read-only project polling.
299
- - `project`: required instead of `read:project` when Symphony will move project cards, update
300
- project fields, or otherwise write GitHub Projects data.
298
+ - `read:project`: enough for readiness checks and read-only GitHub Project polling.
299
+ - `project`: required instead of `read:project` when Symphony will move GitHub Project items,
300
+ update GitHub Project fields, or otherwise write GitHub Projects data.
301
301
 
302
- Classic PATs do **not** ask you to select individual repositories or projects. If GitHub shows a
303
- repository picker, project picker, "Resource owner", or "Repository access" section, you are creating
304
- a fine-grained token. Go back to **Personal access tokens > Tokens (classic) > Generate new token
305
- (classic)** for user-owned Projects.
302
+ Classic PATs do **not** ask you to select individual repositories or GitHub Projects. If GitHub
303
+ shows a repository picker, GitHub Project picker, "Resource owner", or "Repository access" section,
304
+ you are creating a fine-grained token. Go back to **Personal access tokens > Tokens (classic) >
305
+ Generate new token (classic)** for user-owned Projects.
306
306
 
307
307
  Fine-grained PATs are only suitable when the GitHub Project is owned by an organization and GitHub
308
308
  allows fine-grained tokens for that owner. Configure the token with:
@@ -315,75 +315,76 @@ allows fine-grained tokens for that owner. Configure the token with:
315
315
  Store the token in the Workspace Repository Local Environment:
316
316
 
317
317
  ```sh
318
- printf 'GITHUB_TOKEN=github_pat_...\n' > .symphony/.env
318
+ $EDITOR .symphony/.env
319
319
  ```
320
320
 
321
321
  `GITHUB_TOKEN` takes precedence over `GH_TOKEN`. If `gh auth status` shows a working stored token but
322
- Symphony still reports repository or project access gaps, remove the stale `GITHUB_TOKEN` from
323
- `.symphony/.env` or replace it with a token that has the scopes above.
322
+ Symphony still reports Workspace Repository or GitHub Project access gaps, remove the stale
323
+ `GITHUB_TOKEN` from `.symphony/.env` or replace it with a token that has the scopes above.
324
+
325
+ ## Repository Layout
326
+
327
+ - `apps/backend`: OCaml service, workflow loader, GitHub tracker boundary, workspace manager, HTTP
328
+ state API, CLI, and tests.
329
+ - `apps/frontend`: ReScript React/Vite dashboard that consumes the backend state API.
330
+ - `.github/ISSUE_TEMPLATE`: issue template for work items Symphony can dispatch.
331
+ - `.github/project-tracking.md`: required GitHub Project setup and workflow notes.
332
+ - `WORKFLOW.example.md`: legacy/developer fixture for the earlier root workflow format.
333
+ - `bin/symphony.js`: npm `bin` launcher that runs a packaged platform binary or the local dune
334
+ executable in Product Repository development.
324
335
 
325
336
  ## Product Repository Development
326
337
 
327
- 1. Install dependencies:
338
+ Product Repository development is separate from Workspace Repository operation. Runtime files for
339
+ actual orchestration belong in the Workspace Repository where `symphony init` is run; this source
340
+ repository keeps code, tests, packaging scripts, fixtures, and documentation.
328
341
 
329
- ```sh
330
- pnpm install
331
- ```
342
+ Product Repository development requires `pnpm` 10.x and an OCaml toolchain with `opam`, `dune`,
343
+ `cmdliner`, `yojson`, and `alcotest`. The local scripts run OCaml commands through `opam exec`, so
344
+ make sure the active opam switch has the required packages installed.
332
345
 
333
- 2. Optionally create a legacy workflow file for product-repository fixture runs:
346
+ Install dependencies:
334
347
 
335
- ```sh
336
- cp WORKFLOW.example.md WORKFLOW.md
337
- ```
348
+ ```sh
349
+ pnpm install
350
+ ```
338
351
 
339
- 3. Edit `WORKFLOW.md`:
352
+ Run the backend test suite:
340
353
 
341
- ```yaml
342
- tracker:
343
- kind: github
344
- owner: your-org
345
- repo: your-repo
346
- project_number: 1
347
- api_key: $GITHUB_TOKEN
348
- active_states: [Todo, In Progress]
349
- terminal_states: [Done, Closed, Cancelled]
350
- project_status_field: Status
351
- project_status_on_dispatch: In progress
352
- project_status_on_success: In review
353
- project_status_on_retry: Todo
354
- codex:
355
- command: codex exec
356
- model: gpt-5.5
357
- reasoning_effort: medium
358
- ```
354
+ ```sh
355
+ pnpm test
356
+ ```
359
357
 
360
- 4. Configure the GitHub Project:
358
+ Run frontend live-state tests:
361
359
 
362
- - Add a single-select `Status` field.
363
- - Add active values matching `active_states`, usually `Todo` and `In Progress`.
364
- - Add terminal values matching `terminal_states`, usually `Done`, `Closed`, and `Cancelled`.
365
- - Add or let Symphony create transition values such as `In progress` and `In review`.
366
- - Add repository issues to the project before expecting Symphony to pick them up.
360
+ ```sh
361
+ pnpm frontend:test
362
+ ```
367
363
 
368
- 5. Authenticate GitHub access:
364
+ Build frontend assets:
369
365
 
370
- ```sh
371
- gh auth status
372
- export GITHUB_TOKEN=...
373
- ```
366
+ ```sh
367
+ pnpm frontend:build
368
+ ```
374
369
 
375
- See "GitHub Token Permissions" above for the exact PAT scopes and fine-grained permissions.
370
+ Build the OCaml backend:
376
371
 
377
- ## Run Locally
372
+ ```sh
373
+ pnpm backend:build
374
+ ```
378
375
 
379
- Validate and build everything:
376
+ Build the package payload:
380
377
 
381
378
  ```sh
382
- pnpm test
383
- pnpm build
379
+ pnpm prepack
384
380
  ```
385
381
 
386
- Start the OCaml backend:
382
+ `WORKFLOW.example.md` remains only as a legacy fixture/import compatibility file for earlier root
383
+ workflow behavior. Do not use it as the active Workspace Repository Runtime Contract.
384
+
385
+ ## Run Locally
386
+
387
+ Start the backend dev server from the Product Repository root:
387
388
 
388
389
  ```sh
389
390
  pnpm backend:dev
@@ -391,11 +392,11 @@ pnpm backend:dev
391
392
 
392
393
  The backend serves:
393
394
 
394
- - Dashboard placeholder/API root: `http://127.0.0.1:8080/`
395
+ - Terminal Console/API root: `http://127.0.0.1:8080/`
395
396
  - Runtime state JSON: `http://127.0.0.1:8080/api/v1/state`
396
397
  - Tailscale/LAN access: `http://<machine-ip>:8080/` because the backend binds to `0.0.0.0`.
397
398
 
398
- Start the ReScript React frontend in another terminal:
399
+ Start the Web Dashboard dev server in another terminal:
399
400
 
400
401
  ```sh
401
402
  pnpm frontend:dev
@@ -409,17 +410,60 @@ http://127.0.0.1:5173/
409
410
 
410
411
  The frontend proxies `/api/*` requests to the backend at `127.0.0.1:8080`.
411
412
 
413
+ A packaged or dune-run CLI can also start the backend and Web Dashboard from a Workspace Repository:
414
+
415
+ ```sh
416
+ symphony --web --port 8080
417
+ ```
418
+
412
419
  ## Useful Commands
413
420
 
414
421
  ```sh
415
- pnpm backend:build
416
- pnpm backend:test
422
+ pnpm install
423
+ pnpm test
424
+ pnpm frontend:test
417
425
  pnpm frontend:build
426
+ pnpm backend:build
427
+ pnpm prepack
428
+ pnpm backend:dev
429
+ pnpm frontend:dev
430
+ ```
431
+
432
+ For direct Product Repository CLI checks:
433
+
434
+ ```sh
418
435
  opam exec -- dune exec symphony -- --once
419
436
  opam exec -- dune exec symphony -- init
420
437
  opam exec -- dune exec symphony -- --web --port 8080
421
- opam exec -- dune exec symphony -- --once WORKFLOW.md
422
438
  ```
423
439
 
424
440
  If no GitHub token is configured, the runtime still starts, but readiness gaps report the missing
425
441
  token and live issue dispatch is disabled.
442
+
443
+ ## Package Distribution
444
+
445
+ Published packages should include platform-specific binaries for Linux, macOS, and Windows:
446
+
447
+ - `vendor/symphony-linux-x64`
448
+ - `vendor/symphony-darwin-x64`
449
+ - `vendor/symphony-darwin-arm64`
450
+ - `vendor/symphony-win32-x64.exe`
451
+
452
+ When running from this Product Repository, the Node launcher falls back to:
453
+
454
+ ```sh
455
+ opam exec -- dune exec symphony --
456
+ ```
457
+
458
+ Before publishing, run:
459
+
460
+ ```sh
461
+ pnpm npm:validate:release
462
+ ```
463
+
464
+ The GitHub Actions `Export npm package` workflow builds those binaries on Linux, macOS, and Windows,
465
+ assembles the npm tarball, uploads the tarball and binaries as a GitHub workflow artifact, and
466
+ publishes the same files to a GitHub Release with the npm package URL. A `v*` tag uses that tag for
467
+ the release; manual runs publish a `v<package.json version>` release when `publish_npm` is enabled
468
+ and the repository has an `NPM_TOKEN` secret. The npm package is available at
469
+ https://www.npmjs.com/package/symphony-orchestrator.