@lifeaitools/rdc-skills 0.26.6 → 0.28.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/.claude-plugin/plugin.json +58 -12
- package/package.json +1 -1
- package/skills/collab/COLLABORATOR.md +179 -0
- package/skills/collab/SKILL.md +279 -157
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rdc",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"description": "RDC typed-agent dispatch skill suite for Claude Code — plan, build, review, overnight unattended builds with work-item tracking and TDD enforcement.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "LIFEAI",
|
|
@@ -1402,7 +1402,12 @@
|
|
|
1402
1402
|
"name": "action",
|
|
1403
1403
|
"required": false,
|
|
1404
1404
|
"default": "status",
|
|
1405
|
-
"values": [
|
|
1405
|
+
"values": [
|
|
1406
|
+
"status",
|
|
1407
|
+
"install",
|
|
1408
|
+
"repair",
|
|
1409
|
+
"update"
|
|
1410
|
+
]
|
|
1406
1411
|
}
|
|
1407
1412
|
],
|
|
1408
1413
|
"flags": []
|
|
@@ -1424,7 +1429,9 @@
|
|
|
1424
1429
|
"GPU crash"
|
|
1425
1430
|
],
|
|
1426
1431
|
"follows": [],
|
|
1427
|
-
"leads_to": [
|
|
1432
|
+
"leads_to": [
|
|
1433
|
+
"status"
|
|
1434
|
+
],
|
|
1428
1435
|
"sandbox_aware": false,
|
|
1429
1436
|
"output_contract": "guides/output-contract.md",
|
|
1430
1437
|
"enabled_default": true,
|
|
@@ -1580,19 +1587,58 @@
|
|
|
1580
1587
|
"category": "reporting",
|
|
1581
1588
|
"usage": "rdc:behavior-audit <report-dir> [--since-days N] [--latest N] [--reprocess]",
|
|
1582
1589
|
"args": {
|
|
1583
|
-
"positional": [
|
|
1590
|
+
"positional": [
|
|
1591
|
+
{
|
|
1592
|
+
"name": "report-dir",
|
|
1593
|
+
"required": true,
|
|
1594
|
+
"description": "Bounded directory for the evidence bundle.",
|
|
1595
|
+
"accepts": "path"
|
|
1596
|
+
}
|
|
1597
|
+
],
|
|
1584
1598
|
"flags": [
|
|
1585
|
-
{
|
|
1586
|
-
|
|
1587
|
-
|
|
1599
|
+
{
|
|
1600
|
+
"name": "--since-days",
|
|
1601
|
+
"type": "number",
|
|
1602
|
+
"default": 7,
|
|
1603
|
+
"description": "Only include transcripts modified within the window."
|
|
1604
|
+
},
|
|
1605
|
+
{
|
|
1606
|
+
"name": "--latest",
|
|
1607
|
+
"type": "number",
|
|
1608
|
+
"default": null,
|
|
1609
|
+
"description": "Limit to the newest N sessions per engine."
|
|
1610
|
+
},
|
|
1611
|
+
{
|
|
1612
|
+
"name": "--reprocess",
|
|
1613
|
+
"type": "boolean",
|
|
1614
|
+
"default": false,
|
|
1615
|
+
"description": "Intentionally parse completed hashes again without deleting the ledger."
|
|
1616
|
+
}
|
|
1588
1617
|
]
|
|
1589
1618
|
},
|
|
1590
|
-
"requires": [
|
|
1591
|
-
|
|
1619
|
+
"requires": [
|
|
1620
|
+
"codeflow",
|
|
1621
|
+
"work-items-rpc"
|
|
1622
|
+
],
|
|
1623
|
+
"produces": [
|
|
1624
|
+
"work_items",
|
|
1625
|
+
".rdc/reports/"
|
|
1626
|
+
],
|
|
1592
1627
|
"default_model": "inherit",
|
|
1593
|
-
"triggers": [
|
|
1594
|
-
|
|
1595
|
-
|
|
1628
|
+
"triggers": [
|
|
1629
|
+
"audit transcript calls",
|
|
1630
|
+
"audit codex behavior",
|
|
1631
|
+
"audit claude behavior",
|
|
1632
|
+
"truth gate audit",
|
|
1633
|
+
"review behavior evidence",
|
|
1634
|
+
"why did the agent bypass the gate"
|
|
1635
|
+
],
|
|
1636
|
+
"follows": [
|
|
1637
|
+
"workitems"
|
|
1638
|
+
],
|
|
1639
|
+
"leads_to": [
|
|
1640
|
+
"review"
|
|
1641
|
+
],
|
|
1596
1642
|
"sandbox_aware": false,
|
|
1597
1643
|
"output_contract": "guides/output-contract.md",
|
|
1598
1644
|
"enabled_default": true,
|
package/package.json
CHANGED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# Collaborator Contract — read this if you were dispatched by `rdc:collab`
|
|
2
|
+
|
|
3
|
+
> **You are the responder.** Another agent (Claude Code, Codex, a local LLM, or a
|
|
4
|
+
> claude.ai session) dispatched you under a structured collaboration protocol.
|
|
5
|
+
> This document is *your* half of it. The initiator's half is
|
|
6
|
+
> [`SKILL.md`](./SKILL.md) in this directory.
|
|
7
|
+
>
|
|
8
|
+
> Link to this file in the dispatch itself so the peer can read it. Do not
|
|
9
|
+
> assume it has been read.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Why this exists
|
|
14
|
+
|
|
15
|
+
A collaboration fails in a specific, repeatable way: the initiator says **what to
|
|
16
|
+
discuss** and never **how to answer**, so the responder answers in whatever shape
|
|
17
|
+
is habitual to it — a file write, a plan document, a lesson, a wall of prose. A
|
|
18
|
+
full round is then spent parsing, arguing with, or discarding the reply.
|
|
19
|
+
|
|
20
|
+
Both halves carry a responsibility. The initiator owes you a format, numbered
|
|
21
|
+
points, and a named writer. You owe it a reply in that format, an honest
|
|
22
|
+
`BLOCKED`, and no unilateral writes.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## What you can expect FROM the initiator
|
|
27
|
+
|
|
28
|
+
If any of these is missing, say so in your reply — that is a legitimate answer,
|
|
29
|
+
not an evasion.
|
|
30
|
+
|
|
31
|
+
1. **A response contract** stated *before* the content — the exact format your
|
|
32
|
+
answer must take.
|
|
33
|
+
2. **Numbered points.** Unnumbered points get answered in aggregate, which
|
|
34
|
+
settles nothing.
|
|
35
|
+
3. **A named single writer** for the document or code under discussion, decided
|
|
36
|
+
before round one.
|
|
37
|
+
4. **Settled points never re-sent.** Each round carries only what is still open,
|
|
38
|
+
plus a one-line record of what was settled.
|
|
39
|
+
5. **A watchdog, not a nag.** If you go silent the initiator diagnoses first —
|
|
40
|
+
process alive, exit code, guard block, session validity — before re-sending.
|
|
41
|
+
It should not re-dispatch on top of a call you are still working.
|
|
42
|
+
6. **Escalation, not blame,** when you disagree. A stated disagreement with
|
|
43
|
+
evidence is a valid terminal state.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## The boundary — you are in a CONVERSATION, not a build
|
|
48
|
+
|
|
49
|
+
**Do not write to the repository during a collab. Not one file.**
|
|
50
|
+
|
|
51
|
+
This is not a restriction on you; it is what a collab *is*. Your deliverable is
|
|
52
|
+
the **reply**. If settling the point requires code, config, or a document change,
|
|
53
|
+
say what should change — the change itself happens afterward, in a session built
|
|
54
|
+
for it (`rdc:build`, an isolated worktree agent, or you working your own lane
|
|
55
|
+
against a work item).
|
|
56
|
+
|
|
57
|
+
**Why it matters to you specifically:** a peer that tries to write mid-conversation
|
|
58
|
+
can end up holding finished, correct work it cannot deliver — refused by a write
|
|
59
|
+
guard, then refused permission to stop by a gate demanding the delivery evidence
|
|
60
|
+
that guard just made impossible. That happened on 2026-08-14 and cost a complete
|
|
61
|
+
negotiation result. **Your reasoning in the reply is always deliverable. A file
|
|
62
|
+
write may not be.**
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## What you owe BACK — your responsibilities
|
|
67
|
+
|
|
68
|
+
### 1. Answer in the required format. Nothing outside it.
|
|
69
|
+
|
|
70
|
+
If the dispatch gives you a contract, use it verbatim. Prose around the blocks
|
|
71
|
+
is not helpful — it is what the format exists to remove.
|
|
72
|
+
|
|
73
|
+
**One block per point:**
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
POINT <n>: AGREE | AGREE-WITH-AMENDMENT | DISAGREE
|
|
77
|
+
EDIT: <the exact section and change that SHOULD be made, or NONE — describe it, do not make it>
|
|
78
|
+
REASON: <one sentence — only if AMENDMENT or DISAGREE>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**For a factual question rather than a proposal:**
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
FINDING <n>: <the answer, one sentence>
|
|
85
|
+
EVIDENCE: <command run + literal result — exit code, row count, probe status>
|
|
86
|
+
CONFIDENCE: VERIFIED | INFERRED | UNKNOWN
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Always close with:**
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
OWNER: <who lands the resulting Decision or work item — exactly one agent>
|
|
93
|
+
BLOCKED: <what you cannot do from where you are, or NONE>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 2. Declare `BLOCKED` loudly. Silence is the worst answer.
|
|
97
|
+
|
|
98
|
+
If you cannot write, cannot reach a service, or lack the credential — **say it in
|
|
99
|
+
the reply**. A blocked responder that goes quiet is indistinguishable from a dead
|
|
100
|
+
one, and it costs the initiator a full watchdog cycle to discover what you
|
|
101
|
+
already knew.
|
|
102
|
+
|
|
103
|
+
**Your completed reasoning still counts when your write is blocked.** Put the
|
|
104
|
+
answer in the reply body. Do not let it die inside a failed tool call.
|
|
105
|
+
|
|
106
|
+
### 3. Do not write outside your own lane or scope.
|
|
107
|
+
|
|
108
|
+
- **Codex:** if you were started by `codex exec` (headless), you CANNOT write in any lane — your managed identity was never minted and `-C` does not create it. Report `BLOCKED: headless codex exec has no lane claim` and put your answer in the reply. If you were started by the launcher in a Codex-owned lane (`x-codex-N`, `x-codex-sv`), you can write, but not during a collab.
|
|
109
|
+
A session created in the wrong cwd is poisoned for its whole life — `resume` replays the recorded identity. Writes are refused with
|
|
110
|
+
`CODEX MANAGED LANE: App Local must use an owned managed Codex lane`. That is a
|
|
111
|
+
**dispatch defect, not your failure** — report it as `BLOCKED: poisoned session identity, start a NEW session in
|
|
112
|
+
my lane` — `-C` will NOT repair it. Do not attempt a workaround.
|
|
113
|
+
- **Claude agents:** if you will commit, you must have been given
|
|
114
|
+
`isolation: "worktree"` as a real tool parameter. A sentence in your prompt
|
|
115
|
+
claiming isolation is inert.
|
|
116
|
+
- **Everyone:** never `git stash` in a shared checkout, never force-push, never
|
|
117
|
+
commit onto a branch you were not told to use. If the branch you land on is
|
|
118
|
+
someone else's, say so rather than committing "just this once".
|
|
119
|
+
|
|
120
|
+
### 4. Do not take ownership you were not given.
|
|
121
|
+
|
|
122
|
+
Exactly one agent writes each artifact. If you were not named the writer, put
|
|
123
|
+
your change in the **reply**, not in the file. Two writers on one surface loses
|
|
124
|
+
work with no error.
|
|
125
|
+
|
|
126
|
+
If the named writer is you and you are blocked, say so — ownership transfers
|
|
127
|
+
explicitly, never by assumption.
|
|
128
|
+
|
|
129
|
+
### 5. An agreement is a Decision, not an episode.
|
|
130
|
+
|
|
131
|
+
When a negotiation settles, the outcome belongs in the **governing document** —
|
|
132
|
+
the plan, the ARCHITECTURE.md, the rule — where it becomes queryable
|
|
133
|
+
architecture. **Do not file a settled agreement as a lesson.** Lessons are for
|
|
134
|
+
episodes: a root-cause theory that proved wrong, a documented path that did not
|
|
135
|
+
work, a surprising tool behaviour. A settled negotiation filed as a lesson buries
|
|
136
|
+
a constraint in an append-only pile nobody traverses.
|
|
137
|
+
|
|
138
|
+
### 6. Answer the point that was asked.
|
|
139
|
+
|
|
140
|
+
If you disagree with the framing, say `DISAGREE` and give the reason in one
|
|
141
|
+
sentence — do not silently answer a different, easier question. If a point is
|
|
142
|
+
unanswerable without information you do not have, say that in `REASON` and name
|
|
143
|
+
what would settle it.
|
|
144
|
+
|
|
145
|
+
### 7. Do not restate what is already settled.
|
|
146
|
+
|
|
147
|
+
The initiator sends only open points. Re-litigating a settled one restarts a
|
|
148
|
+
negotiation that was converging.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Terminal states — any of these is a complete, legitimate answer
|
|
153
|
+
|
|
154
|
+
| State | Meaning |
|
|
155
|
+
|---|---|
|
|
156
|
+
| All points `AGREE` | Converged. The named writer applies the edits. |
|
|
157
|
+
| Some `DISAGREE` with reasons | A real disagreement. Escalates as a packet, not a transcript. |
|
|
158
|
+
| `BLOCKED` on everything | You cannot act from where you are. Name the fix. |
|
|
159
|
+
| A point needs evidence neither side has | Name the measurement that would settle it. |
|
|
160
|
+
|
|
161
|
+
**"I could not do it and here is exactly why" outranks a plausible answer you are
|
|
162
|
+
not confident in.** The initiator can act on a precise blocker immediately; it
|
|
163
|
+
cannot act on a guess it has to verify.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Anti-patterns — these each cost a full round
|
|
168
|
+
|
|
169
|
+
| Anti-pattern | Why |
|
|
170
|
+
|---|---|
|
|
171
|
+
| Answering in prose when a format was given | The initiator has to parse and may misread you |
|
|
172
|
+
| Writing a file instead of replying | Your answer may be guard-blocked and lost |
|
|
173
|
+
| Filing a settled agreement as a lesson | Buries a queryable Decision |
|
|
174
|
+
| Going silent when blocked | Indistinguishable from being dead |
|
|
175
|
+
| Editing a document you do not own | Lost work, no error, no trace |
|
|
176
|
+
| Writing ANY file during a collab | Not your job here — the reply is the deliverable |
|
|
177
|
+
| Committing to whatever branch you happen to be on | The change strands where nobody looks for it |
|
|
178
|
+
| Answering an easier adjacent question | The real point stays open and looks settled |
|
|
179
|
+
| Attempting a workaround for a guard block | The guard is usually right; the dispatch is usually wrong |
|
package/skills/collab/SKILL.md
CHANGED
|
@@ -1,239 +1,361 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rdc:collab
|
|
3
|
-
description: "Usage `rdc:collab
|
|
3
|
+
description: "Usage `rdc:collab <collaborator> [inbound] <topic>` — Structured agent-to-agent CONVERSATION with Codex, a local LLM, a Claude agent, or a claude.ai session. Converges on a decision and never writes to the repo — work that needs writing becomes a work item for rdc:build. Every dispatch carries a response contract."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
> **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
|
|
7
7
|
> Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
|
|
8
8
|
> One checklist upfront, updated in place, shown again at end with a 1-line verdict.
|
|
9
9
|
|
|
10
|
-
> **Sandbox contract:** This skill honors `RDC_TEST=1` per `guides/agent-bootstrap.md` § RDC_TEST Sandbox Contract. Destructive external calls short-circuit under the flag. Chitchat relay writes (`chitchat_reply`) and git push are skipped under `RDC_TEST=1`.
|
|
10
|
+
> **Sandbox contract:** This skill honors `RDC_TEST=1` per `guides/agent-bootstrap.md` § RDC_TEST Sandbox Contract. Destructive external calls short-circuit under the flag. Chitchat relay writes (`chitchat_reply`), engine dispatch, and git push are skipped under `RDC_TEST=1`.
|
|
11
11
|
|
|
12
|
+
# /rdc:collab — Structured Agent-to-Agent Collaboration
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
>
|
|
15
|
-
>
|
|
16
|
-
> Transport: chitchat MCP tools (`chitchat_poll` / `chitchat_reply`) + SSE stream
|
|
17
|
-
> Dave is watching this terminal and can interject at any time.
|
|
14
|
+
> `rdc:collab <collaborator> [inbound] <topic>`
|
|
15
|
+
> Collaborators: `codex` · `local-llm` · `claude-agent` · `claude-ai`
|
|
16
|
+
> Direction: outbound (default, you dispatch) · `inbound` (claude.ai relay, peer initiates)
|
|
18
17
|
|
|
19
18
|
---
|
|
20
19
|
|
|
21
|
-
##
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
## Collab is CONVERSATION. It never writes to the repo.
|
|
21
|
+
|
|
22
|
+
**There is one mode, because there was only ever one.** v0.27.0 shipped a
|
|
23
|
+
`delegate` mode whose contract asked the peer for `CHANGED: <file paths>` — an
|
|
24
|
+
instruction to go mutate the repo and report back. Handing work off is a real
|
|
25
|
+
need; routing it through a *conversation channel* is a category error. Work goes
|
|
26
|
+
to `rdc:build`, to an `Agent` with `isolation: "worktree"` as a real parameter, or
|
|
27
|
+
to a launcher-started session working its own lane against a work item. Those have
|
|
28
|
+
isolation, a work item, review, and landing. A chat channel has none of them.
|
|
29
|
+
|
|
30
|
+
**This is a design boundary, not a workaround for a broken door.** A separate,
|
|
31
|
+
real constraint exists — a headless `codex exec` peer currently cannot write at
|
|
32
|
+
all (see the note under Step 1) — but that constraint is a **bug being fixed**,
|
|
33
|
+
not the reason for this rule. Even once headless Codex can write, work handoff
|
|
34
|
+
still goes through the build path. Do not read the boundary as "collab can't
|
|
35
|
+
write"; read it as "collab isn't where writing belongs."
|
|
36
|
+
|
|
37
|
+
**The boundary:**
|
|
38
|
+
|
|
39
|
+
| Collab does | Collab never does |
|
|
40
|
+
|---|---|
|
|
41
|
+
| Ask, answer, converge, disagree | Edit a file |
|
|
42
|
+
| Produce a **Decision** for the governing document | Commit or push |
|
|
43
|
+
| Produce a **work item** when writing is required | Build, deploy, or land |
|
|
44
|
+
| Return findings, verdicts, evidence *as text* | Claim to have changed anything |
|
|
45
|
+
|
|
46
|
+
**When code must be written, collab is over.** Its output is a work item, and the
|
|
47
|
+
writing happens where writing belongs — `rdc:build`, an `Agent` with
|
|
48
|
+
`isolation: "worktree"` as a real parameter, or the peer working its own lane
|
|
49
|
+
against that item. A conversation channel is not a build channel.
|
|
50
|
+
|
|
51
|
+
**Why this is structural, not a style rule.** Because collab never mutates, a
|
|
52
|
+
collab session is non-mutating *by definition* — there is no mode to select
|
|
53
|
+
wrongly and no flag to leave on. Delivery gates (truth-gate, completion gate,
|
|
54
|
+
CodeFlow preflight) have nothing to gate, and safety guards (credential exposure,
|
|
55
|
+
cross-tree write, push-main, lane identity) remain fully live because nothing
|
|
56
|
+
here goes near them. The peer that tries to write is not blocked by policy; it is
|
|
57
|
+
simply doing something this skill never asks for.
|
|
25
58
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- `rdc:collab --session <id>` — start or resume a collab relay with the given session ID
|
|
29
|
-
|
|
30
|
-
## What This Is
|
|
59
|
+
---
|
|
31
60
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
61
|
+
> **Two halves.** This file is the **initiator's** contract — how to dispatch,
|
|
62
|
+
> what to demand, how to bound it. [`COLLABORATOR.md`](./COLLABORATOR.md) is the
|
|
63
|
+
> **responder's** contract — what the peer owes back and what it may expect from
|
|
64
|
+
> you. **Link `COLLABORATOR.md` in every dispatch**; a contract only one side has
|
|
65
|
+
> read is a contract only one side keeps.
|
|
37
66
|
|
|
38
67
|
---
|
|
39
68
|
|
|
40
|
-
##
|
|
69
|
+
## The rule this skill exists to enforce
|
|
41
70
|
|
|
42
|
-
|
|
71
|
+
**Never dispatch to another agent without a response contract.**
|
|
43
72
|
|
|
44
|
-
|
|
73
|
+
An agent asked an open question answers in whatever shape is habitual to it — a
|
|
74
|
+
file write, a plan, a lesson, a wall of prose. It is not being unhelpful; you
|
|
75
|
+
did not tell it how to answer. A dispatch without a contract produces output you
|
|
76
|
+
then have to parse, argue with, or discard, and it costs a full round every time.
|
|
77
|
+
|
|
78
|
+
**Corollary: an agreement is a Decision, not an episode.** When collaboration
|
|
79
|
+
settles a question, the output belongs in the governing document (and therefore
|
|
80
|
+
in AKG) as a decision/constraint/policy — never filed as a lesson. Lessons are
|
|
81
|
+
for *episodes*: something was learned the hard way. A settled negotiation filed
|
|
82
|
+
as a lesson buries a queryable constraint in an append-only pile nobody
|
|
83
|
+
traverses.
|
|
45
84
|
|
|
46
85
|
---
|
|
47
86
|
|
|
48
|
-
##
|
|
87
|
+
## Two clocks: the reply drives, a watchdog bounds
|
|
88
|
+
|
|
89
|
+
Both are required, and they do different jobs. Running either alone is a known
|
|
90
|
+
failure:
|
|
91
|
+
|
|
92
|
+
| | Driver | Watchdog |
|
|
93
|
+
|---|---|---|
|
|
94
|
+
| What it is | the collaborator's reply | a `/loop` or `Monitor`, armed at dispatch |
|
|
95
|
+
| Fires on | completion | **silence past the expected envelope** |
|
|
96
|
+
| Job | advance the negotiation | **diagnose why nothing came back** |
|
|
97
|
+
| Cadence | none — event-driven | ~2–3× the peer's normal reply time |
|
|
98
|
+
|
|
99
|
+
**Driver alone → you wait forever.** A background dispatch with no timeout is
|
|
100
|
+
correct about not guessing a duration and wrong about liveness: if the peer dies,
|
|
101
|
+
is guard-blocked, or its session id has expired, nothing ever wakes you. This is
|
|
102
|
+
the failure the watchdog exists to catch.
|
|
103
|
+
|
|
104
|
+
**Watchdog alone → you fire on top of live calls.** A wall-clock cadence has no
|
|
105
|
+
relationship to the work: if the peer answers in 30s you idle the remainder, if
|
|
106
|
+
it takes 8 minutes you stack a second call onto the first.
|
|
107
|
+
|
|
108
|
+
### The watchdog does NOT retry. It investigates.
|
|
109
|
+
|
|
110
|
+
Re-dispatching a silent peer is the wrong reflex — it doubles the load on
|
|
111
|
+
something already failing and destroys the evidence of why. On wake, run the
|
|
112
|
+
diagnosis ladder in order and stop at the first hit:
|
|
113
|
+
|
|
114
|
+
1. **Is the process alive?** Check the background task's status. Still running is
|
|
115
|
+
a legitimate answer — re-arm the watchdog with a longer envelope and stop.
|
|
116
|
+
2. **Did it exit, and with what?** A non-zero exit or exit 143 (killed) is a
|
|
117
|
+
result, not silence. Read it.
|
|
118
|
+
3. **Was it guard-blocked?** Grep the output for a `deny`/`Blocked` line. The
|
|
119
|
+
`CODEX MANAGED LANE` block is the common one and is a *dispatch* defect
|
|
120
|
+
(wrong `-C`), not a peer failure — fix and re-dispatch once.
|
|
121
|
+
4. **Is the session still addressable?** A stale `resume <session-id>`, a stopped
|
|
122
|
+
chitchat session, or a dead local-LLM endpoint all present as silence.
|
|
123
|
+
5. **Did it answer somewhere you are not reading?** A peer that cannot write its
|
|
124
|
+
intended target often reports into stdout, a log, or an error body instead.
|
|
125
|
+
The answer may already exist.
|
|
126
|
+
6. **None of the above** → the peer is genuinely stuck. Escalate per Step 6 with
|
|
127
|
+
the ladder's findings attached. Do not silently retry.
|
|
128
|
+
|
|
129
|
+
Arm the watchdog **at dispatch**, disarm it **on reply**. An armed watchdog
|
|
130
|
+
outliving its dispatch is noise, and noise is how a real stall gets ignored.
|
|
131
|
+
|
|
132
|
+
---
|
|
49
133
|
|
|
50
|
-
|
|
134
|
+
## Step 0 — Parse arguments
|
|
51
135
|
|
|
52
|
-
If the session is not found:
|
|
53
136
|
```
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
chitchat_start(name: "<session-slug>")
|
|
57
|
-
Then pass the returned session_id here.
|
|
137
|
+
rdc:collab <collaborator> [mode] <topic…>
|
|
138
|
+
rdc:collab --session <id> ← legacy form, implies `claude-ai listen`
|
|
58
139
|
```
|
|
59
140
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
141
|
+
- No collaborator → list active chitchat sessions and available engines, then stop.
|
|
142
|
+
- `inbound` (or the legacy `--session <id>` form) → the peer initiates; see the
|
|
143
|
+
claude.ai relay section. Same conversation, opposite direction.
|
|
144
|
+
- **If the topic names work to be performed rather than a question to settle, this
|
|
145
|
+
is the wrong skill.** Create the work item and use `rdc:build` / `rdc:fixit`.
|
|
64
146
|
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
[rdc:collab] Session <id> active (chitchat transport).
|
|
68
|
-
SSE stream: http://127.0.0.1:52437/chitchat/<id>/stream
|
|
69
|
-
Waiting for messages from claude.ai... (Ctrl+C to end)
|
|
70
|
-
```
|
|
147
|
+
---
|
|
71
148
|
|
|
72
|
-
|
|
73
|
-
|
|
149
|
+
## Step 1 — Collaborator matrix
|
|
150
|
+
|
|
151
|
+
Resolve the transport BEFORE composing the message. Getting this wrong is the
|
|
152
|
+
most common failure and it fails at the guard layer, not the prompt layer.
|
|
153
|
+
|
|
154
|
+
| Collaborator | Invocation | Isolation requirement | Known failure mode |
|
|
155
|
+
|---|---|---|---|
|
|
156
|
+
| **`codex`** | `codex exec [-C <dir>] "<msg>"` · resume: `codex exec resume <session-id> "<msg>"` | **A headless `codex exec` peer is READ-ONLY. It cannot write to any lane — see below.** Never dispatch it from your own lane. | Its managed identity is fixed at session creation and `-C` does **not** change it. Dispatch from your lane and every write is refused with `CODEX MANAGED LANE: App Local must use an owned managed Codex lane` — permanently, for that session's whole life. |
|
|
157
|
+
|
|
158
|
+
> **`-C` does not establish lane identity — verified 2026-08-14, and an earlier
|
|
159
|
+
> version of this table said the opposite.** Managed identity is an 8-field record
|
|
160
|
+
> (`lane, role, repoIdentity, ownerPid, ownerStartFingerprint, sessionId,
|
|
161
|
+
> leaseEpoch, ownerToken`) built by `buildStartupIdentity()` in
|
|
162
|
+
> [`pool/codex-topology.mjs`](file:///C:/Dev/lifeai-env/pool/codex-topology.mjs)
|
|
163
|
+
> and minted **only by the interactive launcher**, which also claims the lease.
|
|
164
|
+
> `codex exec` has no lane-claim path, so it cannot produce that record — which
|
|
165
|
+
> means **a headless Codex peer cannot write in any lane, including its own**.
|
|
166
|
+
>
|
|
167
|
+
> Two consequences: (1) `resume` replays the session's *recorded* identity, so a
|
|
168
|
+
> session created in the wrong cwd is poisoned for life and `-C` will not repair
|
|
169
|
+
> it — start a new session instead; (2) treat a `codex exec` peer as a
|
|
170
|
+
> conversational participant only. Writing work belongs to a launcher-started
|
|
171
|
+
> Codex session, `rdc:build`, or an isolated-worktree agent.
|
|
172
|
+
>
|
|
173
|
+
> Beware the error text: `App Local denied: <lane> has a foreign live lease` also
|
|
174
|
+
> fires when there is **no lease at all** (`ownerMatchesLease` returns false for a
|
|
175
|
+
> null lease), so it will send you hunting a conflicting owner that does not exist.
|
|
176
|
+
|
|
177
|
+
file:///C:/Dev/lifeai-env/pool/codex-topology.mjs
|
|
178
|
+
| **`local-llm`** | local endpoint per `.claude/context/clauth.md`; credential via `curl -s http://127.0.0.1:52437/v/<service>` | none (no repo attachment) | Small context windows: send the contract and the open points, never the whole document. Link paths instead of pasting files. |
|
|
179
|
+
| **`claude-agent`** | `Agent` tool, or `claude -p --bare` / `claude --bg` | **`isolation: "worktree"` as an actual tool parameter** if it will commit — a prose claim of isolation is inert | Parallel agents on a shared checkout race on `git stash` and `.git/index`. See `.claude/rules/subagent-credentials.md`. |
|
|
180
|
+
| **`claude-ai`** | chitchat MCP (`chitchat_send` / `chitchat_poll` / `chitchat_reply`) + SSE | session-scoped | Messages evaporate when the session stops — export durable decisions to TinTin. |
|
|
181
|
+
|
|
182
|
+
**Dispatch is long-running.** Run engine dispatch as a **background task**, not
|
|
183
|
+
behind a `timeout` guess. A truncated call looks like a failure and is not one.
|
|
74
184
|
|
|
75
185
|
---
|
|
76
186
|
|
|
77
|
-
## Step
|
|
187
|
+
## Step 2 — Compose the response contract (mandatory)
|
|
78
188
|
|
|
79
|
-
|
|
189
|
+
Every dispatch carries an explicit answer format. The contract is not politeness —
|
|
190
|
+
it is what makes the reply *checkable*.
|
|
80
191
|
|
|
81
|
-
|
|
192
|
+
**Every field returns information. No field asks the peer what it changed** — if a
|
|
193
|
+
contract invites `CHANGED: <file paths>`, it has invited the peer to mutate the
|
|
194
|
+
repo mid-conversation, which is the v0.27.0 defect this version removes.
|
|
82
195
|
|
|
83
|
-
|
|
84
|
-
curl -s -N --max-time 30 http://127.0.0.1:52437/chitchat/<session_id>/stream
|
|
85
|
-
```
|
|
196
|
+
**The contract — one block per open point:**
|
|
86
197
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
198
|
+
```
|
|
199
|
+
POINT <n>: AGREE | AGREE-WITH-AMENDMENT | DISAGREE
|
|
200
|
+
EDIT: <the exact section and change that SHOULD be made, or NONE — describe it, do not make it>
|
|
201
|
+
REASON: <one sentence — only if AMENDMENT or DISAGREE>
|
|
202
|
+
```
|
|
90
203
|
|
|
91
|
-
**When
|
|
92
|
-
|
|
93
|
-
`chitchat_poll` after receiving via SSE. Proceed directly to Step 4 with the
|
|
94
|
-
parsed message body.
|
|
204
|
+
**When the point is a factual question rather than a proposal**, the peer answers
|
|
205
|
+
with findings — still text, still no repo mutation:
|
|
95
206
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
207
|
+
```
|
|
208
|
+
FINDING <n>: <the answer, one sentence>
|
|
209
|
+
EVIDENCE: <command run + literal result — exit code, row count, probe status>
|
|
210
|
+
CONFIDENCE: VERIFIED | INFERRED | UNKNOWN
|
|
211
|
+
```
|
|
100
212
|
|
|
101
|
-
|
|
102
|
-
`curl --max-time 30` ALWAYS exits 28 at the timeout boundary — that is normal for
|
|
103
|
-
a long-lived SSE stream and says nothing about delivery. If a `data:` event was
|
|
104
|
-
received in the output, process it and proceed to Step 4 — do NOT treat exit 28 as
|
|
105
|
-
a curl failure (lesson 2026-06-08-collab-sse-exit-28-is-success: exit 28 arrived
|
|
106
|
-
together with a full `event: message` / `data: {...}` payload, and reading it as a
|
|
107
|
-
failure misclassified a zero-latency delivery). Only **connection-refused or a
|
|
108
|
-
non-200** is a real curl failure that triggers the polling fallback.
|
|
213
|
+
Rules that make the contract hold:
|
|
109
214
|
|
|
110
|
-
**
|
|
111
|
-
|
|
215
|
+
1. **State the format before the content.** Contract first, then the points.
|
|
216
|
+
2. **Say what NOT to produce** when the peer has a known default — e.g. *"do not
|
|
217
|
+
write a lesson; this is a Decision and belongs in the plan."*
|
|
218
|
+
3. **Number the points.** Unnumbered points get answered in aggregate.
|
|
219
|
+
4. **Name the single writer before round 1** (see Step 4).
|
|
220
|
+
5. **Ask for `BLOCKED` explicitly.** Without it, a peer that cannot act reports
|
|
221
|
+
success or silence.
|
|
112
222
|
|
|
113
|
-
|
|
223
|
+
---
|
|
114
224
|
|
|
115
|
-
|
|
225
|
+
## Step 3 — Converge
|
|
116
226
|
|
|
117
227
|
```
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
228
|
+
open_points = [all points]
|
|
229
|
+
round = 0
|
|
230
|
+
while open_points and round < MAX_ROUNDS (default 4):
|
|
231
|
+
round += 1
|
|
232
|
+
dispatch(open_points, contract) ← background task, no timeout guess
|
|
233
|
+
arm_watchdog(envelope = 2-3x expected reply time)
|
|
234
|
+
reply = await completion ← OR watchdog fires first
|
|
235
|
+
if watchdog fired: run the diagnosis ladder; do NOT re-dispatch blindly
|
|
236
|
+
disarm_watchdog()
|
|
237
|
+
if reply does not match the contract:
|
|
238
|
+
re-dispatch ONCE restating the format only — never re-argue the content
|
|
239
|
+
settle: AGREE and accepted AGREE-WITH-AMENDMENT leave open_points
|
|
240
|
+
if open_points did not shrink this round:
|
|
241
|
+
STOP — escalate (Step 6). A non-shrinking round means the disagreement
|
|
242
|
+
is real, and further rounds spend tokens without moving it.
|
|
125
243
|
```
|
|
126
244
|
|
|
127
|
-
|
|
128
|
-
-
|
|
129
|
-
|
|
245
|
+
**Never re-send a settled point.** Each round carries only what is still open,
|
|
246
|
+
plus a one-line record of what was settled. Re-sending settled points is how a
|
|
247
|
+
negotiation becomes a loop that never terminates.
|
|
130
248
|
|
|
131
|
-
|
|
249
|
+
**Convergence is the termination condition, not a timer.**
|
|
132
250
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
You now have the message body (from SSE `data:` JSON or `chitchat_poll` result).
|
|
251
|
+
---
|
|
136
252
|
|
|
137
|
-
|
|
138
|
-
`type` field equal to `"stop"` in the JSON.
|
|
253
|
+
## Step 4 — Single-writer rule (for the OUTCOME, not the conversation)
|
|
139
254
|
|
|
140
|
-
|
|
255
|
+
Nobody writes during a collab. The single-writer rule governs **who lands the
|
|
256
|
+
settled Decision afterward** — name that agent before round 1 and say so in the
|
|
257
|
+
dispatch.
|
|
141
258
|
|
|
142
|
-
|
|
259
|
+
> Two active writers on one surface is forbidden — the same rule the fleet plans
|
|
260
|
+
> state as *"never run two active writers for one effect."*
|
|
143
261
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
──────────────────────────────────────
|
|
150
|
-
```
|
|
262
|
+
If the named writer turns out to be **structurally blocked** (wrong lane, no
|
|
263
|
+
credentials, read-only mount), ownership transfers to the other agent *for that
|
|
264
|
+
artifact only*, recorded in the change itself with attribution. A blocked writer
|
|
265
|
+
never means the agreed work is abandoned — the reasoning already exists in the
|
|
266
|
+
reply, which is exactly why the reply, not a file, is the deliverable.
|
|
151
267
|
|
|
152
268
|
---
|
|
153
269
|
|
|
154
|
-
## Step 5 —
|
|
270
|
+
## Step 5 — Land the outcome
|
|
155
271
|
|
|
156
|
-
|
|
157
|
-
- File edits, git commits to `develop`
|
|
158
|
-
- Supabase RPC queries
|
|
159
|
-
- Type-checks: `npx tsc --noEmit` (never `pnpm build`)
|
|
160
|
-
- Run skills: `/rdc:plan`, `/rdc:fixit`, etc.
|
|
161
|
-
- Answer questions directly
|
|
272
|
+
An agreement is a **Decision**. Route it by kind:
|
|
162
273
|
|
|
163
|
-
|
|
274
|
+
| Outcome | Home |
|
|
275
|
+
|---|---|
|
|
276
|
+
| Settled decision, constraint, or policy | The governing document — plan / ARCHITECTURE.md / rule. AKG ingests from there. |
|
|
277
|
+
| Work to perform | `insert_work_item` via RPC, per `.claude/rules/work-items-rpc.md` |
|
|
278
|
+
| A genuine hard-won episode (a wrong theory, a surprising infra behaviour) | `.rdc/lessons/` per `guides/lessons-learned-spec.md` |
|
|
279
|
+
| A stated, unresolved disagreement | Escalate — Step 6 |
|
|
164
280
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
chitchat_reply(session_id, "Turn <N> in progress: <what you've done so far>...")
|
|
168
|
-
```
|
|
169
|
-
This lets claude.ai see progress immediately rather than waiting for the full
|
|
170
|
-
response.
|
|
281
|
+
**Do not file a settled agreement as a lesson.** That is the single most common
|
|
282
|
+
misroute this skill exists to prevent.
|
|
171
283
|
|
|
172
284
|
---
|
|
173
285
|
|
|
174
|
-
## Step 6 —
|
|
175
|
-
|
|
176
|
-
When work is done, send the response via MCP:
|
|
286
|
+
## Step 6 — Escalate (only after convergence fails)
|
|
177
287
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
```
|
|
288
|
+
Escalation is the last step, never the first. It happens when a round fails to
|
|
289
|
+
shrink the open set, the round cap is hit, or both agents are blocked.
|
|
181
290
|
|
|
182
|
-
|
|
183
|
-
```
|
|
184
|
-
Turn <N> complete.
|
|
185
|
-
Commits: <sha1, sha2 or none>
|
|
186
|
-
|
|
187
|
-
<what you did, what you found, any questions or decisions needed from claude.ai>
|
|
188
|
-
```
|
|
291
|
+
Escalate as **one packet**, not a transcript:
|
|
189
292
|
|
|
190
|
-
Print to terminal:
|
|
191
293
|
```
|
|
192
|
-
|
|
193
|
-
|
|
294
|
+
UNRESOLVED: <the point, in one sentence>
|
|
295
|
+
POSITION A (<agent>): <claim + its evidence>
|
|
296
|
+
POSITION B (<agent>): <claim + its evidence>
|
|
297
|
+
WHAT WOULD SETTLE IT: <the measurement, probe, or decision needed>
|
|
298
|
+
COST OF EACH BRANCH: <one line each>
|
|
194
299
|
```
|
|
195
300
|
|
|
196
|
-
|
|
301
|
+
A transcript is not an escalation. If the human has to read the argument to find
|
|
302
|
+
the question, the packet was not written.
|
|
197
303
|
|
|
198
304
|
---
|
|
199
305
|
|
|
200
|
-
##
|
|
306
|
+
## `listen` mode — claude.ai relay
|
|
201
307
|
|
|
202
|
-
|
|
308
|
+
Legacy behaviour, unchanged and still correct for `claude-ai`. Transport is
|
|
309
|
+
chitchat MCP + SSE; you are the build half of a live session.
|
|
203
310
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
311
|
+
- `chitchat_list` to verify the session; `chitchat_reply` to signal ready.
|
|
312
|
+
- SSE first: `curl -s -N --max-time 30 http://127.0.0.1:52437/chitchat/<id>/stream`.
|
|
313
|
+
**⛔ curl exit 28 is SUCCESS on an SSE read** — `--max-time` always exits 28 at
|
|
314
|
+
the boundary. If a `data:` event arrived, process it. Only connection-refused
|
|
315
|
+
or a non-200 is a real failure (lesson `2026-06-08-collab-sse-exit-28-is-success`).
|
|
316
|
+
- Poll fallback: `chitchat_poll` at 2s — `{status:"idle"}` keep polling,
|
|
317
|
+
`{status:"ready", message}` consume.
|
|
318
|
+
- `type: stop` ends the session; send a final summary, then `chitchat_stop`.
|
|
319
|
+
- Stream progress mid-work with `chitchat_reply` on long tasks.
|
|
208
320
|
|
|
209
|
-
|
|
210
|
-
```
|
|
211
|
-
chitchat_stop(session_id)
|
|
212
|
-
```
|
|
321
|
+
---
|
|
213
322
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
323
|
+
## Dave interjections
|
|
324
|
+
|
|
325
|
+
Anything Dave types is a high-priority override, in every mode.
|
|
326
|
+
|
|
327
|
+
⛔ **When an interjection appears to CONTRADICT the task premise, restate your
|
|
328
|
+
understanding in ONE sentence and confirm before branching into a wide
|
|
329
|
+
`AskUserQuestion` menu.** A tight "I read this as X — correct?" reconciles faster
|
|
330
|
+
and avoids acting on a misread premise (lesson
|
|
331
|
+
`2026-06-08-collab-premise-contradicting-interjection`).
|
|
218
332
|
|
|
219
333
|
---
|
|
220
334
|
|
|
221
|
-
##
|
|
335
|
+
## Anti-patterns
|
|
336
|
+
|
|
337
|
+
| Anti-pattern | Why it costs a round |
|
|
338
|
+
|---|---|
|
|
339
|
+
| Dispatching prose with no response contract | The peer answers in its habitual shape; you parse or discard it |
|
|
340
|
+
| Filing a settled agreement as a lesson | Buries a queryable Decision in an append-only pile |
|
|
341
|
+
| Driving a negotiation with `/loop` | The clock has no relationship to the reply |
|
|
342
|
+
| Dispatching with no watchdog armed | A dead peer is indistinguishable from a slow one; you wait forever |
|
|
343
|
+
| Watchdog re-dispatches instead of diagnosing | Doubles load on a failing peer and destroys the evidence of why |
|
|
344
|
+
| `codex exec` without `-C <its-lane>` | Codex inherits your lane; every write is guard-blocked |
|
|
345
|
+
| Re-sending settled points each round | The negotiation cannot terminate |
|
|
346
|
+
| Wrapping dispatch in a `timeout` guess | A still-running call reads as a failure |
|
|
347
|
+
| Escalating a transcript | The human has to find the question themselves |
|
|
348
|
+
| Two agents editing one document | Lost work, no error |
|
|
349
|
+
| Writing to the repo during a collab | Your answer may be guard-blocked and stranded; the reply is always deliverable, a write may not be |
|
|
350
|
+
| Using collab to hand off WORK | Wrong skill. Create a work item and use rdc:build or an isolated-worktree agent |
|
|
222
351
|
|
|
223
|
-
|
|
224
|
-
- Treat it as an override injected into the current task
|
|
225
|
-
- Acknowledge it in your `chitchat_reply` response
|
|
226
|
-
- If it changes direction mid-task, note what you stopped and why
|
|
227
|
-
- ⛔ **When an interjection appears to CONTRADICT the task premise, restate your
|
|
228
|
-
understanding in ONE sentence and confirm before branching into a wide
|
|
229
|
-
`AskUserQuestion` menu.** A tight "I read this as X — correct?" reconciles faster
|
|
230
|
-
than a multiple-choice and avoids acting on a misread premise (lesson
|
|
231
|
-
2026-06-08-collab-premise-contradicting-interjection: "there is no pm2 this
|
|
232
|
-
replaces it" was read as "PM2 is abolished as the transport" and triggered a
|
|
233
|
-
3-option transport menu, when it meant "there was no dev *site* yet — push to
|
|
234
|
-
the unchanged PM2 path"; the wide menu over-committed to one interpretation and
|
|
235
|
-
cost a round).
|
|
352
|
+
---
|
|
236
353
|
|
|
237
354
|
## Capture lessons (exit step)
|
|
238
355
|
|
|
239
|
-
Before the final verdict line, follow
|
|
356
|
+
Before the final verdict line, follow `guides/lessons-learned-spec.md` § Capture
|
|
357
|
+
procedure. Write a lesson only for a genuine **episode** — a first root-cause
|
|
358
|
+
theory that proved wrong, a documented path that did not work, a surprising
|
|
359
|
+
tool/infra behaviour. **A settled agreement is not a lesson** (see Step 5). Set
|
|
360
|
+
`scope` and `status`; commit alongside the run's other commits; note "N lessons
|
|
361
|
+
captured" in the verdict. A run that taught nothing writes nothing.
|