Skip to content

Two conformance kits reported pass when you pressed Ctrl-C - #102

Merged
arpanghoshal merged 3 commits into
mainfrom
codeql-gaps
Sep 6, 2026
Merged

arpanghoshal merged 3 commits into
mainfrom
codeql-gaps

Conversation

@arpanghoshal

Copy link
Copy Markdown
Member

Reading the 211 open code-scanning alerts turned up four defects behind the noise. PR #99
handles the noise
— the query filters and the redundant imports. This is what was under it.

Two false greens in the conformance kits

conformance/store/suites.py caught BaseException on a path that returns passed(...), in
two cases. Press Ctrl-C during either and the suite whose entire purpose is to refuse false
greens produced one.

SPEC-v0.1 §5.5 is the rule, and it is not "catch less": the executor path must catch
BaseException, record, and re-raise. An adapter or a store may raise anything and the kit
must grade it — the breadth was never the defect, the swallow was. _not_ours_to_grade
re-raises what is not an Exception, at every catch site in both kits.

The adapter kit's sites returned failed rather than passed, so they surfaced an interrupt
instead of hiding it — but an interrupted run still produced a conformance verdict blaming
somebody's adapter for the operator's Ctrl-C.

A cycle between the two gateway servers, which #96 introduced

Mine. Moving check_jwt_flags into server.py and typing it against
GatewayConfig | OperatorConfig needed a TYPE_CHECKING import of the console — so the gateway
named the console and the console imported the gateway. py/unsafe-cyclic-import, six times,
and a layering inversion against ARCHITECTURE §6.

The shared half moves down to gateway/wire.py: response bytes, JSON-RPC envelopes, the header
lookup, the flag validation. Neither server imports the other, and a test says so — nothing
did, which is why the cycle landed.

The access log took the client's request line unescaped

log_message interpolated it straight into a line-per-record log, where a newline forges a whole
record. That is the hazard state.py refuses control characters in an approver's name for. A log
line cannot be refused, so it is escaped — with a control test, because escaping that mangled
every ordinary line would be worse than the hazard.

repoint-claims.py wrote wrong line numbers and its guard accepted them

Flagged in #96 and now fixed. Both sides asked which symbol is this citation about and both
answered with the whole row, so a row citing six commands had every reference re-pointed at
one definition — and the guard passed, because that line does define a symbol the row names.

Two more defects fell out while fixing it:

  • the rewrite was a global str.replace on the citation's text, so two citations of one line in
    a row could not move apart — fixing a stale one broke a correct one beside it;
  • the tokenizer took only the first identifier in a backtick span, so `ctrlrun delegate`
    owned ctrlrun and looked stale.

tools/docs_audit/claims.py is the one producer now, imported by the writer and by the guard, so
they cannot disagree again. It immediately caught a reference this branch's own refactor had
shifted.

Verification

  • 7 mutations, 7 red, control green. The first run had one green — nothing stopped the import
    cycle coming back — so the assertion for it was written and the row went red.
  • Full suite: 4052 passed, 45 skipped. ruff, ruff format --check and mypy --strict
    clean.
  • Built in a separate git worktree, so it never touched the working tree another session was
    using.

Merge order

Touches tests/test_packaging.py, which #99 also touches#99 removes a redundant import
there, this rewrites the CLAIMS guard in the same file. Merge #99 first and this will need a
trivial rebase; the two edits are in different functions.

Reading the 211 open code-scanning alerts turned up four things behind the
noise. PR #99 handles the noise; these are the defects under it.

**`except BaseException` on a path that returns `passed`.** In the store kit,
`no-not-executed` swallowed everything a store method raised and then reported
the case passed, and `insert-not-upsert` did the same after inspecting the
record. Press Ctrl-C during either and the suite whose whole purpose is to
refuse false greens produced one.

SPEC-v0.1 §5.5 is the rule and it is not "catch less": the executor path must
catch BaseException, record, and **re-raise**. The breadth was never the
defect -- an adapter or a store may raise anything and the kit must grade it --
the swallow was. `_not_ours_to_grade` re-raises what is not an Exception, at
every catch site in both kits. The adapter kit's sites returned `failed`
rather than `passed`, so they surfaced an interrupt instead of hiding it, but
an interrupted run still produced a conformance verdict blaming somebody's
adapter for the operator's Ctrl-C.

**A cycle between the two gateway servers, which #96 introduced.** Moving
`check_jwt_flags` into `server.py` and typing it against
`GatewayConfig | OperatorConfig` needed a TYPE_CHECKING import of the console,
so the gateway named the console and the console imported the gateway --
`py/unsafe-cyclic-import`, six times, and a layering inversion against
ARCHITECTURE §6. The shared half moves to `gateway/wire.py`, below both:
response bytes, JSON-RPC envelopes, the header lookup, the flag validation.
Neither server imports the other, and a test says so, because nothing did.

**The access log took the client's request line unescaped.** `log_message`
interpolated it straight into a line-per-record log, where a newline forges a
whole record -- the hazard `state.py` refuses control characters in an
approver's name for. A log line cannot be refused, so it is escaped.

**`repoint-claims.py` wrote wrong line numbers and its guard accepted them.**
Both sides asked "which symbol is this citation about" and both answered with
the whole row, so a row citing six commands had every reference re-pointed at
one definition and the guard passed, because that line does define a symbol
the row names. Two further defects fell out while fixing it: the rewrite was a
global `str.replace` on the citation's text, so two citations of one line in a
row could not move apart and fixing a stale one broke a correct one; and the
tokenizer took only the first identifier in a backtick span, so
`ctrlrun delegate` owned `ctrlrun` and looked stale.

`tools/docs_audit/claims.py` is now the one producer, imported by the writer
and by the guard, and it caught a reference this branch's own refactor had
shifted.

7 mutations, 7 red, control green. 4052 passed.
@mintlify

mintlify Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
ctrlrun 🟢 Ready View Preview Sep 6, 2026, 8:05 PM

💡 Tip: Enable Automations to automatically generate PRs for you.

)
except BaseException:
pass
except BaseException as other:
try:
store.put_delegation(_delegation(identifier))
except BaseException:
except BaseException as raised:
Comment thread src/ctrlrun/gateway/wire.py Fixed
Comment thread src/ctrlrun/gateway/wire.py Fixed
Comment thread src/ctrlrun/gateway/wire.py Fixed
Comment thread src/ctrlrun/gateway/wire.py Fixed
Comment thread src/ctrlrun/gateway/wire.py Fixed
Comment thread src/ctrlrun/gateway/wire.py Fixed
Comment thread src/ctrlrun/gateway/wire.py Fixed
Comment thread tests/test_mcp_operator.py Fixed
@arpanghoshal
arpanghoshal merged commit 750cae9 into main Sep 6, 2026
11 checks passed
@arpanghoshal
arpanghoshal deleted the codeql-gaps branch September 6, 2026 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants