Graph Layers Reference
One section per layer of the Unified Project Graph — node types, edge types, and example traversal queries for each.
Graph Layers Reference
The Unified Project Graph stores all nodes in context_artifacts and all edges in context_artifact_dependencies. Layers are distinguished by the artifact_type prefix on each node. This page documents each layer individually: its purpose, its node types, its edge types, and an example query showing how to traverse it.
For the full architectural overview, see Unified Project Graph.
Layer 1: Business Intent
Prefix: spec_* (business intent subset)
Populated by: The 6-phase elicitation engine (discovery conversations)
Purpose: Captures what the product is supposed to do in human terms — the "why" and "what" before any architectural decisions are made.
Node Types
| Node Type | What It Represents | Key Metadata Fields |
|---|---|---|
spec_project | The project itself | name, description, domain, audience |
spec_bounded_context | A domain boundary | name, responsibilities[], ubiquitous_language{} |
spec_epic | A major feature group | name, goal, priority |
spec_user_story | A user-facing capability | as_a, i_want, so_that, priority, story_points |
spec_acceptance_criterion | A testable condition for a story | description, is_automated, test_node_id |
spec_constraint | A non-functional requirement | type (performance/security/compliance/ux), description, measurable |
spec_persona | A user type | name, role, goals[], pain_points[] |
Edge Types
| Edge Type | From → To | Meaning |
|---|---|---|
contains | spec_project → spec_bounded_context | Project scope contains this domain |
contains | spec_bounded_context → spec_epic | Domain contains this epic |
contains | spec_epic → spec_user_story | Epic contains this story |
has_criteria | spec_user_story → spec_acceptance_criterion | Story requires this criterion to be satisfied |
governs | spec_constraint → spec_epic / spec_operation | Constraint governs this artifact |
renders | spec_ui_page → spec_user_story | This page is the primary UI for this story |
Example Query: Find All Unverified Acceptance Criteria
Returns acceptance criteria with no tests bridge edge — meaning no test case is linked to them.
SELECT ca.id, ca.artifact_key, ca.content
FROM context_artifacts ca
WHERE ca.project_id = :project_id
AND ca.artifact_type = 'spec_acceptance_criterion'
AND ca.is_active = true
AND ca.id NOT IN (
SELECT cad.depends_on_id
FROM context_artifact_dependencies cad
WHERE cad.dependency_type = 'tests'
)
ORDER BY ca.created_at;Layer 2: System Structure
Prefix: spec_* (system structure subset)
Populated by: Discovery engine domain analysis pass; implementation planner
Purpose: Captures the architectural shape of the system — entities, services, APIs, data schemas, and guard conditions. This is where requirements become typed design artifacts.
Node Types
| Node Type | What It Represents | Key Metadata Fields |
|---|---|---|
spec_entity | A domain object | name, fields[], bounded_context, is_aggregate_root |
spec_field | A property of an entity | name, type, required, unique, default |
spec_service | A logical service boundary | name, responsibility, bounded_context |
spec_operation | An action a service performs | name, parameters[], returns, side_effects[] |
spec_endpoint | An API surface | method, path, auth_required, input_schema, output_schema |
spec_schema | A data shape / validation | name, fields[], validation_rules[] |
spec_guard | A security or business rule | condition, type (auth/role/business_rule), failure_behavior |
Edge Types
| Edge Type | From → To | Meaning |
|---|---|---|
contains | spec_bounded_context → spec_entity | Domain contains this entity |
contains | spec_bounded_context → spec_service | Domain contains this service |
has_field | spec_entity → spec_field | Entity has this field |
has_operation | spec_service → spec_operation | Service exposes this operation |
has_input | spec_endpoint → spec_schema | Endpoint accepts this input shape |
has_output | spec_endpoint → spec_schema | Endpoint returns this output shape |
requires | spec_operation → spec_entity | Operation requires this entity to exist |
guards | spec_guard → spec_endpoint | Guard condition must pass before endpoint executes |
guards | spec_guard → spec_operation | Guard condition must pass before operation executes |
Example Query: Find All Endpoints Missing an Auth Guard
Returns spec_endpoint nodes with auth_required = true in their metadata that have no inbound guards edge.
SELECT ca.id, ca.artifact_key, ca.metadata->>'path' AS path, ca.metadata->>'method' AS method
FROM context_artifacts ca
WHERE ca.project_id = :project_id
AND ca.artifact_type = 'spec_endpoint'
AND ca.is_active = true
AND (ca.metadata->>'auth_required')::boolean = true
AND ca.id NOT IN (
SELECT cad.artifact_id
FROM context_artifact_dependencies cad
JOIN context_artifacts guard_ca ON guard_ca.id = cad.depends_on_id
WHERE cad.dependency_type = 'guards'
AND guard_ca.artifact_type = 'spec_guard'
)
ORDER BY ca.artifact_key;Layer 3: Behavior
Prefix: spec_* (behavior subset)
Populated by: Discovery engine journey analysis; UI planning pass
Purpose: Captures how the system behaves at runtime — user journeys, async workflows, and UI structure. This layer is the spec-side equivalent of the code EOG and DFG.
Node Types
| Node Type | What It Represents | Key Metadata Fields |
|---|---|---|
spec_flow_step | A step in a user journey | description, actor, preconditions[], postconditions[] |
spec_workflow | An async multi-step process | name, trigger, timeout, retry_policy |
spec_workflow_step | A step in a workflow | name, action, success_next, failure_next |
spec_ui_page | A page in the application | path, layout, auth_required, data_requirements[] |
spec_ui_component | A UI component | name, purpose, data_source, interactions[] |
spec_ui_state | A UI state condition | name (loading/error/empty/populated), triggers[] |
spec_ui_layout | A layout container | name, slots[], responsive_behavior |
Edge Types
| Edge Type | From → To | Meaning |
|---|---|---|
flow_next | spec_flow_step → spec_flow_step | Sequential step ordering |
flow_branch | spec_flow_step → spec_flow_step | Conditional branching (condition stored in edge metadata) |
workflow_step_of | spec_workflow_step → spec_workflow | Step belongs to this workflow |
invokes | spec_workflow_step → spec_operation | Workflow step invokes this service operation |
triggers | event node → spec_workflow | This event triggers this workflow |
produces | spec_operation → event node | This operation produces this event |
displays | spec_ui_component → spec_entity | Component displays this entity's data |
calls | spec_ui_component → spec_endpoint | Component calls this API endpoint |
manages | spec_ui_component → spec_ui_state | Component manages this state |
navigates_to | spec_ui_page → spec_ui_page | Page navigates to this page |
layout_contains | spec_ui_layout → spec_ui_page | Layout contains this page |
Example Query: Traverse a User Journey in Sequence Order
Returns all flow steps for a given journey in execution order, with branch conditions.
WITH RECURSIVE journey AS (
SELECT ca.id, ca.artifact_key, ca.content, cad.dependency_type, cad.metadata->>'condition' AS branch_condition, 1 AS step_order
FROM context_artifacts ca
LEFT JOIN context_artifact_dependencies cad ON cad.artifact_id = ca.id
WHERE ca.project_id = :project_id
AND ca.artifact_type = 'spec_flow_step'
AND ca.id = :entry_step_id
UNION ALL
SELECT next_ca.id, next_ca.artifact_key, next_ca.content, next_edge.dependency_type, next_edge.metadata->>'condition', j.step_order + 1
FROM context_artifact_dependencies next_edge
JOIN context_artifacts next_ca ON next_ca.id = next_edge.artifact_id
JOIN journey j ON next_edge.depends_on_id = j.id
WHERE next_edge.dependency_type IN ('flow_next', 'flow_branch')
AND j.step_order < 50 -- cycle guard
)
SELECT * FROM journey ORDER BY step_order;Layer 4: Implementation Plan
Prefix: impl_*
Populated by: The implementation plan generator (pre-codegen phase)
Purpose: The bridge between "what" (spec) and "how" (code). Contains all concrete decisions about file paths, libraries, import patterns, type names, and architectural choices. This layer is what gets handed to code Kits as their primary input.
Node Types
| Node Type | What It Represents | Key Metadata Fields |
|---|---|---|
impl_entity | Implementation plan for an entity | file_path, orm, table_name, columns[] |
impl_service | Implementation plan for a service | file_path, class_name, injected_deps[] |
impl_operation | Implementation plan for an operation | file_path, function_name, imports[], validation_library |
impl_endpoint | Implementation plan for a route | file_path, router_library, middleware[] |
impl_guard | Implementation plan for a guard | file_path, guard_type, mechanism |
impl_workflow | Implementation plan for a workflow | file_path, orchestration_library, trigger_event |
impl_ui_page | Implementation plan for a page | file_path, framework, data_fetching_pattern |
impl_ui_component | Implementation plan for a component | file_path, component_library, state_management |
Edge Types
| Edge Type | From → To | Meaning |
|---|---|---|
realizes | impl_* → spec_* | This plan realizes that spec intent |
requires | impl_* → impl_* | This plan depends on another plan being generated first |
composed-of | impl_service → impl_operation | Service plan contains this operation plan |
capability_interface | impl_* → interface contract node | Plan exposes this typed interface |
Example Query: Topological Sort for Code Generation Order
Returns impl nodes in batches — each batch can be generated in parallel; all dependencies of a batch are in earlier batches.
WITH RECURSIVE topo AS (
SELECT ca.id, ca.artifact_key, ca.artifact_type, 0 AS depth
FROM context_artifacts ca
WHERE ca.project_id = :project_id
AND ca.artifact_type LIKE 'impl_%'
AND ca.is_active = true
AND ca.id NOT IN (
SELECT DISTINCT cad.artifact_id
FROM context_artifact_dependencies cad
WHERE cad.dependency_type = 'requires'
)
UNION ALL
SELECT ca.id, ca.artifact_key, ca.artifact_type, t.depth + 1
FROM context_artifact_dependencies cad
JOIN context_artifacts ca ON ca.id = cad.artifact_id
JOIN topo t ON t.id = cad.depends_on_id
WHERE cad.dependency_type = 'requires'
AND t.depth < 20
)
SELECT DISTINCT id, artifact_key, artifact_type, MAX(depth) AS batch
FROM topo
GROUP BY id, artifact_key, artifact_type
ORDER BY batch, artifact_key;Layer 5: Code
Prefix: code_*
Populated by: Brownfield CPG pipeline (existing code analysis) or the codegen pipeline (generated code)
Purpose: Represents what was actually built. Code layer nodes are created from static analysis of source files. They are the "reality" side of the spec-to-code bridge.
Node Types
| Node Type | What It Represents | Key Metadata Fields |
|---|---|---|
code_module | A source file | file_path, language, exports[], import_count |
code_class | A class definition | file_path, class_name, methods[], extends, implements[] |
code_function | A function or method | file_path, function_name, parameters[], return_type, complexity |
code_endpoint | An HTTP route handler | method, path, file_path, middleware_chain[] |
code_table | A database table | table_name, columns[], indexes[], foreign_keys[] |
code_schema | A validation schema | file_path, schema_name, library, fields[] |
code_component | A UI component | file_path, component_name, props[], hooks[] |
code_route | A frontend route | path, file_path, layout, data_loading_pattern |
Edge Types
Within the code layer, edges come from four CPG sub-layers:
AST (structural):
| Edge Type | From → To | Example |
|---|---|---|
references | code_function → code_function | register() calls hashPassword() |
imports | code_module → code_module | auth-service.ts imports crypto.ts |
extends | code_class → code_class | AdminService extends UserService |
EOG (execution order):
| Edge Type | From → To | Example |
|---|---|---|
controls_flow_to | code_function → code_function | Execution continues from handler to service |
DFG (data flow):
| Edge Type | From → To | Example |
|---|---|---|
data_flows_to | code node → code node | Password value flows from request body to bcrypt |
CDG (control dependence):
| Edge Type | From → To | Example |
|---|---|---|
controls | code_function → code_function | Auth middleware controls whether handler executes |
Bridge edges (spec ↔ code):
| Edge Type | From → To | Meaning |
|---|---|---|
implements | code_function → spec_operation | This function implements this operation |
exposes | code_endpoint → spec_endpoint | This handler exposes this API endpoint |
persists | code_table → spec_entity | This table persists this entity |
satisfies | code_function → spec_user_story | This code satisfies this story |
drifts_from | code_function → spec_operation | Implementation has diverged from spec |
generated_from | code_* → impl_* | This code was generated from this plan |
Example Query: Find Code Nodes With No Spec Requirement
Returns code layer nodes that have no inbound bridge edge — code that exists but no spec requires.
SELECT ca.id, ca.artifact_key, ca.artifact_type, ca.metadata->>'file_path' AS file_path
FROM context_artifacts ca
WHERE ca.project_id = :project_id
AND ca.artifact_type LIKE 'code_%'
AND ca.is_active = true
AND ca.id NOT IN (
SELECT cad.artifact_id
FROM context_artifact_dependencies cad
WHERE cad.dependency_type IN ('implements', 'exposes', 'persists', 'satisfies')
)
ORDER BY ca.artifact_type, ca.artifact_key;Layer 6: Verification and Infrastructure
Prefixes: test_*, infra_*
Populated by: Test analysis pipeline; infrastructure configuration ingestion
Purpose: Captures what proves correctness (test_*) and what the system runs on (infra_*). Test nodes are linked to spec acceptance criteria via tests edges, closing the spec → code → verification loop.
Node Types
| Node Type | What It Represents | Key Metadata Fields |
|---|---|---|
test_suite | A test file | file_path, framework, test_count |
test_case | A single test | name, file_path, line_number, status (passing/failing/skipped) |
test_assertion | A specific check within a test | description, type (equality/snapshot/throws) |
test_fixture | Reusable test data | name, shape, values |
infra_service | A deployed service | name, provider, region, tier |
infra_dependency | An external dependency | name, type (api/queue/cdn), sla, authentication_method |
infra_config | Configuration / environment variable | key, required, secret, default |
Edge Types
| Edge Type | From → To | Meaning |
|---|---|---|
tests | test_case → spec_acceptance_criterion | This test verifies this acceptance criterion |
validates | test_case → code_function | This test directly exercises this function |
covers | test_suite → code_module | This test file covers this module |
mocks | test_case → infra_dependency | This test mocks this external dependency |
uses_fixture | test_case → test_fixture | This test uses this fixture |
Example Query: Find Acceptance Criteria Covered by Tests
Returns criteria with their covering test cases and current test status.
SELECT
crit.id AS criterion_id,
crit.artifact_key AS criterion_key,
crit.content AS criterion_text,
tc.id AS test_case_id,
tc.artifact_key AS test_key,
tc.metadata->>'status' AS test_status
FROM context_artifacts crit
JOIN context_artifact_dependencies cad ON cad.depends_on_id = crit.id AND cad.dependency_type = 'tests'
JOIN context_artifacts tc ON tc.id = cad.artifact_id AND tc.artifact_type = 'test_case'
WHERE crit.project_id = :project_id
AND crit.artifact_type = 'spec_acceptance_criterion'
AND crit.is_active = true
ORDER BY crit.artifact_key;Cross-Layer Reachability Matrix
The following matrix shows which layers can reach which other layers through direct traversal (one edge hop):
| From Layer | Reaches | Via Edge Types |
|---|---|---|
| Business Intent (L1) | System Structure (L2) | contains, governs |
| Business Intent (L1) | Behavior (L3) | renders |
| System Structure (L2) | Behavior (L3) | has_operation, invokes |
| System Structure (L2) | Impl Plan (L4) | realizes (reverse) |
| Behavior (L3) | Impl Plan (L4) | realizes (reverse) |
| Impl Plan (L4) | Code (L5) | generated_from (reverse) |
| Code (L5) | System Structure (L2) | implements, exposes, persists, satisfies |
| Code (L5) | Verification (L6) | covers (reverse) |
| Verification (L6) | Business Intent (L1) | tests |
| Verification (L6) | Code (L5) | validates |
For multi-hop traversal (e.g., "which business requirements are covered by currently passing tests?"), use the recursive CTE pattern shown in the layer queries above, filtering by dependency_type at each hop.
Reference
| Topic | Location |
|---|---|
| Full architectural overview | Unified Project Graph |
| Node table schema | src/db/migrations/194_context_artifacts.sql |
| Edge table schema | src/db/migrations/197_context_artifact_dependencies.sql |
| All edge type values | src/db/migrations/427_context_artifact_dependency_types_expand.sql |
| PIM column additions | src/db/migrations/362_context_artifacts_pim_columns.sql |
| GraphQueryService | src/services/graph/graph-query-service.ts |
| Spec-to-impl mapping | docs/scale/specs/SPEC-FULLMAP-001-bidirectional-mapping.md |