feat(cli): opt-in exit contract for index_repository - #2092
Conversation
|
Thanks for opening this — it has been seen, and it is queued. This note is automated, but it is not a brush-off: it exists so you know where your PR stands instead of having to guess from silence. Current review status: working through a backlog. What that means for this PR, concretely:
Things that will genuinely speed it up whenever review does happen:
If this fixes a bug, a reproduction we can run is worth more than a description of the symptom. Thanks for contributing, and sorry in advance for the wait. |
d1abca2 to
1f08f82
Compare
|
Thank you for the detailed CLI proposal and its tests. This spans exit-status semantics, environment defaults, output fields and index handling, so we need more time to review the compatibility and scope decisions before giving a direction. Please do not read the triage labels as approval of new defaults. The review queue is currently full, so detailed feedback may take a little time. We are working through it carefully and appreciate the work you have put into supporting the project. Thank you for your patience. |
b2bb18c to
b317506
Compare
A freshness gate cannot read a tool's account of itself — it reads the
process status. index_repository returned 0 for a partial index and the
same 1 for both a missing repository and a pipeline that fell over inside
an existing one, so no caller could tell those apart.
The CLI now grades its own outcome:
0 indexed, quality at or above the thresholds
1 hard failure inside a reachable repository (unchanged meaning)
2 indexed but below a quality threshold
3 repo_path absent, unreadable, or not a directory
The contract is opt-in: it applies only with CBM_GATE set to a non-empty
value other than "0". Without it the CLI exits exactly as before, so a
caller that never asked for grading never sees a new code. Grading
happens in the CLI only. MCP responses are untouched, so agents and the
soak test, which judge by JSON-RPC and tool-level isError, see exactly
what they saw before.
Thresholds are separate on purpose and overridable:
CBM_GATE_MAX_UNUSABLE default 0 a file that did not parse at all
CBM_GATE_MAX_PARTIAL_PCT default 10 share of partially parsed files
Partial parsing marks constructs a grammar does not cover — a property of
language support, not of index quality; this repository itself sits at
5.8%. A gate its own project cannot pass gets switched off.
Two additive fields carry what the grading needs:
files_indexed, parse_partial_pct the denominator the ratio needs and
the share stated outright, so a gate can quote it in a refusal
reason on failures: target_unavailable vs pipeline_failed
Signed-off-by: Vladislav Rahmanov <rahmanov.official@yandex.ru>
The contract landed measured but unpinned: six outcomes were checked by
hand against the built binary and written into the pull request, and
nothing in the suite would notice if a code moved. A verification that
does not run again is a claim, not a test.
Twelve cases over cbm_cli_index_exit_status, which grades a result
envelope into a process exit code:
clean run stays 0; an unusable file and a partial share above the
ceiling both grade 2; "degraded" grades 2 on the status alone; an
absent target grades 3 while a pipeline failure keeps 1 — the pair
that shared code 1 before and gave the whole contract its reason.
Three of them exist to fail if the grader stops working rather than to
pass when it does:
- the ceiling itself is exercised from both sides, 10 of 100 passing
and 11 failing, because a test that only checks obvious excess stays
green with the check switched off entirely;
- the threshold overrides carry a positive control at the defaults, so
"passed after raising the ceiling" cannot be confused with "no check
ran";
- eight unreadable threshold values are pinned to fall back on the
documented default, since a typo that silently disables a gate is the
failure the strict parse was written to prevent.
Silence is pinned too: a null, empty, unreadable, or content-less
envelope preserves the base status in both directions. Inventing a
quality verdict out of an unparsable payload would fail runs for the
crime of an unexpected response shape.
Envelopes are built with yyjson rather than hand-escaped, so the
payload's quoting is the transport's and not the test's own.
Signed-off-by: Vladislav Rahmanov <rahmanov.official@yandex.ru>
b317506 to
b037b48
Compare
|
Reworked after your note on defaults, and narrowed to one claim per the contributing guide. The contract is now opt-in: nothing changes unless Rebased on |
Refs #2168
Opt-in exit contract for
cli index_repositoryA freshness gate cannot read a tool's account of itself, it reads the process
status. Today
index_repositoryreturns0for an index that parsed part ofthe tree, and the same
1whether the repository is missing or a pipeline fellover inside one that exists. Callers cannot tell those apart.
Nothing changes unless
CBM_GATE=1is set. Without it the CLI exitsexactly as before. With it, grading happens in the CLI only; MCP responses are
untouched, so agents and
scripts/soak-test.sh, which judge by JSON-RPC andtool-level
isError, see exactly what they saw before.CBM_GATE=1status: degraded)repo_pathabsent, unreadable, or not a directoryThresholds, both optional, negative disables the check:
CBM_GATE_MAX_UNUSABLE, default0, absolute count of unparsable filesCBM_GATE_MAX_PARTIAL_PCT, default10, share of partially parsed filesThe two defaults differ deliberately. A file that did not parse at all is a
defect and gets no tolerance. Partial parsing marks constructs a grammar does
not cover, a property of language support rather than of index quality: this
repository itself sits at 5.8% with a fully working graph. A gate its own
project cannot pass gets switched off, which protects nothing.
Additive fields
files_indexedandparse_partial_pcton the index response. The ratio hadno denominator, and a gate that can only pass or fail cannot say how
partial a parse was.
reasonon failures,target_unavailableorpipeline_failed. The hinttext read identically for both.
Verification
Full suite on this branch: 8001 passed, 1 failed, 7 skipped. The one failure is
daemon_ipc_posix_single_uid_userns_real_smoke_issue1830, which fails the sameway on a clean build of
mainat 055fbb7 on this machine (user-namespacesetup), so it is unrelated to this change.
13 tests in the
clisuite pin the contract, including that an unset, emptyor
0CBM_GATEleaves the historical status untouched.End to end on this repository (clean git worktree of this branch, isolated
CBM_CACHE_DIRandCBM_RUNTIME_DIR), exit status read without a pipeline so$?is the command's own:The same sequence against a binary built from
mainat 055fbb7 gives1 / 0 / 1 / 0 / 0: today's status, unchanged by the variable.