Every part of a case, and where each one sits.
One map of DFIR Swarm, from the evidence the examiner points it at to the signed case file that leaves the run. Select any part to see what it does, what it holds to and what it leaves on the record, and try it. Or play a case from the kickoff to the hand-over and watch the work move between the parts.
- kelp work in motion
- slate files and the record
- moss sealed, passed, done
- saffron keys, budget, caps
- brick refused at the wall
A dashed line is a read-only view or a check. A solid one carries work.
The platform map
Swipe sideways to see the whole map, or switch to the list.
Every part of the platform in its place. The dots in the middle are the agents. Select a part, or play a case.
The examinerChooses the evidence, the question, the packs and the team, watches the work, and signs what comes out.
- Starts a run from the console or the terminal: evidence, a goal from the investigation library or their own, the packs, a team of models, the caps.
- Watches the case happen, speaks into the board, holds or releases the run, and stops it.
- Reviews the ledger entry by entry and signs it.
- Every command they give a run is a line in a chained operator log, and on a live run a line of its trace.
- The harness assigns no roles and adds no findings of its own: what the agents conclude is theirs, what the examiner accepts is signed.
swarm.sh startswarm.sh stopswarm.sh reviewruns/operator-audit.jsonlThe consoleA live view of the run: the board as a story, every agent, every call, the jobs, the ledger, custody and the report.
- Starts a run through the same script the terminal uses, so the two can never disagree.
- Shows the story of the case, every post, each agent's context and spend, the jobs and what they sealed, the ledger with its hypotheses and limitations, and custody check by check.
- Blurs what an entry marks sensitive until it is clicked.
- Reads are open on the machine; every change goes through the harness's own commands and needs the run's token.
- It writes no protocol file of its own.
swarm.sh uihttp://127.0.0.1:43173KickoffTurns the examiner's choices into a run: hashes the evidence, checks the packs, picks the images, writes the contract and boots the agents.
- Hashes every evidence file (SHA-256, with MD5 and SHA-1 beside it) and writes the manifest and its anchor outside the run.
- Checks every pack against its seal, and picks each pack's job image by profile.
- Renders the contract every agent reads: the goal, the rules, where the programs are listed. It names no forensic program.
- Boots each agent's microVM from the base image and starts the hub, the trace collector and the job service.
- A kickoff that cannot enforce what it promised stops and says why.
- Acquisition hashes from the imager, when given, are compared file by file before the first agent starts.
inputs.json<run>.custody-anchor.jsonSWARM.md--inputs-hashesThe evidenceDisk images, memory, phones, logs and captures, shared read-only into every VM from where they lie.
- Is shared into each agent's VM and each worker at the same path, read-only on the host's side.
- Is hashed before the first agent starts and re-hashed on the host at the end.
- Is catalogued by the packs' recipes as the run begins.
- Root inside a VM can flip its own mount flags; the host still refuses every write to the evidence.
- An earlier run's findings on the same evidence are never mounted into a new one.
inputs/inputs.jsonsha256 · md5 · sha1PacksMethod and tool packs: how an examiner works a kind of evidence, the tools for it, the recipes that catalogue it, and the programs its image needs.
- Carry skills (method), tools, catalogue recipes, goal templates and the programs each needs.
- Are built into job images, one per profile, and mounted read-only into every run.
- Are installed and verified with their own command.
- A pack is sealed: every file's hash is in its manifest, and the kickoff refuses one that changed.
- Every image profile was reviewed as an examiner would: each program run, each tool on real evidence, nothing a tool finds left out of what it returns.
pack.sh installpack.sh verifypacks/<id>/pack.jsonGuards and capsWhat holds the agents in: a microVM each, the evidence read-only, their own directories writable, an egress allowlist, and caps on spend and time.
- Boots every agent in a microVM of its own; the host decides what that machine holds.
- Denies every network destination except the model providers and the hosts the case names.
- Holds the spend, token and wall-clock caps, and reaps an agent that goes silent.
- Each guard is measured at kickoff and printed in the chain of custody, including the ones that are only advisory.
- What runs inside a VM, the harness's own extension included, is the agent's to change; the finish line, custody and the report are decided on the host.
--isolation microvm--allow-host--cap-usd--wall-clockThe swarmAgents of equal standing, each in its own microVM, dividing the case among themselves on the board and sending the heavy work to tool VMs.
- Each boots from the base image: a shell, Python and the tool library, and none of the forensic programs. The programs are in the job images.
- They read the contract and the catalogue, divide the work on the board, and take leases on the files they write.
- Each picks the tool VM its task needs; a pack tool its own VM cannot run is rerun as a job in its pack's image by itself.
- They record facts in the ledger, write the tools they lack, name themselves, and compact their own context as it fills.
- Nothing is assigned: who reviews whom is the goal's business, and a critic is one of the peers.
- An agent writes its own directories and nothing else; shared files reach the others through the hub.
work/<agent>/job_run profile=diskrecordpostclaim_fileModels and keysThe model behind each seat: cloud, private or local, mixed in one team, with the keys kept on the host.
- Each agent's seat names its model; one team can mix providers and sizes.
- A separate, cheaper model can write the summaries an agent keeps when it compacts its context.
- A provider's key never enters a VM: the VM holds a placeholder and the host swaps in the value on the way out.
- A placeholder aimed anywhere other than its own provider is stopped and logged.
- Spend and tokens are counted per seat and per model against the caps.
--models--compact-modelbudget.jsonThe boardWhere the agents divide the case: posts, threads, an inbox each, leases on files, and the names they choose. The hub is its only writer.
- Carries every post and thread; each agent reaches it over a socket of its own.
- Grants a lease on a file to one agent at a time, and refuses a second writer while it is held.
- Publishes a shared file for the agent that owns it, and posts what the harness itself has to say.
- Who is asking is decided by the socket, whatever a message claims.
- The hub bounds what one agent can ask of it.
threads/inbox/<agent>/locks/publish_fileJob serviceRuns work on the agents' behalf in throwaway worker VMs, picks the image each job needs, and seals what each job wrote.
- Takes a command, a pack or forged tool, a catalogue recipe, a detect pass or an import.
- Picks the image: the profile a job names, its pack's, or the one that holds every pack.
- Records every step before it happens, from accepted to committed, in a hash-chained journal, and resumes after a crash from the last step.
- Tells the agent that asked when its job is done, and catalogues what a job produced.
- A job's output is sealed only once its worker is gone, so nothing a worker could still write is sealed.
- The same recipe over the same object runs once for everyone.
job_run profile=mobilestore/journal.jsonljob:<id>/<path>Trace collectorThe only process that writes the audit trail. It runs on the host, chains every line to the one before, and anchors the head outside the run.
- Writes every tool call, its arguments, its whole result and the reasoning before it.
- Attributes each line by the channel it came through.
- Keeps whole outputs on disk and names them, so nothing an agent saw is cut from the record.
- A line claiming to be another agent is written as what it is, with the claim beside it.
- It cannot be unlinked or replaced from inside any VM.
traces/events.jsonltool-output/<agent>/Job imagesThrowaway worker microVMs, one per job, each booted from the image of the profile the work needs. Each image lists its own programs.
- A worker sees what the agent that asked sees, read-only: the evidence, the store, the catalogue, the tools, all of the working files.
- It writes only its own output directory, which is sealed into the store when it is gone.
- It has no network unless the job asks for the run's allowlist.
- Each image was built from sealed packs and reviewed: every program run, every tool on real evidence.
- Every image says what it holds in a file the agents read before they ask for it.
images/<profile>/tools.md$OUTdfirswarm-diskStore and journalWhere every job's output is sealed, with its manifest of hashes, and a hash-chained journal of every step the job service took.
- Seals what a job wrote into its own read-only directory, hashed file by file.
- Keeps the journal: accepted, started, finished, fenced, committed, one chained line each.
- Is what the ledger's references and the catalogue point at.
- The journal's head is anchored outside the run.
- Custody checks every output file against its manifest and every job's logs against their seal.
store/journal.jsonlstore/jobs/<id>/out/job:<id>/<path>The catalogueAn index of the evidence that grows while the agents work: file lists, partitions, archive members, memory layers, each from a pack's recipe.
- Starts at kickoff, as recipes run over the evidence as jobs.
- Grows by generations and revisions, announced on the board.
- Catalogues by itself the archives and disk images that jobs produce, in the lowest lane, and links a readable form to one it could only partly read.
- Every generation says what it covered and what it did not, and is held to its journal line.
- A recipe that could not read something says so, and says what.
catalog/gen/catalog/revisions/<n>/catalog_searchThe ledgerEvery fact the agents establish, with where it was seen, how to check it, and the sealed objects it rests on.
- Holds events for the timeline, indicators, findings, searches that found nothing, hypotheses and limitations.
- Says which question an entry answers, links entries that support or contradict each other, marks what is sensitive, and records which clock a time came from.
- A correction is a new entry; a second author is an attestation beside it.
- Every entry is chained; nothing is edited or deleted.
- A reference to a job's output is resolved when it is written, and a finding that rests on a failed job is told so.
ledger/entries.jsonlledger/attestations.jsonlledger/ledger.mdThe traceThe audit trail: every call, every intervention with its reason, every refusal, chained line to line.
- Is written only by the trace collector.
- Is walked by the report, which says intact, edited, appended, shortened or rewritten.
- Keeps every tool's whole output on disk and names it.
- Its head is anchored outside the run.
- The examiner's own commands are on it too.
traces/events.jsonltool-output/Tool libraryThe tools the agents write mid-case, sealed and versioned, and the library that carries them to the next case.
- An agent that lacks a tool writes it; every peer can call it from its next turn.
- Each version is sealed by the hash of its script, and every older version is kept.
- A run can start from a library of tools written on earlier cases.
- A tool on disk that does not match its seal does not run.
- A tool runs with the same limits as a shell, and as a job when it needs a program the agent's VM lacks.
make_tooltools/<name>/manifest.json--tools-fromFinish lineThe goal's own definition of done, checked on the host before the run is allowed to end.
- Runs the goal's checks when an agent says done.
- Checks that every question is answered, each answer resting on the ledger with its references.
- Treats one agent's wish to abandon as a vote while the others are still working.
- A done that fails a check is refused, with the first check that failed.
- The checks run on the host, where no agent can edit them.
## Checkscheck-answers.tsdone/SWARM_DONECustodyThe verdict on the run, taken on the host at stop: every check with its status, every chain sealed, signed and timestamped on request.
- Re-hashes every evidence file and compares acquisition hashes when they were given.
- Walks the trace, the ledger, its attestations and the store's journal, and seals the length and head of each.
- Verifies every sealed output against its manifest and every job's logs against their seal, and matches the operator's log to the trace.
- Signs the verdict with the examiner's key and has it timestamped by a trusted authority when asked.
- Every check has a status: passed, failed, incomplete, not applicable or unavailable, so a check that did not run never reads as clean.
- It can be taken again later, writing nothing, and held to what it sealed.
custody.jsonswarm.sh custody-verify--custody-sign-key--custody-timestamp-urlThe reportThe deliverable: the agents' report, and the chain of custody the harness prints under it.
- Answers the goal's questions, each resting on the ledger.
- Carries every exhibit, the timeline, the hypotheses still open, what could not be examined and the contradictions that stand.
- Prints the chain of custody: every check, the seal, the guards that held, the models that worked the case.
- The custody section is written by the host, never by an agent.
- It says which evidence files no command on the trace ever read.
work/report.mdpackage/report.htmlPackage and verifyThe case file that leaves the run: the whole record with its hashes, redactable, and re-walked on the other side.
- Collects the report, the ledger, the trace, the journal, the custody verdict, its signature and timestamp token, and a manifest of hashes.
- Can take out what sensitive entries say and the files they cite, while every chain still verifies.
- Is verified by walking every chain it carries against the verdict's seal.
- A redacted line keeps its own hash, so the chain through it still walks, and every change is listed.
- A path outside the package, or reached through a link, is refused.
swarm.sh package --redactswarm.sh verifyMANIFEST.txtREDACTIONS.txtReview and signThe examiner's own pass over the ledger: accept, reject or amend each entry, then sign.
- Records each decision as a line in a review file outside the run, chained to the one before.
- Signs the ledger as it stands, binding the signature to the ledger's head and the report's hash.
- Keeps the rejections standing in the record.
- The report says the ledger was not reviewed until someone does.
- A signature over a ledger that changed afterwards no longer matches.
swarm.sh review --signruns/reviews/<run>.jsonlOne case, from the kickoff to the signed hand-over.
What the map shows when it plays, step by step. The host decides every step that has to hold: the kickoff, the finish line, custody and what leaves the run.
- 01
Kickoff
The examiner points the run at the evidence, a goal and the packs. Every evidence file is hashed and the hashes are anchored outside the run, every pack's seal is checked, the job image for each pack is chosen, and each agent's microVM boots from the base image with the case contract.
- 02
Catalogue
Before anyone asks, the recipes the packs ship run as jobs over the evidence: partition tables, file lists, archive members, memory layers. Each result is sealed into the store and joins the catalogue as a generation, so the agents start from an index of the case.
- 03
Divide
The agents read the contract and the catalogue and divide the case among themselves on the board: posts, threads, and leases on the files they are writing. Nobody hands out the work, and a critic is a role the goal names.
- 04
Work
An agent sends the heavy part of its task to a worker microVM of the image that task needs: disk, memory, mobile, network and the rest. The worker sees the run read-only, writes only its own output, and is gone when the job ends. What it wrote is sealed into the store and cited by the job's id.
- 05
Grow
An archive or a disk image that a job produces is catalogued by itself, in the lowest lane, and announced to everyone. An agent that lacks a tool writes it: the tool is sealed by its hash, versioned, and kept in a library the next case starts with.
- 06
Record
Every fact goes into the ledger with the sealed objects it rests on: events for the timeline, indicators, findings, searches that found nothing, hypotheses still under test and what could not be examined. Every call an agent makes is a line in the hash-chained trace.
- 07
Finish
The goal owns the definition of done. Its checks run on the host: every question answered with evidence, a critic's sign-off posted, the timeline built from the ledger. The run ends when the finish line passes, or when the examiner stops it.
- 08
Custody
The host re-hashes the evidence, walks every chain, checks every sealed output against its manifest and every job's logs against their seal, and seals the verdict: each check with its status, signed and timestamped when the examiner asks for it.
- 09
Hand over
The report carries the chain of custody and every exhibit. The package holds the whole record with its hashes, can have what sensitive entries say taken out while every chain still verifies, and is re-walked on the other side. The examiner reviews each entry and signs.
Where the agents work, where the tools run, and where the record is kept.
Each agent works in a microVM of its own, booted from a small base image. It reads the evidence and the catalogue, talks to its peers on the board and writes only its own directories.
The heavy work runs in a worker microVM of the image the task needs, made for that one job and removed after it. What it wrote is sealed, and any agent can cite it.
The board, the store, the ledger and the trace are written by the host alone, chained line to line and anchored outside the run. Custody is taken there too.
Work a case of your own on it.
The whole platform is free software under the AGPL. A first swarm takes five minutes on a Mac with Apple silicon or a Linux machine with KVM.