mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-10-02 12:54:03 +00:00
OpenFleet reference implementation: @logicsrc/openfleet 0.1.0 and logicsrc fleet
Ship what docs/openfleet.md describes. The new workspace package holds the record (write once, never overwrite, 0600), the ledger (append-only JSON Lines, merged across ledger*.jsonl by at), the ceiling rules (whole fleet ceiling, narrowed swarm keys, a merge that never widens, refusals by key), claiming and deriving exactly as the spec's "Claiming and deriving" and rule 13, and fold(), which turns any $OPENFLEET_HOME plus the engine rosters into the tree the landing page shows. logicsrc fleet open|cap|tree|stop|log are the sysop's verbs, every one with --json. open and cap exit 4 when OPENFLEET_MEMBER is set; stop exits 4 outside the caller's subtree, ends nested swarms first, goes through each member's own engine (claude stop, moshcode herd kill, tmux kill-pane, a signal for claude-p) and writes one swarm.end per swarm. tree reads claude agents --json --all and ~/.moshcode/herd/sessions.json when it can, draws recordless sessions as roster roots of the implicit fleet, and writes member.end lost for a recorded member its engine no longer lists. Claude Code takes part through hooks: logicsrc fleet hooks install merges SessionStart, UserPromptSubmit, PreToolUse, Stop and SessionEnd into ~/.claude/settings.json without clobbering it, and logicsrc fleet hook <Event> runs each one. SessionStart claims, derives or writes a root record and hands the member its variables through CLAUDE_ENV_FILE; UserPromptSubmit checks the ceiling with the permission mode the engine reports and writes member.start, or refuses the first prompt with exit 2 and ceiling.refuse; PreToolUse denies an edit outside piece.owns; Stop and SessionEnd write member.end. A hand-started root takes the engine's reported approvals before member.start, since the command line only guesses them. Hooks never fail the engine: everything is caught and logged to hooks.log. The spec and the landing page now say what ships, keep Status 0.1, and record the two verified Claude Code limits: a background job dispatched from claude agents gets no launcher environment, and OPENFLEET_* exported at SessionStart reach the member's tools but not later hooks, so hooks key on session_id through $OPENFLEET_HOME/sessions/<session_id>.json. PRD 0008 covers the work. CLI 0.2.1 -> 0.3.0; build and build:cli chains build the package before the CLI; README and docs/cli.md list the group. Tests: 95 in the package (record, ledger merge, every narrower case, the worked example's claim and derive, the folded tree, hook install idempotence, each hook handler including the exit-2 refusal and the PreToolUse deny, every verb with fake deps) and 4 in the CLI. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RZV4zJ2pDZLNN3kE5jFCmV
This commit is contained in:
parent
123ba2e39a
commit
4ceaaaaa1f
34 changed files with 5510 additions and 15 deletions
133
prd/0008-openfleet-reference-implementation.md
Normal file
133
prd/0008-openfleet-reference-implementation.md
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
---
|
||||
openprd: "0.3"
|
||||
id: "0008"
|
||||
title: "Ship the OpenFleet reference implementation"
|
||||
status: Draft
|
||||
authors:
|
||||
- anthony@profullstack.com
|
||||
created: 2026-09-13
|
||||
updated: 2026-09-13
|
||||
repo: profullstack/logicsrc
|
||||
discussion:
|
||||
implementation: packages/openfleet
|
||||
tags:
|
||||
- openfleet
|
||||
- agents
|
||||
- fleet
|
||||
- swarm
|
||||
- claude-code
|
||||
- moshcode
|
||||
- cli
|
||||
supersedes:
|
||||
superseded-by:
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
The OpenFleet specification (docs/openfleet.md) was published on 2026-09-13 from
|
||||
one incident: a Claude Code background job asked moshcode to split a task across
|
||||
two agents, and afterwards nobody, human or agent, could say who had started
|
||||
either worker, why, under what ceiling, or with whose approval. The spec names
|
||||
the record, the ledger and five sysop verbs, and named `logicsrc fleet` as the
|
||||
reference sysop tool. It shipped with the line "None of the three ships yet".
|
||||
A standard nothing implements is prose; the incident repeats every morning until
|
||||
the files exist and something writes them.
|
||||
|
||||
## Goals
|
||||
|
||||
- A human can open a fleet, set its ceiling, see every agent session under them
|
||||
as one tree, stop a swarm as one unit, and read afterwards what happened and
|
||||
who did it, from one command: `logicsrc fleet`.
|
||||
- Every Claude Code session on a box with the hooks installed becomes a
|
||||
recorded member: it claims the record its starter wrote, or derives its own,
|
||||
or is a root member of the implicit fleet, and it refuses to run above the
|
||||
ceiling it was started under.
|
||||
- moshcode and Claude Code write the same files the same way, so one tree
|
||||
shows both engines' members without either reading the other's roster.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- No orchestration: splitting a task, choosing an engine, verifying, and
|
||||
synthesising stay in `moshcode swarm` and `@logicsrc/agentswarm`.
|
||||
- No change to Claude Code itself. The engine side ships as hooks over its own
|
||||
settings file; FleetView grouping and `member.spend` at intervals wait on the
|
||||
engine.
|
||||
- No network surface, no signed ledger lines, no freeze, no `adopt`: the 0.2
|
||||
questions stay open.
|
||||
|
||||
## Users
|
||||
|
||||
- The sysop: one developer answerable for every agent session on their box,
|
||||
who wants to see the tree and stop the wrong part of it.
|
||||
- An agent that spawns a swarm and wants its children to know who they are and
|
||||
what they own.
|
||||
- A later session inspecting a member's record to answer the five questions the
|
||||
incident could not.
|
||||
|
||||
## Requirements
|
||||
|
||||
- R1 [P0] `@logicsrc/openfleet` 0.1.0: the record (write once, never
|
||||
overwrite), the ledger (append-only, 0600, merged across `ledger*.jsonl` by
|
||||
`at`), the ceiling rules (whole fleet ceiling, narrowed swarm keys, merge
|
||||
that never widens, refusal by key), claim and derive exactly as the spec's
|
||||
"Claiming and deriving", and `fold` into the tree the landing page shows.
|
||||
- R2 [P0] `logicsrc fleet open|cap|tree|stop|log` with the spec's flags;
|
||||
`open` and `cap` exit 4 when `OPENFLEET_MEMBER` is set; `stop` exits 4
|
||||
outside the caller's subtree; `stop` ends nested swarms first and writes one
|
||||
`swarm.end` per swarm; every verb takes `--json`.
|
||||
- R3 [P0] `stop` goes through the member's own engine: `claude stop` for
|
||||
`claude-code`, `moshcode herd kill` for `moshcode/*`, `tmux kill-pane` for
|
||||
`tmux`, a signal for `claude-p`. Never a shell string.
|
||||
- R4 [P0] Claude Code hooks: `logicsrc fleet hook <Event>` for SessionStart,
|
||||
UserPromptSubmit, PreToolUse, Stop and SessionEnd, and `logicsrc fleet hooks
|
||||
install|remove|status` that merges into `~/.claude/settings.json` and never
|
||||
clobbers it. A hook never fails the engine; a refused start exits 2 before
|
||||
any `member.start`.
|
||||
- R5 [P1] `tree` reads `claude agents --json --all` and
|
||||
`~/.moshcode/herd/sessions.json` when it can, draws recordless sessions as
|
||||
roots of the implicit fleet, and writes `member.end` state `lost` for a
|
||||
recorded member its engine no longer lists.
|
||||
- R6 [P1] The spec and the landing page say what ships, keep `Status: 0.1`,
|
||||
and record the two verified Claude Code limits (no launcher environment
|
||||
reaches a dispatched background job; exported variables reach tools but not
|
||||
later hooks).
|
||||
- R7 [P1] Tests cover record and ledger IO, every narrower case, the worked
|
||||
example's claim and derive, the folded tree, hook install idempotence, and
|
||||
each hook handler, including the exit-2 refusal and the PreToolUse deny.
|
||||
|
||||
## UX Notes
|
||||
|
||||
`logicsrc fleet tree` prints the tree the landing page shows: fleet header,
|
||||
root members, swarms nested under their spawner, members with engine, state,
|
||||
`[bypass]`, `owns`. `log` prints one line per event, oldest first, with who did
|
||||
it. Refusals name the key, what was wanted and what was allowed.
|
||||
|
||||
## Tech Stack
|
||||
|
||||
TypeScript, NodeNext, commander 14, vitest 4. No workspace dependencies beyond
|
||||
the CLI's `file:../openfleet` link. Node 18+ (the installer's floor), so the
|
||||
tree is plain text rather than a TUI.
|
||||
|
||||
## Monetization
|
||||
|
||||
None. It is the reference implementation of an open standard.
|
||||
|
||||
## Success Metrics
|
||||
|
||||
- The worked example's morning can be replayed against a temp home and
|
||||
`logicsrc fleet tree` prints the tree the spec shows.
|
||||
- A Claude Code session started with the hooks installed appears in
|
||||
`logicsrc fleet tree` with the right approvals mark without anyone editing a
|
||||
file by hand.
|
||||
|
||||
## Risks & Open Questions
|
||||
|
||||
- A background job dispatched from `claude agents` gets no launcher
|
||||
environment, so a launcher that wants it in a swarm must write its record and
|
||||
pass the path another way (a `--settings` hook command, or a lookup by the
|
||||
job's cwd and intent). Until then it is a root of the implicit fleet.
|
||||
- User-level hooks fire for every `claude -p` a tool makes, so each becomes a
|
||||
swarm of one and, at depth 1 in the implicit fleet, is refused on depth. The
|
||||
spec lists this as an open question; the hooks enforce the letter of it.
|
||||
- `hasEvent` before a write is a check, not a lock. Two writers racing on one
|
||||
swarm can still produce two `swarm.end` lines.
|
||||
|
|
@ -18,3 +18,4 @@ Status lives in each file's front-matter and is the source of truth:
|
|||
| [0005](./0005-add-logicsrc-openswarm-spec.md) | Add the LogicSRC OpenSwarm specification family | Draft | openswarm, ipfile, ipdb, ipaudio, ipvideo, iplive, bittorrent, x402, c0mpute |
|
||||
| [0006](./0006-add-pay2seed-spec.md) | Add pay2seed, paid2seed, pay2stream and paid2stream to the OpenSwarm family | Draft | openswarm, pay2seed, paid2seed, pay2stream, paid2stream, iplive, hls, ipfile, ippay, ipdb, bittorrent, torlink, bittorrented, c0mpute |
|
||||
| [0007](./0007-add-tech-stack-and-monetization-to-openprd.md) | Add Tech Stack and Monetization sections to OpenPRD | Draft | openprd, standards, monetization |
|
||||
| [0008](./0008-openfleet-reference-implementation.md) | Ship the OpenFleet reference implementation | Draft | openfleet, agents, fleet, swarm, claude-code, moshcode, cli |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue