09. Contracts: Exit Codes¶
Purpose¶
Define stable process exit semantics and category boundaries.
Public surface¶
- Exit enum:
codeclone/contracts/__init__.py:ExitCode - CLI entry:
codeclone/main.py:main - CLI orchestration:
codeclone/surfaces/cli/workflow.py:_main_impl - Error markers/formatters:
codeclone/ui_messages/*(canonical definitions inmarkers.pyandformatters.py; re-exported from__init__.py)
Data model¶
| Exit code | Category | Meaning |
|---|---|---|
0 |
success | Run completed without gating failures |
2 |
contract error | Input or contract violation |
3 |
gating failure | Analysis succeeded but policy failed |
5 |
internal error | Unexpected exception escaped top-level CLI handling |
Refs:
codeclone/contracts/__init__.py:ExitCodecodeclone/config/argparse_builder.py:_ArgumentParser.error
Contracts¶
- Contract errors use the
CONTRACT ERROR:marker. - Gating failures use the
GATING FAILURE:marker. - Internal errors use
INTERNAL ERROR:and hide traceback unless debug is enabled. main()letsSystemExitfrom contract/gating paths pass through unchanged.
Refs:
codeclone/ui_messages/__init__.py:MARKER_CONTRACT_ERRORcodeclone/ui_messages/__init__.py:MARKER_INTERNAL_ERRORcodeclone/ui_messages/__init__.py:fmt_contract_errorcodeclone/report/gates/reasons.py:print_gating_failure_blockcodeclone/ui_messages/__init__.py:fmt_internal_error
Invariants (MUST)¶
- Only non-
SystemExitexceptions inmain()become exit5. - Gating mode is enabled when any of
--ci,--fail-on-new,--fail-threshold,--fail-complexity,--fail-coupling,--fail-cohesion,--fail-cycles,--fail-dead-code,--fail-health,--fail-on-new-metrics,--fail-on-typing-regression,--fail-on-docstring-regression,--fail-on-api-break,--min-typing-coverage, or--min-docstring-coverageis active (codeclone/surfaces/cli/runtime.py:gating_mode_enabled). --fail-on-untested-hotspotsis a Coverage Join policy gate (exit3when breached). It requires--coverage/coverage_xmland is evaluated after metrics analysis, not viagating_mode_enabledunreadable-source precedence.- In gating mode, unreadable source files produce
CONTRACT ERROR:and exit2before clone/metric gate evaluation (GATING FAILURE:is suppressed when both would apply).
Refs:
codeclone/main.py:maincodeclone/surfaces/cli/workflow.py:_main_impl
Failure modes¶
| Condition | Marker | Exit |
|---|---|---|
| Invalid output extension/path | CONTRACT ERROR |
2 |
| Invalid CLI flag combination | CONTRACT ERROR |
2 |
| Invalid controller query combination | CONTRACT ERROR |
2 |
--patch-verify without trusted baseline |
CONTRACT ERROR |
2 |
| Untrusted baseline in CI/gating | CONTRACT ERROR |
2 |
| Unreadable source in CI/gating | CONTRACT ERROR |
2 |
New clones with --fail-on-new |
GATING FAILURE |
3 |
Blocking --patch-verify violation |
GATING FAILURE |
3 |
| Threshold or metrics gate breach | GATING FAILURE |
3 |
Untested coverage hotspots with --fail-on-untested-hotspots |
GATING FAILURE |
3 |
| Unexpected exception in top-level CLI path | INTERNAL ERROR |
5 |
Determinism / canonicalization¶
- Help epilog strings are generated from static constants.
- Error category markers are static constants.
Refs:
codeclone/contracts/__init__.py:cli_help_epilogcodeclone/ui_messages/__init__.py:MARKER_CONTRACT_ERROR
Locked by tests¶
tests/test_cli_unit.py::test_cli_help_text_consistencytests/test_cli_unit.py::test_cli_internal_error_markertests/test_cli_unit.py::test_cli_internal_error_debug_flag_includes_tracebacktests/test_cli_inprocess.py::test_cli_unreadable_source_fails_in_ci_with_contract_errortests/test_cli_inprocess.py::test_cli_contract_error_priority_over_gating_failure_for_unreadable_source
Non-guarantees¶
- Exact message body wording may evolve; marker category and exit code are contract.