env-hygiene
Skill1 starsChanged 3 months agoMITView on GitHub
Environment-isolation-hygiene — own-scoped ephemeral-env lifecycle + teardown (/foundry:env-hygiene). Status of this session's owned dev/test resources (containers, kind/k3d/minikube clusters, LocalStack, dev servers) + the shared runtime daemon; on-demand own-scoped teardown; the reuse-before-start / label-what-you-start / pair-setup-with-teardown / never-stop-the-shared-runtime directive. Trigger to check what this session left running, tear down own resources, or learn the hygiene lifecycle.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- Hayatelin/devsecops-skillstheir own version, first seen Jun 27, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- Hayatelin/devsecops-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository71 other files it gives its agents.
- AGENTS.mdAGENTS.md
- llms.txtllms.txt
- amendSkill
- auditSkill
- authorize-releaseSkill
- authorizeSkill
- certify-localSkill
- certify-stagingSkill
- coherence-checkSkill
- command-deckSkill
- contextSkill
- cut-releaseSkill
- dashboards-as-codeSkill
- data-tier-cutoverSkill
- decommission-gateSkill
- deploy-statusSkill
- dispatchSkill
- doctorSkill
- drift-sweepSkill
- extract-specSkill
- fleetSkill
- grounding-conformanceSkill
- id-applySkill
- id-architectSkill
- id-baselineSkill
- id-discoverSkill
- id-documentSkill
- id-driftSkill
- id-impactSkill
- id-implementSkill
- id-importSkill
- id-planSkill
- id-promoteSkill
- id-reviewSkill
- id-rollbackSkill
- id-simulateSkill
- id-syncSkill
- id-testSkill
- id-validateSkill
- id-verifySkill
- indexSkill
- infra-sandboxed-applySkill
- initSkill
- intakeSkill
- learn-captureSkill
- learn-distillSkill
- merge-when-greenSkill
- mode-autonomousSkill
- mode-interactiveSkill
- modeSkill
- post-upgradeSkill
- releaseSkill
- relockSkill
- report-citation-graphSkill
- reposSkill
- research-captureSkill
- research-firstSkill
- revertSkill
- sd-debugSkill
- sd-discoverSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 2 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 15
Reuse before start: Check whether a suitable resource is already running before firing up a new one (reference-counting spirit) — don't …
- Distinctive: line 23
Pair setup with teardown: Every fire-up has a matching bring-down at end of work.
- Very specific: line 45
ONLY resources carrying this session's ownership marker (foundry.session=<id> label, foundry-<id> cluster name, or a recorded dev-server …
- Distinctive: line 84
ONLY an allocation whose holder pid is confirmed no-longer-live.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
/foundry:env-hygiene
The environment-isolation-hygiene lifecycle. Agents that spin up ephemeral dev/test
RESOURCES must bring them DOWN when the work is done — no stacking, no leaks. The enforcement
for the forgetful agent is automatic (a SessionEnd reaper); this skill is the on-demand
status + teardown surface plus the discipline.
The directive (own what you start)
- Reuse before start. Check whether a suitable resource is already running before firing up a new one (reference-counting spirit) — don't stack a second Colima/kind/dev-server.
- LABEL what you start with the session id. Stamp ownership at create-time so the reaper
can identify your resources (and only yours):
- containers:
docker run --label foundry.session=$CLAUDE_SESSION_ID … - clusters: name it
foundry-$CLAUDE_SESSION_ID(kind create cluster --name foundry-$CLAUDE_SESSION_ID) - dev servers: record the pid with its command + start-time under
.foundry/env-hygiene/<name>.jsonso the pid-recycling guard has a signature to verify.
- containers:
- Pair setup with teardown. Every fire-up has a matching bring-down at end of work.
- Never stop the shared runtime. The container-runtime daemon/host (Colima/Docker/Podman)
is shared singleton infrastructure — leave it running;
statussurfaces it, the operator stops it manually if they wish. Tunnels/VPN are status-only too. - Leave no orphans. What you started, you bring down (own-scoped).
Actions
| action | what it does |
| status | Lists this session's owned resources (reaped on SessionEnd); the shared runtime daemon shown running but NEVER auto-brought-down; and any foundry-labelled orphan from a prior/non-current session as a manual-clear candidate. |
| teardown | On-demand own-scoped reap — brings down THIS session's owned resources now (same decision core the SessionEnd hook uses). |
python3 "${CLAUDE_PLUGIN_ROOT}"/scripts/foundry-env-hygiene.py status
python3 "${CLAUDE_PLUGIN_ROOT}"/scripts/foundry-env-hygiene.py reap # on-demand teardownAutomatic enforcement (the forgetful-agent backstop)
A hook on the native SessionEnd event (hooks/foundry-env-reap.sh) invokes the
own-scoped reap when the session ends — the trap/finally happy-path class. It brings down
ONLY resources carrying this session's ownership marker (foundry.session=<id> label,
foundry-<id> cluster name, or a recorded dev-server pid whose live identity matches its
signature), reconciled from live reality, idempotently. It never brings down the shared
runtime daemon or a tunnel, never reaps another session's or an unlabelled resource, and
never runs a blind prune/kill-all — on any ownership ambiguity it reaps nothing.
Per-worker ephemeral env: port isolation + conductor mutex (feat-foundry-per-worker-ephemeral-env-and-conductor-mutex, AC-PWE-1..4)
Gap G7. N per-atom workers each bringing up identical dev/test services on fixed ports
collided; a duplicate-conductor race let two sessions drive the same release onto shared
worktrees at once. scripts/foundry_env_isolation.py is the primitive home
for both fixes (see its module docstring for the full design + industry-grounding).
- Per-worker port isolation (AC-PWE-1).
allocate_ephemeral_port()claims a port via OS-assigned dynamic (ephemeral) port allocation (socket.bind((host, 0))) — the dominant CI-parallelism practice. The kernel'sbind(2)IS the atomic claim; there is no client-side read-then-bind window, so concurrently-starting workers structurally cannot collide. Propagate the allocated port into the worker's compose/dev-server config (anenv-hygieneimplementation concern — this seam only allocates + tracks the claim). Hand-off caveat (security review):bind(0)'s atomicity holds only while the foundry socket is HELD OPEN — theclose()→ real-service-bind()hand-off is itself a TOCTOU window (another process could grab the just-freed port between the two). Consumers should either keep the foundry socket open until the real service successfully binds (close it only after), or hand off viaSO_REUSEPORT/ fd-passing to the real service. Do NOT overclaim "no read-then-bind window" for that external hand-off — the guarantee is scoped to the allocation itself, not to what happens afterclose(). - Conductor mutex (AC-PWE-2).
acquire_conductor_mutex(release_id, blocking=False)takes anfcntl.flock(LOCK_EX|LOCK_NB)on a sidecar lock file keyed by the release id's CANONICALIZED form (so"v0.19.0"and" V0.19.0 "— and"v 0.19.0", v + whitespace — all contend for the SAME lock; whitespace is collapsed BEFORE the leading-vstrip so a v+whitespace spelling isn't missed) — the same kernel-held advisory-lock primitive asscripts/foundry_id_alloc.py. FAIL-CLOSED: a driver that cannot immediately acquire getsNoneand MUST NOT proceed to drive the release. The staleness signal is the KERNEL-HELD LOCK ITSELF (not a PID-liveness/TTL side record) — a dead holder's lock auto-releases at process exit (including SIGKILL), so detect-stale -> reclaim -> re-acquire is one atomicflock()syscall, never a non-atomic client race. - Allocation reaper (AC-PWE-3).
record_allocation()/release_allocation()track a worker's port claim (ownership stamped with the holder pid's live process-identity signature).hooks/foundry-env-reap.sh(SessionEnd) also invokesreap_stale_allocations()— it reclaims ONLY an allocation whose holder pid is confirmed no-longer-live; it NEVER reaps a live concurrent worker's allocation. Hardened past a straight port (security review): preservation anchors on the holder's LIVE START-TIME alone (commandis advisory-only, since a live worker thatexec()s into its real service changes argv but keeps its pid+start-time); aps-probe FAILURE (not a confirmed "no such pid") is treated as INCONCLUSIVE and PRESERVES (never convicts on uncertainty — a transient probe failure must never mass-reap live workers); andworker_idis hashed into the on-disk record filename (mirrors the mutex's release-id hashing) so an externalworker_idcan never path-traverse out of the allocations directory. - Single-worker path unchanged (AC-PWE-4). A lone worker's
env-hygieneteardown selftest and its conductor-mutex acquisition are both uncontended — this atom adds isolation for the concurrent case without changing the single-worker lifecycle.
Live-seam: python3 -m pytest tests/test_env_isolation.py -q (the v0.25.0 test-suite realignment — converted to pytest).
Scope + non-goals
- In scope: containers, kind/k3d/minikube clusters, LocalStack, dev servers / background processes — the per-task resources that stack.
- NOT auto-reaped: the shared container-runtime daemon/host (status-only), tunnels/VPN
(status-only), and hard-crash orphans (a SIGKILL/OOM session never runs its SessionEnd
reaper — its orphan is surfaced by
statusfor manual clearing, not auto-reaped; true crash-survival = the deferred external reaper).
Anti-patterns
- Bringing down the shared runtime because "the session is done" — it's shared singleton infra; another parallel session may be actively reusing it. Never do it.
- A blind
docker system prune/ kill-all — reap own-scoped from live reality, never wholesale. - Tearing down a tunnel/VPN automatically — status-only (highest connectivity risk).
- Replaying a persisted "kill-these" list — reconcile ownership markers against live reality every time; a stale list misattributes.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

