hypgraph 0.1.0__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hypgraph-0.1.0 → hypgraph-0.2.0}/AGENTS.md +8 -1
- hypgraph-0.2.0/CHANGELOG.md +67 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/CITATION.cff +3 -1
- hypgraph-0.2.0/NOTICE +8 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/PKG-INFO +56 -12
- {hypgraph-0.1.0 → hypgraph-0.2.0}/README.md +52 -10
- {hypgraph-0.1.0 → hypgraph-0.2.0}/docs/spec.md +35 -13
- {hypgraph-0.1.0 → hypgraph-0.2.0}/pyproject.toml +4 -3
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/__init__.py +1 -1
- hypgraph-0.2.0/src/hypgraph/checks.py +366 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/cli.py +25 -2
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/derive.py +56 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/graph.py +52 -9
- hypgraph-0.2.0/src/hypgraph/language.py +59 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/mcp.py +35 -3
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/schema.py +2 -1
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/skill/SKILL.md +27 -11
- hypgraph-0.2.0/src/hypgraph/stats.py +91 -0
- hypgraph-0.2.0/tests/test_refusals.py +174 -0
- hypgraph-0.1.0/src/hypgraph/checks.py +0 -140
- {hypgraph-0.1.0 → hypgraph-0.2.0}/.gitignore +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/LICENSE +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/docs/PLAN.md +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/__main__.py +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/bundle.py +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/demos/__init__.py +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/demos/broad_street.py +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/plan.py +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/policy.py +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/server.py +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/store.py +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/ui/__init__.py +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/ui/atlas.css +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/ui/atlas.js +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/ui/hypgraph.svg +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/ui/index.html +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/ui/vendor/LICENSES.md +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/ui/vendor/cose-base.js +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/ui/vendor/cytoscape-fcose.js +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/ui/vendor/cytoscape.min.js +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/src/hypgraph/ui/vendor/layout-base.js +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/tests/test_engine.py +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/tests/test_incremental.py +0 -0
- {hypgraph-0.1.0 → hypgraph-0.2.0}/tests/test_surfaces.py +0 -0
|
@@ -56,9 +56,16 @@ reserved.
|
|
|
56
56
|
```
|
|
57
57
|
with `links=[{"rel": "supports", "from": "RS3", "why": "RS3 is the measurement this claim states."}]`.
|
|
58
58
|
- every number in the statement must match a bound measurement, the scope, or an investigation constant;
|
|
59
|
-
- "never", "
|
|
59
|
+
- "never", "always", "eliminates", "100%" need a count of what they're about with k = 0 or k = n, enough
|
|
60
|
+
trials that the 95% bound is under 5%, and n in the statement ("never, in 3,000 probes"). Check first:
|
|
61
|
+
`bound(k, n, exposure)` says what a count supports and how many failures it leaves unruled out at scale;
|
|
62
|
+
- "beats" / "outperforms" need both sides measured; "significantly" needs a test (the record runs one on two
|
|
63
|
+
bound counts); "causes" needs an experiment that intervened;
|
|
64
|
+
- numbers computed from bound counts (differences, percentages, ratios, intervals) are fine; invented ones
|
|
65
|
+
are not;
|
|
60
66
|
- `kind: "exclusion"` needs a result with `power: "demonstrated"` (a search that found a planted answer).
|
|
61
67
|
Otherwise use `"inconclusive"`.
|
|
68
|
+
Each refusal ends in a code (`[ABSOLUTE_UNDERPOWERED]`) and already gives the honest sentence: use it.
|
|
62
69
|
6. **Reviews.** Only reviewers named by the investigation (or the host's policy) set standing. Nobody reviews their
|
|
63
70
|
own work. A revision makes earlier reviews stale.
|
|
64
71
|
7. **Start summaries from `report()`.** It's generated from the record, so it can't restate a withdrawn claim. Write
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.2.0 — 2026-10-24
|
|
4
|
+
|
|
5
|
+
**Refusal, remastered.** The claim checks now do the arithmetic the writer skipped, and every refusal says what the
|
|
6
|
+
count actually supports and offers the honest sentence.
|
|
7
|
+
|
|
8
|
+
- **The arithmetic of never.** "Never" / "always" / "eliminates" / "100%" need a count of what they're about with
|
|
9
|
+
k = 0 or n (`ABSOLUTE_WITHOUT_COUNT`, `ABSOLUTE_UNRELATED_COUNT`). That count needs a 95% bound under 5%
|
|
10
|
+
(`ABSOLUTE_UNDERPOWERED`: "0 of 3 only rules out more than 63%"), and the statement has to show its denominator
|
|
11
|
+
(`ABSOLUTE_HIDES_DENOMINATOR`). The bounds are exact at k = 0 (1 − 0.05^(1/n), the rule of three) and Wilson
|
|
12
|
+
otherwise.
|
|
13
|
+
- **Exposure.** A claim can say how many uses, users or units it applies to (`exposure`, `exposure_unit`). Refusals
|
|
14
|
+
and the claim's standing then state how many failures the bound leaves unruled out: "up to 58,155 of 1,000,000".
|
|
15
|
+
- **New rules:** `COMPARATIVE_WITHOUT_COMPARISON`, `SIGNIFICANCE_WITHOUT_TEST`, `SIGNIFICANCE_NOT_SHOWN` (the
|
|
16
|
+
record runs a two-proportion test on bound counts itself), `CAUSAL_WITHOUT_INTERVENTION`, and
|
|
17
|
+
`EXCLUSION_WITHOUT_POWER` for "no effect" however it is filed, with the smallest effect the sample could have
|
|
18
|
+
detected.
|
|
19
|
+
- **True numbers pass.** Differences, ratios, percentages and relative changes computed from bound measurements are
|
|
20
|
+
accepted ("2.8 points", "81.2% vs 78.4%", "+3.6%"). Statistical quantities must be written to one decimal place, so
|
|
21
|
+
"5 points" can't borrow an interval's end.
|
|
22
|
+
- **Refusals agents can act on:** a stable code on every line, and `GraphError.problems` with `code`, `message`,
|
|
23
|
+
`fix` and `words`.
|
|
24
|
+
- **Blast radius.** `withdraw()`, and a review that makes a node fall, return `blast_radius`: what rests on it, by
|
|
25
|
+
type, with claims and decisions named (and spend, if metered). The CLI and MCP print it.
|
|
26
|
+
- **`hypgraph bound K N --exposure X`** and the MCP tool `bound`: what a count supports, before anyone writes "never".
|
|
27
|
+
- A claim's standing carries `bounds`, and `test` for "significantly" claims. Spec draft 2 (§7 rewritten).
|
|
28
|
+
- Credits: made by Nicolas Houghtaling at VoodooMods LLC (README, NOTICE, CITATION.cff, package metadata, site).
|
|
29
|
+
|
|
30
|
+
## 0.1.0 — 2026-10-24
|
|
31
|
+
|
|
32
|
+
First release on PyPI.
|
|
33
|
+
|
|
34
|
+
- **Writes cost what they touch.** A write no longer copies the whole in-memory snapshot. Tables are shallow
|
|
35
|
+
copies, and a node's list is copied only when the write appends to it. Derived standing is kept for every node the
|
|
36
|
+
write can't affect (`derive.affected_by`), so the first full read after a write no longer re-derives the graph.
|
|
37
|
+
At 10,000 nodes: building the graph took 77 s instead of 133 s, a full read after a write 0.02 s instead of
|
|
38
|
+
0.17 s, and a write at 5,000 nodes 5.8 ms instead of 12 ms. A randomized suite checks the carried standing
|
|
39
|
+
against a full rebuild after every kind of write.
|
|
40
|
+
- New indexes for display codes and the rate limit (`nodes(inv, type)`, `nodes(inv, code)`, `events(actor, kind,
|
|
41
|
+
at)`). Created on open; existing records just gain them.
|
|
42
|
+
- Positioning: the evidence layer for AI research agents. README and site lead with the MCP server and the Agent
|
|
43
|
+
Skill; a new engineering guide (`/engineers/`) replaces the human guide; the eval-report example replaces the
|
|
44
|
+
classroom one.
|
|
45
|
+
|
|
46
|
+
### Extracted from PegasusDMZ
|
|
47
|
+
|
|
48
|
+
Extracted from the PegasusDMZ research graph and verified against it: on a copy of Pegasus's live
|
|
49
|
+
graph (1,357 events, 790 nodes in 5 investigations), the library reproduces the same chain head, every node's
|
|
50
|
+
standing, the work queues and the next-experiment rankings.
|
|
51
|
+
|
|
52
|
+
- **Engine** (stdlib only): typed nodes and edges, append-only SQLite with a SHA-256 event chain and `verify()`,
|
|
53
|
+
standing derived on read, claim checks on write, review pinned to versions, independence and evidence profile,
|
|
54
|
+
leases, next experiments, work map, digest, report.
|
|
55
|
+
- **Policy**: reviewers, instrument, operator, importer and system are the host's to set (they were hardcoded in
|
|
56
|
+
Pegasus). Optional `spend` hook for cost. Injectable `clock`; only the importer may set a write's time.
|
|
57
|
+
- **Bundles** (`hypgraph/1-bundle`): every event and body as the exact hashed string, so they can be verified in any
|
|
58
|
+
language. Scoped exports redact events outside the investigation and say so. A complete bundle replays row for row.
|
|
59
|
+
- **CLI**: `init`, `add`, `link`, `review`, `revise`, `withdraw`, `ls`, `show --why/--impact/--history`, `next`, `work`,
|
|
60
|
+
`report`, `export`, `import`, `verify`, `demo`, `schema`, `serve`, `mcp`, `skill`.
|
|
61
|
+
- **MCP server** (FastMCP, `hypgraph[mcp]`): 17 tools, 4 resources, a `method` prompt. Writes as one fixed author.
|
|
62
|
+
- **Agent skill**: `SKILL.md` ships in the package; `hypgraph skill --install`.
|
|
63
|
+
- **Atlas**: the framework-free explorer, with an HTTP source and a bundle source (it verifies the chain in the
|
|
64
|
+
browser). Cytoscape is vendored.
|
|
65
|
+
- **Demo**: Broad Street, 1854 — a teaching reconstruction with three refusals built into the story.
|
|
66
|
+
- Fixed while extracting it: a report listed stale-reviewed claims under the wrong key; claim measurements now accept
|
|
67
|
+
result codes (RS3) and store ids.
|
|
@@ -10,8 +10,10 @@ type: software
|
|
|
10
10
|
authors:
|
|
11
11
|
- family-names: Houghtaling
|
|
12
12
|
given-names: Nicolas
|
|
13
|
+
affiliation: VoodooMods LLC
|
|
14
|
+
- name: VoodooMods LLC
|
|
13
15
|
license: Apache-2.0
|
|
14
|
-
version: 0.
|
|
16
|
+
version: 0.2.0
|
|
15
17
|
date-released: "2026-10-24"
|
|
16
18
|
url: "https://hypgraph.com"
|
|
17
19
|
repository-code: "https://github.com/voodoomods/hypgraph"
|
hypgraph-0.2.0/NOTICE
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
HypGraph
|
|
2
|
+
Copyright 2026 Nicolas Houghtaling and VoodooMods LLC
|
|
3
|
+
|
|
4
|
+
This product is licensed under the Apache License, Version 2.0 (see LICENSE).
|
|
5
|
+
The record format specification and documentation are licensed under CC BY 4.0.
|
|
6
|
+
|
|
7
|
+
This product includes software developed by third parties, shipped in src/hypgraph/ui/vendor/ under the MIT
|
|
8
|
+
license: Cytoscape.js (The Cytoscape Consortium), layout-base, cose-base and cytoscape-fcose (iVis@Bilkent).
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: hypgraph
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: The evidence layer for AI research agents: a hash-chained research record that checks every claim as it is written and derives how well each is known.
|
|
5
5
|
Project-URL: Homepage, https://hypgraph.com
|
|
6
6
|
Project-URL: Documentation, https://hypgraph.com/engineers/
|
|
7
7
|
Project-URL: Changelog, https://github.com/voodoomods/hypgraph/blob/main/CHANGELOG.md
|
|
8
8
|
Project-URL: Source, https://github.com/voodoomods/hypgraph
|
|
9
|
-
Author: Nicolas Houghtaling
|
|
9
|
+
Author: Nicolas Houghtaling, VoodooMods LLC
|
|
10
|
+
Maintainer: VoodooMods LLC
|
|
10
11
|
License-Expression: Apache-2.0
|
|
11
12
|
License-File: LICENSE
|
|
13
|
+
License-File: NOTICE
|
|
12
14
|
Keywords: agent-skills,ai-agents,evaluation,hypothesis,mcp,provenance,reproducibility,research
|
|
13
15
|
Classifier: Development Status :: 3 - Alpha
|
|
14
16
|
Classifier: Intended Audience :: Developers
|
|
@@ -38,21 +40,59 @@ The evidence layer for AI research agents.<br>
|
|
|
38
40
|
|
|
39
41
|
---
|
|
40
42
|
|
|
41
|
-
Agents doing research write fluent summaries. Some of the numbers in them match no result.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
Agents doing research write fluent summaries. Some of the numbers in them match no result. A clean red-team run of
|
|
44
|
+
50 prompts becomes "the model never leaks". A search too weak to find anything becomes "ruled out", and three copies
|
|
45
|
+
of one result get counted as three lines of evidence. Then other claims, decisions and deployments get built on top.
|
|
46
|
+
HypGraph is the record agents write into instead. It checks every claim as it's written, does the arithmetic the
|
|
47
|
+
writer skipped, and refuses:
|
|
45
48
|
|
|
46
49
|
```text
|
|
47
|
-
$ hypgraph add claim statement="The
|
|
50
|
+
$ hypgraph add claim statement="The model never leaks training data." exposure=1000000 exposure_unit=users …
|
|
48
51
|
refused: claim refused:
|
|
49
|
-
-
|
|
52
|
+
- 'never' rests on 0 of 50: that only rules out it happening more than 5.8% of the time (95% upper bound).
|
|
53
|
+
Honest version: 'no occurrences in 50 trials (95% upper bound 5.8%)'. To support a rate below 1 in 1,000 you need
|
|
54
|
+
about 2,995 trials without one. Across the 1,000,000 users this claim applies to, that leaves up to 58,155 not
|
|
55
|
+
ruled out. [ABSOLUTE_UNDERPOWERED]
|
|
50
56
|
```
|
|
51
57
|
|
|
52
|
-
|
|
58
|
+
The honest version goes in, and it carries its consequence wherever it's read:
|
|
53
59
|
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
```text
|
|
61
|
+
active claim · unchecked · 1 independent line of support · … · 0 of 50 = at most 5.8% at 95%, up to 58,155 of 1,000,000 not ruled out
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## The arithmetic of never
|
|
65
|
+
|
|
66
|
+
"Never" is the most expensive word in research, because everything built on it inherits it. Zero failures in *n*
|
|
67
|
+
trials doesn't mean a rate of zero. It means a rate below 1 − 0.05^(1/*n*), about 3/*n*, at 95% confidence. HypGraph
|
|
68
|
+
holds every claim to that:
|
|
69
|
+
|
|
70
|
+
| The claim says | Refused as | Because |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| "never leaks", from 0 of 50 | `ABSOLUTE_UNDERPOWERED` | it could still be 5.8%, up to 58,155 of a million users |
|
|
73
|
+
| "never leaks", from 0 of 3,000, without saying 3,000 | `ABSOLUTE_HIDES_DENOMINATOR` | readers hear "never", but it means "at most 1 in 1,000" |
|
|
74
|
+
| "eliminates hallucinations entirely" | `ABSOLUTE_WITHOUT_COUNT` | nothing was counted |
|
|
75
|
+
| "5 points better" (the counts say 2.8) | `UNBOUND_NUMBER` | the number comes from nowhere. 2.8 points, 81.2% vs 78.4% and +3.6% all pass, because they follow from the counts. |
|
|
76
|
+
| "significantly better", counts 812/1,000 vs 800/1,000 | `SIGNIFICANCE_NOT_SHOWN` | the record runs the test: p = 0.5 |
|
|
77
|
+
| "prompt format has no effect" | `EXCLUSION_WITHOUT_POWER` | at 2,000 items a 3.6-point effect would usually go unseen |
|
|
78
|
+
| "longer prompts cause the gain" | `CAUSAL_WITHOUT_INTERVENTION` | no experiment intervened |
|
|
79
|
+
| "outperforms the baseline", no numbers | `COMPARATIVE_WITHOUT_COMPARISON` | only one side was measured |
|
|
80
|
+
|
|
81
|
+
Every refusal has a stable code, the arithmetic, and the sentence that *would* be honest, so an agent can repair a
|
|
82
|
+
claim in one step. `hypgraph bound 0 50 --exposure 1e6` (or the MCP tool `bound`) answers "what does my count
|
|
83
|
+
actually support?" before anyone writes the word.
|
|
84
|
+
|
|
85
|
+
And when something does fall, the record says what falls with it:
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
$ hypgraph withdraw CL1 --why "the held-out set leaked into training"
|
|
89
|
+
CL1 — withdrawn claim · …
|
|
90
|
+
⚠ 2 nodes rest on CL1: 1 decision (D1); 1 claim (CL2) — now AT RISK
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Derived, never asserted
|
|
94
|
+
|
|
95
|
+
Nothing in the record is ever *set* as known. How well each claim is known is **derived on every read**:
|
|
56
96
|
|
|
57
97
|
- **reviewed, and which version?** Only named reviewers count, and never on their own work. A revised claim goes back
|
|
58
98
|
to unchecked.
|
|
@@ -76,7 +116,7 @@ hypgraph skill --install # +
|
|
|
76
116
|
The server writes as one author, fixed when it starts. The agent can't pass another name or write as your job runner,
|
|
77
117
|
and its verdicts count only if you name it as a reviewer. Tools: `overview`, `find`, `show`, `start_investigation`,
|
|
78
118
|
`add`, `link`, `revise`, `withdraw`, `retract_link`, `review`, `next_experiments`, `work_queue`, `claim_work`,
|
|
79
|
-
`register_run`, `report`, `verify`, `schema`. The method is in [AGENTS.md](https://github.com/voodoomods/hypgraph/blob/main/AGENTS.md); the short version is
|
|
119
|
+
`register_run`, `bound`, `report`, `verify`, `schema`. The method is in [AGENTS.md](https://github.com/voodoomods/hypgraph/blob/main/AGENTS.md); the short version is
|
|
80
120
|
[llms.txt](https://hypgraph.com/llms.txt).
|
|
81
121
|
|
|
82
122
|
## Wire it into your system
|
|
@@ -134,6 +174,10 @@ standing takes 0.09 s, reading one node 0.3 ms, and a write about 10 ms, mostly
|
|
|
134
174
|
costs what it touches: cached standing is kept for every node the write can't affect, and a randomized suite checks
|
|
135
175
|
that against a full rebuild.
|
|
136
176
|
|
|
177
|
+
## Made by
|
|
178
|
+
|
|
179
|
+
HypGraph is made by **Nicolas Houghtaling** at **[VoodooMods LLC](https://github.com/voodoomods)**.
|
|
180
|
+
|
|
137
181
|
## License
|
|
138
182
|
|
|
139
183
|
Code: [Apache-2.0](https://github.com/voodoomods/hypgraph/blob/main/LICENSE). The record format ([docs/spec.md](https://github.com/voodoomods/hypgraph/blob/main/docs/spec.md)) and the docs: CC BY 4.0. Cite it with
|
|
@@ -8,21 +8,59 @@ The evidence layer for AI research agents.<br>
|
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
Agents doing research write fluent summaries. Some of the numbers in them match no result.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
Agents doing research write fluent summaries. Some of the numbers in them match no result. A clean red-team run of
|
|
12
|
+
50 prompts becomes "the model never leaks". A search too weak to find anything becomes "ruled out", and three copies
|
|
13
|
+
of one result get counted as three lines of evidence. Then other claims, decisions and deployments get built on top.
|
|
14
|
+
HypGraph is the record agents write into instead. It checks every claim as it's written, does the arithmetic the
|
|
15
|
+
writer skipped, and refuses:
|
|
15
16
|
|
|
16
17
|
```text
|
|
17
|
-
$ hypgraph add claim statement="The
|
|
18
|
+
$ hypgraph add claim statement="The model never leaks training data." exposure=1000000 exposure_unit=users …
|
|
18
19
|
refused: claim refused:
|
|
19
|
-
-
|
|
20
|
+
- 'never' rests on 0 of 50: that only rules out it happening more than 5.8% of the time (95% upper bound).
|
|
21
|
+
Honest version: 'no occurrences in 50 trials (95% upper bound 5.8%)'. To support a rate below 1 in 1,000 you need
|
|
22
|
+
about 2,995 trials without one. Across the 1,000,000 users this claim applies to, that leaves up to 58,155 not
|
|
23
|
+
ruled out. [ABSOLUTE_UNDERPOWERED]
|
|
20
24
|
```
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
The honest version goes in, and it carries its consequence wherever it's read:
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
```text
|
|
29
|
+
active claim · unchecked · 1 independent line of support · … · 0 of 50 = at most 5.8% at 95%, up to 58,155 of 1,000,000 not ruled out
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## The arithmetic of never
|
|
33
|
+
|
|
34
|
+
"Never" is the most expensive word in research, because everything built on it inherits it. Zero failures in *n*
|
|
35
|
+
trials doesn't mean a rate of zero. It means a rate below 1 − 0.05^(1/*n*), about 3/*n*, at 95% confidence. HypGraph
|
|
36
|
+
holds every claim to that:
|
|
37
|
+
|
|
38
|
+
| The claim says | Refused as | Because |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| "never leaks", from 0 of 50 | `ABSOLUTE_UNDERPOWERED` | it could still be 5.8%, up to 58,155 of a million users |
|
|
41
|
+
| "never leaks", from 0 of 3,000, without saying 3,000 | `ABSOLUTE_HIDES_DENOMINATOR` | readers hear "never", but it means "at most 1 in 1,000" |
|
|
42
|
+
| "eliminates hallucinations entirely" | `ABSOLUTE_WITHOUT_COUNT` | nothing was counted |
|
|
43
|
+
| "5 points better" (the counts say 2.8) | `UNBOUND_NUMBER` | the number comes from nowhere. 2.8 points, 81.2% vs 78.4% and +3.6% all pass, because they follow from the counts. |
|
|
44
|
+
| "significantly better", counts 812/1,000 vs 800/1,000 | `SIGNIFICANCE_NOT_SHOWN` | the record runs the test: p = 0.5 |
|
|
45
|
+
| "prompt format has no effect" | `EXCLUSION_WITHOUT_POWER` | at 2,000 items a 3.6-point effect would usually go unseen |
|
|
46
|
+
| "longer prompts cause the gain" | `CAUSAL_WITHOUT_INTERVENTION` | no experiment intervened |
|
|
47
|
+
| "outperforms the baseline", no numbers | `COMPARATIVE_WITHOUT_COMPARISON` | only one side was measured |
|
|
48
|
+
|
|
49
|
+
Every refusal has a stable code, the arithmetic, and the sentence that *would* be honest, so an agent can repair a
|
|
50
|
+
claim in one step. `hypgraph bound 0 50 --exposure 1e6` (or the MCP tool `bound`) answers "what does my count
|
|
51
|
+
actually support?" before anyone writes the word.
|
|
52
|
+
|
|
53
|
+
And when something does fall, the record says what falls with it:
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
$ hypgraph withdraw CL1 --why "the held-out set leaked into training"
|
|
57
|
+
CL1 — withdrawn claim · …
|
|
58
|
+
⚠ 2 nodes rest on CL1: 1 decision (D1); 1 claim (CL2) — now AT RISK
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Derived, never asserted
|
|
62
|
+
|
|
63
|
+
Nothing in the record is ever *set* as known. How well each claim is known is **derived on every read**:
|
|
26
64
|
|
|
27
65
|
- **reviewed, and which version?** Only named reviewers count, and never on their own work. A revised claim goes back
|
|
28
66
|
to unchecked.
|
|
@@ -46,7 +84,7 @@ hypgraph skill --install # +
|
|
|
46
84
|
The server writes as one author, fixed when it starts. The agent can't pass another name or write as your job runner,
|
|
47
85
|
and its verdicts count only if you name it as a reviewer. Tools: `overview`, `find`, `show`, `start_investigation`,
|
|
48
86
|
`add`, `link`, `revise`, `withdraw`, `retract_link`, `review`, `next_experiments`, `work_queue`, `claim_work`,
|
|
49
|
-
`register_run`, `report`, `verify`, `schema`. The method is in [AGENTS.md](https://github.com/voodoomods/hypgraph/blob/main/AGENTS.md); the short version is
|
|
87
|
+
`register_run`, `bound`, `report`, `verify`, `schema`. The method is in [AGENTS.md](https://github.com/voodoomods/hypgraph/blob/main/AGENTS.md); the short version is
|
|
50
88
|
[llms.txt](https://hypgraph.com/llms.txt).
|
|
51
89
|
|
|
52
90
|
## Wire it into your system
|
|
@@ -104,6 +142,10 @@ standing takes 0.09 s, reading one node 0.3 ms, and a write about 10 ms, mostly
|
|
|
104
142
|
costs what it touches: cached standing is kept for every node the write can't affect, and a randomized suite checks
|
|
105
143
|
that against a full rebuild.
|
|
106
144
|
|
|
145
|
+
## Made by
|
|
146
|
+
|
|
147
|
+
HypGraph is made by **Nicolas Houghtaling** at **[VoodooMods LLC](https://github.com/voodoomods)**.
|
|
148
|
+
|
|
107
149
|
## License
|
|
108
150
|
|
|
109
151
|
Code: [Apache-2.0](https://github.com/voodoomods/hypgraph/blob/main/LICENSE). The record format ([docs/spec.md](https://github.com/voodoomods/hypgraph/blob/main/docs/spec.md)) and the docs: CC BY 4.0. Cite it with
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# The HypGraph record format — `hypgraph/1`
|
|
2
2
|
|
|
3
|
-
Status: draft
|
|
3
|
+
Status: draft 2 (HypGraph 0.2). Licence: CC BY 4.0. This page is enough to write another implementation, a
|
|
4
4
|
verifier or a viewer.
|
|
5
5
|
|
|
6
6
|
## 1. Model
|
|
@@ -23,7 +23,7 @@ correction is a new row, never an edited one.
|
|
|
23
23
|
| `investigation` | INV | **title**\*, **objective**\*, success_criteria, scope, state, reviewers, constants, strict_claims, keywords, projects, doi, note, legacy_case | The study: an objective, its scope, who reviews it. Every other node belongs to one. |
|
|
24
24
|
| `question` | Q | **text**\*, why | Something you want to know. |
|
|
25
25
|
| `hypothesis` | H | **statement**\*, assumptions, **predictions**\*, distinguishing, open_questions | A possible answer, with the predictions that would show it wrong. |
|
|
26
|
-
| `claim` | CL | **statement**\*, scope, limitations, kind, measurements, evidence_note, legacy | What you assert is known, with its scope and its numbers bound to results. |
|
|
26
|
+
| `claim` | CL | **statement**\*, scope, limitations, kind, measurements, evidence_note, exposure, exposure_unit, legacy | What you assert is known, with its scope and its numbers bound to results. |
|
|
27
27
|
| `experiment` | X | **aim**\*, **protocol**\*, controls, **success_criteria**\*, method, budget, power_check, cost_minutes, seed | A planned test: aim, protocol, controls, success criteria, and what each hypothesis expects. |
|
|
28
28
|
| `run` | RUN | **kind**\*, job_id, name, state, code, inputs, outputs, args, config, seed, env, started, finished, exit_code, log_sha256, note | One execution: code, inputs and outputs hashed, seed, state. `kind=lab` only from an instrument. |
|
|
29
29
|
| `result` | RS | **summary**\*, kind, outcome, values, expected, limitations, power, evidence_note, legacy | What a run (or an observation, or a citation) found: values, outcome, power. |
|
|
@@ -158,14 +158,36 @@ Implementations must derive these, never store them:
|
|
|
158
158
|
|
|
159
159
|
## 7. Claim checks
|
|
160
160
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
161
|
+
A claim is checked before it enters the record. Each failed rule is reported with a stable code, a message that does
|
|
162
|
+
the arithmetic, a suggested fix, and the words that triggered it. Checks are skipped for the operator and importer,
|
|
163
|
+
and in an investigation with `strict_claims: false`. Leads and conventions skip rules 7–9.
|
|
164
|
+
|
|
165
|
+
**Arithmetic.** For a count of k in n trials, the 95% interval is the Wilson score interval. At k = 0 (or k = n) it is
|
|
166
|
+
the exact one-sided bound 1 − 0.05^(1/n), the "rule of three" (≈ 3/n). "Never, in n trials" means at most that rate,
|
|
167
|
+
and never zero. Two counts are compared with Newcombe's hybrid score interval and a pooled two-proportion z-test. The
|
|
168
|
+
smallest detectable difference uses 80% power at two-sided α = 0.05.
|
|
169
|
+
|
|
170
|
+
| # | Code | Refused when |
|
|
171
|
+
|---|---|---|
|
|
172
|
+
| 1 | `SCOPE_MISSING` | a finding or exclusion has a scope shorter than 10 characters |
|
|
173
|
+
| 2 | `EVIDENCE_MISSING` | a finding, exclusion or inconclusive claim has no supporting node |
|
|
174
|
+
| 3 | `MEASUREMENT_MALFORMED` / `MEASUREMENT_UNKNOWN_FIELD` / `MEASUREMENT_MISMATCH` | a measurement doesn't name a result and a key present in its `values`, or states a `value` / `k` / `n` different from the result's at the precision written (a fraction ≤ 1 may be written as a percentage) |
|
|
175
|
+
| 4 | `UNBOUND_NUMBER` | a number in the statement (digits, or the words two to twenty; digits in quotes are names) is not one of: a bound measurement's numbers; for a count, its rate, complement or n − k; for any two measurements, their difference, ratios, relative change or sum; the scope's numbers; the investigation's `constants`; or the conventions 95 / 99 / 90 / 80 / 0.05 / 0.01 when the statement speaks of intervals, bounds, confidence, power or significance. *Statistical* quantities (a rate's 95% bounds; for two counts the difference interval, p-value and detectable difference) count only when written to at least one decimal place. |
|
|
176
|
+
| 5 | `ABSOLUTE_WITHOUT_COUNT` | an absolute word (never, always, all, every, none, impossible, cannot, proves, certainly, guaranteed, eliminates, entirely, completely, universally, consistently, perfect, solves, zero, 100%, …) with no bound count where k is 0 or n |
|
|
177
|
+
| 5a | `ABSOLUTE_UNRELATED_COUNT` | the counts with k ∈ {0, n} share no content word with the statement in their name or key |
|
|
178
|
+
| 5b | `ABSOLUTE_UNDERPOWERED` | the 95% bound on the opposite rate is above 5%. The message gives the honest wording and the trials needed for a 1-in-1,000 bound. |
|
|
179
|
+
| 5c | `ABSOLUTE_HIDES_DENOMINATOR` | the count is enough, but n appears in neither the statement nor the scope |
|
|
180
|
+
| 6 | `CONVENTION_HEDGED` | a `convention` hedges (could, might, suggests, consistent with, …) |
|
|
181
|
+
| 7 | `COMPARATIVE_WITHOUT_COMPARISON` | a comparative (better, beats, outperforms, higher than, improves, exceeds, …) with fewer than two measured sides, no bound p-value or interval, and no supporting claim that binds two sides |
|
|
182
|
+
| 8 | `SIGNIFICANCE_WITHOUT_TEST` / `SIGNIFICANCE_NOT_SHOWN` | "significantly" / "statistically" with no bound p-value and fewer than two counts, or when the bound p-value, or the test the record runs on the first two counts, is not below 0.05 |
|
|
183
|
+
| 9 | `CAUSAL_WITHOUT_INTERVENTION` | a causal word (causes, leads to, results in, drives, due to, because of, responsible for, …) when no supporting result was produced by a run that `executes` an experiment |
|
|
184
|
+
| 10 | `EXCLUSION_WITHOUT_POWER` | `kind: exclusion`, or wording that says an effect is absent (no effect, no difference, makes no difference, does not affect, rules out, ineffective, …) in a finding, without a supporting result with `power: demonstrated` or one produced by a run of an experiment with a `power_check`. With two counts, the message gives the smallest detectable difference. |
|
|
185
|
+
|
|
186
|
+
**Exposure.** A claim may set `exposure` (how many uses, users or units it will be applied to) and `exposure_unit`.
|
|
187
|
+
Absolute refusals then state how many failures the bound leaves unruled out at that scale. An accepted claim's
|
|
188
|
+
standing carries `bounds` (per count: k, n, rate, lo, hi and, with exposure, `unruled_out`), its sentence reads
|
|
189
|
+
"'never' = at most 0.1% (0 of 3,000, 95%), up to 998 of 1,000,000 not ruled out", and a "significantly" claim carries
|
|
190
|
+
`test` (the difference, its interval and p).
|
|
191
|
+
|
|
192
|
+
**Blast radius.** Withdrawing a node, or a verdict that makes it fall, returns `blast_radius`: every node resting on it
|
|
193
|
+
by type, with claims and decisions named and, if a spend meter is connected, the cost of the work behind them.
|
|
@@ -8,9 +8,10 @@ dynamic = ["version"]
|
|
|
8
8
|
description = "The evidence layer for AI research agents: a hash-chained research record that checks every claim as it is written and derives how well each is known."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache-2.0"
|
|
11
|
-
license-files = ["LICENSE"]
|
|
11
|
+
license-files = ["LICENSE", "NOTICE"]
|
|
12
12
|
requires-python = ">=3.10"
|
|
13
|
-
authors = [{ name = "Nicolas Houghtaling" }]
|
|
13
|
+
authors = [{ name = "Nicolas Houghtaling" }, { name = "VoodooMods LLC" }]
|
|
14
|
+
maintainers = [{ name = "VoodooMods LLC" }]
|
|
14
15
|
keywords = ["ai-agents", "mcp", "agent-skills", "research", "provenance", "reproducibility", "evaluation", "hypothesis"]
|
|
15
16
|
classifiers = [
|
|
16
17
|
"Development Status :: 3 - Alpha",
|
|
@@ -45,7 +46,7 @@ path = "src/hypgraph/__init__.py"
|
|
|
45
46
|
packages = ["src/hypgraph"]
|
|
46
47
|
|
|
47
48
|
[tool.hatch.build.targets.sdist]
|
|
48
|
-
include = ["src/hypgraph", "tests", "docs", "README.md", "LICENSE", "CITATION.cff", "AGENTS.md"]
|
|
49
|
+
include = ["src/hypgraph", "tests", "docs", "README.md", "LICENSE", "NOTICE", "CITATION.cff", "AGENTS.md", "CHANGELOG.md"]
|
|
49
50
|
|
|
50
51
|
[tool.pytest.ini_options]
|
|
51
52
|
testpaths = ["tests", "src/hypgraph/__init__.py"]
|
|
@@ -16,7 +16,7 @@ Standing is derived on every read, never stored; every write is an event in a SH
|
|
|
16
16
|
their numbers; reviews pin versions; independence is counted, not assumed. See https://hypgraph.com.
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
|
-
__version__ = "0.
|
|
19
|
+
__version__ = "0.2.0"
|
|
20
20
|
|
|
21
21
|
from .bundle import verify_bundle # noqa: E402
|
|
22
22
|
from .graph import Author, Graph, GraphError, file_sha256 # noqa: E402
|