For agents

Research you can stand behind.

Give your agent a record that checks its claims as they're written, won't let it review its own work, and explains every refusal — so its research gets better, not just longer.

If you are an agent reading this

Plain instructions. HypGraph is a research record. Use it whenever you investigate a question with evidence and need to say what is established. Read before writing (overview). Write hypotheses with predictions. Write each experiment's expected outcome per hypothesis before running it. Record runs with hashed files. Bind every number in a claim to a result field. Never write "always/never/proves" without k of n with k = 0 or n. Never call something ruled out without a power check. Report standing exactly as the record states it. When a write is refused, fix what the message says. Short version: /llms.txt · full skill: /SKILL.md.

Install the skill

For Claude Code and other hosts that load Agent Skills. The skill carries the method, the refusals and their fixes, and works through the CLI — no server needed.

pip install hypgraph
hypgraph skill --install            # .claude/skills/hypgraph/SKILL.md in this project
hypgraph skill --install --user     # or under your home directory, for every project

Connect over MCP

Claude Code
pip install "hypgraph[mcp]"
claude mcp add hypgraph -- hypgraph --db study.hypgraph --as claude mcp
Claude Desktop · Cursor · any MCP client
{
  "mcpServers": {
    "hypgraph": {
      "command": "hypgraph",
      "args": ["--db", "/absolute/path/study.hypgraph", "--as", "claude", "mcp"]
    }
  }
}
Streamable HTTP
hypgraph --db study.hypgraph --as claude mcp --transport http --port 8766
# → http://127.0.0.1:8766/mcp

The server writes as one author, fixed at start. The agent can't pass another name, can't write as the instrument (lab) or the operator, and its verdicts count only if the investigation names it as a reviewer. Files for register_run must be under the directory the server was started in.

The method

  1. overview() first. What's established, what's contested, what's waiting, what to run next.
  2. Hypotheses with predictions — and rivals, linked alternative_to.
  3. Experiments that can fail — tests links with data.expected per hypothesis, written before running. Add a power_check: plant a known answer and show the method finds it.
  4. register_run — hashes code, inputs and outputs, and adds the result with values {name: {value} | {k, n}}.
  5. Claims with measurements — every number bound; a supports link with a reason; a scope.
  6. Review — only named reviewers count, never on their own work.
  7. report() at the top of every summary; interpretation below it — then check_report(text) on the write-up before you hand it over. Fix every error.

Tools

toolwhat it does
overview(investigation?)Objective, reviewers, live hypotheses, checked claims and how they're known, contested / at-risk work, leases, queues, next experiments.
find(text, type?, investigation?)Search by words or code (H1, CL3).
show(node, view)summary · why (what it rests on) · impact (what breaks if it's wrong) · history.
start_investigation(title, objective, reviewers)Open a study with its reviewers.
add(type, fields, investigation?, links?)Question, hypothesis, experiment, run, result, claim, source, decision. Links accept ids or codes.
link(src, rel, dst, why, data?)Typed links; a backwards link is turned round when only the reverse is allowed.
revise · withdraw · retract_linkCorrections as new rows; nothing is erased.
review(node, verdict, method, notes)A verdict on the current version.
check_report(text)Lint a write-up against the record: unsourced numbers, claims called settled that aren't, withdrawn or unknown codes, never / no effect / significantly with nothing behind them.
refusal_log(author?)The overclaims the record refused — yours or the team's — and whether each came back honest.
bound(k, n, exposure)What a count supports: the 95% bounds behind any "never", trials needed, failures not ruled out at scale.
next_experiments · work_queue · claim_workWhat to run next; what's waiting; take a node so others see who's on it.
register_run(name, code_paths, input_paths, output_paths, result_summary, result_values)Record a computation with hashed files.
report · verify · schemaThe generated facts; the chain check; the vocabulary.

Resources: hypgraph://skill, hypgraph://schema, hypgraph://investigations, hypgraph://investigation/{inv}/report. Prompt: method.

Refusals are instructions

Each refused claim lists one line per problem, ending in a stable code. The message has done the arithmetic and usually contains the honest sentence — use it. In Python, GraphError.problems gives code, message, fix and words.

codedo this
ABSOLUTE_UNDERPOWERED"never" on 0 of n with too few trials. Write the honest sentence it gives ("no occurrences in n trials (95% upper bound X)"), or run the trials it says you need.
ABSOLUTE_HIDES_DENOMINATORPut n in the statement: "never, in 3,000 probes".
ABSOLUTE_WITHOUT_COUNT · ABSOLUTE_UNRELATED_COUNTSay what was seen ("in k of n"); name the count after what it counts.
UNBOUND_NUMBERBind it to a result field. Differences, percentages, ratios and intervals computed from bound counts pass — never drop the number to get past.
EXCLUSION_WITHOUT_POWER"No effect" needs a search shown to find a planted effect (power: demonstrated). Otherwise file kind: inconclusive and say "no detectable effect" — the refusal says how large an effect could have hidden.
COMPARATIVE_WITHOUT_COMPARISONBind both sides.
SIGNIFICANCE_WITHOUT_TEST · SIGNIFICANCE_NOT_SHOWNBind both sides as k/n (the record tests them) or a p-value; if it isn't significant, say so.
CAUSAL_WITHOUT_INTERVENTIONSay "is associated with", or support it from an experiment that intervened.

Before writing never or always, call bound(k, n, exposure): what the count supports and how many failures it leaves unruled out at the scale the claim will be used. Set exposure on the claim so its standing carries that number. When you withdraw or contest a node, the reply lists what now rests on something that fell — tell their owners. The full story: the arithmetic of never.

Reading standing

active claim · checked (fisher:pass, v2) · 2 independent lines of support · replicated on new data · no external replication

Quote it as it is. "Unchecked" is not "shown"; one agent-reported line is not "established". AT RISK: a premise fell. REVISIT: a decision's basis changed. UNSUPPORTED: every support fell.

For the engineer wiring it up

Running many agents? Embed the library and set the trust yourself: Graph(path, policy=Policy(reviewers=…, instrument="lab", operator="operator")). Fix each caller's author on your side and refuse the reserved names. Give your job runner the instrument identity so its runs count as lab-recorded. Pass spend= to price the work behind each investigation. PegasusDMZ runs a team of agents on exactly this. The engineering guide has the patterns. The HTTP API (hypgraph.server.dispatch) and the Atlas (hypgraph.ui.static_dir()) drop into any web framework.

Machine-readable