Install
$ agentstack add skill-edhoferdian-eef-safe-execution-edho-ferdian Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Destructive filesystem operation.
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Safe Execution — Edho Ferdian Mode
Why this exists: reasoning gates cannot catch this class
This ecosystem is already dense with reasoning gates — the 8-gate Reflection block, the Critique-Correction Loop, EDHO SCAN, the Output Scorecard. Every one of them asks the model about its own work, after the work is done.
That has a known ceiling. Asking a model "did you violate anything?" reliably returns "no" — self-evaluation shares the biases that produced the output. What changes behaviour is being made to produce a fact: asked to list every file that imports a module, the model has to actually run Grep and Read, and the resulting context changes what it writes next. Internal A/B measurements on gated vs ungated agents put the gap at roughly +2.25 points on a 10-point rubric across two tasks — a small sample, quoted as directional evidence rather than proof.
So the gates here are deliberately not reasoning gates. Each one either demands an artifact or checks a machine-verifiable fact.
Gate 1 — Fact-forcing, before the first touch of a file
Three stages, in order. Stopping at DENY is what most guards do and it is the least useful part:
DENY — block the first Edit/Write/Bash attempt against a target
FORCE — state exactly which facts must be produced
ALLOW — permit the retry once those facts are on the table
Before editing an existing file, produce:
- Every file that imports or requires it (search the tree — Grep/Glob).
- The public functions or classes this change affects.
- If it reads or writes data files: the field names, structure, and date
format — using redacted or synthetic values, never raw production data.
- The user's current instruction, quoted verbatim.
Before creating a new file, produce:
- The file(s) and line(s) that will call it.
- Confirmation that no existing file already serves that purpose.
- Data-shape facts, as above, if it touches data files.
- The user's current instruction, quoted verbatim.
Fact 3 is the one people skip and the one that pays. In both A/B trials the ungated agent assumed ISO-8601 dates while the real data used %Y/%m/%d %H:%M. Checking the actual shape kills that entire bug class.
Fact 4 looks like ceremony and is not: re-reading the literal instruction before acting is the cheapest defence against the drift where an agent, six tool calls deep, is solving an adjacent problem it invented.
Scope: first touch per target, not every edit. Once the facts are presented, further edits to that same file proceed freely. A gate that fires on every call gets disabled by lunchtime.
Gate 2 — Destructive commands, every single time
Unlike Gate 1, this one never gets a free pass after the first hit.
Watched: rm -rf (especially against /, ~, or a project root), git reset --hard, git push --force, git checkout ., git clean -fd, DROP TABLE / DROP DATABASE, docker system prune, kubectl delete, chmod 777, sudo rm, npm publish, and anything carrying --no-verify.
On a hit, produce before running:
- Every file or dataset the command will modify or delete.
- A one-line rollback procedure.
- The user's current instruction, quoted verbatim.
If step 2 cannot be written, that is the answer: do not run it.
--no-verify is on the list deliberately — it is the mechanical form of "skip the checks", and it is exactly what an agent under time pressure reaches for.
Runaway searches are destructive too — of time and of the machine. A recursive search starting at a filesystem, drive, or home root (find /, find ~, rg x /, Get-ChildItem -Recurse C:\, dir /s C:\) never needs the three-step justification above: it is simply refused. On Windows it runs for hours and outlives the tool call as an orphaned process — this ecosystem's own agent wrappers once spawned six find.exe scans hunting for a SKILL.md, some alive for ten hours. Search a known directory instead; if the target has no known location, ask. The Claude Code binding is hooks/block-fs-wide-search.js in this skill (see the appendix).
Never build a shell command by interpolating a string. Pass the executable and its arguments as separate entries with shell: false — string interpolation is how a filename with a space or a quote becomes an arbitrary command.
Gate 3 — Freeze: scope the write surface
Freeze Mode locks Write/Edit to a named subtree; reads stay unrestricted. Anything outside is refused with an explanation rather than silently allowed.
This is the directly load-bearing gate for how this ecosystem actually works. Its own porting effort dispatches several Sonnet agents in parallel, each owning a slice of the tree — and the kelompok 3 batch found real damage of exactly this shape afterwards (an agent leaving stale pointers into out-of-scope paths across files outside its brief, fixed by hand later). A freeze on each agent's assigned subtree turns that from a post-hoc discovery into a refusal at the moment it happens.
Use it whenever: an agent runs unattended, several agents run in parallel, or the work touches production or a migration.
Single writer, even across models. When more than one model or process contributes to one change, only one of them may write to the filesystem — the rest produce a proposal (a diff, a patch, a plan) for the writer to apply, never a direct write of their own. Two writers on the same change means there is no single diff left to review and no way to attribute a regression to the process that caused it.
Gate 4 — Stop-gate: do not declare done before the record is written
Retargeted from a learning-library path convention to this ecosystem's project-memory/.
Stage 6 REMEMBER of dev-kickoff-edho-ferdian requires the memory files to be updated "in the same turn, not later", and the anti-pattern table already names Snapshot debt (>3 tasks with no fresh snapshot) — an anticipated failure with no enforcer. This is the enforcer, and it uses only deterministic checks: mtimes and counters, no inference.
| Check | Mechanism | On hit | |---|---|---| | Task was substantial | count of Edit/Write calls this session ≥ 3 | classifies the session as complex; below that, nothing else runs | | Memory files untouched | mtime of project-memory/03-progress.md, 01-decision-register.md, 04-instincts.md older than this session's start | Block when the session is complex and none were touched | | Rationalization language | regex over the transcript tail | Warning only, never a block |
The rationalization patterns worth watching are the exact phrases that precede a Gate 2 or regression-rule violation: "skip tests for now", "pre-existing bug", "this was already broken", "good enough for now". They warn and never block, because a regex on prose false-positives and a gate that blocks on a false positive gets turned off.
Note the honest limitation: this enforces the habit of writing the record, not the quality of what was written. That is what the Reflection block and the audit skills are for. Defense in depth, not a replacement.
Report execution state with exactly one of: inspected / changed locally / verified locally / committed / pushed / blocked. Never say fixed until the proving command has been rerun and named. Never say pushed unless the upstream branch actually moved.
Choosing gates
| Situation | Gates | |---|---| | Ordinary interactive work | 4 only | | Unfamiliar or high-fan-in codebase | 1 + 2 + 4 | | Parallel agents, each owning a subtree | 1 + 2 + 3 (per agent) + 4 | | Production, migrations, deploys | 2 + 3, always |
Rules
- Never substitute self-evaluation for a gate. "Are you sure?" always
returns yes; that is measured, not assumed.
- Do not gate every Bash call. Routine commands gate once per session,
destructive ones every time. Getting this balance wrong is how gates get switched off, and a disabled gate protects nothing.
- Do not pre-answer a gate's questions from memory to satisfy it. The
investigation is the mechanism; a recited answer is theatre.
- A gate that cannot persist its state should fail open — allow the
action and warn — rather than loop.
- These gates never replace REVIEW or VERIFY. They are pre-action and
post-session bookends around a loop that still has to run.
Appendix — implementing these as hooks (Claude Code)
Portable practice first: every gate above is written so a human or an agent can run it by hand in any harness (D-008). This appendix is the optional mechanical binding for Claude Code specifically — PreToolUse for gates 1-3, Stop for gate 4 — including hookify rule-file syntax (.claude/hookify..local.md) for the pattern-matching gates. Nothing above depends on this appendix existing.
One gate ships ready-made: hooks/block-fs-wide-search.js (Node, no dependencies) denies root-level recursive searches for Gate 2 and fails open on anything it cannot parse. Copy it to ~/.claude/hooks/ and add to ~/.claude/settings.json:
"PreToolUse": [{
"matcher": "Bash|PowerShell",
"hooks": [{ "type": "command", "command": "node \"/.claude/hooks/block-fs-wide-search.js\"", "timeout": 10 }]
}]
Growth path
This skill is intentionally single-file — four gates read fine as one document because they share one voice (mechanical, fact-forcing) rather than four distinct lenses. If a fifth gate is added, or any single gate above grows enough to need its own worked examples/edge-case catalogue (the way click-path-audit-edho-ferdian split framework-specific tracing detail out), split that gate into references/, following the domain+lens pattern other skills in this ecosystem use — do not let this file creep past ~300 lines to avoid making that call.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: edhoferdian
- Source: edhoferdian/EEF
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.