From 7ec2c16c6fc7ce74aa22acb12b95ed0270f081f9 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Tue, 28 Apr 2026 13:07:20 -0400 Subject: [PATCH 01/12] Bootstrap Holmes README --- README.md | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 77766f9..c3e0eb0 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,55 @@ -# holmes -Holmes Language Intelligence Fabric: governed classical NLP, neural NLP, semantic search, retrieval, knowledge graphs, foundation-language services, guardrails, evals, and investigative agentic discovery. +# Holmes + +Holmes is SocioProphet's open language intelligence fabric. + +It is built to outgrow assistant-grade discovery: classical NLP, neural NLP, semantic search, retrieval, knowledge graphs, foundation-language services, guardrails, evals, and investigative agentic discovery under one governed product surface. + +## Product thesis + +Watson-style systems answer. Holmes investigates. + +Holmes is not a chatbot wrapper, a loose model zoo, or a domain NLP repo. It is the governed language layer above search, evidence, retrieval, casefiles, semantic graphs, tools, models, evals, and agents. + +## Product family + +- **Holmes**: language intelligence fabric. +- **Sherlock Search**: discovery, retrieval, evidence search, and investigation engine. +- **221B**: casefile and workspace surface. +- **Mycroft**: model routing, policy intelligence, and strategic model/service selection. +- **Moriarty Bench**: adversarial eval and red-team harness. +- **Irene Shield**: privacy, masking, identity-sensitive redaction, and sensitive-context handling. +- **The Canon**: curated evidence corpus, provenance records, accepted facts, and source trust. +- **Deduction Engine**: synthesis, contradiction detection, claim extraction, fallacy analysis, and reasoning workflows. + +## Layer stack + +1. Ingestion: documents, web, OCR handoff, transcripts, tables, metadata, language detection. +2. Linguistic primitives: tokenization, lemmatization, POS, morphology, parsing, NER, normalization. +3. Rule and table techniques: matchers, gazetteers, taxonomies, table extraction, rule-based relation extraction. +4. Classical ML NLP: classifiers, clustering, topic models, sentiment baselines, calibration, explainability. +5. Neural NLP: transformers, embeddings, rerankers, span extraction, relation extraction, multilingual encoders. +6. Foundation language services: extraction, summarization, generation, translation, RAG answering, long-context analysis, tool planning. +7. Retrieval and knowledge: sparse/dense/hybrid retrieval, vector stores, GraphBrain, semantic-serdes, ontogenesis, Slash Topics, Sherlock Search. +8. Guardrails and governance: PII checks, source provenance, prompt-injection checks, policy gates, eval gates, factsheets, promotion records. +9. Agent and tool orchestration: tool contracts, agent identity, sessions, memory, MCP/A2A, execution traces, model routing. + +## Repo role + +This repo is the Holmes product surface and integration spine. + +Normative cross-surface standards live in `SocioProphet/functional-model-surfaces`. +Runtime service deployment should graduate into `SocioProphet/prophet-platform` when contracts and smoke tests are stable. +Linux-native NLP lab execution belongs in `SociOS-Linux/nlplab`. +SourceOS carries clients and signed service references through `SourceOS-Linux/sourceos-model-carry`. + +## Initial validation + +```bash +make validate +``` + +Expected result: + +```text +OK: Holmes contracts validated +``` From c546d04d5e5f349597b76703caa996ebdd8d5c73 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Tue, 28 Apr 2026 13:07:49 -0400 Subject: [PATCH 02/12] Add Holmes architecture --- docs/ARCHITECTURE.md | 89 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 docs/ARCHITECTURE.md diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..903c2fd --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,89 @@ +# Holmes Architecture + +## Objective + +Holmes is the governed language intelligence fabric for SocioProphet. + +It connects classical NLP, neural NLP, retrieval, semantic graphs, foundation-language services, guardrails, evals, tools, and agents into an evidence-first discovery product. + +## Product components + +### Sherlock Search + +Discovery, retrieval, evidence search, and investigation. + +### 221B + +Casefile and workspace surface for investigations, projects, and review bundles. + +### Mycroft + +Model routing, policy intelligence, cost/latency/quality/privacy selection, and fallback strategy. + +### Moriarty Bench + +Adversarial evals, prompt-injection tests, retrieval sabotage tests, hallucination regression tests, and safety regressions. + +### Irene Shield + +Privacy, PII masking, source masking, consent boundaries, identity-sensitive redaction, and sensitive-context handling. + +### The Canon + +Curated evidence corpus, provenance-backed accepted facts, citation records, source trust records, and knowledge-base manifests. + +### Deduction Engine + +Claim extraction, contradiction detection, fallacy analysis, summarization, synthesis, and report generation. + +## Data flow + +```text +ingest + -> linguistic analysis + -> extraction and normalization + -> retrieval and graph conversion + -> guarded foundation-language services + -> deduction and casefile assembly + -> evidence records and promotion outputs +``` + +## Service boundaries + +Holmes should not embed every model or data source directly. It should compose governed services: + +- functional model surfaces from `functional-model-surfaces`; +- runtime platform services from `prophet-platform`; +- search and retrieval from `sherlock-search`; +- local NLP lab outputs from `SociOS-Linux/nlplab`; +- SourceOS client references from `sourceos-model-carry`. + +## Internal transport + +Internal services should be TriTRPC-first. Gateway routes may exist for web clients and third-party integration. + +Recommended method families: + +- `language.primitive.v1/Analyze` +- `language.entity.v1/Extract` +- `language.relation.v1/Extract` +- `language.classify.v1/Classify` +- `language.embed.v1/Embed` +- `language.rerank.v1/Rerank` +- `language.translate.v1/Translate` +- `language.summarize.v1/Summarize` +- `language.rag.v1/Answer` +- `language.graph.v1/ToSemanticGraph` +- `language.govern.v1/Evaluate` + +## Promotion rule + +No Holmes pipeline, model, adapter, retrieval package, or agent route becomes stable without: + +1. dataset or corpus reference; +2. pipeline or model artifact reference; +3. eval record; +4. guardrail policy; +5. evidence receipt; +6. signed promotion record; +7. rollback reference. From 797924d804fa1fe20903f63cc3c15d0ac7ea9034 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Tue, 28 Apr 2026 13:19:07 -0400 Subject: [PATCH 03/12] Add Holmes surface example --- examples/holmes-surface.json | 50 ++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 examples/holmes-surface.json diff --git a/examples/holmes-surface.json b/examples/holmes-surface.json new file mode 100644 index 0000000..7f9508f --- /dev/null +++ b/examples/holmes-surface.json @@ -0,0 +1,50 @@ +{ + "apiVersion": "holmes.socioprophet.dev/v1", + "kind": "HolmesSurface", + "metadata": { + "name": "holmes-core", + "version": "0.1.0" + }, + "spec": { + "product": "Holmes", + "tagline": "Watson-style systems answer. Holmes investigates.", + "components": [ + "sherlock-search", + "221b", + "mycroft-router", + "moriarty-bench", + "irene-shield", + "the-canon", + "deduction-engine" + ], + "methodFamilies": [ + "language.primitive.v1/Analyze", + "language.entity.v1/Extract", + "language.relation.v1/Extract", + "language.classify.v1/Classify", + "language.embed.v1/Embed", + "language.rerank.v1/Rerank", + "language.translate.v1/Translate", + "language.summarize.v1/Summarize", + "language.rag.v1/Answer", + "language.graph.v1/ToSemanticGraph", + "language.govern.v1/Evaluate" + ], + "requiredPromotionEvidence": [ + "corpusRef", + "pipelineOrModelRef", + "evalRecord", + "guardrailPolicy", + "evidenceReceipt", + "promotionRecord", + "rollbackRef" + ], + "integrations": { + "standards": "SocioProphet/functional-model-surfaces", + "platform": "SocioProphet/prophet-platform", + "search": "SocioProphet/sherlock-search", + "lab": "SociOS-Linux/nlplab", + "sourceosCarry": "SourceOS-Linux/sourceos-model-carry" + } + } +} From e8685ede4a06b58e26d83560450491442c34c29a Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Tue, 28 Apr 2026 13:19:29 -0400 Subject: [PATCH 04/12] Add Holmes validator --- tools/validate_holmes.py | 61 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 tools/validate_holmes.py diff --git a/tools/validate_holmes.py b/tools/validate_holmes.py new file mode 100644 index 0000000..f433588 --- /dev/null +++ b/tools/validate_holmes.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import json +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +EXAMPLE = ROOT / "examples" / "holmes-surface.json" +REQUIRED_COMPONENTS = { + "sherlock-search", + "221b", + "mycroft-router", + "moriarty-bench", + "irene-shield", + "the-canon", + "deduction-engine", +} +REQUIRED_EVIDENCE = { + "corpusRef", + "pipelineOrModelRef", + "evalRecord", + "guardrailPolicy", + "evidenceReceipt", + "promotionRecord", + "rollbackRef", +} + + +def fail(message: str) -> int: + print(f"ERROR: {message}", file=sys.stderr) + return 1 + + +def main() -> int: + if not EXAMPLE.exists(): + return fail("missing examples/holmes-surface.json") + data = json.loads(EXAMPLE.read_text()) + if data.get("apiVersion") != "holmes.socioprophet.dev/v1": + return fail("wrong apiVersion") + if data.get("kind") != "HolmesSurface": + return fail("wrong kind") + spec = data.get("spec", {}) + components = set(spec.get("components", [])) + missing_components = REQUIRED_COMPONENTS - components + if missing_components: + return fail(f"missing components: {sorted(missing_components)}") + evidence = set(spec.get("requiredPromotionEvidence", [])) + missing_evidence = REQUIRED_EVIDENCE - evidence + if missing_evidence: + return fail(f"missing promotion evidence: {sorted(missing_evidence)}") + integrations = spec.get("integrations", {}) + for key in ["standards", "platform", "search", "lab", "sourceosCarry"]: + if key not in integrations: + return fail(f"missing integration: {key}") + print("OK: Holmes contracts validated") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From 4ffcc86221815699ad872ccc030aba3b162d4374 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Tue, 28 Apr 2026 13:19:48 -0400 Subject: [PATCH 05/12] Add Holmes validation target --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..970ae67 --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +.PHONY: validate + +validate: + python3 tools/validate_holmes.py From 2de1d7a7d73b16de66ee01e5d4ddcb1eb1a246de Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Tue, 28 Apr 2026 14:49:57 -0400 Subject: [PATCH 06/12] Add Go module for Holmes CLI --- go.mod | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 go.mod diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..83fb3f9 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/SocioProphet/holmes + +go 1.22 From 5458a6ca44c7ad21d53e638aef915f46c75fba42 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Tue, 28 Apr 2026 14:52:12 -0400 Subject: [PATCH 07/12] Add Holmes CLI skeleton --- cmd/holmes/main.go | 237 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 cmd/holmes/main.go diff --git a/cmd/holmes/main.go b/cmd/holmes/main.go new file mode 100644 index 0000000..83a3922 --- /dev/null +++ b/cmd/holmes/main.go @@ -0,0 +1,237 @@ +package main + +import ( + "crypto/sha256" + "encoding/hex" + "encoding/json" + "errors" + "flag" + "fmt" + "os" + "path/filepath" + "strings" +) + +var ( + version = "0.1.0-dev" + commit = "unknown" + date = "unknown" +) + +type evidence struct { + Tool string `json:"tool"` + Version string `json:"version"` + Commit string `json:"commit"` + BuildDate string `json:"buildDate"` + Repo string `json:"repo"` + Command string `json:"command"` + Status string `json:"status"` + Details map[string]any `json:"details,omitempty"` +} + +type analysisRecord struct { + Tool string `json:"tool"` + Version string `json:"version"` + Status string `json:"status"` + Path string `json:"path"` + Bytes int `json:"bytes"` + SHA256 string `json:"sha256"` + Lines int `json:"lines"` + Words int `json:"words"` + Components []string `json:"components"` + EvidenceRef string `json:"evidenceRef"` +} + +func usage() { + fmt.Fprintf(os.Stderr, `holmes %s + +Usage: + holmes --version + holmes doctor + holmes self-test + holmes emit-evidence + holmes analyze + holmes search + holmes graph + holmes govern + +`, version) +} + +func main() { + if len(os.Args) == 1 { + usage() + os.Exit(2) + } + if os.Args[1] == "--version" || os.Args[1] == "version" { + fmt.Printf("holmes %s commit=%s date=%s\n", version, commit, date) + return + } + + switch os.Args[1] { + case "doctor": + runDoctor() + case "self-test": + runSelfTest() + case "emit-evidence": + runEvidence("emit-evidence", "ok", map[string]any{"surface": "language-intelligence", "mode": "local"}) + case "analyze": + requireArgs(os.Args, 3) + runAnalyze(os.Args[2]) + case "search": + requireArgs(os.Args, 3) + runSearch(strings.Join(os.Args[2:], " ")) + case "graph": + requireArgs(os.Args, 3) + runGraph(os.Args[2]) + case "govern": + requireArgs(os.Args, 3) + runGovern(os.Args[2]) + default: + usage() + os.Exit(2) + } +} + +func requireArgs(args []string, n int) { + if len(args) < n { + usage() + os.Exit(2) + } +} + +func runDoctor() { + details := map[string]any{ + "components": []string{"sherlock-search", "221b", "mycroft-router", "moriarty-bench", "irene-shield", "the-canon", "deduction-engine"}, + "wired": []string{}, + "pending": []string{"sherlock-search", "221b", "mycroft-router", "moriarty-bench", "irene-shield", "the-canon", "deduction-engine"}, + } + runEvidence("doctor", "not-yet-wired", details) +} + +func runSelfTest() { + if _, err := os.Stat("examples/holmes-surface.json"); err != nil { + runEvidence("self-test", "failed", map[string]any{"error": err.Error()}) + os.Exit(1) + } + runEvidence("self-test", "ok", map[string]any{"example": "examples/holmes-surface.json"}) +} + +func runAnalyze(path string) { + record, err := analyzeFile(path) + if err != nil { + printJSON(map[string]any{"status": "failed", "error": err.Error(), "path": path}) + os.Exit(1) + } + printJSON(record) +} + +func runSearch(query string) { + printJSON(map[string]any{ + "tool": "holmes", + "version": version, + "status": "not-yet-wired", + "query": query, + "engine": "sherlock-search", + "message": "Sherlock Search binding is declared but runtime search is not wired in this CLI skeleton.", + "evidenceId": stableID("search:" + query), + }) +} + +func runGraph(path string) { + record, err := analyzeFile(path) + if err != nil { + printJSON(map[string]any{"status": "failed", "error": err.Error(), "path": path}) + os.Exit(1) + } + printJSON(map[string]any{ + "tool": "holmes", + "version": version, + "status": "not-yet-wired", + "path": record.Path, + "sha256": record.SHA256, + "target": "language.graph.v1/ToSemanticGraph", + "message": "Semantic graph conversion is declared but not wired in this CLI skeleton.", + "evidenceId": stableID("graph:" + record.SHA256), + }) +} + +func runGovern(path string) { + record, err := analyzeFile(path) + if err != nil { + printJSON(map[string]any{"status": "failed", "error": err.Error(), "path": path}) + os.Exit(1) + } + printJSON(map[string]any{ + "tool": "holmes", + "version": version, + "status": "not-yet-wired", + "path": record.Path, + "sha256": record.SHA256, + "target": "language.govern.v1/Evaluate", + "message": "Governance/eval binding is declared but not wired in this CLI skeleton.", + "evidenceId": stableID("govern:" + record.SHA256), + }) +} + +func analyzeFile(path string) (analysisRecord, error) { + clean := filepath.Clean(path) + bytes, err := os.ReadFile(clean) + if err != nil { + return analysisRecord{}, err + } + text := string(bytes) + sum := sha256.Sum256(bytes) + record := analysisRecord{ + Tool: "holmes", + Version: version, + Status: "demo-analysis", + Path: clean, + Bytes: len(bytes), + SHA256: hex.EncodeToString(sum[:]), + Lines: countLines(text), + Words: len(strings.Fields(text)), + Components: []string{"ingestion", "linguistic-primitives", "evidence"}, + } + record.EvidenceRef = "evidence://holmes/" + stableID(record.SHA256) + return record, nil +} + +func countLines(text string) int { + if text == "" { + return 0 + } + count := strings.Count(text, "\n") + if !strings.HasSuffix(text, "\n") { + count++ + } + return count +} + +func runEvidence(command, status string, details map[string]any) { + fs := flag.NewFlagSet(command, flag.ContinueOnError) + _ = fs + printJSON(evidence{ + Tool: "holmes", + Version: version, + Commit: commit, + BuildDate: date, + Repo: "SocioProphet/holmes", + Command: command, + Status: status, + Details: details, + }) +} + +func stableID(value string) string { + sum := sha256.Sum256([]byte(value)) + return hex.EncodeToString(sum[:])[:16] +} + +func printJSON(value any) { + enc := json.NewEncoder(os.Stdout) + enc.SetIndent("", " ") + if err := enc.Encode(value); err != nil { + panic(errors.New("failed to encode JSON: " + err.Error())) + } +} From 27c826d797245fa5c8e6277f6172e79b8cac135c Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Tue, 28 Apr 2026 14:53:18 -0400 Subject: [PATCH 08/12] Remove unused import from Holmes CLI --- cmd/holmes/main.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/cmd/holmes/main.go b/cmd/holmes/main.go index 83a3922..240974e 100644 --- a/cmd/holmes/main.go +++ b/cmd/holmes/main.go @@ -5,7 +5,6 @@ import ( "encoding/hex" "encoding/json" "errors" - "flag" "fmt" "os" "path/filepath" @@ -209,8 +208,6 @@ func countLines(text string) int { } func runEvidence(command, status string, details map[string]any) { - fs := flag.NewFlagSet(command, flag.ContinueOnError) - _ = fs printJSON(evidence{ Tool: "holmes", Version: version, From 8ca75e0ca72b2ac494b649bf68187d55cfbeadba Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Tue, 28 Apr 2026 14:54:06 -0400 Subject: [PATCH 09/12] Add Holmes build and release targets --- Makefile | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 970ae67..b7b874c 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,40 @@ -.PHONY: validate +.PHONY: build test validate dist release-dry-run clean -validate: +BIN := holmes +DIST_DIR := dist +VERSION ?= 0.1.0-dev +COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown) +DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ) +GOOS ?= $(shell go env GOOS 2>/dev/null || uname -s | tr A-Z a-z) +GOARCH ?= $(shell go env GOARCH 2>/dev/null || uname -m) +DIST_NAME := $(BIN)_$(VERSION)_$(GOOS)_$(GOARCH) +LDFLAGS := -X main.version=$(VERSION) -X main.commit=$(COMMIT) -X main.date=$(DATE) + +build: + mkdir -p bin + go build -ldflags "$(LDFLAGS)" -o bin/$(BIN) ./cmd/holmes + +test: + go test ./... + +validate: build python3 tools/validate_holmes.py + bin/$(BIN) --version + bin/$(BIN) doctor + bin/$(BIN) self-test + bin/$(BIN) emit-evidence >/tmp/holmes-evidence.json + bin/$(BIN) analyze examples/sample.txt >/tmp/holmes-analysis.json + bin/$(BIN) search "truth and evidence" >/tmp/holmes-search.json + bin/$(BIN) graph examples/sample.txt >/tmp/holmes-graph.json + bin/$(BIN) govern examples/sample.txt >/tmp/holmes-govern.json + +dist: validate + mkdir -p $(DIST_DIR) + cp bin/$(BIN) $(DIST_DIR)/$(DIST_NAME) + (cd $(DIST_DIR) && sha256sum $(DIST_NAME) > $(DIST_NAME).sha256) + +release-dry-run: dist + @echo "release dry-run complete: $(DIST_DIR)/$(DIST_NAME)" + +clean: + rm -rf bin $(DIST_DIR) From 6112672e47b731cd58b3b5347930934662d77ddc Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Tue, 28 Apr 2026 14:54:46 -0400 Subject: [PATCH 10/12] Add Holmes sample analysis input --- examples/sample.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 examples/sample.txt diff --git a/examples/sample.txt b/examples/sample.txt new file mode 100644 index 0000000..948afb3 --- /dev/null +++ b/examples/sample.txt @@ -0,0 +1,4 @@ +Holmes investigates evidence-first language workflows. +Sherlock Search provides discovery and retrieval. +The Canon records provenance. +Deduction Engine assembles claims, contradictions, and casefile outputs. From 59c1c9318010b12f04c0be617bba06eb97fd42a1 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Tue, 28 Apr 2026 14:55:14 -0400 Subject: [PATCH 11/12] Add Holmes CLI docs --- docs/HOLMES_CLI.md | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 docs/HOLMES_CLI.md diff --git a/docs/HOLMES_CLI.md b/docs/HOLMES_CLI.md new file mode 100644 index 0000000..9e002e2 --- /dev/null +++ b/docs/HOLMES_CLI.md @@ -0,0 +1,61 @@ +# Holmes CLI + +`holmes` is the local command-line surface for the Holmes language intelligence fabric. + +It is a releaseable skeleton for evidence-first language workflows. Runtime integrations with Sherlock Search, The Canon, Deduction Engine, Mycroft Router, Moriarty Bench, Irene Shield, and 221B are declared but intentionally reported as `not-yet-wired` until their backing services are integrated. + +## Command contract + +```bash +holmes --version +holmes doctor +holmes self-test +holmes emit-evidence +holmes analyze examples/sample.txt +holmes search "truth and evidence" +holmes graph examples/sample.txt +holmes govern examples/sample.txt +``` + +## Build and validation + +```bash +make build +make test +make validate +make dist +make release-dry-run +``` + +`make validate` runs the contract validator and exercises the compiled CLI. + +## Prophet CLI delegation + +`prophet-cli` should delegate these command families to `holmes`: + +```bash +prophet holmes analyze +prophet holmes search +prophet holmes graph +prophet holmes govern +``` + +## Integration boundaries + +Holmes owns the language intelligence product surface. + +Sherlock Search owns discovery and retrieval. + +Prophet Core Query owns shared governed query contracts. + +Agentplane owns governed execution and evidence replay. + +Prophet Platform owns runtime deployment and platform records. + +SourceOS Model Carry owns local carry refs and on-device service access. + +## Current skeleton behavior + +- `analyze` performs deterministic local file analysis: byte count, line count, word count, SHA-256, and evidence ref. +- `search`, `graph`, and `govern` return deterministic `not-yet-wired` records with stable evidence ids. +- `doctor` reports declared components as pending rather than pretending they are wired. From e4b086d598e63ec023d49649764802d4e148803c Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Tue, 28 Apr 2026 14:55:37 -0400 Subject: [PATCH 12/12] Add Holmes validation workflow --- .github/workflows/validate.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/validate.yml diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..61ab575 --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,27 @@ +name: validate + +on: + pull_request: + push: + branches: [main] + +permissions: + contents: read + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.22' + + - name: Validate + run: make validate + + - name: Release dry run + run: make release-dry-run