Go.Sign sh sibling -- Mac/Linux parity — Board 98 (14 pts, 4 phases). Closes the first-commit wall on macOS and every Linux distro by mirroring Board 97's Windows pattern in bash:
metal: (1) new Go.Sign.sh — bash port of Go.Sign.ps1, identical algorithm and idempotency; uses gh api user --jq '.email' instead of a separate jq dependency; gpg path probe walks /opt/homebrew/bin (Apple Silicon brew) -> /usr/local/bin (Intel brew / Linux) -> /usr/bin (system). ASCII + LF clean per Project DoD P1 + P2; bash -n parses cleanly; smoke-tested on Windows via Git Bash before any commit. (2) Go.Fe.sh Step 2 calls bash Go.Sign.sh instead of cp .gitconfig + sed -- the uname-branched gpg-path sed is gone, Go.Sign handles it.
install.sh: Step 5b calls Go.Sign.sh < /dev/tty after Fe (preserves stdin for the gh auth refresh interactive flow when scope grant is needed); Step 5c runs git ls-remote origin in $METAL_DIR as the fresh-install smoke. Same defensive pattern as the Windows version: failure of either step warns but does not block Be launch.
Empirical fresh-Mac and fresh-Linux VM tests outstanding (Joey's hands; needs VMs to actually validate). Until then, the bash sibling is verified by code-path symmetry to the Windows pattern + algorithmic smoke on this laptop.
r813 2026-05-04
Go.Sign install integration — Board 97 (17 pts, 5 phases). Closes the first-commit wall every fresh laptop hit. Root cause: shipped .gitconfig hardcoded signingkey = B7213318225D642A with commit.gpgsign = true — the key didn't exist on any new laptop, so the first git commit failed with "gpg failed to sign the data." Fix is split across two repos:
metal: (1) new Go.Sign.ps1 — idempotent script that reads identity from gh api user, finds or generates a per-laptop GPG key, registers via gh gpg-key add, writes git config --global, smoke-tests with an empty signed commit; (2) Go.Fe.ps1 Step 2 calls Go.Sign.ps1 instead of cp .gitconfig; (3) .gitconfig stripped to [filter "lfs"] only — identity moved to per-machine git config --global; (4) be/tools/pre-commit.hook as canonical hook source; go.ps1 + go.sh SHA256-compare and self-install on every launch (Project DoD P4 promise kept); (5) Go.Fe.ps1 Python install now filters MS Store stub at WindowsApps and verifies version output (mirrors the npm fix at line 138).
install.bat: Step 5b calls Go.Sign.bat after Fe (gh authed, identity setup); Step 5c runs git ls-remote origin in C:\metal as fresh-install smoke verifying HTTPS push auth. Combined with Go.Sign's signed-commit smoke, install reports "first commit will land" before launching Be. Replaces the manual handoff documented at setup.html. Empirical proof: this entry exists because the very commit that documented the design landed signed on a laptop where the previous attempt had failed.
r798 2026-05-02
install.bat v3.5 — cd + go at end of install — Board 96 (3 pts). User-driven hotfix: the success path at the end of install.bat now uses cd /d C:\metal + call go.bat, identical to the recovery instruction the script prints on every error path. Replaces the older pushd C:\metal / call "C:\metal\go.bat" / popd sequence. Same end result, simpler control flow, one mental model for both success and recovery
r794 2026-05-02
install.bat v3.4 — CRLF + inline ensure_claude (regression fix) — Board 95 (8 pts). v3.3 introduced a :ensure_claude subroutine that on real fresh installs aborted with "system cannot find batch label ensure_claude" mid-execution. Root cause: cmd.exe's label-stack frame was evicted from the parser cache when npm install (an external .cmd) ran from inside call :ensure_claude on an LF-only file. Three coordinated changes restore deterministic behavior: (1) :ensure_claude body is now inlined directly into Step 6 main flow — no subroutine, no label to re-resolve; (2) npm install -g changed to call npm install -g for explicit child-batch invocation; (3) install.bat converted from LF-only (194 LF) to CRLF (196 CRLF), the standard Windows .bat convention. Other .bat files in the repo keep LF for now — they have only simple linear flow and are unaffected
r790 2026-05-02
install.bat v3.3 — Claude install hardening — Board 94 (11 pts). Two coordinated changes guarantee Claude Code is installed and callable by the time install.bat exits. Primary fix in Go.Fe.ps1 Phase 2: prepend C:\Program Files\nodejs to $env:PATH, resolve npm.cmd to a concrete path via probe + Get-Command fallback, loud failure when npm cannot be found, invoke RunInstall with the quoted full $npmCmd path. Fixes the silent npm install -g claude failure on fresh installs where Phase 1's PATH refresh missed the just-installed Node entry. Contract enforcement in install.bat: new :ensure_claude subroutine called before go.bat; probes claude, refreshes PATH, retries; if still missing, runs npm install -g @anthropic-ai/claude-code directly with visible output; if that fails, hard-fails with a one-line recovery command. install.bat now refuses to launch Be unless claude is callable
r788 2026-05-01
install.bat v3.2 — refresh_path PATH expansion hotfix — Board 93 (6 pts). Bug: :refresh_path read HKLM\...\Environment\Path via reg query, which returns the raw REG_EXPAND_SZ string with literal %SystemRoot% tokens. set "PATH=..." stored those literals; cmd.exe does not expand %var% tokens when walking PATH for command resolution, so powershell.exe (at %SystemRoot%\System32\WindowsPowerShell\v1.0\) became unfindable, killing Step 6's go.bat launcher with "powershell is not recognized." Fix: replace reg query with PowerShell [Environment]::GetEnvironmentVariable('Path','Machine') which expands REG_EXPAND_SZ via the Win32 API; PATH now stores fully expanded literals like C:\Windows\System32
r784 2026-05-01
install.bat v3.1 — winget bootstrap — Board 92 (9 pts). Fresh Windows installs without winget no longer die on Step 1. New :Step 0 ensure_winget guard at the top of install.bat: where winget detection, then PowerShell Invoke-WebRequest aka.ms/getwinget + Add-AppxPackage bootstrap, then re-check and hard-fail with the manual URL on bootstrap failure. Existing winget-based flow below is unchanged. install.sh untouched (Mac/Linux paths already handle missing package managers per platform). Three em-dashes in install.bat replaced with ASCII hyphens (Project DoD P1)
~GO chain end-to-end — first full-lifecycle ~GO hotfix on metal: ~d design (winget bootstrap vs direct .exe fallback — picked bootstrap), ~p plan, ~e estimate (Board 92, 3 items, 9 pts), ~b build, ~t test, ~s ship. Cross-repo: artifacts in metal/be/, code change in joeycastillo.us/metal/install.bat (commit 59ff659)
r763 2026-04-24
~design command (~d) — Boards 90 + 91 (29 pts). New first-class thinking tool, typically after ~i and before ~p. Produces an 8-section design artifact: Subject+Intent, Discovery, Naming Pass, Shape, Choices+Consequences, Escape Routes, Pure Metal Test, First Move. Template at be/designs/_template.html; convention in be/docs/conventions.md § Design Report Convention; full spec in be/docs/commands.md § ~d — Design
~delete killed — ~d reassigned from delete to design cleanly. Removals of code/files are sub-acts of ~u (update) or ~f (fix); a standalone verb made them feel like isolated acts when they're not. Historical ~d ✅ items on past boards stay as frozen history
~GO chain gains ~I ~D at front — full lifecycle default is now ~I ~D ~P ~E /~B ~T/ ~S ~R: inspect → design → plan → estimate → build/test loop → ship → retro. ~HOTFIX stays ~I ~P /~T ~F/ ~S ~R (emergency path, fix is the design). Flow line rewritten; "remove from" verb retired; CLAUDE.md folder tree adds designs/
Report pop rule + pop.py helper — ~HOTFIX. The old "Launch rule" was aspirational prose that never fired. Replaced with be/tools/pop (Python + .bat/.sh wrappers) that reads be/config.json and dispatches to os.startfile / open / xdg-open. Universal coverage: every tilde command that produces a report ends with be/tools/pop <path>, or --final at chain end. Four modes verified: silent, print, preview+each, preview+final (queue via be/.chain_reports, drain on --final)
be/config.json explicit — defaults file committed so runtime state is visible and auditable. reports.display: preview, reports.chain_timing: each. Tunable via ~config reports.display <silent|print|preview> and ~config reports.chain_timing <each|final>
Site catch-up pending — this entry covers today's ship; prior revisions r507–r762 are still absent from history/reference and noted as a ~r follow-up
r506 2026-04-11
Prompt capture layer — Board 51 (14 pts). New UserPromptSubmit hook in settings.json pipes every typed prompt through be/tools/capture_prompt.py, which redacts 12 secret patterns (sk-, ghp_, xox[baprs]-, AKIA, AIza, password=, …) before appending one JSON row per prompt to be/prompts.jsonl. Stdlib-only, silent-failure on any exception so capture never blocks user input
Unified telemetry viewer — Board 52 (14 pts). be/telemetry.html now renders a merged timeline of command telemetry + user prompts. New Type filter (All / Commands / Prompts), purple-bordered prompt entries with [REDACTED] badges, interleaved newest-first via a shared _sortKey. 13 structural + 5 runtime simulation checks all pass
Public telemetry page — Board 53 (13 pts). New /metal/telemetry.html viewer on the public site, matching the #0a0a0a / #4ec9b0 site aesthetic. Built by be/tools/build_site_telemetry.py (stdlib Python), which inlines telemetry.json + prompts.jsonl at deploy time. Stats grid (commands / prompts / redacted / days), Type filter, site-wide nav link added across index / history / architecture / reference / setup
~s deploy chain — self-healing site telemetry — be/docs/conventions.md now codifies build_site_telemetry.py as step 2 of the deploy chain, so the public viewer converges with the private one at every ship. Idempotent, skip-when-absent, no dependency footprint added
Ship + verify — Board 54 (13 pts). 35/35 smoke-test checks green on the public viewer (structural, data integrity, secret leak scan, runtime). Bootstrap length:0 prompt rows filtered from display so schema placeholders never reach the public page
r481 2026-04-11
go.bat parser error flood fixed — Board 67 (11 pts). Dirty-tree listing no longer spews '-', 'ision:', '/f', or literal %T [%S] leaks. Root cause: an inner FOR loop was echoing the first 5 lines of every dirty file, pushing arbitrary file contents back through the batch parser
Fix: call :show_entry label pattern — each dirty entry runs in its own parser scope, replacing the fragile nested IF-ELSE chain inside the FOR body. Adds scope isolation that the batch language itself lacks
Robust FOR /F — %TEMP% paths now quoted with usebackq; tokens=1,2 replaced with tokens=1* so filenames with spaces are preserved
ASCII hyphens in echoes — em-dash removed from echoed strings (REM comments keep it); eliminates code-page edge cases
6-scenario smoke test — untracked, modified, deleted, spaces-in-filename, long path, zero-flood all pass. Clean-tree and menu-dispatch regression-safe
r463 2026-04-11
~h Discipline section — DoR (3-read pre-flight), DoD (7 items + 4 chain-final), and Proposal convention now surfaced in help display instead of buried in rules
Compact ~h (Option A) — main display collapsed from 55 rows to 20, widest col 95→71. Dropped redundant WORKFLOW arrow column + USE CASES column (both derivable from Flow line + Chain expansions)
~new + ~chain-reaction options surfaced — ~new <name> [org] <fqdn> arg shape inline, plus third Chains row documenting ~<NAME> shorthand and ~chain-reaction new interview mode
Dynamic Latest block — top of ~h now computed at render time from be/telemetry.json. Shows the last 3 non-backfill work entries with revision, date, time, command, and description. No manual maintenance — always fresh
Spec tightening — description truncation corrected from ≤50 chars to ≤40 chars to match the actual 80-col width budget
5 iterations, 1 chain — all commits r453–r463, one ship, full chain-final DoD (11 items)
r416 2026-04-10
~tag command — universal tagging system. Tag anything with triples ({subject, tagged as, value}), stored in be/tags.json, searchable, git-managed. HTML viewer at be/tags.html with filter + group-by
Ship DoD expanded — chain-final commands (~s, ~r) now require 11 items: original 7 + chain complete + site in sync + ~h in sync + revision current
Creator credit — "by Joey Castillo" line added to go.bat/go.sh launcher banner. Visible every session
Site sync — all 4 pages updated: ~tag in tilde tables, DoD 9-11 documented, 48 boards / 680 pts stats, reference.html updated with ~tag + chain-final rules
Version is 0. Always. — semver removed everywhere. Every change is a revision (git rev-list --count HEAD). Display: v0 · rN · date · pts. History page converted from vX.Y to rN format
Definition of Done — 7-item mandatory quality gate enforced on every tilde command. DoD section added to index, architecture, commands.md, and conventions.md
Definition of Ready — 3-item session pre-flight: board state, last telemetry entry, source of truth
Chain cleanup — removed ghost chains (QUICK, FIXSHIP, POLISH). GO and HOTFIX are the two built-in chains. GO loop fixed: /~B ~T/ not /~B ~T ~F/
DoD in docs — be/docs/commands.md gets DoD preamble + cross-references on all 23 command specs. be/docs/conventions.md gets pre-deploy gate + HTML snippet template
Command telemetry — rolling 100-entry work log with commit hash backfill, HTML viewer dashboard
settings.json — file-based tool whitelist with Bash(*) wildcard; zero approval prompts
--append-system-prompt-file — CLAUDE.md injected as system prompt every session
install.bat/sh — new curl target replaces metal.bat/sh; flow: git → gh → clone → Fe → go
No K (Potassium) — orchestrator removed; install.bat handles the flow directly
Li standalone — Lithium (OS diet) broken out as separate add-on, not part of main install
Site revamp — tilde commands (~H) are the hero product; Be is the centerpiece
$50 budget + max effort — raised from $20 budget + high effort
r73 2026-03-23
Consolidated — tools.bat/sh, setup.bat/sh, provision.bat inlined into Go.Fe; six fewer files
Go.Fe.bat diet — downloads Go.Li.bat from website instead of calling old provision.bat
Clean metal naming — repo now contains Go.Fe.bat/sh, Go.Li.bat/sh, and supporting data
r68 2026-03-23
Architecture docs — full system schematic with flow diagrams, script tables, known gotchas
Architecture link on main page — joeycastillo.us/metal/architecture.html
Version sync — all 10 files stamped consistently
r67 2026-03-23
Fix false admin check in Go.Li.bat — net session unreliable when called from another batch file; removed check, steps handle errors individually
r65 2026-03-23
Fix curl not found in Fe — PATH refresh drops System32; now uses %SystemRoot%\System32\curl.exe
r63 2026-03-23
Li in Fe flow uses Go.Li.bat/sh — downloads the real Li script with list + all/pick/skip menu instead of old boring provision.bat preamble
r61 2026-03-23
Rename go-runtime → Go.Fe.2 — cleaner naming, step 5 now says "Launch full toolchain (Fe → Li → Be)"
r59 2026-03-23
Preview before action — every script shows a numbered list of what it will do before doing anything
Go.Fe: install all or skip — shows 5 steps, then [A] all / [S] skip
Go.Li: all, pick, or skip — shows step list, then [A] all / [P] pick one by one / [S] skip
r57 2026-03-23
Fix Be launch after fresh install — PATH not refreshed after tools.bat installs Claude Code via npm; now refreshes PATH from registry and checks %APPDATA%\npm
r55 2026-03-23
metal.Na (Sodium) — uninstall/reset script; removes metal repos for fresh install testing, leaves tools and OS changes
Na card on website — Windows and Mac/Linux commands with copy button
Fe → Li → Be → Na — full chain: foundation → diet → work → reset
r53 2026-03-23
Fix Go.Fe clone verification — clone could fail silently on fresh machines; now verifies repo exists before launching runtime, clear error if not
r52 2026-03-23
Go.Li: every step is optional — shows numbered list upfront, apply all at once or pick one by one
Go.Li.bat: self-contained, zero deps — all 12 Windows diet steps inline, no git/gh/repo needed
Go.Li.sh: Windows keyboard remap for Mac — Win→Ctrl, Alt→Cmd via hidutil + LaunchAgent persistence
Fe → Li → Be flow restructure — tools first, then diet, then launch Beryllium
r50 2026-03-23
Go.Li.sh: launch metal.Be after diet — asks if you want to launch Be when diet finishes; clones repo if needed
Be Mac command — website command now clones + runs in one step instead of bare ./Go.Be.sh
r49 2026-03-23
Fix Go.Be.sh frozen stdin — claude launched but couldn't read keyboard; exec < /dev/tty reconnects terminal
r48 2026-03-23
Fix browser install hanging — winget list updates source index on every call, can hang for ages; replaced with instant .exe path checks
r46 2026-03-23
Go.Li: every step is optional — each diet step asks before applying, safe to run on any machine
Go.Li.bat: self-contained, zero deps — all 12 diet steps inline, no git/gh/repo needed
Go.Li.sh: Windows keyboard remap for Mac — Win→Ctrl, Alt→Cmd via hidutil + LaunchAgent persistence
Go.Fe and Go.Li standalone scripts — bootstrap scripts for Windows and Mac/Linux, served from joeycastillo.us/metal/
Fe → Li → Be flow — tools first, then diet, then launch Beryllium
r44 2026-03-23
Fix Go.Fe.bat winget "already installed" — winget returns non-zero for existing packages; no longer treated as fatal
Fix curl|bash stdin — all read commands use < /dev/tty so piped execution works
Fix false admin check in go-runtime.bat — stale %errorlevel% with delayed expansion; tools.bat and Go.Li.bat check themselves
Fix bash 3.2 on Mac — ${var,,} syntax doesn't exist in macOS default bash; replaced with case statements