Context
Follow-up to the REVIEW.md instruction-injection issue. v1 folds maintainer instructions into the stdin prompt body via buildSystemPrompt (works for both providers, fully covered). Claude Code separates the system prompt from the user turn, so passing maintainer instructions via the dedicated --append-system-prompt flag marks them unambiguously SYSTEM (not author-controlled user content) — a cleaner separation for the self-host Claude reviewer. Ship ONLY after v1 is merged.
Requirements
- Do NOT break the
SelfHostAi.run(model, options) contract: thread an optional systemAppend through AiRunOptions (src/selfhost/ai.ts:12).
- In
createClaudeCodeAi (~ai.ts:261), when options.systemAppend is set, push "--append-system-prompt", options.systemAppend onto the args (arg order is irrelevant to the CLI). Keep the existing stdin path for the review prompt itself. The 32 KB cap keeps the argv string well under the per-arg ARG_MAX ceiling, so a flag (not a temp file) is safe.
- Codex has no
--append-system-prompt equivalent: prepend the composed instructions to the prompt string before args.push('--', prompt) (~ai.ts:309), labeled.
- Avoid double-injection: if the instructions are passed via the CLI flag for a provider, strip the instruction block from the
system string handed to THAT provider — OR keep v1's system-prompt injection as the single source and treat the flag as purely additive structure for Claude. Pick one and make it explicit; do not feed the same block twice.
Deliverables
AiRunOptions gains optional systemAppend; createClaudeCodeAi pushes the flag when set; createCodexAi prepends the labeled block when set.
- The caller in
src/queue/processors.ts passes systemAppend (the composed instructions) when the feature is active.
Acceptance criteria
--append-system-prompt is present in the Claude args ONLY when systemAppend is set; absent otherwise (byte-identical argv to today when the feature is off).
- No provider receives the instruction block twice.
- Tests assert: flag present iff
systemAppend set; codex prepend present iff set; the de-dup rule holds. 100% branch on the changed src/** lines.
npm run test:coverage (unsharded) 100% patch; npm run test:ci green; npm audit --audit-level=moderate clean.
Parent: #1029
Context
Follow-up to the REVIEW.md instruction-injection issue. v1 folds maintainer instructions into the stdin prompt body via
buildSystemPrompt(works for both providers, fully covered). Claude Code separates the system prompt from the user turn, so passing maintainer instructions via the dedicated--append-system-promptflag marks them unambiguously SYSTEM (not author-controlled user content) — a cleaner separation for the self-host Claude reviewer. Ship ONLY after v1 is merged.Requirements
SelfHostAi.run(model, options)contract: thread an optionalsystemAppendthroughAiRunOptions(src/selfhost/ai.ts:12).createClaudeCodeAi(~ai.ts:261), whenoptions.systemAppendis set, push"--append-system-prompt", options.systemAppendonto the args (arg order is irrelevant to the CLI). Keep the existing stdin path for the review prompt itself. The 32 KB cap keeps the argv string well under the per-arg ARG_MAX ceiling, so a flag (not a temp file) is safe.--append-system-promptequivalent: prepend the composed instructions to thepromptstring beforeargs.push('--', prompt)(~ai.ts:309), labeled.systemstring handed to THAT provider — OR keep v1's system-prompt injection as the single source and treat the flag as purely additive structure for Claude. Pick one and make it explicit; do not feed the same block twice.Deliverables
AiRunOptionsgains optionalsystemAppend;createClaudeCodeAipushes the flag when set;createCodexAiprepends the labeled block when set.src/queue/processors.tspassessystemAppend(the composed instructions) when the feature is active.Acceptance criteria
--append-system-promptis present in the Claude args ONLY whensystemAppendis set; absent otherwise (byte-identical argv to today when the feature is off).systemAppendset; codex prepend present iff set; the de-dup rule holds. 100% branch on the changedsrc/**lines.npm run test:coverage(unsharded) 100% patch;npm run test:cigreen;npm audit --audit-level=moderateclean.Parent: #1029