feat(warpline): advisory preflight consumer + forge-proof per-SEI attestation read#17
Conversation
…station read Design for warpline request item 5: (a) advisory warpline preflight read (warpline_preflight_get, sibling to the governance honesty reads, HTTP client mirroring HttpFiligreeClient) and (b) per-SEI attestation_get returning human-cleared attestation facts (not a proven-good verdict). Boundary: governance verdicts byte-identical when warpline is absent. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8-task plan for the advisory preflight consumer + per-SEI attestation read. Grounded + adversarially reviewed; Tasks 1-7 ready, Task 8 (classifier) BLOCKED pending owner ratification of the forge-proof discriminator. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implements HttpWarplineClient (GET-only, injectable fetch, no new deps) as a faithful security-primitive clone of filigree/client.py; clone-parity guard test locks the SSRF/redirect/DoS helpers in lockstep. Routes are inferred (TO-CONFIRM per spec §6). 10 new tests, 1204 pass total. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Transport-agnostic preflight read returning checked/unavailable; WarplineError is always caught and converted, never escapes; asymmetric honesty ensures None client or any method failure degrades the whole read to unavailable. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add McpRuntime.warpline field, build_runtime env-gating (WARPLINE_API_URL, try/except degrade to None), handler _tool_warpline_preflight_get, tool definition with _one_of discriminated schema, and three-registry sync (warpline_preflight_get added to _AGENT_TOOLS, _TOOL_HANDLERS, tool_definitions). TDD: dispatch/env/degrade tests written first (red), then implementation (green). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two tests prove the governance invariant: 1. Verdicts from policy_evaluate (VIOLATION + UNKNOWN) are byte-identical whether runtime.warpline is None or a hostile client returning garbage advisory data — warpline presence cannot perturb a verdict. 2. Structural scan confirms runtime.warpline is referenced in no verdict-path function source (defense-in-depth complement). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…OCKED) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add warpline_preflight_get and attestation_get to the surface-set literal in test_initialize_and_tools_list_exposes_full_agent_surface (22→24 names), clearing the long-RED test introduced by Tasks 3 and 5. Add test_warpline_tools_introduce_no_new_error_codes to lock that both tools degrade to a success-envelope (status:"unavailable"), confirming no new error code requires _recovery_for / pinned-code list changes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n tools Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… guard Adds _tool_attestation_get and read_sei_attestations to the warpline advisory-boundary structural test, and strengthens it by deriving tool-handler coverage from _TOOL_HANDLERS so future handlers are covered automatically. The single legitimate warpline reader (_tool_warpline_preflight_get) is excluded by name; any other handler that starts touching .warpline will cause an immediate test failure. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… BLOCKED (no false-green) read_sei_attestations previously returned status='checked' with an empty attestations list even when the positive-admission classifier (Task 8) had not run. In a key-wired deployment this passes the pre-gate in _tool_attestation_get and reaches read_sei_attestations, producing a false-green: 'checked: []' asserts "I checked this SEI and found no attestation" when no check actually ran. The honesty surface forbids this verbatim (asymmetric rule: unavailable is safe, false-checked is a security hole letting warpline skip reverify). Fix: return status='unavailable' with reason "attestation classifier pending owner ratification (Task 8)" until Task 8 ratifies the discriminator. Tests: renamed unit test to assert the unavailable-pending shape; added test_attestation_get_wired_deployment_returns_unavailable_not_false_checked to cover the previously-untested key-wired path that was the buggy false-green. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…002, PDR-0003 Checkpoint of the warpline-interfaces build session. Records the accept of the advisory preflight consumer + attestation fail-closed scaffolding, the federation-read doctrine (facts-not-verdict), and the Task-8/merge/spec-correction owner escalations. Workspace committed on branch warpline-interfaces; lands on main when the branch merges. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ratified) + spec §4 correction Implement read_sei_attestations: admit operator_override and signoff_cleared attestations from the VERIFIED governance trail, keying only off SIGNED fields. - operator_override: gated on the judge_metadata_signature MARKER (proves the record was in the verified selection), signed judge_verdict == OVERRIDDEN_BY_OPERATOR (FORGE-A closed), signed protected_cell, signed inline loomweave.content_hash (non-empty), and the signed entity_key dict == sei + identity_stable. - signoff_cleared: gated on the signoff_signature MARKER, SIGNED_OFF state, and the FORGE-B integrity join — recompute content_hash over the full stored PENDING payload and require it == the signed request_payload_hash; surface the PENDING's loomweave.content_hash (non-empty). seq = SIGNED_OFF, signoff_seq = request_seq. The function now always returns status='checked' (the handler pre-gate owns the unavailable case). Added forge-negative tests (FORGE-A/B, chill stuffing, unsigned procedural sign-off, cross-SEI, identity_stable False, empty content_hash, BLOCKED) + positive end-to-end MCP test. Spec §4.1/§4.2/§7 corrected: the unconditional "forged attested never returned" claim is false (verifiable only when both gate+verifier wired); fixed lowercase 'signed_off' -> 'SIGNED_OFF'; replaced the "pinned during implementation" hand-wave with the ratified discriminator. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…Task 8 forge-negative) The asymmetric twin of the no-marker stuffing case: a self-clear stuffing operator-override extensions WITH a garbage judge_metadata_signature marker. The classifier trusts marker presence by design, so the defense is the pre-gate — TrailVerifier selects the marker-bearing record and raises TamperError before the classifier runs (same principle as FORGE-A). Closes the task-enumerated "with and without a non-verifying signature" coverage requirement. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…; PDR-0004 Warpline interfaces now complete (Tasks 1-8). Records the owner ratification + forge-proof classifier implementation (both kinds, 0 forges admitted), the spec §4 correction, and the held-on-merge state. Workspace on warpline-interfaces; lands on main when the branch merges. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fb33a9e062
ℹ️ 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".
| parsed = urllib.parse.urlparse(base_url) | ||
| if parsed.scheme not in {"http", "https"} or not parsed.hostname: |
There was a problem hiding this comment.
Wrap URL parser failures as WarplineError
When WARPLINE_API_URL is malformed as an invalid IPv6 URL such as http://[, urllib.parse.urlparse()/.hostname raises ValueError before this function can raise WarplineError. build_runtime() only catches WarplineError around HttpWarplineClient(...), so an advisory-only Warpline misconfiguration can still abort MCP startup instead of degrading to runtime.warpline = None as intended.
Useful? React with 👍 / 👎.
Warpline federation interfaces release: advisory preflight consumer (warpline_preflight_get) and forge-proof per-SEI attestation read (attestation_get). Agent MCP surface 22 -> 24 tools. Bump version (pyproject + __init__ + lockfile) and add the 1.2.0 CHANGELOG entry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Implements Warpline interfaces (filigree
legis-1734128d34): an advisory preflight consumer plus a forge-proof per-SEI attestation read on the agent MCP surface.HttpWarplineClient+read_warpline_preflightdiscriminated service read, surfaced as thewarpline_preflight_getadvisory sibling MCP tool. Advisory-only: a byte-identical acceptance spine guards the advisory boundary so a preflight result can never be mistaken for an enforcement verdict.attestation_getships fail-closed (returnsunavailable/BLOCKED, never a false-green) and is then backed by a forge-proof per-SEI attestation classifier (Task 8, PDR-0004): chill-stuffing with a non-verifying signature is rejected, with forge-negative coverage and a spec §4 correction.outputSchemaconformance vectors covering the warpline + attestation tools.Branch / worktree status
main, 0 behind (based directly onmain's HEAD).rc4andrc5are already fully contained inmain(verified--is-ancestor), so they are transitively already in this branch — nothing to merge.origin/dependabot/uv/starlette-1.3.1is an independent automated dependency bump and is intentionally not folded into this feature PR.Test plan
uv run pytest→ 1237 passed, 5 skipped.🤖 Generated with Claude Code