1
0
Fork 0
Code Issues Pull requests Projects Releases 2 Packages Wiki Activity Actions Pages

Complete DFG-8 adapter proposal support

This commit is contained in:
Andraxion 2026-07-22 11:50:49 -04:00
parent f1e31487c0
commit 591bf0ae7d
14 changed files with 525 additions and 75 deletions

View file

@ -7,6 +7,7 @@ import json
import subprocess
import tomllib
from collections import Counter
from collections.abc import Mapping
from dataclasses import replace
from pathlib import Path
from typing import Any
@ -500,6 +501,46 @@ def validate_graph(nodes: tuple[Node, ...], edges: tuple[Edge, ...]) -> None:
visit(node_id, ())
def validate_source_layout(nodes: tuple[Node, ...]) -> None:
"""Validate the generic Markdown and TOML source-layout contract."""
markdown_sources: dict[str, list[str]] = {}
anchors: dict[tuple[str, str], list[str]] = {}
for node in nodes:
if Path(node.source_path).suffix == ".md":
markdown_sources.setdefault(node.source_path, []).append(node.node_id)
continue
if not node.source_anchor:
raise DocForgeError(
"source_anchor_required",
"TOML nodes require a stable source anchor",
node_id=node.node_id,
)
anchors.setdefault((node.source_path, node.source_anchor), []).append(node.node_id)
markdown_conflicts = {
source: sorted(node_ids)
for source, node_ids in markdown_sources.items()
if len(node_ids) > 1
}
if markdown_conflicts:
raise DocForgeError(
"source_conflict",
"Markdown sources may contain only one node",
sources=markdown_conflicts,
)
anchor_conflicts = [
{"source": source, "source_anchor": anchor, "nodes": sorted(node_ids)}
for (source, anchor), node_ids in sorted(anchors.items())
if len(node_ids) > 1
]
if anchor_conflicts:
raise DocForgeError(
"source_anchor_conflict",
"TOML source anchors must be unique within their source",
conflicts=anchor_conflicts,
)
def _revision(root: Path) -> str:
try:
result = subprocess.run(
@ -588,7 +629,7 @@ class Project:
digest.update(relative.encode())
digest.update(b"\0")
digest.update(hashlib.sha256(captured[path]).digest())
digest.update(b"docforge-core:0.5.0:index:1")
digest.update(b"docforge-core:0.6.0:index:1")
return ProjectSnapshot(
descriptor=self.descriptor,
nodes=ordered_nodes,
@ -617,3 +658,14 @@ class Project:
if not ordered_sources:
raise DocForgeError("empty_project", "No canonical Markdown or TOML sources were found")
return tuple(ordered_sources)
def validate_proposal(
self,
base: ProjectSnapshot,
projected: ProjectSnapshot,
operations: tuple[Mapping[str, object], ...],
) -> None:
"""Generic sources require no policy beyond the core proposal validation."""
del base, operations
validate_source_layout(projected.nodes)