rl-workspaces 0.5.0 → 0.6.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 +173 -141
- package/dist/agent-presets.js +42 -17
- package/dist/agent-runner.js +20 -0
- package/dist/agent-workflows.js +60 -16
- package/dist/automation-config.js +144 -5
- package/dist/git-workflow.js +8 -102
- package/dist/help.js +32 -32
- package/dist/session-workflows.js +51 -17
- package/dist/workflow-collaboration.js +531 -0
- package/lib/rl.zsh +3 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ Install from npm:
|
|
|
18
18
|
npm install --global rl-workspaces
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
See Development below to build and try unpublished changes.
|
|
22
22
|
|
|
23
23
|
Add one line to your shell configuration, then open a new terminal:
|
|
24
24
|
|
|
@@ -173,21 +173,14 @@ deleted automatically.
|
|
|
173
173
|
|
|
174
174
|
## Finish a feature
|
|
175
175
|
|
|
176
|
+
Use Git directly to inspect changes, commit, rebase, or squash feature history.
|
|
177
|
+
RL handles merging across checkouts and removing the finished workspace:
|
|
178
|
+
|
|
176
179
|
```sh
|
|
177
|
-
rl git diff --base origin/test -- --stat
|
|
178
|
-
rl git log --base origin/test -- --graph
|
|
179
|
-
rl git commit -m "Add login" # staged changes
|
|
180
|
-
rl git commit --all -m "Fix login" # tracked changes; untracked files require git add
|
|
181
|
-
rl git rebase --base origin/test
|
|
182
|
-
rl git squash --base origin/test -m "Add login"
|
|
183
180
|
rl git merge test --dry-run
|
|
184
181
|
rl git merge test --cleanup
|
|
185
182
|
```
|
|
186
183
|
|
|
187
|
-
Git mutation commands also accept `--dry-run`. Rebase and squash require a clean
|
|
188
|
-
workspace. Squash preserves the original HEAD under a printed
|
|
189
|
-
`refs/rl/backups/<UUID>` ref; it rewrites local feature history without pushing.
|
|
190
|
-
|
|
191
184
|
Merge targets a checked-out local branch in the main or a managed checkout.
|
|
192
185
|
It requires clean source and target workspaces and defaults to fast-forward only.
|
|
193
186
|
For an explicit squash merge, use `rl git merge test --squash -m "Add login"`.
|
|
@@ -388,176 +381,215 @@ and [Claude hooks](https://code.claude.com/docs/en/hooks) contracts.
|
|
|
388
381
|
|
|
389
382
|
## Session-driven agent workflows
|
|
390
383
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
384
|
+
An adopted workspace has a built-in `writer-reviewer-dry` workflow immediately,
|
|
385
|
+
without creating configuration files. Your current Codex or Claude session
|
|
386
|
+
creates and controls its native children. RL supplies their editable roles,
|
|
387
|
+
handoff rules, review policy and durable run records. RL never launches a
|
|
388
|
+
provider CLI, model API or check process for a workflow.
|
|
389
|
+
|
|
390
|
+
The default team starts together and stays available for the task:
|
|
391
|
+
|
|
392
|
+
- **Writer** implements scoped changes. Before adding a function, it asks DRY
|
|
393
|
+
about existing implementations and waits for the answer. It submits stable
|
|
394
|
+
file groups to the reviewer, then fixes and resubmits rejected work.
|
|
395
|
+
- **Reviewer** stays read-only, reviews writer checkpoints and returns a rating
|
|
396
|
+
with evidence and actionable feedback. On suspected duplication it asks the
|
|
397
|
+
same DRY agent before returning its review.
|
|
398
|
+
- **DRY** stays read-only and serves both peers, returning paths, symbols,
|
|
399
|
+
behavioral differences and reuse options, or explicitly reporting that no
|
|
400
|
+
suitable implementation was found.
|
|
401
|
+
|
|
402
|
+
Submitted files stay frozen while awaiting review; the writer can work on
|
|
403
|
+
unrelated files meanwhile. Ratings apply to saved file contents and staged
|
|
404
|
+
versions. RL rejects changed or superseded checkpoints and requires current
|
|
405
|
+
accepted reviews for the writer's changes before completion. The defaults are
|
|
406
|
+
**90/100** and at most **five review rounds** per file group. Required fixes
|
|
407
|
+
and incomplete coverage block acceptance regardless of rating. Pending check
|
|
408
|
+
requests or routing leads must be resolved before a checkpoint can be accepted.
|
|
396
409
|
|
|
397
410
|
```sh
|
|
398
|
-
rl workflow
|
|
399
|
-
rl agent add auth --instructions auth-review.md --description "Authentication reviewer"
|
|
411
|
+
rl workflow context --json # discover active definitions and their source
|
|
400
412
|
rl agent list
|
|
401
|
-
rl agent show
|
|
402
|
-
rl workflow add auth-review --file auth-workflow.json
|
|
403
|
-
rl workflow set auth-review --file auth-workflow.json
|
|
404
|
-
rl workflow context --json # discover definitions and trigger rules
|
|
405
|
-
rl workflow status # latest saved run
|
|
406
|
-
rl workflow metrics
|
|
413
|
+
rl agent show writer
|
|
407
414
|
rl policy show review
|
|
415
|
+
rl workflow init # write editable copies and refresh workspace hooks
|
|
416
|
+
rl agent set writer --instructions writer.md
|
|
417
|
+
rl workflow set writer-reviewer-dry --file workflow.json --default
|
|
418
|
+
rl workflow status # latest saved run and checkpoint ratings
|
|
419
|
+
rl workflow metrics
|
|
408
420
|
```
|
|
409
421
|
|
|
410
|
-
|
|
422
|
+
Export a definition before editing it:
|
|
423
|
+
`rl workflow show writer-reviewer-dry --json > workflow.json`.
|
|
424
|
+
`agent set --instructions` preserves the profile's other settings. Complete
|
|
425
|
+
profiles can be saved with `rl agent set writer --file profile.json`.
|
|
426
|
+
Use `rl agent add` and `rl workflow add` to create additional definitions.
|
|
427
|
+
|
|
428
|
+
Configuration stays in this worktree. The three concerns remain separate:
|
|
411
429
|
|
|
412
430
|
| File | Owns |
|
|
413
431
|
| --- | --- |
|
|
414
|
-
| `.rl/agents.json` | Roles: description, instructions, optional model/reasoning and
|
|
415
|
-
| `.rl/agent-workflows.json` |
|
|
416
|
-
| `.rl/policies.json` |
|
|
432
|
+
| `.rl/agents.json` | Roles: description, instructions, optional model/reasoning and access preferences; provider defaults to inherit |
|
|
433
|
+
| `.rl/agent-workflows.json` | Default workflow, triggers, dependencies, concurrency, retries, deadlines, collaboration routes and review rounds |
|
|
434
|
+
| `.rl/policies.json` | Review criteria, rating scale/threshold, severity deduction weights and acceptance requirements |
|
|
417
435
|
|
|
418
436
|
Each file has `"version": 1` and a named `agents`, `workflows` or `policies` map.
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
Prompt hooks refresh it after configuration changes, including after compaction.
|
|
428
|
-
Tool hooks deliver matching requests as the parent works. Before-edit/tool rules
|
|
429
|
-
deny the pending tool until their request completes or is explicitly dismissed
|
|
430
|
-
(or the user cancels its run), so the parent can delegate before retrying.
|
|
431
|
-
Workflow coordination tools are excluded from this gate. The preset queues
|
|
432
|
-
`triple-review` before finishing changed work: behavior/security, reuse/complexity
|
|
433
|
-
and implementation-quality roles, all read-only. Child hooks do not recursively
|
|
434
|
-
queue workflows. Normal session resume and task checkpoints remain independent.
|
|
435
|
-
|
|
436
|
-
For example, save the following as `auth-workflow.json`, then add it using the
|
|
437
|
-
command above:
|
|
437
|
+
The workflow file also accepts `"default": "writer-reviewer-dry"`; use
|
|
438
|
+
`workflow add/set --default` to select a different default. Existing explicit
|
|
439
|
+
configurations are preserved, including workspaces with partial legacy settings.
|
|
440
|
+
A missing file uses built-in definitions, which
|
|
441
|
+
are active for automatic triggers too. Run `workflow init` only when you want
|
|
442
|
+
editable copies and none of the three files exists yet.
|
|
443
|
+
|
|
444
|
+
The default workflow's `collaboration` section is editable:
|
|
438
445
|
|
|
439
446
|
```json
|
|
440
447
|
{
|
|
441
|
-
"
|
|
442
|
-
"
|
|
443
|
-
"
|
|
444
|
-
"
|
|
445
|
-
"
|
|
446
|
-
|
|
447
|
-
{ "
|
|
448
|
-
{ "event": "before_finish", "changes": true },
|
|
449
|
-
{ "event": "task_planned" }
|
|
450
|
-
],
|
|
451
|
-
"steps": [
|
|
452
|
-
{ "id": "types", "command": ["pnpm", "tsc", "--noEmit"], "after": [] },
|
|
453
|
-
{ "id": "auth", "agent": "auth", "after": ["types"] },
|
|
454
|
-
{ "id": "quality", "agent": "quality", "after": ["types"] }
|
|
448
|
+
"writer": "writer",
|
|
449
|
+
"reviewer": "reviewer",
|
|
450
|
+
"dry": "dry",
|
|
451
|
+
"maxRounds": 5,
|
|
452
|
+
"rules": [
|
|
453
|
+
{ "from": "writer", "event": "new_function", "to": "dry", "required": true },
|
|
454
|
+
{ "from": "reviewer", "event": "suspected_duplicate", "to": "dry", "required": true }
|
|
455
455
|
]
|
|
456
456
|
}
|
|
457
457
|
```
|
|
458
458
|
|
|
459
|
+
These names refer to step IDs. All three collaboration steps must be ready at
|
|
460
|
+
startup with concurrency at least three; reviewer and DRY must be read-only.
|
|
461
|
+
Change routes, requirements, review rounds, triggers and profiles as needed.
|
|
462
|
+
Required gates support writer `new_function` and reviewer `suspected_duplicate`;
|
|
463
|
+
additional event routes can be added with `required: false` for optional messaging.
|
|
464
|
+
Other workflows can use sequential/parallel dependencies and parent-run command
|
|
465
|
+
steps without collaboration. A writing stage runs exclusively in those workflows;
|
|
466
|
+
explicit dependency results are shared and independent reviews remain isolated.
|
|
467
|
+
|
|
468
|
+
The separate policy has a `rating` object with `min`, `max`, `minimum` and
|
|
469
|
+
`instructions`. Agents use that rubric to rate checkpoints. RL also calculates
|
|
470
|
+
a separate score from findings: the default deducts 50/20/10/2 for
|
|
471
|
+
critical/high/medium/low findings, deduplicates exact file/line/root-cause matches,
|
|
472
|
+
and blocks readiness on required fixes or coverage gaps. `rl workflow score`
|
|
473
|
+
rescores saved evidence without agent calls. Native model/reasoning settings are
|
|
474
|
+
preferences applied by the parent where supported; unsupported settings must be
|
|
475
|
+
reported. Provider preferences never authorize another provider process.
|
|
476
|
+
|
|
477
|
+
Session-start hooks identify the active configuration and teach the parent the
|
|
478
|
+
protocol. Prompt hooks refresh it after configuration changes and compaction.
|
|
479
|
+
The default queues the team at the parent's `task_planned` coding milestone or
|
|
480
|
+
before its first edit. Before-edit/tool rules deny the pending tool until their
|
|
481
|
+
request completes, is explicitly dismissed or its run is cancelled. Coordination
|
|
482
|
+
tools are excluded from this gate. Child hooks do not recursively queue teams.
|
|
483
|
+
Normal session resume and task checkpoints remain independent.
|
|
484
|
+
|
|
459
485
|
Automatic events are `session_start`, `prompt`, `before_edit`, `after_edit`,
|
|
460
|
-
`before_tool`, `after_tool
|
|
486
|
+
`before_tool`, `after_tool` and `before_finish`. Edit events recognize
|
|
461
487
|
Edit/Write/MultiEdit/apply_patch; other tools, including shell commands, use the
|
|
462
488
|
tool events. `tools` matches exact hook tool names; `paths` matches workspace
|
|
463
|
-
relative
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
Matching events queue requests for that parent conversation only. Identical
|
|
489
|
+
relative paths with `*` and `**`. Path filtering reads structured edit paths
|
|
490
|
+
and patch headers, without guessing about shell commands. `changes: true`
|
|
491
|
+
requires changes in the local comparison scope. Semantic events such as
|
|
492
|
+
`task_planned` are reported by the parent, since RL cannot observe private
|
|
493
|
+
reasoning. All conditions on a rule must match; multiple rules are alternatives.
|
|
494
|
+
|
|
495
|
+
Matching requests belong to that parent conversation only. Identical
|
|
471
496
|
scope/configuration events are deduplicated; newer changes coalesce into an
|
|
472
|
-
unclaimed request. Before-finish hooks can continue the turn once
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
to every child. Read-only roles receive instructions to remain read-only; host
|
|
478
|
-
permissions are enforced by the host, not by RL.
|
|
497
|
+
unclaimed request. Before-finish hooks can continue the turn once, guarding
|
|
498
|
+
against repeated Stop-hook loops. If native delegation is unavailable or
|
|
499
|
+
disallowed, the session must dismiss the request with its concrete reason and
|
|
500
|
+
report that limitation. Current permissions and workspace boundaries apply to
|
|
501
|
+
every child. Host permissions are enforced by the host.
|
|
479
502
|
|
|
480
503
|
The MCP server (`rl agent mcp`) exposes:
|
|
481
504
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
505
|
+
| Tool | Purpose |
|
|
506
|
+
| --- | --- |
|
|
507
|
+
| `rl_workflow_context` | Discover roles, workflows, triggers, policies and configuration source |
|
|
508
|
+
| `rl_workflow_pending` | Read this parent's queued requests |
|
|
509
|
+
| `rl_workflow_event` | Report a milestone and match trigger rules |
|
|
510
|
+
| `rl_workflow_start` | Prepare a session-owned run, optionally from a request |
|
|
511
|
+
| `rl_workflow_claim` | Claim a ready step and receive its prompt, scope, result schema and native settings |
|
|
512
|
+
| `rl_workflow_report` | Return final evidence, actual check output or failure with the claim token |
|
|
513
|
+
| `rl_workflow_dismiss` | Decline a queued request with a recorded reason |
|
|
514
|
+
| `rl_workflow_bind` | Bind a claimed role to its unique native child ID |
|
|
515
|
+
| `rl_workflow_inbox` | Read that role's consultations, submissions, ratings and peer handles |
|
|
516
|
+
| `rl_workflow_consult` | Ask an existing peer through a configured route |
|
|
517
|
+
| `rl_workflow_answer` | Answer a consultation addressed to that role |
|
|
518
|
+
| `rl_workflow_submit` | Submit a writer checkpoint and declare new functions as path#function subjects |
|
|
519
|
+
| `rl_workflow_review` | Return a rating, rationale, evidence and declared duplicate suspicions |
|
|
520
|
+
|
|
521
|
+
The parent claims, spawns and binds all three peers, then announces readiness.
|
|
522
|
+
Handoff tools return a `notify` destination with the peer's native handle. The
|
|
523
|
+
caller delivers it through native messaging or asks the parent to relay it.
|
|
524
|
+
RL persists the handoff; it cannot wake native children on its own. Peers use
|
|
525
|
+
native wait/messaging tools while idle. Finish the writer first, then reviewer,
|
|
526
|
+
then DRY, reporting final evidence through `rl_workflow_report`.
|
|
527
|
+
|
|
528
|
+
RL verifies answered consultations for declared new functions and duplicate
|
|
529
|
+
suspicions. Identifying those semantic events and declaring them honestly is
|
|
530
|
+
the agents' responsibility; RL cannot independently prove that every new
|
|
531
|
+
function was declared.
|
|
532
|
+
|
|
533
|
+
Supply `agent` and the parent's full `sessionId`; Codex may infer its ID from
|
|
534
|
+
the environment, while Claude supplies its UUID explicitly. Observed Codex
|
|
535
|
+
`thr_` IDs also coordinate workflows, but never enter UUID-based resumable
|
|
536
|
+
history. These are local coordination identities, not an authentication boundary
|
|
537
|
+
against a process that already has access to the state files.
|
|
538
|
+
|
|
539
|
+
CLI equivalents are available without an MCP connection:
|
|
499
540
|
|
|
500
541
|
```sh
|
|
501
542
|
rl workflow pending --agent claude --session <UUID>
|
|
502
|
-
rl workflow run --request <request-UUID> --agent claude --session <UUID>
|
|
503
543
|
rl workflow event --file event.json --agent claude --session <UUID>
|
|
504
|
-
rl workflow run
|
|
505
|
-
rl workflow claim <run> --agent claude --session <UUID>
|
|
544
|
+
rl workflow run --request <request-UUID> --agent claude --session <UUID>
|
|
545
|
+
rl workflow claim <run> --step writer --agent claude --session <UUID>
|
|
546
|
+
rl workflow bind <run> --file binding.json --agent claude --session <UUID>
|
|
547
|
+
rl workflow inbox <run> --step writer --claim <token> --agent claude --session <UUID>
|
|
506
548
|
rl workflow report <run> --file report.json --agent claude --session <UUID>
|
|
507
549
|
```
|
|
508
550
|
|
|
509
|
-
An event file contains `{ "event": "task_planned" }
|
|
510
|
-
`step`, `claim
|
|
511
|
-
`
|
|
512
|
-
|
|
513
|
-
`
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
predecessor results are supplied to dependent agents; independent roles receive
|
|
518
|
-
no peer reports. A failed check blocks dependents. Reported agent failures may
|
|
519
|
-
be retried within the configured budget. Routing leads receive one focused
|
|
520
|
-
follow-up by their owning role. Further leads remain coverage limitations.
|
|
551
|
+
An event file contains `{ "event": "task_planned" }`. Binding files contain
|
|
552
|
+
`step`, `claim` and `childId`. CLI equivalents for `consult`, `answer`,
|
|
553
|
+
`submit` and `review` take `--file` with the same tool fields. Each role's
|
|
554
|
+
prompt supplies its claim token and parent conversation identity. Final reports
|
|
555
|
+
contain `step`, `claim` and `result` (the supplied schema), or an actual
|
|
556
|
+
`check` result or `error`. Reports may include native `childId` and token/cost
|
|
557
|
+
usage. `workflow run` prepares work without spawning agents; `--dry-run`
|
|
558
|
+
previews the scope without creating a run.
|
|
521
559
|
|
|
522
560
|
Review scope includes committed branch changes from the merge-base, staged,
|
|
523
|
-
unstaged and non-ignored untracked changes, capped at 4 MiB.
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
and
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
new run. Neither command sends process signals. Runs retain their parent UUID,
|
|
545
|
-
claim tokens, native child IDs, evidence, scope and policy assessments under the
|
|
546
|
-
current instance's `workflow-runs/` directory. RL measures claim-to-report elapsed
|
|
547
|
-
time; token/cost usage is parent-reported and missing totals remain unknown.
|
|
561
|
+
unstaged and non-ignored untracked changes, capped at 4 MiB. Bases use local refs
|
|
562
|
+
without fetching; event detection falls back to HEAD if the saved base is
|
|
563
|
+
unresolvable. Generic workflows validate whole-scope fingerprints; collaborative
|
|
564
|
+
reviews validate each saved file group while implementation continues. Initial
|
|
565
|
+
unrelated dirty files need no submission unless changed during the run. RL
|
|
566
|
+
refreshes the whole scope when the writer closes and verifies it for remaining
|
|
567
|
+
final reports. Earlier checks/reviews in generic workflows remain historical
|
|
568
|
+
after writing; place final validation after the writer. Failed checks block
|
|
569
|
+
dependents. Reported failures can be retried within the configured budget.
|
|
570
|
+
Generic routing leads receive one focused follow-up; further leads remain
|
|
571
|
+
limitations. Collaborative peers handle consultations without replacement stages.
|
|
572
|
+
|
|
573
|
+
`workflow pause` stops new claims and submissions but lets claimed children
|
|
574
|
+
report and finish pending answers/reviews. The parent owns child cancellation.
|
|
575
|
+
`workflow resume` lets collaborative peers continue with the same claims and
|
|
576
|
+
native handles. Generic workflows require running children to report first.
|
|
577
|
+
Cancellation rejects further results and requires a new run. Neither command
|
|
578
|
+
sends process signals. Run records retain the parent identity, native IDs,
|
|
579
|
+
claims, evidence, checkpoints and assessments under this instance's
|
|
580
|
+
`workflow-runs/` directory. RL measures claim-to-report elapsed time; token/cost
|
|
581
|
+
usage is parent-reported and missing totals remain unknown.
|
|
548
582
|
|
|
549
583
|
After upgrading existing workspaces, run `rl doctor --repair` to add tool hooks,
|
|
550
|
-
and restart/review hooks as required by your host.
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
exercise hook payloads and MCP/CLI coordination; they do not certify live model
|
|
554
|
-
compliance or native delegation availability in every client.
|
|
584
|
+
and restart/review hooks as required by your host. Automated tests exercise
|
|
585
|
+
hook payloads and MCP/CLI coordination; they do not certify live model compliance
|
|
586
|
+
or native delegation availability in every client.
|
|
555
587
|
|
|
556
588
|
## Let agents use notes through MCP
|
|
557
589
|
|
|
558
590
|
`rl agent mcp` serves workspace-scoped tools over stdio: `rl_status`, `rl_context`,
|
|
559
591
|
`rl_progress`, `rl_context_append`, `rl_progress_append`, `rl_session_save`,
|
|
560
|
-
`rl_task_pause`, and the
|
|
592
|
+
`rl_task_pause`, and the thirteen `rl_workflow_*` coordination tools described above.
|
|
561
593
|
`rl_task_pause` accepts the handoff JSON described above and atomically saves
|
|
562
594
|
the session and task checkpoint. `rl_status` includes task state and handoff history.
|
|
563
595
|
`rl_status` automatically discovers Codex sessions for this workspace.
|
|
@@ -672,7 +704,7 @@ keep one primary spelling for each operation:
|
|
|
672
704
|
|
|
673
705
|
| Previous command | Primary command |
|
|
674
706
|
| --- | --- |
|
|
675
|
-
| `rl
|
|
707
|
+
| `rl merge` | `rl git merge` |
|
|
676
708
|
| `rl context/progress show/set/append/path` | `rl notes show/set/append/path context/progress` |
|
|
677
709
|
| `rl summary` | `rl notes summary` |
|
|
678
710
|
| `rl session list/save/add` | `rl agent sessions/save` |
|
package/dist/agent-presets.js
CHANGED
|
@@ -1,45 +1,70 @@
|
|
|
1
1
|
export const PRESET = {
|
|
2
|
+
defaultWorkflow: "writer-reviewer-dry",
|
|
2
3
|
agents: {
|
|
3
|
-
|
|
4
|
+
writer: {
|
|
4
5
|
provider: "inherit",
|
|
5
6
|
reasoning: "high",
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
access: "workspace-write",
|
|
8
|
+
description: "Implement scoped changes and submit review checkpoints",
|
|
9
|
+
instructions: "Own implementation in the assigned workspace and files. You are not alone: preserve other people's work and coordinate changes with the parent. Start alongside the reviewer and DRY peer; do not spawn replacement reviewers or searchers. Follow the workflow's configured consultation rules. By default, before adding any new function consult the existing DRY peer using event new_function and a precise subject such as src/file.ts#functionName, then wait for its answer and reuse existing behavior when appropriate. Submit bounded, stable file groups to the reviewer with all newFunctions declared. Freeze submitted files while a review is pending; you may continue on unrelated files. Address feedback and resubmit until the configured rating and policy requirements pass. Report actual checks, remaining work and limitations honestly. Do not close your stage until current changes have accepted reviews and your consultations are answered.",
|
|
8
10
|
},
|
|
9
|
-
|
|
11
|
+
reviewer: {
|
|
10
12
|
provider: "inherit",
|
|
11
13
|
reasoning: "high",
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
access: "read-only",
|
|
15
|
+
description: "Review writer submissions and return evidence-backed ratings",
|
|
16
|
+
instructions: "Stay read-only and available alongside the writer and DRY peer. Review each writer submission against its saved checkpoint, surrounding source, intended behavior and the separate policy. Assess correctness, authorization, persistence, concurrency, type contracts and meaningful validation. Return a rating and rationale using the configured rating scale, with structured findings, coverage limitations and required fixes. Follow the workflow's configured consultation rules. By default, if you suspect duplication consult the existing DRY peer using event suspected_duplicate and a precise subject before returning the review. Declare every duplicateSuspicions subject. Incorporate its evidence rather than treating similarity as proof. Send actionable feedback to the writer, re-review resubmissions, and never equate missing evidence with a clean result. Do not edit code, silently replace peers, or finish before the writer and all submitted work are settled.",
|
|
14
17
|
},
|
|
15
|
-
|
|
18
|
+
dry: {
|
|
16
19
|
provider: "inherit",
|
|
17
20
|
reasoning: "high",
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
access: "read-only",
|
|
22
|
+
description: "Shared reuse and duplication specialist for writer and reviewer",
|
|
23
|
+
instructions: "Stay read-only and available as the single DRY peer for both writer and reviewer. You may map relevant existing utilities while waiting for requests. Answer new_function consultations from the writer before it adds behavior, and suspected_duplicate consultations from the reviewer before it returns a rating. Search current source for existing functions, components, services, types and dependencies. Cite concrete paths/symbols, behavioral overlap, relevant differences and a viable reuse approach; state explicitly when no suitable implementation was found or coverage is incomplete. Small or superficial similarity alone is not evidence of harmful duplication. Respond to the requesting peer through its consultation record; do not edit files, assign ratings, create more agents, or close while requests or either peer remain active.",
|
|
20
24
|
},
|
|
21
25
|
},
|
|
22
26
|
policies: {
|
|
23
27
|
review: {
|
|
24
|
-
instructions: "Report
|
|
28
|
+
instructions: "Report evidence-backed defects caused or materially worsened by the submitted work. Separate required fixes from optional improvements, and explain prerequisites, expected behavior and observed or inferred failures. Evaluate reuse against concrete alternatives. Avoid style-only blockers and invented findings. Missing checks, dependencies and unverified material paths are coverage limitations. Review ratings are judgments supported by evidence; RL's policy score is calculated separately and is not a probability of correctness.",
|
|
25
29
|
weights: { critical: 50, high: 20, medium: 10, low: 2 },
|
|
26
30
|
minimumScore: 0,
|
|
27
31
|
blockRequired: true,
|
|
32
|
+
rating: {
|
|
33
|
+
min: 0,
|
|
34
|
+
max: 100,
|
|
35
|
+
minimum: 90,
|
|
36
|
+
instructions: "Rate each submission from 0 to 100. 90–100 means ready with verified material behavior and no required fixes; 70–89 needs contained corrections or validation; below 70 needs substantial corrections. Explain the rating and uncertainty. A high rating never overrides required fixes, failed checks or incomplete coverage.",
|
|
37
|
+
},
|
|
28
38
|
},
|
|
29
39
|
},
|
|
30
40
|
workflows: {
|
|
31
|
-
"
|
|
32
|
-
description: "
|
|
41
|
+
"writer-reviewer-dry": {
|
|
42
|
+
description: "Parallel writer, reviewer and DRY peers with rated review checkpoints",
|
|
33
43
|
policy: "review",
|
|
34
44
|
concurrency: 3,
|
|
35
45
|
retries: 1,
|
|
36
|
-
timeoutSeconds:
|
|
37
|
-
triggers: [{ event: "
|
|
46
|
+
timeoutSeconds: 3600,
|
|
47
|
+
triggers: [{ event: "task_planned" }, { event: "before_edit" }],
|
|
38
48
|
steps: [
|
|
39
|
-
{ id: "
|
|
40
|
-
{ id: "
|
|
41
|
-
{ id: "
|
|
49
|
+
{ id: "writer", agent: "writer", after: [] },
|
|
50
|
+
{ id: "reviewer", agent: "reviewer", after: [] },
|
|
51
|
+
{ id: "dry", agent: "dry", after: [] },
|
|
42
52
|
],
|
|
53
|
+
collaboration: {
|
|
54
|
+
writer: "writer",
|
|
55
|
+
reviewer: "reviewer",
|
|
56
|
+
dry: "dry",
|
|
57
|
+
maxRounds: 5,
|
|
58
|
+
rules: [
|
|
59
|
+
{ from: "writer", event: "new_function", to: "dry", required: true },
|
|
60
|
+
{
|
|
61
|
+
from: "reviewer",
|
|
62
|
+
event: "suspected_duplicate",
|
|
63
|
+
to: "dry",
|
|
64
|
+
required: true,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
},
|
|
43
68
|
},
|
|
44
69
|
},
|
|
45
70
|
};
|
package/dist/agent-runner.js
CHANGED
|
@@ -6,6 +6,7 @@ import { readJsonObject } from "./json.js";
|
|
|
6
6
|
import { validateAutomation, } from "./automation-config.js";
|
|
7
7
|
import { evaluate, validateResult, } from "./review-policy.js";
|
|
8
8
|
import { agentAdapter } from "./agent-registry.js";
|
|
9
|
+
import { collaborationAssessment, initializeCollaboration, validateCollaborationState, } from "./workflow-collaboration.js";
|
|
9
10
|
export function captureScope(cwd, base) {
|
|
10
11
|
if (!base || base.startsWith("-") || /[\x00-\x20\x7f]/.test(base))
|
|
11
12
|
throw new Error("Expected a literal base ref");
|
|
@@ -126,6 +127,8 @@ function load(directory) {
|
|
|
126
127
|
if (!Object.hasOwn(raw.config.workflows, raw.workflow))
|
|
127
128
|
throw new Error("Invalid saved workflow");
|
|
128
129
|
const definition = raw.config.workflows[raw.workflow];
|
|
130
|
+
if (definition.collaboration)
|
|
131
|
+
validateCollaborationState(raw.collaboration);
|
|
129
132
|
const seen = new Set();
|
|
130
133
|
for (const stage of raw.stages) {
|
|
131
134
|
if (!object(stage) ||
|
|
@@ -213,11 +216,14 @@ export function evaluation(run, policy = run.config.policies[run.config.workflow
|
|
|
213
216
|
stage.result !== undefined &&
|
|
214
217
|
currentScope(stage))
|
|
215
218
|
.map((stage) => ({ owner: stage.id, result: stage.result }));
|
|
219
|
+
const collaboration = collaborationAssessment(run);
|
|
220
|
+
reports.push(...collaboration.reports);
|
|
216
221
|
const limitations = run.stages
|
|
217
222
|
.filter((stage) => stage.status !== "completed")
|
|
218
223
|
.map((stage) => `${stage.id}: ${stage.error ?? stage.status}`);
|
|
219
224
|
if (run.status !== "completed")
|
|
220
225
|
limitations.push(`Run ${run.status}`);
|
|
226
|
+
limitations.push(...collaboration.limitations);
|
|
221
227
|
for (const stage of run.stages.filter((stage) => stage.status === "completed" && !currentScope(stage))) {
|
|
222
228
|
if (stage.agent &&
|
|
223
229
|
run.config.agents[stage.agent].access === "workspace-write")
|
|
@@ -269,6 +275,19 @@ export function runMetrics(run) {
|
|
|
269
275
|
outputTokens: total("outputTokens"),
|
|
270
276
|
costUsd: total("costUsd"),
|
|
271
277
|
usageCoverage: `${reported.length}/${run.stages.filter((step) => step.agent && step.attempts).length} agent stages`,
|
|
278
|
+
...(run.collaboration
|
|
279
|
+
? {
|
|
280
|
+
collaboration: {
|
|
281
|
+
consultations: run.collaboration.consultations.length,
|
|
282
|
+
awaitingAnswers: run.collaboration.consultations.filter((item) => !item.answer).length,
|
|
283
|
+
submissions: run.collaboration.submissions.length,
|
|
284
|
+
accepted: run.collaboration.submissions.filter((item) => !item.supersededBy && item.review?.accepted).length,
|
|
285
|
+
latestRating: [...run.collaboration.submissions]
|
|
286
|
+
.reverse()
|
|
287
|
+
.find((item) => item.review)?.review?.rating ?? null,
|
|
288
|
+
},
|
|
289
|
+
}
|
|
290
|
+
: {}),
|
|
272
291
|
stages: run.stages.map(({ id, status, attempts, durationMs, usage }) => ({
|
|
273
292
|
id,
|
|
274
293
|
status,
|
|
@@ -326,6 +345,7 @@ export function createRunLocked(store, config, workflow, base, prompt) {
|
|
|
326
345
|
durationMs: 0,
|
|
327
346
|
})),
|
|
328
347
|
};
|
|
348
|
+
initializeCollaboration(run);
|
|
329
349
|
fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
330
350
|
fs.writeFileSync(path.join(directory, "scope.json"), context, {
|
|
331
351
|
mode: 0o600,
|