Skip to content

Commit 5d0684e

Browse files
committed
Keep unsafe foundation prose out of publication without losing approvals
1 parent b205599 commit 5d0684e

2 files changed

Lines changed: 110 additions & 0 deletions

File tree

‎src/infermatrix_copilot/kb_service/init_knowledge_parallel.py‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@ def offered_ranges(items):
4545
return ranges
4646

4747

48+
def local_privacy_reason(text):
49+
"""Match the knowledge-tree IPv4 rule without echoing its matched value."""
50+
if any(not match.group().startswith("127.") for match in
51+
re.finditer(r"(?<![\w.])(?:\d{1,3}\.){3}\d{1,3}(?![\w.])", text)):
52+
return ("local publication exclusion: literal IPv4; use <REMOTE_HOST> or describe "
53+
"wildcard binding in words while preserving the source contract. "
54+
"The original native approval is unchanged.")
55+
return ""
56+
57+
4858
def related_test_sources(stage, paths, limit=20_000):
4959
"""Shared-index localization only: direct imports, symbols and real assertions.
5060
@@ -389,6 +399,12 @@ def _apply(stage, result):
389399
stage.record.unfinished.extend(result["unfinished"])
390400
accepted = []
391401
for artifact in result["artifacts"]:
402+
reason = local_privacy_reason(artifact["text"]) if stage.rt.unlimited_subscription else ""
403+
if reason:
404+
stage.record.dropped.append({"rule_id": artifact["key"], "page": artifact["page"],
405+
"why": reason, "local_publication_exclusion": True})
406+
stage.record.unfinished.append(f"{artifact['key']}: {reason}")
407+
continue # Original body, result hash and native pass remain immutable.
392408
item = stage._append_approved(Owner(artifact["owner"], artifact["page"], ()),
393409
artifact["page"], artifact["title"], artifact["facet"], artifact["text"],
394410
[Evidence.from_dict(e) for e in artifact["evidence"]])
@@ -516,6 +532,13 @@ def _with_review_feedback(stage, jobs, saved):
516532
"last_error": latest.get("error", ""),
517533
"last_dropped_reasons": [p["why"] for p in latest.get("dropped", [])
518534
if p.get("rule_id") == key and p.get("page") == original["page"]]}
535+
for artifact in latest.get("artifacts", []):
536+
if (artifact.get("key") == key and artifact.get("owner") == original["owner"].owner
537+
and artifact.get("page") == original["page"] and artifact.get("facet") == facet):
538+
reason = local_privacy_reason(artifact["text"])
539+
if reason:
540+
feedback[facet]["last_local_publication_reasons"] = [reason]
541+
feedback[facet]["prior_artifact_text_sha256"] = artifact["text_sha256"]
519542
if not requested:
520543
continue
521544
if not feedback and requested == original["requested"]:
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
"""Publication eligibility stays separate from immutable native approval."""
2+
import copy
3+
import hashlib
4+
from types import SimpleNamespace
5+
6+
from infermatrix_copilot.kb_service import init_knowledge_parallel as parallel
7+
from infermatrix_copilot.kb_service.init_support import InitRecord
8+
from test_kb_foundation_context import _audit_stage
9+
from test_kb_foundation_feedback import _stage_job, _task
10+
from test_kb_foundation_parallel import _complete_native
11+
from test_kb_init_knowledge import KnowledgeGateway
12+
from test_kb_init_skeleton import world # noqa: F401
13+
14+
15+
def test_genuine_old_native_pass_is_locally_declined_without_mutating_proof(world, monkeypatch):
16+
original = KnowledgeGateway.call_json
17+
def historical(self, role, **kwargs):
18+
reply = original(self, role, **kwargs)
19+
if role.name == "generator":
20+
for section in reply.data.get("sections", []):
21+
if section["facet"] == "tradeoffs":
22+
section["body"] += " Example wildcard host: `0.0.0.0`."
23+
return reply
24+
# Simulate genuine previously accepted native prose before local publication
25+
# checks; only the offline fixture's old tree/privacy gate is bypassed.
26+
with monkeypatch.context() as old:
27+
old.setattr(KnowledgeGateway, "call_json", historical)
28+
old.setattr(parallel, "local_privacy_reason", lambda text: "")
29+
old.setattr("infermatrix_copilot.kb_service.init_stages.run_knowledge_validators", lambda *a: [])
30+
rt, record, offline, traces = _complete_native(world)
31+
before = copy.deepcopy(record.coverage["foundation_jobs"])
32+
native_bytes = {p: p.read_bytes() for p in (rt.state_dir / "init" / "traces" / "records").glob("*.jsonl")}
33+
count = len(offline.calls)
34+
parallel.validate_checkpoint(_audit_stage(rt, record), record, record.inputs_digest)
35+
task = next(iter(before["tasks"].values()))
36+
applied = []
37+
stage = SimpleNamespace(rt=rt, record=InitRecord("knowledge", "toy"),
38+
_append_approved=lambda *args: applied.append(args[3]) or args[3])
39+
# The exact task already passed the unchanged full native/source replay above.
40+
monkeypatch.setattr(parallel, "_validate_result", lambda *a: None)
41+
parallel._apply(stage, task)
42+
assert "tradeoffs" not in applied and len(applied) == len(task["artifacts"]) - 1
43+
assert stage.record.verdicts["knowledge:" + task["owner"] + ":tradeoffs"]["verdict"] == "pass"
44+
assert stage.record.dropped[-1]["local_publication_exclusion"] is True
45+
assert "0.0.0.0" not in str(stage.record.dropped) + str(stage.record.unfinished)
46+
assert record.coverage["foundation_jobs"] == before and len(offline.calls) == count
47+
assert {p: p.read_bytes() for p in native_bytes} == native_bytes
48+
49+
50+
def test_feedback_recomputes_only_matching_latest_artifact_local_problem():
51+
stage, job = _stage_job()
52+
prior = _task(job, verdict="pass")
53+
text = "Listen on 0.0.0.0 for wildcard IPv4 interfaces."
54+
artifact = {"key": "knowledge:sample:api", "owner": "sample", "page": job["page"],
55+
"facet": "api", "text": text, "text_sha256": hashlib.sha256(text.encode()).hexdigest()}
56+
prior["artifacts"] = [artifact, {**artifact, "page": "other.md", "facet": "configuration"},
57+
{**artifact, "owner": "other", "facet": "configuration"}]
58+
prior["result_sha256"] = parallel._hash({k: v for k, v in prior.items() if k != "result_sha256"})
59+
stage._foundation_validated_results = {prior["result_sha256"]}
60+
saved = {"binding": "batch", "tasks": {"initial": prior}}
61+
before = copy.deepcopy(saved)
62+
retry = list(parallel._with_review_feedback(stage, [job], saved))[0]
63+
facets = retry["payload"]["prior_review_feedback"]["facets"]
64+
assert facets["api"]["prior_artifact_text_sha256"] == artifact["text_sha256"]
65+
assert "local publication exclusion" in facets["api"]["last_local_publication_reasons"][0]
66+
assert facets["api"]["last_verdict"] == "unknown" # Native pass never becomes a rejection.
67+
assert facets["api"]["prior_attempts"] == [{k: prior[k] for k in ("input_sha256", "result_sha256")}]
68+
assert "last_local_publication_reasons" not in facets["configuration"]
69+
assert "0.0.0.0" not in str(facets) and saved == before
70+
71+
72+
def test_only_unsafe_items_are_excluded_and_loopback_or_finite_mode_are_preserved(monkeypatch):
73+
for unlimited, expected in ((True, ["api", "validation"]), (False, ["api", "configuration", "features", "validation"])):
74+
artifacts = [{"key": "knowledge:sample:" + facet, "owner": "sample", "page": "page.md",
75+
"facet": facet, "title": "Title", "text": text, "evidence": []}
76+
for facet, text in [("api", "127.0.0.1 remains an allowed loopback example"),
77+
("configuration", "wildcard host 0.0.0.0"),
78+
("features", "frontend wildcard host 0.0.0.0"), ("validation", "manual source checks")]]
79+
task = {"artifacts": artifacts, "verdicts": {}, "dropped": [], "unfinished": []}
80+
before = copy.deepcopy(task)
81+
applied = []
82+
stage = SimpleNamespace(rt=SimpleNamespace(unlimited_subscription=unlimited),
83+
record=InitRecord("knowledge", "toy"), _append_approved=lambda *a: applied.append(a[3]) or a[3])
84+
monkeypatch.setattr(parallel, "_validate_result", lambda *a: None)
85+
parallel._apply(stage, task)
86+
assert applied == expected and task == before
87+
assert len(stage.record.dropped) == (2 if unlimited else 0)

0 commit comments

Comments
 (0)