feat(d3): evaluator core — per-type handlers + advisory-lock eval-tx (component 2 step 3)#119
Merged
Conversation
added 3 commits
June 1, 2026 13:14
…(component 2 step 3) app/enforcement/evaluator.py: async _eval_<type> handlers (max_transaction_value w/ numeric-hardening + value_source gating, allowed_domains exact-match, rate_limit COUNT over aae_evaluations, not_before/not_after w/ clock-skew, single_use, revocation_check deferred-DENY stub); Default-DENY on unknown/unevaluable required:true; evaluate_envelope orchestrator: single-bigint pg_advisory_xact_lock + load + aggregate (one DENY -> DENY) + signed eval-row insert (created_at = signed timestamp) all in one tx. 14 server-venv tests green incl. parallel-TOCTOU (advisory-lock serializes) + stored-row re-verify. Per evaluator brief v4 (#115). Code+tests only — NOT live. NB: parallel-toctou test leaves test-marked append-only rows (immutable table, per convention).
1) advisory-lock key: null-byte separator (DIDs+sha256-refs contain ':' -> colon-concat collision); 2) constraint-handler exception -> always DENY (fail-closed, was ALLOW on required=False); 3) server-timestamp written into action_context (verbatim jsonb store + signed -> robust re-verify, enforces server time over client); 4) rate_limit per-(agent_did, aae_ref) not agent-global; 5) domain case-insensitive + string-type check, constraints-is-list guard. 18 server-venv tests green (4 new: no-colon-collision, fail-closed-on-exception, per-envelope rate-limit isolation, server-overrides-timestamp).
1) nonce REQUIRED — no uuid fallback (server never mints the client replay-token); missing/empty -> fail-closed DENY (closes replay-bypass). 2) never-crash-without-audit: evaluate_envelope fully wrapped, any error -> signed DENY audit row; nonce-replay (unique_violation) -> controlled DENY. 3) empty/missing agent_did -> DENY (no shared advisory-lock). 4) ISO-8601 duration upper-bound cap (>366d -> reject, DoS). 23 server-venv tests green (5 new). STEP-4 QUEUE (endpoint /vc/aae/evaluate, defense-in-depth): nonce-missing->422 (user-facing, before core); action_context schema+size validation; format checks; size-cap. Endpoint 422 AND core-DENY both. Per evaluator brief v4 (#115).
Owner
Author
|
Step-4-Queue (endpoint-boundary, explizit dokumentiert — nicht verlieren): Am |
…nt single_use TOCTOU Lock key = sha256(aae_ref) only (not agent_did:aae_ref): serializes ALL evals of an envelope incl. cross-agent, closing the single_use bypass where two agent_dids present the same envelope concurrently. rate_limit stays per-agent (count query still filters agent_did). 25 server-venv tests green (2 new: cross-agent-single_use-serialized, rate_limit-per-agent-isolated-under-envelope-lock).
This was referenced Jun 1, 2026
MoltyCel
added a commit
that referenced
this pull request
Jun 2, 2026
Boundary validation (defense-in-depth to fail-closed core): aae_ref format, action_context schema+8KB size-cap, nonce-missing->422, numeric value finite-check, agent_did==auth-principal (403 else), vc_id<->envelope direct binding (substitution-safe; delegation-chain = follow-up). Calls evaluate_envelope; returns signed verdict. verdict_signature added to _KNOWN_PUBLIC_CREDENTIAL_FIELDS (scrub-allowlist, lesson #101). Per evaluator brief v4 (#115) + core #119. Co-authored-by: Lars Kroehl <kersten.kroehl@cryptokri.ch>
MoltyCel
added a commit
that referenced
this pull request
Jul 11, 2026
…moltrust-web (#238) Load the positive English voice profile (my-voice-en.md) into the drafter system prompt next to anti-KI-Sprech.md, register-matched via its sarcasm scale. Repoint DOC_ANTI_KI at the moltrust-web shallow clone so the worker reads the canonical anti-KI-Sprech.md (with the new 2026-07-11 §3 tells) instead of the stale ~/moltstack/docs copy. Retire that copy to a pointer stub — one canonical source (moltrust-web) so the two cannot diverge again. Depends on moltrust-web PR #119 (adds anti-KI-Sprech.md + my-voice-en.md at repo root on main); merge #119 BEFORE deploying this branch, else the .webdocs main clone lacks the files and the drafter loads the [missing] marker.
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.
Evaluator (Komponente 2) Code-Schritt 3 — der ALLOW/DENY-Kern. Verweist Evaluator-Brief v4 (#115).
app/enforcement/evaluator.pymax_transaction_value: numeric-hardening (integer-minor-units, >=0, finite, upper-bound, float/str/bool→reject) + currency-match + value_source-Gating (self_asserted + required → Default-DENY)allowed_domains: exakter Match (kein substring-bypass)rate_limit: COUNT über aae_evaluations (NICHT IPR) im ISO-8601-Fenster via created_atnot_before/not_after: server-timestamp vs window + D1-clock-skewsingle_use: aae_ref schon in einem ALLOW-eval? (gleiche Lock-tx)revocation_check: DEFERRED-Stub → bei Präsenz fail-closed DENY (SSRF-proxy-Subkomponente)evaluate_envelope: single-bigintpg_advisory_xact_lock(('x'||substr(sha256_hex,1,16))::bit(64)::bigint)+ load + alle Constraints + VALIDITY + aggregate (ein DENY → DENY) + signiertes eval-row (verdict_sign feat(d3): verdict signing — component 2 step 2 (Ed25519 over full record) #118, created_at = signierter timestamp) — alles in EINER Transaktion (TOCTOU-frei).Tests (server-venv, 14 grün)
pro Typ ALLOW+DENY; numeric-bypass (neg/str/over-bound/float/bool→reject); self_asserted-Betrag→DENY; currency-mismatch; rate_limit-window-count; single_use-collision; parallel-TOCTOU (2 Verbindungen, advisory-lock serialisiert → genau 1 ALLOW + 1 DENY); unknown required→DENY / not-required→ignore; aggregierter DENY; revocation-deferred-DENY; signiertes eval-row in-memory + aus-DB-rekonstruiert verifizierbar.
Hinweise
§3.1 + §3.2 ✅. NICHT auf Live. Der Parallel-TOCTOU-Test hinterlässt test-markierte append-only Rows (immutable Tabelle, kein DELETE — Konvention wie IPR/credit_transactions).
Nächste Schritte
POST /vc/aae/evaluate-Endpoint + vc_id-Binding · 5. violation_records-Write. Davor: Security-Code-Review (ai_review security auf evaluator.py).🤖 Generated with Claude Code