Conversation
…`moshcode fleet` reads it (PRD 0016) Implements the moshcode side of the OpenFleet 0.1 spec (logicsrc.com/docs/openfleet). src/openfleet.mjs: the vendored IO over $OPENFLEET_HOME, read on every call like herdDir(): records (written once at 0600, never overwritten), the append-only per-fleet ledger with per-host merge by `at`, claim detection, the end line that counts, the ceiling merge and every narrower case, checkCeiling refusals, context() (own record, else OPENFLEET_FLEET, else current, else the implicit fleet), the <slug>-<HHMM> swarm id, and fold() plus renderTree() for the tree. src/swarm.mjs: the swarm id is minted before the plan; the planner, the skeptic and the synthesis run with OPENFLEET_SWARM omitted; the planner's `files` becomes piece.owns; the effective ceiling (parent's chain, narrowed by --agents and --timeout) is checked before anything is written, a refusal appends ceiling.refuse and starts nothing; swarm.spawn precedes the first start; one unclaimed record per member, panes named after member ids, the four OPENFLEET_* variables plus the home in the pane env; member.start on submit for a pane that has none; member.end lines, then one swarm.end (synthesis as summary, --verify as verdict), then the kills in a finally; --keep writes no end lines and names the swarm. --json carries swarm and fleet. src/herd.mjs, src/herd-cli.mjs: startSession extraEnv on both substrates, kept through the strip; `herd start --env KEY=VALUE`; carriesBypass() so the manifest, the JSON and the warning tell the truth about a pane started with the engine's bypass flags; roster rows carry fleet, swarm, member and approvals; `herd ps` groups by fleet then swarm and marks bypass; restore hands the env back. src/fleet-cli.mjs: `moshcode fleet open|cap|tree|stop|log`, every verb --json. open and cap refuse with exit 4 when OPENFLEET_MEMBER is set; stop refuses outside what that member spawned, ends nested swarms first, members through their engines (herd kill, `claude stop`, a pid), then one swarm.end; tree joins the herd roster, draws recordless sessions as implicit-fleet roots and writes member.end lost for a claimed pane the roster dropped; cap stops members above the new ceiling. Wiring: bin dispatch, pit /fleet, schema entry + FLEET_VERBS + pit entry, moshscript fleet(), README table regenerated plus a fleet section, PRD 0016, PRD 0015 R3/R6 naming, version 0.99.0. Tests: test/openfleet.test.mjs, test/fleet-cli.test.mjs, and the swarm, herd and herd-cli suites extended; every fleet test runs under a mkdtemp OPENFLEET_HOME. Suite: 3035 tests, 0 fail (was 2980). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RZV4zJ2pDZLNN3kE5jFCmV
…rule 6 in tree, honest swarm.end The review of the two OpenFleet implementations found the two sysop tools disagreeing on the same ledger. This is moshcode's half of the fix round, under the shared rulings R-A to R-J. The ceiling (R4, R5, R7, R11, R18, R1, R16, R-A, R-B, R-C): - A fleet.cap never opens a fleet; `opened` is true only for fleet.open. A cap on the implicit fleet that names no approvals leaves each root's own in place, so `moshcode fleet cap anthony@dev --depth 2` no longer stops every bypass root. - effectiveCeiling is base (latest fleet-target cap, else fleet.open, else implicit), then every swarm.spawn on the path, then the latest cap on any swarm on the path, applied last. The record's copy is a snapshot and never an input, so a later widening fleet cap takes effect. mergeCeiling never widens and carries unknown keys through. - rootOf walks records, then member.start lines, and a broken chain reads native. A parentless record supplies its own approvals. - `moshcode swarm` writes the member's own approvals into ceiling.approvals for a swarm the sysop runs by hand, so logicsrc's hook no longer refuses the pane's first prompt; each prompt's wait is clamped to an inherited until. The ledger (R28, R-G): member.start, member.end and swarm.end take a once-marker under fleets/<fleet>/marks/<event>.<id> (0600, dir 0700) before appending; EEXIST writes nothing and reports already. lost takes member.end.<id>.lost so a real end still supersedes it. Same paths as logicsrc. The verbs (R2, R8, R12, R13, R19, R20, R26, R37, R-D, R-E, R-F, R-H): - stop writes swarm.end only when every started member and every nested swarm has an end line; a member its engine would not end gets no end line, the verb exits 3 and says the swarm is left open. A never-started member writes nothing. - A claude-code member is stopped by its job id: the 8-hex member id, else the first eight of a session UUID; an interactive session has none and the tool says so. - lost is written only for a member the herd roster can hold (moshcode/*, tmux, on this host) when the manifest is readable; never for claude-code. - tree enforces rule 6: a working member past its effective until is stopped with member.end timeout, members under a swarm or fleet whose summed spend in the budget's unit has reached the budget with member.end budget, then swarm.end once the swarm is complete. - The implicit fleet is injectable, so the stop --fleet test holds on CI. Also: tree prints `working`, keeps the herd's state out of the state column (a [gone] mark instead), quotes and clips a task the way logicsrc does, and pads columns per fleet (R24); a blocked pane is not `done` (R38); herd restore hands a fresh session only OPENFLEET_HOME and OPENFLEET_FLEET (R39); the serve flag text says swarm members are withheld too (R29); no em dashes in swarm.mjs (R30, R40). PRD 0016 documents the lost rule, the markers and enforcement. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RZV4zJ2pDZLNN3kE5jFCmV
# Conflicts: # package.json
| ], | ||
| seeAlso: ["swarm", "herd", "ps"], | ||
| note: "the records and the ledger live under $OPENFLEET_HOME (default ~/.openfleet), the same files `logicsrc fleet` and claude code read. " | ||
| + "open and cap are the sysop's alone and refuse when OPENFLEET_MEMBER is set, because a process carrying it is an agent; " |
| ], | ||
| note: "on a fleet the keys given are the whole new ceiling; on a swarm they must narrow what it has. members already above the new " | ||
| + "ceiling, a bypass member under a now-native ceiling or one on a now-forbidden host, are stopped with member.end stopped. " | ||
| + "refuses with exit 4 when OPENFLEET_MEMBER is set." }, |
| flags: [["--fleet <id>", "stop every swarm and root member of this fleet", ""], ["--json", "machine-readable", ""]], | ||
| note: "each member ends through its own engine: a moshcode pane through the herd, a claude code job through `claude stop <job id>` " | ||
| + "(the 8-hex id; an interactive claude session has none and is reported), a `claude -p` through its pid; one it cannot reach is " | ||
| + "reported, never faked, and its swarm stays open until it has an end line. an agent (OPENFLEET_MEMBER set) may stop only a swarm " |
ThreatCrush Security Scan7 finding(s) in the 19 file(s) this pull request changes. MEDIUM: 7
90 pre-existing finding(s) elsewhere in the repository — **HIGH/CRITICAL**: 8 | **MEDIUM**: 71 | **LOW**: 11Not introduced by this pull request. The full set is in the Security tab.
…and 70 more. Full results in the Security tab. Snippets are redacted; ThreatCrush never prints matched credential material. |
…is machine's The harness passes implicit: anthony@dev; comparing against the real user@host only passed on the dev box and failed on CI as runner@<vm>. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RZV4zJ2pDZLNN3kE5jFCmV
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
OpenFleet: a swarm leaves a record behind (PRD 0016)
Implements the moshcode side of the OpenFleet specification (https://logicsrc.com/openfleet), written this morning after a
moshcode swarmrun whose workers could not name their parent.moshcode swarmmints the swarm id before the plan call, runs the planner withoutOPENFLEET_SWARM, asks the planner for the files each piece may write and stores them aspiece.owns, writesswarm.spawnbefore the first pane starts, writes one unclaimed record per pane (member id<swarm>-<n>, also the pane name,sessionthe pane), passes the fiveOPENFLEET_*variables into the pane environment beside the herd variables and keeps them through the credential strip, writesmember.starton the pane's behalf when a prompt goes in and nothing has claimed the record, and at the endmember.endfor every pane, oneswarm.endwith the synthesis and--verifyverdicts, then the kills in a finally.--keepwrites no end lines and no kills. A swarm that would exceed the inherited ceiling is refused before anything starts, withceiling.refuse. A parentless swarm carries its own approvals into its members' ceilings.herd:startSessiontakes extra env;herd start --env KEY=VALUE; the manifest records approvals truthfully (a pane started with the engine's bypass flag isagent: true);herd psgroups by fleet and swarm and marks bypass;herd servetherefore withholds swarm panes unless--expose-autonomous.moshcode fleet open|cap|tree|stop|log, the sysop tool over$OPENFLEET_HOME, sharing the file format withlogicsrc fleet.treejoins the herd roster and enforces deadlines and budgets;stopends a swarm as one unit throughherd kill./fleet, command schema, completion, moshscript verb, README table regenerated, PRD 0016, PRD 0015 naming updated. Version 0.98.2 to 0.99.0.Verification.
node --testwhole suite 0 fail (3,035 tests before the fix round),fleet --helpand every verb's help exit 0, README table identical tohelp --markdown, an end-to-end run of the verbs against a temp home, and a cross-tool interop run in which this branch'srunSwarmwrote a two-piece swarm through fake engines and bothmoshcode fleet treeandlogicsrc fleet treerendered the identical tree. Three adversarial review rounds; every blocker and major fixed.🤖 Generated with Claude Code
https://claude.ai/code/session_01RZV4zJ2pDZLNN3kE5jFCmV