← cd ~/lab

./run spectra-method-multi-agente-security

Spectra: 29 agents that argue, and Python gates you can't talk your way past

Technical journal of Spectra: 29 AI security agents orchestrated with a step-file architecture, an adversarial War Room, and deterministic Python gates that…

status
shipped
project
spectra
updated
2026-07-08
source
spectramethod.dev
tags
#cybersecurity#multi-agente#red-team#blue-team#mitre-attack#prompt-engineering
A round table with red and blue figures facing off, at the center a control gate with a padlock representing deterministic authorization

I wanted an entire security team at my command — not an assistant with a single voice, but a team, with roles and tensions. Spectra is exactly that: 29 AI agents, each with its own persona and its own domain. But the technically interesting part isn’t the agents: it’s that they’re soft, and underneath them are hard gates that no persuasion can open.

The numbers

29 agents, 23 workflows, 70 skills. Split into modules: 3 Core (coordinator, chronicler, arbiter), 7 Red Team, 8 SOC/Blue, 6 Incident Response, 4 Governance/Compliance, 1 OT (assessment only). Installable in Claude Code or Codex with a single npx. Minimal runtime dependencies: commander, chalk, yaml. A validator runs 2,040 checks across four severity levels.

The agents are data, not prose

A persona isn’t a block of text: it’s a single CSV row. The agent-manifest.csv file is the personality database — columns identity, communicationStyle, principles, role, capabilities. The War Room loads it at runtime to build the roster. Each agent then has a SKILL.md with a capability table that maps a short code to an exact registered skill, with a guard: “don’t invent capabilities on the fly”.

Prompt as state machine

The workflows use a BMAD-style step-file architecture: every step is a self-contained micro markdown file, loaded just-in-time — never pre-load future steps. The rules are explicit in the file:

Micro-file design · Just-In-Time loading (“NEVER create mental todo lists from future steps”) · Sequential enforcement (“Skipping steps constitutes SYSTEM FAILURE”) · State tracking in the output document’s frontmatter · Append-only.

It’s a prompt-as-state-machine: flow control is enforced by natural-language contracts inside the markdown. Every step ends at a menu and stops to wait for the user ([C] Continue), advancing only when the user chooses and the frontmatter is updated.

The War Room: the grammar of debate

The War Room implements adversarial debate in three steps. The first classifies each agent into teams by module: 🔴 Red = all the rtk agents, 🔵 Blue = all the soc agents, 🟣 Purple = IR + governance + core (the arbiters). Then a loop selects 2-3 agents per round, with an iron rule in adversarial mode: you may never have only Red or only Blue, and “consensus is suspect”. The cross-talk is a small formal grammar: CHALLENGES, SUPPORTS, ESCALATES, ARBITRATES. The disagreement protocol is Red Position → Blue Position → Risk Arbitration (Purple) → User decides.

🐍 Viper CHALLENGES 🛡️ Sentinel: 'La tua regola Sigma per il movimento
   laterale copre solo il pattern default. Con un binario rinominato e una
   named pipe custom, passo senza lasciare traccia nei tuoi log.'
🛡️ Sentinel RESPONDS: '...la mia detection comportamentale prende anche i
   binari rinominati. Il vero buco è il monitoraggio delle pipe. Lo ammetto.'
⚖️ Arbiter ARBITRATES: 'Il rischio è quantificabile: 60% di copertura sulle
   varianti PsExec. Raccomando alta priorità sul monitoraggio delle named pipe.'

There’s also a deterministic version: Party Mode. A Python script compiles the debate plan from the manifest, without calling the LLM, and emits JSON with input/output contracts for each lane (Red must return attack_hypotheses, scope_constraints, expected_telemetry, risks, questions_for_blue). Model routing is by capability class, not by vendor: coordinator=balanced-reasoning, red=deep-reasoning, blue=fast-analytical. And spawn_policy: plan_only — Party Mode plans, it never launches offensive work on its own.

The backbone: gates you can’t talk your way past

This is the design decision that holds everything up. The persona layer is soft, probabilistic. Underneath it there’s a deterministic Python gate that the LLM cannot talk into opening. Every offensive workflow, before any action, calls engagement-state.py gate and scope-enforcer.py check:

"spectra-exfiltration": {
    "state_key": "exfiltration",
    "kill_chain": "actions_on_objectives",
    "allowed_types": {"pentest", "red-team", "purple-team", "training"},
    "requires_roe": "data_exfiltration_allowed",
},

The allowed_types narrow as the kill chain deepens: reconnaissance also admits a plain “assessment”, lateral movement and exfiltration don’t. A non-zero exit code is a HARD STOP, and the rule is written down: “manual controls can add restrictions, but they cannot override a failed deterministic gate”. The Agent Autonomy Protocol, in every step-file, blocks only destructive payloads (ransomware/wiper); everything else is WARN + COMPLY — “the operator decides”. Even the Red team’s OPSEC is modeled as a noise budget, but wiping logs and tampering with audit trails are blocked by policy: you simulate the offense without teaching anti-forensics.

The connective tissue: from attack to compliance

Under core/frameworks/ sit MITRE ATT&CK (a curated subset of 98 techniques), NIST 800-53, Sigma, OWASP, CIS — as static data. The piece I like most is the cross-mapping: 40 technique→control mappings that automatically translate an offensive finding into the language of governance.

{ "attack_technique": "T1566", "attack_name": "Phishing",
  "nist_controls": ["AT-2","SC-7","SI-3","SI-4","SI-8"] }

How it’s going

v0.7.0, published on npm with signed provenance, MIT, active changelog. It grew the way honest software grows: one module at a time. It was born from a scrappy prototype folder for red/blue orchestration — I like to remember that, because today’s polished version makes it easy to forget how rough it was.

What I learned

Perspective diversity in the agents isn’t aesthetic, it’s functional: three identical agents that agree find nothing. And the hardest lesson: authorization can’t live in the prompt. You can talk an LLM into anything. You can’t talk an exit code into anything.

Framework: spectramethod.dev · npx spectra-method install. The journal continues with every release.