CTFFactory Docs

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

  1. 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.
  2. 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.
  3. 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.
  4. 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

πŸ‡¨πŸ‡¦ Data hosted in Canada Β· Β© 2026 ExamBoot Β· Terms Β· Privacy