Parent: #1936
Problem
ai-review.ts's dual-AI CombineStrategy/onMerge/reviewers config is a real, shipped capability that changes how the two independent AI opinions become one gate decision — but it's only settable via the self-host operator-level env.AI_REVIEW_PLAN boot config, not per-repo. There is no review.combine, review.on_merge, or review.reviewers field in the manifest schema, so an individual repo maintainer on a shared self-host instance cannot opt into synthesis (block on either reviewer) or pick a different confidence trade-off without an operator redeploying the whole instance's env config. This breaks the house pattern (.gittensory.yml > DB > safe default, config-driven per repo) every other AI-review knob (profile, inline_comments, path_instructions, instructions, exclude_paths, pre_merge_checks) already follows. Lower priority — the operator-level default is a reasonable v1, this is a refinement.
Requirements
- Add
review.combine/review.onMerge/review.reviewers-equivalent fields to FocusManifestSettings's review config, allowing a per-repo override of the operator's AI_REVIEW_PLAN default.
- Per-repo override should be a REFINEMENT only, not a way to bypass an operator-imposed floor (e.g. an operator running a strict instance shouldn't have a repo able to loosen
onMerge below the operator's own minimum, if the operator has set one) — worth a short design note on precedence before implementing.
- Config-driven, matching the existing
.gittensory.yml > DB > safe-default precedence pattern.
Deliverables
- The new manifest fields wired through
src/signals/focus-manifest.ts and consumed by src/services/ai-review.ts in place of the unconditional env.AI_REVIEW_PLAN read.
- A short precedence design note (operator floor vs. per-repo override) resolved before/during implementation.
- Tests covering: a repo without an override inherits the operator default unchanged; a repo with a valid override uses it; an invalid/out-of-bounds override is rejected or clamped per the precedence design.
Acceptance criteria
- A repo can set its own combine strategy via
.gittensory.yml, overriding the operator's instance-wide default, within whatever precedence bounds are decided.
- A repo without an override sees zero behavior change.
Expected outcome
The dual-AI combine strategy follows the same config-as-code precedence every other AI-review knob already follows, instead of being the one operator-only exception.
Parent: #1936
Problem
ai-review.ts's dual-AICombineStrategy/onMerge/reviewersconfig is a real, shipped capability that changes how the two independent AI opinions become one gate decision — but it's only settable via the self-host operator-levelenv.AI_REVIEW_PLANboot config, not per-repo. There is noreview.combine,review.on_merge, orreview.reviewersfield in the manifest schema, so an individual repo maintainer on a shared self-host instance cannot opt into synthesis (block on either reviewer) or pick a different confidence trade-off without an operator redeploying the whole instance's env config. This breaks the house pattern (.gittensory.yml> DB > safe default, config-driven per repo) every other AI-review knob (profile, inline_comments, path_instructions, instructions, exclude_paths, pre_merge_checks) already follows. Lower priority — the operator-level default is a reasonable v1, this is a refinement.Requirements
review.combine/review.onMerge/review.reviewers-equivalent fields toFocusManifestSettings's review config, allowing a per-repo override of the operator'sAI_REVIEW_PLANdefault.onMergebelow the operator's own minimum, if the operator has set one) — worth a short design note on precedence before implementing..gittensory.yml> DB > safe-default precedence pattern.Deliverables
src/signals/focus-manifest.tsand consumed bysrc/services/ai-review.tsin place of the unconditionalenv.AI_REVIEW_PLANread.Acceptance criteria
.gittensory.yml, overriding the operator's instance-wide default, within whatever precedence bounds are decided.Expected outcome
The dual-AI combine strategy follows the same config-as-code precedence every other AI-review knob already follows, instead of being the one operator-only exception.