diff --git a/Makefile b/Makefile index 415b9f3..64376a9 100644 --- a/Makefile +++ b/Makefile @@ -78,7 +78,7 @@ test-opencode-server-agents: for reviewer in adversarial-code-reviewer infra-security-reviewer recruiter-resume-reviewer; do \ reviewer_frontmatter="$$(awk '{print} /^---$$/{n++; if (n==2) exit}' "opencode-server/files/agents/$$reviewer.md")"; \ grep -Fqx 'model: openai/gpt-6.1-sol' <<< "$$reviewer_frontmatter"; \ - case "$$reviewer" in recruiter-resume-reviewer) variant=high ;; *) variant=xhigh ;; esac; \ + variant=high; \ grep -Fqx "variant: $$variant" <<< "$$reviewer_frontmatter"; \ done; \ for agent in luna qa-engineer; do \ @@ -87,7 +87,7 @@ test-opencode-server-agents: case "$$agent" in luna) variant=low ;; *) variant=medium ;; esac; \ grep -Fqx "variant: $$variant" <<< "$$luna_frontmatter"; \ done; \ - grep -Fqx 'version: 0.5.7' opencode-server/Chart.yaml; \ + grep -Fqx 'version: 0.5.8' opencode-server/Chart.yaml; \ grep -Fqx ' "model": "openai/gpt-6.1-sol",' opencode-server/files/opencode.json; \ grep -Fqx ' "default_agent": "default",' opencode-server/files/opencode.json; \ ! grep -Fq 'twilio-docs' opencode-server/files/opencode.json; \ @@ -285,7 +285,7 @@ test-opencode-server-agents: archive_dir="$$(mktemp -d)"; \ trap 'rm -rf "$$archive_dir"' EXIT; \ helm package opencode-server --destination "$$archive_dir" > /dev/null; \ - archive="$$(find "$$archive_dir" -maxdepth 1 -type f -name 'opencode-server-0.5.7.tgz' -print -quit)"; \ + archive="$$(find "$$archive_dir" -maxdepth 1 -type f -name 'opencode-server-0.5.8.tgz' -print -quit)"; \ test -n "$$archive"; \ archive_entries="$$(tar -tzf "$$archive")"; \ ! grep -Fq 'twilio-docs-troubleshooting' <<< "$$archive_entries"; \ diff --git a/opencode-server/Chart.yaml b/opencode-server/Chart.yaml index 619e41e..18739dc 100644 --- a/opencode-server/Chart.yaml +++ b/opencode-server/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: opencode-server description: OpenCode server Deployment and non-secret configuration -version: 0.5.7 +version: 0.5.8 appVersion: "2.0.22" type: application diff --git a/opencode-server/README.md b/opencode-server/README.md index ac405c5..08701a9 100644 --- a/opencode-server/README.md +++ b/opencode-server/README.md @@ -27,7 +27,7 @@ The global model is `openai/gpt-6.1-sol`, and `default_agent` remains | All ten primaries | `openai/gpt-6.1-sol` | `medium` | | `terra` | `openai/gpt-6.1-terra` | `medium` | | `cloud-architecture-reviewer`, `devops-engineer` | `openai/gpt-6.1-sol` | `medium` | -| `adversarial-code-reviewer`, `infra-security-reviewer` | `openai/gpt-6.1-sol` | `xhigh` | +| `adversarial-code-reviewer`, `infra-security-reviewer` | `openai/gpt-6.1-sol` | `high` | | `recruiter-resume-reviewer` | `openai/gpt-6.1-sol` | `high` | | `luna` | `openai/gpt-6-luna` | `low` | | `qa-engineer` | `openai/gpt-6-luna` | `medium` | @@ -46,12 +46,25 @@ unchanged. The goal is lower delegated-task spend, not fewer tokens by fiat. See the [subagent engagement assessment](docs/agent-instruction-architecture.md#subagent-engagement-assessment-057) for the retained reviewer tiers and verification limits. -The reasoning policy follows [OpenAI model-selection guidance](https://developers.openai.com/api/docs/guides/model-selection): -Luna low for focused work, Sol medium for coordinated revisable work, and Sol -xhigh for decisions involving conflicting evidence. Recruiter high and QA -medium are role-specific starting points, not benchmarked quality guarantees. -Astra remains an exceptional, explicit owner-selected review option; no agent -or automatic escalation is introduced. Avoid a universal high/max default. +### Reviewer reasoning policy (0.5.8) + +Chart 0.5.8 changes only `adversarial-code-reviewer` and +`infra-security-reviewer` from Sol 6.1 `xhigh` to `high`. Their models, prompt +bodies and permissions remain unchanged, as do every other model/variant, +all ten primaries, the global Sol fallback, API version 2 and appVersion 2.0.22. +This is an owner-approved risk/cost starting policy, not measured optimality, +equivalent review quality or demonstrated savings. No matched comparative +evaluation was performed; CI validates configuration, render and archive contracts. + +[OpenAI reasoning guidance](https://developers.openai.com/api/docs/guides/reasoning) +reserves xhigh for evaluated benefits that justify extra latency and cost. +Effort labels are not equivalent across providers: `glm-flash` remains at `max` +for its bounded reasoning-sensitive automation, tool research, multimodal and +broad-context role, consistent with [Z.ai guidance](https://docs.z.ai/devpack/latest-model). +The flagship `glm` remains at `high`; Kimi, Luna and MiniMax remain unchanged. +After a separately approved rollout, verify fresh reviewer child sessions select +Sol/high and exercise representative synthetic reviews before making quality +claims. Astra remains an explicit owner-selected option, not automatic escalation. The chart preserves its supported legacy frontmatter format: a base model plus a separate `variant` field. The pinned OpenCode 2.0.22 @@ -384,7 +397,7 @@ allowlist transform runs after provider migration and changes only `kimi.md`, asserting each old model/variant/mode block exactly once; `kimi-256k.md` stays unchanged by that header transform. A subsequent exact two-worker source-routing transform applies only the 0.5.6 schema and full-source paragraphs to `kimi.md` and `kimi-256k.md`, asserting each old paragraph exactly once. An additional exact reasoning-policy transform applies medium to the nine historical primaries; upgrades the six -historical Sol subagents to GPT-6.1 Sol with the variants listed above; adds +historical Sol subagents to GPT-6.1 Sol with the historical 0.5.4 variants; adds low/medium to Luna/QA; replaces only the cloud reviewer's stale Terra sentence; and changes the post-migration root Kimi CN model to Sol. Each old block must occur exactly once. The mechanic is still the sole approved new agent absent @@ -393,8 +406,13 @@ from that baseline and is copied from the current source. The 0.5.7 restoration adds one exact transform after the historical reasoning step: only `terra.md` changes from GPT-6.1 Sol to GPT-6.1 Terra with its subagent mode and medium variant preserved. The old header block must occur -exactly once. Primary and reviewer headers and bodies remain unchanged; the -historical transforms, pinned baselines and full parity checks are retained. +exactly once. In that restoration, primary and reviewer headers and bodies +remain unchanged. The separate 0.5.8 transform then changes only the exact +Sol/subagent/xhigh header blocks of `adversarial-code-reviewer.md` and +`infra-security-reviewer.md` to high, requiring each old block exactly once +and rejecting missing, wrong or duplicate selection keys. Prompt bodies and +unrelated files remain protected; historical transforms, both pinned baselines +and full parity checks are retained. The existing ten-primary runtime-policy transform remains explicit; a separate pinned-base check protects every primary operating-rules tail. Non-primary @@ -428,12 +446,12 @@ is deferred. 4. Treat that pull request as a separate desired-state change gated by `kustomize-cluster` required checks. Its creation does not deploy or sync Argo CD. 5. After the GitOps pin merge, verify the `gitops-workloads` root, `opencode` child Application, Deployment rollout, pods, events, and representative OpenCode behavior. -### 0.5.7 consumer coordination gate +### 0.5.8 consumer coordination gate -At [kustomize-cluster revision 00469e89](https://github.com/makeitworkcloud/kustomize-cluster/blob/00469e89a658ffab0659d732920b792674d18ecd/.github/workflows/test.yml#L911-L916), -`test_chart_pin_and_selector_coupled` expects chart/API pair (`0.5.6`, `2`), -and the Application pins `0.5.6`. The publisher changes only the Application -pin, so its generated `0.5.7` pin PR needs the exact chart assertion updated +At [kustomize-cluster revision 2edd5531](https://github.com/makeitworkcloud/kustomize-cluster/blob/2edd55319072c9bc52ecece692c36925c28bd715/.github/workflows/test.yml), +`test_chart_pin_and_selector_coupled` expects chart/API pair (`0.5.7`, `2`), +and the Application pins `0.5.7`. The publisher changes only the Application +pin, so its generated `0.5.8` pin PR needs the exact chart assertion updated atomically in that same consumer PR, retaining API selector `2`. Do not merge an assertion-only change first or bypass required checks. Existing pin-PR auto-merge stays configured but is blocked by this assertion until coordination. diff --git a/opencode-server/docs/agent-instruction-architecture.md b/opencode-server/docs/agent-instruction-architecture.md index a6e6757..edc8449 100644 --- a/opencode-server/docs/agent-instruction-architecture.md +++ b/opencode-server/docs/agent-instruction-architecture.md @@ -199,7 +199,7 @@ The global model is `openai/gpt-6.1-sol`, and `default_agent` remains | All ten primaries | `openai/gpt-6.1-sol` | `medium` | | `terra` | `openai/gpt-6.1-terra` | `medium` | | `cloud-architecture-reviewer`, `devops-engineer` | `openai/gpt-6.1-sol` | `medium` | -| `adversarial-code-reviewer`, `infra-security-reviewer` | `openai/gpt-6.1-sol` | `xhigh` | +| `adversarial-code-reviewer`, `infra-security-reviewer` | `openai/gpt-6.1-sol` | `high` | | `recruiter-resume-reviewer` | `openai/gpt-6.1-sol` | `high` | | `luna` | `openai/gpt-6-luna` | `low` | | `qa-engineer` | `openai/gpt-6-luna` | `medium` | @@ -216,12 +216,25 @@ with their existing variants. Other workers, default-agent selection, prompts, permissions, providers, image/appVersion 2.0.22, API version 2, and pilot are unchanged. The goal is lower delegated-task spend, not fewer tokens by fiat. -The reasoning policy follows [OpenAI model-selection guidance](https://developers.openai.com/api/docs/guides/model-selection): -Luna low for focused work, Sol medium for coordinated revisable work, and Sol -xhigh for decisions involving conflicting evidence. Recruiter high and QA -medium are role-specific starting points, not benchmarked quality guarantees. -Astra remains an exceptional, explicit owner-selected review option; no agent -or automatic escalation is introduced. Avoid a universal high/max default. +### Reviewer reasoning policy (0.5.8) + +Chart 0.5.8 changes only `adversarial-code-reviewer` and +`infra-security-reviewer` from Sol 6.1 `xhigh` to `high`. Their models, prompt +bodies and permissions remain unchanged, as do every other model/variant, +all ten primaries, the global Sol fallback, API version 2 and appVersion 2.0.22. +This is an owner-approved risk/cost starting policy, not measured optimality, +equivalent review quality or demonstrated savings. No matched comparative +evaluation was performed; CI validates configuration, render and archive contracts. + +[OpenAI reasoning guidance](https://developers.openai.com/api/docs/guides/reasoning) +reserves xhigh for evaluated benefits that justify extra latency and cost. +Effort labels are not equivalent across providers: `glm-flash` remains at `max` +for its bounded reasoning-sensitive automation, tool research, multimodal and +broad-context role, consistent with [Z.ai guidance](https://docs.z.ai/devpack/latest-model). +The flagship `glm` remains at `high`; Kimi, Luna and MiniMax remain unchanged. +After a separately approved rollout, verify fresh reviewer child sessions select +Sol/high and exercise representative synthetic reviews before making quality +claims. Astra remains an explicit owner-selected option, not automatic escalation. The chart preserves its supported legacy frontmatter format: a base model plus a separate `variant` field. The pinned OpenCode 2.0.22 @@ -283,8 +296,13 @@ prompt, permission, and unrelated-file protection without a baseline rebase. The The 0.5.7 restoration adds one exact transform after the historical reasoning step: only `terra.md` changes from GPT-6.1 Sol to GPT-6.1 Terra with its subagent mode and medium variant preserved. The old header block must occur -exactly once. Primary and reviewer headers and bodies remain unchanged; the -historical transforms, pinned baselines and full parity checks are retained. +exactly once. In that restoration, primary and reviewer headers and bodies +remain unchanged. The separate 0.5.8 transform then changes only the exact +Sol/subagent/xhigh header blocks of `adversarial-code-reviewer.md` and +`infra-security-reviewer.md` to high, requiring each old block exactly once +and rejecting missing, wrong or duplicate selection keys. Prompt bodies and +unrelated files remain protected; historical transforms, both pinned baselines +and full parity checks are retained. ### Subagent engagement assessment (0.5.7) diff --git a/opencode-server/docs/memory-pilot.md b/opencode-server/docs/memory-pilot.md index da37975..12bb5d8 100644 --- a/opencode-server/docs/memory-pilot.md +++ b/opencode-server/docs/memory-pilot.md @@ -132,7 +132,7 @@ allowlist transform runs after provider migration and changes only `kimi.md`, asserting each old model/variant/mode block exactly once; `kimi-256k.md` stays unchanged. An additional exact reasoning-policy transform applies medium to the nine historical primaries; upgrades the six -historical Sol subagents to GPT-6.1 Sol with the variants in the [chart model policy](../README.md#packaged-configuration); adds +historical Sol subagents to GPT-6.1 Sol with the historical 0.5.4 variants; adds low/medium to Luna/QA; replaces only the cloud reviewer's stale Terra sentence; and changes the post-migration root Kimi CN model to Sol. Each old block must occur exactly once. The mechanic is still the sole approved new agent absent @@ -141,8 +141,13 @@ from that baseline and is copied from the current source. The 0.5.7 restoration adds one exact transform after the historical reasoning step: only `terra.md` changes from GPT-6.1 Sol to GPT-6.1 Terra with its subagent mode and medium variant preserved. The old header block must occur -exactly once. Primary and reviewer headers and bodies remain unchanged; the -historical transforms, pinned baselines and full parity checks are retained. +exactly once. In that restoration, primary and reviewer headers and bodies +remain unchanged. The separate 0.5.8 transform then changes only the exact +Sol/subagent/xhigh header blocks of `adversarial-code-reviewer.md` and +`infra-security-reviewer.md` to high, requiring each old block exactly once +and rejecting missing, wrong or duplicate selection keys. Prompt bodies and +unrelated files remain protected; historical transforms, both pinned baselines +and full parity checks are retained. The existing ten-primary runtime-policy transform remains explicit; a separate pinned-base check protects every primary operating-rules tail. Non-primary diff --git a/opencode-server/files/agents/adversarial-code-reviewer.md b/opencode-server/files/agents/adversarial-code-reviewer.md index 067725e..0c0e9b1 100644 --- a/opencode-server/files/agents/adversarial-code-reviewer.md +++ b/opencode-server/files/agents/adversarial-code-reviewer.md @@ -2,7 +2,7 @@ description: Independent hostile review of a completed implementation immediately before its pull request is opened; use for any non-trivial code, chart, workflow, or documentation change and for owner-requested second opinions; not for research, planning, trivial rewording, or implementation mode: subagent model: openai/gpt-6.1-sol -variant: xhigh +variant: high permission: edit: deny bash: deny diff --git a/opencode-server/files/agents/infra-security-reviewer.md b/opencode-server/files/agents/infra-security-reviewer.md index 9bc3087..8db2f34 100644 --- a/opencode-server/files/agents/infra-security-reviewer.md +++ b/opencode-server/files/agents/infra-security-reviewer.md @@ -2,7 +2,7 @@ description: Adversarial security review of infrastructure-affecting changes — OpenTofu, Kubernetes, Helm, GitHub Actions workflows, SOPS/KSOPS, network exposure, IAM/RBAC, and supply-chain pins — before merge of security-relevant changes; refuses secret retrieval or printing; not for runtime exploitation, account access, or implementation mode: subagent model: openai/gpt-6.1-sol -variant: xhigh +variant: high permission: edit: deny bash: deny diff --git a/opencode-server/tests/test_memory_pilot_render.py b/opencode-server/tests/test_memory_pilot_render.py index 2cf900b..88049ba 100644 --- a/opencode-server/tests/test_memory_pilot_render.py +++ b/opencode-server/tests/test_memory_pilot_render.py @@ -191,6 +191,21 @@ def _apply_approved_terra_restoration(self, baseline_chart): b"mode: subagent\nmodel: openai/gpt-6.1-terra\nvariant: medium\n", ) + def _apply_approved_reviewer_reasoning_change(self, baseline_chart): + agents_dir = os.path.join(baseline_chart, "files", "agents") + for name in ("adversarial-code-reviewer.md", "infra-security-reviewer.md"): + with open(os.path.join(agents_dir, name), "rb") as handle: + parts = handle.read().split(b"---\n", 2) + self.assertEqual(len(parts), 3, name) + self.assertEqual(parts[0], b"", name) + for key in (b"mode:", b"model:", b"variant:"): + self.assertEqual(sum(line.startswith(key) for line in parts[1].splitlines()), 1, name) + self._replace_frontmatter_line( + agents_dir, name, + b"mode: subagent\nmodel: openai/gpt-6.1-sol\nvariant: xhigh\n", + b"mode: subagent\nmodel: openai/gpt-6.1-sol\nvariant: high\n", + ) + def _apply_approved_homesteader_changes(self, baseline_chart): path = os.path.join(baseline_chart, "files", "agents", "homesteader.md") with open(path, "rb") as handle: @@ -318,6 +333,7 @@ def _extract_baseline(self, tmp): self._apply_approved_cbm_worker_source_changes(baseline_chart) self._apply_approved_reasoning_policy(baseline_chart) self._apply_approved_terra_restoration(baseline_chart) + self._apply_approved_reviewer_reasoning_change(baseline_chart) self._apply_approved_new_agent_files(baseline_chart) self._apply_primary_runtime_policy(baseline_chart) self._apply_approved_production_runtime_changes(baseline_chart) @@ -450,6 +466,51 @@ def test_transform_rejects_missing_wrong_or_duplicate_old_selections(self): BaselineParity()._apply_approved_terra_restoration(chart) +class ReviewerReasoningTransformContract(unittest.TestCase): + REVIEWERS = ("adversarial-code-reviewer.md", "infra-security-reviewer.md") + OLD = b"mode: subagent\nmodel: openai/gpt-6.1-sol\nvariant: xhigh\n" + NEW = b"mode: subagent\nmodel: openai/gpt-6.1-sol\nvariant: high\n" + ORIGINAL = b"---\ndescription: Fixture\n" + OLD + b"permission:\n edit: deny\n---\nBody retains variant: xhigh.\n" + + def _write_fixture(self, chart, originals): + agents_dir = os.path.join(chart, "files", "agents") + os.makedirs(agents_dir) + for name, content in originals.items(): + with open(os.path.join(agents_dir, name), "wb") as handle: + handle.write(content) + return agents_dir + + def test_only_allowlisted_headers_change(self): + originals = {name: self.ORIGINAL for name in self.REVIEWERS} + originals["recruiter-resume-reviewer.md"] = self.ORIGINAL + originals["terra.md"] = self.ORIGINAL + with tempfile.TemporaryDirectory() as chart: + agents_dir = self._write_fixture(chart, originals) + BaselineParity()._apply_approved_reviewer_reasoning_change(chart) + self.assertEqual(set(os.listdir(agents_dir)), set(originals)) + for name, original in originals.items(): + expected = original.replace(self.OLD, self.NEW, 1) if name in self.REVIEWERS else original + with open(os.path.join(agents_dir, name), "rb") as handle: + self.assertEqual(handle.read(), expected, name) + + def test_rejects_missing_wrong_or_duplicate_old_selections(self): + invalid = [self.ORIGINAL.replace(self.OLD, b""), self.ORIGINAL.replace(self.OLD, self.OLD * 2)] + for line, wrong in ((b"mode: subagent\n", b"mode: primary\n"), + (b"model: openai/gpt-6.1-sol\n", b"model: openai/gpt-6.1-terra\n"), + (b"variant: xhigh\n", b"variant: high\n")): + invalid.extend((self.ORIGINAL.replace(line, b""), + self.ORIGINAL.replace(line, wrong), + self.ORIGINAL.replace(line, line * 2))) + for name in self.REVIEWERS: + for candidate in invalid: + with self.subTest(agent=name, frontmatter=candidate), tempfile.TemporaryDirectory() as chart: + originals = {reviewer: self.ORIGINAL for reviewer in self.REVIEWERS} + originals[name] = candidate + self._write_fixture(chart, originals) + with self.assertRaises(AssertionError): + BaselineParity()._apply_approved_reviewer_reasoning_change(chart) + + class PrimaryModelContract(unittest.TestCase): def test_exactly_ten_primary_headers_use_gpt_6_1_sol_medium(self): expected = {"default.md", "makeitwork.md", "xnoto.md", "career.md", "teacher.md", "grillmaster.md", "homerepair.md", "homesteader.md", "lawnmowerman.md", "mechanic.md"} @@ -489,8 +550,8 @@ class OpenAIModelVariantContract(unittest.TestCase): "terra.md": ("openai/gpt-6.1-terra", "medium"), "cloud-architecture-reviewer.md": ("openai/gpt-6.1-sol", "medium"), "devops-engineer.md": ("openai/gpt-6.1-sol", "medium"), - "adversarial-code-reviewer.md": ("openai/gpt-6.1-sol", "xhigh"), - "infra-security-reviewer.md": ("openai/gpt-6.1-sol", "xhigh"), + "adversarial-code-reviewer.md": ("openai/gpt-6.1-sol", "high"), + "infra-security-reviewer.md": ("openai/gpt-6.1-sol", "high"), "recruiter-resume-reviewer.md": ("openai/gpt-6.1-sol", "high"), "luna.md": ("openai/gpt-6-luna", "low"), "qa-engineer.md": ("openai/gpt-6-luna", "medium"),