ctlrm 0.1.0__tar.gz
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.
- ctlrm-0.1.0/.agents/skills/ctlrm/SKILL.md +29 -0
- ctlrm-0.1.0/.agents/skills/ctlrm/references/protocol.md +68 -0
- ctlrm-0.1.0/.github/workflows/ci.yml +121 -0
- ctlrm-0.1.0/.github/workflows/release.yml +33 -0
- ctlrm-0.1.0/.gitignore +19 -0
- ctlrm-0.1.0/.pre-commit-config.yaml +13 -0
- ctlrm-0.1.0/AGENTS.md +12 -0
- ctlrm-0.1.0/PKG-INFO +82 -0
- ctlrm-0.1.0/docs/evidence/csv-brief-recovery-2026-09-06.json +203 -0
- ctlrm-0.1.0/docs/evidence/managed-codex-recovery-2026-09-05.json +1 -0
- ctlrm-0.1.0/docs/evidence/managed-interrupted-recovery-2026-09-05.json +1 -0
- ctlrm-0.1.0/docs/evidence/managed-native-recovery-2026-09-05.json +1 -0
- ctlrm-0.1.0/docs/evidence/mixed-workflow-2026-09-05.json +1 -0
- ctlrm-0.1.0/docs/evidence/native-delivery-retry-2026-09-05.json +1 -0
- ctlrm-0.1.0/docs/evidence/pocket-tasks-workflow-2026-09-06.json +85 -0
- ctlrm-0.1.0/docs/evidence/project-archive-2026-09-05.json +79 -0
- ctlrm-0.1.0/docs/evidence/provider-recovery-2026-09-05.json +45 -0
- ctlrm-0.1.0/docs/evidence/provider-recovery-streamed-2026-09-05.json +59 -0
- ctlrm-0.1.0/docs/evidence/readme.md +11 -0
- ctlrm-0.1.0/docs/evidence/suite-timing-2026-09-06.json +283 -0
- ctlrm-0.1.0/docs/evidence/web-workbench-2026-09-06.json +69 -0
- ctlrm-0.1.0/docs/managed-sessions.md +31 -0
- ctlrm-0.1.0/docs/projects.md +47 -0
- ctlrm-0.1.0/docs/provider-session-recovery.md +80 -0
- ctlrm-0.1.0/docs/releases.md +31 -0
- ctlrm-0.1.0/docs/superpowers/plans/2026-06-20-tui-agent-orchestrator.md +1142 -0
- ctlrm-0.1.0/docs/superpowers/plans/2026-09-05-background-agent-workflows.md +242 -0
- ctlrm-0.1.0/docs/superpowers/plans/2026-09-05-project-jobs.md +14 -0
- ctlrm-0.1.0/docs/superpowers/specs/2026-06-20-tui-agent-orchestrator-design.md +350 -0
- ctlrm-0.1.0/docs/web-workbench.md +54 -0
- ctlrm-0.1.0/docs/workflows.md +41 -0
- ctlrm-0.1.0/frontend/build.mjs +14 -0
- ctlrm-0.1.0/frontend/package-lock.json +94 -0
- ctlrm-0.1.0/frontend/package.json +18 -0
- ctlrm-0.1.0/frontend/playwright.config.mjs +17 -0
- ctlrm-0.1.0/pyproject.toml +51 -0
- ctlrm-0.1.0/readme.md +64 -0
- ctlrm-0.1.0/src/ctlrm/__init__.py +3 -0
- ctlrm-0.1.0/src/ctlrm/__main__.py +307 -0
- ctlrm-0.1.0/src/ctlrm/communication/__init__.py +1 -0
- ctlrm-0.1.0/src/ctlrm/communication/terminal.py +292 -0
- ctlrm-0.1.0/src/ctlrm/managed/__init__.py +1 -0
- ctlrm-0.1.0/src/ctlrm/managed/archive.py +269 -0
- ctlrm-0.1.0/src/ctlrm/managed/area.py +201 -0
- ctlrm-0.1.0/src/ctlrm/managed/artifacts.py +164 -0
- ctlrm-0.1.0/src/ctlrm/managed/cli.py +276 -0
- ctlrm-0.1.0/src/ctlrm/managed/codex_host.py +187 -0
- ctlrm-0.1.0/src/ctlrm/managed/commits.py +178 -0
- ctlrm-0.1.0/src/ctlrm/managed/host.py +58 -0
- ctlrm-0.1.0/src/ctlrm/managed/project_cli.py +162 -0
- ctlrm-0.1.0/src/ctlrm/managed/projects.py +494 -0
- ctlrm-0.1.0/src/ctlrm/managed/providers.py +157 -0
- ctlrm-0.1.0/src/ctlrm/managed/sessions.py +691 -0
- ctlrm-0.1.0/src/ctlrm/managed/storage.py +232 -0
- ctlrm-0.1.0/src/ctlrm/managed/supervisor.py +133 -0
- ctlrm-0.1.0/src/ctlrm/managed/workflow_cli.py +161 -0
- ctlrm-0.1.0/src/ctlrm/managed/workflows.py +696 -0
- ctlrm-0.1.0/src/ctlrm/runtime/__init__.py +1 -0
- ctlrm-0.1.0/src/ctlrm/runtime/documents.py +60 -0
- ctlrm-0.1.0/src/ctlrm/runtime/filesystem.py +65 -0
- ctlrm-0.1.0/src/ctlrm/runtime/location.py +36 -0
- ctlrm-0.1.0/src/ctlrm/runtime/manifest.py +125 -0
- ctlrm-0.1.0/src/ctlrm/runtime/messages.py +69 -0
- ctlrm-0.1.0/src/ctlrm/runtime/participants.py +89 -0
- ctlrm-0.1.0/src/ctlrm/runtime/paths.py +17 -0
- ctlrm-0.1.0/src/ctlrm/runtime/projects.py +113 -0
- ctlrm-0.1.0/src/ctlrm/runtime/room.py +265 -0
- ctlrm-0.1.0/src/ctlrm/runtime/workflows.py +230 -0
- ctlrm-0.1.0/src/ctlrm/scheduler.py +23 -0
- ctlrm-0.1.0/src/ctlrm/version.py +11 -0
- ctlrm-0.1.0/src/ctlrm/web/__init__.py +1 -0
- ctlrm-0.1.0/src/ctlrm/web/api.py +272 -0
- ctlrm-0.1.0/src/ctlrm/web/app.py +74 -0
- ctlrm-0.1.0/src/ctlrm/web/service.py +354 -0
- ctlrm-0.1.0/src/ctlrm/web/static/app.css +1220 -0
- ctlrm-0.1.0/src/ctlrm/web/static/app.js +1319 -0
- ctlrm-0.1.0/src/ctlrm/web/static/index.html +129 -0
- ctlrm-0.1.0/src/ctlrm/web/static/vendor/addon-fit.LICENSE +19 -0
- ctlrm-0.1.0/src/ctlrm/web/static/vendor/addon-fit.js +2 -0
- ctlrm-0.1.0/src/ctlrm/web/static/vendor/xterm.LICENSE +21 -0
- ctlrm-0.1.0/src/ctlrm/web/static/vendor/xterm.css +285 -0
- ctlrm-0.1.0/src/ctlrm/web/static/vendor/xterm.js +2 -0
- ctlrm-0.1.0/src/ctlrm/web/templates/implement-review.yaml +44 -0
- ctlrm-0.1.0/src/ctlrm/web/templates/ship.yaml +81 -0
- ctlrm-0.1.0/src/ctlrm/web/templates/single-agent.yaml +21 -0
- ctlrm-0.1.0/src/ctlrm/web/terminal.py +164 -0
- ctlrm-0.1.0/tests/communication/test_terminal.py +288 -0
- ctlrm-0.1.0/tests/managed/conftest.py +140 -0
- ctlrm-0.1.0/tests/managed/test_archive.py +540 -0
- ctlrm-0.1.0/tests/managed/test_area.py +91 -0
- ctlrm-0.1.0/tests/managed/test_artifacts.py +77 -0
- ctlrm-0.1.0/tests/managed/test_cli.py +225 -0
- ctlrm-0.1.0/tests/managed/test_codex_host.py +133 -0
- ctlrm-0.1.0/tests/managed/test_commits.py +171 -0
- ctlrm-0.1.0/tests/managed/test_dispatch.py +109 -0
- ctlrm-0.1.0/tests/managed/test_host.py +122 -0
- ctlrm-0.1.0/tests/managed/test_interactions.py +252 -0
- ctlrm-0.1.0/tests/managed/test_projects.py +441 -0
- ctlrm-0.1.0/tests/managed/test_providers.py +134 -0
- ctlrm-0.1.0/tests/managed/test_sessions.py +379 -0
- ctlrm-0.1.0/tests/managed/test_specialists.py +382 -0
- ctlrm-0.1.0/tests/managed/test_storage.py +121 -0
- ctlrm-0.1.0/tests/managed/test_supervisor.py +111 -0
- ctlrm-0.1.0/tests/managed/test_workflow_engine.py +958 -0
- ctlrm-0.1.0/tests/runtime/test_messages.py +16 -0
- ctlrm-0.1.0/tests/runtime/test_room.py +677 -0
- ctlrm-0.1.0/tests/runtime/test_workflows.py +99 -0
- ctlrm-0.1.0/tests/test_bootstrap.py +28 -0
- ctlrm-0.1.0/tests/test_scheduler.py +32 -0
- ctlrm-0.1.0/tests/web/__init__.py +1 -0
- ctlrm-0.1.0/tests/web/browser/seed.py +124 -0
- ctlrm-0.1.0/tests/web/browser/workbench.spec.mjs +229 -0
- ctlrm-0.1.0/tests/web/conftest.py +103 -0
- ctlrm-0.1.0/tests/web/test_app.py +258 -0
- ctlrm-0.1.0/tests/web/test_code.py +197 -0
- ctlrm-0.1.0/tests/web/test_task_artifacts.py +178 -0
- ctlrm-0.1.0/tests/web/test_terminal.py +107 -0
- ctlrm-0.1.0/tests/web/test_terminal_cleanup.py +182 -0
- ctlrm-0.1.0/uv.lock +799 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ctlrm
|
|
3
|
+
description: Coordinate independent agents or humans through a shared project directory using a first-authored prompt, author-assigned roles, participant-owned signatures, and immutable mailbox messages. Use when participants share a filesystem but not one native agent thread; do not use for ordinary in-thread subagent delegation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Ctlrm
|
|
7
|
+
|
|
8
|
+
Use the single `ctlrm` command to join and communicate through a project-local `.ctlrm/` directory. Joining a room does not grant permission beyond the user's existing authorization.
|
|
9
|
+
|
|
10
|
+
## Enter a room
|
|
11
|
+
|
|
12
|
+
1. Use the explicit project root. Do not create a room at an inferred location when the target is ambiguous.
|
|
13
|
+
2. Read `.ctlrm/room.md` if it exists. It contains the first participant's canonical prompt and complete role roster.
|
|
14
|
+
3. If the room does not exist, act as its first participant only when responsible for defining the task. Initialize it with one `--assign PARTICIPANT=ROLE` option for every expected participant, including yourself.
|
|
15
|
+
4. If the room exists, select the participant ID assigned to you. Do not invent or alter your role. Run `ctlrm --root <root> join ...`; the command copies the assigned role into your signature.
|
|
16
|
+
5. Each participant invokes `join` only for itself, creating `.ctlrm/participants/<id>.yaml`. Never create, replace, or edit another participant's signature.
|
|
17
|
+
6. Read the prompt and existing signatures before starting work or addressing messages.
|
|
18
|
+
|
|
19
|
+
A signature is immutable acceptance of an assigned role. The CLI does not manage heartbeat or progress state.
|
|
20
|
+
|
|
21
|
+
## Communicate
|
|
22
|
+
|
|
23
|
+
Send findings, questions, requests, and handoffs with `ctlrm --root <root> send ...`. Messages are created exclusively and cannot overwrite an existing message ID. Read them with `ctlrm --root <root> inbox --participant <id>`.
|
|
24
|
+
|
|
25
|
+
Use messages only when another participant needs the information. Include concrete file paths and evidence when relevant. Keep private scratch work outside the mailbox.
|
|
26
|
+
|
|
27
|
+
Poll only when the task requires waiting. Use bounded intervals and stop at the user's deadline or after reporting a real blocker.
|
|
28
|
+
|
|
29
|
+
Read [references/protocol.md](references/protocol.md) for the directory schema, initialization behavior, and command examples.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Ctlrm directory protocol
|
|
2
|
+
|
|
3
|
+
```text
|
|
4
|
+
.ctlrm/
|
|
5
|
+
├── room.md
|
|
6
|
+
└── participants/
|
|
7
|
+
├── coordinator.yaml
|
|
8
|
+
├── coordinator/
|
|
9
|
+
│ └── inbox/
|
|
10
|
+
├── reviewer.yaml
|
|
11
|
+
└── reviewer/
|
|
12
|
+
└── inbox/
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Room definition
|
|
16
|
+
|
|
17
|
+
`room.md` is an immutable Markdown document with YAML front matter. The body is the first participant's prompt. The front matter records `protocol_version`, a room `id`, the `author`, `created_at`, and the complete list of participant-to-role `assignments`.
|
|
18
|
+
|
|
19
|
+
The author must assign itself a role. Participant IDs must be unique, and every participant must have exactly one role. Only assigned participant IDs can join.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
ctlrm --root /path/to/project init \
|
|
23
|
+
--id coordinator \
|
|
24
|
+
--name Coordinator \
|
|
25
|
+
--provider codex \
|
|
26
|
+
--assign coordinator=coordinate \
|
|
27
|
+
--assign reviewer=review \
|
|
28
|
+
--prompt-file /path/to/prompt.md
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Room creation is exclusive. A repeated `init` by the same author with the same prompt and assignments repairs a missing author signature and otherwise leaves the room unchanged. A different author, prompt, or roster is a conflict.
|
|
32
|
+
|
|
33
|
+
## Participant signatures
|
|
34
|
+
|
|
35
|
+
Each participant accepts its preassigned role by invoking:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
ctlrm --root /path/to/project join \
|
|
39
|
+
--id reviewer \
|
|
40
|
+
--name Reviewer \
|
|
41
|
+
--provider claude \
|
|
42
|
+
--capability code-review
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`join` has no role option. It reads the role from `room.md` and creates `participants/<id>.yaml` plus that participant's inbox. A signature contains `protocol_version`, `room_id`, `id`, `name`, `role`, `kind`, optional `provider`, `joined_at`, and optional `capabilities`.
|
|
46
|
+
|
|
47
|
+
## Messaging
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
ctlrm --root /path/to/project send \
|
|
51
|
+
--from coordinator \
|
|
52
|
+
--to reviewer \
|
|
53
|
+
--kind review_request \
|
|
54
|
+
--title "Review the implementation" \
|
|
55
|
+
--file src/ctlrm/runtime/room.py \
|
|
56
|
+
--body "Check role enforcement and recovery."
|
|
57
|
+
|
|
58
|
+
ctlrm --root /path/to/project inbox --participant reviewer
|
|
59
|
+
ctlrm --root /path/to/project participants
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Both endpoints must have valid signatures bound to the current room and their assigned roles. Duplicate message IDs return conflict exit code 3. Validation returns 2, missing files return 4, and storage failures return 5.
|
|
63
|
+
|
|
64
|
+
## Ownership and storage
|
|
65
|
+
|
|
66
|
+
The CLI exclusively creates `room.md`, signatures, and messages. By convention, the first participant authors `room.md`, each participant authors only its own signature, and each declared sender authors its messages. These rules are cooperative rather than authenticated; any process with directory write access can unlink or forge files.
|
|
67
|
+
|
|
68
|
+
Ctlrm creates files with mode `0660` and directories with mode `2770`. Participants running as different users must share the directory's Unix group. Exclusive creation requires a POSIX-style filesystem supporting hard links and directory `fsync`; ctlrm reports a storage error rather than weakening the no-overwrite guarantee.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
name: checks
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [main]
|
|
5
|
+
pull_request:
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
workflow_call:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
timeout-minutes: 10
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
with:
|
|
19
|
+
fetch-depth: 0
|
|
20
|
+
persist-credentials: false
|
|
21
|
+
- uses: astral-sh/setup-uv@v6
|
|
22
|
+
with:
|
|
23
|
+
python-version: '3.11'
|
|
24
|
+
- name: Validate release tag
|
|
25
|
+
if: github.event_name == 'release'
|
|
26
|
+
env:
|
|
27
|
+
RELEASE_TAG: ${{ github.event.release.tag_name }}
|
|
28
|
+
run: |
|
|
29
|
+
[[ "$RELEASE_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+((a|b|rc)[0-9]+)?$ ]]
|
|
30
|
+
git fetch --no-tags origin +refs/heads/main:refs/remotes/origin/main \
|
|
31
|
+
"+refs/tags/$RELEASE_TAG:refs/tags/$RELEASE_TAG"
|
|
32
|
+
git merge-base --is-ancestor HEAD origin/main
|
|
33
|
+
test "$(git rev-parse "refs/tags/$RELEASE_TAG^{commit}")" = "$(git rev-parse HEAD)"
|
|
34
|
+
- name: Build sdist, then wheel from sdist
|
|
35
|
+
run: uv build
|
|
36
|
+
- run: uvx twine==7.0.0 check --strict dist/*
|
|
37
|
+
- name: Verify release package version
|
|
38
|
+
if: github.event_name == 'release'
|
|
39
|
+
env:
|
|
40
|
+
RELEASE_TAG: ${{ github.event.release.tag_name }}
|
|
41
|
+
run: |
|
|
42
|
+
uv run --no-project python - <<'PYTHON'
|
|
43
|
+
import email
|
|
44
|
+
import os
|
|
45
|
+
import pathlib
|
|
46
|
+
import zipfile
|
|
47
|
+
|
|
48
|
+
wheel, = pathlib.Path("dist").glob("*.whl")
|
|
49
|
+
with zipfile.ZipFile(wheel) as archive:
|
|
50
|
+
metadata_path, = (name for name in archive.namelist() if name.endswith(".dist-info/METADATA"))
|
|
51
|
+
metadata = email.message_from_bytes(archive.read(metadata_path))
|
|
52
|
+
if metadata["Name"] != "ctlrm" or "v" + metadata["Version"] != os.environ["RELEASE_TAG"]:
|
|
53
|
+
raise SystemExit("Package name/version does not match the release tag")
|
|
54
|
+
PYTHON
|
|
55
|
+
- uses: actions/upload-artifact@v4
|
|
56
|
+
with:
|
|
57
|
+
name: python-distributions
|
|
58
|
+
path: dist/*
|
|
59
|
+
if-no-files-found: error
|
|
60
|
+
retention-days: 7
|
|
61
|
+
|
|
62
|
+
test:
|
|
63
|
+
needs: build
|
|
64
|
+
runs-on: ubuntu-latest
|
|
65
|
+
timeout-minutes: 20
|
|
66
|
+
strategy:
|
|
67
|
+
fail-fast: false
|
|
68
|
+
matrix:
|
|
69
|
+
python: ['3.11', '3.14']
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/checkout@v4
|
|
72
|
+
with:
|
|
73
|
+
fetch-depth: 0
|
|
74
|
+
persist-credentials: false
|
|
75
|
+
- uses: astral-sh/setup-uv@v6
|
|
76
|
+
with:
|
|
77
|
+
python-version: ${{ matrix.python }}
|
|
78
|
+
- uses: actions/setup-node@v4
|
|
79
|
+
with:
|
|
80
|
+
node-version: '24'
|
|
81
|
+
cache: npm
|
|
82
|
+
cache-dependency-path: frontend/package-lock.json
|
|
83
|
+
- name: Install tmux for terminal integration tests
|
|
84
|
+
run: sudo apt-get update && sudo apt-get install -y tmux
|
|
85
|
+
- run: uv sync --locked
|
|
86
|
+
- run: npm --prefix frontend ci
|
|
87
|
+
- run: npm --prefix frontend run check
|
|
88
|
+
- name: Verify bundled terminal assets are reproducible
|
|
89
|
+
run: |
|
|
90
|
+
npm --prefix frontend run build
|
|
91
|
+
git diff --exit-code -- src/ctlrm/web/static/vendor
|
|
92
|
+
- name: Install browser for workbench acceptance
|
|
93
|
+
run: npm --prefix frontend exec -- playwright install --with-deps chromium --only-shell
|
|
94
|
+
- run: uv run ruff check .
|
|
95
|
+
- run: uv run ruff format --check .
|
|
96
|
+
- run: uv run pytest --cov ctlrm --cov-report term-missing --cov-report xml:test-results/coverage.xml --durations=25 --junitxml=test-results/python.xml
|
|
97
|
+
- uses: actions/download-artifact@v4
|
|
98
|
+
with:
|
|
99
|
+
name: python-distributions
|
|
100
|
+
path: dist
|
|
101
|
+
- name: Test installed wheel outside source tree
|
|
102
|
+
run: |
|
|
103
|
+
uv venv --python '${{ matrix.python }}' /tmp/ctlrm-wheel
|
|
104
|
+
uv pip install --python /tmp/ctlrm-wheel/bin/python dist/*.whl
|
|
105
|
+
cd /tmp
|
|
106
|
+
/tmp/ctlrm-wheel/bin/ctlrm --help
|
|
107
|
+
- name: Test installed workbench in Chromium
|
|
108
|
+
env:
|
|
109
|
+
CTLRM_BROWSER_PYTHON: /tmp/ctlrm-wheel/bin/python
|
|
110
|
+
CTLRM_BROWSER_REQUIRE_WHEEL: '1'
|
|
111
|
+
run: npm --prefix frontend run test:browser
|
|
112
|
+
- name: Preserve test results
|
|
113
|
+
if: always()
|
|
114
|
+
uses: actions/upload-artifact@v4
|
|
115
|
+
with:
|
|
116
|
+
name: test-results-python-${{ matrix.python }}
|
|
117
|
+
path: |
|
|
118
|
+
test-results/
|
|
119
|
+
frontend/test-results/
|
|
120
|
+
if-no-files-found: ignore
|
|
121
|
+
retention-days: 7
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
on:
|
|
3
|
+
release:
|
|
4
|
+
types: [published]
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: pypi-${{ github.event.release.tag_name }}
|
|
11
|
+
cancel-in-progress: false
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
checks:
|
|
15
|
+
uses: ./.github/workflows/ci.yml
|
|
16
|
+
|
|
17
|
+
publish:
|
|
18
|
+
needs: checks
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
timeout-minutes: 10
|
|
21
|
+
environment:
|
|
22
|
+
name: pypi
|
|
23
|
+
url: https://pypi.org/project/ctlrm/
|
|
24
|
+
permissions:
|
|
25
|
+
contents: read
|
|
26
|
+
id-token: write
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/download-artifact@v4
|
|
29
|
+
with:
|
|
30
|
+
name: python-distributions
|
|
31
|
+
path: dist
|
|
32
|
+
- name: Publish tested distributions to PyPI
|
|
33
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
ctlrm-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
.ctlrm/
|
|
2
|
+
.superpowers/
|
|
3
|
+
.venv/
|
|
4
|
+
.venv-*/
|
|
5
|
+
.pytest_cache/
|
|
6
|
+
.ruff_cache/
|
|
7
|
+
__pycache__/
|
|
8
|
+
*.py[cod]
|
|
9
|
+
# Local coordination data, including a .scratch symlink.
|
|
10
|
+
.scratch
|
|
11
|
+
.coverage*
|
|
12
|
+
htmlcov/
|
|
13
|
+
dist/
|
|
14
|
+
|
|
15
|
+
frontend/node_modules/
|
|
16
|
+
|
|
17
|
+
frontend/test-results/
|
|
18
|
+
frontend/playwright-report/
|
|
19
|
+
/test-results/
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: local
|
|
3
|
+
hooks:
|
|
4
|
+
- id: ruff-check
|
|
5
|
+
name: ruff check
|
|
6
|
+
entry: uv run ruff check
|
|
7
|
+
language: system
|
|
8
|
+
types_or: [python, pyi]
|
|
9
|
+
- id: ruff-format
|
|
10
|
+
name: ruff format
|
|
11
|
+
entry: uv run ruff format --check
|
|
12
|
+
language: system
|
|
13
|
+
types_or: [python, pyi]
|
ctlrm-0.1.0/AGENTS.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Code development guidance
|
|
2
|
+
- Put tests under `tests/` mirroring package structure.
|
|
3
|
+
- Group tests in classes.
|
|
4
|
+
- Place fixtures as close as practical to usage (class, module, then `conftest.py`).
|
|
5
|
+
- Write tests that focus on boundaries, not implementation details.
|
|
6
|
+
- Keep test names short; put extra detail in the docstring when needed.
|
|
7
|
+
- Add type hints for public functions/methods.
|
|
8
|
+
- All functions, classes and modules must have a docstring, private code needs only something short.
|
|
9
|
+
- Prefer concise explanatory docstrings. Describe parameters and return values when their behavior needs clarification.
|
|
10
|
+
- Don't add newlines to markdown prose; let editors wrap.
|
|
11
|
+
- coverage by `pytest --cov ctlrm --cov-report term-missing`
|
|
12
|
+
- link by `uvx prek run --all-files`
|
ctlrm-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: ctlrm
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local web workbench for orchestrating CLI agents and human workflow participants
|
|
5
|
+
Project-URL: Repository, https://github.com/d-chambers/ctlrm
|
|
6
|
+
Project-URL: Documentation, https://github.com/d-chambers/ctlrm/tree/main/docs
|
|
7
|
+
Project-URL: Issues, https://github.com/d-chambers/ctlrm/issues
|
|
8
|
+
Requires-Python: >=3.11
|
|
9
|
+
Requires-Dist: anyio<5,>=4
|
|
10
|
+
Requires-Dist: fastapi<1,>=0.115
|
|
11
|
+
Requires-Dist: libtmux<0.63,>=0.62
|
|
12
|
+
Requires-Dist: pydantic>=2.7
|
|
13
|
+
Requires-Dist: pyyaml>=6.0
|
|
14
|
+
Requires-Dist: typer>=0.12
|
|
15
|
+
Requires-Dist: uvicorn<1,>=0.34
|
|
16
|
+
Requires-Dist: websockets<17,>=14
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# ctlrm
|
|
20
|
+
|
|
21
|
+
Control room coordinates CLI agents and human participants through a shared directory. The CLI manages background Codex and Claude sessions, native recovery, reusable sequential workflows, review loops, and human response steps. Projects organize improvements to a codebase; each job uses its own Git worktree and branch to execute a workflow. Standalone managed sessions are also supported. The local web workbench provides project and participant tabs, workflow graphs, human responses, artifacts, code browsing, and direct access to managed agent sessions.
|
|
22
|
+
|
|
23
|
+
## Open the workbench
|
|
24
|
+
|
|
25
|
+
Run `uv run ctlrm serve` and open the complete loopback URL printed in the terminal. Installed packages use `ctlrm serve`. The browser uses the same central project records as the CLI; `--data PATH` selects an isolated store and `--port PORT` changes the default port 8766. The server binds only to `127.0.0.1`. Its generated access capability is carried in the initial URL fragment, removed from the address bar, and retained for that browser tab.
|
|
26
|
+
|
|
27
|
+
Create a project, add a job using a packaged workflow or custom YAML, then explicitly start it. Opening an agent terminal attaches to its existing tmux session. Interactive providers accept direct keyboard input; native Codex sessions use a conversation message composer between turns. Closing the terminal or browser leaves the agent running. Drag the sidebar divider or terminal divider, or focus a divider and use arrow keys; Full screen and Escape preserve the same terminal view. See the [web workbench guide](https://github.com/d-chambers/ctlrm/blob/main/docs/web-workbench.md) for controls and boundaries.
|
|
28
|
+
|
|
29
|
+
## Data model
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
Codebase
|
|
33
|
+
└── Project — a goal or related goals, with an optional design document
|
|
34
|
+
└── Job — a deliverable, usually a PR, defined by a workflow
|
|
35
|
+
└── Task — a fixed, generic assignment defined in the workflow
|
|
36
|
+
└── Execution — one attempt, assigned to a participant and optional agent session
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
A **workflow** is a reusable YAML template defining the task graph, task instructions, participant roles, provider/model profiles, and outcome transitions. For example, a job might run “implement the goal,” “review blast radius,” and “review performance.” The job supplies the concrete goal and acceptance criteria; its workflow tasks provide the instructions for carrying it out.
|
|
40
|
+
|
|
41
|
+
An **execution** records the task's inputs, participant/session assignment, status, outputs, and outcome within a particular job. Review loops and explicit retries create new executions of the same task. Restarting an agent session continues its existing execution. A session can perform multiple executions; human participants need no agent session. A single-agent job can use a one-task workflow. Each execution records its initial commit, timestamps, and outgoing mailbox messages. Its accepted outcome retains commit messages and diffs alongside the worktree manifest. In task details, double-click a commit or sent message to view its full retained text in a read-only editor window; Enter and Open are also supported.
|
|
42
|
+
|
|
43
|
+
Projects can contain dependent jobs, each with an immutable workflow snapshot and its own worktree/branch. PR identity belongs to the job: assign a repository and PR number, then search by number with an optional repository filter. Workflow completion, PR merge, project completion, and archival are distinct milestones.
|
|
44
|
+
|
|
45
|
+
The OS-specific user data directory owns durable project and job records. Each job worktree exposes its records through `.scratch/ctlrm`, a symlink into the central job directory. See [project/job commands, storage, and PR lookup](https://github.com/d-chambers/ctlrm/blob/main/docs/projects.md) and the [backend implementation plan](https://github.com/d-chambers/ctlrm/blob/main/docs/superpowers/plans/2026-09-05-project-jobs.md). Workflows can request bounded specialist-review tasks from a predefined allowlist. The [ship workflow](https://github.com/d-chambers/ctlrm/blob/main/src/ctlrm/web/templates/ship.yaml) uses review lenses, fresh reviewer sessions, PR publication, and CI/review handling; the [single-agent workflow](https://github.com/d-chambers/ctlrm/blob/main/src/ctlrm/web/templates/single-agent.yaml) keeps simple jobs small. Project completion retires owned processes and retains the accepted code; `project archive` creates a verified ZIP while keeping PR metadata searchable. See [completion and archival](https://github.com/d-chambers/ctlrm/blob/main/docs/projects.md#completion-and-archival).
|
|
46
|
+
|
|
47
|
+
## Development
|
|
48
|
+
|
|
49
|
+
Use Linux, Python 3.11 or newer, tmux 3.2a or newer, and local POSIX storage. `libtmux` 0.62.x is installed with the package. Install and authenticate the provider CLIs separately. Run `uv sync`, then `uv run ctlrm --help`. Run checks with `uv run pytest --cov ctlrm --cov-report term-missing`, `uv run ruff check .`, `uv run ruff format --check .`, and `uvx prek run --all-files`. Browser assets are packaged locally. After editing frontend source, run `npm --prefix frontend ci`, `npm --prefix frontend run build`, and `npm --prefix frontend run check`; `npm --prefix frontend run format` formats authored assets. Node is needed for frontend development, not to run the installed workbench.
|
|
50
|
+
|
|
51
|
+
## Releases
|
|
52
|
+
|
|
53
|
+
CI checks pull requests and `main` on Python 3.11 and 3.14. Publishing a GitHub release runs those checks again and uploads the tested packages to PyPI through Trusted Publishing. See [release setup and versioning](https://github.com/d-chambers/ctlrm/blob/main/docs/releases.md), including the one-time PyPI account configuration.
|
|
54
|
+
|
|
55
|
+
## Managed sessions and workflows
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
ctlrm --root /path/to/worktree session start --provider codex
|
|
59
|
+
ctlrm --root /path/to/worktree session status
|
|
60
|
+
ctlrm workflow validate --template src/ctlrm/web/templates/implement-review.yaml
|
|
61
|
+
ctlrm --root /path/to/another-worktree workflow submit --template src/ctlrm/web/templates/implement-review.yaml --title "Implement the task" --file task.md --request-id my-task
|
|
62
|
+
ctlrm --root /path/to/another-worktree workflow status
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Use a fresh worktree for each independent job. The [example template](https://github.com/d-chambers/ctlrm/blob/main/src/ctlrm/web/templates/implement-review.yaml) binds implementer and reviewer roles to separate Codex sessions, then waits for a human owner. Profiles explicitly select provider permissions; Claude automatic input requires an unattended profile. See [session operations and recovery limits](https://github.com/d-chambers/ctlrm/blob/main/docs/managed-sessions.md) and [workflow acknowledgment, approval, retry, and cancellation](https://github.com/d-chambers/ctlrm/blob/main/docs/workflows.md).
|
|
66
|
+
|
|
67
|
+
For project jobs, use `project complete` and `project archive`. To retire a standalone area, explicitly stop every managed session and verify its owned provider processes have exited, then stop the supervisor. Preserve wanted logs and artifacts outside the area before explicitly removing runtime files or the worktree with normal filesystem/Git tools. Supervisor stop alone leaves agents running. Project jobs can create dedicated worktrees automatically. Automatic worktree removal, recycling, parallel workflows in one area, cron, remote delegation, and embedded editing are deferred.
|
|
68
|
+
|
|
69
|
+
## Room example
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
ctlrm --root /path/to/worktree init --id coordinator --name Coordinator --assign coordinator=coordinate --assign reviewer=review --prompt "Review the change."
|
|
73
|
+
ctlrm --root /path/to/worktree join --id reviewer --name Reviewer
|
|
74
|
+
ctlrm --root /path/to/worktree send --from coordinator --to reviewer --title Review --body "Please review."
|
|
75
|
+
ctlrm --root /path/to/worktree inbox --participant reviewer
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Restart commands in room signatures are stored only; use managed sessions for executable recovery. Room identity is cooperative rather than authenticated. All participants need appropriate shared filesystem permissions.
|
|
79
|
+
|
|
80
|
+
### Conversation input
|
|
81
|
+
|
|
82
|
+
Managed native Codex sessions accept conversation messages between turns with `ctlrm --root WORKTREE session interact --session-id ID --generation N --text "Explain the current change"`. This resumes the recorded native conversation and does not assign, acknowledge, or complete a workflow task. The supervisor accepts up to eight pending messages, each at most 16 KiB. A runner claims each message before invoking the provider; interrupted turns are retained as `uncertain` and are never automatically replayed. Explicitly replacing a conversation cancels its queued messages. Recent messages remain in the session snapshot and older messages remain in the event journal. Interactive providers continue to accept direct input through their owned tmux terminal.
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
{
|
|
2
|
+
"date": "2026-09-06",
|
|
3
|
+
"application": "CSV Brief",
|
|
4
|
+
"description": "Standard-library Python streaming CSV summary CLI",
|
|
5
|
+
"project": "csv-brief",
|
|
6
|
+
"job": "build",
|
|
7
|
+
"provenance": {
|
|
8
|
+
"managed_agent_build": true,
|
|
9
|
+
"provider": "codex",
|
|
10
|
+
"terminal_manager": "libtmux",
|
|
11
|
+
"app_commit": "e0db8affd86cc79ab27253ccbcea3b22749a1c54",
|
|
12
|
+
"runtime_commit": "d0cba76"
|
|
13
|
+
},
|
|
14
|
+
"recovery_checks": [
|
|
15
|
+
{
|
|
16
|
+
"test": "initial live writer checkpoint",
|
|
17
|
+
"at": "2026-09-06T15:20:29Z",
|
|
18
|
+
"generation": 1,
|
|
19
|
+
"native_id": "01a07747-69a5-7e90-b843-0aad144b817a",
|
|
20
|
+
"execution": "execution-257d8cb8c6824a6a85fde7c75120d470",
|
|
21
|
+
"files": 5
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"test": "automatic recovery after provider death",
|
|
25
|
+
"at": "2026-09-06T15:22:15Z",
|
|
26
|
+
"generation": 2,
|
|
27
|
+
"same_native_id": true,
|
|
28
|
+
"same_execution": true,
|
|
29
|
+
"uncommitted_files_preserved": true,
|
|
30
|
+
"killed_owned_processes": 3,
|
|
31
|
+
"exit_status": -9
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"test": "supervisor crash and restart",
|
|
35
|
+
"at": "2026-09-06T15:22:15Z",
|
|
36
|
+
"agent_generation_unchanged": true,
|
|
37
|
+
"agent_process_identity_unchanged": true,
|
|
38
|
+
"same_execution": true,
|
|
39
|
+
"uncommitted_files_preserved": true
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"test": "automatic recovery after terminal loss",
|
|
43
|
+
"at": "2026-09-06T15:23:55Z",
|
|
44
|
+
"generation": 3,
|
|
45
|
+
"same_native_id": true,
|
|
46
|
+
"same_execution": true,
|
|
47
|
+
"uncommitted_files_preserved": true
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"test": "explicit stop suppresses automatic restart",
|
|
51
|
+
"at": "2026-09-06T15:23:59Z",
|
|
52
|
+
"generation": 3,
|
|
53
|
+
"repeated_request_idempotent": true
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"test": "explicit native resume",
|
|
57
|
+
"at": "2026-09-06T15:25:46Z",
|
|
58
|
+
"generation": 4,
|
|
59
|
+
"same_native_id": true,
|
|
60
|
+
"same_execution": true,
|
|
61
|
+
"uncommitted_files_preserved": true
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"test": "stale generation rejected",
|
|
65
|
+
"at": "2026-09-06T15:25:46Z",
|
|
66
|
+
"current_generation": 4,
|
|
67
|
+
"old_generation": 3,
|
|
68
|
+
"current_process_preserved": true
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"test": "writer released after faults",
|
|
72
|
+
"at": "2026-09-06T15:25:46Z"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"test": "explicit fresh-session replacement",
|
|
76
|
+
"at": "2026-09-06T15:34:23Z",
|
|
77
|
+
"generation": 2,
|
|
78
|
+
"new_native_id": true,
|
|
79
|
+
"same_review_execution": true,
|
|
80
|
+
"same_input_artifact": true,
|
|
81
|
+
"code_unchanged": true
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"test": "one implementation and one review handoff",
|
|
85
|
+
"at": "2026-09-06T15:36:03Z",
|
|
86
|
+
"tasks": [
|
|
87
|
+
{
|
|
88
|
+
"task": "implement",
|
|
89
|
+
"status": "completed",
|
|
90
|
+
"outcome": "completed",
|
|
91
|
+
"execution": "execution-257d8cb8c6824a6a85fde7c75120d470"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"task": "review",
|
|
95
|
+
"status": "completed",
|
|
96
|
+
"outcome": "approved",
|
|
97
|
+
"execution": "execution-8b20888aa86443869c3627cb4735ff9d"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"task": "counterpart",
|
|
101
|
+
"status": "pending",
|
|
102
|
+
"outcome": null,
|
|
103
|
+
"execution": "execution-0829201f9f564bc585eb34852c0c8a89"
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"commit": "e0db8affd86cc79ab27253ccbcea3b22749a1c54",
|
|
107
|
+
"worktree_clean": true
|
|
108
|
+
}
|
|
109
|
+
],
|
|
110
|
+
"final_checks": {
|
|
111
|
+
"completed_writer_resumed_same_native_session": true,
|
|
112
|
+
"writer_final_generation": 5,
|
|
113
|
+
"completed_task_not_reopened": true,
|
|
114
|
+
"no_duplicate_task_or_commit": true,
|
|
115
|
+
"implementation_commits": 1,
|
|
116
|
+
"unchanged_commit": "e0db8affd86cc79ab27253ccbcea3b22749a1c54",
|
|
117
|
+
"all_agent_sessions_stopped": true,
|
|
118
|
+
"supervisor_stopped": true,
|
|
119
|
+
"tmux_sessions_remaining": 0,
|
|
120
|
+
"processes_in_app_worktree": [],
|
|
121
|
+
"counterpart_gate": "pending"
|
|
122
|
+
},
|
|
123
|
+
"task_artifacts": [
|
|
124
|
+
{
|
|
125
|
+
"task": "implement",
|
|
126
|
+
"items": [
|
|
127
|
+
{
|
|
128
|
+
"kind": "commit",
|
|
129
|
+
"id": "commit-bcd2e031bc052bc23b118af27aff3e7d0e0a58399947a2aef544fbec404c3405"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"kind": "message",
|
|
133
|
+
"id": "msg-20260906T152656-24f1ff5e"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"kind": "report",
|
|
137
|
+
"id": "execution-257d8cb8c6824a6a85fde7c75120d470"
|
|
138
|
+
}
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"task": "review",
|
|
143
|
+
"items": [
|
|
144
|
+
{
|
|
145
|
+
"kind": "commit",
|
|
146
|
+
"id": "commit-bcd2e031bc052bc23b118af27aff3e7d0e0a58399947a2aef544fbec404c3405"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"kind": "message",
|
|
150
|
+
"id": "msg-20260906T153546-3237d120"
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"kind": "report",
|
|
154
|
+
"id": "execution-8b20888aa86443869c3627cb4735ff9d"
|
|
155
|
+
}
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
],
|
|
159
|
+
"validation": {
|
|
160
|
+
"app_tests_passed": 14,
|
|
161
|
+
"app_cli_acceptance_passed": 13,
|
|
162
|
+
"runtime_tests_passed": 41,
|
|
163
|
+
"ruff": "passed",
|
|
164
|
+
"prek": "passed",
|
|
165
|
+
"independent_review": "approved with no actionable findings"
|
|
166
|
+
},
|
|
167
|
+
"scope": {
|
|
168
|
+
"counterpart_review": "pending source-transmission approval",
|
|
169
|
+
"remote_pr_and_ci": "not exercised; no remote was configured",
|
|
170
|
+
"not_exercised": [
|
|
171
|
+
"machine reboot",
|
|
172
|
+
"provider credential or network outage",
|
|
173
|
+
"different interpreter installation path",
|
|
174
|
+
"crash before native recovery registration"
|
|
175
|
+
]
|
|
176
|
+
},
|
|
177
|
+
"source_evidence": [
|
|
178
|
+
{
|
|
179
|
+
"file": "recovery-checks.json",
|
|
180
|
+
"sha256": "5f3a61f2d485bf9b1e3dd7695381d2cfdd147230351181318d6be41bc9b4b032"
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"file": "final-acceptance.json",
|
|
184
|
+
"sha256": "0483a05d81cd0d76c5818a91da3fa3f6d79d0a52236f2b4e788bb228c39207c6"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"file": "app-acceptance.json",
|
|
188
|
+
"sha256": "2332c8f8cad6dfafec7dfcbb5519a83d71663e93906d50b41fb1fcd3671d22d8"
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"file": "app-tests.txt",
|
|
192
|
+
"sha256": "189ba3e93109df5c0e2844a310a6be7d2a2f21d45cad6afe125bf9815602596f"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"file": "runtime-tests.txt",
|
|
196
|
+
"sha256": "d77b1376218e38d6643d1705fad4ef31f241e9c801355fbe10d4e315b14aae91"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"file": "runtime-lint.txt",
|
|
200
|
+
"sha256": "84617e5ab13858c275ee0228d2588844cac631a8dce9f3d2dadc36a8d5320d67"
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"area_id":"area-5bac55c1489946ee91ed5af7ed47320c","at":"2026-09-05T09:04:44.328906+00:00","context_token_recalled":true,"final_session":"stopped","initial_generation":1,"native_id":"01a070cd-2b8a-7170-bf30-64ac34c353e6","provider":"codex-cli 0.153.4","resumed_generation":2,"session_id":"session-b116ebd7feca4c7cb8171aada15534d9","status":"completed","work_id":"work-60cb312d51774f0988fc283e9e69edef"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"area_id":"area-439baa3c8c9543fcaad869f78a661653","completed_at":"2026-09-05T08:17:59.603639+00:00","exit_observation":"{\"returncode\":-9,\"token\":\"launch-acdf98f7971f4d4a9251e4476f6d32e5\"}\n","final_session_status":"stopped","final_work_status":"completed","interrupted_generation":3,"kill_at":"2026-09-05T08:17:35.270240+00:00","native_id":"540f01be-c322-4bcf-bcd1-3c2a5b75f0bd","provider_pid":194934,"recovered_generation":4,"session_id":"session-d6917cd078db429fa8bed5a9d49211e7","work_id":"work-582c13ff8d384649983051e0834075e7","work_status_at_kill":"acknowledged"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"area_id":"area-439baa3c8c9543fcaad869f78a661653","completed_at":"2026-09-05T07:33:56.802582+00:00","explicit_stop_at":"2026-09-05T07:34:41.853755+00:00","final_generation":2,"final_status":"stopped","initial_generation":1,"initial_recovery":{"area_id":"area-439baa3c8c9543fcaad869f78a661653","at":"2026-09-05T07:28:24.041481+00:00","context":"/home/derrick/.claude","executable":"/home/derrick/.local/bin/claude","generation":1,"native_id":"540f01be-c322-4bcf-bcd1-3c2a5b75f0bd","required_environment":[],"resume_argv":["/home/derrick/.local/bin/claude","--permission-mode","dontAsk","--tools","Read,Bash","--allowedTools","Read,Bash(/tmp/ctlrm-implementation/.venv/bin/python3 -m ctlrm --root /tmp/ctlrm-managed-native:*)","--resume","540f01be-c322-4bcf-bcd1-3c2a5b75f0bd",""],"root":"/tmp/ctlrm-managed-native","schema_version":1,"session_id":"session-d6917cd078db429fa8bed5a9d49211e7"},"initial_work":{"generation":1,"id":"work-0a7ea1c14e084de0bfda23db95b861a9","message":{"body":"Work ID: work-0a7ea1c14e084de0bfda23db95b861a9\nAcknowledge this work ID before acting.\n\nRemember the exact token IRIS-7382 in this conversation. Acknowledge this work ID before acting. Then report completed with the documented session disposition command. Do not edit files or poll.","created_at":"2026-09-05T07:29:53.806863+00:00","files":[],"from":"coordinator","id":"msg-9338beba8e8546668a51ad65e41f55b8","kind":"prompt","node_id":null,"run_id":null,"status":"pending","title":"prompt","to":"agent","workflow_id":null},"status":"completed"},"killed_at":"2026-09-05T07:31:17.481761+00:00","native_id":"540f01be-c322-4bcf-bcd1-3c2a5b75f0bd","provider_process":"157014:850395","recall_work":{"generation":2,"id":"work-515bc22c1858446ab0e409d74446d342","message":{"body":"Work ID: work-515bc22c1858446ab0e409d74446d342\nAcknowledge this work ID before acting.\n\nWithout opening old mailbox messages or any other files, recall the exact acceptance token from the previous completed prompt in this native conversation and print it in your response. Acknowledge this work ID first and report completed afterward. Only read this current assignment and use the documented ctlrm commands. Do not poll.","created_at":"2026-09-05T07:32:21.946279+00:00","files":[],"from":"coordinator","id":"msg-f282df14eb214504a9dad380bbe4f18a","kind":"prompt","node_id":null,"run_id":null,"status":"pending","title":"prompt","to":"agent","workflow_id":null},"status":"completed"},"resumed_generation":2,"resumed_native_id":"540f01be-c322-4bcf-bcd1-3c2a5b75f0bd","resumed_recovery":{"area_id":"area-439baa3c8c9543fcaad869f78a661653","at":"2026-09-05T07:31:48.001959+00:00","context":"/home/derrick/.claude","executable":"/home/derrick/.local/bin/claude","generation":2,"native_id":"540f01be-c322-4bcf-bcd1-3c2a5b75f0bd","required_environment":[],"resume_argv":["/home/derrick/.local/bin/claude","--permission-mode","dontAsk","--tools","Read,Bash","--allowedTools","Read,Bash(/tmp/ctlrm-implementation/.venv/bin/python3 -m ctlrm --root /tmp/ctlrm-managed-native:*)","--resume","540f01be-c322-4bcf-bcd1-3c2a5b75f0bd",""],"root":"/tmp/ctlrm-managed-native","schema_version":1,"session_id":"session-d6917cd078db429fa8bed5a9d49211e7"},"root":"/tmp/ctlrm-managed-native","session_id":"session-d6917cd078db429fa8bed5a9d49211e7","signal":"SIGKILL"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"area_id":"area-dcbf097538734122960a5b612e277636","at":"2026-09-05T09:12:15.847055+00:00","final_output":"version two","handoff_supervisor_restart":true,"human_response":"exercised by acceptance controller","interrupted_execution":"execution-7edfb41a22c645149b86086b20110f8a","native_implementer":"01a070d1-f394-75d0-9fe7-13e13ddf6e22","recovered_generation":2,"run":{"active":null,"executions":[{"artifact":"artifact-3a808a7cd8b04730ae4f679d86c30919502cb1f0cfc9d42884c6a91ca3a871e9","generation":2,"id":"execution-7edfb41a22c645149b86086b20110f8a","input":{},"message":{"body":"Area: area-dcbf097538734122960a5b612e277636\nRun: run-74e3b4884e844374a6c4ef9894c065ad\nWork ID: execution-7edfb41a22c645149b86086b20110f8a\nRole instructions: This is a bounded ctlrm protocol acceptance test. Only edit acceptance.txt. No repository implementation work or code review subprocesses are requested. Always follow assignment acknowledgment/report commands. On the FIRST implement visit, acknowledge, write acceptance.txt with exactly version one, then end your turn WITHOUT reporting completion. The controller will interrupt and natively resume you. In the resumed generation, acknowledge readiness, reconcile as in_progress, acknowledge this same execution using the current generation, then report completed. Do not rewrite the existing version one file after recovery. On a later implement visit triggered by changes_requested, write exactly version two and report completed normally. Never act as the human owner.\nTask: .ctlrm/task.md\nInput: {}\nAllowed outcomes: completed\nBefore acting, run: /tmp/ctlrm-implementation/.venv/bin/python3 -m ctlrm --root /tmp/ctlrm-mixed-native workflow acknowledge --run-id run-74e3b4884e844374a6c4ef9894c065ad --execution-id execution-7edfb41a22c645149b86086b20110f8a --participant implementer --session-id session-1e23fc2d53e144a89602c4d51f80e503 --generation 1\nReport with: /tmp/ctlrm-implementation/.venv/bin/python3 -m ctlrm --root /tmp/ctlrm-mixed-native workflow report --run-id run-74e3b4884e844374a6c4ef9894c065ad --execution-id execution-7edfb41a22c645149b86086b20110f8a --participant implementer --session-id session-1e23fc2d53e144a89602c4d51f80e503 --generation 1 --outcome OUTCOME --summary SUMMARY\nAfter native resume use your CURRENT generation in these commands. Do not choose the next recipient; the workflow routes accepted outcomes. After an accepted report, finish your turn and wait; do not perform further work.","created_at":"2026-09-05T09:07:26.747440+00:00","files":[],"from":"coordinator","id":"msg-745f6060b3ef4d37835410bebd1aca1e","kind":"assignment","node_id":null,"run_id":null,"status":"pending","title":"assignment","to":"implementer","workflow_id":null},"outcome":"completed","participant":"implementer","session_id":"session-1e23fc2d53e144a89602c4d51f80e503","status":"completed","step":"implement","summary":"Reconciled as in_progress and acknowledged in generation 2. Verified acceptance.txt contains exactly version one without rewriting it."},{"artifact":"artifact-21550c592394dee7a54f4e234eeaa3deb49385749322a851d545316473fb04b7","generation":1,"id":"execution-af1ac02a58734ee58c75f535ecd72d1d","input":{"artifact":"artifact-3a808a7cd8b04730ae4f679d86c30919502cb1f0cfc9d42884c6a91ca3a871e9","execution_id":"execution-7edfb41a22c645149b86086b20110f8a","outcome":"completed","summary":"Reconciled as in_progress and acknowledged in generation 2. Verified acceptance.txt contains exactly version one without rewriting it."},"message":{"body":"Area: area-dcbf097538734122960a5b612e277636\nRun: run-74e3b4884e844374a6c4ef9894c065ad\nWork ID: execution-af1ac02a58734ee58c75f535ecd72d1d\nRole instructions: Bounded protocol acceptance test. Read acceptance.txt and acknowledge the exact input artifact. If it says version one, report changes_requested with summary Change acceptance.txt to exactly version two. If it says version two, report approved with summary Version two verified. Do not modify any files and do not run another review agent. Use the supplied workflow acknowledgment/report commands with your current generation. Never act as the human owner.\nTask: .ctlrm/task.md\nInput: {\"artifact\": \"artifact-3a808a7cd8b04730ae4f679d86c30919502cb1f0cfc9d42884c6a91ca3a871e9\", \"execution_id\": \"execution-7edfb41a22c645149b86086b20110f8a\", \"outcome\": \"completed\", \"summary\": \"Reconciled as in_progress and acknowledged in generation 2. Verified acceptance.txt contains exactly version one without rewriting it.\"}\nAllowed outcomes: approved, changes_requested\nBefore acting, run: /tmp/ctlrm-implementation/.venv/bin/python3 -m ctlrm --root /tmp/ctlrm-mixed-native workflow acknowledge --run-id run-74e3b4884e844374a6c4ef9894c065ad --execution-id execution-af1ac02a58734ee58c75f535ecd72d1d --participant reviewer --session-id session-3bd4551d3215426287a69e82a2845b81 --generation 1 --input-artifact artifact-3a808a7cd8b04730ae4f679d86c30919502cb1f0cfc9d42884c6a91ca3a871e9\nReport with: /tmp/ctlrm-implementation/.venv/bin/python3 -m ctlrm --root /tmp/ctlrm-mixed-native workflow report --run-id run-74e3b4884e844374a6c4ef9894c065ad --execution-id execution-af1ac02a58734ee58c75f535ecd72d1d --participant reviewer --session-id session-3bd4551d3215426287a69e82a2845b81 --generation 1 --input-artifact artifact-3a808a7cd8b04730ae4f679d86c30919502cb1f0cfc9d42884c6a91ca3a871e9 --outcome OUTCOME --summary SUMMARY\nAfter native resume use your CURRENT generation in these commands. Do not choose the next recipient; the workflow routes accepted outcomes. After an accepted report, finish your turn and wait; do not perform further work.","created_at":"2026-09-05T09:10:33.547900+00:00","files":[],"from":"coordinator","id":"msg-cea145f2be0c421296b1f64ed9c3bfb9","kind":"assignment","node_id":null,"run_id":null,"status":"pending","title":"assignment","to":"reviewer","workflow_id":null},"outcome":"changes_requested","participant":"reviewer","session_id":"session-3bd4551d3215426287a69e82a2845b81","status":"completed","step":"review","summary":"Change acceptance.txt to exactly version two"},{"artifact":"artifact-29f8a96dc842cb5a351514c06da7b6f05bf828c29f2c7bf84cc21f6eb29340d2","generation":2,"id":"execution-01d6eba5e01a4cb0af250761664a59f6","input":{"artifact":"artifact-21550c592394dee7a54f4e234eeaa3deb49385749322a851d545316473fb04b7","execution_id":"execution-af1ac02a58734ee58c75f535ecd72d1d","outcome":"changes_requested","summary":"Change acceptance.txt to exactly version two"},"message":{"body":"Area: area-dcbf097538734122960a5b612e277636\nRun: run-74e3b4884e844374a6c4ef9894c065ad\nWork ID: execution-01d6eba5e01a4cb0af250761664a59f6\nRole instructions: This is a bounded ctlrm protocol acceptance test. Only edit acceptance.txt. No repository implementation work or code review subprocesses are requested. Always follow assignment acknowledgment/report commands. On the FIRST implement visit, acknowledge, write acceptance.txt with exactly version one, then end your turn WITHOUT reporting completion. The controller will interrupt and natively resume you. In the resumed generation, acknowledge readiness, reconcile as in_progress, acknowledge this same execution using the current generation, then report completed. Do not rewrite the existing version one file after recovery. On a later implement visit triggered by changes_requested, write exactly version two and report completed normally. Never act as the human owner.\nTask: .ctlrm/task.md\nInput: {\"execution_id\": \"execution-af1ac02a58734ee58c75f535ecd72d1d\", \"outcome\": \"changes_requested\", \"summary\": \"Change acceptance.txt to exactly version two\", \"artifact\": \"artifact-21550c592394dee7a54f4e234eeaa3deb49385749322a851d545316473fb04b7\"}\nAllowed outcomes: completed\nBefore acting, run: /tmp/ctlrm-implementation/.venv/bin/python3 -m ctlrm --root /tmp/ctlrm-mixed-native workflow acknowledge --run-id run-74e3b4884e844374a6c4ef9894c065ad --execution-id execution-01d6eba5e01a4cb0af250761664a59f6 --participant implementer --session-id session-1e23fc2d53e144a89602c4d51f80e503 --generation 2 --input-artifact artifact-21550c592394dee7a54f4e234eeaa3deb49385749322a851d545316473fb04b7\nReport with: /tmp/ctlrm-implementation/.venv/bin/python3 -m ctlrm --root /tmp/ctlrm-mixed-native workflow report --run-id run-74e3b4884e844374a6c4ef9894c065ad --execution-id execution-01d6eba5e01a4cb0af250761664a59f6 --participant implementer --session-id session-1e23fc2d53e144a89602c4d51f80e503 --generation 2 --input-artifact artifact-21550c592394dee7a54f4e234eeaa3deb49385749322a851d545316473fb04b7 --outcome OUTCOME --summary SUMMARY\nAfter native resume use your CURRENT generation in these commands. Do not choose the next recipient; the workflow routes accepted outcomes. After an accepted report, finish your turn and wait; do not perform further work.","created_at":"2026-09-05T09:10:50.277924+00:00","files":[],"from":"coordinator","id":"msg-ee19c4fbe2384019991dbafa9390df2b","kind":"assignment","node_id":null,"run_id":null,"status":"pending","title":"assignment","to":"implementer","workflow_id":null},"outcome":"completed","participant":"implementer","session_id":"session-1e23fc2d53e144a89602c4d51f80e503","status":"completed","step":"implement","summary":"Changed acceptance.txt to exactly version two and verified its exact bytes."},{"artifact":"artifact-c321e643b05bb8c8cc288018d93a011185d8cfa13bf544657e3cc4194684aee1","generation":1,"id":"execution-e7a895f0890d450ca0a3ba48eb605cfd","input":{"artifact":"artifact-29f8a96dc842cb5a351514c06da7b6f05bf828c29f2c7bf84cc21f6eb29340d2","execution_id":"execution-01d6eba5e01a4cb0af250761664a59f6","outcome":"completed","summary":"Changed acceptance.txt to exactly version two and verified its exact bytes."},"message":{"body":"Area: area-dcbf097538734122960a5b612e277636\nRun: run-74e3b4884e844374a6c4ef9894c065ad\nWork ID: execution-e7a895f0890d450ca0a3ba48eb605cfd\nRole instructions: Bounded protocol acceptance test. Read acceptance.txt and acknowledge the exact input artifact. If it says version one, report changes_requested with summary Change acceptance.txt to exactly version two. If it says version two, report approved with summary Version two verified. Do not modify any files and do not run another review agent. Use the supplied workflow acknowledgment/report commands with your current generation. Never act as the human owner.\nTask: .ctlrm/task.md\nInput: {\"execution_id\": \"execution-01d6eba5e01a4cb0af250761664a59f6\", \"outcome\": \"completed\", \"summary\": \"Changed acceptance.txt to exactly version two and verified its exact bytes.\", \"artifact\": \"artifact-29f8a96dc842cb5a351514c06da7b6f05bf828c29f2c7bf84cc21f6eb29340d2\"}\nAllowed outcomes: approved, changes_requested\nBefore acting, run: /tmp/ctlrm-implementation/.venv/bin/python3 -m ctlrm --root /tmp/ctlrm-mixed-native workflow acknowledge --run-id run-74e3b4884e844374a6c4ef9894c065ad --execution-id execution-e7a895f0890d450ca0a3ba48eb605cfd --participant reviewer --session-id session-3bd4551d3215426287a69e82a2845b81 --generation 1 --input-artifact artifact-29f8a96dc842cb5a351514c06da7b6f05bf828c29f2c7bf84cc21f6eb29340d2\nReport with: /tmp/ctlrm-implementation/.venv/bin/python3 -m ctlrm --root /tmp/ctlrm-mixed-native workflow report --run-id run-74e3b4884e844374a6c4ef9894c065ad --execution-id execution-e7a895f0890d450ca0a3ba48eb605cfd --participant reviewer --session-id session-3bd4551d3215426287a69e82a2845b81 --generation 1 --input-artifact artifact-29f8a96dc842cb5a351514c06da7b6f05bf828c29f2c7bf84cc21f6eb29340d2 --outcome OUTCOME --summary SUMMARY\nAfter native resume use your CURRENT generation in these commands. Do not choose the next recipient; the workflow routes accepted outcomes. After an accepted report, finish your turn and wait; do not perform further work.","created_at":"2026-09-05T09:11:49.072292+00:00","files":[],"from":"coordinator","id":"msg-6316c2609e874c32bbf2b82d8003d98d","kind":"assignment","node_id":null,"run_id":null,"status":"pending","title":"assignment","to":"reviewer","workflow_id":null},"outcome":"approved","participant":"reviewer","session_id":"session-3bd4551d3215426287a69e82a2845b81","status":"completed","step":"review","summary":"Version two verified"},{"artifact":"artifact-cfa8a12a6fe891eba8425a22bcde66e427b475c60456dfb506ef12803dcb2421","generation":null,"id":"execution-9592c63076df4f4c9cae4097b08374d1","input":{"artifact":"artifact-c321e643b05bb8c8cc288018d93a011185d8cfa13bf544657e3cc4194684aee1","execution_id":"execution-e7a895f0890d450ca0a3ba48eb605cfd","outcome":"approved","summary":"Version two verified"},"message":{"body":"Area: area-dcbf097538734122960a5b612e277636\nRun: run-74e3b4884e844374a6c4ef9894c065ad\nWork ID: execution-9592c63076df4f4c9cae4097b08374d1\nRole instructions: Accept the final version after the review loop.\nTask: .ctlrm/task.md\nInput: {\"execution_id\": \"execution-e7a895f0890d450ca0a3ba48eb605cfd\", \"outcome\": \"approved\", \"summary\": \"Version two verified\", \"artifact\": \"artifact-c321e643b05bb8c8cc288018d93a011185d8cfa13bf544657e3cc4194684aee1\"}\nAllowed outcomes: approved\nBefore acting, run: /tmp/ctlrm-implementation/.venv/bin/python3 -m ctlrm --root /tmp/ctlrm-mixed-native workflow acknowledge --run-id run-74e3b4884e844374a6c4ef9894c065ad --execution-id execution-9592c63076df4f4c9cae4097b08374d1 --participant owner --input-artifact artifact-c321e643b05bb8c8cc288018d93a011185d8cfa13bf544657e3cc4194684aee1\nReport with: /tmp/ctlrm-implementation/.venv/bin/python3 -m ctlrm --root /tmp/ctlrm-mixed-native workflow report --run-id run-74e3b4884e844374a6c4ef9894c065ad --execution-id execution-9592c63076df4f4c9cae4097b08374d1 --participant owner --input-artifact artifact-c321e643b05bb8c8cc288018d93a011185d8cfa13bf544657e3cc4194684aee1 --outcome OUTCOME --summary SUMMARY\nAfter native resume use your CURRENT generation in these commands. Do not choose the next recipient; the workflow routes accepted outcomes. After an accepted report, finish your turn and wait; do not perform further work.","created_at":"2026-09-05T09:12:11.489732+00:00","files":[],"from":"coordinator","id":"msg-faef987c47e54fafa6919d466cfd281e","kind":"assignment","node_id":null,"run_id":null,"status":"pending","title":"assignment","to":"owner","workflow_id":null},"outcome":"approved","participant":"owner","session_id":null,"status":"completed","step":"approve","summary":"Acceptance controller verified version two and exercised the human response API."}],"id":"run-74e3b4884e844374a6c4ef9894c065ad","reason":null,"status":"completed","task_id":"task-6d7369d3d346443eb9747bae13ae9f95"},"second_area_canceled_before_launch":true,"second_area_id":"area-213057c5365e4a0eb75fd48969b7f981","sessions_explicitly_stopped":true,"unchanged_template_reused":true}
|