From 5ec59526aa20da6084f0a6e86b1376984d0199fb Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Tue, 12 May 2026 19:18:01 -0400 Subject: [PATCH 1/4] Add proof-claim responsibility to current Holmes surface --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 879f517..54c3e75 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,12 @@ Holmes supports Slash Topics by producing governed topic-model training artifact For Slash Topics, Holmes emits or prepares topic seeds, positive/negative/adjacent/ambiguous boundary evidence, candidate labels, topic taxonomy candidates, eval slices, and replayable topic-pack generation receipts. Slash Topics owns `/topic` pack semantics and policy membranes; Holmes owns language evidence, candidate generation, model-training support, and promotion evidence required before a topic model or topic pack can become stable. +## Proof-claim reasoning role + +Holmes reasoning-layer ownership is bounded to claim `Propose -> Explain -> Verify` contracts. Holmes emits `Claim` candidates plus `ExplanationTrace`, optional `ProofCertificate`, and `ContradictionReport` artifacts for downstream policy evaluation. Holmes does not make policy admission decisions. + +Reference: [`docs/PROOF_CLAIM_CONTRACT.md`](docs/PROOF_CLAIM_CONTRACT.md) + ## NLP component alignment Holmes explicitly covers these component families: @@ -66,6 +72,15 @@ Runtime service deployment should graduate into `SocioProphet/prophet-platform` Linux-native NLP lab execution belongs in `SociOS-Linux/nlplab`. SourceOS carries clients and signed service references through `SourceOS-Linux/sourceos-model-carry`. +## Contract responsibility catalog + +- Holmes: proof-claim reasoning contracts and verification/explanation artifacts. +- Sherlock: retrieval and evidence discovery used as inputs to reasoning. +- Slash Topics: governed `/topic` pack semantics, topic membranes, and topic-model surfaces trained from Holmes evidence artifacts. +- GAIA: graph/world grounding inputs consumed by Holmes reasoning adapters. +- Agentplane: governed execution after policy outcomes are decided. +- Policy Fabric: admission decisioning after Holmes evidence, proof, contradiction, and training artifacts are produced. + ## Initial validation ```bash From 5c043e69d83dca7a0efc09878559749c52cc30bb Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Tue, 12 May 2026 19:18:21 -0400 Subject: [PATCH 2/4] Add Holmes proof-claim contract --- docs/PROOF_CLAIM_CONTRACT.md | 63 ++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 docs/PROOF_CLAIM_CONTRACT.md diff --git a/docs/PROOF_CLAIM_CONTRACT.md b/docs/PROOF_CLAIM_CONTRACT.md new file mode 100644 index 0000000..f728de6 --- /dev/null +++ b/docs/PROOF_CLAIM_CONTRACT.md @@ -0,0 +1,63 @@ +# Holmes Proof-Claim Contract + +## Scope and ownership + +Holmes owns the reasoning-layer contract segment of the canonical loop: + +`Observe -> Anchor -> Normalize -> Propose -> Explain -> Verify -> Govern -> Act -> Receipt -> Learn` + +Holmes ownership is bounded to: `Propose -> Explain -> Verify`. + +Holmes does **not** admit claims into policy-approved truth. Policy Fabric evaluates Holmes outputs and decides: + +`allow | deny | require_review | provisional` + +## Contract invariant + +`VectorCandidate | ModelOutput | GraphCandidate -> ProposedClaim -> ExplanationTrace + ProofCertificate? + ContradictionReport` + +Vector and model outputs remain `candidate_only` unless sufficient evidence/proof exists and policy admits them. + +## Canonical contract mapping (Ontogenesis) + +Holmes maps to Ontogenesis canonical contracts without divergence: + +- `Claim` -> `ontogenesis.socioprophet.dev/v1/Claim` +- `ProofCertificate` -> `ontogenesis.socioprophet.dev/v1/ProofCertificate` +- `ExplanationTrace` -> `ontogenesis.socioprophet.dev/v1/ExplanationTrace` +- `ContradictionReport` -> `ontogenesis.socioprophet.dev/v1/ContradictionReport` +- `TruthBounds` -> `ontogenesis.socioprophet.dev/v1/TruthBounds` +- `ReasoningTrace` -> `holmes.socioprophet.dev/v1/ReasoningTrace` (Holmes-local minimal trace payload embedded in explanation/proof artifacts; not a separate Ontogenesis canonical object) +- `VectorCandidate` is candidate input only +- `PolicyDecision` is downstream admission status (owned by Policy Fabric, not Holmes) + +## Minimal `ReasoningTrace` format + +Each reasoning step should include: + +- `ruleName` +- `premises` (list) +- `conclusion` +- `evidenceRefs` (list of evidence IDs/URIs) +- `confidence` (0..1) +- `truthBounds` (`lower`, `upper`, `method`) + +## Worked examples + +Deterministic worked examples are captured in: + +- `examples/holmes-proof-claim-contract.json` + +They cover: + +1. Technical document span -> proposed platform claim -> explanation trace -> contradiction report -> policy-ready claim package. +2. Vector candidate -> candidate claim -> verification/rejection path. + +## Repo boundaries + +- Holmes: propose/explain/verify artifacts and traces for claims. +- Sherlock: retrieval/discovery and source evidence acquisition. +- Slash Topics: topic-pack semantics and membranes trained from Holmes evidence artifacts. +- GAIA: graph and world-model grounding inputs used by Holmes reasoners. +- Agentplane: governed runtime execution after policy admission. +- Policy Fabric: admission decisioning (`allow | deny | require_review | provisional`). From 470a9cf132e58938612a32be575bbce9e9adb9ca Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Wed, 13 May 2026 07:35:15 -0400 Subject: [PATCH 3/4] Add proof-claim worked fixture --- examples/holmes-proof-claim-contract.json | 163 ++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 examples/holmes-proof-claim-contract.json diff --git a/examples/holmes-proof-claim-contract.json b/examples/holmes-proof-claim-contract.json new file mode 100644 index 0000000..a93dbce --- /dev/null +++ b/examples/holmes-proof-claim-contract.json @@ -0,0 +1,163 @@ +{ + "apiVersion": "holmes.socioprophet.dev/v1", + "kind": "HolmesReasoningContract", + "metadata": { + "name": "holmes-proof-claim-contract", + "version": "0.1.0" + }, + "spec": { + "canonicalLoop": [ + "Observe", + "Anchor", + "Normalize", + "Propose", + "Explain", + "Verify", + "Govern", + "Act", + "Receipt", + "Learn" + ], + "holmesOwnedSegment": [ + "Propose", + "Explain", + "Verify" + ], + "admissionInvariant": "VectorCandidate | ModelOutput | GraphCandidate -> ProposedClaim -> ExplanationTrace + ProofCertificate? + ContradictionReport", + "candidateOnlyStatus": "candidate_only", + "policyDecisions": [ + "allow", + "deny", + "require_review", + "provisional" + ], + "contractMappings": { + "Claim": "ontogenesis.socioprophet.dev/v1/Claim", + "ProofCertificate": "ontogenesis.socioprophet.dev/v1/ProofCertificate", + "ExplanationTrace": "ontogenesis.socioprophet.dev/v1/ExplanationTrace", + "ContradictionReport": "ontogenesis.socioprophet.dev/v1/ContradictionReport", + "TruthBounds": "ontogenesis.socioprophet.dev/v1/TruthBounds" + }, + "workedExamples": { + "documentSpanToPolicyReadyClaim": { + "input": { + "sourceRef": "doc://platform-rfc/compute/section-2", + "spanRef": "doc://platform-rfc/compute/section-2#char=121-262", + "proposerType": "ModelOutput" + }, + "proposedClaim": { + "claimId": "claim-platform-kernel-hardening", + "type": "platform.security.posture", + "text": "Platform kernel hardening is enabled by default on all production clusters.", + "status": "candidate_only", + "truthBoundsNote": "Bounds are illustrative for reference-fixture calibration only; they demonstrate candidate confidence interval semantics, not admission.", + "truthBounds": { + "lower": 0.61, + "upper": 0.82, + "method": "calibrated_estimate" + } + }, + "explanationTrace": { + "traceId": "exp-001", + "steps": [ + "Extracted assertion span from technical document", + "Mapped assertion to canonical platform security claim template", + "Matched evidence references to claim predicates" + ], + "evidenceRefs": [ + "evidence://doc/platform-rfc/section-2", + "evidence://graph/platform-controls/kernel-hardening" + ] + }, + "reasoningTrace": [ + { + "ruleName": "rule.platform.security.default_control", + "premises": [ + "technical_doc_asserts_default=true", + "control_type=kernel_hardening" + ], + "conclusion": "claim.platform.security.posture.default_enabled", + "evidenceRefs": [ + "evidence://doc/platform-rfc/section-2", + "evidence://graph/platform-controls/kernel-hardening" + ], + "confidence": 0.74, + "truthBounds": { + "lower": 0.61, + "upper": 0.82, + "method": "calibrated_estimate" + } + } + ], + "contradictionReport": { + "reportId": "contra-001", + "status": "contradiction_detected", + "conflicts": [ + { + "sourceRef": "doc://runbook-exceptions/kernel-hardening", + "statement": "Legacy clusters may disable kernel hardening by exception.", + "severity": "medium" + } + ] + }, + "proofCertificate": { + "certificateId": "proof-001", + "verificationMethod": "rule+evidence-check", + "verificationStatus": "insufficient_for_admission", + "evidenceRefs": [ + "evidence://doc/platform-rfc/section-2", + "evidence://graph/platform-controls/kernel-hardening" + ] + }, + "policyReadyClaim": { + "claimId": "claim-platform-kernel-hardening", + "admissionStatus": "pending_policy_decision", + "eligiblePolicyDecisions": [ + "allow", + "deny", + "require_review", + "provisional" + ] + } + }, + "vectorCandidateVerificationPath": { + "input": { + "vectorCandidate": { + "candidateId": "vec-9001", + "embeddingRef": "vec://sherlock/chunk/9001", + "nearestText": "Kernel hardening appears enabled on cluster class A.", + "similarity": 0.88 + } + }, + "candidateClaim": { + "claimId": "claim-vector-kernel-hardening", + "type": "platform.security.posture", + "text": "Kernel hardening is enabled by default in production.", + "status": "candidate_only", + "truthBoundsNote": "Vector-symbolic candidate uses intentionally lower confidence bounds until proof/evidence verification.", + "truthBounds": { + "lower": 0.36, + "upper": 0.59, + "method": "vector-symbolic-prior" + } + }, + "verificationPath": { + "textualEntailment": "not_entailed", + "proofCertificate": null, + "contradictionReport": { + "reportId": "contra-vec-001", + "status": "unsupported_candidate", + "conflicts": [ + { + "sourceRef": "doc://controls/production-baseline", + "statement": "No default guarantee found for all production clusters.", + "severity": "high" + } + ] + }, + "result": "rejected_before_policy" + } + } + } + } +} From cd0910ddf0a9fee1f02e0a10f40ac6d4ad4bcdfa Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Wed, 13 May 2026 07:37:16 -0400 Subject: [PATCH 4/4] Validate proof-claim contract alongside Holmes surface --- tools/validate_holmes.py | 71 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/tools/validate_holmes.py b/tools/validate_holmes.py index 84d5bc0..0d87a11 100644 --- a/tools/validate_holmes.py +++ b/tools/validate_holmes.py @@ -7,6 +7,7 @@ ROOT = Path(__file__).resolve().parents[1] EXAMPLE = ROOT / "examples" / "holmes-surface.json" +REASONING_EXAMPLE = ROOT / "examples" / "holmes-proof-claim-contract.json" REQUIRED_COMPONENTS = { "sherlock-search", "221b", @@ -78,6 +79,23 @@ "promotionRecord", "rollbackRef", } +REQUIRED_MAPPINGS = { + "Claim", + "ProofCertificate", + "ExplanationTrace", + "ContradictionReport", + "TruthBounds", +} +REQUIRED_HOLMES_SEGMENT = ["Propose", "Explain", "Verify"] +REJECTED_BEFORE_POLICY = "rejected_before_policy" +REQUIRED_REASONING_TRACE = { + "ruleName", + "premises", + "conclusion", + "evidenceRefs", + "confidence", + "truthBounds", +} def fail(message: str) -> int: @@ -93,7 +111,7 @@ def require_set(spec: dict, field: str, required: set[str]) -> int | None: return None -def main() -> int: +def validate_surface() -> int | None: if not EXAMPLE.exists(): return fail("missing examples/holmes-surface.json") data = json.loads(EXAMPLE.read_text()) @@ -116,6 +134,57 @@ def main() -> int: for key in ["standards", "platform", "search", "slashTopics", "lab", "sourceosCarry"]: if key not in integrations: return fail(f"missing integration: {key}") + return None + + +def validate_reasoning_contract() -> int | None: + if not REASONING_EXAMPLE.exists(): + return fail("missing examples/holmes-proof-claim-contract.json") + reasoning = json.loads(REASONING_EXAMPLE.read_text()) + if reasoning.get("apiVersion") != "holmes.socioprophet.dev/v1": + return fail("wrong reasoning contract apiVersion") + if reasoning.get("kind") != "HolmesReasoningContract": + return fail("wrong reasoning contract kind") + reasoning_spec = reasoning.get("spec", {}) + if reasoning_spec.get("candidateOnlyStatus") != "candidate_only": + return fail("candidateOnlyStatus must be candidate_only") + actual_segment = reasoning_spec.get("holmesOwnedSegment", []) + if actual_segment != REQUIRED_HOLMES_SEGMENT: + return fail( + "holmesOwnedSegment must be ordered exactly as [Propose, Explain, Verify]; " + f"got {actual_segment}" + ) + mappings = set(reasoning_spec.get("contractMappings", {}).keys()) + missing_mappings = REQUIRED_MAPPINGS - mappings + if missing_mappings: + return fail(f"missing contract mappings: {sorted(missing_mappings)}") + worked_examples = reasoning_spec.get("workedExamples", {}) + for key in ["documentSpanToPolicyReadyClaim", "vectorCandidateVerificationPath"]: + if key not in worked_examples: + return fail(f"missing worked example: {key}") + doc_example = worked_examples["documentSpanToPolicyReadyClaim"] + reasoning_trace = doc_example.get("reasoningTrace", []) + if not reasoning_trace: + return fail("documentSpanToPolicyReadyClaim must include reasoningTrace") + for index, entry in enumerate(reasoning_trace): + missing_reasoning_fields = REQUIRED_REASONING_TRACE - set(entry.keys()) + if missing_reasoning_fields: + return fail( + f"missing reasoningTrace fields at index {index}: {sorted(missing_reasoning_fields)}" + ) + vector_example = worked_examples["vectorCandidateVerificationPath"] + if vector_example.get("candidateClaim", {}).get("status") != "candidate_only": + return fail("vector candidateClaim status must be candidate_only") + if vector_example.get("verificationPath", {}).get("result") != REJECTED_BEFORE_POLICY: + return fail("vector verification path result must be rejected_before_policy") + return None + + +def main() -> int: + for validator in [validate_surface, validate_reasoning_contract]: + result = validator() + if result is not None: + return result print("OK: Holmes contracts validated") return 0