past, present, future system architecture
Netsky has an honest architectural arc. The early system leaned on the surfaces one harness made easy. The current system keeps authority in repo code. The future keeps the same shape and stretches it across machines instead of replacing it with a cloud control plane (rearch.md:13-31, src/crates/netsky-prompts/prompts/base.md:20-49).
flowchart LR
P[past<br>harness-centric] --> N[present<br>CLI-owned control plane]
N --> F[future<br>netsky0 across constellations]
This post is a retrospective, so the past matters. It still does not need an apology tour. The point of the past section is to explain which boundaries failed and why the present system looks the way it does.
past #
The early rule was simple. Use whatever Claude Code exposed well. That bought speed. It also fused too much authority into one runtime.
The rearchitecture note captures the correction in one line: “CLI preferred, MCP when needed” (rearch.md:13-14). That line only exists because the previous shape was the inverse. Useful mutations lived behind MCP tools. Scheduling lived in session memory. Clone orchestration depended too much on prompt custom and not enough on program state (rearch.md:13-31).
Three problems fell out of that shape.
The first problem was mutation portability. If a side effect only existed as an MCP tool, the system inherited the quirks of the harness that happened to expose it. Runtime parity became a translation project instead of a design property. The fix landed in code, not prose. Clone surfaces now route channel work through the CLI and no longer need MCP mutation tools (src/crates/netsky-core/src/consts.rs:134-145). The current .mcp.json keeps only four inbound sources: agent, imessage, email, and iroh (.mcp.json:1-20).
The second problem was soft scheduling. The current deny list explains the failure in its comment. Claude-side self-scheduling leaks across sessions and does not deduplicate correctly. Netsky moved one-shot delays and dynamic loops into netsky loop, recurring prompts into netsky cron, and delivery into the ticker writing envelopes into agent inboxes (src/crates/netsky-core/src/consts.rs:153-167). Durable paths back that up. Cron entries live in ~/.netsky/cron.toml (src/crates/netsky-core/src/paths.rs:117-119, docs/cron.md:1-11). Loop ticks write envelopes from agentloop and persist their next fire time after dispatch (src/crates/netsky-cli/src/cmd/loop_cmd.rs:140-185).
The third problem was that the bus and supervision layers were easier to starve than they looked. The current channel surface comments are explicit about the fixes: drain is claim then archive, hostile input is quarantined instead of poisoning the whole inbox, and shell sends use one canonical envelope writer (src/crates/netsky-cli/src/cmd/channel.rs:7-33, src/crates/netsky-cli/src/cmd/channel.rs:35-58). That is the mature form of a lesson the early system learned the hard way. Shared panes and ad hoc wakeups are fast. They are weak protocol surfaces.
The old system was still viable. It ran. It made progress. It also kept too much of its control plane inside one conversation and one harness. That is why the past matters. Netsky did not change because a cleaner diagram was available. It changed because the wrong layers owned the wrong verbs.
| era | authority | mutation path | scheduling | replay |
|---|---|---|---|---|
| past | harness-centric | MCP-heavy | session memory | weak |
| present | netsky-owned | CLI-first | durable loop and cron | envelopes plus meta.db |
| future | netsky0 across constellations | same CLI-first shape | same durable surfaces | cross-machine over iroh |
present #
The present architecture is narrow on purpose.
The prompt stack names the control split directly: S5 policy in prompts, S4 intelligence in notes, S3 control in agent0, S3* audit in spot checks, S2 coordination in workspaces, and S1 operations in clones (src/crates/netsky-prompts/prompts/base.md:20-28). The topology block is equally blunt. One machine runs one constellation. agent0 is the root. agentinfinity is the watchdog. agent1..N are clones. Work lands in fresh repo clones under workspaces/<task>/ (src/crates/netsky-prompts/prompts/base.md:30-40).
That topology only works because the CLI owns the verbs. The command tree exposes up, down, restart, agent, ai, channel, cron, loop, imessage, email, task, sync, and clone at the top level. Clone lifecycle is a real subcommand family. netsky clone brief|status|wait|kill|ls exists because orchestration is not prompt theater.
The manager and worker split is now codified at both ends. Clones get a small tool floor. Agent0 and agentinfinity get broader harness access, but the repo still denies sub-clone recursion and harness-local scheduling (src/crates/netsky-core/src/consts.rs:134-169). Mutation surfaces moved into repo-owned commands. netsky imessage send and netsky email send are ordinary CLI verbs (src/crates/netsky-cli/src/cmd/imessage.rs:4-47, src/crates/netsky-cli/src/cmd/email.rs:4-123). netsky cron add persists a durable entry and netsky cron tick dispatches due prompts with from=agentcron and kind=cron (src/crates/netsky-cli/src/cmd/cron.rs:46-96, src/crates/netsky-cli/src/cmd/cron.rs:183-208). netsky loop tick does the same for self-paced work with from=agentloop (src/crates/netsky-cli/src/cmd/loop_cmd.rs:156-170).
netsky clone brief briefs/fix-transport.md --type codex --workspace transport-fix --agent 4 netsky channel send agent4 "focus on replay and backpressure" --from agent0 netsky loop create 10m "check the clone result and harvest if green" netsky cron add morning-brief "0 11 * * *" agent0 /morning-brief netsky ai run --model codex-gpt-5.4 --detach "summarize today's crash markers"
Those verbs also explain the current runtime posture. Claude and Codex are both first-class operator surfaces. netsky up and netsky agent accept --type, and netsky ai run handles bounded worker calls. The repo does not pretend the runtimes are identical. It makes the bus identical instead.
Codex support is where the present architecture becomes clearer than any manifesto. Spawn creates inbox, outbox, and processed directories for Codex-backed agents (src/crates/netsky-core/src/spawn.rs:144-152). netsky channel forward-outbox then rewrites Codex replies to the owning agent id and forwards them into agent0’s inbox (src/crates/netsky-cli/src/cmd/channel.rs:142-257, src/crates/netsky-cli/src/cmd/channel.rs:1142-1168). That is a good architectural sentence. Different runtime on one side. Same envelope protocol on the other.
flowchart TD
owner --> agent0
agent0 -->|netsky clone brief| clone
clone -->|MCP inbound| inbox
clone -->|netsky CLI mutation| state
codex -->|outbox| forwarder
forwarder -->|normalized envelope| agent0
Scheduling is also fully present-tense now. The base prompt calls netsky-ticker the 60 second heartbeat and launchd at 120 seconds the failsafe (src/crates/netsky-prompts/prompts/base.md:83-88). The ticker loop literally runs netsky watchdog tick, netsky cron tick, and netsky loop tick every interval, then records one observability tick (src/crates/netsky-cli/src/cmd/tick.rs:133-163). That means a schedule is no longer an intention stuck inside a session. It is durable state plus a driver.
Observability completes the current shape. ~/.netsky/meta.db is the durable observability store (src/crates/netsky-prompts/prompts/base.md:17-18, src/crates/netsky-db/README.md:7-10). The schema records messages, CLI invocations, crashes, ticks, workspaces, sessions, clone dispatches, token usage, watchdog events, and iroh events (src/crates/netsky-db/README.md:27-47). The present system is not just a cluster of live panes. It is a cluster with replay.
That replay surface changes the architectural meaning of failure. A dead pane is no longer the end of the evidence. A bad restart can be read back through restart-status, watchdog events, and handoff archives. A noisy day can be queried through netsky query. The present system is easier to repair because it is easier to inspect (src/crates/netsky-core/src/consts.rs:307-315, src/crates/netsky-db/README.md:23-25, src/crates/netsky-cli/src/cmd/watchdog.rs:478-517).
future #
The future is less dramatic than most agent diagrams. Netsky is not pointed at a central SaaS brain. It is pointed at the same local system shape, spread across more than one machine.
The topology block in the base prompt already says it. netsky0 is the root constellation. Other machines become netsky1..netskyN. Owner communication goes to netsky0 only. Sibling constellations relay through it over iroh (src/crates/netsky-prompts/prompts/base.md:40-49). That is a concrete authority model, not a vague aspiration.
The transport side is already grounded. The inter-agent communication section defines iroh as an extension of the same envelope shape used locally, with the same untrusted-data posture (src/crates/netsky-prompts/prompts/base.md:42-49). Observability already has an iroh_events table because the repo expects that traffic to be operationally real (src/crates/netsky-db/README.md:42-45).
What is not finished is everything above transport.
Cross-machine routing is described. Large-network backpressure is not. Authority is clear. Replay under broader failure domains is not fully proven. The channel code already admits that ordering across producers is best-effort because filenames sort by wall-clock nanoseconds (src/crates/netsky-cli/src/cmd/channel.rs:26-33). That is a good local trade. It is not the final answer for a busy multi-constellation network.
The future therefore looks like a continuation, not a reset:
- keep one root for owner communication
- keep one CLI-owned mutation surface
- keep envelopes as the universal bus format
- strengthen backpressure and replay as agent counts and machine counts rise
The important restraint is what does not change. Future netsky still wants text edges, small files, and operator-readable state. That is why the current bus is files, why scheduling is TOML plus inbox delivery, and why restart state lives in named markers instead of hidden daemon memory (src/crates/netsky-cli/src/cmd/channel.rs:7-18, docs/cron.md:3-24, src/crates/netsky-core/src/consts.rs:283-338). A multi-machine netsky that abandoned those constraints would not be an extension of the present architecture. It would be a different system.
what’s next #
The honest next step is not “more agents”. It is tighter protocol where the current protocol is still cheap. Netsky already proved that moving authority out of a harness and into repo code pays off. The next proof is that the same rule survives a network boundary.