Skip to content

Harden lifecycle cleanup and verification boundaries - #926

Merged
morluto merged 4 commits into
mainfrom
agent/harden-runtime-cleanup
Aug 9, 2026
Merged

Harden lifecycle cleanup and verification boundaries#926
morluto merged 4 commits into
mainfrom
agent/harden-runtime-cleanup

Conversation

@morluto

@morluto morluto commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Summary

Tightens the cleanup and verification boundaries identified in the repository hotspot audit.

  • preserve every runtime, MCP tenant, portfolio, Lean-session, and SQLite-close failure while continuing sibling teardown
  • reject missing polynomial checkers at the capability boundary and keep bounded inline checker outcomes unverified
  • move common worker launch and settlement mechanics into the lifecycle owner
  • split trajectory replay validation into named invariants and remove the final C901 baseline exception

Why

Several nested resource owners previously stopped on KeyboardInterrupt or discarded a secondary close failure. That could leave sibling resources running or hide useful shutdown diagnostics. Polynomial capability construction and inline verification also had paths where checker availability or bounded coverage did not produce the clearest fail-closed result.

Validation

  • make test-unit — 869 passed
  • make test-process — 235 passed
  • make test-composition — 481 passed
  • make lint typecheck — passed; C901 baseline now has 0 violations
  • make check-static — passed
  • make security-audit — no known vulnerabilities
  • make duplicate-code — 0 clones

Suggested review order

  1. Runtime/MCP/SQLite teardown behavior and regressions
  2. Polynomial checker and inline-verification safeguards
  3. Shared lifecycle extraction
  4. Trajectory replay validation refactor

@morluto
morluto marked this pull request as ready for review August 9, 2026 08:16
@cursor

cursor Bot commented Aug 9, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@morluto
morluto merged commit 5ebc889 into main Aug 9, 2026
39 of 40 checks passed
@morluto
morluto deleted the agent/harden-runtime-cleanup branch August 9, 2026 08:19

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Open in Devin Review

Comment on lines +306 to +314
if not decision.accepted or decision.coverage is Coverage.BOUNDED:
detail = (
decision.detail
if not decision.accepted
else (
"Inline exact verification cannot bind a bounded scope; the "
"checker must report exhaustive or not-applicable coverage."
)
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Inline exact guard covers only BOUNDED coverage, not other unverifiable decisions

The new guard fails closed for an accepted decision with Coverage.BOUNDED, but an accepted decision with Coverage.RESTRICTED/Coverage.SAMPLED, a non-replayable Method, or Arithmetic.FLOATING_HEURISTIC still falls through to the accepted path. In that case _commit_verification_record persists an InlineExactVerificationRecord first, and only afterwards does the Assurance model validator (src/jacobian/contracts/results.py:104-140) reject Verification.VERIFIED, so the ValueError is swallowed by _RECOVERABLE_VERIFICATION_ERRORS and the caller sees an ERROR result while the record artifact already exists in the store. No in-tree checker produces those combinations today (src/jacobian_checkers/exact_domain_operations.py only emits NOT_APPLICABLE/EXHAUSTIVE), so this is currently unreachable, but the same defensive reasoning that motivated the BOUNDED guard applies to the other unverifiable combinations.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8cdd91e5a8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 319 to +320
input=InputValidation(
status=InputStatus.REJECTED, errors=(decision.detail,)
status=InputStatus.REJECTED, errors=(detail,)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve accepted input for bounded checker outcomes

When an authorized checker accepts the exact claim but reports Coverage.BOUNDED, the request has already passed schema and binding validation, yet this branch marks its input as rejected. This conflates input validity with insufficient coverage and causes consumers to diagnose a valid request as malformed; keep the input accepted while reporting the bounded decision as UNKNOWN and UNVERIFIED through the conclusion, assurance, and execution detail.

AGENTS.md reference: AGENTS.md:L140-L143

Useful? React with 👍 / 👎.

Comment on lines +324 to +326
error.add_note(
f"state database handle cleanup also failed: {close_error}"
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the secondary database close exception

When checkpointing and handle cleanup both fail, converting close_error to a note discards its type, traceback, and identity; it also turns a secondary KeyboardInterrupt or SystemExit into an ordinary StateDatabaseError. Raise both failures in an appropriate exception group so callers and diagnostics can inspect every teardown failure rather than retaining only its string.

Useful? React with 👍 / 👎.

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.

1 participant