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
14 changes: 14 additions & 0 deletions docs/sync-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ context.

---

## [2026-05-06] sync @ Hans Air M4

Config:
- statusline: switch hostname source from `hostname -s` (returns generic "Mac")
to `scutil --get LocalHostName` (returns "Hans-Air-M4"), matching the
SessionStart machine-banner hook. User noticed the statusline read `@Mac`
instead of the actual machine name; root cause was the macOS default
smb-style hostname clobbering the more useful LocalHostName.

Other drift deferred (Brewfile, .chezmoiscripts/*, dotfiles-sync.md command
edits) — needs its own dedicated sync pass.

---

## [2026-05-05] security: rewrite history to scrub leaked SSH file @ Hans Air M4

Following the privacy-gate work in PR #72, decided to also retroactively scrub
Expand Down
2 changes: 1 addition & 1 deletion home/dot_claude/executable_statusline-command.sh
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ if [ -n "$duration_ms" ] && [ "$duration_ms" != "0" ]; then
fi

# --- Hostname ---
host=$(hostname -s 2>/dev/null)
host=$(scutil --get LocalHostName 2>/dev/null || hostname -s)
[ -n "$host" ] && host_part=" ${DIM}@${host}${RESET}" || host_part=""

printf '%b' "${BLUE}${dir}${RESET}${git_part}${model_part}${effort_part}${ctx_part}${rate_part}${duration_part}${host_part}"
11 changes: 11 additions & 0 deletions home/dot_claude/hooks/machine-banner/executable_machine-banner.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
# SessionStart hook: emit "Machine: <user>@<localhostname> (<hw.model>)"
# so Claude Code always knows which physical box this session is on.
# Read by ~/.claude/settings.json -> hooks.SessionStart.
set -eu

USER_NAME=$(whoami)
HOSTNAME=$(scutil --get LocalHostName 2>/dev/null || hostname -s)
MODEL=$(sysctl -n hw.model 2>/dev/null || echo unknown)

printf 'Machine: %s@%s (%s)\n' "$USER_NAME" "$HOSTNAME" "$MODEL"
19 changes: 19 additions & 0 deletions home/dot_claude/modify_CLAUDE.md.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,25 @@ printf '%s\n' "$PREFIX"

cat <<'MARKDOWN'

# Machines I work from

The SessionStart hook prints `Machine: <user>@<localhostname> (<hw.model>)` so you always know which box you landed on. This table maps shorthand the user uses verbally to actual SSH targets.

| Shorthand | Hostname / SSH alias | User | Role |
|---|---|---|---|
| air | mac-air (Hans-Air-M4) | tieubao | daily driver, Da Nang. MacBook Air M4. |
| mini | `ssh mini` (Tailscale) / `ssh mini-lan` (mDNS fallback) | server | Mac Mini M4 Pro 64GB, daemon-runtime account. Use for status checks, log inspection, and the one ADR-0012 grant: `kickstart -k system/foundation.d.hermes-agent` (passwordless). Anything else needs the `tieubao` user via `mini-tieubao`. |
| mini-tieubao | `ssh mini-tieubao` | tieubao | Same physical Mini, ops-script account. Passwordless `print` / `kickstart -k` / `bootout` / `bootstrap` against `system/foundation.d.*` per SPEC-032. **Use this in any script that needs broader launchctl verbs than `kickstart -k hermes-agent`.** Convention defined in SPEC-052. |
| egress-tokyo, trading-egress-tokyo | `ssh trading-egress-tokyo` | server | Vultr Tokyo VPS, trading egress. |
| egress | `ssh egress` (see `~/.ssh/config.d/egress.local`) | server | egress relay. |

Resolution rules:

- "the mini" / "mac mini" → `mini` if the work is daemon control / log tail / `kickstart -k hermes-agent`. `mini-tieubao` if the work is broader foundation.d.* manipulation (bootout, bootstrap, print on a non-hermes label) or needs `(server) ALL` run-as-server escalation.
- "this machine" / "here" → use whatever the SessionStart banner shows. If the banner contradicts the user's framing, surface the conflict before acting.

The Mini hosts the ops-agent (`foundation.d.hermes-agent` LaunchDaemon, project at `/Users/server/dev/hermes-agent`) plus Ollama and `vps-mon-agent`. SPEC-032 specifies the substrate; ADR 0012 explains why `server`'s grant is narrow.

# Tool selection

Durable rule for Claude Code. Applies to every session. Default to acting. Only ask when escalation triggers fire (see bottom).
Expand Down
8 changes: 8 additions & 0 deletions home/dot_claude/modify_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
# "BLOCKED: Pipe-to-shell detected" -- block curl|wget | bash/sh/zsh
# "BLOCKED: Destructive delete" -- block rm -rf /|~|$HOME
#
# Managed SessionStart hooks (keyed by unique marker):
# "machine-banner.sh" -- prints "Machine: user@host (model)"
#
# Note: `git push` to main/master/production is intentionally only a warning,
# not a block. Solo workflow -- PR gating is not needed here.
# The dedup list still strips any previously installed block hook on apply.
Expand Down Expand Up @@ -95,6 +98,11 @@ echo "$INPUT" | jq \
{matcher: "Bash", hooks: [{type: "command", command: $git_push_warn_cmd}]},
{matcher: "Bash", hooks: [{type: "command", command: $rm_rf_block_cmd}]}
]
),
SessionStart: (
((.hooks.SessionStart // []) | map(select(
(.hooks // []) | map(.command // "" | contains("machine-banner.sh")) | any | not
))) + [{hooks: [{type: "command", command: "~/.claude/hooks/machine-banner/machine-banner.sh", timeout: 3}]}]
)
})
'
Loading