- Wrap skill copying in copy_skills() helper function
- Call copy_skills() before early exit for lightweight states (Triage/Closure/Request Changes)
- Clone openclaw repo BEFORE copying skills (fixes empty-dir clone failure)
- Call copy_skills() AFTER clone + checkout for normal states
- Replace 'git pull --rebase origin HEAD' with 'git rebase origin/main' in before_run
- Add regression test to verify hook ordering in core_test.exs
- WORKFLOW.md: Prepare phase now generates executable test scripts in
.local/test-kit/ for PRs with API-observable behavioral changes
- common.sh template with gw_call() and assert_jq() helpers
- Numbered test scripts per scenario, independently runnable
- Linear comment includes worktree path to test-kit
- priv/scripts/test-gateway.sh: standalone tool to run a PR build
on alternate port (18790) without touching the production gateway
Supports start/stop/status/call subcommands
- Move skill copy before early-exit in after_create hook (fixes pr-cluster missing for Triage agents)
- Add Triage and Request Changes as active states
- Move enrichment template from Backlog to Triage
- Add prior GitHub CHANGES_REQUESTED review check to Triage template
- Require structured duplicate assessment comments on both duplicate paths
- Add Request Changes template (posts gh pr review, moves to Backlog)
- Add missing state IDs to states map (review, review_complete, prepare, prepare_complete)
- Default mix caclawphony.review to Triage state (--direct skips to Review)
- gitignore workspaces/
- Use {:map, :string, :any} and {:map, :string, :string} types for labels/states
- Return empty map instead of :omit when config sections are absent
- Fix test using self() as agent pid (causes EXIT shutdown)
- Update in-repo WORKFLOW.md integration tests to match current prompt
- Fix list ordering assertions for gate states (use Enum.sort)
- Add notifications section to WORKFLOW.yaml with telegram credentials and template
- Add gates section with state_id, assignee, and notify for each gate
- Add labels section with recommendation and subsystem label UUIDs
- Add states section for state name to ID mappings
- Add retry_base_ms and continuation_delay_ms to agent config
- Config module parses all new sections with env var resolution
- Notifier reads from Config instead of env vars directly
- Orchestrator uses Config for gate states and retry delays
- PromptBuilder exposes labels/gates/states as Solid template variables
- Tests cover all new config paths
Linear labels created:
- Recommendation: review (green), wait (yellow), skip (gray)
- Subsystem: gateway, channels, browser, agents, config, cli,
runtime, auth, providers, docs
Enrichment agent now sets all metadata in a single issueUpdate:
- Title with [REVIEW]/[WAIT]/[SKIP] prefix
- Priority (0-4 based on recommendation + scope)
- Estimate (Fibonacci complexity 1/2/3/5/8)
- Labels (one recommendation + matching subsystem labels)
- Assignee (Josh at human gates, for review queue filtering)
Review/Prepare phases also assign to maintainer at gate transitions.
Triage task gains --priority flag for manual override on intake.
Summary:
- remove workspaces directly from orchestrator terminal-state cleanup
- build cleanup path as Config.workspace_root() <> "/" <> issue identifier
- log workspace cleanup actions when terminal issues are detected
Rationale:
- enforce immediate workspace cleanup when Linear issues reach terminal states
- align cleanup path and deletion behavior with requested implementation
Tests:
- cd elixir && mix compile
- cd elixir && mix test (first run had one flaky timing failure; rerun passed)
Refs: caclawphony-f2f
Regeneration-Prompt: |
Implement workspace cleanup in the orchestrator when an issue reaches a
terminal state (Done, Canceled, Duplicate). Keep cleanup limited to terminal
transitions only, not active or gate states. Update the cleanup helper to
construct the workspace path from Config.workspace_root() and issue
identifier, remove it with File.rm_rf/1, and emit a log entry describing the
cleanup. Verify by compiling and running tests, then close pebbles issue
caclawphony-f2f and commit the change.
Co-authored-by: Codex <codex@openai.com>
Summary:
- Add `mix caclawphony.review` task for batch PR intake
- Fetch PR title/url via `gh pr view` per PR number
- Create Linear issues in MAR team Review state + Caclawphony project
- Print created Linear identifier and URL for each PR
Rationale:
- Provide a direct CLI for converting PR numbers into Linear review work
- Keep Linear GraphQL interactions aligned with existing client patterns
Tests:
- cd elixir && mix compile
- cd elixir && LINEAR_API_KEY=test mix caclawphony.review --help
Issue:
- caclawphony-432
Regeneration-Prompt: |
Implement a new Mix task `mix caclawphony.review` that accepts one or
more PR numbers and creates one Linear issue per PR for review intake.
Preserve existing project behavior by reusing the repository's
`SymphonyElixir.Linear.Client.graphql/3` helper instead of inventing a
new HTTP client path.
For each PR number, call GitHub CLI to fetch title exactly via
`gh pr view <num> --json title -q .title` and gather the PR URL for the
issue description. Build Linear issue titles as `PR #<num>: <title>`,
include PR metadata in the description, and set `stateId` to Review and
`projectId` to Caclawphony using the provided IDs.
Determine the team ID dynamically by querying Linear for team key `MAR`
before creating issues. Require `LINEAR_API_KEY` through existing config
resolution, fail loudly on GraphQL errors or command failures, and print
the created issue identifier for each PR.
Co-authored-by: Codex <codex@openai.com>
#### Context
Replace the custom Elixir observability TCP server with Phoenix while
keeping the shipped escript and existing operational API calls working
the same way they did before.
#### TL;DR
*Move the Elixir observability dashboard and API onto Phoenix without
breaking the escript or curl workflows.*
#### Summary
- replace the custom HTTP server with a Phoenix endpoint, router,
controller, and shared presenter
- add a LiveView operations dashboard with PubSub-driven updates and
embed its CSS and JS assets in code
- preserve runtime compatibility by accepting form-style POSTs and
extending the endpoint coverage around those paths
#### Alternatives
- keep extending the hand-rolled TCP server, but that keeps custom
parsing and routing complexity in the app
- serve dashboard assets from priv directories, but the shipped escript
cannot rely on those files existing on disk
#### Test Plan
- [x] `make -C elixir all`
- [x] `mix -C elixir test test/symphony_elixir/extensions_test.exs`
- [x] `./bin/symphony
--i-understand-that-this-will-be-running-without-the-usual-guardrails
--port 40123`
- [x] `curl -si http://127.0.0.1:40123/dashboard.css`
- [x] `curl -si http://127.0.0.1:40123/vendor/phoenix/phoenix.js`
- [x] `curl -si -X POST -d '' http://127.0.0.1:40123/api/v1/refresh`
- [x] `curl -si -X POST -d '' http://127.0.0.1:40123/api/v1/state`
---------
Co-authored-by: Codex <codex@openai.com>