Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand Down
63 changes: 63 additions & 0 deletions docs/PROOF_CLAIM_CONTRACT.md
Original file line number Diff line number Diff line change
@@ -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`).
163 changes: 163 additions & 0 deletions examples/holmes-proof-claim-contract.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
}
}
71 changes: 70 additions & 1 deletion tools/validate_holmes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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:
Expand All @@ -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())
Expand All @@ -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

Expand Down
Loading