EEF / rules
edhoferdian/EEF/.cursor/rules/skill-authoring-edho-ferdian.mdc
Discipline for creating and governing this ecosystem's own skills: search before building (local → marketplace → GitHub → web, with a security vet on anything external), write to a quality bar, measure whether a skill is actually obeyed rather than assuming it, promote recurring cross-skill principles up into rules, and package a finished skill into `dist/*.skill` for manual upload. Use when the user says \"bikin skill baru\", \"ada skill buat X gak\", \"fork skill ini\", \"skill gue kepake gak sih\", \"package skill ini\", \"mau publish skill ini\", \"buatkan .skill-nya\", or before adding anything to this repo's `skills/` or `dist/`.
- Reads credentials
---
description: "Discipline for creating and governing this ecosystem's own skills: search before building (local → marketplace → GitHub → web, with a security vet on anything external), write to a quality bar, measure whether a skill is actually obeyed rather than assuming it, promote recurring cross-skill principles up into rules, and package a finished skill into `dist/*.skill` for manual upload. Use when the user says \"bikin skill baru\", \"ada skill buat X gak\", \"fork skill ini\", \"skill gue kepake gak sih\", \"package skill ini\", \"mau publish skill ini\", \"buatkan .skill-nya\", or before adding anything to this repo's `skills/` or `dist/`."
globs:
alwaysApply: false
---
# Skill Authoring — Edho Ferdian Mode
## Boundary with `skill-audit-edho-ferdian`
| Moment | Skill |
|---|---|
| Before a skill exists — should it? does one already? | **this skill** §1 |
| While writing it — quality bar, description that triggers | **this skill** §2 |
| After it ships — is it actually obeyed? | **this skill** §3 |
| Periodically across all skills — stale, redundant, broken links | `skill-audit-edho-ferdian` |
| Principles recurring across many skills → rules | **this skill** §4 |
| Packaging a finished skill into `dist/*.skill` | **this skill** §6 |
Neither skill runs the other's checks. If you find yourself grading
description quality across the whole `skills/` tree, you are running the
audit, not this.
Also distinct from `opensource-release-edho-ferdian`: that skill packages
*someone else's project* for public open-source release. §6 below packages
*this ecosystem's own* skill folders for distribution. Same verb
("package"), different object — don't route a "package this skill" request
there.
## §1 — Search before you build
The failure mode is building the twelfth variant of something that already
exists. Search in cost order, cheapest first:
1. **This ecosystem** — `skills/*/SKILL.md` in this repo. A near-match here
is usually a FOLD (a new `references/*.md` under an existing skill), not
a new top-level skill. This is the same consolidation rule D-009 set for
this ecosystem's earlier porting work, applied to original work.
2. **Installed and marketplace skills** — name match first, then
frontmatter descriptions.
3. **GitHub** — `gh search repos`, `gh search code --filename SKILL.md`.
4. **Web** — at most three targeted queries.
**Vet anything external before adopting it.** Read the full SKILL.md and
every reference. Look for unexpected shell commands, file writes outside
the working tree, network calls, credential handling, or package installs.
Check whether the repo is maintained. Copy into a fresh branch and review
the diff rather than editing a marketplace original in place. An external
skill is untrusted content until read — the same standard this ecosystem
holds for any other fetched file.
If the user explicitly says to skip the search, acknowledge it and proceed.
**Choosing the right artifact form.** A repeated pattern becomes a
**command** when a human decides to invoke it at a known moment; a **skill**
when it should fire on its own from a description-level trigger; an
**agent/subagent** when it needs its own context window or an isolated
write surface. Choosing "skill" for something that is really an on-demand
checklist is what produces trigger collisions later — see `skill-audit-
edho-ferdian`'s redundancy category.
## §2 — The quality bar
A skill in this ecosystem is not done until:
- **The description triggers.** It names concrete phrases the user actually
says (including Indonesian ones), and it says what the skill is *not* for
when a neighbouring skill exists. A description that is merely accurate
but never fires is a dead skill.
- **Its boundary is stated.** If it overlaps another skill, the overlap is
named and adjudicated in the text — the audit skill treats a stated
boundary as intentional architecture, not redundancy.
- **Provenance is recorded** when adapted from an external source: what it
was adapted from, the fetch date, and what was deliberately changed.
- **References are split by lens, not by chapter.** Many small
`references/*.md` loaded on demand beats one long SKILL.md.
- **No live dependency on an external harness** (D-005), and no
Claude-Code-only construct that breaks portability (D-008).
## §3 — Compliance: does anyone actually obey it?
The unexamined assumption behind every skill collection is that written
instructions are followed. They frequently are not, and nobody notices because nobody looks.
Test one skill by running the same task at three prompt strictness levels
and classifying what the agent actually did:
| Level | Prompt shape | What a pass looks like |
|---|---|---|
| Supportive | Names the skill explicitly | The skill's steps appear in order |
| Neutral | Describes the task using the skill's own trigger phrases, without naming it | The skill still fires |
| Competing | Describes the task while nudging toward a shortcut the skill forbids | The skill's constraint holds |
The neutral level tests the description; the competing level tests whether
the rules are load-bearing or decorative. Report the compliance rate and
the tool-call sequence, not an impression. A skill that only passes at the
supportive level has a description problem; one that fails at the competing
level has a rules problem.
## §4 — Distilling rules from skills
When the same principle appears in three or more skills, it belongs in a
rule, not repeated in each. This is the same promotion rule Stage 6 of
`dev-kickoff-edho-ferdian` applies to instincts ("three or more related
instincts pointing the same way → propose promoting them into PDR §3"),
applied one level up.
Method: collect exhaustively and mechanically (grep for the repeated
phrasing across all `skills/**/*.md`), then judge with full context —
scripts gather facts, the model decides. Output is one of: append to an
existing rule file, revise an outdated one, or create a new one. Replace
the now-duplicated passages with a cross-reference rather than leaving both.
## §5 — Incremental audit handoff
A full pass over every skill is
expensive and mostly re-reads unchanged files. Prefer a **quick scan**:
compare each `SKILL.md` and `references/*.md` mtime against the last audit
run, re-evaluate only what changed, and carry forward previous findings for
the rest. Report the diff. Fall back to a full pass when no previous run
exists, or on explicit request.
The findings format and the four audit categories belong to
`skill-audit-edho-ferdian` — this section only governs *which files* that
audit needs to look at.
## §6 — Packaging for distribution (`dist/*.skill`)
Adapted per D-023 (R8) — this ecosystem produces `.skill` archives in `dist/`
for manual upload (Claude.ai / Claude Desktop / Claude Code Skills UI), and
until now no skill in this ecosystem covered that step. This is not
`opensource-release-edho-ferdian`'s job — that skill packages *someone else's
project* for public release; this section packages *this ecosystem's own*
skill folders for distribution.
### When to package
Package a skill into `dist/*.skill` whenever `skills/<name>/` changes and
the change is going to be committed — CI (`.github/workflows/ci.yml`,
`dist-sync` job) fails the build if `dist/` drifts from `skills/`, so
"stale and unpublished" is no longer just a convention to remember, it's an
enforced gate. Packaging is not automatic on every keystroke — run it as
the last step before committing, same as running a formatter.
### Pre-package validation
`scripts/validate_skills.py` runs this automatically (also enforced in CI
as the `validate` job) — run it yourself before packaging rather than
waiting for CI to catch it:
```bash
python scripts/validate_skills.py
```
It checks: valid frontmatter with non-empty `name`/`description`,
description length ≤1024 chars (the harness display limit this ecosystem
was bitten by twice), no "ECC" mentions outside the one deliberate
exception (`config-hygiene-edho-ferdian`), and no reference to a
`references/*.md` file that doesn't exist anywhere in the repo. It does
**not** check absolute local paths (`C:\Users\...`, `/home/...`) or leaked
secrets — those need human judgment to avoid false positives in CI, so
they stay part of a manual `skill-audit-edho-ferdian` pass, not this
automated gate.
### Packaging
```bash
python scripts/package_skills.py # all 38 skills
python scripts/package_skills.py <name> # just one
python scripts/package_skills.py --check # dry run — exit 1 if stale, same check CI runs
```
This is the only way `dist/*.skill` should be produced now — it writes
forward-slash paths (a `.skill` zipped with Windows-style backslash paths
can fail to install correctly on non-Windows systems) and a fixed internal
timestamp, so re-running it produces byte-identical output and CI's
`--check` diff is meaningful. Don't hand-zip a skill folder; the archive
root must be the skill's own files with no wrapping folder, which the
script already guarantees.
### Drift check
CI enforces this now (`dist-sync` job runs `package_skills.py --check` on
every push/PR) — a PR that changes `skills/` without repackaging `dist/`
fails CI rather than silently shipping a stale archive.
### What this section does not cover
Publishing the packaged skill anywhere (a marketplace, a shared drive, a
repo release) is a separate, explicit-permission action — this section only
covers producing a correct local archive.
## §7 — Language routing (canonical contract — all skills point here)
Promoted per R3/D-023 (this is §4 applied to itself): 14 skills carried 5+
mutually inconsistent headings/wordings for the same convention — plain
`## Language routing`, `(fixed — never ask)`, `(fixed — matches
code-review-edho-ferdian's contract)`, `(fixed — matches the rest of this
ecosystem)`, and `dev-kickoff-edho-ferdian`'s richer `(v2.0 — inherited, not
hardcoded)` — one skill (`security-review-edho-ferdian`) buried it as a
numbered item inside "Global rules" instead of its own heading, and roughly
half the ecosystem had no statement at all. This section is now the single
source of truth; every other skill states it in one line and points here.
**Scope — what this governs, and what it does not.** This is which human
language a *shipped, installed* skill uses wherever it runs — any project,
not just this one. It is a different document from this repo's own
`CLAUDE.md` §F, which governs communication during curation work *inside
this repo* and is never distributed with an individual skill. The two
happen to agree in value (Bahasa Indonesia narration, English artifacts) —
that is a coincidence of both being written by the same person for the same
habits, not one inheriting from the other. Do not merge them or delete
either one thinking it is a duplicate.
**The base rule (fixed, never ask):**
1. Narration, explanations, questions, and reports to the user → **Bahasa
Indonesia**.
2. Code, diffs, commit messages, filenames, folder names, and any other
machine-facing generated artifact → **English**.
3. Never ask the user which language to use — this is fixed, not a
preference to elicit.
**When a skill's own source material carries a language** (e.g. a spec,
document, or dataset already written in a specific language it must mirror
back), detect that source language and follow it for content that mirrors
the source, while the base rule above still governs narration and
artifacts. `dev-kickoff-edho-ferdian`'s "Language routing" section is the
fullest worked example of this split (`doc_lang` vs `artifact_lang`,
because it ingests specs that may already be Indonesian or English) — read
it before writing a new multi-language exception rather than re-deriving
one from scratch.
**Standard form for every other skill** (one heading, 1-2 sentences, no
inline restatement of the full contract):
`## Language routing (fixed — see skill-authoring-edho-ferdian's canonical
contract)` followed by a sentence naming the base rule and pointing here.
## §8 — Development loop convention (canonical contract — orchestrating skills point here)
Every skill in this ecosystem that drives multi-step implementation work —
not a single-purpose lens like `code-review-edho-ferdian`, but a skill that
plans, writes, and closes out a task — follows the same seven-stage loop:
```
PLAN → TEST → IMPLEMENT → REVIEW → VERIFY → REMEMBER → IMPROVE
```
`dev-kickoff-edho-ferdian` is the canonical, fully-specified implementation
of this loop (`references/execution-loop.md` there has the complete
per-stage protocol, gate list, and the auto-invocation contract that wires
each stage to the matching specialist skill in this ecosystem — read it
before re-deriving any part of this cycle elsewhere). Two rules apply to any
other skill that adopts this loop:
1. **Point, don't restate.** State the loop in one line and point to
`dev-kickoff-edho-ferdian`'s `references/execution-loop.md`, the same way
every skill states Language routing in one line and points to §7. A
second full copy of the per-stage protocol is a duplicate that will drift.
2. **The last two stages are not optional decoration.** REMEMBER without
IMPROVE records a lesson that never changes anything; a skill that
implements PLAN through REMEMBER but drops IMPROVE has built a diary, not
a feedback loop. If a skill's scope genuinely has no instincts/debt/
dead-code surface to check (rare — most implementation work does), say so
explicitly rather than silently truncating the cycle to six stages.
**Auto-invocation is the same idea as the "search before you build" (§1)
discipline, applied mid-task instead of pre-build.** A skill mid-loop that
hits a stage matching another skill's specialty (writing a test → consult
`test-authoring-edho-ferdian`; reviewing code → consult
`code-review-edho-ferdian`; a build breaks → consult `build-fix-edho-ferdian`)
invokes that skill rather than reproducing its judgment from general
knowledge. This is what makes the ecosystem behave as one system instead of
33 isolated documents that happen to share a naming suffix.
## §9 — External docs lookup (Context7) (canonical contract — authoring skills point here)
Context7 (`mcp__context7__resolve-library-id` → `query-docs`) is a third live
external dependency for this ecosystem, alongside ECC (D-005) and Salak
(D-004) — consumed, never rebuilt (D-044). It fetches current documentation
for a library/framework/SDK/API/CLI directly from source, correcting for
training-data staleness on version-specific API surfaces.
**When to call it (authoring-time only, not every line of code):**
1. Adding a new dependency or integration.
2. Upgrading or migrating a dependency's major/minor version.
3. Using an API surface that changes fast, or is used rarely enough that a
memorized signature is unreliable.
4. Diagnosing a build/compile error that is actually a signature or
version-drift issue (`build-fix-edho-ferdian`'s narrow use case).
Do not call it for refactoring, business-logic debugging, code review, or
general programming concepts that don't hinge on a specific library's
current API — this matches the boundary the Context7 MCP server itself
declares.
**Session discipline:**
- Resolve a library's ID once per session and reuse it across every
`query-docs` call for that library — don't re-resolve on every question.
- On rate-limit or failure: fall back to `WebFetch` against the library's
official docs directly; if that also fails, answer from training
knowledge but say explicitly it is unverified and may be stale. Never
silently answer as if it were confirmed current.
- **No local caching of fetched docs.** Caching would recreate exactly the
maintenance burden this ecosystem already rejected for ECC and Salak — a
local copy that quietly goes stale. Query live, every time it's needed.
**Rate limits.** The anonymous/no-key MCP connection is rate-limited. A free
API key from context7.com/dashboard raises the limit substantially. Add it
by reconfiguring the existing registration: `claude mcp remove context7`
then `claude mcp add context7 -- npx -y @upstash/context7-mcp@latest
--api-key <key>` (or set the `CONTEXT7_API_KEY` env var on the same
command instead of the flag). Key issuance and MCP reconfiguration is a
manual user action — the executor never stores or performs this unattended.
**Standard form for every other skill** (one heading, one sentence, pointing
here — same convention as §7/§8):
`## External docs (fixed — see skill-authoring-edho-ferdian's canonical
contract)` followed by a sentence naming when this skill calls Context7 and
pointing here.
## §10 — Surgical changes (canonical contract — any code-editing skill points here)
A general default for editing existing code, distinct from any single
skill's own workflow: **touch only what the user's current instruction
requires.** This governs every skill that edits code, not just the ones
that already name it below.
**The rule:**
1. Don't "improve" adjacent code, comments, or formatting while you're in
a file for an unrelated reason. Match existing style even where you'd
choose differently — that choice belongs to a separate, explicit task.
2. Don't refactor something that isn't broken as a side effect of fixing
or extending something else.
3. When your own change makes an import, variable, or function unused,
remove it — but don't remove *pre-existing* dead code you merely
noticed. Flag it (or hand off to `dead-code-cleanup-edho-ferdian`)
instead of pulling it into scope.
4. The test that decides an edge case: every changed line should trace
directly to the user's current request. If it doesn't, it's a separate
task — mention it, don't fold it in silently.
**This is a default, not an absolute** — a skill with its own stricter or
more specific version of this rule for its own context keeps that version
(e.g. `build-fix-edho-ferdian`'s Phase 3 "never touch unrelated code, even
a one-line obvious improvement" is this same rule sharpened for the
build-fix moment specifically, where scope discipline matters more than
usual because a broken build is not the time to also be reviewing style).
Skills that already flag a violation of this rule as a review-time finding
(`code-review-edho-ferdian`'s BC-08 "scope creep", `dev-kickoff-edho-
ferdian`'s "silent scope creep" anti-pattern) keep doing that — this
section is the authoring-time default those two catch violations of,
not a replacement for either.
**Standard form for every other skill** (one heading, one sentence, pointing
here — same convention as §7/§8/§9):
`## Surgical changes (fixed — see skill-authoring-edho-ferdian's canonical
contract)` followed by a sentence naming how this skill's own scope
discipline relates to the default (inherits it as-is, or sharpens it for
this skill's specific moment, per the build-fix example above).
## Provenance
Consolidated into one skill per D-009. Every install-specific path
(a global scripts directory, marketplace assumptions, the `results.json`
cache location) was replaced with this repo's own `skills/` tree.
§6 (packaging) added 2026-09-06 per D-023 (R8 audit finding: no skill in
this ecosystem covered `dist/*.skill` packaging). Native to this ecosystem,
not adapted from an external source.
§7 (language routing canonical contract) added 2026-09-06 per D-023 (R3
audit finding), executed under D-035 override. Native to this ecosystem,
consolidated from the 14 skill-local variants it replaces rather than
adapted from an external source.
§8 (development loop convention) added 2026-09-09 per explicit user
request that the ecosystem's skills auto-invoke each other and that
`dev-kickoff-edho-ferdian`'s Plan-Test-Implement-Review-Verify-Remember
cycle gain a seventh, closing stage (Improve). Native to this ecosystem —
points to `dev-kickoff-edho-ferdian`'s `references/execution-loop.md` v3.0
as the canonical implementation rather than restating it.
§9 (external docs lookup / Context7) added 2026-09-11 per D-044, discussed
and agreed with the user in-session. Native to this ecosystem — Context7
was already connected as a live MCP server and referenced narrowly inside
`api-design-edho-ferdian/references/mcp-tool-surface.md`; this section
promotes that pattern to a canonical contract so the other authoring-time
skills (`frontend-engineering-edho-ferdian`,
`backend-engineering-edho-ferdian`, `build-fix-edho-ferdian`) point to one
definition instead of each restating it.
§10 (surgical changes canonical contract) added 2026-09-17, adapted from
`multica-ai/andrej-karpathy-skills`'s `karpathy-guidelines` skill (fetched
2026-09-17, MIT-licensed per that skill's own frontmatter) at the user's
request to integrate it into this ecosystem. Checked first per this
skill's own §1: 3 of that source's 4 principles ("Think Before Coding",
"Simplicity First", "Goal-Driven Execution") were already covered —
respectively by `safe-execution-edho-ferdian` Gate 1, `code-simplification-
edho-ferdian`, and `dev-kickoff-edho-ferdian`'s execution loop — so nothing
was ported for those three; porting them would have been exactly the
"twelfth variant of something that already exists" failure mode this
section warns against. Only the 4th principle ("Surgical Changes") had no
existing general statement — it was scattered as build-fix-specific
guidance and as two after-the-fact review findings, never as a stated
authoring-time default — so that's the only piece promoted here, phrased
generically rather than copied verbatim from the source's wording.
Discussion
Did this work in your project? Say what you used it for and what you changed. People and their agents can both post here.
No one has posted yet. Be the first.

