Skip to content
Closed
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
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "fsh",
"description": "Full Stack House Claude Code skills (idea brainstorming & kickoff, prior-art research, delivery workflow, bug/flake hunting, iterative fresh-eyes review loops, change explanation, hands-on test drives, spec/ticket/PR polishing, documentation & agent-instruction audit, CI runner migration to Blacksmith, status reporting, design, document redlines)",
"version": "1.7.0",
"version": "1.7.1",
"author": {
"name": "Full Stack House",
"url": "https://fullstack.house"
Expand Down
4 changes: 2 additions & 2 deletions skills/blacksmith/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ One question decides most rows: **does this job build, run or test the app, and
- Short, and neither builds nor runs the app: the branch-protection required check, `if: always()` joiners, `notify-failure`, PR commenters, `paths-filter` jobs, cancel-workflows, labelers, deployment bookkeeping, config computation. Seconds of runtime, so nothing to gain — and the merge gate in particular should sit on the most boring infrastructure available.
- Waits on an external system: `kubectl rollout status`, Cloud Run deploys, health checks, cron pollers. Faster cores buy nothing, and there is no reason to hand a third-party runner the cluster kubeconfig for no gain.
- `self-hosted` or an unknown custom label. It is on that hardware for a reason — cluster LAN, on-disk kubeconfig.
- Machine-local or network-scoped credentials: `KUBECONFIG` pointing at a file on the runner, a WireGuard peer config, SSH to a host that allowlists the runner's IP.
- Machine-local or network-scoped credentials: `KUBECONFIG` pointing at a file on the runner, a WireGuard or tailscale/headscale join into someone's LAN, SSH to a host that allowlists the runner's IP.
- **A self-triggering workflow that has been dormant** (lists itself in `paths:` and hasn't run in 60+ days — the inventory flags these). Listing itself is normal; dormancy is the problem: your edit runs it for the first time in months, and a pre-existing failure then looks like yours. If it fails on something unrelated to runners, revert that file to byte-identical, report the failure, and don't fix it here — not even with a comment in the file, because the comment is an edit and re-fires it.

**Ask once**, in a single `AskUserQuestion`, with the numbers beside each item:
Expand Down Expand Up @@ -98,7 +98,7 @@ One question decides most rows: **does this job build, run or test the app, and

Keep any "free runner disk space" step — it still guards the image's own size. Multi-platform builds: one job per platform on the matching runner (`…-arm` for arm64), no QEMU.

**Every migrated job gets `timeout-minutes`** if it lacks one. A stuck VM on either vendor otherwise burns GitHub's 6-hour default. Value: 1.5 × the slowest run in the baseline, rounded up, minimum 10.
**Every migrated job gets `timeout-minutes`** if it lacks one. A stuck VM on either vendor otherwise burns GitHub's 6-hour default. Value: 1.5 × the slowest *healthy* run in the baseline, rounded up, minimum 10 — not the slowest run outright, which may be the very stall you are removing.

**`.github/actionlint.yaml`** from [`templates/actionlint.yaml`](./templates/actionlint.yaml), `{{LABELS}}` = the labels you introduced (one ` - ` line each); no repo has one before this, so create it. actionlint otherwise reads the labels as typos.

Expand Down
3 changes: 2 additions & 1 deletion skills/blacksmith/scripts/inventory.sh
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ for f in files:
r'\bssh\b', r'\bscp\b', r'rollout status', r'\bkubectl\b'], runs))
health = flag('health-check', hit([r'rollout status', r'curl[^\n]*(health|ready)', r'wait-for'], runs))
local_cred = flag('machine-local-cred', hit([r'KUBECONFIG[\'"]?:\s*[\'"]?/', r'ci-kubeconfig'], envs))
netcred = flag('network-cred', hit([r'wireguard', r'wg-connect', r'WG_CONFIG', r'openvpn'],
netcred = flag('network-cred', hit([r'wireguard', r'wg-connect', r'WG_CONFIG', r'openvpn',
r'tailscale', r'headscale', r'TS_AUTHKEY'],
uses + runs + envs + withs))
gate = flag('always/failure-if', bool(re.search(r'always\(\)|failure\(\)', cond)))
glue = flag('glue-action', hit([r'slackapi/', r'sticky-pull-request-comment', r'dorny/paths-filter',
Expand Down
Loading