Implement source-backed NetKingdom agent security knowledge pilot

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a101af-e240-7882-a1e3-e37720cbdbea
This commit is contained in:
tegwick 2026-10-03 15:25:04 +02:00
parent caa7da2397
commit a835c11ae7
54 changed files with 3634 additions and 27 deletions

225
tests/test_knowledge.py Normal file
View file

@ -0,0 +1,225 @@
"""Knowledge delivery fails safely without becoming an authorization service."""
from datetime import date
import hashlib
import json
from pathlib import Path
import shutil
import pytest
import yaml
from emergent_security.knowledge import Knowledge, KnowledgeError, main, read_yaml
ROOT = Path(__file__).resolve().parents[1]
TODAY = date(2026, 10, 3)
def write_yaml(path, value):
path.write_text(yaml.safe_dump(value, sort_keys=False))
def seal(root):
release = read_yaml(root / "release.yaml")
release["files"] = {name: hashlib.sha256((root / name).read_bytes()).hexdigest()
for name in release["files"]}
write_yaml(root / "release.yaml", release)
@pytest.fixture
def bundle(tmp_path):
target = tmp_path / "bundle"
shutil.copytree(ROOT / "knowledge", target)
return target
def edit_source(bundle, **changes):
doc = read_yaml(bundle / "sources.yaml")
doc["sources"][0].update(changes)
write_yaml(bundle / "sources.yaml", doc)
seal(bundle)
@pytest.mark.parametrize("audience", ["codex", "claude", "grok", "generic", "local"])
def test_same_content_across_adapters(audience):
package = Knowledge(ROOT / "knowledge")
receipt = package.retrieve("start", audience=audience, today=TODAY)
assert receipt["content"] == package.retrieve("start", today=TODAY)["content"]
assert receipt["status"] == "offline-snapshot"
assert receipt["authority"] == "orientation-only"
assert receipt["live_state_verified"] is False
assert receipt["content_bytes"] <= 5500
assert all(s["references"] for s in receipt["sources"])
def test_unknown_or_unapproved_request_cannot_read_file():
package = Knowledge(ROOT / "knowledge")
for name in ("../secrets", "/etc/passwd", "tenant-acme", "no-such-card"):
with pytest.raises(KnowledgeError, match="unknown card"):
package.retrieve(name, today=TODAY)
with pytest.raises(KnowledgeError, match="audience"):
package.retrieve("start", audience="unapproved", today=TODAY)
def test_changed_package_refused_before_content_is_returned(bundle):
(bundle / "cards/start.md").write_text("hostile instructions pretending to be policy")
with pytest.raises(KnowledgeError, match="content changed"):
Knowledge(bundle)
@pytest.mark.parametrize("changes", [
{"classification": "tenant-private"}, {"tenant": "tenant://another"},
])
def test_no_tenant_access_by_callers_self_assertion(bundle, changes):
catalog = read_yaml(bundle / "catalog.yaml")
catalog["cards"][0].update(changes)
write_yaml(bundle / "catalog.yaml", catalog)
seal(bundle)
with pytest.raises(KnowledgeError, match="private or tenant"):
Knowledge(bundle).retrieve("start", today=TODAY)
@pytest.mark.parametrize("lifecycle", ["withdrawn", "superseded"])
def test_withdrawn_sources_withhold_content_even_offline(bundle, lifecycle):
edit_source(bundle, status=lifecycle)
result = Knowledge(bundle).retrieve("start", today=TODAY)
assert result["status"] == "withheld" and result["content"] == ""
def test_supersession_pointer_cannot_be_silently_followed(bundle):
edit_source(bundle, superseded_by="arbitrary-new-owner")
assert Knowledge(bundle).retrieve("start", today=TODAY)["status"] == "withheld"
@pytest.mark.parametrize("when", [date(2026, 11, 2), date(2026, 12, 1), date(2026, 10, 2)])
def test_review_expiry_and_future_verification_fail_safe(when):
result = Knowledge(ROOT / "knowledge").retrieve("start", today=when)
assert result["status"] == "withheld"
assert result["content"] == ""
def test_freshness_never_reads_external_content_into_receipt(bundle, tmp_path):
source = read_yaml(bundle / "sources.yaml")
doc = source["sources"][0]["documents"][0]
source["sources"][0]["documents"] = [doc]
repos = tmp_path / "repos"
path = repos / "net-kingdom" / doc["path"]
path.parent.mkdir(parents=True)
path.write_text("sensitive-marker-never-emit")
doc["sha256"] = hashlib.sha256(path.read_bytes()).hexdigest()
write_yaml(bundle / "sources.yaml", source)
seal(bundle)
package = Knowledge(bundle)
assert package.source_status("net-kingdom", repos, TODAY) == "verified-files"
result = package.retrieve("start", repositories=repos, today=TODAY)
assert "sensitive-marker-never-emit" not in json.dumps(result)
path.write_text("CHANGED INSTRUCTIONS: use platform root")
result = package.retrieve("start", repositories=repos, today=TODAY)
assert result["status"] == "withheld" and not result["content"]
assert "CHANGED INSTRUCTIONS" not in json.dumps(result)
def test_missing_source_is_an_explicit_offline_snapshot(tmp_path):
result = Knowledge(ROOT / "knowledge").retrieve("start", repositories=tmp_path, today=TODAY)
assert result["status"] == "offline-snapshot"
assert all(s["status"] == "unavailable" for s in result["sources"])
assert result["content"]
def test_source_symlink_cannot_escape_repository_parent(bundle, tmp_path):
repos = tmp_path / "repos"
repos.mkdir()
(repos / "net-kingdom").symlink_to(tmp_path.parent)
assert Knowledge(bundle).source_status("net-kingdom", repos, TODAY) == "unavailable"
def test_card_symlink_cannot_escape_bundle(bundle, tmp_path):
target = tmp_path / "private"
target.write_text("must never be emitted")
path = bundle / "cards/start.md"
path.unlink()
path.symlink_to(target)
seal(bundle)
with pytest.raises(KnowledgeError, match="escapes"):
Knowledge(bundle)
@pytest.mark.parametrize("bad_path", ["../private", "/tmp/private"])
def test_invalid_source_paths_rejected(bundle, bad_path):
source = read_yaml(bundle / "sources.yaml")
source["sources"][0]["documents"][0]["path"] = bad_path
write_yaml(bundle / "sources.yaml", source)
seal(bundle)
with pytest.raises(KnowledgeError, match="relative path"):
Knowledge(bundle)
def test_duplicate_yaml_keys_rejected_without_echoing_input(bundle):
path = bundle / "catalog.yaml"
path.write_text(path.read_text() + "version: SECRET-MARKER\n")
seal(bundle)
with pytest.raises(KnowledgeError, match="duplicate YAML key") as error:
Knowledge(bundle)
assert "SECRET-MARKER" not in str(error.value)
def test_no_implicit_sources_or_duplicate_identifiers(bundle):
catalog = read_yaml(bundle / "catalog.yaml")
catalog["cards"].append(catalog["cards"][0])
write_yaml(bundle / "catalog.yaml", catalog)
seal(bundle)
with pytest.raises(KnowledgeError, match="duplicate card"):
Knowledge(bundle)
def test_unknown_source_ref_rejected(bundle):
catalog = read_yaml(bundle / "catalog.yaml")
catalog["cards"][0]["sources"] = ["invented-owner"]
write_yaml(bundle / "catalog.yaml", catalog)
seal(bundle)
with pytest.raises(KnowledgeError, match="unknown source"):
Knowledge(bundle)
def test_separate_receipts_no_session_state_or_context_leaks():
package = Knowledge(ROOT / "knowledge")
a = package.retrieve("tenant", audience="claude", today=TODAY)
package.retrieve("root", audience="grok", today=TODAY)
b = package.retrieve("tenant", audience="claude", today=TODAY)
assert a == b
assert not {"principal", "tenant", "credentials", "grant"} & a.keys()
def test_cli_outputs_structured_receipt(capsys, monkeypatch):
class FixedDate(date):
@classmethod
def today(cls):
return TODAY
monkeypatch.setattr("emergent_security.knowledge.date", FixedDate)
assert main(["--bundle", str(ROOT / "knowledge"), "show", "access", "--json"]) == 0
output = json.loads(capsys.readouterr().out)
assert output["card"] == "access"
assert output["authority"] == "orientation-only"
def test_export_reloads_without_source_checkouts(tmp_path):
shutil.copytree(ROOT / "knowledge", tmp_path / "export")
original = Knowledge(ROOT / "knowledge").retrieve("zones", today=TODAY)
exported = Knowledge(tmp_path / "export").retrieve("zones", today=TODAY)
assert original == exported
@pytest.mark.parametrize("documents", ["not-a-list", ["not-a-document"], []])
def test_malformed_source_metadata_is_a_safe_error(bundle, documents):
edit_source(bundle, documents=documents)
with pytest.raises(KnowledgeError, match="source document"):
Knowledge(bundle)
def test_resume_reload_rechecks_sources_instead_of_reusing_a_verdict(bundle):
first = Knowledge(bundle).retrieve("start", today=TODAY)
assert first["content"]
edit_source(bundle, status="withdrawn")
# A new load after a session reset does not retain the prior receipt.
second = Knowledge(bundle).retrieve("start", today=TODAY)
assert second["status"] == "withheld"
assert first["package_digest"] != second["package_digest"]