Jev Meets the Recon Pipeline
1 / 18
RedAmon · Recon Pipeline

Jev Meets the
Recon Pipeline

A typed decision model that reads each target's response and settles eight decisions the scanner used to make from fixed lists.

Page typeCrawl orderFFuf base pathsFFuf extensionsTool healthNuclei tagsWAF classifierTakeover classifier

The whole idea in one line: at eight points in the pipeline, Jev reads the target's response and decides, then hands control straight back to the scan.

Page type
Crawl order
Base paths
FFuf ext.
Tool health
Nuclei
WAF
Takeover
JEVdecision model
01 · The problem

Scanners ship with static lists.

FFuf has one extension list. Nuclei has default tags. Crawlers run A to Z, smart fuzz picks directories at random, and every page is just another URL. They were set once — but targets aren't frozen.

Static listEvery target gets the same guesses — wasted requests on the wrong stack, and misses on the right one.
Response-awareRead what the target just said, then decide. A fixed rule becomes a narrow, tech-aware call.
One static list, fired at every host
.php.aspx.jsp.do
Apache · PHPactually there: .php
.php ✓.aspx ✗.jsp ✗.do ✗
3 wasted
IIS · ASP.NETactually there: .aspx
.php ✗.aspx ✓.jsp ✗.do ✗
3 wasted
Node · Expressactually there: .js .json
.php ✗.aspx ✗.jsp ✗.do ✗
4 wasted
Nothing in the list fits Node — the files that exist are never even tried.
Eight points in the pipeline now ask Jev instead of following a fixed rule — one narrow, typed question at a time.
02 · What Jev is

Not a chatbot. A decision chip.

1

A chat model writes text, and your code has to parse it into a decision.

2

Jev takes facts plus typed questions and returns one typed answer per question.

3

The answer space is fixed in advance — so it cannot hallucinate: no invented option, no JSON to repair, no retry loop.

State · the facts

server: nginx
x-powered-by: PHP/8.2
status: 403
asks: 40 × yes/no
JEVone pass

Typed answers

.php
0.91
.inc
0.74
.env
0.58
.aspx
0.04
~20 tokens a questionone parallel pass · under a secondpinned to jev-1.13.0
03 · The whole model

Three kinds of question.

Noul

“Is this statement true?”

A calibrated probability from 0 to 1. At 0.5 or above, RedAmon reads it as yes.

0 · no0.51 · yes
noul = 0.91 → yes
Used for: each extension, tag, page class, directory and host, plus “is it a WAF?”, “is it a block page?” and “is it transient?”
Choice

“Which one of these?”

Exactly one option from a list you define — never anything outside it.

cloudflare
.82
akamai
.09
imperva
.05
…11 more
.04
Used for: which WAF vendor, out of 14.
Score

“How much, on this rubric?”

One ordered level, from a rubric of 2 to 10 concrete steps.

low
moderate
high
critical
Not needed by the recon decisions so far.
All the questions in one call are answered in a single parallel pass — fast and cheap enough to sit inside a live scan.
04 · Where it plugs in

Eight decisions, five stages.

Discovery · ports
subdomains · DNS · services
unchanged
HTTP probe
tech fingerprint · page body
1
Page type
What kind of page is this?
Resource enumeration
crawlers · fuzzing · collectors
2
Crawl order
Which host does Hakrawler crawl first?
3
FFuf base paths
Which directories deserve the wordlist?
4
FFuf extensions
Which extensions fit this host?
5
Tool health
Did the tool fail, or find nothing?
Vulnerability scanning
Nuclei · security checks
6
Nuclei tags
Which tags fit this stack?
7
WAF classifier
Is a WAF in front? Which one?
Subdomain takeover
fingerprint collisions
8
Takeover classifier
Real takeover, or a WAF page?
Jev decision pointUnchanged stepThe numbers follow the slides that come next
05 · How a call flows

The key never leaves the agent.

Recon container · holds no key
Agent container · holds the token
TypeSafe
1
Recon hook · Jev on
all eight decision points
2
/jev/* endpoint
internal key · rate limit · the project must belong to the caller
3
Load the owner's token · build typed questions
target text sent as data, clipped to a fixed size · ≤ 200 questions a request
4
api.typesafe.ai
jev-1.13.0 · one pass · 5 s timeout, no retry
5
Map answers to the /llm/* shape
floors and closed answer sets applied
6
Recon validator
or the built-in default if Jev is unavailable
target data ≤ 200 questions typed answers
The token stays in the agent, and goes only to api.typesafe.ai.
If Jev is unavailable, recon uses the hook's built-in value and the scan continues.
Hook 1 of 8 · HTTP probing

Page-type labels

Without JevA parked domain, a login wall and a real admin panel are all just another URL.
With JevEvery page is read and labelled: app, login wall, parked, default install, placeholder or error.
What Jev is asked · yes/no × 5 per page

“Is this page only a login or single-sign-on wall?” Then the same for parked, default page, placeholder and error.

State given: status, sizes, word and line counts, title, Server, headers and the first 4 KB of the body. Identical pages are asked once; at most 300 distinct pages a scan, within 60 seconds.

Labels for six pages

illustrative
AcmeShop · storefront/ · 200 · 18 KB
app0.94
Sign in/login · 200 · 4 KB
login_only0.91
This domain is for saleparking CNAME · 200
parked0.96
Welcome to nginx!/ · 200 · 615 B
default0.97
Coming soon/ · 200 · 1 KB
placeholder0.96
404 Not Found/old · 404 · 2 KB
error0.93
→ kept on each Endpoint as page_class, with its confidence and source
Where Jev gives no answer for a page, a built-in pre-filter's label stands: default titles, parking CNAMEs, error statuses, login paths.
+
Benefit: every URL carries a label in the graph, so the real apps stand out from parked, default and error pages.
Hook 2 of 8 · Resource enumeration

Hakrawler crawl order

Without JevHakrawler crawls its seeds A to Z and stops at its URL cap, so hosts late in the alphabet are never reached.
With JevEach probed host is scored for a rich web surface, and the best are crawled first.
What Jev is asked · yes/no × 1 per host

“Is this host likely to have a rich web application surface (many pages, forms, APIs or an admin area) rather than a thin or static site?”

State given: status, size, word and line counts of the host's root page, its title and Server, and its seed count. Up to 400 hosts are scored. Every seed stays in the list; a partial recon keeps A to Z.

Seven hosts, a cap of three

illustrative
A to Z
assets
.04
blog
.35
cdn
.03
URL cap
status
.08
www
.62
xapp
.93
yportal
.89
Jev order
xapp
.93
yportal
.89
www
.62
URL cap
blog
.35
status
.08
assets
.04
cdn
.03
→ the same cap now reaches xapp, yportal, www instead of assets, blog and cdn
Ordering only: every seed stays in the list. Without a score for a host, it follows the scored ones in A to Z order.
+
Benefit: under a tight URL cap, the crawl budget goes to the hosts with the most to find.
Hook 3 of 8 · Resource enumeration

FFuf base-path ranking

Without JevSmart fuzz runs its wordlist under a handful of the directories the crawl found (20 by default), picked at random.
With JevEach discovered directory is scored, and the cap is filled with the most promising ones.
What Jev is asked · yes/no × 1 per directory

“Is this directory likely to hold sensitive, administrative or application content, rather than static assets?”

State given: the directory names from the crawl, up to 400. It runs only when the crawl found more directories than the cap; under it, every directory is fuzzed.

Ten directories, a cap of five

illustrative
admin
0.96
api/v1
0.93
backup
0.90
config
0.88
internal
0.81
assets
0.07
static
0.05
images
0.06
css
0.04
fonts
0.03
→ FFuf fuzzes admin api/v1 backup config internal (cap: 5)
Jev ranks only the directories the crawl found, and the cap keeps the same number of directories either way.
+
Benefit: the wordlist budget lands on admin, API and config directories, not on images and fonts.
Hook 4 of 8 · Resource enumeration

FFuf extension planner

Without JevOne extension list for every host.
With JevEach of 40 extensions is scored against this host's stack. The best, at most 6, are fuzzed.
What Jev is asked · yes/no × 40

“Is .x likely to find real files on this server, given its headers and URL?”

State given: the target URL and the response headers of one HEAD request. Cached per header fingerprint — 100 hosts on one stack cost one call.

Scores for an Apache + PHP host

illustrative
.bak
always
.old
always
.php
0.93
.inc
0.76
.env
0.61
.sql
0.34
.log
0.27
.aspx
0.04
.jsp
0.03
.do
0.02
→ FFuf fuzzes .bak .old .php .inc .env on this host (cap: 6)
.bak and .old are always in the list; Jev picks the rest, up to 6 in total.
+
Benefit: stack-aware fuzzing — fewer wasted requests on the wrong extensions, backups always covered.
Hook 5 of 8 · Resource enumeration

Tool health

Without JevA crawler that comes back empty looks the same whether the site has nothing to show or the tool broke.
With JevEvery empty result is checked. Error text the checks can't place goes to Jev: transient or permanent?
What Jev is asked · yes/no × 1 per unplaced result

“The tool's error output describes a transient failure (a timeout, a network or rate-limit error, a crashed or killed container) rather than a permanent one.”

State given: tool name, exit code, elapsed time, seed count and the error output, with header values, session headers and credential-shaped text redacted. At most 20 questions a run.

What happens to an empty result

Katana · Hakrawler · GAU · FFuf · Arjun …
Clean exit, nothing on stderrthe tool ran and found nothing
Genuine empty result
Timeout, crash, non-zero exit, a named errorthe tool did not do its job
Failure → coverage gap
Error output no rule recognisesneither routine nor a known failure
Ask Jev
stderr: i/o timeout while reading response
exit 0 · 3 seeds · 41 s
transient
.91
permanent
.09
Every failure and unplaced result is a coverage gap on the run. Jev's verdict is kept in the recon output next to it.
+
Benefit: you can tell which empty results deserve a second run, and which mean the target really has nothing.
Hook 6 of 8 · Vulnerability scanning

Nuclei tag selector

Without JevOne fixed tag list — or all 9,000+ templates, which is slow.
With JevEvery candidate tag is scored against the detected stack. The best, at most 15, run.
What Jev is asked · yes/no × ~130

“Should the Nuclei tag x run against a host with this detected tech stack?”

State given: the detected technologies and Server headers. Runs once per scan, so no cache is needed.

~130→≤ 15candidate tags → tags that run
Always included
cveexposuremisconfigdefault-loginkevoasttakeover
Scored for a PHP · WordPress · Apache host (illustrative)
php 0.92wordpress 0.88apache 0.71mysql 0.55iis 0.06aspnet 0.04tomcat 0.05jira 0.03
The universal high-impact tags are always in the run when present; Jev adds the tags that fit the stack.
+
Benefit: a leaner template set for the stack in front of you, with every high-impact check still in it.
Hook 7 of 8 · Security checks

WAF classifier

Without JevHeader tokens like cf-ray. A WAF that strips or rebrands them is invisible.
With JevJudged from the whole response: status, headers, body sample and latency.
What Jev is asked · yes/no + pick one

“A WAF or CDN edge produced this response.” Then, if yes: “which vendor, of these 14?”

State given: URL, status, response time, headers and a body sample. Cached per response fingerprint.

HTTP/1.1 403 · 480 ms
server: (stripped) · cf-ray: (stripped)
body: "Request blocked. Reference #…"
static header check → no WAF found
0
WAF edge present?
…and which vendor? (pick one of 14)
cloudflare
.82
akamai
.09
imperva
.05
Confidence 86 ≥ 70 → WAF present · detection_method: jev_classifier
At confidence ≥ 70 the response counts as WAF-fronted, and the finding names the vendor.
+
Benefit: finds header-stripped WAFs, so a WAF-bypass origin isn't missed — and the finding names the vendor.
Hook 8 of 8 · Subdomain takeover

Takeover classifier

Without Jev“Nothing here yet” matches an unclaimed provider page — and a WAF block page just the same.
With JevIn the ambiguous case only, ask Jev whether the page is a WAF block.
What Jev is asked · yes/no × 1

“This response is a WAF or edge block page, not the unclaimed-site page of the claimed provider.”

State given: hostname, claimed provider, status, headers, response sample. Skipped when a vendor token (Heroku-Request-Id, …) settles it.

Strongest static matchconfirmedlikely — still reported
manual review · 0–59
likely
confirmed · 70+
Borderline matchlikelymanual review
manual review · 0–59
likely
confirmed · 70+
A block-page verdict at confidence ≥ 70 lowers the score by 40. Bands at the default threshold of 60.
The finding stays in the report, marked ai_engine: jev and ranked by its new score.
+
Benefit: real takeovers stay on top; WAF-block collisions drop instead of paging on-call at 3 a.m.
11 · Hook by hook

Eight decisions, and what each one gains.

Hook
The decision
What Jev does
Benefit
Page type
What kind of page is this?
Labels each page: app, login wall, parked, default, placeholder or error
A label on every Endpoint in the graph
Crawl order
Which host does Hakrawler crawl first?
Scores each host for a rich web surface; crawls the best first
The URL cap is spent where there is most to find
FFuf base paths
Which directories deserve the wordlist?
Scores each directory; the cap is filled with the best
Admin, API and config directories get fuzzed
FFuf extensions
Which of 40 extensions fit this host?
Scores each from the headers; 6 at most, .bak/.old always
Fewer wasted requests, no lost backups
Tool health
Did the tool fail, or find nothing?
Reads unplaced error output: transient or permanent
Know which empty results deserve a second run
Nuclei tags
Which of ~130 tags fit this stack?
Scores each from the detected tech; 15 at most, universal tags always
A leaner scan that still covers what matters
WAF classifier
Did a WAF or CDN answer? Which of 14?
Judges status, headers, body and latency
Header-stripped WAFs found, so bypass origins aren't missed
Takeover
Is this a WAF block page, not the provider's?
A block-page verdict in the ambiguous case; score down 40
Real takeovers rise, WAF collisions drop
12 · Switch it on

Three steps, per project.

1 · Add your key

One TypeSafe key, saved once on your account.

Create it at console.typesafe.ai, then add it under Global Settings → LLM Providers → TypeSafe AI (Jev). The model is pinned to jev-1.13.0, and Test Connection is free.

TypeSafe AI (Jev)Global Settings
apikey_••••••••••••
Modeljev-1.13.0 · pinned
Test ConnectionSave Provider
2 · AI in Pipeline

The master switch for every AI hook.

In the project's Target & Modules tab, turn on Enable AI in Pipeline. Each hook gets its own card, and the Jev engine panel shows whether your account has a key.

Enable AI in PipelineON
AI Modelyour chat model
Jev engineYour Jev token is included
Hook cardsone per decision
3 · Pick Jev per hook

LLM or Jev, hook by hook.

FFuf extensions, Nuclei tags, WAF and takeover show an Engine row: LLM | Jev. The four Jev-only hooks show Off | Jev. Both controls of a hook write the same field.

FFuf extensionsLLMJev
Nuclei tagsLLMJev
Page typeOffJev
Crawl orderOffJev
A scan uses the project owner's key. If Jev is unavailable for any reason, each hook uses its built-in behaviour and the scan completes.
13 · Why a decision model

What Jev brings that a chat model doesn't.

Chat LLM
Jev
Output
Free text your code must parse
One typed answer per question
Wrong shape
Possible: malformed JSON, an invented option
Impossible: the answer space is fixed
Every option
Usually just the short list it picked
A calibrated score for each one
Cost
Input and output tokens are billed
About 20 input tokens a question; output is free
Speed
A generated reply
One pass, under a second even for 1,000 questions
Jev · RedAmon Recon

Eight decisions.
One sharper pipeline.

Jev reads each target's response and answers what static lists can't: what a page is, what to crawl first, what to fuzz, what to run, whether a tool really failed, whether a WAF is in the way, and whether a takeover is real. Typed answers, in under a second.

labelorderrankselectclassify

Full guide: the “TypeSafe Jev” page in the RedAmon wiki

RedAmon · Jev Meets the Recon Pipeline1 / 18