Files
Mark-VIII/docs/superpowers/specs/2026-08-20-recon-reports-enterprise-stability-design.md
T

15 KiB

Recon, Reports, Enterprise Certificates, and PineAP Stability Design

Summary

This change improves five related Mark VIII workflows on Pineapple Pager 24.10.1:

  1. Recon reports radio coverage from observed runtime behavior instead of treating an enabled dummy STA as proof of starvation.
  2. Self-contained HTML reports include signal maps matching the Recon UI.
  3. Evil Enterprise can generate and activate a user-defined self-signed server certificate.
  4. Handshakes moves from Recon to PineAP while old links continue to work.
  5. Mark VIII contains and diagnoses known pineapd crash loops without attempting an unsupported binary patch.

The implementation remains compatible with the existing constraints: Python standard library only, no frontend build step, no external report assets, and no modifications to the stock pineapd binary.

Confirmed Current Behavior

On the target Pager, wireless.dummy_radio0 is enabled, but wlan0 is unassociated and wlan0mon exists. The current UI nevertheless displays 2.4GHz starved because wlan0_sta means only that the UCI section is enabled. It does not prove association, administrative state, channel pinning, or a failed channel change.

Recon completion is also currently timer-based. The service does not associate the timer with the resulting scan row, and the UI prefers the newest nonempty scan. A completed run can therefore leave an older scan selected.

The target also has crash-prone PineAP settings: the nonexistent wlan2mon is enabled for hopping, wlan1mon includes 2.4 GHz, and pool broadcast lacks an explicit disabled value. Mark VIII reports these states but does not currently reconcile them. The running daemon is the stock /usr/sbin/pineapd with SHA-256 e2cf0453d7e7d2e08bf31a242289e480d44649923a5199eed954d73df0cf1da5.

Recon Runtime Accuracy

Radio State Model

The backend will expose a structured 2.4 GHz coverage state rather than asking the frontend to infer it from UCI booleans. The state will distinguish:

  • full: wlan0mon passed the channel-control probe and is participating in the active hopper.
  • pinned: a live associated STA or active AP holds phy0, and the monitor cannot change channel.
  • current_channel_only: the channel-control probe failed, but native Recon remains able to collect on the current channel.
  • unavailable: wlan0mon is absent or down and cannot collect.
  • idle: no scan is active, with no claim about current scan coverage.

Supporting fields will identify the observed reason, current channel, associated STA state, dummy-STA configured state, dummy-STA parked state, and active hopper interfaces. User-visible messages will come from this backend diagnosis.

An enabled but unassociated dummy_radio0 will not by itself produce a starvation warning. The preflight channel probe remains authoritative. If the dummy STA causes Resource busy, the existing safe borrowing flow will park it and retry. If the retry succeeds, coverage is full; if it fails, coverage reflects the observed limitation.

The hopper loop will clear active interface state when it exits. Completed scans must not retain stale hopper_ifaces that imply hopping remains active.

Scan Identity and Completion

Before starting native Recon, Mark VIII will record the highest existing scan ID. After the daemon accepts the start, polling will identify the first newer scan row and retain that ID as the run's result. The status response will include the tracked scan ID when available.

Elapsed duration still controls when Mark VIII requests or recognizes the end of the timed run, but the frontend will not announce a completed result until the new scan row is available. A 15-second settlement period will allow final SQLite writes to appear. If no row appears within that period, the scan ends with an explicit result-unavailable warning rather than silently selecting an older scan.

The Recon UI will follow the tracked scan ID, including while it is initially empty. It will no longer use the newest nonempty historical scan as a substitute for the active run.

UI Presentation

The scan bar will preserve the existing styling and use concise messages:

  • 2.4 GHz hopping for full coverage.
  • 2.4 GHz limited to channel N -- <observed reason> for pinned collection.
  • 2.4 GHz monitor unavailable when collection is impossible.

Warnings describe coverage quality, not whether the scan as a whole succeeded. The 5 GHz radio can continue independently when 2.4 GHz is limited.

HTML Report Signal Maps

Rendering

The shared live/archive HTML generator will add dependency-free inline SVG maps for every populated band. The geometry will match MiniChart.channelMap:

  • Prefer observed frequency and otherwise derive it from channel.
  • Use the same 2.4, 5, and 6 GHz ranges.
  • Use a fixed -100 to -30 dBm vertical scale.
  • Represent each AP as a raised-cosine 20 MHz lobe.
  • Use the same green, yellow, orange, and red signal thresholds.

Each SVG will include axes, channel/frequency labels, a signal-strength scale, and an accessible title. Each AP path will include an SVG <title> containing escaped SSID, BSSID, channel, signal, encryption, and vendor metadata. Reports require no JavaScript and remain printable and usable offline.

Existing Statistics

This pass retains the current report scope: summary cards, band breakdown, encryption breakdown, channel occupancy, and AP details. It will not add new client or handshake detail tables.

Labels will describe their actual semantics. The report will use the existing exact client-count query instead of raw device observations. GPS metadata will state that it is the current fix at report generation time; archived reports will continue to omit current GPS.

Report helpers will accept empty or incomplete AP data safely. Unknown bands or channels will not produce malformed SVG. User-controlled fields are HTML-escaped in text and attribute contexts.

Evil Enterprise Certificate Generation

User Flow

The Evil Enterprise page will gain a certificate card matching the current PineAP cards, form controls, infoboxes, and action buttons. This is an inline flow rather than a visually distinct wizard.

The form accepts:

  • Country
  • State or province
  • Locality
  • Organization
  • Organizational unit
  • Common name
  • Subject alternative DNS names
  • Validity in days

The card shows the installed certificate subject, SHA-256 fingerprint, validity range, key type/size, and certificate/key-match status. It never displays or returns private-key material.

Generation and Validation

The backend generates a 2048-bit RSA self-signed server certificate using the device's openssl command. The certificate includes SHA-256 signatures, server-auth key usage, the requested subject, and validated DNS SAN entries. Validity is constrained to 1 through 3650 days.

Inputs are rejected when they contain line breaks or control characters, exceed 128 UTF-8 bytes per subject field, contain an invalid two-letter country code, contain invalid DNS SAN values, include more than 20 SAN entries, or result in an empty common name. Each SAN must be a valid DNS name of at most 253 ASCII characters. Arguments are passed as an argv list rather than through a shell.

Generation occurs in a private temporary directory. Before installation, the backend verifies that:

  • OpenSSL can parse the certificate.
  • OpenSSL can parse the private key.
  • Certificate and key public keys match.
  • The generated certificate is currently valid.
  • Subject and SAN values reflect the request.

Only validated files replace the active certificate and key. Replacement uses backups and atomic renames. The private key and temporary files use mode 0600; public certificates use 0644.

The fallback certificate path will use this same validated generator rather than copying a shared private key. The payload init script will stop applying recursive 0755 permissions to secret material.

Automatic Restart and Rollback

If Evil Enterprise is not active, a successful generation becomes the certificate for the next deployment.

If Evil Enterprise is active, the backend snapshots its current deployment state, installs the new certificate, and automatically redeploys the AP with the same SSID, channel, encryption, hidden state, EAP method, and secret. Success requires hostapd to reach ENABLED with the new certificate.

If redeployment fails, the backend restores the prior certificate files and attempts to redeploy the previous AP configuration. The API reports both the generation failure and whether rollback restored service. Concurrent generation/deployment operations are serialized with the existing attack-operation boundary extended to certificate changes.

Navigation

Top-level Recon remains. Its tabs become:

  • Scanning
  • Reports

Handshakes moves into PINEAP_TABS at #/pineap/handshakes. Its page body and data APIs remain unchanged. The Recon handshake summary card links to the new route.

#/recon/handshakes redirects to #/pineap/handshakes so bookmarks and old links continue to work. This redirect is a concrete compatibility requirement because the previous route shipped in the UI.

pineapd Containment and Diagnostics

Supported-Build Policy

Mark VIII will identify the device by firmware description and daemon SHA-256. The initial affected-build record covers Pager 24.10.1 and the confirmed daemon hash. Known affected builds receive automatic crash-prevention reconciliation.

Unknown builds retain the conservative UI block on pool broadcast, but Mark VIII will not silently apply hash-specific assumptions. Health output will identify the build as unknown and explain that broadcast remains unavailable pending validation. A future verified-safe build can be allowlisted without changing the UI contract.

Safe Reconciliation

Before Mark VIII starts or explicitly restarts pineapd on the affected build, it will ensure:

  • pineapd.@ssidpool[0].disable=1
  • pineapd.wlan2mon.disable=1
  • pineapd.wlan2mon.hop=0
  • pineapd.wlan1mon.bands=5
  • pineapd.wlan0mon.bands=2

Mark VIII will continue using passive pidof checks and will not health-poll the daemon command socket. It will not disable normal 5 GHz hopping merely to make startup appear safe.

The reconciler records original and resulting values and changes only known crash-prevention keys. It does not rewrite unrelated wireless or PineAP settings. Normal startup does not clear the SSID pool.

Crash Circuit Breaker

The health monitor will track PID transitions and SIGSEGV-count changes in a rolling two-minute window. Three observed crashes within that window will stop additional Mark VIII restarts and mark the daemon quarantined; stock procd behavior remains visible but is not amplified by the web UI.

If the pool has refilled above 64 entries or 4096 encoded bytes during a correlated crash loop, Mark VIII will first save a timestamped diagnostic copy, then clear the pool as a last-resort recovery action and perform one controlled restart. This action and its reason appear in health status. A pool at or below both limits is preserved.

The circuit breaker resets only after the daemon remains alive for five minutes or after an explicit operator recovery action. Recovery reruns safe reconciliation before restart.

Diagnostic Bundle

A read-only diagnostic endpoint will produce a downloadable text or JSON bundle containing:

  • Firmware and board identity
  • pineapd hash and process state
  • Relevant PineAP UCI values
  • Monitor interface presence and channel state
  • Pool entry count and encoded size, without exposing unrelated secrets
  • Recent PID transitions, restart decisions, and SIGSEGV deltas
  • Relevant recent log lines
  • Mark VIII health actions and quarantine state

The bundle supports vendor reporting and future safe-build validation. It does not include the stock binary or private certificate/key material.

Error Handling

  • Recon probe failures remain per-radio failures; one radio does not invalidate the other.
  • Database settlement uses bounded retries and reports a missing result explicitly.
  • Report generation returns the existing 404/503 responses for missing or unavailable scans.
  • Certificate APIs return validation errors as HTTP 400, generation/runtime failures as 502, and include rollback state when an active AP was affected.
  • Health reconciliation failures do not trigger unbounded retries. They are exposed through /api/health and diagnostics.
  • All new state-changing APIs retain authentication and same-origin enforcement.

Testing

Backend tests will cover:

  • Enabled but unassociated dummy STA does not imply starvation.
  • Associated client/AP and failed channel probes produce accurate limited-coverage states.
  • Parked dummy STA and successful retry report full coverage.
  • Hopper interfaces clear when hopping ends.
  • Active runs bind to a newly created scan ID and do not select older nonempty scans.
  • Missing result settlement produces an explicit warning.
  • SVG maps render each populated band, signal colors, escaped metadata, empty data, and archive reports without external assets.
  • Certificate input validation, SAN generation, key/certificate matching, atomic replacement, file modes, active-AP restart, and rollback.
  • Navigation route declarations and legacy redirect.
  • Affected-build matching, safe UCI reconciliation, unknown-build policy, passive health checks, crash threshold, pool quarantine, and circuit-breaker recovery.

Verification on the Pager will include:

  • A 2.4 GHz scan with the enabled but unassociated dummy STA.
  • A scan while an actual STA or AP pins phy0.
  • Opening and printing generated live and archived HTML reports.
  • Generating a certificate and inspecting it with OpenSSL.
  • Generating while Evil Enterprise runs and confirming automatic restart.
  • Exercising a forced restart failure and confirming certificate/AP rollback.
  • Observing pineapd stability and health state after safe reconciliation.
  • Desktop and mobile checks of Recon, Reports, PineAP Handshakes, and Evil Enterprise.

Deployment Order

  1. Recon state and scan-result identity.
  2. Firmware-gated pineapd reconciliation and health containment.
  3. HTML report SVG maps.
  4. Handshakes navigation move.
  5. Certificate generation, permissions, restart, and rollback.
  6. Full local test suite, payload build, device deployment, and on-device verification.

Non-Goals

  • Patching or replacing the proprietary pineapd binary.
  • Enabling SSID-pool broadcast on the known affected daemon.
  • Adding external chart libraries or report assets.
  • Adding client or handshake detail tables to reports in this pass.
  • Creating a CA hierarchy or CA-download workflow; the selected certificate design is a self-signed server certificate.
  • Persisting browser-only signal history in reports.