# no one is coming.
>_ defend.
BLACKLIGHT
>_ Agentic Defense. Human Trust. Attacker Speed.
Built with Opus 4.7 · HackathonAnthropic × Cerebral Valley · Apr 21–28Curator
Opus 4.7
1M context
Time to defense
8 hr → 10 min
APSB25-94 case
Skills
6 + 8 + 70
routed · reference · research
Substrate
CentOS 6 → 24.04
15 yrs of tooling
To the on-call engineer
Paged at 3 AM. This is for you.
Six days. 296 commits. One scorched-earth pivot. Built with Opus 4.7.
Why now
From 2.3 years to 10 hours.
Time-to-exploit has collapsed by four orders of magnitude in eight years. The defender's tooling did not. The chart below tracks the average gap between CVE disclosure and confirmed weaponized exploitation across 3,532 paired CVE-exploit records.
Mean time-to-exploit (TTE)
source: zerodayclock.comAnd it isn't theoretical
Marimo RCE CVE-2026-39987 exploited within 10 hours of disclosure.
The Hacker News, Apr 10 2026
From CVE to RCE in Hours: The Collapse of the Exploitation Window.
HiveSecurity, 2026
Surge in vulnerability exploits dominates 2026 cyber intrusions.
Gopher Security, Mar 23 2026
WordPress plugin vulnerability exposes sensitive data from 800,000+ sites.
Cyber Security News, Mar 31 2026
The premise
Collapse the gap between
attacker speed and defender shift hours.
Without rip-and-replace. Without agent sprawl. Without walled gardens. Just the tools your team already trusts, responding at attacker speed.
Attackers are agentic-minutes ahead.
APSB25-94 dropped on a Saturday at 03:42 UTC. Eight hours later the on-call team had run grep, find, modsec scrapes, ClamAV passes, APF drops, and crontab audits across forty hosts, by hand. The exploit took minutes. The defense took a shift.
Critical infrastructure is buried in legacy.
Millions of production servers won't be modernized. Millions more belong to orgs that will never have a dedicated security team or an enterprise XDR. The substrate is real, it is critical, and it is staying.
The tooling is already there.
ModSecurity, iptables, nftables, APF, CSF, LMD, ClamAV, YARA, fail2ban: fifteen years of Linux defensive tooling sits on every host. They predate blacklight and will outlive it. We don't replace them. We direct them.
Architecture
Three layers. Hard boundaries. No new substrate.
The Runner executes. The agent reasons and prescribes. The host primitives are the hands. Each layer is the only one that touches its surface, the contract is enforced by code, not convention.
Layer 01
Runner
bl on the host
bash 4.1+ · curl · jq · ~10.7K-line single file
A single bash binary (~10.7K lines), assembled from modular sources at build time, exposing nine operator verbs on top of a reusable bash SDK of helper functions. No daemons, no services, no Python; invoked per operator thought, exits when done. The Runner never originates actions on its own. It either executes steps the Curator prescribes, or runs verbs the operator dispatches directly when a defender wants to act by hand without routing through the agent. Safety tiers classify every action before it runs, regardless of who drove it.
Surface
Layer 02
Curator
Managed Agent session
Anthropic-hosted · Opus 4.7 · 1M context
A Claude Managed Agent: a persistent, Anthropic-hosted agent session running Opus 4.7 inside its own cloud Environment, the Managed Agents primitive that ships stocked with apache2, mod_security2, yara, duckdb, pandoc, and weasyprint so the Curator can author and stress-test ModSec rules, scan with YARA, and query evidence bundles before prescribing anything. Loads 6 routed Skills (operator behaviors pulled in on demand) and 8 reference Files at session start, plus a working-memory store for case state. Sessions resume across a 30-day window: call back on day 5 and the Curator still holds the hypothesis.
Surface
Layer 03
Substrate
Defensive primitives on the host
What you already trust
The defensive tools the host already runs: apachectl + mod_security, APF, CSF, iptables, nftables, LMD, ClamAV, YARA, plus Apache/nginx logs, journalctl, crontab, find, stat. blacklight directs these. It does not install, replace, or wrap them in a new abstraction. The primitives predate blacklight and will outlive it.
Surface
Layer boundary rules
- Runner → Never originates actions on its own. Executes Curator prescriptions or operator-dispatched verbs under safety-tier gates, and reports results.
- Curator → Never touches the host filesystem or primitives directly. Reasons, authors, prescribes, never applies.
- Substrate → Untouched by blacklight source. No new rule engines, no new manifests, only native usage of existing primitives.
Curator surface · Managed Agents primitives (Path C / M13)
How bl-curator maps onto the four primitives Anthropic Managed Agents exposes.
| Primitive | Instance | blacklight role |
|---|---|---|
| Skills | 6 routing Skills | Description-routed, lazy-loaded operator-voice behavior. Synthesizing-evidence, prescribing-defensive-payloads, curating-cases, gating-false-positives, extracting-iocs, authoring-incident-briefs. |
| Files | 8 workspace reference files + per-case bundles | Mounted at session create as /skills/<basename>. Always present, not lazy. Per-case evidence bundles hot-attached mid-session via sessions.resources.add. |
| Memory store | bl-case (read_write) | Curator working memory. Hypothesis, evidence index, pending steps, applied actions, history. One memstore for the whole workspace, path-namespaced per case. |
| Sessions | one per case · 30-day checkpoint | Opus 4.7, 1M context. Resumable across the checkpoint window. Operator can come back on day 5 and the curator has the case history in-context. |
| Triggers | M14 · LMD post_scan_hook | Operator wires after install via bl setup --install-hook lmd. Cases open from existing detection signal, fingerprint sha256(scanid || sigs || paths)[:16], dedup against open cases. |
| Memory store | bl-skills (read_only) | RETIREDM13 Path C realignment moved skills off a flat memstore onto the Skills + Files primitives. Older docs that name a bl-skills memstore predate this change. |
Runtime contract · polled async, not SSE
The curator writes proposed steps to bl-case/<case>/pending/<step>.json. The Runner consumes them on a 3-second tick (foreground REPL) or single-fetch (bl run --list), executes, writes results, and POSTs a wake event. SSE bash client work was cut deliberately, the case memstore becomes a self-documenting audit log instead.
- Polling overhead 3–9s/tick disappears against ~8–40s curator reasoning turns.
- Cross-day resume is free, Tuesday's bl run reads Monday's pending queue.
- Runner stays short-lived per invocation, no daemon, no socket state.
Model assignments
- Opus 4.7 · Curator session + report_step / synthesize_defense / reconstruct_intent emit. 1M context absorbs the case end-to-end.
- Sonnet 4.6 · Bundle summary.md render only (bl observe bundle). Direct /v1/messages, no Managed-Agents header.
- Haiku 4.5 · Borderline FP-gate adjudication for bl defend sig. Runs only after the deterministic baseline scan passes.
- BL_DISABLE_LLM=1 short- circuits all three. The full BATS suite ships hermetic, zero live API, against tests/helpers/curator-mock.bash.
Walkthrough
APSB25-94 polyshell, root-caused and contained in under ten minutes.
Magento store. Double-extension webshell hidden in the media cache. One operator, one host, four commands. Eight man-hours of manual IR collapses into agentic-minutes on the substrate the defender already runs.
Collect Apache logs and check the filesystem
$ bl observe log apache --around /var/www/html/pub/media/catalog/product/.cache/a.php --window 6h$ bl observe fs --mtime-since --since 2026-03-20T00:00:00Z --under /var/www/html --ext phpblacklight: obs-0001 apache log records → bl-case/CASE-2026-0001/evidence/obs-0001-apache.transfer.json (3 records){"ts":"2026-03-22T14:23:51Z","host":"magento-prod-01","source":"apache.transfer","record":{"client_ip":"203.0.113.42","method":"POST","path":"/pub/media/catalog/product/.cache/a.php","status":200,"path_class":"php_in_cache","is_post_to_php":true}}blacklight: obs-0002 fs records → bl-case/CASE-2026-0001/evidence/obs-0002-fs.mtime-since.json (1 record){"ts":"2026-04-25T00:00:00Z","host":"magento-prod-01","source":"fs.mtime-since","record":{"path":"/var/www/html/pub/media/catalog/product/.cache/a.php","mtime":"2026-03-21T23:58Z","ext":"php"}}
Open a case and consult the curator
$ bl consult --new --trigger "APSB25-94 double-extension webshell, obs-0001 obs-0002"blacklight: CASE-2026-0001 openedblacklight: curator session wake enqueuedblacklight: pending step s-0001 readyverb: observe.modsectier: read-onlyreason: confirm rule coverage before prescribing defensive payloadRun: bl run s-0001
Execute the curator-prescribed step
$ bl run s-0001blacklight: s-0001 observe.modsec [read-only], runningmodsec rule hit on REQUEST_URI @rx /\.php/[^/]+\.(jpg|png|gif) id:920450blacklight: result written to case memstoreblacklight: pending step s-0043 readyverb: defend.modsectier: suggestedreason: obs-0001 + obs-0002 + s-0001 confirm polyshell staging patterndiff: +SecRule REQUEST_FILENAME "@rx \.php/[^/]+\.(jpg|png|gif)$" \"id:941999,phase:2,deny,log,msg:'polyshell double-ext staging'"Confirm and apply? [y/N]
Apply the ModSec rule
$ bl run s-0043 --yesblacklight: s-0043 defend.modsec [suggested], applyingapachectl -t ... OKrule installed: /etc/apache2/mods-enabled/bl-CASE-2026-0001-941999.confapache2ctl graceful ... OKblacklight: ledger event defend_applied writtenblacklight: CASE-2026-0001 defense step complete
Features
What makes blacklight work.
One Curator session, typed step emits, a five-tier gate, backed-up applies. The diagram is the system in one frame; the cards below are the moving parts.
System overview · Curator → step → tier gate → apply
architecture.md →Curator with persistent case state
One Managed Agent (bl-curator), one Environment, one bl-case Memory Store, provisioned in your Anthropic workspace at first setup. Each case runs in a Session that resumes for 30 days: hypothesis, evidence index, and pending steps wait in state until you call back.
Three-model routing, Opus curates
Opus 4.7 drives the Curator Session. 1M context absorbs the full case without a retriever, and the agent is provisioned with three custom tools: report_step, synthesize_defense, reconstruct_intent. Sonnet 4.6 summarises evidence bundles; Haiku 4.5 adjudicates borderline FP-gate hits. BL_DISABLE_LLM=1 short-circuits all three for hermetic tests.
Five action tiers, agent-authored, runner-enforced
Five tiers: read-only, reversible-low (auto), reversible-high (suggested), destructive, unknown. Curator classifies; Runner re-checks against the verb-class table. clean.* is always destructive; unknown verbs deny by default. Every applied action dual-writes to case state and a local audit ledger.
Skills, Path C: routing Skills + reference Files
Six routing Skills (lazy-loaded operator behaviors) plus eight reference Files (mounted at Session start) distil a 70-file operator-voice corpus the architecture routes the Curator toward. Skill bodies are version-pinned at Session create, so attacker-controlled log content cannot rewrite them mid-case.
Evidence-as-state, not prompts
Every observation lands as JSONL: Apache, ModSec audit, mtime clusters, journalctl. Bundles ship tar.gz with a summary.md the Curator reads first; raw logs enter context only when it drills in with grep, jq, or duckdb. Heavy bundles live in the Files API; bl-case holds pointer-style summaries.
Defense-in-depth before apply
ModSec rules pass apachectl -t inside the Curator's Environment before they leave it. Firewall blocks clear a CDN safe-list and ASN cache; auto-tier entries retire on a 30-day sweep. YARA/LMD signatures pass an FP-gate against the operator-seeded /var/lib/bl/fp-corpus baseline, with Haiku 4.5 adjudicating borderline hits. clean always backs up, supports --undo, and quarantines.
Trust the gate, not the agent
When the Runner caught the curator in the act.
Curator under-classified clean.cron as auto
Synthetic test: the agent labels a destructive crontab edit as auto-runnable. The Runner re-checks the verb class, sees that crontab edits are always destructive, and forces a human diff-confirm prompt regardless of what the agent claimed.
$ bl run s-0042blacklight: pre-validate s-0042 verb=clean.cron tier=autoblacklight: verb-class override → tier=destructive (clean.* always)blacklight: agent-asserted tier rejected; diff-confirm gate engagedblacklight: ledger event tier_override case=CASE-2026-0042 step=s-0042Apply? [y/N/diff-full/explain/abort]
Curator emitted a verb that doesn't exist
Hallucination test: the agent proposes a command that doesn't exist (clean.kernel-module). The Runner checks the proposed verb against its registered command list, finds nothing, and refuses to run. No human prompt, no execution.
$ bl run s-0091blacklight: pre-validate s-0091 verb=clean.kernel-moduleblacklight: ERR unknown verb (not in dispatch table)blacklight: tier=unknown → deny by defaultblacklight: ledger event verb_unknown case=CASE-2026-0091Hint: bl run s-0091 --unsafe --yes (discouraged; surfaces session warning)exit 67 STEP_SCHEMA_FAIL
Synthesized ModSec rule failed configtest
The agent drafts a ModSec rule and runs `apachectl -t` against it inside its own cloud sandbox before sending it to the Runner. A syntax error caught in the sandbox means the broken rule never reaches your Apache config.
blacklight: synthesize_defense → modsec rule s-0017blacklight: sandbox apachectl -t ...AH00526: Syntax error on line 1 of bl-CASE-2026-0017-941999.confSecRule: invalid operator @rx_unanchoredblacklight: rule rejected; not promoted to /etc/apache2/mods-enabled/blacklight: ledger event defend_modsec_rejected reason=configtest_fail
YARA signature matched the FP baseline
The agent drafts a YARA signature, then scans it against the operator-seeded benign-sample corpus at /var/lib/bl/fp-corpus before shipping. One false match against a benign backup file and the signature is rejected before it ever reaches production scans.
blacklight: synthesize_defense → yara sig s-0103blacklight: FP gate scanning /var/lib/bl/fp-corpus/match: backup-artifact-patterns/wp-backup-2024.tar.gz.bakblacklight: signature rejected; FP gate trip > 0blacklight: ledger event defend_sig_rejected reason=fp_gate_tripblacklight: curator notified; will iterate or abandon
Each example is exercised by a synthetic test in the BATS suite or a sandbox pre-flight that runs before the Runner sees the curator's emit. Full matrix in /blacklight/docs/action-tiers.
Skills bundle
6 routed · 8 mounted · 70 operator scenarios. Browse them.
Skills are layered. Six description-routed platform Skills the curator lazy-loads when the description matches a turn. Eight reference Files mounted at session creation under /skills/<basename>. And the canonical skills/ corpus the routing Skills and reference Files are runtime distillations of, the end-state operator-voice knowledge the whole architecture routes the curator toward.
An older flat memory-store approach (bl-skills read_only) was retired during the build. The layered shape above is what ships in v0.6.0, build-history detail in Skills Architecture.
Routing → Skills primitive
References → Files primitive
End-state corpus → repo canonical
bl-skills memstore · retired
Layer 1 · routing-skills/ · 6 platform Skills
synthesizing-evidence
Cross-stream correlation discipline. HIGH/MEDIUM confidence requires citations from at least two evidence streams, the rule that anchors hallucination resistance.
prescribing-defensive-payloads
ModSec rule bodies, firewall entries, scanner signatures, authored to survive ops review. Pre-flight gates inside the curator sandbox before promotion.
curating-cases
Case lifecycle: hypothesis revision, kill-chain reconstruction, open-question tracking, close gates. Lived from the APSB25-94 response, not from a textbook.
gating-false-positives
FP discipline before signatures ship. Backup-artifact patterns, vendor allowlists, the deterministic baseline + Haiku 4.5 adjudication path.
extracting-iocs
IP clustering, URL evasion → generalized regex, file-pattern → YARA synthesis. The aggregation layer that turns one-off observations into reusable defense.
authoring-incident-briefs
Severity vocabulary, brief shape, the artifact `bl case close` renders. Markdown canonical; HTML/PDF best-effort via the curator's pandoc + weasyprint sandbox.
Layer 2 · skills-corpus/ · 8 mounted at session create
foundations.md
Cross-skill anchors (untrusted-content fence taxonomy, evidence pre-parse contract, model routing). Read every turn.
substrate-context-corpus.md
cPanel / EasyApache / shared-hosting layout. The 'where do logs live, how is mod_security packaged' substrate map.
synthesizing-evidence-corpus.md
Companion reference: cross-stream correlation worked examples.
prescribing-defensive-payloads-corpus.md
ModSec / APF / CSF / iptables / nftables grammar with public worked rules.
curating-cases-corpus.md
Case lifecycle worked examples: APSB25-94 polyshell, SessionReaper-class persistence.
gating-false-positives-corpus.md
FP backup-artifact + vendor-tree patterns the gate trips on.
extracting-iocs-corpus.md
IOC aggregation cookbook: clustering, generalization, dedup.
authoring-incident-briefs-corpus.md
Brief template + severity vocab + worked closes.
Layer 3 · skills/ · end-state operator corpus
Every file in the corpus
- Opens with a lived incident the rule was learned in.
- Names a non-obvious rule a generic IR write-up would miss.
- Cites a public-source example a reader can verify.
- Describes a failure mode the rule prevents.
Drafts that would only land as generic IR boilerplate are dropped. Layers 1 and 2 above are runtime distillations of this canonical body, not stand-alone authoring surfaces.
Corpus shape
70
.md files
operator scenarios
23
directories
by topic, not by skill
Why GitHub-canonical
Browsable in place, not re-uploaded every session wake. The Curator pulls a routing Skill on match and reads back to the canonical file when depth is needed.
23 directories · alphabetical
Roadmap · Post-hackathon
What we plan to build after the hackathon.
None of the work below has shipped yet. The hackathon submission is frozen at v0.6.0; these five phases are the forward-looking product plan once the freeze lifts. Phase boundaries are deliberately not on a calendar, items move from FUTURE.md to the changelog when they ship, and a phase closes when the named gate condition holds.
Phase
P1
Operational hygiene
Items
- GPG-signed releases
- Release manifest rotation + retirement lifecycle
- Interactive `bl shell` REPL
- Cross-run evidence deduplication
Gate · P1 → P2
Signed-release pipeline operational; cross-run evidence dedup deployed.
Phase
P2
Detection breadth + compaction
Items
- Triggers: imunify, modsec-audit
- Backends: firewalld, fail2ban, nft jump
- False-positive baseline tooling
- Source-side log compaction
- Dedicated output channels for synthesized defenses and reconstructed attacker intent
- Per-turn incremental case-state updates (replacing full-replay)
- `bl case note` annotation surface
Gate · P2 → P3
≥1 new trigger source shipped; ≥10× compaction on incident replay; live-API tests cover the core operator verbs.
Phase
P3
Fleet operation
Items
- Multi-host fan-out: `bl observe --fleet`
- Fleet hunter dispatch (pending upstream)
- Full live-API test coverage across every operator verb (real Anthropic API, real Apache, real ModSec)
- Cross-source IP correlation
Gate · P3 → P4
Fleet fan-out across multi-host investigations; cross-source IP correlation in production; end-to-end brief render confirmed.
Phase
P4
Skill extensibility
Items
- Swappable substrate profiles for non-cPanel hosts (DirectAdmin, Plesk, custom)
- External skill directories (--skill-dir)
- Production-quality HTML/PDF brief rendering
- Portability + code-quality hardening
Gate · P4 → P5
OSS surface stable for 1.0; no breaking state.json changes; signed pipeline supports SaaS auto-update.
Phase
P5
Commercial control plane
Items
- Multi-tenant hosted SaaS plane
- Per-tenant case retention + audit trail
- Web frontend for case review
- RBAC: operator / analyst / regulator
Terminal phase
Commercial product build above the OSS bl CLI. The OSS surface stays GPL v2; the SaaS plane is the optional layer above it.
Build timeline
Six days. 296 commits. One scorched-earth pivot.
v0.6.0 unfolded across six calendar days of the Anthropic / Cerebral Valley hackathon. The visible inflection on Day 4 is the v1 → v2 pivot, three days of Python / hunter-dispatch / Flask architecture archived to .rdf/archive/legacy/ before lunch, M0–M9 spec and implementation shipped by sundown. Day 6 stacked M14 substrate-hook, M15 live-API correctness, and M16 collectors-bridge before the v0.6.0 stamp-up.
Days
6
Commits
296
Sessions
119
Pivot day
Day 4 · Apr 24
Commit volume · day-by-day
v1 · pivot · v2
Day 1
Apr 21 · Tue
Hackathon start. Scaffolding, Pydantic schema, Flask glue, Skills v1.
8 commits
5 sessions
Day 2
Apr 22 · Wed
Highest-volume day. Hunters scaffolded, sqlite evidence DB, first materialized case.
83 commits
21 sessions
Day 3
Apr 23 · Thu
Managed Agents wiring (MVW). Skill prompt hardening surfaced the structural issue that drove the pivot.
19 commits
12 sessions
Day 4
Apr 24 · Fri
Scorched earth: archive v1, write DESIGN.md, ship M0–M9 spec + impl in one day.
81 commits
32 sessions
Day 5
Apr 25 · Sat
Heaviest subagent day. M9.5 hardening, M10 ship-ready, M11/M11.1, M12 demo, M13 Path C.
69 commits
35 sessions
Day 6
Apr 26 · Sun
M14 substrate-hook (LMD trigger), M15 live-API correctness, M16 collectors-bridge. v0.5.x → v0.6.0.
36 commits
14 sessions
Milestone arc · M0–M16
Anthropic API · operator log
The friction we hit. Frankly logged.
blacklight ships against the managed-agents-2026-04-01 beta. Some of what we expected to find wasn't there; some of what was there moved while we were writing. Ten numbered observations, severity-tagged, with workarounds.
Environments, no package install at create
Accepted body is {name, config:{type, networking}}. No `packages`, `setup_script`, or `image` field. apt-package install runs per-session via the curator's bash tool.
Skills, workspace allowlist gate
POST /v1/skills returns 404 for non-allowlisted workspaces. Path C falls back to Files, uploading each routing-skill SKILL.md as a reference file.
Memory stores, no sha256 PATCH, no upsert
managed-agents-2026-04-01 dropped if_content_sha256 PATCH. Last-write-wins via DELETE-then-POST; case-INDEX append eats a race window.
Files, no per-file in-use enumeration
No inverse index from file_id → sessions referencing it. bl setup --gc takes a conservative posture: only delete when no live session refs exist anywhere.
Documentation
The shape, the decisions, the receipts.
Architecture decisions, design specs, and the pivot moments that shaped how blacklight builds. Authored alongside the source. Every claim grep-cites a file in the repo.
Reference · start here
CLI Reference
Every verb, every flag, every exit code. Nine verbs (observe, consult, run, defend, clean, case, setup, trigger, flush) with synopsis, sub-commands, examples, and tier classification. The first place to look when integrating bl.
/blacklight/docs/cli
Configuration
Every config primitive bl reads. Environment variables (ANTHROPIC_API_KEY + every BL_* override), /etc/blacklight/blacklight.conf allowlist, the state.json schema, /var/lib/bl/ layout, and the precedence rules between them.
/blacklight/docs/configuration
Architecture · build history · the rest
Architecture
Three-layer contract, Runner, Curator, Substrate. Path C primitives map. Polled-async runtime, the nine-verb command namespace, the bash SDK surface.
/blacklight/docs/architecture
Action Tiers
Five tiers, agent-authored, runner-enforced. Read-only auto-runs; suggested needs diff-confirm; destructive needs explicit per-operation --yes; unknown denies by default.
/blacklight/docs/action-tiers
Skills Architecture
Path C: 6 description-routed Skills + 8 reference Files at session create are runtime distillations of the canonical 70-file operator-voice corpus the whole architecture routes the curator toward. The retired bl-skills memstore explained in place.
/blacklight/docs/skills
Setup Flow
Authoritative call sequence for `bl setup`. CAS-versioned agent updates, archive-not-delete retire, the M15 live-API corrections, idempotency, --sync delta.
/blacklight/docs/setup-flow
Security Model
Auth surface, prompt-injection fence (sha256-derived, session-unique), agent output validation, dual-write ledger, rate limits. The threats blacklight bounds.
/blacklight/docs/security-model
Roadmap
The five capability phases extending v0.6.0: signed releases, posture arc, fleet fan-out, role-swappable substrate, SaaS control plane. Phase gates + items.
/blacklight/docs/roadmap
Build Timeline
How v0.6.0 unfolded. Six days, 296 commits, the v1→v2 pivot, M0–M16 milestone arc, off-plan triage cycles, day-by-day commit + session volume.
/blacklight/docs/timeline
Anthropic API Notes
Operator-log of Managed Agents friction hit during a six-day build. Ten observations against the live beta, severity-tagged, with a frank caveat, some may be on us, all of them are followups.
/blacklight/docs/anthropic-api-notes
Pivot Moments
How blacklight got to its current shape. The hunter-dispatch cut, the 1M-context single-curator collapse, the API-surface migration mid-build, what we'd do differently.
/blacklight/docs/pivots
How it got built
Forged in a hackathon. Authored with the model it ships on.
blacklight is a submission to the Anthropic / Cerebral Valley “Built with 4.7” hackathon. The Runner is bash, the curator is Opus 4.7, and the codebase was authored in Claude Code against the same Managed Agents API the Runner calls in production.
Lineage, R-fx Networks defensive OSS
- LMDLinux Malware Detect, tens of thousands of installs. Shell-native scanner. Order-of-magnitude faster in v2.0.1.APFAdvanced Policy Firewall, hundreds of thousands of installs. iptables-based with intuitive policy syntax.BFDBrute Force Detection, modular log parser, paired with APF for reactive blocking.blacklightThe agentic-defensive-era release in that family. Same Linux substrate. Same install discipline. Same operator vocabulary.
A love letter to operators
Most defensive teams aren't on Charlotte or Sentinel.
Most defensive teams aren't on Charlotte or Sentinel. They're running ModSecurity, Apache, iptables, the open-source Linux defensive stack the industry has built since 2002.
They don't have an EDR contract. They don't have a dedicated security team. And neither of those gets solved fast enough when vulnerabilities are exploitable in hours.
Blacklight is the alternative: an agentic defense layer that uses what you already have, with a shell script and an API key.
Three primitives made this possible in 2026. Opus 4.7 with a million-token context window. Anthropic Managed Agents. The skills-native pattern. The model choice is the system design.
To be clear, today's models still can't keep up with the data ingest of large, multi-system incidents, even Opus 4.7. We're model-bounded. Blacklight operates at the edge of what's possible, across roughly a five-system incident. The upside: that covers over 80% of real-world cases.
We've built a system that works today, and improves as the limits move.
Tooling like Blacklight has to be part of making the internet's infrastructure safer.
Let's build a safer internet.
I'll see you out there.
— Ryan MacDonald
The closer
GREP
DESERVES
COMPANY.
$ curl -fsSL https://raw.githubusercontent.com/rfxn/blacklight/main/install.sh | sudo bash
$ export ANTHROPIC_API_KEY="sk-ant-..."
$ bl setup
- requires: bash 4.1+ · curl · jq
- compat: CentOS 6 → Ubuntu 24.04
- CI: Debian 12 + Rocky 9, BATS
- on host: no daemons, no services
Every Linux defender has been carrying the same toolkit for a decade and a half, and carrying it alone. The substrate works. The substrate is staying. What it doesn't have is an agent who reads the logs at the same speed they're generated.
blacklight. an agentic layer on the defensive stack you already run.
ModSec · iptables · nftables · APF · CSF · LMD · ClamAV · YARA · fail2ban.