hypgraph 0.8.3__tar.gz → 0.8.5__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.8.3 → hypgraph-0.8.5}/CHANGELOG.md +38 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/PKG-INFO +1 -1
- {hypgraph-0.8.3 → hypgraph-0.8.5}/docs/PLAN.md +1 -1
- {hypgraph-0.8.3 → hypgraph-0.8.5}/docs/RELEASE-READINESS.md +12 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/docs/ui-plan.md +3 -2
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/__init__.py +1 -1
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/checks.py +14 -3
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/report_check.py +26 -3
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/ui/hypgraph.css +15 -1
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/ui/hypgraph.i18n.js +68 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/ui/hypgraph.js +229 -27
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_i18n.py +2 -1
- hypgraph-0.8.5/tests/test_report_significance_denied.py +62 -0
- hypgraph-0.8.5/tests/test_statement_slots.py +60 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_ui_app.py +2 -2
- hypgraph-0.8.5/tests/test_ui_sources_focus.py +138 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_versions_not_figures.py +8 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/.gitignore +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/AGENTS.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/CITATION.cff +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/DISCLAIMER.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/LICENSE +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/NOTICE +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/README.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/docs/decisions/ADR-001-token-bound-authors.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/docs/decisions/ADR-002-governance-profiles.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/docs/profile-workflows-plan.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/docs/review-2026-10-24.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/docs/site-plan.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/docs/spec.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/docs/verification.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/docs/workflows/README.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/docs/workflows/knowledge.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/docs/workflows/optimization.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/docs/workflows/scientific.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/docs/workflows/software.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/docs/workflows/trading.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/examples/frameworks/README.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/pyproject.toml +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/__main__.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/assertions.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/blind.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/bundle.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/cli.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/coord.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/demos/__init__.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/demos/broad_street.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/demos/dispute.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/demos/linked.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/derive.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/graph.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/language.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/mcp.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/plan.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/policy.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/profiles.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/references.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/refusals.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/schema.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/server.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/skill/SKILL.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/stats.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/store.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/ui/__init__.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/ui/atlas.css +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/ui/atlas.js +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/ui/hypgraph.svg +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/ui/index.html +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/ui/vendor/LICENSES.md +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/ui/vendor/cose-base.js +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/ui/vendor/cytoscape-fcose.js +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/ui/vendor/cytoscape.min.js +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/ui/vendor/layout-base.js +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/src/hypgraph/workflow.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_accept_work_kind.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_anchoring.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_assertions.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_blind.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_blind_oracles.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_borrowed_words.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_bound_support.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_bundle_telemetry.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_cancel_releases_lease.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_cited_and_failed_support.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_contradictions.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_coord.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_counts_that_bear.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_d10.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_demo_dispute.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_direction_and_units.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_engine.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_engine_fixes.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_figure_said_twice.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_framework_examples.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_incremental.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_link_translate.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_linked_records.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_log_and_check.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_measure_questions.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_next_order.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_opposed_answers.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_option_lead.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_order_detail.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_profiles.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_profiles_041.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_quantifiers_and_identity.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_questions_not_assertions.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_quoted_counterexample.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_references.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_refusal_friction.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_refusal_results.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_refusals.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_relation_words.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_report_answers.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_rerunnable.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_restates_scale.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_server_auth.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_server_hosts.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_shape_refusals.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_stats_not_backtests.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_stats_values.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_surfaces.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_telemetry_stream.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_trust_boundary.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_typed_audits.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_ui_engine.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_uncorrected_effect.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_unnamed_inputs.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_verify_complete.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_verify_lifecycle.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_verify_scope.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_verify_scoped_views.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_verify_trust.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_verify_views.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_vocabulary_friction.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_what_a_count_is_of.py +0 -0
- {hypgraph-0.8.3 → hypgraph-0.8.5}/tests/test_workflows.py +0 -0
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 0.8.5 — 2026-11-06: fewer false refusals
|
|
6
|
+
|
|
7
|
+
- A date a source writes as an ordinal is in the source: "the 14th of June 1887" accounts for "14 June 1887". It was refused as an unbound number, and a seat ended up with a claim saying the bridge opened "on a date".
|
|
8
|
+
- A statement with an unfilled slot is refused as STATEMENT_EMPTY: a template's `{date}`, or a variable's name where its value belongs (`accuracy = A_easy_acc`). Inline code is not read for this.
|
|
9
|
+
- **A report that denies significance isn't refused for it.** `REPORT_SIGNIFICANCE_UNBACKED` is a warning, not an
|
|
10
|
+
error, when the sentence denies the test: emphasis ("*not* significantly"), "no statistically significant difference",
|
|
11
|
+
"does not support a statistically significant advantage". Before, only the bare "not significant" counted, so an
|
|
12
|
+
honest negative was refused and small models gave up on the report. A sentence that also asserts significance
|
|
13
|
+
("not only significantly", "B is not significantly cheaper, but A is significantly better") stays an error.
|
|
14
|
+
- **A named p-value carries the test.** A result whose values name one (`p`, `p_value`, `pvalue`, `p_exact`, …) backs a
|
|
15
|
+
significance word, and so does a claim whose statement gives a p-value or that rests on such a result. Before, only a
|
|
16
|
+
value with a `p` field did, so citing the claim that held the test was refused.
|
|
17
|
+
- **A word and a figure say something.** `STATEMENT_EMPTY` no longer fires on "A's accuracy is 0.814."; placeholders
|
|
18
|
+
still do, with a number beside them or not.
|
|
19
|
+
|
|
20
|
+
## 0.8.4 — 2026-11-04: sources in the sidebar; a focus on one node's part of the graph
|
|
21
|
+
|
|
22
|
+
- **A Sources view in the Explorer's sidebar.** Everything an investigation cites, in one place: outside literature
|
|
23
|
+
(citation, kind, DOI and URL as links, the passage as the author quoted it, when it was retrieved) and pinned
|
|
24
|
+
references into other records (the linked-records table, moved here from under the graph), each with the claims,
|
|
25
|
+
results, hypotheses and experiments that cite it and their standing. Filters for sources cited by nothing, sources
|
|
26
|
+
with no DOI or URL, and sources that fell (withdrawn or superseded) while live nodes still cite them. CSV and BibTeX
|
|
27
|
+
export. The view says what the record checked: a pinned reference's version hash; for outside literature, nothing.
|
|
28
|
+
A DOI or URL in a node's fields now opens where it points. Key `6`; the later views move to `7`–`9`.
|
|
29
|
+
- **A focus on one node's part of the graph.** From a node's details, "Show what it rests on" (the engine's `why`
|
|
30
|
+
walk), "Show what rests on it" (its mirror: everything that rests on the node by a link, the claims that cite a
|
|
31
|
+
source included; what would *fall* with it is the narrower engine walk the drawer shows under "If it fell") or
|
|
32
|
+
"Show its neighbours" (depth 1–3) draws only that part of the record, with a bar naming the node, the lens, the
|
|
33
|
+
depth and how many nodes are shown; the type chips still apply, the centre is always drawn, a focus of one or two
|
|
34
|
+
nodes is drawn at a readable size rather than filling the pane, Esc clears it. Under Graph, the sidebar lists the
|
|
35
|
+
records this one pins (the subgraphs, each a jump to that record in the linked graph) and the investigation's
|
|
36
|
+
questions, each a focus on the question, what answers or addresses it and what that rests on. The focus is in the link
|
|
37
|
+
(`#view=graph&focus=CL7&lens=why`, "Copy link" on the bar), so a review comment can point at exactly the subgraph it
|
|
38
|
+
means, and the JSON export of a focused graph is that part of the record with the focus named. `HypGraph.focusIds`
|
|
39
|
+
computes the set from the record's own edges, so a bundle and a server agree (`tests/test_ui_sources_focus.py`).
|
|
40
|
+
|
|
3
41
|
## 0.8.3 — 2026-11-03: the next-experiments view in a stable order
|
|
4
42
|
|
|
5
43
|
- **`verify --standing` no longer fails on a sound bundle with two or more untested hypotheses.** `next_experiments`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: hypgraph
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.5
|
|
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/
|
|
@@ -109,7 +109,7 @@ claim's derived standing.
|
|
|
109
109
|
Multi-writer sync between graphs (bundles cover sharing), authentication (the host's job; the HTTP server binds to
|
|
110
110
|
loopback and is read-only unless started with `--writable`), and a hosted service.
|
|
111
111
|
|
|
112
|
-
## Status at 0.8.
|
|
112
|
+
## Status at 0.8.5 (2026-11-06)
|
|
113
113
|
|
|
114
114
|
All seven phases are done: the library, bundles, the server and UI, the MCP server, the website, Pegasus running on
|
|
115
115
|
the package, and releases to PyPI from tags with trusted publishing. What came after the plan, by release, is in
|
|
@@ -261,6 +261,18 @@ was taken from a changelog without being checked against the code.*
|
|
|
261
261
|
> with two or more of them when the exporting and verifying processes hashed strings differently. The list now follows
|
|
262
262
|
> the order the hypotheses were added. #109 is merged with green CI. Released as 0.8.3.
|
|
263
263
|
|
|
264
|
+
> **After 0.8.4 (2026-11-06).** Checks only, no change to the bundle format: false refusals found running HypSwarm on a
|
|
265
|
+
> small local model. A report that denies significance is warned, not refused; a named p-value carries the test; a word
|
|
266
|
+
> and a figure are a statement, and an unfilled slot isn't; an ordinal in a source accounts for the number. Tests:
|
|
267
|
+
> `tests/test_report_significance_denied.py`, `tests/test_statement_slots.py`, `tests/test_versions_not_figures.py`.
|
|
268
|
+
> #113 is merged with green CI. Released as 0.8.5.
|
|
269
|
+
|
|
270
|
+
> **After 0.8.3 (2026-11-04).** Explorer only, no change to the engine, the checks or the bundle format: a Sources view
|
|
271
|
+
> (what an investigation cites, with what the record did and did not check about each) and a focus on one node's part
|
|
272
|
+
> of the graph, carried in the link. The focus is computed in the browser from the record's own edges;
|
|
273
|
+
> `tests/test_ui_sources_focus.py` holds "what it rests on" and "what rests on it" to one relation read from either
|
|
274
|
+
> end. #111 is merged with green CI. Released as 0.8.4.
|
|
275
|
+
|
|
264
276
|
## Recommendation: CONDITIONAL GO
|
|
265
277
|
|
|
266
278
|
HypGraph is ready for a public developer preview once #59, #60 and #61 are merged with green CI and released as one
|
|
@@ -28,15 +28,16 @@ docs. For one release, `HypAtlas` stays as a global alias and `/atlas/` redirect
|
|
|
28
28
|
Every view uses them, and the stages, gates and report name come from the profile's workflow. A record with no
|
|
29
29
|
profile falls back to the kernel's words.
|
|
30
30
|
|
|
31
|
-
**Information architecture.** These are the
|
|
31
|
+
**Information architecture.** These are the Explorer's nine views, all driven by data the engine already derives:
|
|
32
32
|
|
|
33
33
|
| view | what it answers |
|
|
34
34
|
|---|---|
|
|
35
35
|
| **Overview** | Is this done, and is it sound? KPI tiles (settled, checked, stale, contested, work orders, spend), the completion criteria, each question's stage, recent activity |
|
|
36
36
|
| **Live** | What is the swarm doing right now? (§3) |
|
|
37
37
|
| **Pipeline** | Where is each question in the workflow, and what would move it? A swimlane of the profile's stages with each gate MET / NOT MET, its evidence and what would meet it |
|
|
38
|
-
| **Graph** | What rests on what? The graph, with profile labels, checked and stale rings, and click-through to the node |
|
|
38
|
+
| **Graph** | What rests on what? The graph, with profile labels, checked and stale rings, and click-through to the node. A focus draws one node's part of it — what it rests on, what rests on it, its neighbours to depth 3, or a question with what answers it — named in the link (`#focus=CL7&lens=why`); the sidebar lists the pinned records (the subgraphs) and the questions as focuses |
|
|
39
39
|
| **Evidence** | Every claim, result, source and decision, with its derived standing: checked, stale, contested, at risk, re-run by the instrument |
|
|
40
|
+
| **Sources** | What does this rest on outside itself? Every source the investigation cites — outside literature with its DOI, URL and the passage as quoted, and pinned references into other records with their hash checks — and what rests on each; filters for the uncited, the unlinked and the fallen-but-still-cited; CSV and BibTeX |
|
|
40
41
|
| **Work orders** | What was each seat asked to do, its predicates for done, and how it ended |
|
|
41
42
|
| **Audit log** | The append-only event log, with the hash chain re-verified on read (the badge in the top bar) |
|
|
42
43
|
| **Report** | The profile's report (Change report, Desk note, Sourced brief, …), with PDF and bundle export |
|
|
@@ -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.8.
|
|
19
|
+
__version__ = "0.8.5"
|
|
20
20
|
|
|
21
21
|
from .bundle import anchored, verify_bundle # noqa: E402
|
|
22
22
|
from .graph import Author, Graph, GraphError, file_sha256 # noqa: E402
|
|
@@ -1598,6 +1598,9 @@ def _exclusion(s: Snap, stmt: str, kind: str, support: list[str], bound: list) -
|
|
|
1598
1598
|
"effect", words=words)]
|
|
1599
1599
|
|
|
1600
1600
|
|
|
1601
|
+
_ORDINAL = re.compile(r"\b(\d+)(?:st|nd|rd|th)\b", re.I)
|
|
1602
|
+
# a value not filled in: a template's {date}, or a variable's name where its value belongs ("accuracy = A_easy_acc")
|
|
1603
|
+
_SLOT = re.compile(r"\{\s*[A-Za-z_][\w.]*\s*\}|=\s*[A-Za-z]+_[A-Za-z0-9_]*\b(?!\s*\()")
|
|
1601
1604
|
_PLACEHOLDER = re.compile(r"^\W*(?:(?:placeholder|tbd|todo|tba|n/?a|none|wip|xxx|test|claim|statement|pending|"
|
|
1602
1605
|
r"to be (?:determined|confirmed|added)|lorem ipsum)\W*)+$", re.I)
|
|
1603
1606
|
|
|
@@ -1776,13 +1779,20 @@ def claim_issues(s: Snap, body: dict, support: list[str], inv: str) -> list[Prob
|
|
|
1776
1779
|
if invb.get("strict_claims") is False:
|
|
1777
1780
|
return []
|
|
1778
1781
|
problems: list[Problem] = []
|
|
1779
|
-
|
|
1780
|
-
|
|
1782
|
+
words = len(re.findall(r"[^\W\d_]{3,}", stmt))
|
|
1783
|
+
if _PLACEHOLDER.match(_NUM.sub("", stmt)) or words < (1 if _NUM.search(stmt) else 2):
|
|
1784
|
+
# a claim written to clear a gate (studies/challenges E2: "Placeholder.", contested and left in the record);
|
|
1785
|
+
# a word and a figure do say something: "A's accuracy is 0.814."
|
|
1781
1786
|
problems.append(Problem("STATEMENT_EMPTY", "the statement says nothing: write the finding itself — what was "
|
|
1782
1787
|
"measured, on what, and what it came to"))
|
|
1783
1788
|
if kind in ("finding", "exclusion") and len(scope.strip()) < 10:
|
|
1784
1789
|
problems.append(Problem("SCOPE_MISSING", "scope: say under which conditions this holds (the data, method, "
|
|
1785
1790
|
"sample) — at least a sentence"))
|
|
1791
|
+
slot = _SLOT.search(re.sub(r"`[^`]*`", " ", stmt))
|
|
1792
|
+
if slot:
|
|
1793
|
+
# refused the date, a seat wrote "opened on {date}", and a later version "on a date" was checked as the answer
|
|
1794
|
+
problems.append(Problem("STATEMENT_EMPTY", f"the statement has an unfilled slot ({slot.group(0).strip()}): "
|
|
1795
|
+
"write the value itself", words=[slot.group(0).strip()]))
|
|
1786
1796
|
if kind == "convention" and L.HEDGE.search(stmt):
|
|
1787
1797
|
problems.append(Problem("CONVENTION_HEDGED", "a convention states agreed notation; a hedged interpretation "
|
|
1788
1798
|
"(could / suggests / consistent with) is a finding or a lead"))
|
|
@@ -1799,7 +1809,8 @@ def claim_issues(s: Snap, body: dict, support: list[str], inv: str) -> list[Prob
|
|
|
1799
1809
|
[float(c) for c in (invb.get("constants") or []) if isinstance(c, (int, float))]
|
|
1800
1810
|
for src in support: # a cited source's own text accounts for the numbers in it
|
|
1801
1811
|
sb = s.nodes[src]["body"] if s.nodes[src]["type"] == "source" else {}
|
|
1802
|
-
|
|
1812
|
+
said = " ".join(str(sb.get(k) or "") for k in ("passage", "citation", "title"))
|
|
1813
|
+
allowed += [v for v, *_ in numbers(_ORDINAL.sub(r"\1", said))] # "the 14th of June" accounts for "14 June"
|
|
1803
1814
|
if _CONVENTIONS.search(clean): # "95% interval", "α 0.05", "80% power" are conventions
|
|
1804
1815
|
allowed += [95.0, 99.0, 90.0, 80.0, 0.05, 0.01]
|
|
1805
1816
|
loose = [p for p in numbers(clean) if not _matches(p, allowed) and not _matches_stat(p, stat)]
|
|
@@ -92,6 +92,28 @@ def _asserted(pattern: re.Pattern, text: str) -> list[str]:
|
|
|
92
92
|
return [m.group(0).lower() for m in pattern.finditer(text) if not _NEGATOR.search(text[:m.start()])]
|
|
93
93
|
|
|
94
94
|
|
|
95
|
+
_P_KEY = re.compile(r"p(?:[_-]?val(?:ue)?|_[a-z0-9_]+)?", re.I)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _carries_test(s: D.Snap, nid: str) -> bool:
|
|
99
|
+
"""Does this node hold a test: a two-sample count the record worked out, a value with a p, a value named as one
|
|
100
|
+
(p_value, p_exact, pvalue), or, for a claim, its own statement's p-value or any such result it rests on?"""
|
|
101
|
+
def holds(n: str) -> bool:
|
|
102
|
+
vals = s.nodes[n]["body"].get("values") or {}
|
|
103
|
+
return bool(D.state(s, n).get("test")) or any(
|
|
104
|
+
_P_KEY.fullmatch(str(k)) or (isinstance(v, dict) and "p" in v) for k, v in vals.items())
|
|
105
|
+
if holds(nid):
|
|
106
|
+
return True
|
|
107
|
+
n = s.nodes[nid]
|
|
108
|
+
if n["type"] != "claim":
|
|
109
|
+
return False
|
|
110
|
+
if _P_VALUE.search(n["body"].get("statement") or ""):
|
|
111
|
+
return True
|
|
112
|
+
bound = [m.get("result") for m in n["body"].get("measurements") or [] if isinstance(m, dict)]
|
|
113
|
+
rests = [e["dst"] for e in s.out.get(nid, []) if e["rel"] == "derived_from"]
|
|
114
|
+
return any(holds(r) for r in [*bound, *rests] if r in s.nodes)
|
|
115
|
+
|
|
116
|
+
|
|
95
117
|
def _blank(m: re.Match) -> str:
|
|
96
118
|
return re.sub(r"[^\n]", " ", m.group(0))
|
|
97
119
|
|
|
@@ -286,9 +308,10 @@ def check(g: "Graph", text: str, inv: str = "") -> dict:
|
|
|
286
308
|
f"'{causal[0]}' is causal and no claim is cited — cite the claim backed by an experiment, or say "
|
|
287
309
|
"'is associated with'.")
|
|
288
310
|
sig = L.found(L.SIGNIFICANCE, own)
|
|
289
|
-
if sig and not _P_VALUE.search(sent) and not any(
|
|
290
|
-
|
|
291
|
-
|
|
311
|
+
if sig and not _P_VALUE.search(sent) and not any(_carries_test(s, c) for c in cited):
|
|
312
|
+
# the sentence denies the test rather than claims it: emphasis ("*not* significantly") is no assertion
|
|
313
|
+
plain = re.sub(r"\bnot\s+(?:only|just|merely)\b", "", re.sub(r"[*_]", "", own), flags=re.I)
|
|
314
|
+
negated = bool(L.denied(L.SIGNIFICANCE, plain)) and not L.asserted(L.SIGNIFICANCE, plain)
|
|
292
315
|
add(ln, "warning" if negated else "error", "REPORT_SIGNIFICANCE_UNBACKED", sent,
|
|
293
316
|
f"'{sig[0]}' — cite the claim or result that carries the test.")
|
|
294
317
|
_check_answers(s, text or "", invs, by_code, add, counted)
|
|
@@ -247,7 +247,7 @@
|
|
|
247
247
|
padding: 6px 8px; gap: 4px; }
|
|
248
248
|
.hg .hg-nav h2 { display: none; }
|
|
249
249
|
.hg .hg-nav button { width: auto; flex: none; white-space: nowrap; padding: 6px 10px; }
|
|
250
|
-
.hg .hg-nav .n { margin-left: 4px; } .hg .hg-nav .inv .s { display: none; }
|
|
250
|
+
.hg .hg-nav .n { margin-left: 4px; } .hg .hg-nav .inv .s { display: none; } .hg .hg-nav .subnav { display: none; }
|
|
251
251
|
.hg .hg-main { padding: 16px 16px 32px; }
|
|
252
252
|
.hg.hg-embed .hg-nav { overflow-x: auto; overflow-y: hidden; } /* beats the embed's overflow: visible: every tab reachable */
|
|
253
253
|
.hg .trace .tr { grid-template-columns: minmax(90px, 40%) minmax(0, 1fr) 48px; }
|
|
@@ -266,6 +266,20 @@
|
|
|
266
266
|
.hg .lk-from:first-child { margin-top: 0; }
|
|
267
267
|
.hg .lk-sec { border-left: 3px solid var(--accent); padding-left: 10px; }
|
|
268
268
|
.hg .lk-sec .lk-pin + .lk-pin { margin-top: 8px; }
|
|
269
|
+
/* sources: the passage as the author quoted it, under the citation; its links */
|
|
270
|
+
.hg .so-cite { margin-top: 3px; font-size: 12px; color: var(--ink2); border-left: 2px solid var(--line2); padding-left: 8px; }
|
|
271
|
+
.hg .so-links { margin-top: 3px; font-size: 11.5px; overflow-wrap: anywhere; }
|
|
272
|
+
/* focus: one node's part of the graph — the bar names it, switches the lens, clears it */
|
|
273
|
+
.hg .focusbar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; padding: 8px 12px; margin-bottom: 12px; border-radius: 9px;
|
|
274
|
+
background: var(--accent-soft); color: var(--accent-ink); font-size: 12.5px; }
|
|
275
|
+
.hg .focusbar .sp { flex: 1; } .hg .focusbar > button.code { all: unset; cursor: pointer; font-family: var(--mono); font-size: 12px; font-weight: 600; }
|
|
276
|
+
.hg .focusbar > button.code:hover { text-decoration: underline; }
|
|
277
|
+
.hg .focus-acts { display: flex; gap: 6px; flex-wrap: wrap; }
|
|
278
|
+
.hg .hg-nav .subnav { margin: 0 0 4px; display: flex; flex-direction: column; gap: 1px; }
|
|
279
|
+
.hg .hg-nav .subnav h3 { margin: 4px 8px 3px 34px; font: 600 10.5px var(--sans); letter-spacing: .05em; text-transform: uppercase; color: var(--ink3); }
|
|
280
|
+
.hg .hg-nav .subnav button { padding: 4px 10px 4px 34px; font-size: 12px; gap: 7px; }
|
|
281
|
+
.hg .hg-nav .subnav .t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
282
|
+
.hg .hg-toast[hidden] { display: none; }
|
|
269
283
|
@media print {
|
|
270
284
|
.hg .hg-nav, .hg .hg-top, .hg .head .acts, .hg .hg-drawer, .hg .hg-pal { display: none !important; }
|
|
271
285
|
.hg .hg-app { display: block; } .hg { overflow: visible; height: auto; } .hg .hg-main { overflow: visible; padding: 0; }
|
|
@@ -124,6 +124,23 @@
|
|
|
124
124
|
"empty.none": "Este registro aún no tiene investigaciones.",
|
|
125
125
|
"empty.live": " Lance un enjambre contra él y aparecerá aquí en cuanto empiece.",
|
|
126
126
|
"empty.demo": " <code>hypgraph demo</code> construye una para explorar.", "err.read": "No se pudo leer el registro: {msg}",
|
|
127
|
+
"view.sources": "Fuentes", "exp.sources": "La situación se muestra",
|
|
128
|
+
"so.lede": "Todo lo que esta investigación cita — literatura externa y referencias fijadas a otros registros — con lo que se apoya en cada una.",
|
|
129
|
+
"so.honest": "Un enlace de cita dice que su autor apoya ese nodo en esta fuente. En una referencia fijada el registro ha comprobado el hash de la versión fijada; en la literatura externa no ha comprobado nada: el pasaje es tal como lo citó el autor.",
|
|
130
|
+
"so.filter": "Filtrar por código, cita, enlace o quien la cita", "so.filter.aria": "Filtrar las fuentes",
|
|
131
|
+
"so.only.uncited": "sin nada que la cite", "so.only.nolink": "sin DOI ni URL", "so.only.fallen": "caída, aún citada",
|
|
132
|
+
"so.literature": "Literatura externa", "so.literature.sub": "{n} fuente(s)", "so.pinned": "Referencias fijadas",
|
|
133
|
+
"so.pinned.sub": "{n} fuente(s) que nombran un nodo de otro registro",
|
|
134
|
+
"so.col.citation": "Cita", "so.col.kind": "Tipo", "so.col.cited_by": "Citada por", "so.col.record": "Registro", "so.col.node": "Nodo fijado",
|
|
135
|
+
"so.kind.primary": "primaria", "so.kind.secondary": "secundaria", "so.kind.tertiary": "terciaria",
|
|
136
|
+
"so.uncited": "nada la cita", "so.says": "dice", "so.retrieved": "consultada el {date}", "so.loading": "leyendo los campos de cada fuente…",
|
|
137
|
+
"so.none": "Esta investigación aún no cita ninguna fuente.", "so.bibtex": "Exportar BibTeX",
|
|
138
|
+
"gr.refs.see": "Sus referencias fijadas se listan en Fuentes.", "gr.aria.focus": "Grafo de {n} nodos alrededor de {code}",
|
|
139
|
+
"fo.why": "en qué se apoya", "fo.impact": "qué se apoya en esto", "fo.near": "sus vecinos",
|
|
140
|
+
"fo.question": "la pregunta, lo que la responde y en qué se apoya eso",
|
|
141
|
+
"fo.n": "{n} de {of} nodos", "fo.depth": "profundidad", "fo.link": "Copiar enlace", "fo.copied": "Enlace copiado",
|
|
142
|
+
"fo.clear": "Registro completo", "fo.clear.aria": "Quitar el foco", "fo.by_question": "Por pregunta",
|
|
143
|
+
"dr.graph": "En el grafo", "dr.focus.why": "Mostrar en qué se apoya", "dr.focus.impact": "Mostrar qué se apoya en esto", "dr.focus.near": "Mostrar sus vecinos",
|
|
127
144
|
"nouns": {
|
|
128
145
|
"Artifact": ["Artefacto", "Artefactos"], "Backtest": ["Backtest", "Backtests"], "Backtest plan": ["Plan de backtest", "Planes de backtest"],
|
|
129
146
|
"Change": ["Cambio", "Cambios"], "Claim": ["Afirmación", "Afirmaciones"], "Code review": ["Revisión de código", "Revisiones de código"],
|
|
@@ -261,6 +278,23 @@
|
|
|
261
278
|
"empty.none": "Ce registre n'a pas encore d'enquête.",
|
|
262
279
|
"empty.live": " Lancez un essaim dessus et elle apparaît ici dès qu'elle commence.",
|
|
263
280
|
"empty.demo": " <code>hypgraph demo</code> en construit une à explorer.", "err.read": "Impossible de lire le registre : {msg}",
|
|
281
|
+
"view.sources": "Sources", "exp.sources": "Le statut est affiché",
|
|
282
|
+
"so.lede": "Tout ce que cette enquête cite — littérature externe et références épinglées vers d'autres registres — avec ce qui repose sur chacune.",
|
|
283
|
+
"so.honest": "Un lien de citation dit que son auteur fait reposer ce nœud sur cette source. Pour une référence épinglée, le registre a contrôlé le hachage de la version épinglée ; pour la littérature externe, il n'a rien contrôlé : le passage est tel que l'auteur l'a cité.",
|
|
284
|
+
"so.filter": "Filtrer par code, citation, lien ou citant", "so.filter.aria": "Filtrer les sources",
|
|
285
|
+
"so.only.uncited": "citée par rien", "so.only.nolink": "sans DOI ni URL", "so.only.fallen": "tombée, encore citée",
|
|
286
|
+
"so.literature": "Littérature externe", "so.literature.sub": "{n} source(s) citée(s)", "so.pinned": "Références épinglées",
|
|
287
|
+
"so.pinned.sub": "{n} source(s) nommant un nœud d'un autre registre",
|
|
288
|
+
"so.col.citation": "Citation", "so.col.kind": "Nature", "so.col.cited_by": "Citée par", "so.col.record": "Registre", "so.col.node": "Nœud épinglé",
|
|
289
|
+
"so.kind.primary": "primaire", "so.kind.secondary": "secondaire", "so.kind.tertiary": "tertiaire",
|
|
290
|
+
"so.uncited": "rien ne la cite", "so.says": "dit", "so.retrieved": "consultée le {date}", "so.loading": "lecture des champs de chaque source…",
|
|
291
|
+
"so.none": "Cette enquête ne cite encore aucune source.", "so.bibtex": "Exporter en BibTeX",
|
|
292
|
+
"gr.refs.see": "Ses références épinglées sont listées sous Sources.", "gr.aria.focus": "Graphe de {n} nœuds autour de {code}",
|
|
293
|
+
"fo.why": "ce sur quoi il repose", "fo.impact": "ce qui repose dessus", "fo.near": "ses voisins",
|
|
294
|
+
"fo.question": "la question, ce qui y répond et ce sur quoi cela repose",
|
|
295
|
+
"fo.n": "{n} nœuds sur {of}", "fo.depth": "profondeur", "fo.link": "Copier le lien", "fo.copied": "Lien copié",
|
|
296
|
+
"fo.clear": "Registre entier", "fo.clear.aria": "Retirer le focus", "fo.by_question": "Par question",
|
|
297
|
+
"dr.graph": "Dans le graphe", "dr.focus.why": "Montrer ce sur quoi il repose", "dr.focus.impact": "Montrer ce qui repose dessus", "dr.focus.near": "Montrer ses voisins",
|
|
264
298
|
"nouns": {
|
|
265
299
|
"Artifact": ["Artefact", "Artefacts"], "Backtest": ["Backtest", "Backtests"], "Backtest plan": ["Plan de backtest", "Plans de backtest"],
|
|
266
300
|
"Change": ["Modification", "Modifications"], "Claim": ["Affirmation", "Affirmations"], "Code review": ["Revue de code", "Revues de code"],
|
|
@@ -398,6 +432,23 @@
|
|
|
398
432
|
"empty.none": "Dieses Protokoll hat noch keine Untersuchungen.",
|
|
399
433
|
"empty.live": " Starten Sie einen Schwarm darauf, und sie erscheint hier, sobald sie beginnt.",
|
|
400
434
|
"empty.demo": " <code>hypgraph demo</code> erstellt eine zum Erkunden.", "err.read": "Das Protokoll konnte nicht gelesen werden: {msg}",
|
|
435
|
+
"view.sources": "Quellen", "exp.sources": "Der Stand stammt",
|
|
436
|
+
"so.lede": "Alles, was diese Untersuchung zitiert — externe Literatur und fixierte Verweise auf andere Protokolle — mit dem, was jeweils darauf beruht.",
|
|
437
|
+
"so.honest": "Ein Zitat-Link sagt, dass sein Autor diesen Knoten auf diese Quelle stützt. Bei einem fixierten Verweis hat das Protokoll den Hash der fixierten Version geprüft; bei externer Literatur hat es nichts geprüft: die Passage ist so, wie der Autor sie zitiert hat.",
|
|
438
|
+
"so.filter": "Nach Code, Zitat, Link oder Zitierendem filtern", "so.filter.aria": "Quellen filtern",
|
|
439
|
+
"so.only.uncited": "von nichts zitiert", "so.only.nolink": "ohne DOI oder URL", "so.only.fallen": "gefallen, noch zitiert",
|
|
440
|
+
"so.literature": "Externe Literatur", "so.literature.sub": "{n} Quelle(n)", "so.pinned": "Fixierte Verweise",
|
|
441
|
+
"so.pinned.sub": "{n} Quelle(n), die einen Knoten eines anderen Protokolls nennen",
|
|
442
|
+
"so.col.citation": "Zitat", "so.col.kind": "Art", "so.col.cited_by": "Zitiert von", "so.col.record": "Protokoll", "so.col.node": "Fixierter Knoten",
|
|
443
|
+
"so.kind.primary": "primär", "so.kind.secondary": "sekundär", "so.kind.tertiary": "tertiär",
|
|
444
|
+
"so.uncited": "nichts zitiert sie", "so.says": "sagt", "so.retrieved": "abgerufen am {date}", "so.loading": "Felder jeder Quelle werden gelesen…",
|
|
445
|
+
"so.none": "Diese Untersuchung zitiert noch keine Quellen.", "so.bibtex": "Als BibTeX exportieren",
|
|
446
|
+
"gr.refs.see": "Seine fixierten Verweise stehen unter Quellen.", "gr.aria.focus": "Graph aus {n} Knoten um {code}",
|
|
447
|
+
"fo.why": "worauf es beruht", "fo.impact": "was darauf beruht", "fo.near": "seine Nachbarn",
|
|
448
|
+
"fo.question": "die Frage, was sie beantwortet und worauf das beruht",
|
|
449
|
+
"fo.n": "{n} von {of} Knoten", "fo.depth": "Tiefe", "fo.link": "Link kopieren", "fo.copied": "Link kopiert",
|
|
450
|
+
"fo.clear": "Ganzes Protokoll", "fo.clear.aria": "Fokus aufheben", "fo.by_question": "Nach Frage",
|
|
451
|
+
"dr.graph": "Im Graph", "dr.focus.why": "Zeigen, worauf es beruht", "dr.focus.impact": "Zeigen, was darauf beruht", "dr.focus.near": "Seine Nachbarn zeigen",
|
|
401
452
|
"nouns": {
|
|
402
453
|
"Artifact": ["Artefakt", "Artefakte"], "Backtest": ["Backtest", "Backtests"], "Backtest plan": ["Backtest-Plan", "Backtest-Pläne"],
|
|
403
454
|
"Change": ["Änderung", "Änderungen"], "Claim": ["Behauptung", "Behauptungen"], "Code review": ["Code-Review", "Code-Reviews"],
|
|
@@ -535,6 +586,23 @@
|
|
|
535
586
|
"empty.none": "此记录还没有调查。",
|
|
536
587
|
"empty.live": "让一个智能体群在它上面运行,调查一开始就会出现在这里。",
|
|
537
588
|
"empty.demo": "<code>hypgraph demo</code> 会构建一个可供探索的调查。", "err.read": "无法读取记录:{msg}",
|
|
589
|
+
"view.sources": "来源", "exp.sources": "现状",
|
|
590
|
+
"so.lede": "本调查引用的一切——外部文献,以及固定引用到其他记录的引用——以及各自支撑的内容。",
|
|
591
|
+
"so.honest": "一条引用链接表示其作者把该节点建立在这个来源之上。对固定引用,记录核查了所固定版本的哈希;对外部文献,记录没有核查任何内容:段落是作者引述的原样。",
|
|
592
|
+
"so.filter": "按代码、引文、链接或引用者筛选", "so.filter.aria": "筛选来源",
|
|
593
|
+
"so.only.uncited": "无人引用", "so.only.nolink": "没有 DOI 或 URL", "so.only.fallen": "已失效,仍被引用",
|
|
594
|
+
"so.literature": "外部文献", "so.literature.sub": "{n} 个来源", "so.pinned": "固定引用",
|
|
595
|
+
"so.pinned.sub": "{n} 个来源指向另一记录的节点",
|
|
596
|
+
"so.col.citation": "引文", "so.col.kind": "类别", "so.col.cited_by": "被引用于", "so.col.record": "记录", "so.col.node": "固定的节点",
|
|
597
|
+
"so.kind.primary": "一手", "so.kind.secondary": "二手", "so.kind.tertiary": "三手",
|
|
598
|
+
"so.uncited": "没有内容引用它", "so.says": "称", "so.retrieved": "检索于 {date}", "so.loading": "正在读取每个来源的字段…",
|
|
599
|
+
"so.none": "本调查尚未引用任何来源。", "so.bibtex": "导出 BibTeX",
|
|
600
|
+
"gr.refs.see": "它的固定引用列在“来源”下。", "gr.aria.focus": "以 {code} 为中心的 {n} 个节点的图谱",
|
|
601
|
+
"fo.why": "它依赖的内容", "fo.impact": "依赖它的内容", "fo.near": "它的邻居",
|
|
602
|
+
"fo.question": "该问题、回答它的内容以及这些内容所依赖的内容",
|
|
603
|
+
"fo.n": "{of} 个节点中的 {n} 个", "fo.depth": "深度", "fo.link": "复制链接", "fo.copied": "链接已复制",
|
|
604
|
+
"fo.clear": "完整记录", "fo.clear.aria": "清除聚焦", "fo.by_question": "按问题",
|
|
605
|
+
"dr.graph": "在图谱中", "dr.focus.why": "显示它依赖的内容", "dr.focus.impact": "显示依赖它的内容", "dr.focus.near": "显示它的邻居",
|
|
538
606
|
"nouns": {
|
|
539
607
|
"Artifact": ["产物", "产物"], "Backtest": ["回测", "回测"], "Backtest plan": ["回测计划", "回测计划"],
|
|
540
608
|
"Change": ["变更", "变更"], "Claim": ["主张", "主张"], "Code review": ["代码审查", "代码审查"],
|