AI-Driven Mesh
Most challenge generation produces one challenge at a time. Each is self-contained: it has its own story, its own hostnames, its own flag, and it has nothing to do with the challenge next to it on the scoreboard.
AI-Driven Mesh produces a graph instead. You give it one anchor challenge; it designs a small set of connected pieces β challenges, deployable services and file artifacts β where what a player finds in one piece is what opens the next. The whole set is built inside a single invented world, so hostnames, usernames, IP addresses and timestamps agree across every artifact.
You review the plan before anything is generated.
Why a graph and not a list
A flat list of challenges asks the player ten unrelated questions. A mesh asks one question with several steps, which is what a real investigation looks like:
- A player opens the entry artifact and finds a hostname.
- That hostname is the one to search for in the SIEM the mesh also deployed.
- The SIEM query surfaces a filename, which is in the packet capture.
- The capture yields the credentials that reach the final objective.
Nothing about that chain can be assembled from a shared challenge library, because its exercises were written by different people, for different events, and share no world.
The two layers of the world
Before planning any challenge, the mesh builds a World Seed β a complete fictional cyber world, generated once and reused by every generator in the mesh. It has two layers.
Story layer β what the narrative needs:
| Element | What it holds |
|---|---|
company |
Name, industry, the organisation the incident happened to |
employees |
Named staff with roles β one of them is usually patient zero |
scenario_context |
Scenario type (incident response, intrusionβ¦) and the posture the player takes |
story_premise |
One or two sentences: the situation the player walks into |
Technical layer β what the generators need as deterministic seeds:
| Element | What it holds |
|---|---|
network |
External IP, internal subnet, and the hosts with their OS hints |
data_artifacts |
The files and records that exist in this world |
vulnerability_scenario |
The weakness that was exploited |
attack_chain_summary |
The chain of events, in order |
The separation is the point. Because every generator β PCAP, memory, disk, web β reads the same seed, the IP in the packet capture is the IP in the SIEM alert, and the username in the phishing email is the username in the memory dump. Cross-artifact coherence is a property of the seed, not something checked afterwards.
The proposal
Once the world exists, the mesh planner proposes a topology. It is a plan only β no challenge content has been generated at this stage.
Nodes
Each node is one of three kinds:
node_type |
What it is |
|---|---|
challenge |
A generated challenge |
service_artifact |
A deployable fake service β SIEM, web app, mail server, chat appβ¦ |
file_artifact |
A deterministically generated file β capture, memory dump, disk image, documentβ¦ |
Each node also carries a role:
entryβ where the player starts. There can be more than one.pivotβ a step in the middle of the chain.flag_terminalβ the final objective. There is exactly one.
Edges β the part that makes it a mesh
An edge is not decoration. It is a clue handoff, and it says precisely where the clue lives:
| Field | Meaning |
|---|---|
from_node / to_node |
Source and destination |
field_path |
Dot-path inside the source artifact where the clue is planted |
clue_encoding |
plain, base64, hex, or embedded_in_text |
clue_kind |
The semantic type of the clue |
clue_description |
Human-readable description, shown on the graph |
Because the edge names the exact field, the generator on the source side knows what to plant, and the generator on the destination side knows what to expect. That contract is what keeps a multi-step chain solvable.
Guard rails
Mesh planning runs under constraints, so a proposal cannot grow into something unplayable or unaffordable:
| Constraint | Default |
|---|---|
max_nodes |
6 |
max_service_artifacts |
3 |
max_file_artifacts |
3 |
max_chain_depth |
4 |
A proposal also carries estimated_credits, plus any warnings and guard_violations the planner found. Read them before confirming β they are the planner telling you what it is unsure about.
Working with a mesh
- Pick the anchor. From the challenge library, choose a spec and select Build Mesh instead of adding it as a standalone challenge. In the CTF wizard, the same thing happens from the AI-Driven selection panel.
- Watch the plan. The planning log streams as the world is built and the topology designed. The World Seed panel fills in with the story and technical layers; the Challenge Graph draws the nodes and edges as they are decided.
- Read the graph. Check that the entry point is where you want players to start, that the chain depth suits your audience, and that the services proposed are ones you want to deploy.
- Revise or confirm. Revise sends the planner back with your feedback. Confirm & Generate turns the plan into real content β and only then are credits spent.
[!NOTE] The topology can be validated on its own, before generation, through
POST /mesh/validate. It returns{valid, errors, warnings, stats}for a set of nodes and edges β useful if you build or modify a mesh programmatically rather than through the UI.
When not to use it
A mesh is more expensive than a single challenge and takes longer to plan. Use a standalone generation when:
- you need one challenge to fill a gap in an otherwise finished event;
- the category has no natural chain β a pure crypto exercise rarely gains from a network of clues;
- your event is short and the players will not have time to work through a four-step chain.
Use a mesh when the event is the point: a training day, a cohort exercise, a hiring scenario β anything where you want participants to reconstruct something rather than answer a list.
See also
- Challenge Generation β single-challenge generation and prompting
- Themes & Universes β narrative overrides that also feed the world seed
- Challenge Workbenches β how file artifacts are analysed without being downloaded