simplify SaaS SIP configuration response

This commit is contained in:
2026-09-28 16:06:24 +08:00
parent bd2e5ad2b1
commit efb2b86f5e
23 changed files with 700 additions and 169 deletions
+41 -3
View File
@@ -85,7 +85,7 @@ for index, match in enumerate(re.finditer(r"```json\s*(.*?)\s*```", doc, re.DOTA
positive_counts[name] += 1
for path in sorted(EXAMPLES.glob("config-read-*.json")):
if "invalid" in path.name or path == STATUS_FIXTURE:
if "invalid" in path.name or path == STATUS_FIXTURE or path.name.endswith("-v0.2.json"):
continue
validators["config-read"].validate(load_json(path))
positive_counts["config-read"] += 1
@@ -198,7 +198,8 @@ def validate_manifest():
required_artifacts.update(
path.relative_to(ROOT).as_posix()
for path in EXAMPLES.glob("*.json")
if path.name.startswith(("config-read-", "command-next-", "call-result-"))
if (path.name.startswith(("config-read-", "command-next-", "call-result-"))
and not path.name.endswith("-v0.2.json"))
or (path.name.startswith("task-discovery-") and path.name.endswith("-v0.1.json"))
)
artifact_paths = [entry.get("path") for entry in artifacts if isinstance(entry, dict)]
@@ -274,7 +275,8 @@ for example in ("snapshot", "changes"):
raise SystemExit(f"v0.2 {field} accepted more than 256 items")
proposal_doc = ROOT / "docs/thirds/v0.2.md"
proposal_versions = {**versions, "task-discovery.v0.2-proposal": "task-discovery-v0.2"}
proposal_versions = {**versions, "config-read.v0.2": "config-read-sip-v0.2", "task-discovery.v0.2-proposal": "task-discovery-v0.2"}
validators["config-read-sip-v0.2"] = Draft202012Validator(load_json(ROOT / "docs/contracts/config-read-v0.2.schema.json"), registry=registry, format_checker=FormatChecker())
for match in re.finditer(r"```json\s*(.*?)\s*```", proposal_doc.read_text(encoding="utf-8"), re.DOTALL):
sample = json.loads(match.group(1))
if isinstance(sample, dict) and sample.get("schema_version") in proposal_versions:
@@ -306,6 +308,42 @@ for entry in [source, *artifacts]:
raise SystemExit(f"v0.2 manifest SHA-256 mismatch: {relative}")
print(f"Task discovery v0.2 proposal (historical): positive={proposal_positive}, negative={proposal_negative}, manifest files={1 + len(artifacts)}")
# The SIP-only v0.2 response replaces the old static-artifact SIP payload;
# the other config-read resources remain on v0.1.
sip_schema_path = ROOT / "docs/contracts/config-read-v0.2.schema.json"
if (ROOT / "contracts/local/v0.2/config-read-v0.2.schema.json").read_bytes() != sip_schema_path.read_bytes():
raise SystemExit("embedded SIP config-read v0.2 schema differs from project source")
sip_schema = load_json(sip_schema_path)
Draft202012Validator.check_schema(sip_schema)
sip_validator = validators["config-read-sip-v0.2"]
sip_positive = EXAMPLES / "config-read-sip-v0.2.json"
sip_negative = EXAMPLES / "config-read-sip-invalid-artifact-v0.2.json"
sip_validator.validate(load_json(sip_positive))
try:
sip_validator.validate(load_json(sip_negative))
except ValidationError:
pass
else:
raise SystemExit("old artifact payload unexpectedly accepted by SIP v0.2")
sip_manifest = load_json(ROOT / "docs/contracts/local-contract-manifest-v0.5.json")
expected_sip_files = {
"docs/thirds/v0.2.md", "docs/contracts/config-read-v0.2.schema.json",
"docs/contracts/examples/config-read-sip-v0.2.json",
"docs/contracts/examples/config-read-sip-invalid-artifact-v0.2.json",
}
if (sip_manifest.get("manifest_version") != "local-contract-manifest.v0.5"
or sip_manifest.get("hash_algorithm") != "SHA-256"
or sip_manifest.get("source", {}).get("path") != "docs/contracts/config-read-fields-v0.2-proposal.md"):
raise SystemExit("invalid SIP v0.2 manifest header")
sip_entries = [sip_manifest["source"], *sip_manifest.get("artifacts", [])]
if {entry.get("path") for entry in sip_entries[1:]} != expected_sip_files or len(sip_entries) != 5:
raise SystemExit("SIP v0.2 manifest artifact set mismatch")
for entry in sip_entries:
path = ROOT / entry["path"]
if hashlib.sha256(path.read_bytes()).hexdigest() != entry.get("sha256"):
raise SystemExit(f"SIP v0.2 manifest SHA-256 mismatch: {entry['path']}")
print("SIP config-read v0.2: positive=1, negative=1, manifest files=5")
# v0.3 replaces the v0.2 runtime path; v0.2 files above remain historical evidence.
event_doc = ROOT / "docs/thirds/v0.3.md"
event_schema_path = ROOT / "docs/contracts/task-discovery-v0.3-proposal.schema.json"