Context
Follow-up from #414 (clean Ctrl+C exit for the jrag console script).
Every other jrag failure mode emits a structured status="error" envelope to stdout so JSON consumers always get a parseable result:
- internal error — `src/java_codebase_rag/jrag.py` `main()` `except Exception`
- usage error — `main()` `except argparse.ArgumentError`
On Ctrl+C, the new handler writes only `"\Interrupted."\n"` to stderr and exits `130` — no envelope on stdout.
The decision
Which is the intended contract?
- (A) Hard stop, no envelope, exit 130 (current). Defensible: emitting mid-interrupt can itself be unsafe, and 130 is the conventional SIGINT code.
- (B) Emit a final `status="error"` envelope (e.g. `message="interrupted"`) so JSON consumers terminate cleanly. Cost: must be safe to emit on the interrupt path.
If (A) is chosen
Add a one-line docstring note on `jrag._console_script_main` so the divergence from the envelope contract is deliberate rather than accidental.
If (B) is chosen
Emit the envelope before the `os._exit(130)` in the `except KeyboardInterrupt` block.
Needs a maintainer call — flagging so it's a conscious decision, not a silent gap.
Context
Follow-up from #414 (clean Ctrl+C exit for the
jragconsole script).Every other
jragfailure mode emits a structuredstatus="error"envelope to stdout so JSON consumers always get a parseable result:On Ctrl+C, the new handler writes only `"\Interrupted."\n"` to stderr and exits `130` — no envelope on stdout.
The decision
Which is the intended contract?
If (A) is chosen
Add a one-line docstring note on `jrag._console_script_main` so the divergence from the envelope contract is deliberate rather than accidental.
If (B) is chosen
Emit the envelope before the `os._exit(130)` in the `except KeyboardInterrupt` block.
Needs a maintainer call — flagging so it's a conscious decision, not a silent gap.