Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Deploy DeckMD to GitHub Pages

on:
push:
branches: [master]
paths:
- "docs/**"
- ".github/workflows/pages.yml"
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: true

jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v3
with:
path: docs
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
24 changes: 24 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: DeckDoc tests

on:
push:
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Shell syntax
run: bash -n deckdoc.sh setup.sh modules/*.sh probe/*.sh bootprobe/*.sh privileged/* tests/*.sh
- name: Regression and safety suite
run: bash tests/test_runner.sh
- name: Documentation links
run: node tests/validate_links.js
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
logs/
*.log
.env.local
342 changes: 216 additions & 126 deletions README.md

Large diffs are not rendered by default.

169 changes: 78 additions & 91 deletions ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,97 +1,84 @@
# DeckDoc v3.1 — Roadmap: Diagnosis → Safe Remediation

v2.0 added 9 new diagnostic modules covering software/OS failure modes. v3.0 shifts focus from **detecting** failures to **automatically remediating** them — and building the feedback loop that tells you whether the fix worked.

## Implemented (v2.0 / v3.0)

| Module | Detects | Status |
|---|---|---|
| gpu_apu.sh | CPU 400MHz lock, GPU 200MHz SCLK lock, GPU reset outcome | Delivered |
| battery_pmic.sh | Deep discharge, trickle-charge, cell degradation | Delivered |
| thermal_fan.sh | Thermal trip > 90°C, fan failure (0 RPM) | Delivered |
| storage_smart.sh | NVMe SMART health (sudo fallback) | Delivered |
| fs_integrity.sh | BTRFS corruption, EXT4 state (sudo fallback) | Delivered |
| audio_sof.sh | SOF DSP panic, IPC error -22, pipeline resume failure | Delivered |
| display_blackout.sh | eDP disconnection, backlight=0, wrong ACPI sleep state, modesetting errors | Delivered |
| coredump_analysis.sh | systemd-coredump crash counts, signal profiling | Delivered |
| wifi_firmware.sh | ath11k/iwlwifi firmware crash, wlan0 state | Delivered |
| gamescope_session.sh | Session restarts, Vulkan descriptor failures | Delivered |
| memory_swap.sh | OOM events, memory pressure, swap analysis | Delivered |
| steam_client_logs.sh | /tmp/dumps/ crash inventory, stdout errors | Delivered |
| mmc_sd_card.sh | mmc driver errors, ext4 corruption on SD | Delivered |
| acpi_pm_state.sh | Suspend/resume failures, fan-after-wake bug | Delivered |
| dxvk_page_fault.sh | GPU page fault classification (CB/DB/CPF) | Delivered |

## Delivered (v3.0)

| Module | Action | Status |
|---|---|---|
| **rem_audio_sof.sh** | Reload snd_sof_amd_vangogh, verify aplay recovery, PRE_CHECK/BACKUP/EXECUTE/VERIFY/REPORT lifecycle | Delivered |
| deckdoc.sh --fix flag | Runs remediation modules after diagnostics, requires explicit flag | Delivered |
| **rem_display_blackout.sh** | Force one composed Gamescope scanout plane after live-panel prechecks; persistent policy survives per-app convar resets | Delivered |
| display-black signature | Correlate physical black with live eDP, EDID, backlight, CRTC, and multi-plane state | Delivered |
| MangoApp fdinfo signature | Separate MangoApp overlay aborts from Gamescope compositor crashes | Delivered |

## v3.0 — Remediation Modules (Remaining)

### P0 — Must Have

| Module | Trigger | Remediation Action |
|---|---|---|
| **rem_wifi_firmware.sh** | wifi_firmware.sh: wlan0 DOWN or firmware crash | `sudo modprobe -r ath11k_pci && sudo modprobe ath11k_pci`, then verify `ip link show wlan0` shows UP. |
| **rem_coredump_cleanup.sh** | coredump_analysis.sh: >100 dumps | `sudo rm /var/lib/systemd/coredump/*.zst` older than 30 days, report freed space. |
| **rem_gpu_recovery_advice.sh** | gpu_apu.sh: GPU reset failed (hard lock) | Preserve logs, stop remediation, and advise an orderly reboot. DeckDoc will not power-cycle GPU or panel sysfs nodes. |

### P1 — Should Have

| Module | Trigger | Remediation Action |
|---|---|---|
| **rem_oom_protection.sh** | memory_swap.sh: MemAvailable < 1GB | Recommend closing games, list top memory consumers by %mem. Non-destructive advisory only. |
| **rem_fan_recovery.sh** | acpi_pm_state.sh + thermal_fan.sh: fan 0 RPM after resume | `sudo systemctl restart jupiter-fan-control`, verify RPM returns in 10s. |
| **rem_steam_cache.sh** | steam_client_logs.sh: shader cache errors | Identify the affected title cache and offer a recoverable, title-scoped move after confirmation. |
| **rem_btrfs_scrub.sh** | fs_integrity.sh: BTRFS corruption > 0 | `sudo btrfs scrub start /` and report progress. |

### P2 — Nice to Have

| Module | Trigger | Remediation Action |
|---|---|---|
| **rem_battery_calibrate.sh** | battery_pmic.sh: `energy_full` / `energy_full_design` ratio < 60% or voltage desync | Guide user through full discharge/charge calibration cycle. |
| **rem_sd_repair.sh** | mmc_sd_card.sh: EXT4 errors on mmc | Resolve and display the exact unmounted partition, then require explicit confirmation before repair. |
| **rem_gamescope_restart.sh** | gamescope_session.sh: >3 session restarts | Kill stale gamescope processes, restart session cleanly. |
| **rem_dxvk_cache.sh** | dxvk_page_fault.sh: CB/DB page faults in specific game | Clear DXVK state cache for that title ID. |

### Non-Functional Improvements

- `--fix` flag: `./deckdoc.sh --fix` runs all remediation modules after diagnosis
- `--watch` mode: Run in a loop with configurable interval for thermal/memory trend monitoring
- JSON output: Machine-parseable output alongside human-readable logs
- USB bootable mode: Run from recovery media to diagnose unbootable SteamOS installations
- Report upload: Optional `gh issue` creation with diagnostic output attached

## Architecture for Remediation

Each remediation module follows a strict lifecycle:
# DeckDoc v3.2 roadmap — full-system diagnostics and incident response

```
1. PRE_CHECK — Verify the trigger condition still exists (race-safe)
2. BACKUP — Snapshot state before modification (if destructive)
3. EXECUTE — Perform the remediation action (with timeout guard)
4. VERIFY — Confirm the fix worked (re-check trigger condition)
5. REPORT — Log outcome: SUCCESS, FAILED, or PARTIAL
```
DeckDoc's product is evidence, correlation, and safe decision support. It should help a user separate
application/configuration faults, SteamOS/driver faults, accessory or dock faults, and strong hardware
suspicion without turning one log line into a verdict. Automatic remediation stays intentionally
narrow and is not the measure of project coverage.

## Current platform

| Capability | Current state |
|---|---|
| Full report | 17 read-only modules across GPU, power, thermal, storage, filesystems, audio, display, docks, crashes, Wi-Fi, Gamescope, memory, probe history, Steam, microSD, resume, and GPU page faults |
| Incident probe | Opt-in bounded event capture prototype; private, resource-limited, no remediation |
| Dock analysis | USB/Type-C/PD/Alt Mode/display/Ethernet evidence and current-boot path-error correlation |
| DeckDoc Rescue | Read-only collector plus unsigned ArchISO alpha builder for outside-OS comparison |
| DeckMD | Static local-only symptom checker with progressive questions and ranked diagnostic branches |
| Diagnostic wiki | Symptom routes, evidence interpretation, safe contrasts, recovery, and hardware decisions |
| Privileged collection | One-time approved, exact-command, root-owned diagnostic broker prototype |
| Remediation | Two guarded signature-specific paths: SOF reload and Gamescope forced-composition test |

## P0 — trustworthy evidence foundation

### [#15 Model and capability manifest](https://github.com/deucebucket/deckdoc/issues/15)

Identify model, OS/build/slot, drivers, devices, and supported evidence sources before interpreting
their presence or absence. Modules must not assume LCD/OLED behavior, device indices, or driver names.

### [#17 Unified timeline and access ledger](https://github.com/deucebucket/deckdoc/issues/17)

Normalize boot IDs, time scopes, sources, events, and permission/retention state. “No matching event,”
“not retained,” “permission denied,” and “not applicable” must remain different outcomes.

### [#22 Safe redacted bundle and storage-risk gate](https://github.com/deucebucket/deckdoc/issues/22)

Remediation modules never run automatically — they require `--fix` flag or explicit invocation.
Stop normal writes when storage evidence threatens data, then produce separate private/raw and reviewed,
redacted bundles without automatic upload.

## Permanent safety policy
## P1 — productionize the new diagnostic modes

- [#18 Continuous probe](https://github.com/deucebucket/deckdoc/issues/18): measure overhead, harden
suspend/restart/rotation behavior, expand fixtures, and integrate the incident timeline.
- [#16 DeckDoc Rescue](https://github.com/deucebucket/deckdoc/issues/16): pin and reproduce builds,
sign releases, boot-test LCD/OLED, and document authenticated docked-Ethernet support.
- [#20 Dock/USB-C/PD](https://github.com/deucebucket/deckdoc/issues/20): validate official and
third-party paths and generate direct-vs-dock differential summaries.
- [#19 Privileged authorization](https://github.com/deucebucket/deckdoc/issues/19): adversarially
review the allowlist, snapshot integrity, output path, environment, and revocation flow.
- [#23 DeckMD](https://github.com/deucebucket/deckdoc/issues/23): deploy Pages, share a versioned
vocabulary, expand rules, and complete keyboard/touch/responsive/accessibility validation.

## P2 — close broad subsystem gaps

[#21](https://github.com/deucebucket/deckdoc/issues/21) covers three evidence families:

- staged networking from device and association through route, gateway, DNS, VPN/captive portal, and
service reachability;
- Bluetooth, HID, Steam Input, touch, gyro, and controller lifecycle without logging raw input;
- SteamOS update, slot, image, immutable-root, free-space, and previous-image health.

Future coverage should also add structured JSON output, battery trend baselines, performance timelines,
firmware/recovery contrasts, and an upstream-ready issue packet built from the redacted bundle.

## Remediation policy

A fix is eligible only when DeckDoc has a current, model-compatible signature; a bounded reversible
action; a backup where state changes; direct verification; and a documented rollback. Unsupported or
ambiguous cases end in evidence and escalation.

```text
PRE_CHECK -> BACKUP -> EXECUTE -> VERIFY -> REPORT -> documented ROLLBACK
```

- Never change panel voltage, brightness, display power, TDP, clocks, charging behavior, or firmware as a blackout experiment.
- Never attempt a blind GPU/panel sysfs power cycle. Preserve evidence and prefer an orderly reboot when the GPU is genuinely wedged.
- Keep display fixes in the compositor plane-selection layer when evidence shows valid rendered/captured frames but failed physical scanout.
- Require exact device resolution and recoverable backups before filesystem or cache mutation.
DeckDoc will not add generic driver unloads, blind GPU resets, automatic cache deletion, mounted
filesystem repair, clock/voltage/power changes, firmware flashing, or automatic report upload as
routine remedies. Advisory actions such as closing a memory-heavy process are described as advice,
not disguised as remediation modules.

## Completed (v1.0.1)
## Definition of a credible hardware decision

- gpu_apu.sh: dmesg → `journalctl -k -b 0 --priority=err`
- gpu_apu.sh: Separate recoverable vs hard lock classification
- storage_smart.sh: Add `sudo -n` fallback
- fs_integrity.sh: Add `sudo -n` fallback
DeckDoc may report a strong hardware suspicion when a repeatable failure persists across clean
software/configuration tests, outside the installed OS or in firmware where applicable, and across
known-good external parts. Confirmed hardware failure requires direct hardware/service evidence or a
validated repair outcome. A timeout, core dump, persistent BTRFS counter, swap allocation, hot chassis,
zero idle fan, or black screen alone is never confirmation.
26 changes: 26 additions & 0 deletions bootprobe/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# DeckDoc Rescue image (alpha)

DeckDoc Rescue is a separate, bootable evidence environment for a Deck that cannot boot its installed
OS or whose behavior needs an outside-OS comparison. It is not a Valve recovery image and performs no
repair, re-image, filesystem check, unlock, mount, firmware change, or write to the installed disk.

The collector works from a compatible Linux rescue environment today:

```bash
sudo ./deckdoc-rescue-collect.sh --installed-disk /dev/nvme0n1 --output-dir /path/to/removable-media
```

The alpha ArchISO builder requires an Arch Linux build host with the official `archiso` package:

```bash
sudo ./build-rescue-image.sh ./out
```

The resulting rolling, unsigned image is for controlled development testing. Do not publish it as a
trusted release until package versions are pinned, artifacts are reproducible and signed, checksums are
published, and it has boot/hardware validation on both Jupiter LCD and Galileo OLED Decks.

For remote operation, use authenticated SSH over docked Ethernet. The image intentionally does not
enable an unauthenticated web server or a default password. Direct USB gadget networking is future,
capability-gated work: Linux requires a USB Device Controller plus configfs gadget support, and the
transport must never be assumed from the connector alone.
39 changes: 39 additions & 0 deletions bootprobe/build-rescue-image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bash
set -euo pipefail

if [ "$(id -u)" -ne 0 ]; then
echo "Run the ArchISO build with sudo on an Arch Linux build host." >&2
exit 1
fi
if ! command -v mkarchiso >/dev/null 2>&1; then
echo "mkarchiso is required. Install the official Arch Linux archiso package." >&2
exit 1
fi

SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
RELENG_PROFILE="${DECKDOC_ARCHISO_PROFILE:-/usr/share/archiso/configs/releng}"
OUTPUT_DIR="${1:-${SOURCE_DIR}/out}"
if [ ! -d "$RELENG_PROFILE" ]; then
echo "ArchISO releng profile not found: ${RELENG_PROFILE}" >&2
exit 1
fi
mkdir -p "$OUTPUT_DIR"
OUTPUT_DIR=$(readlink -f "$OUTPUT_DIR")
BUILD_ROOT=$(mktemp -d -p /var/tmp deckdoc-rescue-build.XXXXXX)
case "$BUILD_ROOT" in /var/tmp/deckdoc-rescue-build.*) ;; *) exit 1 ;; esac
trap 'rm -rf -- "$BUILD_ROOT"' EXIT
PROFILE="${BUILD_ROOT}/profile"
cp -a "$RELENG_PROFILE" "$PROFILE"

install -d -m 755 "${PROFILE}/airootfs/usr/local/bin" "${PROFILE}/airootfs/root"
install -m 755 "${SOURCE_DIR}/deckdoc-rescue-collect.sh" "${PROFILE}/airootfs/usr/local/bin/deckdoc-rescue-collect"
install -m 644 "${SOURCE_DIR}/README.md" "${PROFILE}/airootfs/root/DeckDoc-Rescue-README.md"

for package in smartmontools nvme-cli btrfs-progs e2fsprogs usbutils pciutils iw ethtool openssh; do
if ! grep -qx "$package" "${PROFILE}/packages.x86_64"; then printf '%s\n' "$package" >> "${PROFILE}/packages.x86_64"; fi
done

echo "Building unsigned DeckDoc Rescue alpha image with the current Arch repositories."
echo "The resulting ISO is not a Valve recovery image and must not be presented as one."
mkarchiso -v -r -w "${BUILD_ROOT}/work" -o "$OUTPUT_DIR" "$PROFILE"
echo "Image written under ${OUTPUT_DIR}. Verify its checksum and boot-test both LCD and OLED before release."
Loading
Loading