build(deps): update uvicorn[standard] requirement from >=0.40.0 to >=0.46.0 in /apps/api#4
Merged
Conversation
Updates the requirements on [uvicorn[standard]](https://github.com/Kludex/uvicorn) to permit the latest version. - [Release notes](https://github.com/Kludex/uvicorn/releases) - [Changelog](https://github.com/Kludex/uvicorn/blob/main/docs/release-notes.md) - [Commits](Kludex/uvicorn@0.40.0...0.46.0) --- updated-dependencies: - dependency-name: uvicorn[standard] dependency-version: 0.46.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>
xmap
added a commit
that referenced
this pull request
May 16, 2026
Lands the 4 in-scope items flagged by the Phase 11a gate review (3-agent parallel: architecture / test coverage / cross-BC consistency). Nit #3 (`test_hazard_classification.py`) was a false positive — the file already exists with full coverage of bool-trap + 4 Invalid* errors + boundary values. ## Doc drift (#4) `state.py:13,38` claimed "12-value ClearanceKind" — the enum has 10 values (post-11a-a refactor split form-type from facility identity via the orthogonal `facility_asset_id` field). Comment now reflects the locked 10 + cites the refactor history. ## 5 missing projection apply() arms (#2) `test_clearance_summary_projection.py` had direct `apply()` assertions for ClearanceRegistered / ClearanceApproved / ClearanceRejected + the ClearanceReviewStepAppended no-op (4 of 9 event types). The 5 missing arms (Submitted / ReviewStarted / Activated / Expired / Superseded) were only covered transitively through `test_list_clearances_handler_postgres.py`. New direct tests pin each event's status update + last_status_changed_at + event-specific columns (Expired carries `reason`; Superseded deliberately drops `by_clearance_id` per deferred column). Notable: the Superseded test asserts `by_clearance_id` does NOT land in the SQL args — pins the deferred-projection-column intent so an accidental SQL change surfacing it would fail loudly. ## End-to-end Run.start gate integration test (#1) `test_postgres_clearance_lookup.py` pins the adapter in isolation; `test_start_run_clearance_gate_decider.py` pins the decider in isolation; until this commit, NOTHING exercised the COMPOSITION of real PG event store + real `PostgresClearanceLookup` + Run.start handler chain. The 11a gate review's #1 coverage gap. New `test_start_run_clearance_gate_postgres.py` seeds the full upstream chain (Capability + Asset + Method + Practice + Plan + Subject + mount), overrides `build_postgres_deps`'s default `AlwaysCoveredClearanceLookup` with the real `PostgresClearanceLookup(db_pool)`, and pins three scenarios: 1. Active Clearance bound to Subject -> Run.start succeeds 2. NO Clearance references the scope -> RunRequiresActiveClearanceError 3. Defined-only Clearance -> RunClearanceCoverageMismatchError Uses `SubjectBinding` (not `RunBinding`) to decouple from FixedIdGenerator ordering -- subject_id is operator-supplied. ## Amend idempotency contract test (#5) `register_clearance` had `test_register_clearance_idempotency.py`; `amend_clearance` (also create-style 201-returning + idempotency- wrapped at wire.py) had no equivalent. New `test_amend_clearance_idempotency.py` pins three flows mirroring the register tests: 1. No key + same body -> two calls; second hits the parent's post-Superseded gate and returns 409 (documents why the key matters for amend specifically) 2. Same key + same body -> 201 with the SAME child clearance_id (cached response; handler not re-executed; parent not transitioned twice) 3. Same key + different body -> 422 idempotency conflict ## Verification - pyright 0/0/0 - ruff clean (lint + format) - 5423 unit+contract+architecture tests pass (8 new: 5 projection + 3 amend idempotency) - 275 PG integration tests pass (3 new gate end-to-end) - All pre-commit hooks pass (ruff, pyright, tach, architecture fitness, secrets scan) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
xmap
added a commit
that referenced
this pull request
May 18, 2026
…rrorPort + gen_ai telemetry (Phase 8f-b iter 2a)
Ships the infrastructure plumbing 8f-b iter 2b's RunDebrief
subscriber will consume: a provider-neutral LLMPort with value-
type bundle (CacheBreakpoint, LLMContentBlock, LLMSystemPrompt,
ModelRef, LLMUsage, LLMResponse, LLMChatRequest) and a six-class
LLMError taxonomy; a production AnthropicLLMAdapter implementing
the port; an abstract LogbookMirrorPort with no implementor; a
gen_ai OTel telemetry helper with per-call token + cost histograms;
Kernel wiring for both ports; an Anthropic SDK dependency.
NO subscriber, NO Agent seed, NO actual LLM behavior at iter 2a --
those land at iter 2b with the security-specialist gate review.
## Port surface (cora.infrastructure.ports.llm)
LLMPort.chat(request: LLMChatRequest) -> LLMResponse with:
- System prompt as layered LLMContentBlock tuple; each block can
carry an optional CacheBreakpoint (ttl: "5m" | "1h") to mark a
cached prefix boundary.
- User message as a single LLMContentBlock (also breakpoint-able).
- Structured output as a JSON Schema dict (the adapter forces
tool-use-as-structured-output convention).
- ModelRef VO (provider + model + snapshot_pin) carrying the
Agent.model_ref shape; deliberately duplicated (not hoisted) from
the agent aggregate's validated VO since one carries domain
invariants and the other is a wire shape. Hoist deferred to
rule-of-three trigger (second LLM-consuming agent at 8f-c+).
- LLMUsage (input/output/cache_creation/cache_read tokens; None
coerced to 0 at the adapter boundary).
- LLMResponse (parsed + raw_text + usage + stop_reason + model_id).
Six error subclasses (LLMRateLimitError, LLMServerError,
LLMTimeoutError, LLMAuthenticationError, LLMInvalidRequestError,
LLMSchemaValidationError) all inherit from LLMError so iter 2b's
retry layer can isinstance-classify on the base.
FakeLLMAdapter test stub with a response queue + LLMError pass-
through + received-request capture; mirrors the
AlwaysCoveredClearanceLookup / AlwaysQuietCautionLookup test-default
convention.
## Production adapter (cora.agent.adapters.anthropic_llm_adapter)
AnthropicLLMAdapter wraps anthropic.AsyncAnthropic with:
- max_retries=2, request_timeout=600s (design memo lock).
- 4-cache-breakpoint client-side validation (fail-fast before API
call instead of opaque 400; raises LLMInvalidRequestError).
- 1h-TTL beta header (extended-cache-ttl-2025-04-11) set
conditionally when any block requests "1h".
- Tool-use-as-structured-output via stable synthetic tool name
cora_structured_output (cache-correctness invariant pinned by
test_synthetic_tool_name_stable_across_calls).
- Full Anthropic SDK error -> LLMError translation including the
defensive APIStatusError default arm (pinned by
test_unknown_apistatuserror_subclass_translates_to_server_error).
- ModelRef snapshot_pin appended as "<model>-<pin>" suffix when
set.
Owns the adapter per cross-BC convention (Safety BC owns
PostgresClearanceLookup; Caution BC owns PostgresCautionLookup;
Agent BC owns AnthropicLLMAdapter). Tach validated.
## LogbookMirrorPort (cora.infrastructure.ports.logbook_mirror)
Abstract Protocol with no production implementor at 8f-b. Reserves
the Kernel slot (Kernel.logbook_mirror: LogbookMirrorPort | None)
so iter 2b's subscriber can short-circuit cleanly on `is None`
and a future PhoebusOlogAdapter / SciLogAdapter / SciCatAdapter
slots in without subscriber churn. mirror_decision is
fire-and-forget (returns None) so logbook outages never propagate
to the Decision-emission path.
## gen_ai telemetry helper (cora.infrastructure.observability.gen_ai)
record_llm_call(span, ...) sets OTel GenAI semantic-convention
span attributes (gen_ai.system, gen_ai.request.model,
gen_ai.response.model, gen_ai.usage.{input,output,
cache_creation,cache_read}_tokens, gen_ai.response.finish_reasons)
and records two histograms (gen_ai.client.token.usage per OTel
spec + cora.agent.llm.cost.usd custom).
PRICING dict keyed on (provider, model) carrying per-MTok rates
for opus/sonnet/haiku 4-x (1h-TTL cache write tier). Unknown
models cost $0.00 with a one-time-per-process warning. compute_
cost_usd returns dollar value the adapter intentionally discards
(histogram is the persistent record; return value is for tests).
Helpers NOT re-exported from observability/__init__.py: the only
consumer (AnthropicLLMAdapter) imports from the submodule directly.
Re-export trigger is "second LLM adapter ships" (cross-BC review
P1).
## Settings + secret handling
Settings.anthropic_api_key: SecretStr | None = None (read from
ANTHROPIC_API_KEY env var). SecretStr redacts to `**********` in
repr(), str(), and model_dump_json() so no debug-log / json-dump
path can leak the credential. Verified by
test_anthropic_api_key_is_secret_str_and_redacted_in_repr.
The factory (cora.agent.llm_factory.build_llm) is the one and
only call site of .get_secret_value(); composition root binds
build_llm into build_kernel's llm_factory parameter.
## Composition root
LLMPortFactory Protocol in cora.infrastructure.deps:
__call__(settings) -> LLMPort | None. Returns None when settings
indicate no LLM should be wired (eg. anthropic_api_key unset);
iter 2b's subscriber-registration step will fail-fast on
kernel.llm is None.
cora.api.main binds build_llm into build_kernel(llm_factory=...).
## Gate review (Stage 3, 3 baseline panel)
Architecture / test-coverage / cross-BC consistency all
APPROVE WITH NITS, 0 P0s. All P1s addressed in same commit:
- arch P1 #1 (SecretStr leak): anthropic_api_key now SecretStr
with redaction test pin.
- arch P1 #2 (ModelRef duplication): documented as intentional
separation with rule-of-three trigger to hoist.
- test-coverage P1 #1 (APIStatusError defensive default
untested): added
test_unknown_apistatuserror_subclass_translates_to_server_error.
- test-coverage P1 #2 (tool-name stability not pinned): added
test_synthetic_tool_name_stable_across_calls (cache-correctness
invariant).
- test-coverage P1 #3 (record_llm_call return discard intent):
documented at the call site.
- test-coverage P1 #4 (None cache-token coercion untested): added
test_none_cache_token_fields_coerce_to_zero.
- cross-BC P1 #1 (gen_ai re-export bloat): dropped from
observability/__init__.py.
Deferred to iter 2b (with documented triggers):
- test-coverage watch (AsyncAnthropic.aclose leak): subscriber
lifecycle is iter 2b scope.
- cross-BC nit (LLMPort/LogbookMirrorPort suffix vs prior no-
suffix ports): cross-cutting naming review; not iter 2a scope.
- cross-BC nit (AlwaysSilentLLM stub for Kernel symmetry):
Optional shape gives fail-fast at subscriber registration,
intentional; revisit if RecipeScreener at 8f-c surfaces friction.
## Tests + verification
49 new tests, all green: 22 unit (AnthropicLLMAdapter) + 12 unit
(LLMPort + FakeLLMAdapter) + 7 unit (gen_ai telemetry) + 3 unit
(LogbookMirrorPort Protocol) + 5 unit (deps Kernel composition +
build_llm + SecretStr redaction).
Full suite: 6608 unit+contract+architecture + 329 PG integration
tests pass, 107 skipped, 0 failures. pyright 0/0/0, ruff clean
(8f-b iter 2a scope), tach validated. anthropic>=0.79.0,<1 added
to dependencies (0.102.0 installed); uv.lock committed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Updates the requirements on uvicorn[standard] to permit the latest version.
Release notes
Sourced from uvicorn[standard]'s releases.
Changelog
Sourced from uvicorn[standard]'s changelog.
... (truncated)
Commits
b224045Version 0.46.0 (#2918)7375b5bUsebytearrayfor incoming WebSocket message buffer in websockets-sansio (#...d438fb1Supportws_ping_intervalandws_ping_timeoutinwsprotoimplementation ...3e6b964Supportws_max_sizeinwsprotoimplementation (#2915)2c423bdVersion 0.45.0 (#2914)7f027f8Revert "Emithttp.disconnecton server shutdown for streaming responses" (#...73a80c3Add--reset-contextvarsflag to isolate ASGI request context (#2912)45c0b56Revert empty context for ASGI runs (#2911)850d926Raise helpfulImportErrorwhen PyYAML is missing for YAML log config (#2906)fdcacb4Acceptlog_levelstrings case-insensitively (#2907)Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting
@dependabot rebase.Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
@dependabot rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot show <dependency name> ignore conditionswill show all of the ignore conditions of the specified dependency@dependabot ignore this major versionwill close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this minor versionwill close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this dependencywill close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)