From ee6c1adc58234a17322592585ea0783d1e84cf66 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sun, 13 Sep 2026 18:01:50 +0900 Subject: [PATCH 1/6] test(docs): prove agent admission documentation drift --- .../agent_artifact_documentation_contract.rs | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 tests/agent_artifact_documentation_contract.rs diff --git a/tests/agent_artifact_documentation_contract.rs b/tests/agent_artifact_documentation_contract.rs new file mode 100644 index 00000000..a36537ec --- /dev/null +++ b/tests/agent_artifact_documentation_contract.rs @@ -0,0 +1,45 @@ +use std::fs; + +fn read_repo_file(path: &str) -> String { + fs::read_to_string(path).unwrap_or_else(|error| panic!("failed to read {path}: {error}")) +} + +#[test] +fn agent_artifact_admission_stays_in_code_current_operator_and_architecture_docs() { + let architecture = read_repo_file("docs/architecture.md"); + assert!( + architecture.contains("Agent Artifact Admission"), + "architecture must name the Wardnet-owned Agent Artifact Admission bounded context" + ); + assert!( + architecture.contains("crates/agent-artifact-admission"), + "architecture must identify the shipped Agent Artifact Admission crate" + ); + for foreign_owner in [ + "quarantine-sandbox-runtime", + "EgressWeave", + "contextual-orchestrator", + "appguardrail", + ] { + assert!( + architecture.contains(foreign_owner), + "architecture must preserve the external-owner boundary for {foreign_owner}" + ); + } + + let claude = read_repo_file("CLAUDE.md"); + assert!( + claude.contains("crates/agent-artifact-admission"), + "operator/developer guidance must include the shipped Agent Artifact Admission workspace member" + ); + assert!( + !claude.contains("Root Cargo workspace with two members"), + "workspace guidance must not claim two members after Agent Artifact Admission is present" + ); + + let agents = read_repo_file("AGENTS.md"); + assert!( + agents.contains("Agent Artifact Admission"), + "canonical agent guidance must retain Wardnet's Agent Artifact Admission ownership boundary" + ); +} From 97300939870680c820f31d8fd4b9ba32ae1a67b3 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sun, 13 Sep 2026 18:05:34 +0900 Subject: [PATCH 2/6] docs(agent-admission): state canonical ownership boundary --- AGENTS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AGENTS.md b/AGENTS.md index ae81252e..8fcda392 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,7 @@ # Agent Instructions - Keep the project Rust-first for gateway, DNSBL, and high-throughput control-plane code. +- Preserve Wardnet ownership of Agent Artifact Admission, gateway/SOC control-plane policy, and security evidence. Treat `quarantine-sandbox-runtime`, `EgressWeave`, `contextual-orchestrator`, and `appguardrail` as external canonical owners whose released contracts/evidence Wardnet validates rather than reimplements. - Prefer proven security engines over fake in-house detections. Integrate OWASP CRS/Coraza, Suricata, STIX/TAXII, MISP, or OpenCTI before inventing equivalent engines. - Do not use Figma Code Connect for this project unless explicitly requested later. - Keep MVP work narrow: web management, gateway decisions, event/KPI visibility, and DNSBL publishing before broader SIEM/SOAR scope. From 99bdec0fe6ab965efaef7cab3a323d133ae39752 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sun, 13 Sep 2026 18:06:27 +0900 Subject: [PATCH 3/6] docs(agent-admission): align workspace guidance --- CLAUDE.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 742e3096..db146691 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -44,9 +44,10 @@ cargo +nightly fuzz run fuzz_score_request -- -max_total_time=60 ## Workspace Layout -Root Cargo workspace with two members (resolver 3): +Root Cargo workspace with three members (resolver 3): - `crates/waf-ids-core` — pure domain crate, no async/HTTP deps (only `serde` + `percent-encoding`): models, validation, upserts, request scoring, DNSBL zone formatting, event retention, threat-feed freshness, KPI snapshots, commercial readiness, buyer evidence manifests. +- `crates/agent-artifact-admission` — Wardnet-owned pre-execution admission boundary for immutable agent artifact/evidence facts, policy evaluation, and auditable allow/deny receipts. It validates released evidence/contracts from canonical sibling owners; it does not execute hostile workloads or reimplement sandbox, egress, orchestration, or guardrail policy engines. - Root crate `waf-ids-ai-soc` (`src/lib.rs`) — Axum management API, embedded admin console, optional JSON state persistence, upstream proxying, NDJSON event export, support bundle assembly, plus the in-crate HTTP tests. Depends on `waf-ids-core`. - `src/main.rs` — deliberately thin shim over `waf_ids_ai_soc::run_from_env` so all config/serve logic is unit-testable; covered end-to-end by `tests/binary.rs` (SIGTERM graceful shutdown). - `fuzz/` — a **separate** cargo workspace (empty `[workspace]` table in `fuzz/Cargo.toml` — do not remove) so root `cargo test --workspace` never builds fuzz targets. Seed corpora live in `fuzz/corpus//`. @@ -67,6 +68,7 @@ Read in `run_from_env` (`src/lib.rs`): `BIND_ADDR` (default `127.0.0.1:8080`), ` ## Key Conventions - Management writes require `X-Admin-Token` and are **upserts**: routes keyed by `id`, threat indicators by `indicator_type` + `value` + `source`, DNSBL entries by `address`. DNSBL response codes must be in `127.0.0.0/8`. +- Agent Artifact Admission owns Wardnet's artifact/evidence binding, admission policy decision, and Wardnet receipt. `quarantine-sandbox-runtime`, `EgressWeave`, `contextual-orchestrator`, and `appguardrail` remain external canonical owners; consume only released contracts/evidence and never copy their implementation logic into Wardnet. - State persistence uses write-to-temp-sibling + atomic rename; management API mutations roll back in memory if the state file cannot be replaced. - Audit logs must never leak admin tokens (`scripts/smoke.sh` asserts this). - Untrusted-input surfaces (request scorer, state deserializer, admin-token parser, DNSBL zone export) are fuzzed; if you change one, keep its libFuzzer target and proptest mirror in sync (`docs/fuzzing.md` lists the invariants per target). From 0f35f048ad594c3d8d8bba6847f87916ee2982ab Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sun, 13 Sep 2026 18:08:20 +0900 Subject: [PATCH 4/6] docs(agent-admission): make architecture code-current --- docs/architecture.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/architecture.md b/docs/architecture.md index e1ee578b..7908089f 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -8,6 +8,8 @@ flowchart LR admin --> api["Management API"] api --> app["App Crate"] app --> core["waf-ids-core"] + api --> admission["Agent Artifact Admission"] + admission --> admissionCore["crates/agent-artifact-admission"] core --> state["Runtime State"] state --> file["Optional JSON State File"] client["HTTP Client"] --> gateway["Rust Gateway"] @@ -23,6 +25,10 @@ flowchart LR api --> feeds["Threat Feed Import"] feeds --> freshness["Feed Freshness"] commercial --> bundle["Support Bundle"] + sandbox["quarantine-sandbox-runtime\nexternal released evidence"] -.-> admission + egress["EgressWeave\nexternal released evidence"] -.-> admission + orchestrator["contextual-orchestrator\nexternal released API/evidence"] -.-> admission + guardrail["appguardrail\nexternal released evidence"] -.-> admission ``` ## Components @@ -30,6 +36,7 @@ flowchart LR - `src/main.rs`: process startup and operator configuration from `BIND_ADDR`, `ADMIN_TOKEN`, `WAF_IDS_STATE_PATH`, `DNSBL_ORIGIN`, and `EVENT_LIMIT`. - `src/lib.rs`: Axum app, routing, management APIs, optional JSON persistence, gateway handler, upstream proxying, admin console, support bundle assembly, NDJSON event export, and in-crate HTTP tests. - `crates/waf-ids-core`: reusable domain models plus validation, upsert, scoring, DNSBL zone export, event retention, threat-feed freshness, KPI snapshot, and commercial readiness logic. +- `crates/agent-artifact-admission`: Wardnet-owned Agent Artifact Admission domain/application boundary. It binds immutable artifact identity and evidence, evaluates Wardnet admission policy, and emits auditable Wardnet allow/deny receipts; it does not execute hostile workloads or copy sibling-owner sandbox, egress, orchestration, or guardrail logic. - `/admin`: embedded web console. - `/gateway/{path}`: route selection, request scoring, monitor/block decision, optional upstream proxying. - `/dnsbl/zone`: DNSBL zone text using the configured origin, suitable for publication through an authoritative DNS server. @@ -66,6 +73,19 @@ flowchart LR - Commercial readiness is a runtime evidence model for buyer pilots, not a legal revenue recognition or compliance certification system. - The reusable core remains in-repo as a workspace crate. A git submodule is intentionally deferred until an independently versioned engine, SDK, or adapter needs a separate release lifecycle. +### Agent Artifact Admission ownership boundary + +Wardnet owns Agent Artifact Admission policy semantics, immutable artifact/evidence binding, and the admission receipt consumed by its gateway/SOC control plane. Missing or malformed mandatory evidence fails closed according to Wardnet policy; availability of a foreign owner never converts absent evidence into success. + +The following systems remain external canonical owners. Wardnet may validate their released contracts or cryptographically bound evidence, but it must not copy their implementation logic, query their private persistence directly, or bind production behavior to mutable branch/PR state: + +- `quarantine-sandbox-runtime`: hostile-workload isolation, execution profiles, resource/syscall/filesystem controls, ephemeral workspaces, cleanup/recovery, and dynamic artifact-analysis execution. +- `EgressWeave`: outbound destination, transport, and egress authorization/control semantics. +- `contextual-orchestrator`: production LLM/model/tool orchestration and its released API. Wardnet owns the security question and deterministic policy around any advisory result, not provider/model routing. +- `appguardrail`: application/agent guardrail enforcement and its released security evidence contracts. + +This boundary is intentionally contract-first: no source copy, no cross-service SQL, and no mutable sibling dependency. A sibling capability that lacks an immutable released contract remains unavailable to production Wardnet admission rather than being reimplemented locally. + ## Product Architecture Evidence - FigJam: `docs/figma/enterprise-product-architecture.md` From 67fa380cf69a62197ee12a14185d86a334a77760 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sun, 13 Sep 2026 18:09:13 +0900 Subject: [PATCH 5/6] test(docs): cover stale workspace cardinality prose --- tests/agent_artifact_documentation_contract.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/agent_artifact_documentation_contract.rs b/tests/agent_artifact_documentation_contract.rs index a36537ec..3bcb56ed 100644 --- a/tests/agent_artifact_documentation_contract.rs +++ b/tests/agent_artifact_documentation_contract.rs @@ -36,6 +36,10 @@ fn agent_artifact_admission_stays_in_code_current_operator_and_architecture_docs !claude.contains("Root Cargo workspace with two members"), "workspace guidance must not claim two members after Agent Artifact Admission is present" ); + assert!( + !claude.contains("Both workspace crates use `edition = \"2024\"`"), + "toolchain guidance must not retain the pre-admission two-crate statement" + ); let agents = read_repo_file("AGENTS.md"); assert!( From da77a2957627b9e3655c649465ef95e9f2226705 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sun, 13 Sep 2026 18:09:49 +0900 Subject: [PATCH 6/6] docs(toolchain): remove stale two-crate claim --- CLAUDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index db146691..d9be6212 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -40,7 +40,7 @@ cargo +nightly fuzz run fuzz_score_request -- -max_total_time=60 ## Toolchain -`rust-toolchain.toml` pins the `stable` channel with `llvm-tools-preview` (needed by `cargo llvm-cov`), `rustfmt`, and `clippy`. Both workspace crates use `edition = "2024"`. Fuzzing is the one exception that needs nightly. +`rust-toolchain.toml` pins the `stable` channel with `llvm-tools-preview` (needed by `cargo llvm-cov`), `rustfmt`, and `clippy`. All three root-workspace crates use `edition = "2024"`. Fuzzing is the one exception that needs nightly. ## Workspace Layout