feat(transport): multi-host Transport seam + /verify evidence endpoint#1
Open
imonacloud wants to merge 5 commits into
Open
feat(transport): multi-host Transport seam + /verify evidence endpoint#1imonacloud wants to merge 5 commits into
imonacloud wants to merge 5 commits into
Conversation
Spec (chp-v0.1.md): - §5: add payload validation SHOULD/MUST + duplicate registration semantics - §6: strengthen append-only from SHOULD to MUST - §9: enumerate standard denial codes table - §10: add replay query bounds recommendation (cap: 10,000) - §13: add conformance tagging requirement Implementation (host.py): - Input schema validation against input_schema before handler runs (denial code: input_schema_validation_failed) - Replay query capped at MAX_REPLAY_LIMIT=10_000 to prevent memory exhaustion - Thread-safe capability registry via RLock on _capabilities dict - Duplicate registration emits warnings.warn instead of silent overwrite - Full traceback in execution_failed evidence (removed limit=3) Onboarding: - Add AGENTS.md — machine-first orientation for AI agents (invariants, commands, navigation, pitfalls); follows AGENTS.md open spec - Add docs/llms.txt — ultra-compact protocol reference for LLM context windows - Redirect three legacy docs (onboarding, agent-prompt, capability-lookup-prompt) from Zenoh-era content to current entry points Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…flag, remote resilience, test coverage
Pillar 1 — Input validation at public API boundaries
- Empty capability_id now denies with capability_not_found before _resolve()
- Unknown mode strings caught early in ainvoke() with unsupported_mode denial
- jsonschema ValidationError split from generic Exception; denial now includes path of failing field in details
Pillar 2 — ReplayResult.truncated
- types.py: add truncated: bool = False field to ReplayResult
- host.py: replay_result() sets truncated=True when result was capped by MAX_REPLAY_LIMIT
- schemas/replay-result.schema.json: add truncated property
- spec/chp-v0.1.md §10: add MUST sentence for truncated flag
- docs/llms.txt: update ReplayResult fields line
Pillar 3 — RemoteCapabilityHost resilience
- _send() catches URLError → ConnectionError and OSError → ConnectionError
- Non-dict 200 responses raise RuntimeError("non-JSON response: ...")
- Body capped at 500 chars in error messages
Pillar 4 — Test coverage gaps
- test_local_host.py: unsupported_mode, empty_capability_id, unknown_mode_string, input_schema_error_includes_field_path; truncated and disabled-capability assertions
- test_http.py: connection refused, non-JSON 200, HTTP 500 remote tests; HTTPServerEdgeCaseTests class (404, malformed body)
- test_conformance_runner.py: new file — 4 subprocess self-tests verifying passing sample passes and broken samples fail expected checks
745 tests pass, 29/29 conformance checks pass, 42/42 alignment checks pass.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Conformance suite (26 → 29 checks):
- Added check_standard_denial_codes — uses passed-in host directly to test denial code values
- Added check_input_schema_validation — isolated host registers typed capability; bad payload denied, good succeeds
- Added check_evidence_hash_chain — verifies 64-char hex content_hash and prev_hash linkage
- Added --sample flag with 4 modes: passing, failing-no-evidence, failing-non-standard-codes, failing-no-hash-chain
- Refactored sample_failing_hosts.py: BrokenNoEvidenceHost, BrokenNonStandardCodesHost, BrokenNoHashChainHost
Schemas:
- evidence-event.schema.json: add content_hash and prev_hash optional fields with ^[a-f0-9]{64}$ pattern
- denial-reason.schema.json: add description and examples listing all 8 standard denial codes
- replay-query.schema.json: add maximum: 10000 on limit field, reference spec §10
Docs:
- README: merge duplicate quickstart, fix test command, fix alignment command, update repo map (14 entries)
- CONTRIBUTING.md: update test command to pytest, add check-alignment step (41 checks), add AGENTS.md note
- docs/roadmap.md: add 12 shipped milestones v0.3.5–v0.6.3, update Up Next to v0.7 candidates
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add a transport abstraction so clients can reach a CHP host over any
backend (HTTP first; Zenoh/gRPC pluggable later):
- chp_core/transport.py: Transport Protocol (async ainvoke_envelope,
discover, replay_result, health, supports) + LocalTransport (in-process)
and HttpTransport (stdlib HTTP via RemoteCapabilityHost, run off-loop).
- http.py: RemoteCapabilityHost.invoke_envelope() and .verify(); new
GET /verify/{correlation_id} route returning the SHA256 chain result.
- Export Transport / LocalTransport / HttpTransport from the package.
Additive; existing surface unchanged. 752 tests green.
Co-Authored-By: Claude Opus 4.8 <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.
Summary
chp_core/transport.py—TransportProtocol (async,@runtime_checkable),LocalTransport(wrapsLocalCapabilityHost), andHttpTransport(wrapsRemoteCapabilityHostviaasyncio.to_thread)GET /verify/{correlation_id}to the HTTP server, returningChainVerificationResultas JSON; adds syncRemoteCapabilityHost.invoke_envelope()andRemoteCapabilityHost.verify()client methodsTransport,LocalTransport,HttpTransportfromchp_core/__init__.pyTest plan
pytest packages/python/tests/— 752 tests greenpython conformance/runner.py— 29/29 PASSpython -c "import json,glob; ..."— 27 schemas OKLocalTransportandHttpTransportboth satisfyisinstance(x, Transport)at runtime🤖 Generated with Claude Code