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
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: build test validate dist release-dry-run clean
.PHONY: build test validate validate-maturity dist release-dry-run clean

BIN := holmes
DIST_DIR := dist
Expand All @@ -17,7 +17,10 @@ build:
test:
go test ./...

validate: build
validate-maturity:
python3 tools/validate_maturity.py

validate: build validate-maturity
python3 tools/validate_holmes.py
bin/$(BIN) --version
bin/$(BIN) doctor
Expand Down
62 changes: 62 additions & 0 deletions repo.maturity.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
schemaVersion: repo-maturity.v1
repository: SocioProphet/holmes
plane: runtime
status: active
canonicality: canonical
owners:
- SocioProphet
maturity:
level: M2
targetLevel: M3
evidence:
- README.md defines Holmes purpose, product family, Slash Topics training role, proof-claim reasoning role, repo boundaries, and integration path.
- docs/ARCHITECTURE.md defines Holmes product components, service boundaries, TriTRPC method families, and promotion rules.
- docs/NLP_COMPONENT_ALIGNMENT.md defines governed NLP component coverage and Slash Topics topic-model training alignment.
- docs/PROOF_CLAIM_CONTRACT.md defines the Propose -> Explain -> Verify proof-claim contract and policy-admission boundary.
- examples/holmes-surface.json provides the machine-readable Holmes product surface fixture.
- examples/holmes-proof-claim-contract.json provides deterministic proof-claim reasoning fixture coverage.
- tools/validate_holmes.py validates Holmes surface and proof-claim contract fixtures.
- Makefile provides build, test, validate, dist, and release-dry-run targets.
- .github/workflows/validate.yml runs make validate and make release-dry-run on pull requests and main pushes.
validation:
commands:
- make validate
ciRequired: true
lastKnownStatus: pending
integrations:
- repository: SocioProphet/functional-model-surfaces
relationship: normative cross-surface standards and maturity model reference
required: true
- repository: SocioProphet/prophet-platform
relationship: runtime deployment and platform records after contracts stabilize
required: true
- repository: SocioProphet/sherlock-search
relationship: discovery, retrieval, evidence search, and investigation input surface
required: true
- repository: SocioProphet/slash-topics
relationship: governed topic-pack semantics and topic-model training consumer
required: true
- repository: SociOS-Linux/nlplab
relationship: Linux-native NLP lab execution and benchmark receipts
required: true
- repository: SourceOS-Linux/sourceos-model-carry
relationship: SourceOS client references and signed service carry refs
required: true
- repository: SocioProphet/ontogenesis
relationship: canonical semantic contracts for claims, traces, truth bounds, and contradiction artifacts
required: true
- repository: SocioProphet/policy-fabric
relationship: downstream policy admission for Holmes evidence and proof artifacts
required: true
- repository: SocioProphet/agentplane
relationship: governed execution after policy outcomes are decided
required: true
- repository: SocioProphet/sociosphere
relationship: workspace governance and maturity ingestion
required: false
nextActions:
- Add negative fixtures and a negative-fixture runner so Holmes can honestly claim M3.
- Replace deterministic not-yet-wired CLI stubs with service-backed Sherlock, graph, and governance adapters.
- Add schema files for Holmes surface, proof-claim contract, and Slash Topics training references.
- Add release notes, checksums, and provenance attestations for M4 readiness.
- Register Holmes in workspace-inventory or Sociosphere scorecard ingestion.
101 changes: 101 additions & 0 deletions tools/validate_maturity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/usr/bin/env python3
from __future__ import annotations

import re
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
MATURITY = ROOT / "repo.maturity.yaml"

REQUIRED_HEADER_VALUES = {
"schemaVersion": "repo-maturity.v1",
"repository": "SocioProphet/holmes",
"plane": "runtime",
"status": "active",
"canonicality": "canonical",
}
REQUIRED_TEXT = [
"owners:",
" - SocioProphet",
"maturity:",
" level: M2",
" targetLevel: M3",
"validation:",
" commands:",
" - make validate",
" ciRequired: true",
"integrations:",
"nextActions:",
]
REQUIRED_INTEGRATIONS = {
"SocioProphet/functional-model-surfaces",
"SocioProphet/prophet-platform",
"SocioProphet/sherlock-search",
"SocioProphet/slash-topics",
"SociOS-Linux/nlplab",
"SourceOS-Linux/sourceos-model-carry",
"SocioProphet/ontogenesis",
"SocioProphet/policy-fabric",
"SocioProphet/agentplane",
"SocioProphet/sociosphere",
}
ALLOWED_VALIDATION_STATUS = {"pending", "passing", "failing", "unknown"}


def fail(message: str) -> int:
print(f"ERROR: {message}", file=sys.stderr)
return 1


def scalar(text: str, key: str) -> str | None:
match = re.search(rf"^{re.escape(key)}:\s*(.+?)\s*$", text, flags=re.MULTILINE)
if not match:
return None
return match.group(1).strip().strip('"')


def count_list_items_in_section(text: str, section: str) -> int:
match = re.search(rf"^{re.escape(section)}:\n(?P<body>(?:\s+.*\n?)*)", text, flags=re.MULTILINE)
if not match:
return 0
body = match.group("body")
return len(re.findall(r"^\s+-\s+", body, flags=re.MULTILINE))


def main() -> int:
if not MATURITY.exists():
return fail("missing repo.maturity.yaml")
text = MATURITY.read_text()

for key, expected in REQUIRED_HEADER_VALUES.items():
observed = scalar(text, key)
if observed != expected:
return fail(f"{key} must be {expected!r}; got {observed!r}")

for required in REQUIRED_TEXT:
if required not in text:
return fail(f"missing required maturity text: {required}")

status = scalar(text, "lastKnownStatus")
if status not in ALLOWED_VALIDATION_STATUS:
return fail(f"validation.lastKnownStatus must be one of {sorted(ALLOWED_VALIDATION_STATUS)}; got {status!r}")

missing_integrations = sorted(repo for repo in REQUIRED_INTEGRATIONS if repo not in text)
if missing_integrations:
return fail(f"missing integrations: {missing_integrations}")

evidence_count = count_list_items_in_section(text, " evidence")
if evidence_count < 6:
return fail(f"maturity.evidence should contain at least 6 concrete evidence items; got {evidence_count}")

next_actions = count_list_items_in_section(text, "nextActions")
if next_actions < 3:
return fail(f"nextActions should contain at least 3 roadmap items; got {next_actions}")

print("OK: Holmes maturity manifest validated")
return 0


if __name__ == "__main__":
raise SystemExit(main())
Loading