Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions docs/en/architecture/adr/ADR-0020-the-graph-explorer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
id: ADR-0020
title: The Graph Explorer
slug: the-graph-explorer
iri: arqix:adrs/adr-0020

rdf:
type:
- arqix:classes/adr

triples: []

properties:
decision-status: accepted

external-references: []

meta:
lifecycle-status: draft
owner: hcf
created: 2026-07-19
updated: 2026-07-19
lang: en
translation-of:
generated: false
---

## The Graph Explorer

### Context

The corpus is a graph, and the tooling already serialises it: the trace core graph carries every document node and every resolved edge under a stable schema (ADR-0006), with one identity rule for its nodes (ADR-0007).
The existing projections answer counting questions — matrices, coverage numbers, catalogs.
Navigation questions stay unanswered: what surrounds this story, which clusters exist, where are the hubs and the orphans.
A node-link view with filters answers them at a glance; a table answers them not at all.

Two constraints shape the form.
Published artefacts must stand alone — a page that loads its engine from a third-party network breaks offline reading and ties publication to someone else's availability.
And the dependency bar (ADR-0014) demands the judgement per ingredient: vendor what removes real algorithmic work, write what is plain project code.

### Decision

**The corpus graph ships as one self-contained interactive HTML page, generated on demand.**

- `arqix report graph [--out <path>]` writes the page — an export product on the `report` noun (ADR-0005) — and `publish site` stages it with the published site.
- The page embeds the trace core graph, enriched with each document's title and declared lifecycle status; enrichment decorates existing nodes and never invents new ones (ADR-0007).
- The layout engine is vendored: the four d3-force modules (d3-dispatch, d3-quadtree, d3-timer, d3-force), pinned minified builds concatenated into one file, recorded as a source record whose digest the SRC contract verifies.
The interaction shell — canvas rendering, pan and zoom, filters, search, neighbourhood highlight — is project code in the page.
- The default view shows document nodes, coloured by type and filterable by type and lifecycle status; artefact nodes and their marker edges are a switchable code layer, off by default.
- The page is never committed: its embedded data changes with every corpus edit, so a committed copy either churns every change under a freshness gate or rots without one.

### Alternatives Considered

- **A committed snapshot page:** rejected — graph data ages with every commit; the snapshot treadmill buys no reader value here.
- **A hand-rolled layout:** rejected — a usable force layout means Barnes–Hut approximation, velocity integration, and collision handling; d3-force delivers exactly that in seventeen kilobytes, which is the case where vendoring beats rewriting.
- **Loading the library from a CDN:** rejected — the page stops being self-contained, and offline reading dies with the network.
- **Vendoring the full d3 bundle:** rejected — selection, scales, and transitions serve nothing here; the shell is a few hundred lines over canvas.
- **A server-rendered or baked SVG view:** rejected — a static picture answers none of the navigation questions; the filters and the highlight are the point.

### Consequences

- The Report & Export component owns `report graph`; the publisher stages the page for the default language.
- Third-party code enters the repository once, pinned and digest-recorded; updating it is a deliberate re-vendoring with a new digest, never a silent drift.
- The explorer reads the same core graph every other projection reads — a new data layer (claims, freshness) is a new toggle over the same embedded model, not a new pipeline.
- The page works from the filesystem, from the published site, and offline alike.
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,6 @@ Decisions are kept as ADRs under `../adr/`, maintained per the path model with a
| [ADR-0017](../../adr/ADR-0017-process-profiles-and-the-layered-ontology.md) | Process profiles and the layered ontology: rules stay code, their activation and binding become configuration, vocabulary becomes layered corpus data (reserved core, module vocabularies, project ontology) validated by an ONT meta-rule family; guarded lifecycle stays core, domain status is declared vocabulary | accepted |
| [ADR-0018](../../adr/ADR-0018-evidence-anchors-and-derived-triples.md) | Evidence anchors and derived triples: a claim is a body marker above the supported block plus a `derived-triples` edge that `fmt` generates from it; position-bound attributes stay on the marker, the edge joins the validated graph; confidence is a declared vocabulary; only claim markers are lifted | accepted |
| [ADR-0019](../../adr/ADR-0019-provenance-layers.md) | Provenance layers: one vocabulary, three carriers of increasing depth — computed from history (informational, never gated), inline on the marker (validated dictionary), and the claim record as the fullest form (analysis block, declared review verdict); records are derivable from the lower carriers, several markers may share one record, `supported-by` stays the only edge | accepted |
| [ADR-0020](../../adr/ADR-0020-the-graph-explorer.md) | The graph explorer: the corpus graph as one self-contained interactive HTML page, generated on demand (`report graph`, staged by `publish site`, never committed); vendored d3-force as the pinned, digest-recorded layout engine, the interaction shell as project code; documents by default, artefacts as a switchable layer | accepted |

Decision records predating the ADR directory live in the planning packages under `docs/en/plans/` (ID scheme, canonical-owner model, atomicity, subject conventions).
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
id: REQ-08-01-42-01
title: Embed the Corpus Graph in the Explorer Page
slug: embed-the-corpus-graph-in-the-explorer-page
iri: arqix:requirements/req-08-01-42-01

rdf:
type:
- arqix:classes/functional-requirement

triples:
- predicate: arqix:properties/derived-from
object:
- arqix:user-stories/us-08-01-42
- predicate: arqix:properties/has-verification-method
object:

properties:
priority: medium
fit-criterion: The generated page carries every trace-graph node and edge as embedded data; document nodes carry type and declared lifecycle status, artefact nodes stay distinguishable so the code layer can be toggled.

external-references: []

meta:
lifecycle-status: active
owner: hcf
created: 2026-07-19
updated: 2026-07-19
lang: en
translation-of:
generated: false
---

## Requirement

When `arqix report graph` runs, arqix SHALL embed every trace-graph node and edge in the generated explorer page, each document node carrying its type and declared lifecycle status.

### Notes

The embedded model is the trace core graph (ADR-0006) enriched with title and lifecycle status; enrichment decorates existing nodes and never invents new ones (ADR-0007, ADR-0020).
Derived from US-08-01-42.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
id: REQ-08-01-42-02
title: Keep the Explorer Page Self-Contained
slug: keep-the-explorer-page-self-contained
iri: arqix:requirements/req-08-01-42-02

rdf:
type:
- arqix:classes/functional-requirement

triples:
- predicate: arqix:properties/derived-from
object:
- arqix:user-stories/us-08-01-42
- predicate: arqix:properties/has-verification-method
object:

properties:
priority: medium
fit-criterion: The generated page embeds the graph data and the vendored layout engine inline and references no external script, stylesheet, or other remote resource.

external-references: []

meta:
lifecycle-status: active
owner: hcf
created: 2026-07-19
updated: 2026-07-19
lang: en
translation-of:
generated: false
---

## Requirement

When `arqix report graph` writes the explorer page, arqix SHALL embed the graph data and the vendored layout engine inline so that the page references no external resource.

### Notes

Self-containment is the ADR-0020 form: the page works from the filesystem, from the published site, and offline alike; the vendored engine is pinned and digest-recorded through its source record.
Derived from US-08-01-42.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
id: REQ-08-01-42-03
title: Stage the Explorer With the Published Site
slug: stage-the-explorer-with-the-published-site
iri: arqix:requirements/req-08-01-42-03

rdf:
type:
- arqix:classes/functional-requirement

triples:
- predicate: arqix:properties/derived-from
object:
- arqix:user-stories/us-08-01-42
- predicate: arqix:properties/has-verification-method
object:

properties:
priority: medium
fit-criterion: After publish site for the default language, the staging tree carries the generated explorer page alongside the staged pages.

external-references: []

meta:
lifecycle-status: active
owner: hcf
created: 2026-07-19
updated: 2026-07-19
lang: en
translation-of:
generated: false
---

## Requirement

When `arqix publish site` stages the default language's corpus, arqix SHALL stage the generated graph explorer page alongside the staged pages.

### Notes

The page reaches readers through the site without a committed copy (ADR-0020): staging regenerates it from the current corpus, exactly as the specification catalogue is staged on demand.
Derived from US-08-01-42.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
id: US-08-01-42
title: Explore the Corpus as a Graph
slug: explore-the-corpus-as-a-graph
iri: arqix:user-stories/us-08-01-42

rdf:
type:
- arqix:classes/user-story

triples:
- predicate: arqix:properties/has-persona
object: arqix:personas/per-08
- predicate: arqix:properties/has-requirement
object:
- arqix:requirements/req-08-01-42-01
- arqix:requirements/req-08-01-42-02
- arqix:requirements/req-08-01-42-03
- predicate: arqix:properties/is-part-of-workflow
object: arqix:workflows/wf-08-01

properties:
priority: medium
edge-case: false

external-references: []

meta:
lifecycle-status: draft
owner: hcf
created: 2026-07-19
updated: 2026-07-19
lang: en
translation-of:
generated: false
---

## Explore the Corpus as a Graph

As a knowledge engineer, I want the corpus as a navigable node-link view with filters, so that its structure — clusters, hubs, orphans, neighbourhoods — is visible at a glance instead of assembled from tables.

### Acceptance Criteria

- [ ] `arqix report graph [--out <path>]` writes a single self-contained HTML page: the graph data and the vendored layout engine are embedded, no external resource is referenced.
- [ ] Document nodes carry id, title, type, and declared lifecycle status; every edge carries its kind; artefact nodes and their marker edges ride along flagged as the code layer.
- [ ] The default view shows documents coloured by type, with type and lifecycle filters, search, and neighbourhood highlight; the code layer is a switch, off by default.
- [ ] `arqix publish site` stages the explorer page with the published site.

### Notes

The page projects the trace core graph (ADR-0006) under its identity rules (ADR-0007); the form — self-contained export, vendored engine, on-demand generation — is fixed in ADR-0020.
2 changes: 2 additions & 0 deletions docs/en/plans/knowledge-repository-2026-07-15/STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ Progress log for the knowledge-repository program (see PLANS.md; agents update t
- [x] FR-B3 close-out by investigation: duplicate id and iri are corpus-wide findings (FM-006, linter duplicate-id) and `doc new` checks id uniqueness at creation; the missing slug-per-context check needs the bounded-context concept (FR-C3) and moves there.
- [x] B2 provenance layer: ADR-0019 (provenance layers) accepted 2026-07-19 on the owner's hybrid decision — git optional as the computed floor, the marker carries the same vocabulary as an inline dictionary, records (`arqix:classes/claim`) are derivable and the fullest form, several markers may share one record.
REQ-08-01-40-06/-07/-08 on US-08-01-40, spec-first red/green: CLM-003 (review verdict against the effective vocabulary), CLM-004 (`record=` must resolve to a claim document), and `report claims --provenance` appending the history-computed columns on demand (never in the gated export); the `[kinds.claim]` creation surface with template and declared review vocabulary lands alongside.
- [x] Graph explorer (owner request 2026-07-19, design decided the same day: `report graph` + site staging, vendored d3-force, documents by default with the code layer switchable): ADR-0020 accepted; US-08-01-42 + REQ-08-01-42-01/-02/-03, spec-first red/green — the self-contained explorer page with embedded core graph (title/lifecycle enrichment), the vendored engine digest-recorded as SRC-0005, publish-site staging for the default language; verified live in headless Chromium (545 nodes, 2029 edges, no console errors).
Triage note: the uniform machine-readable findings format (FR-E1) is not a dependency — the explorer reads the ADR-0006 core graph, FR-E1 concerns the findings surface of the lint/verify commands and stays an independent slice.

Band 2 is decided; the remaining PLANS.md table slices are A2-A4 (ontology/entity), B1-B2 (evidence/provenance), C5 (lifecycle), D6 (crosswalk), and D7 (queries).

Expand Down
2 changes: 1 addition & 1 deletion docs/en/project/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ The full record is the second intake in the plan package (`docs/en/plans/knowled
- Landed with the first band-3 slices: the frontmatter vocabularies as configuration (US-08-01-29), the ONT-003 resolution pinned with its scanning boundary recorded (US-08-01-30, FR-A1), the coupling rules bound to the story-driven module via `[process].modules` (US-08-01-31), `--set` placeholder filling (US-08-01-32, FR-B1), kind-declared id and dir templates (US-08-01-33, FR-B2), the local-copy digest verification SRC-006 (US-08-01-34, the FR-A2 integrity half), and declared property vocabularies with FM-009 (US-08-01-35, FR-C1).
- Later bands: FR-A3 (configurable catalog projections) alongside crosswalks and queries; FR-D1/FR-D2 (semantic projections, competency-question traceability) after the evidence layer.

Candidate for 0.3.0 (owner idea 2026-07-12): an interactive graph explorer over the trace graph — the corpus as a navigable node-link view with kind/status filters, in the spirit of Obsidian's graph view; likely a self-contained page generated into the published site from the `trace scan` JSON.
Landed for 0.3.0 (owner idea 2026-07-12, decided as ADR-0020): the interactive graph explorer over the trace graph — `report graph` renders the corpus as a self-contained navigable node-link view with type and lifecycle filters, and `publish site` stages it with the site (US-08-01-42).

## What this roadmap is not

Expand Down
38 changes: 38 additions & 0 deletions docs/en/sources/SRC-0005.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
id: SRC-0005
title: Vendored d3-force Layout Engine
slug: vendored-d3-force-layout-engine
iri: arqix:sources/src-0005

rdf:
type:
- arqix:classes/source

triples: []

properties:
uri: https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz
accessed: 2026-07-19
local-copy: src/assets/d3-force-bundle.min.js
sha256: 98c505670a626aa3dbbdca6f7ae723cbd34e5aa06c08ac4ecb33149b0f1c12a2
licence: ISC
anchor:

external-references: []

meta:
lifecycle-status: final
owner: hcf
created: 2026-07-19
updated: 2026-07-19
lang: en
translation-of:
generated: false
---

## Vendored d3-force Layout Engine

The force-layout engine embedded in the graph explorer page (ADR-0020).
The local copy is a concatenation of four pinned upstream minified UMD builds, in load order: `d3-dispatch@3.0.1`, `d3-quadtree@3.0.1`, `d3-timer@3.0.1`, and `d3-force@3.0.0`, each fetched from its npm registry tarball (the recorded uri names the leading module); a provenance header in the file itself lists all four tarball URIs.
The digest pins the concatenation including that header; updating the engine is a deliberate re-vendoring — refetch, reconcatenate, refresh this digest.
All four modules are ISC-licensed, copyright Mike Bostock.
Loading