docs(dark-factory): Autonomous Agent Coding Pattern design#32
Open
elamaran11 wants to merge 227 commits into
Open
docs(dark-factory): Autonomous Agent Coding Pattern design#32elamaran11 wants to merge 227 commits into
elamaran11 wants to merge 227 commits into
Conversation
… diagrams Design doc for the Dark Factory pattern (doc-only, no runtime code): - docs/dark-factory/README.md — full design: two flows (Agent Sandbox capability + Dark Factory pipeline), pluggable coder (Claude Code / Kiro), holdout gate, AWS frontier agents, live PR status, lifecycle, security model, industry alignment + anti-patterns (lethal trifecta, reward hacking, LLM-judge bias), phased delivery. - docs/dark-factory/diagrams/flow-a-sandbox-capability.md — capability architecture + warm-pool state machine (mermaid). - docs/dark-factory/diagrams/flow-b-dark-factory.md — end-to-end pipeline, detailed sequence, live-status mock (mermaid). Grounds every reuse in eks-platform-openclaw (Sandbox CRD, session-router, LiteLLM), appmod-blueprints (PlatformCluster), and agent-platform-amazon-eks (addon ApplicationSets). Validated against Copilot/Codex/Devin/StrongDM.
Unify all 5 mermaid diagrams on one palette + font (was clumsy: mixed light/dark backgrounds, too many colors, inconsistent fonts): - Squid Ink navy canvas (#1B2733) with layered navy bands/nodes, light text - single AWS Orange (#FF9900) accent reserved for the active/happy path - Amazon Ember font, uniform rounded nodes + stroke weights - fixed linkStyle edge indices (chained edges were mis-counted) Flow A (capability + warm-pool state machine) and Flow B (pipeline + sequence + live-status) now read as one consistent visual system.
Complete documentation covering both observability approaches: - Centralized (Langfuse + AMP/Grafana) — default, no config needed - Decentralized (CloudWatch GenAI) — one line: observability.mode=decentralized Includes: env vars table, Dockerfile, build steps, testing commands, platform infrastructure, and troubleshooting.
The agent platform implements Bifrost as the LLM proxy (bifrost.bifrost.svc:8080, Bedrock via Pod Identity), not LiteLLM. Fixed the Flow A diagram node and all README references (coder contract env, security/egress model, profile notes, intro). Clarified that eks-platform-openclaw uses LiteLLM but this platform uses Bifrost.
…us-agent-coding-pattern
Flow A — Agent Sandbox capability. New GitOps addon chart that packages the Kata micro-VM sandbox substrate for the Open Agent Platform.
Tunable surface: operator image, kata runtime classes + default (kata-clh), warm-pool sizing (targetIdle=3, scale-to-zero TTL, reap TTL), pool-manager config, and the coder SandboxTemplate defaults (Bifrost LLM gateway URL).
Namespace enforces PSS 'restricted' since kata sandboxes run untrusted LLM-generated code. Verified: helm template renders cleanly.
Renders one RuntimeClass per values.kata.runtimeClasses entry with the nodeSelector + toleration that steers pods onto the kata Karpenter pool. Verified: helm template renders kata-clh + kata-qemu with correct handlers.
SandboxTemplate the warm pool clones: kata-clh runtime, no SA token, runAsNonRoot + restricted seccomp + drop ALL caps, readOnlyRootFilesystem, ephemeral workspace PVC, Bifrost LLM gateway URL. Image/secrets patched per-claim by the consumer. Verified: helm template renders correctly.
Locks coder-sandbox egress to DNS + Bifrost:8080 + HTTPS (git/gh/registries), blocks IMDS (169.254.169.254). Breaks the lethal trifecta so untrusted issue text can't reach arbitrary internal services or exfiltrate. Verified: renders + chart lints clean.
Narrowly-scoped Role: sandboxes (+scale subresource), sandboxtemplates/claims read, PVC/Service delete — capability namespace only, no cluster-wide access. Gated on warmPool.enabled. Verified: renders; disabling warmPool emits 0 resources.
Every-minute CronJob that reconciles the warm pool: REFILL idle sandboxes to targetIdle via SandboxClaims, plus scale-to-zero + reap hooks. Runs non-root, readOnlyRootFilesystem, drop ALL. Verified: helm renders + YAML parses. NOTE: scale-to-zero/reap steps are stubbed — jq logic refined next commit.
Replace stubbed steps with real jq logic: idle sandboxes past idleScaleToZeroSeconds → kubectl scale --replicas=0 (PVC kept); claimed sandboxes past reapAfterSeconds → delete (abandoned-run safety net), keyed on the agent-sandbox.io/last-seen annotation. Verified: helm renders, YAML parses, embedded script passes sh -n.
…tefulSet/Service) Controller runtime for agents.x-k8s.io (upstream image v0.1.0) that materializes a Kata-VM pod+service per Sandbox CR. CRDs (~4k lines) come from the upstream bundle at an earlier sync-wave, not vendored. Gated on operator.installCRDs. Verified: full chart renders 14 manifests, all parse, helm lint clean.
Add agent-sandbox to gitops/addons/bootstrap/default/addons.yaml: sync-wave 2, selector enable_agent_sandbox, Bifrost URL from cluster annotation. The ApplicationSet cluster-generator fans it onto any cluster carrying the label. Verified: addons.yaml parses.
Turn on agent_sandbox in the dev environment overlay — the warm-pool capability comes up on spoke-dev where the Dark Factory pipeline runs. Verified: YAML parses.
Install the sandbox capability on prod as a permanent platform feature, but the Dark Factory never runs here — prod warm pool stays dormant, unreviewed code is only built/tested on spoke-dev (production-safety). Verified: YAML parses.
…un Kata) Comment out agent_sandbox on dev. Spoke clusters run EKS Auto Mode + Bottlerocket, which cannot host Kata micro-VMs (no nested-virt/kvm control). Chart is kept; enabling needs a kata-capable nodepool strategy for Auto Mode first. Verified: YAML parses.
…run Kata) Same as dev: comment out agent_sandbox until EKS Auto Mode + Kata integration is designed. Chart retained. Verified: YAML parses.
…options Record why agent-sandbox is disabled on spokes: EKS Auto Mode + Bottlerocket cannot host Kata (no nested-virt/kvm control, no kata-deploy). List 3 paths to evaluate: self-managed kata nodepool, Bedrock AgentCore/Fargate microVM, or gVisor. Top item to resolve before enabling Flow A live.
Record the spike outcome: self-managed nested-virt MNG coexists with EKS Auto Mode and /dev/kvm works via CpuOptions.NestedVirtualization (aws-cli >=2.35). Decision: MNG (not a 2nd Karpenter); AgentCore/gVisor rejected with reasons. Two implementation lessons: AL2023 nodeadm MIME userData (don't clobber bootstrap) + delete MNG-first teardown ordering. Replaces the old blocker note.
Depend on the upstream kata-deploy chart (v3.32.0) to install the Kata runtime + containerd handlers on kata MNG nodes. Gated by kataDeploy.enabled so the chart stays inert on clusters without a kata-capable nodepool. Verified: YAML parses.
Mirror openclaw's kata-deploy config: target the static kata-enabled label (not katacontainers.io/kata-runtime, which deadlocks), tolerate kata + runtime-not-ready taints, install qemu+clh shims, disable kata-deploy's own RuntimeClasses (our chart owns them). Default kataDeploy.enabled=false so it's inert without a kata nodepool. Verified: YAML parses.
The correct AL2023 MIME userData for the nested-virt kata MNG: a boot script that modprobes kvm_intel + persists it (so /dev/kvm exists before Ready), then a nodeadm NodeConfig that joins the cluster with the kata-enabled label + kata=true taint. Encodes spike lesson #1 (don't clobber nodeadm bootstrap).
Declarative nested-virt (c8i/m8i) Managed Node Group for spoke-dev alongside Auto Mode: minSize 0 (scale-to-zero), kata-enabled label + kata=true taint, AL2023, scoped node IAM. Coexistence validated by the spike. Verified: YAML parses.
…late Terraform variant for teams on the appmod/openclaw IaC path: launch template with cpu_options.nested_virtualization=enabled (the flag eksctl can't set) + MIME nodeadm userData (modprobe kvm_intel + join), MNG scale-to-zero, kata=true taint, kata labels. Verified: braces balanced.
…d (A) stackProfiles values (auto/terraform/node; java/rust commented as later). Sensor extracts the dark-factory-<name> label → profile param (sprig over labels[]). df-run: resolve-profile step renders the profiles map into a case-statement and outputs build/test/scaffold; claim injects DF_PROFILE/DF_BUILD_CMD/DF_TEST_CMD/ DF_SCAFFOLD_HINT into the coder. Adding a language = a values entry, no pipeline code. Coder image v0.1.12; chart v0.9.0. See docs/dark-factory/PROFILES.md.
…ot sprig The Sensor sprig dataTemplate over body.issue.labels silently resolved to 'auto' (fragile multi-statement sprig in dataTemplate). Move profile derivation into the resolve-profile step: read the issue's dark-factory-<name> label via the GitHub API with node (robust). Sensor just passes profile=auto. v0.9.1.
… API label resolution
… Manager (B) Replaces the manually-created dark-factory-github secrets with ExternalSecrets synced from AWS Secrets Manager (secret id dark-factory/github, JSON keys token + webhook-secret) — the same mechanism as the rest of the platform. One ExternalSecret per namespace with the right key mapping: argo→token, argo-events→token+webhook-secret, agent-sandbox-system→gh-token. GitOps-managed, reproducible on rebuild, auto-refreshed (1h). external-secrets.io/v1 (v1beta1 not served). Future: GitHub App + short-lived tokens + narrower coder token. Chart v0.10.0.
…views) The dir now holds review.js + deploy-test.sh + status.js + iterate.js + merge.js + comment.js — 'scripts/' reads truer. Renamed the dir and all references: .Files.Get paths, /review/→/scripts/ mountPaths + invocations across df-run/df-merge/df-iterate, and the internal ref in deploy-test.sh. ConfigMap name df-review + volume name review-script kept (stable identifiers, not paths). Template file → 51-scripts-configmap. Render clean, zero /review/ refs remain. v0.10.1.
…plumbing Remove DF_BUILD_CMD/DF_TEST_CMD/DF_SCAFFOLD_HINT injection. buildAndTest now discovers the command from the repo's own marker files (Makefile test target first as the dev override, then package.json/go.mod/pyproject/Cargo.toml/pom.xml/gradle). Language support = toolchains in the coder IMAGE + the repo's markers, not platform profiles. fetchIssueSpec no longer appends a scaffold hint (issue text states the stack).
…dant) Per-language profiles duplicated what the coder auto-detect + detect-deployable already do; their only unique bit (scaffoldHint) is redundant with the issue text. Remove stackProfiles values, the resolve-profile workflow step, the profile workflow/Sensor params, and DF_PROFILE/BUILD/TEST/SCAFFOLD env. Language support is now: toolchains in the coder image + build/test from repo markers + auto-detected verify kind — no label, no central config. Coder v0.1.13. PROFILES.md rewritten to document the decoupled model. Chart v0.11.0.
…shboard (GitOps) Obs1: headless annotated Service (prometheus.io/scrape) exposing the Argo workflow-controller :9090/metrics so the platform AMP scraper's kubernetes-service-endpoints job picks up df_runs_total + df_run_duration_seconds (no scraper edit). Obs2: GrafanaDashboard CR (grafana-operator, same pattern as agent-platform-* dashboards) — Dark Factory dashboard with outcomes/throughput/ lead-time/outcome-mix/queue-depth panels. Both GitOps-managed. Chart v0.12.0.
The UA-shim now buffers each LLM response, parses Anthropic usage (input/output tokens), and accumulates totals into /tmp/llm-usage.json. At run-end the coder posts ONE Langfuse trace + generation observation (issue/PR/repo/profile metadata + token usage) via the batch ingestion API. Keys read from /etc/secrets (projected, 0400); LANGFUSE_URL injected by the claim. Best-effort — never breaks the proxy or the run. Fires on success, failure, and no-change paths.
…o coder (obs) Langfuse ingestion keys synced from AWS Secrets Manager (dark-factory/langfuse) and MERGED into the coder's dark-factory-github mounted secret (keys langfuse-public-key/ langfuse-secret-key → /etc/secrets). LANGFUSE_URL (ClusterIP) injected per-claim. Completes the observability stack: Argo metrics→AMP→Grafana + coder LLM traces→Langfuse. Coder v0.1.14; chart v0.13.0.
…a Merge ES)
ESO refuses creationPolicy:Merge into a secret already Owned by another
ExternalSecret ('target is owned by another ExternalSecret'). Move the langfuse
public/secret keys onto the agent-sandbox-system dark-factory-github ExternalSecret
so one Owner ES projects gh-token + langfuse-* to /etc/secrets. Drop the separate
06-externalsecret-langfuse. v0.13.1.
…races Bifrost's telemetry already exports full per-call LLM traces to Langfuse (prompt/ response/model/tokens, tagged user-agent=dark-factory-coder) — richer than the redundant per-run trace I'd added (which also hit a process.exit race). Revert: shim back to clean pass-through, remove postLangfuseTrace + the langfuse ES keys + LANGFUSE_URL env. LLM observability is Bifrost→Langfuse. Coder v0.1.15.
…rade) Scenarios can declare appliesWhen (a predicate over repo + the PR diff); if false the scenario is SKIPPED, not failed, and the gate is computed over applicable scenarios only (zero applicable → pass, n/a). The subtract scenarios now apply only when the diff touches index.js — so a Terraform PR no longer fails the holdout 1/4 against irrelevant JS scenarios. Chart v0.15.0.
…board Two bugs behind 'No data': (1) the Argo workflow-controller serves metrics over HTTPS (plain HTTP → 400), so the metrics Service needs prometheus.io/scheme: https for the AMP scraper. (2) Argo prefixes custom metrics with argo_workflows_, so the real names are argo_workflows_df_runs_total / _df_run_duration_seconds — the dashboard queried the unprefixed names. Also: these are gauges, not counters, so switched rate()/increase() panels to direct gauge queries. v0.15.1.
…crape Root cause of 'No data': the Argo workflow-controller serves :9090/metrics over HTTPS with a self-signed cert; the platform AMP scraper's kubernetes-service-endpoints job has no insecure_skip_verify, so the scrape fails TLS (verified: verify→000, insecure→200). We can't edit the platform scraper. Add a tiny socat proxy that scrapes the controller over HTTPS-insecure and re-serves plain HTTP :9091; the annotated Service (scheme=http) points at the proxy. Confirmed via awscurl that argo_workflows_df_runs_total was absent in AMP. v0.16.0.
…UI 502) The langfuse web probes lacked timeoutSeconds → k8s 1s default. /api/public/health checks Postgres + ClickHouse and can exceed 1s, so the livenessProbe timed out, failed 3x, and SIGKILLed the pod (exitCode 137) mid-boot → crash loop → empty Service endpoints → ALB 502 (UI down). Set timeoutSeconds:5 on startup/liveness/ readiness (+ liveness period 15→30s). Durable GitOps replacement for the earlier live patch. Langfuse chart v0.1.1.
… comments The factory posts its own PR comments (sticky status, findings, iteration notices) using a real PAT → GitHub reports comment.user.type=User, so the Sensor's exclude-Bot filter did NOT exclude them → every factory comment fired df-iterate → new commit → more comments → runaway loop (observed on issue #31: 3 concurrent df-run executions, 3 commits, split commit statuses, and a stale 'not run' PR body). Add a definitive guard in iterate.js: skip any comment containing a '<!-- dark-factory: -->' marker (RE2 has no negative-lookahead to do this at the Sensor filter). Chart v0.17.0.
…ory's own author Add an IDENTITY-based guard alongside the marker guard: df-iterate resolves the token owner (GET /user) and skips if the triggering comment's author == that identity. Catches every factory-authored comment even without a marker; a real human reviewer is a different login. Sensor now passes comment.user.login. v0.17.1.
…ps-native
Replace the linters+Nova review stub with the genuine managed AWS Frontier
Agents, ordered DevOps -> (needs-security-review label) -> Security.
AWS Security Agent (headless, validated live against the real API):
- scripts/security-agent.sh: clone -> stage {src,diff} in S3 -> create-code-review
-> start-code-review-job -> poll -> list-findings -> dark-factory/security status
+ PR comment. No GitHub App, no OAuth. Advisory unless securityAgent.blockLevel.
- iam/securityagent.tf: OIDC provider + service role (trusts securityagent.amazonaws.com)
+ IRSA role + private S3 diff bucket. IAM-as-code (repo convention). IRSA verified
from a hub pod.
- templates/06-securityagent-bootstrap.yaml + scripts/bootstrap-agentspace.sh:
idempotent ArgoCD PreSync Job find-or-creates the agent space + application ONCE,
writes IDs into the dark-factory-securityagent Secret the review step reads.
AWS DevOps Agent (release-readiness, first/broad review):
- df-run devops-gate waits for the DevOps Agent GitHub App check-run (default) or a
coder-applied label (fallback), then gates the Security Agent step. Never fakes a
pass: not-connected -> Security skipped + sticky status shows not-run.
Coder engine parameterization (both first-class):
- CODER_ENGINE=claude|kiro in entrypoint.js; Dockerfile installs both CLIs
(KIRO_CLI_URL build-arg) + aws-cli/zip (image reused by hub steps).
Removed scripts/review.js (the cooked-up linters+Nova reviewer). Docs Section 6.2
rewritten for the real agents; chart v0.18.0.
The one manual step (flagged, not GitOps-able): one-time console connect of the repo
to the DevOps Agent Agent Space (OAuth). Security Agent needs no repo connect.
…ource
The PreSync bootstrap is a plain batch/v1 Job — 'source:' is an Argo Workflow
field and fails apply ('field not declared in schema'). Move the inline installer
+ script call into command:[bash,-c] + args.
The bootstrap Job is a PreSync hook, but its ServiceAccount + RBAC were regular resources (which sync AFTER PreSync hooks) → 'serviceaccount not found'. Make the SA, Role, RoleBinding, and a dedicated bootstrap-script ConfigMap PreSync hooks at sync-wave -1 (before the Job at wave 0). Mount the hooked CM instead of df-review (which also syncs post-hook).
… verbs)
The alpine/k8s image's aws-cli lacks the brand-new 'securityagent' service
('Invalid choice: securityagent'), and AWS CLI v2 (which has it) is glibc-only —
won't run on musl/Alpine. Run the bootstrap Job on public.ecr.aws/aws-cli/aws-cli
(glibc, always-current v2) and fetch a static kubectl at start to write the Secret.
Add securityAgent.bootstrapImage. Both bootstrap + the df-run security step now
fail LOUD if aws-cli lacks securityagent (never a fake pass).
Only one Security Agent application per account is allowed; create-application throws ServiceQuotaExceededException if one exists but list-applications didn't surface it in-cluster. Treat 'already exists' as success and re-list to adopt — never fatal, idempotent across syncs.
…ript Verified in-cluster that Alpine/musl aws-cli (2.32) LACKS the brand-new securityagent verbs; AWS CLI v2 with them is glibc-only. So the df-run security step can't run on the coder image — point it at public.ecr.aws/aws-cli/aws-cli (glibc, current v2) + install git/zip at start. Rewrite security-agent.sh to be node-free (python3 + curl + git + aws) so that minimal image suffices — drops the comment.js dependency; sticky PR comment now done via curl+python3. Add securityAgent.stepImage. Both steps fail loud if aws-cli lacks securityagent. Validated live: node-free script drove the real API end-to-end (clone->S3-> create-review->job->status via curl); review returned SQL_INJECTION (CRITICAL) + DEFAULT_CREDENTIALS on the flawed sample.
…; install runbook - Built + pushed dark-factory-coder:v0.2.0 (adds aws-cli + git + zip; claude wired, kiro slot present pending KIRO_CLI_URL). Bump both the dark-factory chart refs and the agent-sandbox SandboxTemplate coder image to v0.2.0. - Applied iam/securityagent.tf via terraform (imported the CLI-created resources; 5 added incl S3 hardening, 4 changed in-place, 0 destroyed). IAM is now state-managed as code. - docs/dark-factory/AGENT-INSTALL.md: one-time GitHub-App authorization runbook for a colleague (the only irreducibly-human step — OAuth consent). Security Agent needs NO app (headless S3 diff); only the DevOps Agent GitHub App install is required. Includes CLI to mint the install URL + verification steps. - .helmignore + .gitignore: keep terraform state/plugins out of the chart + git.
…app paths Support the sandbox repo's new infra/ + app/ layout end-to-end: - entrypoint.js buildAndTest now probes .,app,src,backend,server for the project marker (package.json/go.mod/etc.) instead of root-only — generic, layout-agnostic. - deployTest.terraformPath . -> infra (TF now under infra/). - holdout scenarios require app/index.js. Rebuilt+pushed coder v0.2.1; bumped dark-factory + agent-sandbox refs.
Workflow submission failed: 'failed to resolve tasks.drive-coder.outputs...' — a template body can't reference tasks.* (that scope is only the calling DAG's arguments/when). Pass pr-number into devops-gate via the DAG task's arguments + an inputs.parameters declaration (same pattern as holdout-gate).
…heck context The DevOps Agent Release Manager (code review) is allow-list gated in preview — that's why the console shows no Pipeline/GitHub section and there's no API. Document both allow-list paths (Heimdall onboarding ticket + self-serve CR adding acct 940019131157 to the ReleaseManagement*CDK constants), the ReleaseManagerPolicy IAM, and ~1-2h indexing. Pin devopsAgent.checkContext to the confirmed native check 'aws-devops-agent/release-readiness-review' (broad alternation kept as safety net).
…check-run Gap audit of the full GitHub chain surfaced 3 real gaps, now fixed: 1. merge.js gated on 'dark-factory/devops' (a commit status) but the REAL DevOps Agent posts a CHECK-RUN named aws-devops-agent/release-readiness-review on a different GitHub API surface. merge.js now reads BOTH commit statuses AND check-runs, and requires DEVOPS_CHECK (configurable) green. REQUIRE_DEVOPS toggles the gate (false in security-only mode). A real BLOCK now blocks merge. 2. status.js sticky board only read commit statuses -> DevOps row always showed 'not run'. Now folds in check-runs and renders the DevOps row from the real check-run (DEVOPS_CHECK). 3. coder PR body showed 'DevOps: skipped / Security: waiting' in check-mode (misleading — the GitHub App DOES review). Now mode-aware: check-mode shows 'DevOps pending (AWS DevOps Agent reviews this PR)'. Wire DEVOPS_CHECK into the sticky-status + merge steps from devopsAgent.checkRunName (exact name) alongside checkContext (gate regex). Coder image v0.2.2 (mode-aware PR body); bump dark-factory + agent-sandbox refs. Known (not a code gap): PR author elamaran11 can't self-approve -> the approve-> merge leg needs a 2nd GitHub identity or the simulate-approval workflow.
…cess ticket V2290161680)
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.
What
Design document (doc-only, no runtime code) for a Dark Factory — Autonomous Agent Coding Pattern on the Open Agent Platform.
A human files a GitHub issue (a spec); AI agents do the rest — implement → build → test → security/devops review → PR → (human approves results) → merge → teardown. Autonomy Level 3.
Contents
docs/dark-factory/README.md— full designdocs/dark-factory/diagrams/flow-a-sandbox-capability.md— Flow A: the permanent Agent Sandbox capability (Kata/CLH micro-VMs +SandboxCRD + warm pool), capability architecture + warm-pool state machinedocs/dark-factory/diagrams/flow-b-dark-factory.md— Flow B: the Dark Factory pipeline, end-to-end flow + detailed sequence + live-status mockDesign highlights
eks-platform-openclaw(Sandbox CRD, session-router lifecycle, LiteLLM→Bedrock),appmod-blueprints(PlatformClusterephemeral EKS),agent-platform-amazon-eks(addon ApplicationSets).Validated against industry practice
Aligned with GitHub Copilot coding agent, OpenAI Codex, Devin, and StrongDM's Software Factory. Explicitly designs against documented anti-patterns: lethal trifecta / prompt injection, reward hacking / test-gaming, LLM-judge self-preference bias, multi-agent over-orchestration, non-converging comment loops, warm-pool idle burn, and rubber-stamp reviews. Sources cited in the README.
Note
Doc-first by design — this PR ships the pattern/design. Implementation follows the phased roadmap (P1–P5) in the README. Mermaid diagrams render natively on GitHub.