If you are an agent reading this
my_work. It lists your open orders, each with its
objective, the target's own content, the premises it rests on, what has already been tried, and each done-when
predicate with how to meet it. Do what the order says, from the files, with the tools you have. Write what you find
into the record: register_run for every computation (with the exact code — print every value you
register, with its name), and the claim it supports in the same call. Numbers in a claim come from a result; a
refusal tells you the honest sentence — write that. When the reply says every predicate is met, call
return_work with a note of at most 120 words. Do not work past done. Never review your own work.
Never write "never", "proves", "edge", "optimal" or "passes" unless the record's rule for that word is met —
it will refuse you, and it will say why.Connect
The HypGraph MCP server is the whole interface. One author name per server process; you cannot write as anyone
else, and reserved names (harness, lab, operator) are refused.
pip install "hypgraph[mcp]" claude mcp add hypgraph -- hypgraph --db study.hypgraph --as nicolas mcp # in the session: my_work
hypgraph --db study.hypgraph --as nicolas mcp --record-url http://host:8765 --token "$MY_TOKEN"
The seat must exist in the run's roster with external = true; otherwise the scheduler never issues
you anything. Ask whoever runs the swarm (see for engineers).
Read an order
Everything you need is in the order; you should not need show to start. A review order looks like
this (a trading profile, out-of-sample backtest):
WORK ORDER T4 for risk (reviewer) — issued by harness at 2026-10-25T18:02:11+00:00
OBJECTIVE Review CL2, which answers Q1. The order lists the claim, its measurements and the
results it rests on, and what the instrument's re-run of the author's code confirmed —
recompute only a value it CONTRADICTED. Judge the method and the wording; record a verdict.
TARGET CL2 The strategy returns 8.1% a year out of sample after fees. — active claim · unchecked
statement: The strategy returns 8.1% a year out of sample after fees.
scope: Daily bars 2022–2024 (held out), 10 bp fees, 5 bp slippage.
measurement oos_return = 0.081 ← RS2.oos_return
rests on RS2: Out-of-sample backtest 2022–2024. — oos_return = 0.081; fees = 0.001; slippage = 0.0005; max_dd = -0.14
code of RUN3:
import pandas as pd ...
re-run by RUN4: 4 of 4 registered values confirmed by the output
PREMISES
H1 Mean reversion in the 5-day return persists after 2021. — active hypothesis · 1 line of support
DONE WHEN (checked against the record; only what you write after the order counts)
[reviewed] — an official review of the target's current version
how: review(<target>, verdict, method, notes) — by a reviewer, never the claim's author
LEASE until 2026-10-25T22:02:11+00:00
RETURN Your deliverable is the writes above … then return_work with a note of at most 120 words.| line | what it means for you |
|---|---|
| OBJECTIVE | What to do. For a review, which claim and what to judge. |
| TARGET + its content | The node's statement, measurements, the results it rests on with their values, the code behind them, and whether the instrument reproduced them. |
| PREMISES | What the order rests on, pinned to versions. If one is marked REVISED or fallen, say so in your note rather than building on it. |
| ALREADY KNOWN OR TRIED | Earlier orders on this target and why they ended. Don't repeat a failed approach without saying what is different. |
| DONE WHEN | The predicates the record will check, each with the recipe that meets it. Only writes after the order was issued count. |
Do the work
Three writes cover almost everything a worker does.
register_run — a computation, its result, and the claim, in one call
register_run(
name="accuracy of A on items.csv",
code="import pandas as pd\ndf = pd.read_csv('items.csv')\nk = int(df.a.sum()); n = len(df)\nprint('acc_a', k, 'of', n)",
result_summary="Counted A's correct items in items.csv.",
values={"acc_a": {"k": 812, "n": 1000}},
claim="A is right on 812 of 1000 items.", answers="Q1",
scope="The 1000 paired items in items.csv.")Three things that reply tells you: the claim went in with its number bound; your order is done; how much budget is left. Print every value you register, with its name. The instrument re-runs your code in the host's sandbox and checks the output: a value it confirms strengthens your result; one it doesn't find is "not printed" (not held against you); one it finds with a different number is contradicted, and that is what a reviewer will recompute.
graph_add — anything else: a source, a hypothesis, an experiment, a claim on its own
graph_add(type="source", fields={"citation": "Ford, J.K.B. (1991). Vocal traditions among resident killer whales.",
"doi": "10.1139/z91-206", "passage": "…dialects are stable over at least a decade…"})
graph_add(type="claim", fields={"statement": "Resident dialects are stable over at least ten years.",
"scope": "Northern and southern residents, Ford 1991.", "kind": "finding"},
links=[{"rel": "answers", "to": "Q2"}, {"rel": "cites", "to": "S1"}])review — a verdict, by a reviewer, never on your own author's work
review(node="CL2", verdict="checked", method="Read RUN3's code and RUN4's re-run; the OOS window and fees match the scope.",
notes="The claim says what the result says. The 2021 regime change is in H1's premises, not hidden.")Refusals, and what to write instead
Every refusal names a rule, says what it measured, and gives the honest sentence. These are the ones you will meet most. Write the honest version; do not argue with the record.
→ The number isn't in any of your results. Register the computation that produced it, then make the claim from that result. "A is 5 points better" becomes "A is right on 812 of 1000, B on 762 of 1000" — the record derives the 5.
→ Write exactly the honest version. The bound rides up through every claim that rests on yours; "never" would not have.
→ "A is right on 812 of 1000 and B on 800 of 1000; the difference is not significant at 0.05." The record ran the test on your own counts; it will accept that sentence.
→ You already registered this. Make the claim from RS2. If you really re-ran it on purpose (new seed, new
implementation), say so with a replicates link.
Example: scientific profile
seats analyst · stats · critic · lead done when a checked claim answers the question
Order: Answer Q2: Is A significantly better than B? You compute, register the counts with the test, and write the claim the test supports:
register_run(name="paired comparison", code="…print('a', ka, 'of', n); print('b', kb, 'of', n); print('p', p)",
result_summary="Compared A and B on the same 1000 items; two-sided z-test on the paired counts.",
values={"a": {"k": 812, "n": 1000}, "b": {"k": 800, "n": 1000}, "p": {"value": 0.49}},
claim="A is not significantly more accurate than B (812 of 1000 vs 800 of 1000, p = 0.49).", answers="Q2",
scope="The 1000 paired items in items.csv; two-sided test at 0.05.")If you had written "A is significantly better", the record would have refused it with the z-test it ran on your counts. The critic's review settles Q2; the lead writes the interpretation under the facts.
Example: software profile
seats implementer · tester · reviewer · lead done when tests_pass — the instrument ran the tests — and a claim states it
Order to the tester: Verify Q3: the CSV importer handles quoted commas. You run the tests and register the
exact command as the code. The instrument re-runs it; that lab run is what meets tests_pass —
your own report of passing never does.
register_run(name="importer tests", code="import subprocess\nr = subprocess.run(['pytest', '-q', 'tests/test_importer.py'], capture_output=True, text=True)\nprint(r.stdout[-400:])\nprint('passed', r.stdout.count(' passed'), 'failed', r.stdout.count(' failed'))",
result_summary="Ran tests/test_importer.py: 12 passed, 0 failed.",
values={"passed": {"k": 12, "n": 12}, "exit_code": {"value": 0}}, outcome="positive",
claim="The importer passes all 12 of 12 tests in tests/test_importer.py, including quoted commas.", answers="Q3",
scope="tests/test_importer.py at commit 4f2a9c1, run by the instrument.")→ You wrote the claim before the instrument's re-run landed. Wait for the reply that names the lab run (it arrives
within the round), or return the order: the scheduler reproduces first and re-issues the review. The diff you
changed is an artifact by hash — register it with graph_add(type="artifact", …) so the claim can rest on
the exact bytes.
Example: trading profile
seats quant · risk · lead done when backtested_oos — out of sample and after costs — and a claim
Order to the quant: Answer Q1: does the 5-day mean-reversion thesis have an edge after costs?
register_run(name="OOS backtest 2022–2024", code="…print('oos_return', oos_ret); print('fees', fees); print('slippage', slip); print('max_dd', mdd)",
result_summary="Backtested the thesis on the held-out window 2022–2024 with 10 bp fees and 5 bp slippage.",
values={"oos_return": {"value": 0.081}, "fees": {"value": 0.001}, "slippage": {"value": 0.0005}, "max_dd": {"value": -0.14}},
claim="The strategy returns 8.1% a year out of sample after fees, with a 14% maximum drawdown.", answers="Q1",
scope="Daily bars 2022–2024 held out; 10 bp fees, 5 bp slippage; no leverage.")→ Both are the same rule from two sides: a return without costs is not a result here, and "edge" from the fitting
window is not a claim. Positions are paper: the lead records a decision (size, stop) based_on your
claim. There is no live-order path, and nothing you write can create one.
Example: knowledge profile
seats researcher · fact_checker · lead done when sourced — a claim that cites a source node
Order: Answer Q1: when was the Peace of Westphalia signed? Add what you read as a source, then the claim that cites it. Recall is not a source; the record refuses a bare claim.
graph_add(type="source", fields={"citation": "Encyclopaedia Britannica, 'Peace of Westphalia'.",
"url": "https://www.britannica.com/event/Peace-of-Westphalia",
"passage": "…signed on October 24, 1648…", "retrieved": "2026-10-25"})
graph_add(type="claim", fields={"statement": "The Peace of Westphalia was signed on 24 October 1648.",
"scope": "The treaties of Osnabrück and Münster, 1648.", "kind": "finding"},
links=[{"rel": "answers", "to": "Q1"}, {"rel": "cites", "to": "S1"}])→ Add the source first. The fact-checker opens it and records the verdict; the final report is linted against the record, so a sentence that treats an unreviewed claim as settled is refused there too.
Example: optimization profile
seats modeller · solver · verifier · lead done when feasible_bounded — objective, feasible, and a bound or gap
register_run(name="CBC solve, 40 sites", code="…print('objective', obj); print('feasible', feasible); print('gap', gap); print('runtime_s', t)",
result_summary="Solved the 40-site facility model with CBC to a 0.4% MIP gap in 118 s.",
values={"objective": {"value": 412.6, "unit": "k$"}, "feasible": {"value": true}, "gap": {"value": 0.004}, "runtime_s": {"value": 118}},
claim="The best solution found costs 412.6 k$ with a 0.4% optimality gap.", answers="Q1",
scope="The 40-site instance with the stated demand and capacity constraints; CBC, 120 s limit.")→ "Best found, gap 0.4 %" is accepted; "optimal" needs gap = 0 or a bound that meets the objective.
A result with an objective and no feasible is refused before it is even a result.
If you are a reviewer
You hold review orders. The order carries the claim, its measurements, the results it rests on with their values,
the code that produced them, and the instrument's re-run verdict. Judge; don't recompute — recompute only a
value the instrument marked contradicted. Verdicts: checked / pass (it holds),
fail (it doesn't, and why), objection (a specific problem the author must answer),
inconclusive, comment. You cannot review your own author's work, and you cannot write
claims — if the right answer is missing, say so in your notes and return the order; a worker will be asked.
Return, rework, notices
- Return when the reply says every predicate is met:
return_work(note=…), ≤ 120 words — what you did, what you could not. If you stop without returning, the record returns the order on your behalf and the scheduler decides. - Rework. An order that comes back NOT MET returns to you as a new order saying what was missing — at most twice; then the lead judges. If your seat names a deeper model, the rework runs on it.
- Notices. A file declared corrupt is withdrawn in the record and its replacement registered; every order
issued afterwards says so, and
read_filerefuses the withdrawn bytes with the reason. An order resting on a fallen premise is cancelled — check your premises' standing when you resume. - Completion.
completionsays what the profile means by done for the whole investigation and which criteria are met — useful before you tell anyone it's finished.
If you are a person
Everything above applies to you as written: the record can't tell a person from an agent except by name. Hold
your seat from a coding agent (Claude Code, Cursor) with the MCP server, or from the CLI — hypgraph
--db study.hypgraph orders lists orders, hypgraph brief compiles the orchestrator's view. A
token bound to your name is how a served record knows it's you.