diff --git a/AGENTS.md b/AGENTS.md index a31878c13..c9e229bf5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -694,8 +694,10 @@ in this repo. `codegraph init -i` autonomously without asking first; keep generated `.codegraph/` and `.cursor/rules/codegraph.mdc` artifacts local unless a future repository policy explicitly says to commit them. OpenCode PR review - uses the project `opencode.jsonc` MCP servers for CodeGraph, DeepWiki, - Context7, and web search. It must initialize CodeGraph before review so + receives the only `opencode.jsonc` from the central required workflow; do not + add repository-local `opencode.json` or `opencode.jsonc`. The central owner + registers review MCP servers, including Graphify. It must initialize + CodeGraph before review so structural findings cite graph-backed evidence instead of relying only on grep or raw file reads; use Context7 for current library docs, DeepWiki for repository documentation, and web search only for bounded external lookups. diff --git a/CLAUDE.md b/CLAUDE.md index fa0597bce..1814c98ee 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -17,6 +17,9 @@ merged by metadata-only robot governance (see `docs/development/merge-gate-policy.md`); OpenCode Review, Strix Security Scan, and the merge scheduler come from central workflows in `ContextualWisdomLab/.github` — do not reintroduce repo-local copies. +That owner also supplies the only `opencode.jsonc` used by required review; +Naruon must not add `opencode.json` or `opencode.jsonc`. Central review MCP +registration, including Graphify, stays owner-controlled. ## Common commands diff --git a/backend/tests/test_agent_llm_authority_docs.py b/backend/tests/test_agent_llm_authority_docs.py index e8dcc9c40..7104302a5 100644 --- a/backend/tests/test_agent_llm_authority_docs.py +++ b/backend/tests/test_agent_llm_authority_docs.py @@ -1,6 +1,5 @@ """Regression contracts for current LLM-routing authority guidance.""" -import json from pathlib import Path @@ -52,32 +51,3 @@ def test_agent_guidance_names_canonical_llm_owner_and_fail_closed_boundary() -> assert "provider discovery" in architecture assert "immutable released" in architecture assert "fails closed" in architecture - - -def test_opencode_config_uses_only_contextual_orchestrator_free() -> None: - """Repository OpenCode model work must use only the canonical logical pool.""" - raw_config = _read("opencode.jsonc") - config = json.loads(raw_config) - - assert config["model"] == "contextual-orchestrator/orchestrator/free" - assert config["small_model"] == "contextual-orchestrator/orchestrator/free" - assert config["enabled_providers"] == ["contextual-orchestrator"] - assert set(config["provider"]) == {"contextual-orchestrator"} - - provider = config["provider"]["contextual-orchestrator"] - assert provider["options"] == { - "baseURL": "{env:CONTEXTUAL_ORCHESTRATOR_BASE_URL}", - "apiKey": "{env:CONTEXTUAL_ORCHESTRATOR_TOKEN}", - } - assert set(provider["models"]) == {"orchestrator/free"} - - forbidden_direct_routing = ( - "github-models", - "STRIX_GITHUB_MODELS_TOKEN", - "https://models.github.ai/inference", - '"openai/gpt-5"', - '"deepseek/deepseek-r1-0528"', - '"deepseek/deepseek-v3-0324"', - ) - for phrase in forbidden_direct_routing: - assert phrase not in raw_config diff --git a/backend/tests/test_opencode_central_config_consumer.py b/backend/tests/test_opencode_central_config_consumer.py new file mode 100644 index 000000000..32b20a186 --- /dev/null +++ b/backend/tests/test_opencode_central_config_consumer.py @@ -0,0 +1,22 @@ +"""Contract for consuming OpenCode review configuration from the central owner.""" + +from pathlib import Path + + +REPO_ROOT = Path(__file__).resolve().parents[2] + + +def test_required_review_has_no_repository_local_opencode_configuration() -> None: + """Repository-local OpenCode JSON must not fork the central review policy.""" + + for relative_path in ("opencode.json", "opencode.jsonc"): + assert not (REPO_ROOT / relative_path).exists(), ( + "central OpenCode configuration must remain owner-controlled: " + f"{relative_path}" + ) + + agents = (REPO_ROOT / "AGENTS.md").read_text(encoding="utf-8") + claude = (REPO_ROOT / "CLAUDE.md").read_text(encoding="utf-8") + for guidance in (agents, claude): + assert "only `opencode.jsonc`" in guidance + assert "Graphify" in guidance diff --git a/opencode.jsonc b/opencode.jsonc deleted file mode 100644 index f942535d1..000000000 --- a/opencode.jsonc +++ /dev/null @@ -1,60 +0,0 @@ -{ - "$schema": "https://opencode.ai/config.json", - "model": "contextual-orchestrator/orchestrator/free", - "small_model": "contextual-orchestrator/orchestrator/free", - "enabled_providers": ["contextual-orchestrator"], - "mcp": { - "codegraph": { - "type": "local", - "command": ["npx", "-y", "@colbymchenry/codegraph@0.9.9", "serve", "--mcp"], - "enabled": true - }, - "deepwiki": { - "type": "remote", - "url": "https://mcp.deepwiki.com/mcp", - "enabled": true, - "timeout": 300000 - }, - "context7": { - "type": "local", - "command": ["npx", "-y", "@upstash/context7-mcp@3.1.0", "--transport", "stdio"], - "enabled": true, - "timeout": 300000, - "environment": { - "NPM_CONFIG_IGNORE_SCRIPTS": "true", - "NPM_CONFIG_LOGLEVEL": "error" - } - }, - "web_search": { - "type": "local", - "command": ["npx", "-y", "@guhcostan/web-search-mcp@1.0.5"], - "enabled": true, - "timeout": 300000, - "environment": { - "NPM_CONFIG_IGNORE_SCRIPTS": "true", - "NPM_CONFIG_LOGLEVEL": "error" - } - } - }, - "provider": { - "contextual-orchestrator": { - "npm": "@ai-sdk/openai-compatible", - "name": "Contextual Orchestrator", - "options": { - "baseURL": "{env:CONTEXTUAL_ORCHESTRATOR_BASE_URL}", - "apiKey": "{env:CONTEXTUAL_ORCHESTRATOR_TOKEN}" - }, - "models": { - "orchestrator/free": { - "name": "Orchestrator Free", - "tool_call": true, - "reasoning": true, - "limit": { - "context": 200000, - "output": 32768 - } - } - } - } - } -}