feat: bind local capability evidence to tc run#116
Merged
Conversation
Implements CR-DD-013. The tc run route-input construction path no longer synthesizes local health from unobserved literals: lm_studio_ok, local_heavy_available, and local_fast_available now come from an observation or an explicit operator declaration, never from an optimistic default. Adds a validated discriminated capability-evidence union (ObservedAvailable, ObservedUnavailable, Configured, Unknown) built as a projection of the existing local_backend_probe_record.v1. Semantically impossible combinations are rejected at construction: Configured has no observed_at or evidence_tier field, and Unknown has no route-class field. Resolution precedence: a fresh observed-unavailable runtime suppresses every dependent route and cannot be overridden by a declaration; a fresh reachable runtime confirms reachability only; route-class availability requires an explicit declare_local_fast / declare_local_heavy declaration; missing, probe_disabled, stale, invalid, and insufficient-model evidence resolve to Unknown. Local-only work with unknown capability fails closed; cloud-permitted work may consider a configured remote route while evidence and operator output state that local capability was unknown. Adds a [capability] configuration section with a 300-second configurable freshness default; the applied threshold is recorded in evidence. Provenance rides the existing open route_decision payload -- no new ledger schema and no schema-version bump, and route-worker-ledger.v1 is untouched. Observation-backed and declaration-backed route classes stay in separate evidence fields so a declared class is never attributed to the probe. No probe is added and none is performed: capability comes from an already-recorded file or an injected record. Direct callers of run_task that supply no capability keep their previous behavior exactly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
✅ Deploy Preview for poetic-quokka-0fd859 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
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.
Implements CR-DD-013 by binding existing local-backend capability evidence into the
tc runroute-input path.The change:
ObservedAvailable,ObservedUnavailable,Configured, andUnknowncapability variants;[capability]declarations forlocal_fastandlocal_heavy;ResilienceRouteInputcallers and router semantics.Includes 43 focused regression tests and updates the merged CR-DD-013 document with the approved implementation decisions.
No CR-YK, provider, circuit-breaker, token-budget, reviewer-burden, TriageDesk, session, or ledger-schema work is included.
Semantic boundary
Unknowncannot carry a positive capability claim.For a fresh reachable record plus
declare_local_heavy = true, evidence reads:{ "capability_state": "observed_available", "capability_supported_route_classes": [], "capability_declared_route_classes": ["local_heavy"] }supported_route_classesstays empty because the probe record carries no class-specific evidence, so a declared class is never attributed to the probe. Pinned bytest_mixed_observation_and_declaration_keeps_provenance_separate.Behavior matrix
lm_studio_okobserved_availableobserved_unavailableconfiguredunknown(missing)probe_disabledunknown(probe_disabled)unknown(stale)unknown(invalid_record)Review focus
triage_core/capability_evidence.py.Configuredhas noobserved_atorevidence_tierfield andUnknownhas no route-class field, so impossible combinations raiseTypeErrorat construction rather than being merely unused.test_mixed_observation_and_declaration_keeps_provenance_separateintests/test_capability_binding.py.Compatibility
Binding happens at the
tc runboundary.TriageClient.run_taskaccepts an optionalcapability; when absent — every existing library caller — the previous route-input literals are preserved exactly.choose_resilience_routeis unmodified and still reads only the booleans.tc runbehavior does change for operators with neither a recorded observation nor a declaration: local-only work now fails closed instead of assuming local health. That is the point of the CR, and[capability]declarations are the supported remedy.Verification
client.py/tc_cli.pyhold 11 pre-existing findings at baseline and 11 after — none added, none fixed (out of scope)git diff --check origin/main...HEAD: cleangit diff --name-only origin/main...HEAD: exactly nine filesThe lone xfail (
tests/test_authz.py::test_concurrent_consume_race_documented) is pre-existing, strict, and unrelated.Known limitations
lm_studio_ok=TrueunderUnknown, so it is trusted rather than verified.stalecovers both expiry and non-establishable freshness (asynthetic_fixturerecord cannot carryobserved_at).🤖 Generated with Claude Code