NetCortex · dispatch pipeline

The Blackholed UPF

An autonomous 5G incident-triage system that stops before it acts.

One real dispatch run, end to end: the n4_upf_timeout lab scenario drops the UPF’s PFCP traffic, KPI detection raises an Alarm, three specialist agents gather 47 evidence items, a LATS search explains it — and the remediation proposal stops at a human gate. Every number on this page is from the run itself.

inc-kpi-06eebc61 source kpi window 10:11:34 → 10:12:32 UTC 47 evidence items proposal restart_nf upf dry-run approved

01–02Capture & detect

The sandbox runs a live Open5GS core (AMF, SMF, UPF, gNB, UE). The capture script blackholes the UPF’s PFCP port — udp/8805 — for the duration of one UE session, then packets flow again. Nothing else is touched.

capture 10:11:34.944 → 10:12:32.858 UTC 57.9 s

./capture.sh --scenario n4_upf_timeout — three pcaps (N2, N4, SBI) overwrite the committed fixtures; the window is one session’s worth of PDU establishment attempts against the silenced UPF.

detect-kpi 10:12:32.858

The merged export’s KPIs are compared to the golden baseline; the deltas break thresholds, and detect-kpi synthesizes the Alarm event inc-kpi-06eebc61.

procedure success rate
0.0556
golden: 1.0 — 18 sessions, 1 established
pdu session rejects
17
5GSM cause 38 — network failure
pdu session time
1,335.7 ms
golden: 3.3 ms — ~400× slower
blackholed port
udp/8805
UPF PFCP — the scenario’s only fault

03–04Gather & the three specialists

gather validates the event and loads the stub (here: none — all agents run live). Then the evidence fans out to three specialists in parallel, each grounded to its source before it is ever recorded.

gather 10:13:20.282 0.5 ms
pcap_agent 10:13:20.284 → 10:16:01.514 161.2 s

Runs 5gcap analyze over the three captures, then delegates the decode to triage analyze — its own LATS search — which traced 318 chain steps and 114 LLM calls. Returns 5 items: one explicit 5GSMPDUSessionEstabReject cause 38 on N2, four PFCP Session Establishment Requests that never got a terminal message.

kpi_agent 10:16:01.517 → 10:16:04.774 3.3 s

Re-computes the export’s KPIs against the event. 19 items: two deviations and one reject-message item per failed procedure.

log_agent 10:16:04.775 → 10:16:15.162 10.4 s

Pulls docker compose logs for the event’s window, hands the extractor the text with every line numbered [001], [002], …, and the model proposes items citing log:<n> — resolved in code, never trusted. 23 items ground, each carrying its looked-up line.

04The evidence inventory

All 47 items, as recorded — grouped by source. Log items render their citation and the exact looked-up line. The warm-striped rows are the smoking gun: the UPF’s own heartbeat timeout.

5GSMPDUSessionEstabReject cause 38 (keys: flow_id=1)cited: flow:1:11
PFCP Session Establishment Request — no terminal message (timeout)cited: n4:9 ×4
procedure_success_rate 0.0555… below golden 1.0cited: kpi.procedure_success_rate=0.05555555555555555
pdu_session_time_ms 1335.71… above twice golden 3.288…cited: kpi.pdu_session_time_ms=1335.7125450583064
reject message: 5GSMPDUSessionEstabReject nas_cause 38 (Network failure) (keys: flow_id=1)cited: kpi.procedure_failures=17 ×17
UPF heartbeat missing; no response from SMF (keys: component=UPF, issue=No Heartbeat)cited: log:1 sandbox_upf | 2026-09-04T10:12:05.483586102Z 09/04 10:12:05.483: [pfcp] WARNING: [45680] LOCAL No Reponse. Give up! for step 1 type 1 peer [10.53.0.12]:8805 (../lib/pfcp/xact.c:640)
UPF heartbeat missing; no response from SMF (keys: component=UPF, issue=No Heartbeat)cited: log:4 sandbox_upf | 2026-09-04T10:12:12.990874702Z 09/04 10:12:12.990: [pfcp] WARNING: [45681] LOCAL No Reponse. Give up! for step 1 type 5 peer [10.53.0.12]:8805 (../lib/pfcp/xact.c:640)
SMF reports no UPF available (network failure) (keys: error=No UPF available)cited: log:498 sandbox_smf | 2026-09-04T10:12:05.488645822Z 09/04 10:12:05.488: [smf] ERROR: No UPF available (../src/smf/pfcp-sm.c:512)
SMF reports no associated UPF for UE (keys: error=No associated UPF)cited: log:513 sandbox_smf | 2026-09-04T10:12:05.839374559Z 09/04 10:12:05.839: [smf] ERROR: No UPFs are PFCP associated that are suited to RR (../src/smf/context.c:1446)
AMF PDU session establishment reject (keys: error_code=[1:0], type=PDU session establishment reject)cited: log:195 sandbox_amf | 2026-09-04T10:11:57.079776040Z 09/04 10:11:57.079: [amf] ERROR: [1:0] PDU session establishment reject (../src/amf/namf-handler.c:486)
SMF reports no associated UPF for UE (repeat) (keys: error=No associated UPF)cited: log:636 sandbox_smf | 2026-09-04T10:12:10.240016917Z 09/04 10:12:10.239: [smf] ERROR: No UPFs are PFCP associated that are suited to RR (../src/smf/context.c:1446)
SMF reports no associated UPF for UE (repeat) (keys: error=No associated UPF)cited: log:709 sandbox_smf | 2026-09-04T10:12:15.746781339Z 09/04 10:12:15.746: [smf] ERROR: [imsi-999700000000001:1] No associated UPF (../src/smf/npcf-handler.c:546)
UPF heartbeat missing; no response from SMF (keys: component=UPF, issue=No Heartbeat)cited: log:6 sandbox_upf | 2026-09-04T10:12:23.992953684Z 09/04 10:12:23.992: [pfcp] WARNING: [45682] LOCAL No Reponse. Give up! for step 1 type 5 peer [10.53.0.12]:8805 (../lib/pfcp/xact.c:640)
SMF reports no associated UPF for UE (repeat) (keys: error=No associated UPF)cited: log:527 sandbox_smf | 2026-09-04T10:12:06.939657120Z 09/04 10:12:06.939: [smf] ERROR: No UPFs are PFCP associated that are suited to RR (../src/smf/context.c:1446)
SMF reports no associated UPF for UE (repeat) (keys: error=No associated UPF)cited: log:542 sandbox_smf | 2026-09-04T10:12:08.038347817Z 09/04 10:12:08.038: [smf] ERROR: No UPFs are PFCP associated that are suited to RR (../src/smf/context.c:1446)
SMF reports no associated UPF for UE (repeat) (keys: error=No associated UPF)cited: log:665 sandbox_smf | 2026-09-04T10:12:12.442187289Z 09/04 10:12:12.442: [smf] ERROR: No UPFs are PFCP associated that are suited to RR (../src/smf/context.c:1446)
SMF reports no associated UPF for UE (repeat) (keys: error=No associated UPF)cited: log:695 sandbox_smf | 2026-09-04T10:12:14.645844488Z 09/04 10:12:14.645: [smf] ERROR: [imsi-999700000000001:1] No associated UPF (../src/smf/npcf-handler.c:546)
AMF PDU session establishment reject (keys: error_code=[1:0], type=PDU session establishment reject)cited: log:206 sandbox_amf | 2026-09-04T10:12:05.635286797Z 09/04 10:12:05.635: [amf] ERROR: [1:0] PDU session establishment reject (../src/amf/namf-handler.c:486)
AMF PDU session establishment reject (keys: error_code=[1:0], type=PDU session establishment reject)cited: log:217 sandbox_amf | 2026-09-04T10:12:05.841407677Z 09/04 10:12:05.841: [amf] ERROR: [1:0] PDU session establishment reject (../src/amf/namf-handler.c:486)
AMF PDU session establishment reject (keys: error_code=[1:0], type=PDU session establishment reject)cited: log:239 sandbox_amf | 2026-09-04T10:12:08.040195561Z 09/04 10:12:08.039: [amf] ERROR: [1:0] PDU session establishment reject (../src/amf/namf-handler.c:486)
AMF PDU session establishment reject (keys: error_code=[1:0], type=PDU session establishment reject)cited: log:250 sandbox_amf | 2026-09-04T10:12:09.108588059Z 09/04 10:12:09.108: [amf] ERROR: [1:0] PDU session establishment reject (../src/amf/namf-handler.c:486)
AMF PDU session establishment reject (keys: error_code=[1:0], type=PDU session establishment reject)cited: log:261 sandbox_amf | 2026-09-04T10:12:09.141347793Z 09/04 10:12:09.141: [amf] ERROR: [1:0] PDU session establishment reject (../src/amf/namf-handler.c:486)
AMF PDU session establishment reject (keys: error_code=[1:0], type=PDU session establishment reject)cited: log:272 sandbox_amf | 2026-09-04T10:12:10.241894233Z 09/04 10:12:10.241: [amf] ERROR: [1:0] PDU session establishment reject (../src/amf/namf-handler.c:486)
AMF PDU session establishment reject (keys: error_code=[1:0], type=PDU session establishment reject)cited: log:283 sandbox_amf | 2026-09-04T10:12:11.343069570Z 09/04 10:12:11.342: [amf] ERROR: [1:0] PDU session establishment reject (../src/amf/namf-handler.c:486)
AMF PDU session establishment reject (keys: error_code=[1:0], type=PDU session establishment reject)cited: log:294 sandbox_amf | 2026-09-04T10:12:12.444078526Z 09/04 10:12:12.443: [amf] ERROR: [1:0] PDU session establishment reject (../src/amf/namf-handler.c:486)
AMF PDU session establishment reject (keys: error_code=[1:0], type=PDU session establishment reject)cited: log:305 sandbox_amf | 2026-09-04T10:12:13.543309625Z 09/04 10:12:13.543: [amf] ERROR: [1:0] PDU session establishment reject (../src/amf/namf-handler.c:486)
AMF PDU session establishment reject (keys: error_code=[1:0], type=PDU session establishment reject)cited: log:316 sandbox_amf | 2026-09-04T10:12:14.647793755Z 09/04 10:12:14.647: [amf] ERROR: [1:0] PDU session establishment reject (../src/amf/namf-handler.c:486)
AMF PDU session establishment reject (keys: error_code=[1:0], type=PDU session establishment reject)cited: log:327 sandbox_amf | 2026-09-04T10:12:15.748607415Z 09/04 10:12:15.748: [amf] ERROR: [1:0] PDU session establishment reject (../src/amf/namf-handler.c:486)

05Correlate

0.9 ms of deterministic code: items that share a key get linked — unless a key is claimed by more than two items, which would make the link a guess.

no links — 17 of the 19 KPI items share procedure_failures=17, and the ambiguity rule forbids linking when more than two items claim a key. The inventory stays flat, and the investigation reads it as-is.

06Investigate — the LATS search

5.0 seconds, 204 traced phases across five tree nodes. Each phase is one expand / execute / evaluate step of a LATS search over the evidence inventory — the agent may inspect (re-read the inventory) and may only end the search with a finalize whose citations name inventory items exactly. Node 5 is the leaf where the winning episode grounded.

root cause — node.5’s finalize, grounded

“The missing UPF heartbeats caused the SMF to report no UPF available, triggering NAS cause 38 rejections that drove down the procedure success rate and inflated session latency.”
node.1 · root expand ×6 node.2 expand 11 · execute 17 evaluate 17 node.3 expand 12 · execute 33 evaluate 33 node.4 expand 1 · execute 36 evaluate 36 node.5 · winner execute 1 · evaluate 1 finalize, grounded

Tree structure from the LangSmith trace; step payloads live in the checkpoint. The dispatch-level Groq calls traced for this run:

signaturecallsstagewhat it produced
LogEvidenceSignature1log_agent the 23 grounded evidence proposals, each citing log:<n>
ExpandSignature1investigate next-action candidates for the search tree
EvaluateSignature2investigate reward / status / reflection per explored node
ProposalSignature1propose the remediation proposal below

07Propose — from a five-action vocabulary

The proposal must pick one action from a fixed vocabulary (restart_nf, scale_nf, drain_traffic, rollback_config, no_op); the model argued restart_nf upf — the exact box the scenario silenced.

actionrestart_nf
arguments{ "nf": "upf" }
justification Restarting the UPF restores its heartbeat, enabling the SMF to detect an available UPF and stop the NAS cause 38 rejections that were degrading the KPI.
command docker compose --project-directory /path/to/NetCortex/sandbox/core restart upf
hash 20722c43c5b0302e8efcf00a63190048757601c567b2050eccb69ef9a536554a

08The human gate

The graph stops at the approval interrupt — 10:16:21, 2.8 minutes after the alarm. Nothing runs until a human says so. The incident was then approved as a dry-run; the command printed, never executed.

pending — interrupt raised
GraphInterrupt: {"pending": true}
record ends at “Approval status: pending”
approve inc-kpi-06eebc61 (dry-run)
dispatch approve inc-kpi-06eebc61
prints the command to be applied — and applies nothing.
$ dispatch approve inc-kpi-06eebc61 dry-run: docker compose --project-directory /path/to/NetCortex/sandbox/core restart upf

That is the whole loop: capture → detect → evidence → explain → propose → human gate. The pipeline never touched the running core — the restart command is exactly what a human would run, and the human is the one who runs it.