hypgraph 0.7.9__tar.gz → 0.7.10__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.7.9 → hypgraph-0.7.10}/CHANGELOG.md +20 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/PKG-INFO +1 -1
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/__init__.py +1 -1
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/blind.py +8 -7
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/mcp.py +5 -3
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/schema.py +4 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/ui/hypgraph.css +2 -1
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_blind.py +46 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/.gitignore +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/AGENTS.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/CITATION.cff +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/DISCLAIMER.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/LICENSE +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/NOTICE +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/README.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/docs/PLAN.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/docs/decisions/ADR-001-token-bound-authors.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/docs/decisions/ADR-002-governance-profiles.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/docs/profile-workflows-plan.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/docs/review-2026-10-24.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/docs/site-plan.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/docs/spec.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/docs/ui-plan.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/docs/workflows/README.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/docs/workflows/knowledge.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/docs/workflows/optimization.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/docs/workflows/scientific.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/docs/workflows/software.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/docs/workflows/trading.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/pyproject.toml +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/__main__.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/bundle.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/checks.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/cli.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/coord.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/demos/__init__.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/demos/broad_street.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/derive.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/graph.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/language.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/plan.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/policy.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/profiles.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/references.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/refusals.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/report_check.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/server.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/skill/SKILL.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/stats.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/store.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/ui/__init__.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/ui/atlas.css +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/ui/atlas.js +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/ui/hypgraph.js +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/ui/hypgraph.svg +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/ui/index.html +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/ui/vendor/LICENSES.md +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/ui/vendor/cose-base.js +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/ui/vendor/cytoscape-fcose.js +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/ui/vendor/cytoscape.min.js +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/ui/vendor/layout-base.js +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/src/hypgraph/workflow.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_accept_work_kind.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_bound_support.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_bundle_telemetry.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_cancel_releases_lease.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_cited_and_failed_support.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_coord.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_d10.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_engine.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_engine_fixes.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_incremental.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_link_translate.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_log_and_check.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_measure_questions.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_opposed_answers.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_option_lead.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_order_detail.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_profiles.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_profiles_041.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_questions_not_assertions.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_references.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_refusal_friction.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_refusal_results.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_refusals.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_relation_words.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_report_answers.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_rerunnable.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_restates_scale.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_server_auth.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_server_hosts.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_shape_refusals.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_stats_not_backtests.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_stats_values.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_surfaces.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_telemetry_stream.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_ui_app.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_ui_engine.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_uncorrected_effect.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_unnamed_inputs.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_versions_not_figures.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_vocabulary_friction.py +0 -0
- {hypgraph-0.7.9 → hypgraph-0.7.10}/tests/test_workflows.py +0 -0
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.10 — 2026-10-30: fixes from the first live blind run
|
|
4
|
+
|
|
5
|
+
Claude led a question on a HypMesh and issued a blind order; Codex took the order through its seat and counted the
|
|
6
|
+
primes below 1,000,000 whose digits sum to 23 with its own sieve. The record marked its result written blind and
|
|
7
|
+
agreeing blind with Claude's, and nothing sealed reached Codex. Four fixes from that run and a phone-width check:
|
|
8
|
+
|
|
9
|
+
- **Investigations are part of the problem statement a blind checker reads.** Only the order's own investigation
|
|
10
|
+
and the curators' were. A lead whose framing lived in a second investigation had it sealed, the numbers that
|
|
11
|
+
define the problem (1,000,000; 23) read as secrets, and an honest blind order was refused. Questions and
|
|
12
|
+
investigations say what is being found out; don't put answers in them.
|
|
13
|
+
- **`my_work` without an investigation lists your orders in every investigation.** It asked "which
|
|
14
|
+
investigation?" when a record held two, and the seat's first call failed.
|
|
15
|
+
- **`produced_by`, `generated_by`, `output_of`, `executed_by` and `tested_by` are read as the relation they
|
|
16
|
+
invert.** The node types fix the direction, so the link is turned round. Codex's first result was refused for
|
|
17
|
+
`produced_by`.
|
|
18
|
+
- **On a phone, every tab of the embedded app can be reached.** The embed's `overflow: visible` beat the narrow
|
|
19
|
+
rule that makes the nav a scrolling strip. On hypdmz.com at 375 px, four of the eight tabs (Evidence, Work
|
|
20
|
+
orders, Audit log, Report) sat past the edge with no way to scroll to them. The nav now scrolls, and the embed
|
|
21
|
+
clips sideways, so the closed drawer can't widen a host page that doesn't clip it.
|
|
22
|
+
|
|
3
23
|
## 0.7.9 — 2026-10-30: blind work orders
|
|
4
24
|
|
|
5
25
|
- **A checker can measure without seeing the answer it checks.** `issue_work(..., blind=True)` (MCP `issue_work`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: hypgraph
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.10
|
|
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/
|
|
@@ -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.7.
|
|
19
|
+
__version__ = "0.7.10"
|
|
20
20
|
|
|
21
21
|
from .bundle import verify_bundle # noqa: E402
|
|
22
22
|
from .graph import Author, Graph, GraphError, file_sha256 # noqa: E402
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Blind work orders: a checker measures without seeing the answer it is checking.
|
|
3
3
|
|
|
4
4
|
A work order issued with ``blind=True`` seals the record from its assignee until the order is returned. While it is
|
|
5
|
-
open, the assignee reads the problem statement (the
|
|
6
|
-
|
|
5
|
+
open, the assignee reads the problem statement (the investigations and questions: what is being found out, never what
|
|
6
|
+
was found) and its own order; everything else other authors wrote — hypotheses and their predictions, results,
|
|
7
7
|
claims, reviews, runs and their code, sources, other orders, other teams' attempts — is sealed: shown as a placeholder,
|
|
8
8
|
left out of search, its numbers scrubbed wherever else they appear.
|
|
9
9
|
|
|
@@ -39,7 +39,10 @@ _NUM = re.compile(r"(?<![\w.,])-?(?:\d{1,3}(?:,\d{3})+|\d+)(?:\.\d+)?(?![\w])")
|
|
|
39
39
|
READ_ROUTES = frozenset({"investigations", "orders", "order", "resolve", "subgraph", "node", "why", "impact",
|
|
40
40
|
"neighborhood", "search", "events", "verify", "profiles", "profile", "references"})
|
|
41
41
|
POST_ROUTES = frozenset({"check_work"})
|
|
42
|
-
|
|
42
|
+
# The problem statement every reader keeps. An investigation says what is being found out; a lead whose framing
|
|
43
|
+
# lived in a second investigation had it sealed, and the numbers that define the problem (1,000,000; 23) then read
|
|
44
|
+
# as secrets, so an honest blind order was refused (first live run, 2026-10-30). Don't put answers in them.
|
|
45
|
+
VISIBLE_TYPES = frozenset({"question", "investigation"})
|
|
43
46
|
# A blind order asks for a measurement. A review or a report has to read what it judges.
|
|
44
47
|
BLIND_PREDICATES = frozenset({"run_registered", "result_exists", "claim_made", "within_budget"})
|
|
45
48
|
SEALED = "sealed"
|
|
@@ -228,10 +231,8 @@ def _derived(s: D.Snap, x: str, limit: int = 60) -> set[str]:
|
|
|
228
231
|
|
|
229
232
|
# ── what is sealed, and from whom ──────────────────────────────────
|
|
230
233
|
def public(s: D.Snap, n: dict, w: Window) -> bool:
|
|
231
|
-
"""The problem statement every reader keeps: questions
|
|
232
|
-
|
|
233
|
-
return (n["type"] in VISIBLE_TYPES
|
|
234
|
-
or (n["type"] == "investigation" and (n["created_by"] in s.policy.curators or n["id"] == w.inv)))
|
|
234
|
+
"""The problem statement every reader keeps: questions and investigations (the order chain is kept apart)."""
|
|
235
|
+
return n["type"] in VISIBLE_TYPES
|
|
235
236
|
|
|
236
237
|
|
|
237
238
|
def scope(s: D.Snap, w: Window) -> set[str]:
|
|
@@ -551,10 +551,12 @@ def build(graph: Graph | str, author: Optional[str] = None, files_root: str | No
|
|
|
551
551
|
|
|
552
552
|
@tool
|
|
553
553
|
def my_work(investigation: str = "") -> str:
|
|
554
|
-
"""Your open work orders, each with its full text
|
|
555
|
-
it waits for acceptance, and comes back as a new order if it is
|
|
554
|
+
"""Your open work orders, each with its full text, in every investigation unless you name one. An order you
|
|
555
|
+
have returned is no longer yours to work: it waits for acceptance, and comes back as a new order if it is
|
|
556
|
+
reworked."""
|
|
556
557
|
try:
|
|
557
|
-
|
|
558
|
+
invs = [g.resolve(investigation)] if investigation else [i["id"] for i in g.investigations()]
|
|
559
|
+
allmine = [o for inv in invs for o in g.orders(inv) if o["assignee"] == me]
|
|
558
560
|
except (GraphError, KeyError) as e:
|
|
559
561
|
fail(e)
|
|
560
562
|
mine = [o for o in allmine if o["status"] in ("open", "overdue")]
|
|
@@ -148,6 +148,10 @@ REL_SYNONYMS: dict[str, str] = {
|
|
|
148
148
|
"correct": "corrects", "corrected": "corrects", "require": "requires", "required": "requires",
|
|
149
149
|
"depends_on": "requires", "part": "part_of", "belongs_to": "part_of", "motivated": "motivated_by",
|
|
150
150
|
"rests": "rests_on", "works": "works_on", "blocked": "blocked_by", "settle": "settles", "settled": "settles",
|
|
151
|
+
# inverses whose node types fix the direction (a result can't produce a run): turned round by _orient. Not
|
|
152
|
+
# supported_by / challenged_by: a claim can sit at either end of those.
|
|
153
|
+
"produced_by": "produced", "generated_by": "produced", "output_of": "produced", "executed_by": "executes",
|
|
154
|
+
"tested_by": "tests",
|
|
151
155
|
}
|
|
152
156
|
|
|
153
157
|
SYNONYMS: dict[tuple[str, str], dict[str, str]] = {
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
.hg.hg-embed .hg-app { height: auto; grid-template-rows: 52px auto; }
|
|
93
93
|
.hg.hg-embed .hg-main, .hg.hg-embed .hg-nav { overflow: visible; }
|
|
94
94
|
.hg.hg-embed .feed { max-height: none; overflow: visible; }
|
|
95
|
-
.hg.hg-embed { overflow: visible; }
|
|
95
|
+
.hg.hg-embed { overflow-x: clip; overflow-y: visible; } /* the closed drawer sits off to the right: never widen the page */
|
|
96
96
|
.hg .kpi { padding: 12px 14px; } .hg .kpi .k { color: var(--ink2); font-size: 12px; }
|
|
97
97
|
.hg .kpi .v { font-size: 22px; font-weight: 650; letter-spacing: -.02em; margin-top: 2px; font-variant-numeric: tabular-nums; }
|
|
98
98
|
.hg .kpi .s { color: var(--ink3); font-size: 11.5px; margin-top: 2px; }
|
|
@@ -247,6 +247,7 @@
|
|
|
247
247
|
.hg .hg-nav button { width: auto; flex: none; white-space: nowrap; padding: 6px 10px; }
|
|
248
248
|
.hg .hg-nav .n { margin-left: 4px; } .hg .hg-nav .inv .s { display: none; }
|
|
249
249
|
.hg .hg-main { padding: 16px 16px 32px; }
|
|
250
|
+
.hg.hg-embed .hg-nav { overflow-x: auto; overflow-y: hidden; } /* beats the embed's overflow: visible: every tab reachable */
|
|
250
251
|
.hg .trace .tr { grid-template-columns: minmax(90px, 40%) minmax(0, 1fr) 48px; }
|
|
251
252
|
}
|
|
252
253
|
@media (prefers-reduced-motion: reduce) { .hg *, .hg *::before { animation: none !important; transition: none !important; } }
|
|
@@ -166,3 +166,49 @@ def test_mcp_seat_holding_a_blind_order(env, tmp_path):
|
|
|
166
166
|
ov = text(await c.call_tool("overview", {"investigation": inv}))
|
|
167
167
|
assert "Primes below" in ov
|
|
168
168
|
asyncio.run(go())
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
# ── from the first live run (Claude leading, Codex checking on HypMesh, 2026-10-30) ──
|
|
172
|
+
def test_a_framing_investigation_is_the_problem_statement_and_my_work_finds_the_order():
|
|
173
|
+
fastmcp = pytest.importorskip("fastmcp")
|
|
174
|
+
from hypgraph.mcp import build
|
|
175
|
+
g = Graph(clock=Clock())
|
|
176
|
+
lead = g.author("lead")
|
|
177
|
+
frame = lead.investigation("The question", "Count the primes below 1,000,000 whose digits sum to 23.")["id"]
|
|
178
|
+
inv = lead.investigation("Lead's attempt", "Count them, and have the count checked blind.")["id"]
|
|
179
|
+
h = lead.add("hypothesis", inv, statement="There are 5503 primes below 1,000,000 whose digits sum to 23.",
|
|
180
|
+
predictions=["an independent count finds 5503"])["id"]
|
|
181
|
+
o = g.issue_work(author="lead", inv=inv, target=h, assignee="checker", blind=True,
|
|
182
|
+
objective="Count the primes below 1,000,000 whose digits sum to 23, with your own code.")
|
|
183
|
+
v = B.view_for_author(g.snapshot(), "checker")
|
|
184
|
+
assert frame not in v.hide and h in v.hide and "5503" in v.secrets and "23" not in v.secrets
|
|
185
|
+
with pytest.raises(GraphError, match="quotes what it would seal: 5503"):
|
|
186
|
+
h2 = lead.add("hypothesis", inv, statement="Most of them are below 900,000.",
|
|
187
|
+
predictions=["more than half fall below 900,000"])["id"]
|
|
188
|
+
g.issue_work(author="lead", inv=inv, target=h2, assignee="other", blind=True,
|
|
189
|
+
objective="Check that the count is 5503.")
|
|
190
|
+
|
|
191
|
+
async def go():
|
|
192
|
+
async with fastmcp.Client(build(g, author="checker")) as c:
|
|
193
|
+
r = await c.call_tool("my_work", {}) # no investigation named, two in the record
|
|
194
|
+
assert o["code"] in r.content[0].text and "BLIND" in r.content[0].text
|
|
195
|
+
asyncio.run(go())
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def test_inverse_relation_words_are_turned_round(env):
|
|
199
|
+
g, inv, h1, rs1 = env
|
|
200
|
+
a = g.author("lead")
|
|
201
|
+
run = a.add("run", inv, kind="agent", name="second sieve", state="succeeded")["id"]
|
|
202
|
+
rs = a.add("result", inv, summary="The second sieve counts 1230 primes below 10,000; the largest is 9967.",
|
|
203
|
+
outcome="positive", values={"count": 1230, "largest": 9967},
|
|
204
|
+
links=[{"rel": "produced_by", "to": run}])
|
|
205
|
+
assert any(e["rel"] == "produced" and e["src"] == run for e in rs["in"])
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def test_the_embedded_app_never_widens_its_page():
|
|
209
|
+
from pathlib import Path
|
|
210
|
+
import hypgraph.ui as ui
|
|
211
|
+
css = (Path(ui.__file__).parent / "hypgraph.css").read_text(encoding="utf-8")
|
|
212
|
+
assert ".hg.hg-embed { overflow-x: clip;" in css
|
|
213
|
+
narrow = css.split("@container hg (max-width: 760px)", 1)[1].split("\n}\n", 1)[0]
|
|
214
|
+
assert ".hg.hg-embed .hg-nav { overflow-x: auto;" in narrow
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|