cyberfleet 0.2.0 → 0.3.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 +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/agents/headless-operator.md +1 -0
- package/package.json +2 -2
- package/plugin.json +1 -1
- package/skills/authority-governance/README.md +3 -0
- package/skills/authority-governance/SKILL.md +35 -6
- package/skills/merge-backstop-governance/SKILL.md +18 -0
- package/skills/operator/README.md +13 -4
- package/skills/operator/SKILL.md +32 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cyberfleet",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Fleet & crew personas over cyberlegion — Pod (ship's bridge), Operator (command center), Crimp (crew recruitment), and Mechanic (automaton building).",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "unional"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cyberfleet",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Fleet & crew personas over cyberlegion — Pod (ship's bridge), Operator (command center), Crimp (crew recruitment), and Mechanic (automaton building).",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "unional"
|
|
@@ -34,6 +34,7 @@ while capacity K and ready:
|
|
|
34
34
|
on mission-done(m): # m reports through its existing HANDOFF relay
|
|
35
35
|
merge per merge-backstop-governance # Operation order + speculative-CI gate + bisect-on-red
|
|
36
36
|
cyberlegion unit close <id> # tear down the pod that ran it (spawn's inverse)
|
|
37
|
+
mail every other open pod: trunk moved # rebase, adapt, re-verify, report (merge-backstop §5)
|
|
37
38
|
mission-graph append (retire + discovered edges/nodes) # SINGLE WRITER
|
|
38
39
|
# next `ready` reflects it -> re-derive on the next tick
|
|
39
40
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cyberfleet",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Harness-agnostic, MCP-free inter-agent sessions and messaging over the filesystem",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/node": "^24.10.1",
|
|
43
|
-
"tsdown": "^0.
|
|
43
|
+
"tsdown": "^0.23.0",
|
|
44
44
|
"tsx": "^4.22.3",
|
|
45
45
|
"typescript": "^6.0.0",
|
|
46
46
|
"vitest": "^4.1.7"
|
package/plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
|
|
3
3
|
"name": "cyberfleet",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"description": "Fleet & crew personas over cyberlegion — Pod (ship's bridge), Operator (command center), Crimp (crew recruitment), and Mechanic (automaton building).",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "unional"
|
|
@@ -23,6 +23,9 @@ project Captains when they land.
|
|
|
23
23
|
inference from engagement or from work looking finished, no self-grant.
|
|
24
24
|
- **Form and scope** — a relayed Council decision carries the verbatim words, where they were said, the
|
|
25
25
|
relaying unit, and the action and target it covers; it is valid for nothing else.
|
|
26
|
+
- **Standing merge delegations** — summoning the headless loop for a tick, or ordering an in-session
|
|
27
|
+
Operator to dispatch pods, delegates merging exactly that work: clean pull requests only, merged by
|
|
28
|
+
the Operator itself, never passed to a pod, and never any other ratification-class action.
|
|
26
29
|
- **No stall** — a missing decision means: do the rest, raise a decision-request, report both.
|
|
27
30
|
- **Thread** — one thread per work item carries the brief, the reports, and the decisions with their
|
|
28
31
|
relayer named.
|
|
@@ -116,15 +116,44 @@ The positive set. An Operator, a Captain, or a parent agent may command:
|
|
|
116
116
|
- tear down a unit it dispatched, and sweep exited units — in both cases only where no unmerged work is
|
|
117
117
|
being discarded (that is ratification-class, above);
|
|
118
118
|
- and for the headless lifecycle loop, claim and retire on the mission graph as the single writer.
|
|
119
|
+
- and for an Operator the Council ordered in-session to dispatch pods, merge those pods' clean pull
|
|
120
|
+
requests under §7 — the Operator itself, never by commanding a pod to merge.
|
|
119
121
|
|
|
120
122
|
Anything outside the set is declined and raised as a decision-request, not commanded.
|
|
121
123
|
|
|
122
|
-
## 7.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
## 7. Standing merge delegations — the loop's tick, and the Operator's dispatch order
|
|
125
|
+
|
|
126
|
+
Two acts of the Council delegate merges without a decision per merge. Each covers **merging the work
|
|
127
|
+
it dispatched, and nothing else**.
|
|
128
|
+
|
|
129
|
+
**The headless lifecycle loop.** The Council **summoning the loop for a tick** is what permits the loop
|
|
130
|
+
to retire that tick's missions. The merge still lands only on green speculative CI on the merged
|
|
131
|
+
result — `merge-backstop-governance` owns that order and land-or-hold discipline, and this governance
|
|
132
|
+
does not touch it. The delegation covers the tick's missions and no other class of action: a release
|
|
133
|
+
still needs its own decision.
|
|
134
|
+
|
|
135
|
+
**The in-session Operator.** The Council ordering an Operator, **on a turn in the Operator's own
|
|
136
|
+
session**, to dispatch pods is what permits that Operator to merge **the pull requests of the pods it
|
|
137
|
+
spawned for that order**. It merges one only when it is **clean** — all four hold:
|
|
138
|
+
|
|
139
|
+
1. the pod reported the work done on its thread;
|
|
140
|
+
2. the pull request has no merge conflict;
|
|
141
|
+
3. no review requests changes, and no review thread is unresolved;
|
|
142
|
+
4. CI is green on the merged result (`merge-backstop-governance`).
|
|
143
|
+
|
|
144
|
+
Short of clean, hold it and raise a decision-request naming the pull request and what holds it. The
|
|
145
|
+
delegation is bounded the same way as the loop's:
|
|
146
|
+
|
|
147
|
+
- **Only that order's pull requests.** A pull request from a pod dispatched under an earlier order, or
|
|
148
|
+
by anyone else, is not covered — raise a decision-request for it.
|
|
149
|
+
- **Only merging.** Publishing, releasing, settings, history rewrites and the rest of §5 still need
|
|
150
|
+
their own decision.
|
|
151
|
+
- **Never transferable.** The Operator alone merges. A pod asking to merge its own pull request gets no
|
|
152
|
+
approval — §2 holds, and the brief already told it never to merge.
|
|
153
|
+
- **It follows the pull request, not a revision.** A relayed decision naming a revision dies when the
|
|
154
|
+
target moves (§3). The dispatch order names the work, not a revision, so a pull request rebased after
|
|
155
|
+
a sibling merged is still covered — and is gated again from scratch before it merges. It is spent
|
|
156
|
+
when that pull request merges.
|
|
128
157
|
|
|
129
158
|
The SDD **leash** is not this delegation. It is per-CR and governs which SDD **gate** an agent may
|
|
130
159
|
self-assert (`auto-none | auto-spec | auto-all`). A change request recording `auto-all` carries no merge
|
|
@@ -70,6 +70,24 @@ Speculation is an optimization over serial CI-gated merges; it never weakens the
|
|
|
70
70
|
— every mission's merge is still proven green (in isolation, after a bisect) before it counts as
|
|
71
71
|
retired.
|
|
72
72
|
|
|
73
|
+
## 5. After a merge — the open pods rebase, and are gated again
|
|
74
|
+
|
|
75
|
+
A landed merge moves trunk under every mission still open. After each merge, mail every other
|
|
76
|
+
still-open pod of the same dispatch, on its own brief's thread, that trunk moved and it must:
|
|
77
|
+
|
|
78
|
+
- rebase onto the new trunk;
|
|
79
|
+
- adapt its work to what just landed, not only resolve textual conflicts;
|
|
80
|
+
- re-run its verification, push, and report again on the thread.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
cyberlegion mail send --to <pod-handle> --thread <brief-thread> --body "trunk moved: <pr> merged. Rebase, adapt, re-verify, push, report again."
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Send nothing to the pod whose work just merged — tear it down instead (`cyberlegion unit close`). A
|
|
87
|
+
rebased pull request is **a new candidate**: gate it from scratch on its new report (§2, and the
|
|
88
|
+
clean bar the dispatcher's authority rule sets). A green result from before the rebase never carries
|
|
89
|
+
over.
|
|
90
|
+
|
|
73
91
|
## The invariant
|
|
74
92
|
|
|
75
93
|
Trunk is **always-green**: no merge lands on trunk with red CI on its merged result, under any
|
|
@@ -27,12 +27,21 @@ topic, never by a probed location.
|
|
|
27
27
|
all** — report it and route the Council to `init-cyberlegion`, which owns minting a durable owner
|
|
28
28
|
on a human yes, never minted here (fail-loud).
|
|
29
29
|
- `cyberlegion mail inbox --owner operator` — reads what the command center took while nobody was
|
|
30
|
-
connected, and leads with it
|
|
31
|
-
is Operator's to drain: ack a report once acted on, leave an
|
|
30
|
+
connected, and leads with it: reports from pods whose spawning session is gone, and frameless
|
|
31
|
+
headless reports. That mailbox is Operator's to drain: ack a report once acted on, leave an
|
|
32
|
+
unacted one unread.
|
|
32
33
|
- `cyberlegion unit spawn` — spawns every ship: the fleet's first, a new peer session, or a
|
|
33
34
|
parallel worktree-ship on a project that is already a ship, with a self-contained brief the new
|
|
34
|
-
Pod reads cold, whose return address is
|
|
35
|
-
|
|
35
|
+
Pod reads cold, whose return address is this session's own handle — the session that spawned the
|
|
36
|
+
pod and watches it, not whichever session last claimed `operator`. The brief names `operator` only
|
|
37
|
+
as the fallback when that handle resolves to no live unit. All spawning is Operator's; Pod never
|
|
38
|
+
spawns.
|
|
39
|
+
- Watches the pods it spawns: every brief tells the pod to open a pull request, report on its thread,
|
|
40
|
+
never merge, and rebase when told trunk moved. Operator gates each report against the clean bar in
|
|
41
|
+
`authority-governance` §7, merges a clean pull request with no further Council turn (the dispatch
|
|
42
|
+
order is the delegation) and closes its pod, or holds an unclean one and raises a decision-request.
|
|
43
|
+
With several pods on one order it merges in dependency order and, after each merge, tells every other
|
|
44
|
+
open pod to rebase, adapt, re-verify and report again.
|
|
36
45
|
- `cyberlegion unit who` / `mail send` / `mail inbox` / `mail read` / `unit close` / `unit prune` —
|
|
37
46
|
lists, messages, tears down one finished pod, and sweeps the fleet.
|
|
38
47
|
- Routes in-ship mission and crew work to `pod`, by topic — never by probing this working
|
package/skills/operator/SKILL.md
CHANGED
|
@@ -26,9 +26,10 @@ connected wherever the Council invokes it, including inside a project an agent i
|
|
|
26
26
|
last died there and mints a new holder of the handle in every new pane), then `cyberlegion unit
|
|
27
27
|
claim operator` to take the claim on the standing `operator` owner, always — even when another
|
|
28
28
|
session already holds it, since last claim wins and the doorbell rings whoever holds it. Register
|
|
29
|
-
before claiming; the claim needs an identity in this session. Then read the mailbox
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
before claiming; the claim needs an identity in this session. Then read the standing mailbox, which
|
|
30
|
+
holds what had no live session to go to (a pod whose spawner is gone, a frameless headless report):
|
|
31
|
+
`cyberlegion mail inbox --owner operator --unread`, and lead with what the command center took while
|
|
32
|
+
nobody was connected. `cyberlegion mail read <msg-id> --owner
|
|
32
33
|
operator --ack` a report once acted on — never sweep the unread set to tidy the board.
|
|
33
34
|
- **No multiplexer, so no presence can be bound and the claim cannot be taken:** report the standing
|
|
34
35
|
`operator` owner unclaimed and carry on dispatching. This is fail-soft — an unclaimed owner costs
|
|
@@ -42,9 +43,33 @@ connected wherever the Council invokes it, including inside a project an agent i
|
|
|
42
43
|
<claude|cursor|codex> --handle <name> --task "<self-contained brief>" --at workspace` — the brief
|
|
43
44
|
must stand on its own since the new Pod starts cold and reads it through its own SessionStart
|
|
44
45
|
hook, and `--at workspace` opens the ship in its own herdr workspace rather than a pane crowding a
|
|
45
|
-
neighbor's. The brief's return address is
|
|
46
|
-
|
|
46
|
+
neighbor's. The brief's return address is **this session's own registered handle** — the session
|
|
47
|
+
that holds the order and watches the pod — never its id and never `operator`: the claim on
|
|
48
|
+
`operator` moves to whichever session connected last, which never saw this brief. The brief also
|
|
49
|
+
names the fallback: if that handle resolves to no live unit, report to `operator` instead. Every
|
|
50
|
+
spawn is Operator's, including
|
|
47
51
|
parallel work on a project that is already a ship — Pod never spawns.
|
|
52
|
+
- Every brief sets the pod's side of the watch, in the brief itself: open a pull request; report on
|
|
53
|
+
this brief's thread to the return address when the work is done or blocked; **never merge** the pull request;
|
|
54
|
+
and when told trunk moved, rebase onto it, adapt the work to what landed, re-verify, push, and report
|
|
55
|
+
again.
|
|
56
|
+
- Once a pod is out, **watch it — do not wait to be asked**. Act on each report as it arrives (the
|
|
57
|
+
doorbell on this session's own handle): gate its pull request against the four-part **clean** bar in
|
|
58
|
+
`authority-governance` §7 — reported done, no merge conflict (`gh pr view <pr> --json mergeable`), no
|
|
59
|
+
review requesting changes or left unresolved, CI green on the merged result (`gh pr checks <pr>
|
|
60
|
+
--watch`). Load **`merge-backstop-governance`** for the merge step.
|
|
61
|
+
- **Clean → merge it** (`gh pr merge`) with no further turn from the Council — the Council's dispatch
|
|
62
|
+
order is the delegation (`authority-governance` §7) — then `cyberlegion unit close <id>` the pod
|
|
63
|
+
that ran it.
|
|
64
|
+
- **Not clean → hold it.** Do not merge, leave its pod running, and raise a decision-request naming
|
|
65
|
+
the pull request and what holds it.
|
|
66
|
+
- Keep watching until every pod of the order is merged or held, and say which is which.
|
|
67
|
+
- When one order dispatches several pods, orchestrate them: merge in dependency order — a consumer
|
|
68
|
+
never before its producer, whatever order they finished. After each merge, mail every other
|
|
69
|
+
still-open pod of the order on its own thread (`cyberlegion mail send --to <handle> --thread <id>`)
|
|
70
|
+
that trunk moved — rebase, adapt, re-verify, report again — and send nothing to the pod whose work
|
|
71
|
+
merged. A rebased pull request is gated again from scratch; never merge it on the green it had
|
|
72
|
+
before the rebase.
|
|
48
73
|
- When the Council asks what's out there: `cyberlegion unit who` to list the fleet; add `--all`
|
|
49
74
|
to include exited ships.
|
|
50
75
|
- When a message needs to cross ships: `cyberlegion mail send --to <handle>`, `cyberlegion mail
|
|
@@ -68,7 +93,8 @@ connected wherever the Council invokes it, including inside a project an agent i
|
|
|
68
93
|
|
|
69
94
|
Every mechanic is a `cyberlegion` CLI call — unit spawn, unit who, mail send, mail inbox,
|
|
70
95
|
mail read, unit close, unit prune. Cyberlegion owns the mechanism; Operator is the fleet-layer voice on top
|
|
71
|
-
of it.
|
|
96
|
+
of it. Pull-request and CI mechanics — mergeability, reviews, checks, the merge itself — are `gh` and
|
|
97
|
+
git, invoked, never re-implemented. Operator never re-implements the file store, never types into a ship's pane, never reaches
|
|
72
98
|
for an MCP messaging server, and never assumes every ship runs the same harness.
|
|
73
99
|
|
|
74
100
|
## Headless — the lifecycle loop
|