Add versioned independent projection contracts
This commit is contained in:
parent
4c5773c865
commit
96e3965855
22 changed files with 3561 additions and 133 deletions
|
|
@ -506,11 +506,11 @@ class VisualizationIndexSnapshot:
|
|||
)
|
||||
|
||||
def source(self, node_id: str) -> dict[str, object]:
|
||||
"""Return one node's bounded, project-confined UTF-8 source file."""
|
||||
"""Return bounded source evidence stored in the pinned index generation."""
|
||||
|
||||
with self._connection() as connection:
|
||||
row = connection.execute(
|
||||
"SELECT node_id, source_path, source_anchor FROM nodes WHERE node_id = ?",
|
||||
"SELECT node_id, source_path, source_anchor, content FROM nodes WHERE node_id = ?",
|
||||
(node_id,),
|
||||
).fetchone()
|
||||
if row is None:
|
||||
|
|
@ -518,7 +518,8 @@ class VisualizationIndexSnapshot:
|
|||
"""
|
||||
SELECT logic.logic_id AS node_id,
|
||||
owner.source_path AS source_path,
|
||||
logic.source_anchor AS source_anchor
|
||||
logic.source_anchor AS source_anchor,
|
||||
owner.content AS content
|
||||
FROM logic_nodes AS logic
|
||||
JOIN nodes AS owner ON owner.node_id = logic.owner_node_id
|
||||
WHERE logic.logic_id = ?
|
||||
|
|
@ -533,51 +534,26 @@ class VisualizationIndexSnapshot:
|
|||
"No node has the requested stable ID",
|
||||
node_id=node_id,
|
||||
)
|
||||
relative = Path(row["source_path"])
|
||||
if relative.is_absolute() or ".." in relative.parts or not relative.parts:
|
||||
raise DocForgeError("path_escape", "Node source path is unsafe", node_id=node_id)
|
||||
source = self.project_root / relative
|
||||
try:
|
||||
resolved = source.resolve(strict=True)
|
||||
except OSError as error:
|
||||
content = row["content"]
|
||||
if not isinstance(content, str):
|
||||
raise DocForgeError(
|
||||
"missing_source",
|
||||
"Node source file is unavailable",
|
||||
node_id=node_id,
|
||||
) from error
|
||||
if (
|
||||
source.is_symlink()
|
||||
or resolved != source
|
||||
or not source.is_relative_to(self.project_root)
|
||||
or not source.is_file()
|
||||
):
|
||||
raise DocForgeError("path_escape", "Node source file is unsafe", node_id=node_id)
|
||||
if source.stat().st_size > self.max_source_bytes:
|
||||
raise DocForgeError(
|
||||
"source_too_large",
|
||||
"Node source exceeds the configured source limit",
|
||||
"invalid_index",
|
||||
"Pinned source evidence is invalid",
|
||||
node_id=node_id,
|
||||
)
|
||||
raw = source.read_bytes()
|
||||
raw = content.encode("utf-8")
|
||||
if len(raw) > self.max_source_bytes:
|
||||
raise DocForgeError(
|
||||
"source_too_large",
|
||||
"Node source exceeds the configured source limit",
|
||||
"Pinned source evidence exceeds the configured source limit",
|
||||
node_id=node_id,
|
||||
)
|
||||
try:
|
||||
content = raw.decode("utf-8")
|
||||
except UnicodeDecodeError as error:
|
||||
raise DocForgeError(
|
||||
"invalid_source",
|
||||
"Node source is not UTF-8",
|
||||
node_id=node_id,
|
||||
) from error
|
||||
return self._result(
|
||||
node_id=node_id,
|
||||
source_path=row["source_path"],
|
||||
source_anchor=row["source_anchor"],
|
||||
content=content,
|
||||
source_provenance="index_snapshot",
|
||||
snapshot=True,
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue