A small, dependency-free example of documentation stored as a validated knowledge graph.
Markdown files are the source of truth. YAML-like frontmatter gives every document a stable identity and typed relationships. A Python script validates the documents and produces knowledge/graph.json; a localhost viewer turns that JSON back into an explorable graph.
The included content is fictional. It describes a neighborhood community-garden project so you can experiment without exposing private project information.
- Markdown-first authoring that still works in GitHub
- Stable node IDs, types, statuses, aliases, and typed edges
- Validation for duplicate IDs, unknown targets, unsupported relationships, and broken Markdown links
- Deterministic
graph.jsongeneration with a CI-style stale-file check - Optional manifest-derived benchmark, split, run, and artifact nodes
- A dependency-free localhost viewer with search, 1-hop/2-hop/all views, filters, type-color grouping, pan, and zoom
- A fictional example graph and tests
Requires Python 3.11 or newer. No packages need to be installed.
python scripts/build_graph.py
python scripts/build_graph.py --check
python -m unittest discover -s tests
python scripts/serve.pyOpen http://127.0.0.1:8765/viewer/.
knowledge/**/*.md artifacts/*/manifest.json
| |
+---------------+------------------+
|
scripts/build_graph.py
|
validate + normalize
|
knowledge/graph.json
|
viewer/app.js
Authored Markdown owns concepts, decisions, requirements, problems, components, workflows, interfaces, metrics, research, and reading paths. Machine-owned manifests can contribute benchmark families, splits, runs, and immutable artifacts. graph.json is derived and must never be edited manually.
Choose the directory that matches the idea's role, then create one Markdown file:
---
id: rainwater-capture
type: component
status: planned
aliases:
- water collection system
related:
- relation: implements
target: drought-resilience
- relation: measured-by
target: municipal-water-use
---
# Rainwater capture
Collect roof runoff for irrigation. This implements
[drought resilience](../requirements/drought-resilience.md) and is measured by
[municipal water use](../metrics/municipal-water-use.md).Then run:
python scripts/build_graph.py
python scripts/build_graph.py --checkThe generator refuses to write graph.json if validation fails.
Add a related entry to the node that owns the statement:
related:
- relation: depends-on
target: soil-deliveryAlso add a normal Markdown link in the body so the document remains useful without the viewer. Edges are directional. Add the inverse only when it materially improves navigation; do not create reciprocal edges mechanically.
The starter vocabulary is:
depends-on required-by
uses used-by
implements implemented-by
part-of contains
affects affected-by
improves improved-by
measured-by
causes caused-by
mitigates mitigated-by
constrained-by constrains
prerequisite-for
motivates motivated-by
decided-by
supersedes superseded-by
interacts-with
resolves resolved-by
proven-by proves
gated-by unblocks
Prefer a precise existing relationship over inventing a synonym.
Authored types:
| Type | Use it for |
|---|---|
concept |
Shared distinctions and vocabulary |
component |
Systems or modules to build |
decision |
Explicit choices and their rationale |
requirement |
Outcomes the project must serve |
problem |
Constraints and failure modes |
metric |
Evidence that something improved |
interface |
Schemas and contracts |
workflow |
Repeatable operational loops |
research |
Open questions and experiments |
path |
Guided reading orders |
Generated types in the manifest example are benchmark, split, run, and artifact.
Allowed statuses are planned, proposed, accepted, rejected, superseded, deprecated, active, and open.
The fictional file at artifacts/sample-search-eval/manifest.json demonstrates how machine-owned state can enter the graph without duplicating it in Markdown:
{
"name": "sample-search-eval",
"status": "xfer_frozen",
"splits": {
"dev": {"cases": 8},
"xfer": {"cases": 4}
},
"runs": [
{"id": "rules-dev", "split": "dev", "system": "rules", "sealed": true}
]
}Regeneration creates a benchmark-family node, lifecycle split nodes, run nodes, and manifest/seal artifact nodes. This pattern keeps operational truth next to the artifacts that establish it.
- Decide which existing node owns new information.
- Update that node, or create exactly one new canonical node.
- Add typed relationships and ordinary Markdown links.
- Regenerate and validate the graph.
- Review the changed neighborhood in the viewer.
- Commit the Markdown source and regenerated JSON together.
For CI, run:
python scripts/build_graph.py --check
python -m unittest discover -s tests- Markdown remains readable. The graph enhances documentation instead of replacing it.
- IDs are stable. Filenames may move; relationships target IDs.
- Edges are typed. “Related to” is too vague to guide future work.
- Generated data stays generated. Manifests and seals are inventoried automatically.
- Neighborhoods are the default. Large graphs are easier to understand one or two hops at a time.
- The all view can group by type. Colors occupy soft regions while edges still cross between them.
See knowledge/README.md for the concise authoring reference.
MIT