@sigloch/graphify
v0.4.0
Published
Extraction/Slicer — chaos documents → governed SE-graph candidate slices (slicer → auto-typing → suggestion-gate)
Maintainers
Readme
graphify
Extraction / Slicer for the sigloch SE-family — turns chaos documents (PDF, Excel, JIRA, plain text) into governed SE-graph candidate slices. The entrance to the family: "chaos in, structure on day one."
What it is / is not
- IS: a slicer pipeline —
Slicer(document → untyped candidate graph) →Auto-Typing(candidates → SEElementType+ attributes) →Suggestion-Gate(human review →ApprovalMatrix). Stateless, local, GDPR-safe. Validates against the family ontology; emits only governed candidates. - IS NOT: a generator (→ aimprove) · a governed editor / apply-gate (→ graphcode) · a persistent store owner (the harness owns Kuzu) · a learning engine (→ learning-core) · a viewer (→ graph-view-edit).
The pipeline
document ─▶ Slicer ─▶ SlicerOutput ─▶ Auto-Typing ─▶ TypedCandidatesOutput ─▶ Suggestion-Gate ─▶ ApprovalMatrix ─▶ (consumer's apply-gate)
(chaos) (probabilistic, LLM) (untyped cand.) (LLM type-inference) (typed candidates) (human review) (approved fragment)ApprovalMatrix.finalGraph flows to a consumer's apply-gate (graphcode / aimprove harness mutate()).
Determinism boundary: the Slicer is left of the line (probabilistic, recall-first); the apply-gate is
right of it (deterministic, precision). graphify does not enforce V3_RULES — it emits, the gate enforces.
Code-repo input (deterministic, no LLM)
A second UC-1 realization alongside the document pipeline above — the A1 alternate path
(SwappableMatcher.RQ.021): a TypeScript repo is already machine-structured, so it skips Slicer/
Auto-Typing entirely and goes straight to typed candidates via Tree-sitter AST parsing.
{path, content}[] ─▶ extractCodeRepo() ─▶ TypedCandidatesOutput ─▶ Suggestion-Gate ─▶ ApprovalMatrix
(TS files) (Tree-sitter, deterministic) (confidence 1.0, auto-approve)- FUNC per free-function declaration, MOD per file and per directory — the directory tree is the MOD-in-MOD hierarchy (
MOD -compose-> MOD, file MOD = leaf,FUNC -allocate-> MODon the file). - Every internal call (
funcA()callingfuncB(), resolved through the import table) becomesFUNC_A -io-> FLOW -io-> FUNC_B, with the callee's parameter/return signature as a SCHEMA (FLOW -relation-> SCHEMA— the only valid trace for a FLOW's data shape). Calls into libraries/stdlib/anything outside the given file set are not modeled at all (dropped, not flagged) — deliberate scope, not a gap. - TEST candidates from
*.test.ts/*.spec.ts+describe/it/testblocks — emitted as isolated nodes (no edge): the ontology's only valid TEST trace isTEST -verify-> REQ, and this path extracts no REQ from code. A reviewer links them to a REQ later. - Scope (v1): free-function declarations and plain-identifier call callees only — no classes/methods,
no arrow functions, no
obj.method()calls. TypeScript/TSX only; Tree-sitter's ~25 grammars make a second language a new parser file, not a rewrite (seesrc/structure/code/parse-typescript.tsheader).
import { extractCodeRepo, extractCodeRepoPipeline } from '@sigloch/graphify';
// Just the typed candidates:
const typed = extractCodeRepo([{ path: 'src/a.ts', content: '...' }, ...]);
// The full F2 chain (Suggestion-Gate → Import → Markdown/viewer bundle), same as the document path:
const { approval, imported, bundle } = await extractCodeRepoPipeline(files, {
gate: new McpConsumerGate(transport), // see below — wire straight into a live graphcode store
});Wiring into a graphcode harness: McpConsumerGate (src/import/consumer-gate.ts) already speaks
the graphcode mutate-command shape — it just needs a transport: (commands) => Promise<{success, violations}>
that calls the live graph_mutate MCP tool (or, in-process, bindToolsToHarness(harness).graph_mutate.handler).
There is no packaged CLI/skill for this yet (src/ports/cli.ts only drives the document path) — until one
exists, a consumer (a graphcode skill, a script) imports extractCodeRepoPipeline directly and supplies
the transport. docs/cr/done/CR-GF-133/134/135-*.md have the full design + the self-parse E2E
(tests/self-parse-e2e.test.ts — graphify parses its own src/, cross-checked against §3.3's module map).
Locked constraints (verriegelt — bok/docs/governance/graphify-governance.md §3)
- L1 — ElementType set: Auto-Typing emits only the 13 SE types from
@sigloch/contracts/se(SYS/UC/ACTOR/FCHAIN/FUNC/FLOW/REQ/TEST/MOD/SCHEMA/SESSION/CR/MS). Import the ontology, never fork. - L2 — Rules after the gate: graphify does not pre-check
V3_RULES; the consumer's apply-gate does. - L3 — Format-E parity: graphify output round-trips through the shared Format-E codec (
@sigloch/graph-api-core) using a graphify-owned, SE-typed fixture (round-trip = identity). - L4 — Version pin: pins
ONTOLOGY_VERSIONfrom@sigloch/contracts/se(3.6.0).
Status
MVP carve-out from aimpro/src/learning-engine/ (extraction pipeline). See docs/cr/open/ for the CR plan
(CR-GF-100 foundation+schemas → 101 Slicer → 102 Auto-Typing → 103 Suggestion-Gate → 104 Import).
Spec: docs/SPEC.md. Family SSOT: bok/docs/governance/graphify-governance.md.
