domain-context-graph 0.4.0__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.
Files changed (114) hide show
  1. domain_context_graph-0.4.0/.github/workflows/publish.yaml +74 -0
  2. domain_context_graph-0.4.0/.gitignore +13 -0
  3. domain_context_graph-0.4.0/AGENTS.md +92 -0
  4. domain_context_graph-0.4.0/PKG-INFO +186 -0
  5. domain_context_graph-0.4.0/README.md +163 -0
  6. domain_context_graph-0.4.0/TODO.md +17 -0
  7. domain_context_graph-0.4.0/pyproject.toml +43 -0
  8. domain_context_graph-0.4.0/src/dcg/__init__.py +41 -0
  9. domain_context_graph-0.4.0/src/dcg/adapters/__init__.py +8 -0
  10. domain_context_graph-0.4.0/src/dcg/adapters/base.py +156 -0
  11. domain_context_graph-0.4.0/src/dcg/adapters/graphify.py +233 -0
  12. domain_context_graph-0.4.0/src/dcg/adapters/registry.py +18 -0
  13. domain_context_graph-0.4.0/src/dcg/cli.py +206 -0
  14. domain_context_graph-0.4.0/src/dcg/core/__init__.py +63 -0
  15. domain_context_graph-0.4.0/src/dcg/core/builders.py +68 -0
  16. domain_context_graph-0.4.0/src/dcg/core/model.py +113 -0
  17. domain_context_graph-0.4.0/src/dcg/core/ontology.py +386 -0
  18. domain_context_graph-0.4.0/src/dcg/core/packs/code.yaml +27 -0
  19. domain_context_graph-0.4.0/src/dcg/core/packs/core.yaml +65 -0
  20. domain_context_graph-0.4.0/src/dcg/core/packs/dcg-development.yaml +22 -0
  21. domain_context_graph-0.4.0/src/dcg/core/packs/security.yaml +9 -0
  22. domain_context_graph-0.4.0/src/dcg/core/project.py +247 -0
  23. domain_context_graph-0.4.0/src/dcg/core/purge.py +9 -0
  24. domain_context_graph-0.4.0/src/dcg/core/stack.py +643 -0
  25. domain_context_graph-0.4.0/src/dcg/core/store.py +408 -0
  26. domain_context_graph-0.4.0/src/dcg/core/uid.py +28 -0
  27. domain_context_graph-0.4.0/src/dcg/ingest/__init__.py +58 -0
  28. domain_context_graph-0.4.0/src/dcg/ingest/discovery.py +69 -0
  29. domain_context_graph-0.4.0/src/dcg/ingest/models.py +132 -0
  30. domain_context_graph-0.4.0/src/dcg/ingest/report.py +47 -0
  31. domain_context_graph-0.4.0/src/dcg/ingest/runner.py +295 -0
  32. domain_context_graph-0.4.0/src/dcg/mcp/__init__.py +6 -0
  33. domain_context_graph-0.4.0/src/dcg/mcp/__main__.py +4 -0
  34. domain_context_graph-0.4.0/src/dcg/mcp/dcg_ingest_mcp.py +89 -0
  35. domain_context_graph-0.4.0/src/dcg/mcp/dcg_mcp.py +79 -0
  36. domain_context_graph-0.4.0/src/dcg/mcp/helpers.py +12 -0
  37. domain_context_graph-0.4.0/src/dcg/mcp/state.py +20 -0
  38. domain_context_graph-0.4.0/src/dcg/mcp/tools/__init__.py +1 -0
  39. domain_context_graph-0.4.0/src/dcg/mcp/tools/ingest.py +161 -0
  40. domain_context_graph-0.4.0/src/dcg/mcp/tools/project.py +37 -0
  41. domain_context_graph-0.4.0/src/dcg/mcp/tools/query.py +145 -0
  42. domain_context_graph-0.4.0/src/dcg/mcp/tools/stack.py +99 -0
  43. domain_context_graph-0.4.0/src/dcg/ops/__init__.py +1 -0
  44. domain_context_graph-0.4.0/src/dcg/ops/ingest.py +167 -0
  45. domain_context_graph-0.4.0/src/dcg/ops/lifecycle.py +86 -0
  46. domain_context_graph-0.4.0/src/dcg/ops/ontology.py +37 -0
  47. domain_context_graph-0.4.0/src/dcg/ui/__init__.py +116 -0
  48. domain_context_graph-0.4.0/src/dcg/ui/index.html +12 -0
  49. domain_context_graph-0.4.0/src/dcg/ui/package-lock.json +5172 -0
  50. domain_context_graph-0.4.0/src/dcg/ui/package.json +41 -0
  51. domain_context_graph-0.4.0/src/dcg/ui/src/App.tsx +35 -0
  52. domain_context_graph-0.4.0/src/dcg/ui/src/__tests__/store.test.ts +65 -0
  53. domain_context_graph-0.4.0/src/dcg/ui/src/components/AppShell.tsx +45 -0
  54. domain_context_graph-0.4.0/src/dcg/ui/src/components/AttributeRow.tsx +16 -0
  55. domain_context_graph-0.4.0/src/dcg/ui/src/components/CreateEntityDialog.tsx +82 -0
  56. domain_context_graph-0.4.0/src/dcg/ui/src/components/DetailPanel.tsx +20 -0
  57. domain_context_graph-0.4.0/src/dcg/ui/src/components/DomainFilter.tsx +65 -0
  58. domain_context_graph-0.4.0/src/dcg/ui/src/components/EntityDetail.tsx +229 -0
  59. domain_context_graph-0.4.0/src/dcg/ui/src/components/EntityForm.tsx +117 -0
  60. domain_context_graph-0.4.0/src/dcg/ui/src/components/GraphCanvas.tsx +119 -0
  61. domain_context_graph-0.4.0/src/dcg/ui/src/components/LayerDetail.tsx +53 -0
  62. domain_context_graph-0.4.0/src/dcg/ui/src/components/LayerSwitcher.tsx +34 -0
  63. domain_context_graph-0.4.0/src/dcg/ui/src/components/RelationDetail.tsx +55 -0
  64. domain_context_graph-0.4.0/src/dcg/ui/src/components/RelationRow.tsx +43 -0
  65. domain_context_graph-0.4.0/src/dcg/ui/src/components/SearchInput.tsx +26 -0
  66. domain_context_graph-0.4.0/src/dcg/ui/src/components/Sidebar.tsx +13 -0
  67. domain_context_graph-0.4.0/src/dcg/ui/src/components/StackTopology.tsx +147 -0
  68. domain_context_graph-0.4.0/src/dcg/ui/src/components/StatusBar.tsx +24 -0
  69. domain_context_graph-0.4.0/src/dcg/ui/src/components/Toolbar.tsx +88 -0
  70. domain_context_graph-0.4.0/src/dcg/ui/src/components/TypeFilter.tsx +36 -0
  71. domain_context_graph-0.4.0/src/dcg/ui/src/components/ViewModeToggle.tsx +30 -0
  72. domain_context_graph-0.4.0/src/dcg/ui/src/declarations.d.ts +5 -0
  73. domain_context_graph-0.4.0/src/dcg/ui/src/graph/__tests__/transform.test.ts +114 -0
  74. domain_context_graph-0.4.0/src/dcg/ui/src/graph/layouts.ts +36 -0
  75. domain_context_graph-0.4.0/src/dcg/ui/src/graph/styles.ts +90 -0
  76. domain_context_graph-0.4.0/src/dcg/ui/src/graph/transform.ts +140 -0
  77. domain_context_graph-0.4.0/src/dcg/ui/src/index.css +1 -0
  78. domain_context_graph-0.4.0/src/dcg/ui/src/main.tsx +10 -0
  79. domain_context_graph-0.4.0/src/dcg/ui/src/mcp/McpProvider.tsx +57 -0
  80. domain_context_graph-0.4.0/src/dcg/ui/src/mcp/StaticProvider.tsx +24 -0
  81. domain_context_graph-0.4.0/src/dcg/ui/src/mcp/__tests__/types.test.ts +45 -0
  82. domain_context_graph-0.4.0/src/dcg/ui/src/mcp/client.ts +51 -0
  83. domain_context_graph-0.4.0/src/dcg/ui/src/mcp/hooks.ts +115 -0
  84. domain_context_graph-0.4.0/src/dcg/ui/src/mcp/mutations.ts +128 -0
  85. domain_context_graph-0.4.0/src/dcg/ui/src/mcp/static-client.ts +140 -0
  86. domain_context_graph-0.4.0/src/dcg/ui/src/mcp/types.ts +137 -0
  87. domain_context_graph-0.4.0/src/dcg/ui/src/store.ts +88 -0
  88. domain_context_graph-0.4.0/src/dcg/ui/tsconfig.json +20 -0
  89. domain_context_graph-0.4.0/src/dcg/ui/vite.config.ts +21 -0
  90. domain_context_graph-0.4.0/tests/__init__.py +0 -0
  91. domain_context_graph-0.4.0/tests/unit/__init__.py +0 -0
  92. domain_context_graph-0.4.0/tests/unit/test_adapter_graphify.py +485 -0
  93. domain_context_graph-0.4.0/tests/unit/test_adapter_registry.py +27 -0
  94. domain_context_graph-0.4.0/tests/unit/test_cli.py +130 -0
  95. domain_context_graph-0.4.0/tests/unit/test_compose.py +921 -0
  96. domain_context_graph-0.4.0/tests/unit/test_gap_implementations.py +451 -0
  97. domain_context_graph-0.4.0/tests/unit/test_ingest_cli.py +126 -0
  98. domain_context_graph-0.4.0/tests/unit/test_ingest_discovery.py +158 -0
  99. domain_context_graph-0.4.0/tests/unit/test_ingest_models.py +214 -0
  100. domain_context_graph-0.4.0/tests/unit/test_ingest_runner.py +367 -0
  101. domain_context_graph-0.4.0/tests/unit/test_ingest_tools.py +198 -0
  102. domain_context_graph-0.4.0/tests/unit/test_integration_composition.py +179 -0
  103. domain_context_graph-0.4.0/tests/unit/test_mcp_http.py +38 -0
  104. domain_context_graph-0.4.0/tests/unit/test_mcp_query.py +66 -0
  105. domain_context_graph-0.4.0/tests/unit/test_mcp_server.py +110 -0
  106. domain_context_graph-0.4.0/tests/unit/test_mcp_stack.py +117 -0
  107. domain_context_graph-0.4.0/tests/unit/test_ontology.py +389 -0
  108. domain_context_graph-0.4.0/tests/unit/test_project.py +216 -0
  109. domain_context_graph-0.4.0/tests/unit/test_store.py +449 -0
  110. domain_context_graph-0.4.0/tests/unit/test_uid.py +55 -0
  111. domain_context_graph-0.4.0/utility/README.md +91 -0
  112. domain_context_graph-0.4.0/utility/neo4j_export.py +269 -0
  113. domain_context_graph-0.4.0/utility/requirements.txt +2 -0
  114. domain_context_graph-0.4.0/utility/wikidata_import.py +0 -0
@@ -0,0 +1,74 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ id-token: write
9
+ contents: read
10
+
11
+ jobs:
12
+ test:
13
+ name: Run tests
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ matrix:
17
+ python-version: ["3.10", "3.12"]
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+
25
+ - name: Install package with dev dependencies
26
+ run: pip install -e ".[dev]"
27
+
28
+ - name: Run tests
29
+ run: pytest --tb=short -q
30
+
31
+ build:
32
+ name: Build package
33
+ needs: test
34
+ runs-on: ubuntu-latest
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+
38
+ - uses: actions/setup-python@v5
39
+ with:
40
+ python-version: "3.12"
41
+
42
+ - name: Install build tools
43
+ run: pip install --upgrade build
44
+
45
+ - name: Build sdist and wheel
46
+ run: python -m build
47
+
48
+ - name: Verify package version matches release tag
49
+ run: |
50
+ PKG_VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
51
+ TAG_VERSION="${GITHUB_REF_NAME#v}"
52
+ if [ "$PKG_VERSION" != "$TAG_VERSION" ]; then
53
+ echo "::error::Version mismatch: pyproject.toml=$PKG_VERSION tag=$TAG_VERSION"
54
+ exit 1
55
+ fi
56
+ echo "Version $PKG_VERSION matches tag"
57
+
58
+ - uses: actions/upload-artifact@v4
59
+ with:
60
+ name: dist
61
+ path: dist/
62
+
63
+ publish:
64
+ name: Publish to PyPI
65
+ needs: build
66
+ runs-on: ubuntu-latest
67
+ environment: pypi
68
+ steps:
69
+ - uses: actions/download-artifact@v4
70
+ with:
71
+ name: dist
72
+ path: dist/
73
+
74
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,13 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ .venv/
5
+ *.egg-info/
6
+ dist/
7
+ build/
8
+ .pytest_cache/
9
+ .coverage
10
+
11
+ # React/Node
12
+ node_modules/
13
+ *.tsbuildinfo
@@ -0,0 +1,92 @@
1
+ # DCG Development Guide
2
+
3
+ ## Project
4
+
5
+ `domain-context-graph` (import as `dcg`) — a Wikibase-compatible knowledge graph protocol for grounding AI in verified domain knowledge. Python >=3.10, built with hatchling.
6
+
7
+ ## Setup
8
+
9
+ ```bash
10
+ python -m venv .venv
11
+ .venv/bin/pip install -e ".[dev,ui,ingest]"
12
+ ```
13
+
14
+ ## Data Sources
15
+
16
+ DCG operates in two modes. Always use the right one:
17
+
18
+ - **Single project** (`--project <path>`) — a directory containing `graph_card.json` (metadata) and `graphs/default.json` (graph data). Use for isolated domain graphs.
19
+ - **Stack manifest** (`--stack <path/to/dcg-stack.yml>`) — composes multiple project directories as layers with cross-layer resolution. Manifests support multi-parent `extends` (list) and a `joins` section for cross-layer join rules. Use when working with multi-layer graphs (e.g., security + product + code).
20
+
21
+ The `--stack` path is relative to the manifest file's parent directory for layer `source` fields.
22
+
23
+ ## CLI Commands
24
+
25
+ ```
26
+ dcg init <name> [--path .] [--description ""] # Create a new domain project
27
+ dcg compose <manifest> # Validate/inspect a stack manifest
28
+ dcg compact <path> # Compact layers in a project
29
+ dcg query <path> [--type Function] [--domain X] # Query entities (single project)
30
+ dcg ui [<path>] [--stack <manifest>] [--port 8080] # Launch graph explorer web UI
31
+ ```
32
+
33
+ `dcg ui` accepts either a positional project path or `--stack` (mutually exclusive). At least one is required.
34
+
35
+ ## MCP Server
36
+
37
+ ```
38
+ dcg-mcp --project <path> # Single project
39
+ dcg-mcp --stack <manifest> [--layer <name>] # Stack mode
40
+ dcg-mcp --stack <manifest> --no-strict # Skip strict ontology validation
41
+ ```
42
+
43
+ `--project` and `--stack` are mutually exclusive and required. The `--no-strict` flag disables strict ontology validation — use it for read-only access to data that may not meet current strict rules. The UI passes this automatically for stack mode.
44
+
45
+ ## Architecture
46
+
47
+ ```
48
+ src/dcg/
49
+ core/ # GraphStore, ontology, compose (DcgStack, JoinRule), merge, UID generation
50
+ mcp/ # MCP server (FastMCP), tools (query, ingest, stack, project)
51
+ ops/ # Higher-level operations: ingest pipelines, lifecycle, ontology mgmt
52
+ ui/ # NiceGUI web explorer — app, MCP client, transform, components
53
+ cli.py # CLI entry point
54
+ project.py # DomainProject — file-based persistence (graph_card.json + graphs/)
55
+ ```
56
+
57
+ ### Key classes
58
+
59
+ - `GraphStore` — in-memory graph with entities, relations, layered history
60
+ - `DomainProject` — manages a project directory (`graph_card.json` for metadata + `graphs/` for graph data)
61
+ - `DcgStack` — composes multiple projects as layers; `from_project()` wraps a single project as a 1-layer stack
62
+ - `JoinRule` — declarative cross-layer join rule; cross-layer relations are materialized at stack level, not stored in layer data
63
+ - `McpClient` (ui) — async stdio MCP client wrapper; uses `_call()` for single values, `_call_list()` for lists (FastMCP splits list returns into one TextContent per element)
64
+
65
+ ### Entity/relation format
66
+
67
+ - Entity UID: `dcg:sha256:<hash>` (content-addressed) or `dcg:meta:<Name>` (type definitions)
68
+ - Relation UID: `dcg:rel:sha256:<hash>`
69
+ - Entity: `{"id": str, "label": str, "description": str, "attributes": [{"property": str, "ref"|"string"|"quantity": value}]}`
70
+ - Relation: `{"dcg:type": "relation", "uid": str, "source": str, "target": str, "property": str}`
71
+
72
+ ## Testing
73
+
74
+ ```bash
75
+ .venv/bin/pytest # Run all tests
76
+ .venv/bin/pytest tests/unit/ -v # Verbose
77
+ .venv/bin/pytest -k test_compose # Filter by name
78
+ ```
79
+
80
+ Tests live in `tests/unit/`. No conftest.py — fixtures are defined per-file. Async tests use `pytest-asyncio` with `mode=strict`.
81
+
82
+ ## Rules
83
+
84
+ - **`graph_card.json` is metadata-only.** It holds project name, description, and ontology declarations. Entities and relations live in `graphs/default.json` (and other named graphs). Never store graph data in `graph_card.json`.
85
+ - **No `ontology.yaml`.** Ontology definitions are inlined in `graph_card.json` under the `ontology` key. The separate `ontology.yaml` file has been removed.
86
+ - **Stack ontology loads before project data.** `DcgStack.load()` injects the manifest's ontology declarations into each project's store before calling `project.load()`. This is load-order sensitive — do not move ontology injection after project loading.
87
+ - **Cross-layer relations are read-only.** They are materialized at stack level from `JoinRule` definitions in the manifest's `joins` section. Do not store cross-layer relations in individual layer data.
88
+ - **Stack manifests support multi-parent `extends`.** The `extends` field in a layer entry accepts either a single string or a list of layer names. Resolution follows BFS topological order; DAG cycles are rejected at load time.
89
+ - **FastMCP list serialization quirk.** MCP tools returning `list[dict]` are split into one TextContent per element, not a single JSON array. The `McpClient._call_list()` method handles this. Use `_call()` for single-value returns, `_call_list()` for list returns.
90
+ - **`DomainProject.load()` does not restore layers.** Only entities and relations are loaded from `graphs/default.json`. Layer history is not persisted through load/save cycles.
91
+ - **No backward compatibility before v1.0.** Breaking changes are expected. No deprecation shims or re-exports for removed code.
92
+ - **Internal docs go in the workspace.** Specs, plans, and design docs belong in `projects/dcg/` at the workspace root — not in this repo. Only public-facing documentation goes here.
@@ -0,0 +1,186 @@
1
+ Metadata-Version: 2.4
2
+ Name: domain-context-graph
3
+ Version: 0.4.0
4
+ Summary: Domain Context Graph protocol for grounding AI in verified domain knowledge.
5
+ License-Expression: Apache-2.0
6
+ Keywords: ai-grounding,domain-graph,domain-model,graph-protocol,llm-context
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: License :: OSI Approved :: Apache Software License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Topic :: Database :: Database Engines/Servers
12
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
13
+ Requires-Python: >=3.10
14
+ Requires-Dist: mcp>=1.27
15
+ Requires-Dist: pyyaml>=6.0
16
+ Provides-Extra: dev
17
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
18
+ Requires-Dist: pytest>=7.0; extra == 'dev'
19
+ Provides-Extra: ingest
20
+ Requires-Dist: requests>=2.28; extra == 'ingest'
21
+ Provides-Extra: ui
22
+ Description-Content-Type: text/markdown
23
+
24
+ # Domain Context Graph (DCG)
25
+
26
+ **An open protocol for structuring domain knowledge so AI systems reason about your product — not just your code.**
27
+
28
+ ---
29
+
30
+ ## The Problem
31
+
32
+ AI coding assistants write confident code that violates business rules nobody documented. Security scanners flag vulnerabilities without knowing which domain owns the affected service. Incident responders trace call graphs without understanding blast radius across business capabilities.
33
+
34
+ - **LLM training data is generic.** Models know what "payments" means in general — not what *your* Payments domain is, who owns it, or what depends on it.
35
+ - **Code graphs capture structure, not semantics.** They see imports and call chains — not that two modules serve the same bounded context.
36
+ - **Documentation decays instantly.** Wikis are stale, unstructured, and not machine-queryable.
37
+ - **Knowledge is tool-siloed.** Your security scanner's vulnerability data can't connect to your code graph's ownership data because there's no shared schema.
38
+
39
+ DCG fills this gap: a **standard, machine-readable protocol** for domain knowledge that any AI system can consume — versioned, git-backed, and federated across teams and repos.
40
+
41
+ ## Core Concepts
42
+
43
+ - **Wikibase-compatible entities** — same JSON format used by Wikidata's 100M+ items. Labels, descriptions, aliases, and attributes with full snak structure.
44
+ - **Content-addressed identity** — entity UIDs are deterministic hashes (`dcg:sha256:...`). Same entity always gets the same ID, regardless of who creates it or when.
45
+ - **Two-axis classification** — every entity has a structural type (`instance of` Function/Class/Endpoint) and domain membership (`part of` Payments/Security). These are orthogonal.
46
+ - **Retraction and purge** — entities can be retracted (soft-deleted) and later permanently purged from the graph.
47
+ - **Composition** — stack multiple domain graphs via `dcg-stack.yml` manifests with `extends` chains. Query across layers; entities resolve upward through the chain.
48
+ - **Federation** — multiple graphs reference each other's entities via cross-graph resolution. Each team owns their graph independently.
49
+
50
+ ## Install
51
+
52
+ ```bash
53
+ pip install domain-context-graph
54
+ ```
55
+
56
+ With git-backed persistence:
57
+
58
+ ```bash
59
+ pip install domain-context-graph[git]
60
+ ```
61
+
62
+ ## Quick Start
63
+
64
+ ```python
65
+ from dcg.core import GraphStore, entity_uid, builders as kb
66
+
67
+ store = GraphStore()
68
+
69
+ # Define a domain
70
+ payments_uid = entity_uid(name="Payments")
71
+ store.add_entity(kb.entity(
72
+ uid=payments_uid,
73
+ label="Payments",
74
+ description="Payment processing domain",
75
+ attributes=[kb.attribute("instance of", kb.ref_value("dcg:meta:Domain"))],
76
+ ))
77
+
78
+ # Place a code entity in that domain
79
+ fn_uid = entity_uid(name="charge_card", path="src/payments/charge.py")
80
+ store.add_entity(kb.entity(
81
+ uid=fn_uid,
82
+ label="charge_card",
83
+ attributes=[
84
+ kb.attribute("instance of", kb.ref_value("dcg:meta:Function")),
85
+ kb.attribute("part of", kb.ref_value(payments_uid)),
86
+ kb.attribute("file path", kb.string_value("src/payments/charge.py")),
87
+ ],
88
+ ))
89
+
90
+ # Query
91
+ functions = store.query(instance_of="dcg:meta:Function")
92
+ ```
93
+
94
+ ## CLI
95
+
96
+ ```bash
97
+ dcg init <name> [--path .] [--description "..."] # Create a new domain graph project
98
+ dcg serve --project <path> # Start MCP server (single project)
99
+ dcg serve --stack <manifest> # Start MCP server (multi-layer stack)
100
+ dcg compose <manifest> # Validate a dcg-stack.yml manifest
101
+ dcg purge <path> # Remove retracted entities and relations
102
+ dcg query <path> [--type Function] [--domain Pay] # Query entities
103
+ ```
104
+
105
+ ## MCP Server
106
+
107
+ DCG includes a built-in [Model Context Protocol](https://modelcontextprotocol.io) server with 28 tools for reading, writing, and querying domain graphs.
108
+
109
+ ```bash
110
+ # Single project
111
+ dcg serve --project ./my-graph
112
+
113
+ # Multi-layer stack (cross-layer queries)
114
+ dcg serve --stack ./dcg-stack.yml
115
+ ```
116
+
117
+ Tools include `dcg_create_entity`, `dcg_create_domain`, `dcg_connect`, `dcg_query`, `dcg_snapshot`, `dcg_bulk_add`, and more. Stack-mode adds `dcg_stack_info`, `dcg_query_stack`, and `dcg_resolve_cross_layer`.
118
+
119
+ ## Composition
120
+
121
+ Stack multiple domain graphs with a `dcg-stack.yml` manifest:
122
+
123
+ ```yaml
124
+ stack: my-appsec-stack
125
+ layers:
126
+ - name: security
127
+ source: ./graphs/security-domain
128
+
129
+ - name: product
130
+ source: ./graphs/product-domain
131
+ extends: security
132
+
133
+ - name: code
134
+ source: ./graphs/code
135
+ extends: product
136
+ ```
137
+
138
+ The `extends` chain defines resolution order. When querying the `code` layer for an entity, DCG walks `code` → `product` → `security` until found. Cross-layer queries deduplicate by UID (nearest layer wins).
139
+
140
+ ## Package Structure
141
+
142
+ ```
143
+ src/dcg/
144
+ __init__.py # Public API re-exports
145
+ cli.py # CLI entry point (dcg command)
146
+ project.py # DomainProject — manifest-based project manager
147
+ core/
148
+ uid.py # Content-addressed entity/relation IDs
149
+ model.py # Entity, Relation, Attribute dataclasses
150
+ ontology.py # Type and property registries
151
+ builders.py # Wikibase JSON entity/attribute construction
152
+ store.py # GraphStore — in-memory implementation
153
+ compose.py # DcgStack — multi-project composition
154
+ federation.py # Cross-graph registry and resolution
155
+ purge.py # Retraction purge
156
+ git_store.py # GitGraphStore — dulwich-backed persistence
157
+ mcp/
158
+ server.py # FastMCP server (28 tools)
159
+ helpers.py # Shared MCP utilities
160
+ ```
161
+
162
+ ## Specification
163
+
164
+ | Document | Description |
165
+ |----------|-------------|
166
+ | [RFC DCG-002](spec/rfc.md) | Formal protocol specification (IETF RFC 2119). Defines Core, Persistent, and Federated conformance levels. |
167
+ | [Design Spec](spec/design.md) | Full architecture, entity model, ontology, and integration patterns. |
168
+
169
+ The RFC is the authoritative source. This Python package is one implementation — others can implement the same spec in any language.
170
+
171
+ ## Extensibility
172
+
173
+ - **Custom domains** — `register_global_type()` to add domain-specific types
174
+ - **Custom properties** — `register_property()` with Wikidata P-ID aliases
175
+ - **Custom backends** — implement `GraphStoreProtocol` for any storage
176
+ - **Federation** — implement `GraphRegistry` and `BoundaryResolver` for cross-graph resolution
177
+
178
+ ## Related Projects
179
+
180
+ | Project | Description |
181
+ |---------|-------------|
182
+ | [appsec-ctx-graph](https://github.me/atishio/appsec-ctx-graph) | 3-layer security + product + code domain graph built on DCG |
183
+
184
+ ## License
185
+
186
+ Apache-2.0
@@ -0,0 +1,163 @@
1
+ # Domain Context Graph (DCG)
2
+
3
+ **An open protocol for structuring domain knowledge so AI systems reason about your product — not just your code.**
4
+
5
+ ---
6
+
7
+ ## The Problem
8
+
9
+ AI coding assistants write confident code that violates business rules nobody documented. Security scanners flag vulnerabilities without knowing which domain owns the affected service. Incident responders trace call graphs without understanding blast radius across business capabilities.
10
+
11
+ - **LLM training data is generic.** Models know what "payments" means in general — not what *your* Payments domain is, who owns it, or what depends on it.
12
+ - **Code graphs capture structure, not semantics.** They see imports and call chains — not that two modules serve the same bounded context.
13
+ - **Documentation decays instantly.** Wikis are stale, unstructured, and not machine-queryable.
14
+ - **Knowledge is tool-siloed.** Your security scanner's vulnerability data can't connect to your code graph's ownership data because there's no shared schema.
15
+
16
+ DCG fills this gap: a **standard, machine-readable protocol** for domain knowledge that any AI system can consume — versioned, git-backed, and federated across teams and repos.
17
+
18
+ ## Core Concepts
19
+
20
+ - **Wikibase-compatible entities** — same JSON format used by Wikidata's 100M+ items. Labels, descriptions, aliases, and attributes with full snak structure.
21
+ - **Content-addressed identity** — entity UIDs are deterministic hashes (`dcg:sha256:...`). Same entity always gets the same ID, regardless of who creates it or when.
22
+ - **Two-axis classification** — every entity has a structural type (`instance of` Function/Class/Endpoint) and domain membership (`part of` Payments/Security). These are orthogonal.
23
+ - **Retraction and purge** — entities can be retracted (soft-deleted) and later permanently purged from the graph.
24
+ - **Composition** — stack multiple domain graphs via `dcg-stack.yml` manifests with `extends` chains. Query across layers; entities resolve upward through the chain.
25
+ - **Federation** — multiple graphs reference each other's entities via cross-graph resolution. Each team owns their graph independently.
26
+
27
+ ## Install
28
+
29
+ ```bash
30
+ pip install domain-context-graph
31
+ ```
32
+
33
+ With git-backed persistence:
34
+
35
+ ```bash
36
+ pip install domain-context-graph[git]
37
+ ```
38
+
39
+ ## Quick Start
40
+
41
+ ```python
42
+ from dcg.core import GraphStore, entity_uid, builders as kb
43
+
44
+ store = GraphStore()
45
+
46
+ # Define a domain
47
+ payments_uid = entity_uid(name="Payments")
48
+ store.add_entity(kb.entity(
49
+ uid=payments_uid,
50
+ label="Payments",
51
+ description="Payment processing domain",
52
+ attributes=[kb.attribute("instance of", kb.ref_value("dcg:meta:Domain"))],
53
+ ))
54
+
55
+ # Place a code entity in that domain
56
+ fn_uid = entity_uid(name="charge_card", path="src/payments/charge.py")
57
+ store.add_entity(kb.entity(
58
+ uid=fn_uid,
59
+ label="charge_card",
60
+ attributes=[
61
+ kb.attribute("instance of", kb.ref_value("dcg:meta:Function")),
62
+ kb.attribute("part of", kb.ref_value(payments_uid)),
63
+ kb.attribute("file path", kb.string_value("src/payments/charge.py")),
64
+ ],
65
+ ))
66
+
67
+ # Query
68
+ functions = store.query(instance_of="dcg:meta:Function")
69
+ ```
70
+
71
+ ## CLI
72
+
73
+ ```bash
74
+ dcg init <name> [--path .] [--description "..."] # Create a new domain graph project
75
+ dcg serve --project <path> # Start MCP server (single project)
76
+ dcg serve --stack <manifest> # Start MCP server (multi-layer stack)
77
+ dcg compose <manifest> # Validate a dcg-stack.yml manifest
78
+ dcg purge <path> # Remove retracted entities and relations
79
+ dcg query <path> [--type Function] [--domain Pay] # Query entities
80
+ ```
81
+
82
+ ## MCP Server
83
+
84
+ DCG includes a built-in [Model Context Protocol](https://modelcontextprotocol.io) server with 28 tools for reading, writing, and querying domain graphs.
85
+
86
+ ```bash
87
+ # Single project
88
+ dcg serve --project ./my-graph
89
+
90
+ # Multi-layer stack (cross-layer queries)
91
+ dcg serve --stack ./dcg-stack.yml
92
+ ```
93
+
94
+ Tools include `dcg_create_entity`, `dcg_create_domain`, `dcg_connect`, `dcg_query`, `dcg_snapshot`, `dcg_bulk_add`, and more. Stack-mode adds `dcg_stack_info`, `dcg_query_stack`, and `dcg_resolve_cross_layer`.
95
+
96
+ ## Composition
97
+
98
+ Stack multiple domain graphs with a `dcg-stack.yml` manifest:
99
+
100
+ ```yaml
101
+ stack: my-appsec-stack
102
+ layers:
103
+ - name: security
104
+ source: ./graphs/security-domain
105
+
106
+ - name: product
107
+ source: ./graphs/product-domain
108
+ extends: security
109
+
110
+ - name: code
111
+ source: ./graphs/code
112
+ extends: product
113
+ ```
114
+
115
+ The `extends` chain defines resolution order. When querying the `code` layer for an entity, DCG walks `code` → `product` → `security` until found. Cross-layer queries deduplicate by UID (nearest layer wins).
116
+
117
+ ## Package Structure
118
+
119
+ ```
120
+ src/dcg/
121
+ __init__.py # Public API re-exports
122
+ cli.py # CLI entry point (dcg command)
123
+ project.py # DomainProject — manifest-based project manager
124
+ core/
125
+ uid.py # Content-addressed entity/relation IDs
126
+ model.py # Entity, Relation, Attribute dataclasses
127
+ ontology.py # Type and property registries
128
+ builders.py # Wikibase JSON entity/attribute construction
129
+ store.py # GraphStore — in-memory implementation
130
+ compose.py # DcgStack — multi-project composition
131
+ federation.py # Cross-graph registry and resolution
132
+ purge.py # Retraction purge
133
+ git_store.py # GitGraphStore — dulwich-backed persistence
134
+ mcp/
135
+ server.py # FastMCP server (28 tools)
136
+ helpers.py # Shared MCP utilities
137
+ ```
138
+
139
+ ## Specification
140
+
141
+ | Document | Description |
142
+ |----------|-------------|
143
+ | [RFC DCG-002](spec/rfc.md) | Formal protocol specification (IETF RFC 2119). Defines Core, Persistent, and Federated conformance levels. |
144
+ | [Design Spec](spec/design.md) | Full architecture, entity model, ontology, and integration patterns. |
145
+
146
+ The RFC is the authoritative source. This Python package is one implementation — others can implement the same spec in any language.
147
+
148
+ ## Extensibility
149
+
150
+ - **Custom domains** — `register_global_type()` to add domain-specific types
151
+ - **Custom properties** — `register_property()` with Wikidata P-ID aliases
152
+ - **Custom backends** — implement `GraphStoreProtocol` for any storage
153
+ - **Federation** — implement `GraphRegistry` and `BoundaryResolver` for cross-graph resolution
154
+
155
+ ## Related Projects
156
+
157
+ | Project | Description |
158
+ |---------|-------------|
159
+ | [appsec-ctx-graph](https://github.me/atishio/appsec-ctx-graph) | 3-layer security + product + code domain graph built on DCG |
160
+
161
+ ## License
162
+
163
+ Apache-2.0
@@ -0,0 +1,17 @@
1
+ # DCG — TODO
2
+
3
+ ## dcg CLI (`~/Documents/kit/dcg`)
4
+
5
+ ### Remove hardcoded `dcg ingest`
6
+
7
+ **Why:** `dcg ingest` is not generic — it has Wikidata SPARQL queries and the entire Gartner WAAP taxonomy hardcoded in `src/dcg/ingest.py`. It only produces a security domain graph and cannot be configured for other domains.
8
+
9
+ **What to do:**
10
+
11
+ - [ ] Remove `ingest.py` from `src/dcg/`
12
+ - [ ] Remove the `ingest` subcommand from the CLI entrypoint
13
+ - [ ] Remove the `requests` optional dependency (`domain-context-graph[ingest]`)
14
+ - [ ] Move Wikidata+WAAP import logic into `dcg-security-domain` repo as a standalone bootstrap script (e.g., `scripts/bootstrap.py`) — that's where domain-specific seeding belongs
15
+ - [ ] Update `dcg --help` / README to reflect removal
16
+
17
+ **Principle:** `dcg` CLI should be domain-agnostic. Domain-specific data sources belong in the domain project repos, not in the core tool.
@@ -0,0 +1,43 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "domain-context-graph"
7
+ version = "0.4.0"
8
+ description = "Domain Context Graph protocol for grounding AI in verified domain knowledge."
9
+ readme = "README.md"
10
+ license = "Apache-2.0"
11
+ requires-python = ">=3.10"
12
+ dependencies = [
13
+ "pyyaml>=6.0",
14
+ "mcp>=1.27",
15
+ ]
16
+ keywords = ["domain-graph", "ai-grounding", "llm-context", "graph-protocol", "domain-model"]
17
+ classifiers = [
18
+ "Development Status :: 3 - Alpha",
19
+ "Intended Audience :: Developers",
20
+ "License :: OSI Approved :: Apache Software License",
21
+ "Programming Language :: Python :: 3",
22
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
23
+ "Topic :: Database :: Database Engines/Servers",
24
+ ]
25
+
26
+ [project.optional-dependencies]
27
+ ingest = ["requests>=2.28"]
28
+ ui = []
29
+ dev = [
30
+ "pytest>=7.0",
31
+ "pytest-cov>=4.0",
32
+ ]
33
+
34
+ [project.scripts]
35
+ dcg = "dcg.cli:main"
36
+ dcg-mcp = "dcg.mcp:main"
37
+ dcg-ingest-mcp = "dcg.mcp.dcg_ingest_mcp:main"
38
+
39
+ [tool.hatch.build.targets.wheel]
40
+ packages = ["src/dcg"]
41
+
42
+ [tool.pytest.ini_options]
43
+ testpaths = ["tests"]
@@ -0,0 +1,41 @@
1
+ """DCG — Domain Context Graph."""
2
+
3
+ from dcg.core import (
4
+ entity_uid,
5
+ relation_uid,
6
+ Entity,
7
+ Relation,
8
+ SCHEMA_VERSION,
9
+ TYPE_REGISTRY,
10
+ PROPERTY_REGISTRY,
11
+ register_global_type,
12
+ register_property,
13
+ register_alias,
14
+ resolve_property,
15
+ GraphStore,
16
+ GraphStoreProtocol,
17
+ StackLoader,
18
+ DomainProject,
19
+ purge_retracted,
20
+ builders,
21
+ )
22
+
23
+ __all__ = [
24
+ "entity_uid",
25
+ "relation_uid",
26
+ "Entity",
27
+ "Relation",
28
+ "SCHEMA_VERSION",
29
+ "TYPE_REGISTRY",
30
+ "PROPERTY_REGISTRY",
31
+ "register_global_type",
32
+ "register_property",
33
+ "register_alias",
34
+ "resolve_property",
35
+ "GraphStore",
36
+ "GraphStoreProtocol",
37
+ "StackLoader",
38
+ "DomainProject",
39
+ "purge_retracted",
40
+ "builders",
41
+ ]
@@ -0,0 +1,8 @@
1
+ """DCG adapters — pluggable backends for loading layers from external sources."""
2
+ from .base import AdapterProxy, LayerAdapterProtocol
3
+ from .graphify import GraphifyAdapter
4
+ from .registry import register
5
+
6
+ register("graphify", GraphifyAdapter)
7
+
8
+ __all__ = ["AdapterProxy", "GraphifyAdapter", "LayerAdapterProtocol"]