Repository navigation
chore(integration): merge rehearsal for the 10 open PRs, with local proof - #301
PetrefiedThunder wants to merge 32 commits into
Conversation
Updates the requirements on [greenlet](https://github.com/python-greenlet/greenlet) to permit the latest version. - [Changelog](https://github.com/python-greenlet/greenlet/blob/master/CHANGES.rst) - [Commits](python-greenlet/greenlet@3.5.4...3.5.5) --- updated-dependencies: - dependency-name: greenlet dependency-version: 3.5.5 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>
…trument Continues the two open threads from docs/market-research-2026-08.md §8.3, turning both from recommendations into artifacts. The interop experiment has been run. examples/acta_receipt_interop.py transcodes a signed portable receipt into the ScopeBlind ACTA envelope (draft-farley-acta-signed-receipts) as a custom agentmiddleware:governed_invoke receipt type: inner production signature verified over the exact signing_input bytes exactly as b2a-verify-receipt does, outer Ed25519-over-JCS envelope with issuer_id bound to the signing kid, and the ledger/idempotency/permit linkage — the row no surveyed format defines — carried as first-class fields. The demo runs against the checked-in public proof artifact and both signatures verify. Fail-closed by design: unverified inner signatures, tampered signing_input, kid mismatches, missing economic linkage, and floats in the JCS subset are all refused, each with a negative test (8 tests total). Deliberately an experiment in examples/, not an SDK export or route — WEDGE.md's freeze discipline stands, and shipping it is a product call. The measured cost (~200 lines, no trust-plane changes) replaces the estimate in §8.3. The demand question has an instrument. docs/partner-interview-script.md is a past-tense-only discovery script: incident excavation first, the product unmentioned for 25 minutes, current mitigations treated as the real competitor, money questions about past spend rather than hypothetical willingness, a commitment test priced in a named engineer's afternoon, a per-call scoring table, and a decision rule committed before the interviews (3/5 incidents + 2/5 commitments → paid-pilot conversation; incidents without commitment → reposition around evidence; no incidents → the market isn't here yet). The script explicitly forbids using the LangGraph citation to manufacture pain. Also updates §7/§8.3 of the research doc to point at both artifacts, and the changelog. Tests: 51 passed across the new suite, wedge-honesty, and site contracts. Ruff clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FsXYfTHDLiFNQ24R5JPN7H
All 14 jobs on the previous run were refused in under two seconds with no runner assigned and no step output — an Actions capacity/limit refusal, not a test failure. No code changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FsXYfTHDLiFNQ24R5JPN7H
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FsXYfTHDLiFNQ24R5JPN7H
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FsXYfTHDLiFNQ24R5JPN7H
…rview-script rigor
Interop example:
- verify_portable_bundle now takes expected_issuer: the wrapper's issuer
field is outside the signed bytes, so it is checked against the issuer
bound to the key material in the trust-keys snapshot instead of being
trusted on its own. Demo and roundtrip test pass the snapshot's issuer;
a new negative test mutates issuer post-signing and is refused.
- verify_acta_receipt now rejects a signature block whose alg is not
Ed25519 or whose sig is not a hex string; new test tampers only alg.
- Research doc no longer implies the issuer label itself is signed.
Interview script:
- One timing boundary: reveal at ~minute 25, framing says 25 minutes.
- §1 opens with a broad narrative prompt before the pointed probe, so
incidents that don't fit our shape still get told.
- §2 no longer supplies 'idempotency keys'; it reuses the interviewee's
own words (rule 5 marked as applying everywhere except §4).
- §3 adds the buyer question: last approver, budget owner, procurement.
- §3's vendor question is past-tense ('has the fix ever broken') instead
of hypothetical.
- Commitment test requires observables on the call: named engineer, named
staging environment, scheduled date — scoring table records each.
- Decision rule defines qualified_n, adds an unknown outcome, and defaults
every unlisted pattern to more interviews, not a decision.
Tests: 53 passed (interop, wedge-honesty, site contracts). Ruff clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FsXYfTHDLiFNQ24R5JPN7H
…nsistency - verify_acta_receipt refuses an envelope whose issuer_id or signature kid is missing or empty, closing the None == None bypass where a valid signature could verify with no declared signer; regression test signs a body with neither field and asserts refusal. - Commitment test uses one scheduling condition everywhere: date scheduled or a concrete scheduling step taken on the call, in the prompt, the scoring table, and the decision rule. - Commitment gate explicitly marked pre-qualification, pointing at the stricter Pilot Acceptance Test in 30-day-customer-validation.md (partner-owned agent, partner-owned staging MCP tool, partner engineer, independent partner-side receipt verification). - Paid-pilot selection is deterministic: earliest scheduled staging date, tie-break on buyer-evidence completeness, then interview order; 'the strongest one' removed. - §2 opens with a neutral 'what, if anything, did you change' so a no-mitigation answer records as none instead of being presupposed away. Tests: 11 interop tests passed. Ruff clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FsXYfTHDLiFNQ24R5JPN7H
…test - verify_portable_bundle refuses a bundle declaring a non-Ed25519 alg instead of silently verifying with Ed25519 and reporting a result the bundle's own metadata contradicts; negative test included. - The signer-identity regression test is parametrized across absent and empty issuer_id and kid independently, so both validation branches stay covered. Tests: 16 interop tests passed. Ruff clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FsXYfTHDLiFNQ24R5JPN7H
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FsXYfTHDLiFNQ24R5JPN7H
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FsXYfTHDLiFNQ24R5JPN7H
… tests Clears the one remaining non-blocking review warning (docstring coverage below threshold). No behavior changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FsXYfTHDLiFNQ24R5JPN7H
Updates the requirements on [alembic](https://github.com/sqlalchemy/alembic) to permit the latest version. - [Release notes](https://github.com/sqlalchemy/alembic/releases) - [Changelog](https://github.com/sqlalchemy/alembic/blob/main/CHANGES) - [Commits](https://github.com/sqlalchemy/alembic/commits) --- updated-dependencies: - dependency-name: alembic dependency-version: 1.19.1 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>
Updates the requirements on [stripe](https://github.com/stripe/stripe-python) to permit the latest version. - [Release notes](https://github.com/stripe/stripe-python/releases) - [Changelog](https://github.com/stripe/stripe-python/blob/master/CHANGELOG.md) - [Commits](stripe/stripe-python@v15.4.0...v15.5.0) --- updated-dependencies: - dependency-name: stripe dependency-version: 15.5.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>
float() raises OverflowError — not ValueError — for an int too large to represent, so a registry row carrying one made tools.json generation raise instead of falling back. Catch it alongside the existing guards and cover every invalid-price branch: NaN, ±inf, unparseable text, non-numeric types, and oversized ints, in both the exact and non-exact fields. A legitimately zero-priced tool is still advertised as non-economic. Closes the follow-up left open on #277. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y1seEp4Pa4DtY1HMuJS3AX
…isional #285 and #288 added verified, primary-source research to the repository and changed no file in docs/ip/. The package was therefore ranking mechanisms against an art landscape the project had already superseded. This corrects that, and assembles a filing-ordered specification. ## The prior art the package was missing `draft-farley-acta-signed-receipts` is the sharpest of it: Ed25519 over JCS-canonicalized JSON, namespaced receipt types, and from -02 a `spending_authority` type — reaching mechanisms 1, 3 and 4 at once. It was nowhere in docs/ip, including the IDS list. Also absent: protect-mcp (recorded as the closest competitor, emitting receipts verifiable without calling the issuer), jamjet (signed chained receipts plus budget enforcement), latch (idempotency plus budget caps), TraceAgent, and microsoft/agent-governance-toolkit. Separately, 02- ranked the guarded conditional UPDATE first without naming the textbook technique it instantiates. Optimistic concurrency control (Kung & Robinson, ACM TODS 6(2), June 1981, pp. 213-226) is now stated outright, along with the fact that this repository uses the same technique a second time in audit_chain.py — which an examiner may find. The distinction that survives is narrow and is stated narrowly: a domain-cap predicate rather than a version equality test, a zero-row outcome classified into an actionable reason, and no retry loop. ## The ranking changed as a result The settlement mechanisms held; the evidence mechanisms weakened, because the evidence half of this category filled in during 2026 while the package was being drafted. Offline verification drops from second to fourth: what survives is the six-state taxonomy specifically — a key the verifier does not hold resolving to UNKNOWN_KEY rather than to a tampering verdict — not "offline verification," which is now table stakes. Set A and Set C carry matching drafting notes. ## The SDK-release questions got narrower One comfortable assumption did not survive: no workflow or script in this repository downloads its own release assets, so the mechanical explanation that would have made the four download counts self-evidently benign is not present in the tree. The count is unexplained rather than explained. Recorded from the authenticated API instead: the release and both assets were produced by github-actions[bot]; updated_at equals published_at, so the release has not been edited since 2026-08-07; and both asset SHA-256 digests, which are what lets anyone later establish what was in the artifact on that date. Repository visibility could NOT be determined from this environment — an unauthenticated probe traverses a proxy, and a private repo returns 404 regardless, so neither code is evidence. That is now stated rather than assumed. ## New: 07-provisional-specification.md 03- and 05- assembled into one continuous 112(a) written description in filing order. Code citations are wrapped in [[brackets]] so counsel can find and strip them; [not implemented] markers are retained deliberately. Abstract is 146 words against the 150-word cap of 37 CFR 1.72(b). ## Validation - 40 file:line citations across docs/ip verified against the tree - 0 broken internal links - scripts/check_doc_references.py: 249 refs across 242 files resolve - ruff clean; pytest 1666 passed, 19 skipped - Kung & Robinson citation verified against dblp and the ACM DOI rather than asserted from memory Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NVvJpNRU9wp3WXowfeqtPU
aiosqlite.Connection composes its worker Thread without daemon=True, and CPython joins non-daemon threads during shutdown. A durable-state SQLite connection nobody closes therefore wedges the process at exit with no traceback and no output. close() is the real cleanup path, but only two callers reach it -- the FastAPI lifespan and the test teardown -- so any script, REPL, or worker entrypoint that opens the backend hangs on exit. This is the failure mode that cancelled CI at GitHub's six-hour limit. That was fixed test-side only, leaving the class live for every other consumer. Making the SQLite backend correctly reachable then made it reachable in earnest. Registers a process-wide backstop that stops tracked connections nobody closed. Two details are load-bearing: - It uses threading._register_atexit, NOT atexit. Plain atexit handlers run *after* the non-daemon join, so the obvious implementation can never break this hang -- confirmed by observing the ordering directly. The stdlib's own concurrent.futures.thread uses the same hook. - It calls Connection.stop rather than close. stop is synchronous and tolerates a missing event loop by design, so no loop must survive until shutdown. Unlike daemonizing the thread, it closes in order and cannot truncate a write to a durable store. A single module-level hook over a registry, rather than a hook per connection, because _register_atexit has no unregister counterpart. Forked children are guarded by owner pid so a child never closes a connection its parent owns. Scope is SQLite only: neither the asyncpg pool nor the redis client spawns a non-daemon thread. Verified as an A/B/A on the acceptance gate -- a subprocess that opens the backend and exits without closing it. With the backstop the process exits 0; without it the same test returns 124. A backstop never seen failing is not known to work. Closes #287 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0195WsXzT9kFxfxkrWQm4zhR
The harness instruments twelve commit boundaries; six scenarios reached five of them, and PROOF_MATRIX recorded the other seven as a known gap. This closes it with a table-driven boundary suite that kills a worker at each remaining point and pins the disposition it must leave, taking `prove-crash-recovery` from six scenarios to thirteen. Every expectation was checked against the implementing code before being asserted, which is what turned two of them from "observed behaviour" into documentation fixes: - An effect-free local crash is *not* released for retry. `failure-semantics.md` window E said the record is deleted so the key can retry, but `reconcile_stuck_records` scopes that to `operation_kind == "upstream_mcp"` -- a local tool's side-effect ordering is not observable to the reconciler, so the key is held in progress and cannot be reused without an operator. - A reservation stranded before any charge stays stranded. `reconcile_budgets` only reclaims from permits that can no longer admit a charge, because a long-running call is indistinguishable from a dead one and an early reset could let a concurrent request overspend past max_credits. Recorded as a new window F. Both are correct fail-closed choices that were simply never written down, which is the same class of prose-outruns-code defect the doc-reference gate was added for and cannot catch. The new rows assert each record's own durable state rather than the sweep's counters, which are cumulative across the shared database. Three of them leave a needs-review record, so the narrative scenarios that assert exact counters must keep running first; that dependency is now called out in a comment where a future reader will hit it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qz8gaM1yVHVf2j2m6f1Vtx
… open The authenticated API reports private: true as of 2026-08-17. That settles the present state and only the present state — the API exposes current visibility, not history, and the interval since 2026-08-07 is the part that bears on whether the SDK sdist was ever publicly available. Stated that way rather than as a clean answer, and the counsel question updated to say what the API can and cannot close. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NVvJpNRU9wp3WXowfeqtPU
Checks run in throwaway git worktrees under .claude/worktrees/. Those are full repo copies — including .env.production and coverage artifacts — and must never be committed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FsXYfTHDLiFNQ24R5JPN7H
Review caught that the two pre-existing scenarios asserted the sweep's `idempotency_repaired` / `idempotency_needs_review` counters, which are cumulative over every record the shared database still holds. `stress_harness` is module-scoped and this module deliberately does not truncate between tests, so those assertions silently depended on the order the module ran in -- and this branch made that worse by adding three more scenarios that leave a needs-review record. I had documented the hazard in a comment instead of removing it. That was the weaker choice: both assertions are now made against the seeded call's own record, which is what each scenario is actually claiming. Verified rather than assumed, with pytest-randomly installed locally and then removed so the environment still matches CI: - pre-fix code, shuffled with seed 1: both scenarios FAIL, on exactly the two counter assertions - fixed code, shuffled with seeds 1 and 7: 13 passed - fixed code, definition order: 13 passed; full suite 1666 passed Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qz8gaM1yVHVf2j2m6f1Vtx
…1' into claude/merge-pull-requests-plan-emtaye
…' into claude/merge-pull-requests-plan-emtaye # Conflicts: # requirements.txt
…-1ceo8u' into claude/merge-pull-requests-plan-emtaye
…x9f' into claude/merge-pull-requests-plan-emtaye
…stop' into claude/merge-pull-requests-plan-emtaye
…dc6h' into claude/merge-pull-requests-plan-emtaye
…points' into claude/merge-pull-requests-plan-emtaye
…esearch-qr05ry' into claude/merge-pull-requests-plan-emtaye
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_5c0da835-73f6-471c-97d1-e147a97a0ee0) |
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
|
CI is red here, and it is the repo-wide Actions failure described in the PR body — not this branch. All 14 jobs in run No fix to push from here. The local results in the PR body — 1319 unit tests, 376 proof tests, 13/13 crash-recovery scenarios on real PostgreSQL 16, Generated by Claude Code |
…uests-plan-emtaye
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_262de4b5-2744-49f4-ac2d-9b949a75fbf8) |
…uests-plan-emtaye
…uests-plan-emtaye # Conflicts: # docs/ip/07-provisional-specification.md
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_ffbb87ad-0ec4-491d-bc31-3b8ee68dc36b) |
|
Closing — this branch has served its purpose and is now unsafe to merge. All nine PRs it was rehearsing are in
Why closing rather than merging: #297 and #299 both advanced after this branch integrated them, and the versions that landed are the newer ones. This branch is now behind The #291 stays open and should be closed unmerged. It is the one PR from the original ten that was not merged, because widening the Generated by Claude Code |
Summary
An integration branch that merges the remaining open PRs (#290, #292, #293, #294, #297, #299), plus the validation evidence for merging them. This is a pre-flight rehearsal, not a replacement for the individual PRs — see Recommended merge order below.
#291 is deliberately excluded: it is a breaking change. See Blocker below.
Blocker: #291 (
mcp<2→<3) breaks the appThe
<2bound is load-bearing, exactly as its own inline comment says. Withmcp==2.0.0installed,app/main.pyfails to import:mcp 2.x renamed
McpError→MCPError. The symbol is imported inapp/routers/mcp_public.py:40andapp/routers/mcp_standard.py:68. Recommendation: close #291 (or convert it to a port that renames the import and re-checksmcp.server.lowlevel,mcp.server.streamable_http,RequestBodyLimitMiddleware, andmcp.server.fastmcpagainst the 2.x API). The PR carries an approval; the approval predates this evidence.Recommended merge order
Six PRs remain, no cross-conflicts except one adjacent-line collision in
requirements.txt:mcp_generatorOverflowError), fix(state): release the aiosqlite worker thread at interpreter shutdown #299 (aiosqlite shutdown backstop) — disjoint code paths, no shared files. Both marked ready.#296merged 04:45Z.#300merged 05:01Z.#298merged ~05:5xZ.#294's
CHANGES_REQUESTEDis CodeRabbit; its last review's one actionable item (parametrizetest_missing_signer_identity_is_refused) is already implemented at head0932b18.Type of Change
requirements.txtconflict resolution and takingmain's side ofdocs/ip/07-provisional-specification.mdafter fix(permits): enforce expiry in the guarded reservation update; fold the 2026-08 research into docs/ip #298 landed)Validation
CI: 14/14 green on heads
b4e57d5and3a7e15b.Run locally on the merged tree, re-verified after each
mainsync:pytest -q -m "not proof"— 1321 passed, 31 skippedpytest -q -m proof— 376 passed, 1 skippedmake prove-crash-recoveryagainst a clean local PostgreSQL 16 — 13 passed (re-run after fix(permits): enforce expiry in the guarded reservation update; fold the 2026-08 research into docs/ip #298's permits change)make trust-release-gate— passed (discovery drift, OpenAPI parity, simulation inventory parity)ruff check .— cleanmypy app/— no issues in 172 source filespython scripts/check_doc_references.py— 259 references across 242 files resolvesecret_scan(gitleaks) — green on CIinvariant_attack_proof— green on CISECURITY_LIMITATIONS.mdRisk
Notes:
mainin a single squash and orphan the individual review threads. Its value is the evidence. Merge the PRs individually in the order given; if you'd rather land one merge, this branch is ready.requirements.txtresolution keeps all three bumps:greenlet>=3.5.5,stripe>=15.5.0,alembic>=1.19.1, withmcpleft at<2.