diff --git a/.bot_directives/README.scm b/.bot_directives/README.scm new file mode 100644 index 0000000..adda44b --- /dev/null +++ b/.bot_directives/README.scm @@ -0,0 +1,9 @@ +;; SPDX-License-Identifier: PMPL-1.0-or-later +;; .bot_directives — per-bot rules and constraints +;; Media-Type: application/vnd.bot-directives+scm + +(bot-directives + (version "1.0") + (notes + "Repo-specific bot constraints." + "Bots must follow these directives in addition to global policies.")) diff --git a/.bot_directives/echidnabot.scm b/.bot_directives/echidnabot.scm new file mode 100644 index 0000000..6a42426 --- /dev/null +++ b/.bot_directives/echidnabot.scm @@ -0,0 +1,7 @@ +;; SPDX-License-Identifier: PMPL-1.0-or-later +(bot-directive + (bot "echidnabot") + (scope "formal verification and fuzzing") + (allow ("analysis" "fuzzing" "proof checks")) + (deny ("write to core modules" "write to bindings")) + (notes "May open findings; code changes require explicit approval")) diff --git a/.bot_directives/finishbot.scm b/.bot_directives/finishbot.scm new file mode 100644 index 0000000..4ba92f3 --- /dev/null +++ b/.bot_directives/finishbot.scm @@ -0,0 +1,7 @@ +;; SPDX-License-Identifier: PMPL-1.0-or-later +(bot-directive + (bot "finishbot") + (scope "release readiness") + (allow ("release checklists" "docs updates" "metadata fixes")) + (deny ("code changes without approval")) + (notes "Focus on polish, licensing, and packaging")) diff --git a/.bot_directives/glambot.scm b/.bot_directives/glambot.scm new file mode 100644 index 0000000..6261f4e --- /dev/null +++ b/.bot_directives/glambot.scm @@ -0,0 +1,7 @@ +;; SPDX-License-Identifier: PMPL-1.0-or-later +(bot-directive + (bot "glambot") + (scope "presentation + accessibility") + (allow ("docs" "readme badges" "ui/accessibility suggestions")) + (deny ("logic changes")) + (notes "Edits limited to presentation layers")) diff --git a/.bot_directives/rhodibot.scm b/.bot_directives/rhodibot.scm new file mode 100644 index 0000000..ba52990 --- /dev/null +++ b/.bot_directives/rhodibot.scm @@ -0,0 +1,7 @@ +;; SPDX-License-Identifier: PMPL-1.0-or-later +(bot-directive + (bot "rhodibot") + (scope "rsr-compliance") + (allow ("metadata" "docs" "repo-structure checks")) + (deny ("destructive edits without approval")) + (notes "Auto-fix allowed only for formatting in docs and metadata")) diff --git a/.bot_directives/robot-repo-automaton.scm b/.bot_directives/robot-repo-automaton.scm new file mode 100644 index 0000000..e053cd2 --- /dev/null +++ b/.bot_directives/robot-repo-automaton.scm @@ -0,0 +1,7 @@ +;; SPDX-License-Identifier: PMPL-1.0-or-later +(bot-directive + (bot "robot-repo-automaton") + (scope "automated fixes") + (allow ("low-risk automated edits")) + (deny ("core logic changes without approval")) + (notes "Only apply fixes backed by explicit rule approval")) diff --git a/.bot_directives/seambot.scm b/.bot_directives/seambot.scm new file mode 100644 index 0000000..620a93a --- /dev/null +++ b/.bot_directives/seambot.scm @@ -0,0 +1,7 @@ +;; SPDX-License-Identifier: PMPL-1.0-or-later +(bot-directive + (bot "seambot") + (scope "integration health") + (allow ("analysis" "contract checks" "docs updates")) + (deny ("code changes without approval")) + (notes "May add integration test suggestions")) diff --git a/.bot_directives/sustainabot.scm b/.bot_directives/sustainabot.scm new file mode 100644 index 0000000..b402db1 --- /dev/null +++ b/.bot_directives/sustainabot.scm @@ -0,0 +1,7 @@ +;; SPDX-License-Identifier: PMPL-1.0-or-later +(bot-directive + (bot "sustainabot") + (scope "eco/economic standards") + (allow ("analysis" "reporting" "docs updates")) + (deny ("code changes without approval")) + (notes "Focus on measurement and recommendations")) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3575cd9..23c1e39 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Initialize CodeQL uses: github/codeql-action/init@662472033e021d55d94146f66f6058822b0b39fd # v3.28.1 diff --git a/.github/workflows/guix-nix-policy.yml b/.github/workflows/guix-nix-policy.yml index ed6f0c5..3e1103a 100644 --- a/.github/workflows/guix-nix-policy.yml +++ b/.github/workflows/guix-nix-policy.yml @@ -10,7 +10,7 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Enforce Guix primary / Nix fallback run: | # Check for package manager files diff --git a/.github/workflows/hypatia-scan.yml b/.github/workflows/hypatia-scan.yml index f2bf132..5158103 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -20,7 +20,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 with: fetch-depth: 0 # Full history for better pattern analysis diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml index 58f0d38..437010a 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest if: vars.GITLAB_MIRROR_ENABLED == 'true' steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 with: fetch-depth: 0 @@ -32,7 +32,7 @@ jobs: runs-on: ubuntu-latest if: vars.BITBUCKET_MIRROR_ENABLED == 'true' steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 with: fetch-depth: 0 @@ -50,7 +50,7 @@ jobs: runs-on: ubuntu-latest if: vars.CODEBERG_MIRROR_ENABLED == 'true' steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 with: fetch-depth: 0 @@ -68,7 +68,7 @@ jobs: runs-on: ubuntu-latest if: vars.SOURCEHUT_MIRROR_ENABLED == 'true' steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 with: fetch-depth: 0 @@ -86,7 +86,7 @@ jobs: runs-on: ubuntu-latest if: vars.DISROOT_MIRROR_ENABLED == 'true' steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 with: fetch-depth: 0 @@ -104,7 +104,7 @@ jobs: runs-on: ubuntu-latest if: vars.GITEA_MIRROR_ENABLED == 'true' steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 with: fetch-depth: 0 @@ -122,7 +122,7 @@ jobs: runs-on: ubuntu-latest if: vars.RADICLE_MIRROR_ENABLED == 'true' steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 with: fetch-depth: 0 diff --git a/.github/workflows/npm-bun-blocker.yml b/.github/workflows/npm-bun-blocker.yml index 292fd29..2d2783b 100644 --- a/.github/workflows/npm-bun-blocker.yml +++ b/.github/workflows/npm-bun-blocker.yml @@ -10,7 +10,7 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Block npm/bun run: | if [ -f "package-lock.json" ] || [ -f "bun.lockb" ] || [ -f ".npmrc" ]; then diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 6a9a52f..fef1c5c 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -11,7 +11,7 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Check file permissions run: | @@ -43,7 +43,7 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Check documentation run: | MISSING="" diff --git a/.github/workflows/rsr-antipattern.yml b/.github/workflows/rsr-antipattern.yml index 86a006a..a001dcd 100644 --- a/.github/workflows/rsr-antipattern.yml +++ b/.github/workflows/rsr-antipattern.yml @@ -22,7 +22,7 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Check for TypeScript run: | diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index de8af40..f5a22f8 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -16,7 +16,7 @@ jobs: security-events: write id-token: write steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index 051fecf..5ad45b5 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -13,7 +13,7 @@ jobs: trufflehog: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 with: fetch-depth: 0 # Full history for scanning @@ -25,7 +25,7 @@ jobs: gitleaks: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 with: fetch-depth: 0 @@ -39,7 +39,7 @@ jobs: runs-on: ubuntu-latest if: hashFiles('**/Cargo.toml') != '' steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 - name: Check for hardcoded secrets in Rust run: | diff --git a/.github/workflows/security-policy.yml b/.github/workflows/security-policy.yml index 95bf53b..d4e9701 100644 --- a/.github/workflows/security-policy.yml +++ b/.github/workflows/security-policy.yml @@ -10,7 +10,7 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Security checks run: | FAILED=false diff --git a/.github/workflows/ts-blocker.yml b/.github/workflows/ts-blocker.yml index f2762d9..5c34a58 100644 --- a/.github/workflows/ts-blocker.yml +++ b/.github/workflows/ts-blocker.yml @@ -10,7 +10,7 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Block new TypeScript/JavaScript run: | NEW_TS=$(git diff --name-only --diff-filter=A HEAD~1 2>/dev/null | grep -E '\.(ts|tsx)$' | grep -v '\.gen\.' || true) diff --git a/.github/workflows/wellknown-enforcement.yml b/.github/workflows/wellknown-enforcement.yml index 954f303..8e270df 100644 --- a/.github/workflows/wellknown-enforcement.yml +++ b/.github/workflows/wellknown-enforcement.yml @@ -23,7 +23,7 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: RFC 9116 security.txt validation run: | diff --git a/.github/workflows/workflow-linter.yml b/.github/workflows/workflow-linter.yml index 8cb3e7f..16cd6bb 100644 --- a/.github/workflows/workflow-linter.yml +++ b/.github/workflows/workflow-linter.yml @@ -22,7 +22,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Check SPDX Headers run: | @@ -72,7 +72,7 @@ jobs: echo "$unpinned" echo "" echo "Replace version tags with SHA pins, e.g.:" - echo " uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1" + echo " uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.1.1" exit 1 fi echo "All actions are SHA-pinned" diff --git a/.gitignore b/.gitignore index 0338461..b1f2c7a 100644 --- a/.gitignore +++ b/.gitignore @@ -77,3 +77,14 @@ htmlcov/ /tmp/ *.tmp *.bak + +# Crash recovery artifacts +ai-cli-crash-capture/ +target/ +node_modules/ +_build/ +deps/ +.elixir_ls/ +.cache/ +build/ +dist/ diff --git a/.machine_readable/ECOSYSTEM.scm b/.machine_readable/ECOSYSTEM.scm index f5d686f..0c7fe66 100644 --- a/.machine_readable/ECOSYSTEM.scm +++ b/.machine_readable/ECOSYSTEM.scm @@ -1,20 +1,8 @@ ;; SPDX-License-Identifier: PMPL-1.0-or-later -;; ECOSYSTEM.scm - Ecosystem position for bgp-backbone-lab -;; Media-Type: application/vnd.ecosystem+scm - -(ecosystem - (version "1.0") - (name "bgp-backbone-lab") - (type "") - (purpose "") - - (position-in-ecosystem - (category "") - (subcategory "") - (unique-value ())) - - (related-projects ()) - - (what-this-is ()) - - (what-this-is-not ())) +(ecosystem (metadata (version "0.2.0") (last-updated "2026-02-08")) + (project (name "bgp-backbone-lab") (purpose "eBGP backbone simulation with containerlab") (role network-lab)) + (flatracoon-integration + (parent "flatracoon/netstack") + (layer network) + (depended-on-by ()) + (depends-on ()))) diff --git a/0-AI-MANIFEST.a2ml b/0-AI-MANIFEST.a2ml new file mode 100644 index 0000000..d28ef12 --- /dev/null +++ b/0-AI-MANIFEST.a2ml @@ -0,0 +1,114 @@ +# STOP - CRITICAL READING REQUIRED + +**THIS FILE MUST BE READ FIRST BY ALL AI AGENTS** + +## WHAT IS THIS? + +This is the AI manifest for **bgp-backbone-lab**. It declares: +- Canonical file locations (where things MUST be, and nowhere else) +- Critical invariants (rules that must NEVER be violated) +- Repository structure and organization + +## CANONICAL LOCATIONS (UNIVERSAL RULE) + +### Machine-Readable Metadata: `.machine_readable/` ONLY + +These 6 SCM files MUST exist in `.machine_readable/` directory ONLY: +1. **STATE.scm** - Project state, progress, blockers +2. **META.scm** - Architecture decisions, governance +3. **ECOSYSTEM.scm** - Position in ecosystem, relationships +4. **AGENTIC.scm** - AI agent interaction patterns +5. **NEUROSYM.scm** - Neurosymbolic integration config +6. **PLAYBOOK.scm** - Operational runbook + +**CRITICAL:** If ANY of these files exist in the root directory, this is an ERROR. + +### Bot Directives: `.bot_directives/` ONLY + +Bot-specific instructions for: +- rhodibot - Git operations +- echidnabot - Code quality +- sustainabot - Dependency updates +- glambot - Documentation +- seambot - Integration +- finishbot - Task completion + +### Agent Instructions + +- `.claude/CLAUDE.md` - Claude-specific patterns (if exists) +- `0-AI-MANIFEST.a2ml` - THIS FILE (universal entry point) + +## CORE INVARIANTS + +1. **No SCM duplication** - Root must NOT contain STATE.scm, META.scm, etc. +2. **Single source of truth** - `.machine_readable/` is authoritative +3. **No stale metadata** - If root SCMs exist, they are OUT OF DATE +4. **License consistency** - All code PMPL-1.0-or-later unless platform requires MPL-2.0 +5. **Author attribution** - Always "Jonathan D.A. Jewell " + +## REPOSITORY STRUCTURE + +This repo contains: + +``` +bgp-backbone-lab/ +├── 0-AI-MANIFEST.a2ml # THIS FILE (start here) +├── README.md # Project overview +├── [your source files] # Main code +├── .machine_readable/ # SCM files (6 files) +│ ├── STATE.scm +│ ├── META.scm +│ ├── ECOSYSTEM.scm +│ ├── AGENTIC.scm +│ ├── NEUROSYM.scm +│ └── PLAYBOOK.scm +└── .bot_directives/ # Bot instructions +``` + +## SESSION STARTUP CHECKLIST + +Read THIS file (0-AI-MANIFEST.a2ml) first +Understand canonical locations (.machine_readable/, .bot_directives/) +Know the invariants (no SCM duplication, etc.) +Check for MCP enforcement (if applicable) +Read `.machine_readable/STATE.scm` for current status +Read `.machine_readable/AGENTIC.scm` for interaction patterns + +## LIFECYCLE HOOKS + +### on-enter (Session Start) + +When starting a new session: + +1. Read and acknowledge this manifest +2. Log session start (optional but recommended) + - Format: `[YYYY-MM-DD HH:MM:SS] Session started: [agent-name]` + - Location: `.machine_readable/session-log.txt` +3. Read `.machine_readable/STATE.scm` +4. Check for blockers +5. State understanding of canonical locations + +### on-exit (Session End) + +When ending a session: + +1. Update `.machine_readable/STATE.scm` if changes made +2. Log session end (optional but recommended) + - Format: `[YYYY-MM-DD HH:MM:SS] Session ended: [summary]` + - Location: `.machine_readable/session-log.txt` +3. Document new blockers +4. Summarize outcomes + +## ATTESTATION PROOF + +After reading this file, demonstrate understanding by stating: + +**"I have read the AI manifest. SCM files are located in `.machine_readable/` ONLY, bot directives in `.bot_directives/`, and I will not create duplicate files in the root directory."** + +## META + +- **Format Version:** 1.0.0 +- **Created:** 2026-02-08 +- **Maintained By:** Jonathan D.A. Jewell +- **License:** PMPL-1.0-or-later +- **Protocol:** https://github.com/hyperpolymath/0-ai-gatekeeper-protocol diff --git a/ai-cli-crash-capture/README.adoc b/ai-cli-crash-capture/README.adoc deleted file mode 100644 index 2fcda87..0000000 --- a/ai-cli-crash-capture/README.adoc +++ /dev/null @@ -1,39 +0,0 @@ -= AI CLI Crash Capture -:revdate: 2026-01-17 - -Lightweight crash recovery helpers for CLI workflows. - -== Quick start - -[source,bash] ----- -./recoverer-setup.sh -systemctl --user enable --now terminal-recoverer.service -systemctl --user enable --now terminal-recoverer-coredump.service ----- - -== What it does - -- Creates a persistent tmux session named `recovery`. -- Flushes shell history on each prompt (bash). -- Optional full session logging with `script`. -- Watches for `systemd-coredump` events and captures diagnostics. - -== Optional logging - -Enable per-session logging (bash): - -[source,bash] ----- -export ENABLE_TERMINAL_LOGGING=1 ----- - -== Outputs - -- Session logs: `~/Documents/terminal-logs/` -- Crash captures: `~/Documents/crash-captures/` - -== Notes - -- The coredump watcher relies on `journalctl` access to `systemd-coredump`. - If captures are empty, add your user to the `systemd-journal` group and re-login. diff --git a/ai-cli-crash-capture/bash/recoverer.sh b/ai-cli-crash-capture/bash/recoverer.sh deleted file mode 100644 index 115df0f..0000000 --- a/ai-cli-crash-capture/bash/recoverer.sh +++ /dev/null @@ -1,7 +0,0 @@ -# Flush history immediately to reduce loss on crashes. -PROMPT_COMMAND="history -a${PROMPT_COMMAND:+; $PROMPT_COMMAND}" - -# Optional terminal logging. Enable with: export ENABLE_TERMINAL_LOGGING=1 -if [[ ${ENABLE_TERMINAL_LOGGING-} == "1" ]]; then - "$HOME/.local/bin/terminal-recoverer" log-shell -fi diff --git a/ai-cli-crash-capture/recoverer-setup.sh b/ai-cli-crash-capture/recoverer-setup.sh deleted file mode 100755 index ccd7c0b..0000000 --- a/ai-cli-crash-capture/recoverer-setup.sh +++ /dev/null @@ -1,155 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# Install paths -BIN_DIR="$HOME/.local/bin" -BASHRC_D="$HOME/.bashrc.d" -SYSTEMD_USER_DIR="$HOME/.config/systemd/user" -LOG_DIR="$HOME/Documents/terminal-logs" -CRASH_DIR="$HOME/Documents/crash-captures" - -mkdir -p "$BIN_DIR" "$BASHRC_D" "$SYSTEMD_USER_DIR" "$LOG_DIR" "$CRASH_DIR" - -cat > "$BIN_DIR/terminal-recoverer" <<'SCRIPT' -#!/usr/bin/env bash -set -euo pipefail - -cmd=${1:-ensure} - -case "$cmd" in - ensure) - mkdir -p "$HOME/Documents/terminal-logs" - if command -v tmux >/dev/null 2>&1; then - tmux has-session -t recovery 2>/dev/null || tmux new-session -d -s recovery - fi - ;; - log-shell) - # Only run in interactive terminals, and avoid recursion. - if [[ -t 0 && -n ${PS1-} && -z ${RECOVERER_LOGGING-} ]]; then - export RECOVERER_LOGGING=1 - mkdir -p "$HOME/Documents/terminal-logs" - if command -v script >/dev/null 2>&1; then - script -q -f "$HOME/Documents/terminal-logs/terminal-$(date +%F-%H%M%S).log" - fi - fi - ;; - watch-coredump) - # Best-effort watcher for systemd-coredump messages. - mkdir -p "$HOME/Documents/crash-captures" - if command -v journalctl >/dev/null 2>&1; then - journalctl -f -o cat SYSLOG_IDENTIFIER=systemd-coredump | \ - while IFS= read -r line; do - ts=$(date +%F-%H%M%S) - dir="$HOME/Documents/crash-captures/coredump-$ts" - mkdir -p "$dir" - printf "%s\n" "$line" > "$dir/journal-line.txt" - { - echo "time=$ts" - echo "uname=$(uname -a)" - echo "uptime=$(uptime -p)" - } > "$dir/meta.txt" - journalctl --since "2 min ago" -p err..alert --no-pager > "$dir/journal-errors.txt" 2>/dev/null || true - journalctl --since "2 min ago" -k -p err..alert --no-pager > "$dir/journal-kernel-errors.txt" 2>/dev/null || true - journalctl --user --since "2 min ago" -p err..alert --no-pager > "$dir/journal-user-errors.txt" 2>/dev/null || true - journalctl --since "2 min ago" SYSLOG_IDENTIFIER=systemd-coredump --no-pager > "$dir/coredump-journal.txt" 2>/dev/null || true - if command -v coredumpctl >/dev/null 2>&1; then - coredumpctl --since "2 min ago" --no-pager > "$dir/coredumpctl.txt" 2>/dev/null || true - fi - if command -v dmesg >/dev/null 2>&1; then - dmesg -T > "$dir/dmesg.txt" 2>/dev/null || true - fi - if command -v top >/dev/null 2>&1; then - top -b -n 1 > "$dir/top.txt" 2>/dev/null || true - fi - if command -v ps >/dev/null 2>&1; then - ps auxww > "$dir/ps.txt" 2>/dev/null || true - fi - if command -v free >/dev/null 2>&1; then - free -h > "$dir/free.txt" 2>/dev/null || true - fi - if command -v df >/dev/null 2>&1; then - df -h > "$dir/df.txt" 2>/dev/null || true - fi - if command -v lsblk >/dev/null 2>&1; then - lsblk > "$dir/lsblk.txt" 2>/dev/null || true - fi - if command -v systemctl >/dev/null 2>&1; then - systemctl --user --no-pager --failed > "$dir/systemd-user-failed.txt" 2>/dev/null || true - fi - done - fi - ;; - *) - echo "usage: terminal-recoverer [ensure|log-shell|watch-coredump]" >&2 - exit 2 - ;; -esac -SCRIPT - -chmod +x "$BIN_DIR/terminal-recoverer" - -cat > "$BASHRC_D/recoverer.sh" <<'SCRIPT' -# Flush history immediately to reduce loss on crashes. -PROMPT_COMMAND="history -a${PROMPT_COMMAND:+; $PROMPT_COMMAND}" - -# Optional terminal logging. Enable with: export ENABLE_TERMINAL_LOGGING=1 -if [[ ${ENABLE_TERMINAL_LOGGING-} == "1" ]]; then - "$HOME/.local/bin/terminal-recoverer" log-shell -fi -SCRIPT - -cat > "$SYSTEMD_USER_DIR/terminal-recoverer.service" <<'UNIT' -[Unit] -Description=Terminal recoverer (tmux session + log dir) -After=default.target - -[Service] -Type=oneshot -ExecStart=%h/.local/bin/terminal-recoverer ensure - -[Install] -WantedBy=default.target -UNIT - -cat > "$SYSTEMD_USER_DIR/terminal-recoverer-coredump.service" <<'UNIT' -[Unit] -Description=Terminal recoverer coredump watcher (best-effort) -After=default.target - -[Service] -ExecStart=%h/.local/bin/terminal-recoverer watch-coredump -Restart=always -RestartSec=2 - -[Install] -WantedBy=default.target -UNIT - -cat > "$HOME/terminal-recoverer-HOWTO.txt" <<'TXT' -Terminal recoverer installed. - -Start at login (systemd user): - systemctl --user enable --now terminal-recoverer.service - -Enable coredump watcher (best-effort): - systemctl --user enable --now terminal-recoverer-coredump.service - -Optional session logging (bash): - export ENABLE_TERMINAL_LOGGING=1 - # add to ~/.bashrc or ~/.bash_profile if you want it always on - -Using tmux recovery session: - tmux attach -t recovery - -Logs: - ~/Documents/terminal-logs/ -Crash captures: - ~/Documents/crash-captures/ -TXT - -echo "Installed:" -echo "- $BIN_DIR/terminal-recoverer" -echo "- $BASHRC_D/recoverer.sh" -echo "- $SYSTEMD_USER_DIR/terminal-recoverer.service" -echo "- $SYSTEMD_USER_DIR/terminal-recoverer-coredump.service" -echo "- $HOME/terminal-recoverer-HOWTO.txt" diff --git a/ai-cli-crash-capture/systemd/terminal-recoverer-coredump.service b/ai-cli-crash-capture/systemd/terminal-recoverer-coredump.service deleted file mode 100644 index 6551658..0000000 --- a/ai-cli-crash-capture/systemd/terminal-recoverer-coredump.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Terminal recoverer coredump watcher (best-effort) -After=default.target - -[Service] -ExecStart=%h/.local/bin/terminal-recoverer watch-coredump -Restart=always -RestartSec=2 - -[Install] -WantedBy=default.target diff --git a/ai-cli-crash-capture/systemd/terminal-recoverer.service b/ai-cli-crash-capture/systemd/terminal-recoverer.service deleted file mode 100644 index 331e1b0..0000000 --- a/ai-cli-crash-capture/systemd/terminal-recoverer.service +++ /dev/null @@ -1,10 +0,0 @@ -[Unit] -Description=Terminal recoverer (tmux session + log dir) -After=default.target - -[Service] -Type=oneshot -ExecStart=%h/.local/bin/terminal-recoverer ensure - -[Install] -WantedBy=default.target