Claude Skill

skill-creator

Create a new IWE skill with proper frontmatter, gates, scaffold and verification. Use when the pilot says: /skill-creator or «создай скилл <name>». The skill enforces WP Gate precondition, Routing Gate, IntegrationGate hard-check, collects parameters in 4 short steps, generates a

LLM Mart · 0 points · 13 views 2 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download TserenTserenov-FMT-exocortex-template-.claude_skills_skill-creator-4d7b8f2.zip · 15 KB
Part of tserentserenov/fmt-exocortex-template — 50 skills

Install

skills CLI npx skills add https://github.com/TserenTserenov/FMT-exocortex-template/tree/main/.claude/skills/skill-creator
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install tserentserenov-fmt-exocortex-template@llmmart
Git git clone https://github.com/TserenTserenov/FMT-exocortex-template.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole tserentserenov/fmt-exocortex-template collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

/skill-creator — create an IWE skill

Scope: create a new skill OR guide an update to an existing skill in .claude/skills/ or .kimi/skills/. Not in scope: full re-scaffold without deleting the old SKILL.md first (delete manually, then call /skill-creator again); creating a WP; creating a Pack. Role: ad-hoc content-role «Инженер скиллов»; formalize in Pack if ≥3 skills/year.

When to use

  • Pilot wants a new skill for a repeated workflow.
  • A new tool/agent/system needs a Service Clause + Role + SKILL.md.
  • A skill needs promotion from author repo to FMT-exocortex-template.

Preconditions (checked, not performed)

  1. WP Gate precondition. The task must be attached to an agreed WP in the weekly plan or explicitly named by the pilot. /skill-creator does not conduct the WP Gate ritual itself.
  2. Routing Gate. Decide target platform (Claude vs Kimi) and level (project vs user). Default: project-level .claude/skills/ in the author repo.
  3. IntegrationGate hard-check. DP.SC.* and DP.ROLE.* must exist in the PACK repo. If not, the skill stops and offers to create them. Bypass only by explicit pilot instruction «пропусти gate» — no code flag.

Algorithm

Step 1 — Check WP Gate precondition

Look up the current weekly plan (current/WeekPlan W{N}.md) or ask:

К какому РП привязано создание скилла?

If no WP is named and none matches the skill topic → stop:

Создание скилла требует согласованного РП. Сначала откройте РП через WP Gate.

Step 2 — Routing Gate

Ask or infer:

Question Default
Claude или Kimi? Claude
project-level или user-level? project-level
governance-репо для учёта? ${IWE_GOVERNANCE_REPO:-DS-strategy}

Target path:

  • Claude project: .claude/skills/<name>/
  • Kimi project: .kimi/skills/<name>/
  • User level: ~/.claude/skills/<name>/ or ~/.kimi/skills/<name>/

Step 2.5 — Detect existing skill

Check whether <target_path>/SKILL.md already exists.

If it exists → switch to update mode. Do NOT re-scaffold. Show the pilot:

Скилл <name> уже существует (версия X.Y.Z).
Что обновить?
  [ ] description
  [ ] slash / phrase triggers
  [ ] version bump (current: X.Y.Z → new: ?)
  [ ] algorithm step (add / edit)
  [ ] bundled resource (add scripts/ references/ assets/)
  [ ] полный пересоздать → удалите SKILL.md вручную, затем запустите /skill-creator снова
  [ ] отмена → ничего не менять

Collect the pilot's choices. Apply changes directly to the existing SKILL.md via Edit.

Skip Steps 3–6 unless the pilot selected "bundled resource" or any change that expands the skill's scope or gates — in that case, run Step 3 (IntegrationGate) before applying.

For Step 7 (register + verify): run verify-skill.sh always. Run generate-skills-catalog.sh only if frontmatter changed (name, description, triggers, version).

Version bump rule: bump patch for trigger / description edits; bump minor for algorithm changes or adding a bundled resource; bump major for gate or scope changes.

If it does not exist → continue to Step 3 (normal creation flow).

Step 3 — IntegrationGate

Check PACK repo for files matching DP.SC.* and DP.ROLE.*. If missing:

Service Clause (DP.SC.*) и Role (DP.ROLE.*) не найдены.
Создайте их сейчас через /pack-new или соответствующий процесс.
Для продолжения без них скажите явно: «пропусти gate».

Stop until the gate is satisfied or explicitly bypassed by pilot words.

Step 4 — Collect parameters (4 short steps)

4a. Name and description

Имя скилла (hyphen-case): <name>
Краткое описание — что делает и когда использовать:

4b. Agents and interaction axes

agents: single | multi
interaction: one-shot | multi-step

4c. Triggers

slash-команды (через запятую):
фразовые триггеры (через запятую):

Keep phrase triggers narrow: include a skill name placeholder to avoid accidental activation.

4d. Bundled resources

Какие bundled resources нужны?
[ ] scripts/
[ ] references/
[ ] assets/

Default: assets/ for scaffold template, scripts/ for verify script.

Step 5 — Generate scaffold

Choose scaffold template based on skill complexity:

  • Minimal (assets/skill-scaffold-minimal.md): single-step skills without external gates
  • Full (assets/skill-scaffold-full.md): multi-step skills with Preconditions and Bundled resources

Copy chosen template to target path and substitute:

  • {{name}}, {{description}}, {{version}} (default 0.1.0), {{status}} (default experimental)
  • {{agents}}, {{interaction}}, {{layer}}
  • {{slash_triggers}}, {{phrase_triggers}}
  • {{gates_rationale}} — required when gates_required and gates_enforced are both empty

Create selected bundled resource directories with placeholder files.

Step 6 — Show draft

Print generated SKILL.md and file list to stdout. No P5 question. Pilot can cancel with:

/skill-creator undo

Undo works only before next commit or within 15 minutes.

Step 7 — Write files, register, verify

Write files to target path. Then regenerate the catalog and run verify:

bash scripts/generate-skills-catalog.sh   # register in skills-catalog.yaml
bash scripts/verify-skill.sh <name>       # 33-point structural check

Both commands must pass before the skill is considered created.

Tell the user where the new skill lives and that nothing preserves it (issue #873): a project-local skill under .claude/skills/<name>/ is usually outside git and outside the day-close.sh backup, and update.sh neither erases nor carries it over. Until the template owner picks a backup model, suggest keeping a copy in a git repository the user controls.

For skills with interaction: multi-step: run /vdv audit on the Algorithm section. Not a gate — does not block creation — but catches steps with missing Input/Output linkage before the skill is used in practice.

Bundled resources

  • assets/skill-scaffold-minimal.md — scaffold for single-step skills without external gates
  • assets/skill-scaffold-full.md — scaffold for multi-step skills with Preconditions and Bundled resources
  • scripts/verify-skill.sh — validates frontmatter, gates fields, bundled resource existence, L1 location

Known schema gaps

Fields used by some existing skills but not yet in the standard frontmatter schema:

  • argument-hint — CLI-style hint for script-executor skills (e.g. agent-fault, apply-captures). Encodes the argument contract. Keep until schema is extended or absorbed into description.
  • routing.executor — indicates whether the skill runs via script, sonnet, or another executor. Useful for the dispatcher but not validated by verify-skill.sh. Candidate for standardization.

Until standardized: leave these fields as-is in existing skills; do not remove during Step 2.5 updates.

Known tool gaps

  • verify-skill.sh L1 location check for .kimi/skills/: check_l1_location only checks FMT-exocortex-template/.claude/skills/. For skills placed at .kimi/skills/ (platform:kimi), the L1 location check is skipped when layer: L2, or produces a spurious FAIL when layer: L1. Until verify-skill.sh is extended with a --platform kimi flag, use layer: L2 for .kimi/skills/ test skills, and document any intentional L1 Kimi skills separately.
  • content-audit.sh coverage (Ф9): audit script checks 5 structural criteria (gates_rationale, Algorithm section, step headings ≥3, step content ≥2 lines, When-to-use section). 7 YELLOW skills (single C3 issue) are simple alias/mode skills without numbered step headings. This is structural noise, not content error — these skills are functionally correct. See scripts/content-audit.sh for full output.

Anti-patterns

  • Do not create a skill without a linked WP.
  • Do not bypass IntegrationGate with a code flag.
  • Do not put wide phrase triggers like «надо сделать скилл».
  • Run generate-skills-catalog.sh after writing files (Step 7) — not before, not manually.
  • Do not make the skill verify itself; use scripts/verify-skill.sh.
  • Do not skip verify-skill.sh after editing an existing skill — always run it after any update.
  • Do not re-scaffold for minor updates (triggers, description, version bump, algorithm); use Step 2.5 update mode instead. Exception: platform or layer change (e.g. Claude→Kimi, L1→L3) requires a new path and a fresh scaffold — delete old SKILL.md first.
  • Do not forget version bump when changing gates, scope, or algorithm steps (bump minor or major).

Verification

After creation, run:

bash scripts/verify-skill.sh <skill-name>

Expected result: PASS with checks for: valid YAML frontmatter, non-empty description, recognized triggers, gates_required/gates_enforced fields with valid enum values, bundled resource files exist, scaffold templates valid, L1 skills present in FMT.

Files (fmt-exocortex-template)
  • assets
    • skill-scaffold-full.md 1.6 KB
      ---
      name: {{name}}
      description: |
        {{description}}
      version: {{version}}
      status: {{status}}
      layer: {{layer}}
      agents: {{agents}}
      interaction: {{interaction}}
      gates_required: {{gates_required}}
      gates_enforced: {{gates_enforced}}
      gates_rationale: "{{gates_rationale}}"
      triggers:
        slash:
      {{slash_triggers}}
        phrases:
      {{phrase_triggers}}
      ---
      
      # /{{name}}
      
      > **Scope:** <one-sentence scope>
      > **Not in scope:** <what this skill does NOT do>
      > **Role:** <content-role that uses this skill>
      
      ## When to use
      
      - <trigger situation 1>
      - <trigger situation 2>
      - <trigger situation 3>
      
      ## Preconditions
      
      1. **WP Gate precondition.** The task must be attached to an agreed WP in the weekly plan.
      2. <additional gate or precondition>
      
      ## Algorithm
      
      <!-- Each step: Input (what must be ready), Action (what the agent does), Output (artifact or state produced).
           For multi-step skills, run /vdv audit on this section before finalizing. -->
      
      ### Step 1 — <action>
      
      Input: <what must be ready at this step>
      Action: <what the agent does>
      Output: <artifact or state produced>
      
      ### Step 2 — <action>
      
      Input: <output of step 1 + anything else>
      Action: <what the agent does>
      Output: <artifact or state produced>
      
      ### Step 3 — <action>
      
      Input: <output of step 2 + anything else>
      Action: <what the agent does>
      Output: <artifact or state produced>
      
      ## Bundled resources
      
      - `scripts/` — <what scripts do>
      - `assets/` — <what assets contain>
      
      ## Anti-patterns
      
      - <anti-pattern 1>
      - <anti-pattern 2>
      - <anti-pattern 3>
      
      ## Verification
      
      <how to verify the skill works; reference verify-skill.sh if applicable>
      
    • skill-scaffold-minimal.md 696 B
      ---
      name: {{name}}
      description: |
        {{description}}
      version: {{version}}
      status: {{status}}
      layer: {{layer}}
      agents: {{agents}}
      interaction: {{interaction}}
      gates_required: {{gates_required}}
      gates_enforced: {{gates_enforced}}
      gates_rationale: "{{gates_rationale}}"
      triggers:
        slash:
      {{slash_triggers}}
        phrases:
      {{phrase_triggers}}
      ---
      
      # /{{name}}
      
      > **Scope:** <one-sentence scope>
      > **Not in scope:** <what this skill does NOT do>
      > **Role:** <content-role that uses this skill>
      
      ## When to use
      
      - <trigger situation 1>
      - <trigger situation 2>
      
      ## Algorithm
      
      ### Step 1 — <action>
      
      <what to do and how>
      
      ### Step 2 — <action>
      
      <what to do and how>
      
      ## Anti-patterns
      
      - <anti-pattern 1>
      
  • scripts
    • batch-fix-skills.py 6 KB
      #!/usr/bin/env python3
      """Batch fix for SKILL.md files missing required fields/sections.
      Adds: agents, interaction, gates_required, gates_enforced, gates_rationale,
            ## When to use, ## Algorithm.
      """
      
      import os
      import re
      import sys
      
      SKILLS_DIR = os.path.expanduser("~/IWE/.claude/skills")
      
      # Already PASS — skip
      SKIP = {"agent-fault", "apply-captures", "skill-creator"}
      
      # executor:script + deterministic:true → agents: none, interaction: one-shot
      SCRIPT_EXECUTOR = {
          "check-secret", "connect-guide", "consent", "extend",
          "iwe-bug-report", "lesson-close", "setup-wakatime", "transcribe", "w-reflection"
      }
      
      # Skills where ## Scope should be renamed to ## When to use (Scope = When-to-use content)
      SCOPE_AS_WTU = {"ke"}
      
      
      def get_description(content):
          m = re.search(r'^description:\s*["\']?(.*?)["\']?$', content, re.MULTILINE)
          return m.group(1).strip() if m else ""
      
      
      def has_field(content, field):
          return bool(re.search(rf'^{re.escape(field)}:', content, re.MULTILINE))
      
      
      def add_frontmatter(content, skill_name):
          """Insert missing frontmatter fields before closing ---."""
          is_script = skill_name in SCRIPT_EXECUTOR
          agents_val = "none" if is_script else "single"
          inter_val = "one-shot" if is_script else "multi-step"
      
          # Find end of frontmatter (second occurrence of ---)
          idx = content.find('\n---', 4)
          if idx == -1:
              return content
      
          additions = []
          if not has_field(content, 'agents'):
              additions.append(f'agents: {agents_val}')
          if not has_field(content, 'interaction'):
              additions.append(f'interaction: {inter_val}')
          if not has_field(content, 'gates_required'):
              additions.append('gates_required: []')
          if not has_field(content, 'gates_enforced'):
              additions.append('gates_enforced: []')
          # Rationale needed when both gates are empty
          if not has_field(content, 'gates_rationale'):
              # Determine if gates will be empty after fix
              req_val = re.search(r'^gates_required:\s*(.*)', content, re.MULTILINE)
              enf_val = re.search(r'^gates_enforced:\s*(.*)', content, re.MULTILINE)
              req_empty = (req_val is None) or re.match(r'\[\s*\]', req_val.group(1).strip())
              enf_empty = (enf_val is None) or re.match(r'\[\s*\]', enf_val.group(1).strip())
              if req_empty and enf_empty:
                  additions.append(
                      'gates_rationale: '
                      '"операционный скилл; WP Gate применим только при создании нового РП, '
                      'не для операционных вызовов"'
                  )
      
          if additions:
              content = content[:idx] + '\n' + '\n'.join(additions) + content[idx:]
          return content
      
      
      def add_when_to_use(content, description, skill_name):
          """Add ## When to use section if missing."""
          if '## When to use' in content:
              return content
      
          # ke: rename ## Scope → ## When to use (Scope IS the when-to-use content)
          if skill_name in SCOPE_AS_WTU:
              if re.search(r'^## Scope\b', content, re.MULTILINE):
                  return re.sub(r'^## Scope\b', '## When to use', content, count=1, flags=re.MULTILINE)
      
          # Insert before first level-2 section in the body
          fm_end = content.find('\n---\n', 4)
          if fm_end == -1:
              return content
          body_start = fm_end + 4
      
          m = re.search(r'\n## ', content[body_start:])
          if m:
              pos = body_start + m.start()
          else:
              pos = len(content)
      
          section = f'\n## When to use\n\n{description}\n'
          return content[:pos] + section + content[pos:]
      
      
      def add_algorithm(content):
          """Add ## Algorithm section if missing."""
          if '## Algorithm' in content:
              return content
      
          # Priority order: rename known Russian/alternative headings first
          rename_map = [
              r'^## Алгоритм\b',
              r'^## Инструкция для Claude\b',
              r'^## Порядок выполнения\b',
              r'^## Поведение\b',
          ]
          for pattern in rename_map:
              if re.search(pattern, content, re.MULTILINE):
                  return re.sub(pattern, '## Algorithm', content, count=1, flags=re.MULTILINE)
      
          # Numbered sections ## N. (like think skill)
          m = re.search(r'\n## \d+\.', content)
          if m:
              return content[:m.start()] + '\n## Algorithm\n' + content[m.start():]
      
          # Level-2 ## Шаг or ## Step
          m = re.search(r'\n## (Шаг|Step)\b', content)
          if m:
              return content[:m.start()] + '\n## Algorithm\n' + content[m.start():]
      
          # Level-2 ## Режим (multi-mode skills like vdv)
          m = re.search(r'\n## Режим\b', content)
          if m:
              return content[:m.start()] + '\n## Algorithm\n' + content[m.start():]
      
          # Fallback: append minimal section
          return content.rstrip() + '\n\n## Algorithm\n\nВыполнить согласно инструкции в теле скилла.\n'
      
      
      def process_skill(skill_name):
          path = os.path.join(SKILLS_DIR, skill_name, 'SKILL.md')
          if not os.path.exists(path):
              return False
      
          with open(path, encoding='utf-8') as f:
              orig = f.read()
      
          content = orig
          desc = get_description(content)
          content = add_frontmatter(content, skill_name)
          content = add_when_to_use(content, desc, skill_name)
          content = add_algorithm(content)
      
          if content != orig:
              with open(path, 'w', encoding='utf-8') as f:
                  f.write(content)
              return True
          return False
      
      
      def main():
          target = sys.argv[1] if len(sys.argv) > 1 else None
          skills = [target] if target else sorted(os.listdir(SKILLS_DIR))
      
          fixed = []
          skipped = []
          for skill_name in skills:
              if skill_name in SKIP:
                  skipped.append(skill_name)
                  continue
              skill_dir = os.path.join(SKILLS_DIR, skill_name)
              if not os.path.isdir(skill_dir):
                  continue
              if process_skill(skill_name):
                  fixed.append(skill_name)
                  print(f"  fixed: {skill_name}")
              else:
                  print(f"  no-op: {skill_name}")
      
          print(f"\nDone: {len(fixed)} fixed, {len(skipped)} skipped (already PASS)")
      
      
      if __name__ == '__main__':
          main()
      
    • content-audit.sh 7.4 KB
      #!/usr/bin/env bash
      # content-audit.sh — minimal content check for IWE skills (WP-422 Ф9 + Ф10)
      # Ф9: 5 structural+content criteria (C1-C5).
      # Ф10: C6 verification-anchor (ВДВ — выгода-действие-верификация), calibrated.
      # Outputs: RED (>=2 issues), YELLOW (1 issue), GREEN (0 issues)
      set -euo pipefail
      
      SKILLS_DIR="${IWE_DIR:-$HOME/IWE}/.claude/skills"
      # SKIP_SKILLS — intentional exemptions, NOT "forgot to remove" (WP-422 Ф10):
      #   skill-creator    — meta-skill that bundles this very script (bootstrap circularity);
      #                      its own quality is gated by verify-skill.sh + /vdv audit (Step 7).
      #   agent-fault      — script-executor skill (argument-hint contract, no numbered steps);
      #   apply-captures   — script-executor skill; both structurally diverge from the step template.
      SKIP_SKILLS="${SKIP_SKILLS:-agent-fault apply-captures skill-creator}"
      
      # C6 verification-anchor vocabulary (Ф10). Broad on purpose — a skill "has a verification
      # notion" if any of: a Verification section (RU/EN), a verify/audit script, an acceptance
      # criterion, or an inline check (Expected/PASS/FAIL/smoke/test -f/проверь).
      C6_ANCHOR_RE='(^## .*[Вв]ерификаци|^## (Verification|Проверка)|[Вв]ерификаци|verify[-_a-z]*\.sh|[-_a-z]*audit\.sh|verify-skill|критери[йи] (готовности|приёмки|приемки)|acceptance|Expected result|Expected:|PASS\b|FAIL\b|smoke|смоук|test -f |проверь|проверить, что|sanity)'
      # Gate-critical = skill performs an irreversible/blocking action or enforces a gate.
      # Narrow on purpose: mere mention of "Pack"/"запиши" does NOT make a skill gate-critical
      # (that flagged 41/43 — manufactured churn). Only real side-effects count.
      C6_GATECRIT_RE='git push|git commit|deploy|skill-promote|promote\.sh|--no-verify'
      
      RED=0; YELLOW=0; GREEN=0
      declare -a RED_LIST YELLOW_LIST
      # C6 advisory: non-gate-critical skills lacking any verification notion. Listed for manual
      # triage, NOT counted as an issue (many are inherently advisory: classifiers, transcribers).
      declare -a C6_ADVISORY_LIST
      
      audit_skill() {
        local name="$1"
        local skill_md="$SKILLS_DIR/$name/SKILL.md"
        local issues=0
        local issue_list=""
      
        if [[ ! -f "$skill_md" ]]; then
          return
        fi
      
        # C1: gates_rationale non-empty when gates_required or gates_enforced are non-empty
        local gates_req gates_enf gates_rat
        gates_req=$(grep -E '^gates_required:' "$skill_md" | sed 's/gates_required:[[:space:]]*//' | tr -d '[]' | tr -d ' ' || true)
        gates_enf=$(grep -E '^gates_enforced:' "$skill_md" | sed 's/gates_enforced:[[:space:]]*//' | tr -d '[]' | tr -d ' ' || true)
        gates_rat=$(grep -E '^gates_rationale:' "$skill_md" | sed 's/gates_rationale:[[:space:]]*//' | tr -d '"' | tr -d "'" | xargs 2>/dev/null || true)
      
        local has_gates=false
        [[ -n "$gates_req" && "$gates_req" != "" ]] && has_gates=true
        [[ -n "$gates_enf" && "$gates_enf" != "" ]] && has_gates=true
      
        if $has_gates && [[ -z "$gates_rat" || "$gates_rat" == "\"\"" || "$gates_rat" == "''" ]]; then
          issues=$((issues + 1))
          issue_list+=" C1:gates_rationale_missing"
        fi
      
        # C2: "## Algorithm" section present
        if ! grep -q '^## Algorithm' "$skill_md"; then
          issues=$((issues + 1))
          issue_list+=" C2:no_algorithm_section"
        fi
      
        # C3: >= 3 step-like headings (##/### level) anywhere in file
        # Accepts: "## Шаг N", "## Step N", "### N.", "### Фn", "### n —", etc.
        local step_count
        step_count=$(grep -cE '^#{2,3} (Step|Шаг|Phase) [0-9]|^#{2,3} Ф[0-9]|^#{2,3} [0-9]+[а-яa-z]?\. |^#{2,3} [0-9]+[а-яa-z]? (—|-)' "$skill_md" || true)
        if [[ "$step_count" -lt 3 ]]; then
          issues=$((issues + 1))
          issue_list+=" C3:steps_lt_3(found:${step_count})"
        fi
      
        # C4: each "### Step N" has >= 2 non-empty lines after it
        local step_fail=0
        local in_step=false
        local step_content_count=0
        while IFS= read -r line; do
          if [[ "$line" =~ ^###\ Step\ [0-9] ]]; then
            # check previous step
            if $in_step && [[ "$step_content_count" -lt 2 ]]; then
              step_fail=$((step_fail + 1))
            fi
            in_step=true
            step_content_count=0
          elif $in_step; then
            if [[ "$line" =~ ^## ]]; then
              # new top-level section, close current step
              if [[ "$step_content_count" -lt 2 ]]; then
                step_fail=$((step_fail + 1))
              fi
              in_step=false
            elif [[ -n "$line" && ! "$line" =~ ^#+ ]]; then
              step_content_count=$((step_content_count + 1))
            fi
          fi
        done < "$skill_md"
        # check last step
        if $in_step && [[ "$step_content_count" -lt 2 ]]; then
          step_fail=$((step_fail + 1))
        fi
        if [[ "$step_fail" -gt 0 ]]; then
          issues=$((issues + 1))
          issue_list+=" C4:empty_steps(${step_fail})"
        fi
      
        # C5: "## When to use" section present
        if ! grep -q '^## When to use' "$skill_md"; then
          issues=$((issues + 1))
          issue_list+=" C5:no_when_to_use"
        fi
      
        # C6: verification-anchor (Ф10, ВДВ). Calibrated two-tier:
        #   - gate-critical skill (irreversible action) WITHOUT any verify notion → counted issue;
        #   - non-gate skill without anchor → advisory only (not counted), for manual triage.
        local has_anchor=false gate_crit=false
        grep -qiE "$C6_ANCHOR_RE" "$skill_md" && has_anchor=true
        grep -qE "$C6_GATECRIT_RE" "$skill_md" && gate_crit=true
        local genf
        genf=$(grep -E '^gates_enforced:' "$skill_md" | sed 's/gates_enforced:[[:space:]]*//' | tr -d '[] ' || true)
        [[ -n "$genf" ]] && gate_crit=true
        if ! $has_anchor; then
          if $gate_crit; then
            issues=$((issues + 1))
            issue_list+=" C6:gate_critical_no_verification"
          else
            C6_ADVISORY_LIST+=("$name")
          fi
        fi
      
        # Classify
        if [[ "$issues" -ge 2 ]]; then
          RED=$((RED + 1))
          RED_LIST+=("$name$issue_list")
          printf "  RED    %-30s %s\n" "$name" "$issue_list"
        elif [[ "$issues" -eq 1 ]]; then
          YELLOW=$((YELLOW + 1))
          YELLOW_LIST+=("$name$issue_list")
          printf "  YELLOW %-30s %s\n" "$name" "$issue_list"
        else
          GREEN=$((GREEN + 1))
          printf "  GREEN  %-30s\n" "$name"
        fi
      }
      
      echo "=== content-audit.sh — WP-422 Ф9 ==="
      echo "Skills dir: $SKILLS_DIR"
      echo "Skipping:   $SKIP_SKILLS"
      echo ""
      
      for skill_path in "$SKILLS_DIR"/*/; do
        skill_name=$(basename "$skill_path")
        if echo "$SKIP_SKILLS" | grep -qw "$skill_name"; then
          continue
        fi
        audit_skill "$skill_name"
      done
      
      TOTAL=$((RED + YELLOW + GREEN))
      echo ""
      echo "=== Summary: $TOTAL skills audited ==="
      echo "  GREEN  (0 issues, minimal-content gate): $GREEN"
      echo "  YELLOW (1 issue, fix by type):           $YELLOW"
      echo "  RED    (2+ issues, needs VDV audit):     $RED"
      echo ""
      echo "NOTE: GREEN = minimal structural+content barrier, not 'perfect skill'."
      echo "      Logic errors in GREEN skills are possible — this audit checks structure only."
      echo ""
      if [[ ${#RED_LIST[@]} -gt 0 ]]; then
        echo "=== RED skills (need VDV audit) ==="
        for s in "${RED_LIST[@]}"; do
          echo "  $s"
        done
      fi
      if [[ ${#YELLOW_LIST[@]} -gt 0 ]]; then
        echo "=== YELLOW skills (single fix) ==="
        for s in "${YELLOW_LIST[@]}"; do
          echo "  $s"
        done
      fi
      if [[ ${#C6_ADVISORY_LIST[@]} -gt 0 ]]; then
        echo ""
        echo "=== C6 advisory: no verification anchor, NOT gate-critical (${#C6_ADVISORY_LIST[@]}) ==="
        echo "    Manual triage: add a verification step only where it genuinely applies."
        echo "    Inherently advisory skills (classifiers, transcribers, recorders) may stay as-is."
        for s in "${C6_ADVISORY_LIST[@]}"; do
          echo "  $s"
        done
      fi
      
    • scaffold-init.sh 5.6 KB
      #!/bin/bash
      # scaffold-init.sh — substitute {{placeholders}} in a skill scaffold template
      # Usage: bash scripts/scaffold-init.sh --name <name> [options]
      # Output: path to created SKILL.md (stdout)
      
      set -euo pipefail
      
      SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
      SKILL_CREATOR_DIR="$(dirname "$SCRIPT_DIR")"
      
      usage() {
        cat >&2 <<'EOF'
      Usage: bash scaffold-init.sh --name <name> [options]
      
      Required:
        --name <name>               Skill name (hyphen-case)
      
      Optional:
        --description <text>        Skill description
        --layer L1|L2|L3            Skill layer (default: L2)
        --agents single|multi       Agent count (default: single)
        --interaction one-shot|multi-step  Interaction type (default: multi-step)
        --version <semver>          Version (default: 0.1.0)
        --status <status>           Status (default: experimental)
        --slash-trigger <cmd>       Slash trigger, repeatable
        --phrase-trigger <phrase>   Phrase trigger (may include spaces), repeatable
        --gates-required wp|integration|routing  Gate, repeatable
        --gates-enforced wp|integration|routing  Gate, repeatable
        --gates-rationale <text>    Required explanation when no gates declared
        --full                      Use full scaffold template (default: minimal)
        --target <path>             Output path (default: .claude/skills/<name>/SKILL.md)
      EOF
        exit 1
      }
      
      SKILL_NAME=""
      SKILL_DESCRIPTION="TODO: describe this skill"
      SKILL_LAYER="L2"
      SKILL_AGENTS="single"
      SKILL_INTERACTION="multi-step"
      SKILL_VERSION="0.1.0"
      SKILL_STATUS="experimental"
      SKILL_GATES_RATIONALE=""
      USE_FULL=false
      TARGET_PATH=""
      
      declare -a SLASH_TRIGGERS=()
      declare -a PHRASE_TRIGGERS=()
      declare -a GATES_REQUIRED=()
      declare -a GATES_ENFORCED=()
      
      while [[ $# -gt 0 ]]; do
        case "$1" in
          --name)             SKILL_NAME="$2";                 shift 2 ;;
          --description)      SKILL_DESCRIPTION="$2";          shift 2 ;;
          --layer)            SKILL_LAYER="$2";                shift 2 ;;
          --agents)           SKILL_AGENTS="$2";               shift 2 ;;
          --interaction)      SKILL_INTERACTION="$2";          shift 2 ;;
          --version)          SKILL_VERSION="$2";              shift 2 ;;
          --status)           SKILL_STATUS="$2";               shift 2 ;;
          --slash-trigger)    SLASH_TRIGGERS+=("$2");          shift 2 ;;
          --phrase-trigger)   PHRASE_TRIGGERS+=("$2");         shift 2 ;;
          --gates-required)   GATES_REQUIRED+=("$2");          shift 2 ;;
          --gates-enforced)   GATES_ENFORCED+=("$2");          shift 2 ;;
          --gates-rationale)  SKILL_GATES_RATIONALE="$2";      shift 2 ;;
          --full)             USE_FULL=true;                   shift ;;
          --target)           TARGET_PATH="$2";                shift 2 ;;
          -h|--help)          usage ;;
          *) echo "ERROR: Unknown option: $1" >&2; usage ;;
        esac
      done
      
      if [ -z "$SKILL_NAME" ]; then
        echo "ERROR: --name is required" >&2
        usage
      fi
      
      if $USE_FULL; then
        TEMPLATE="$SKILL_CREATOR_DIR/assets/skill-scaffold-full.md"
      else
        TEMPLATE="$SKILL_CREATOR_DIR/assets/skill-scaffold-minimal.md"
      fi
      
      if [ ! -f "$TEMPLATE" ]; then
        echo "ERROR: template not found: $TEMPLATE" >&2
        exit 1
      fi
      
      if [ -z "$TARGET_PATH" ]; then
        TARGET_PATH=".claude/skills/$SKILL_NAME/SKILL.md"
      fi
      mkdir -p "$(dirname "$TARGET_PATH")"
      
      # Build YAML trigger list fragment (4-space indent under slash:/phrases: key)
      build_trigger_yaml() {
        local result=""
        local item
        for item in "$@"; do
          result="${result}    - ${item}"$'\n'
        done
        printf '%s' "$result"
      }
      
      # Build inline YAML list: [] or [a, b, c]
      build_gates_yaml() {
        if [ $# -eq 0 ]; then
          echo "[]"
          return
        fi
        local result="["
        local g
        for g in "$@"; do
          result="${result}${g}, "
        done
        result="${result%, }]"
        echo "$result"
      }
      
      SKILL_SLASH_TRIGGERS="$(build_trigger_yaml "${SLASH_TRIGGERS[@]+"${SLASH_TRIGGERS[@]}"}")"
      SKILL_PHRASE_TRIGGERS="$(build_trigger_yaml "${PHRASE_TRIGGERS[@]+"${PHRASE_TRIGGERS[@]}"}")"
      SKILL_GATES_REQUIRED="$(build_gates_yaml "${GATES_REQUIRED[@]+"${GATES_REQUIRED[@]}"}")"
      SKILL_GATES_ENFORCED="$(build_gates_yaml "${GATES_ENFORCED[@]+"${GATES_ENFORCED[@]}"}")"
      
      if [ "$SKILL_GATES_REQUIRED" = "[]" ] && [ "$SKILL_GATES_ENFORCED" = "[]" ] && [ -z "$SKILL_GATES_RATIONALE" ]; then
        echo "WARNING: gates_required=[] and gates_enforced=[] but --gates-rationale not set." >&2
        echo "         verify-skill.sh will FAIL. Pass --gates-rationale to explain why no gates." >&2
      fi
      
      export SKILL_NAME SKILL_DESCRIPTION SKILL_LAYER SKILL_AGENTS SKILL_INTERACTION
      export SKILL_VERSION SKILL_STATUS SKILL_GATES_RATIONALE
      export SKILL_SLASH_TRIGGERS SKILL_PHRASE_TRIGGERS
      export SKILL_GATES_REQUIRED SKILL_GATES_ENFORCED
      
      python3 - "$TEMPLATE" "$TARGET_PATH" <<'PYEOF'
      import sys, os, pathlib
      
      template_path, output_path = sys.argv[1], sys.argv[2]
      text = pathlib.Path(template_path).read_text()
      
      replacements = {
          "{{name}}":            os.environ["SKILL_NAME"],
          "{{description}}":     os.environ["SKILL_DESCRIPTION"],
          "{{version}}":         os.environ["SKILL_VERSION"],
          "{{status}}":          os.environ["SKILL_STATUS"],
          "{{layer}}":           os.environ["SKILL_LAYER"],
          "{{agents}}":          os.environ["SKILL_AGENTS"],
          "{{interaction}}":     os.environ["SKILL_INTERACTION"],
          "{{slash_triggers}}":  os.environ["SKILL_SLASH_TRIGGERS"],
          "{{phrase_triggers}}": os.environ["SKILL_PHRASE_TRIGGERS"],
          "{{gates_required}}":  os.environ["SKILL_GATES_REQUIRED"],
          "{{gates_enforced}}":  os.environ["SKILL_GATES_ENFORCED"],
          "{{gates_rationale}}": os.environ["SKILL_GATES_RATIONALE"],
      }
      
      for placeholder, value in replacements.items():
          text = text.replace(placeholder, value)
      
      pathlib.Path(output_path).write_text(text)
      PYEOF
      
      echo "$TARGET_PATH"
      
    • verify-skill.sh 4.5 KB
      #!/bin/bash
      # verify-skill.sh — smoke test for a newly created IWE skill
      # Usage: bash scripts/verify-skill.sh <skill-name> [skills-dir]
      
      set -euo pipefail
      
      SKILL_NAME="${1:-}"
      SKILLS_DIR="${2:-.claude/skills}"
      
      if [ -z "$SKILL_NAME" ]; then
        echo "Usage: bash scripts/verify-skill.sh <skill-name> [skills-dir]"
        exit 1
      fi
      
      SKILL_PATH="$SKILLS_DIR/$SKILL_NAME/SKILL.md"
      SKILL_DIR="$SKILLS_DIR/$SKILL_NAME"
      FAILED=0
      
      fail() { echo "FAIL: $1"; FAILED=1; }
      ok()   { echo "OK:   $1"; }
      
      check_frontmatter_fields() {
        local file="$1" label="$2"
        for field in name description version status layer agents interaction; do
          if grep -qE "^${field}:" "$file"; then
            ok "$label frontmatter.$field"
          else
            fail "$label missing frontmatter.$field"
          fi
        done
      }
      
      check_body_sections() {
        local file="$1" label="$2"
        for section in "## When to use" "## Algorithm"; do
          if grep -qF "$section" "$file"; then
            ok "$label section '${section}'"
          else
            fail "$label missing required section '${section}'"
          fi
        done
      }
      
      check_gates() {
        local file="$1"
        local has_req has_enf
        has_req=$(grep -cE "^gates_required:" "$file" || true)
        has_enf=$(grep -cE "^gates_enforced:" "$file" || true)
      
        if [ "$has_req" -eq 0 ] || [ "$has_enf" -eq 0 ]; then
          fail "missing frontmatter: both gates_required and gates_enforced are mandatory"
          return
        fi
        ok "gates_required + gates_enforced present"
      
        local valid_re="^(wp|integration|routing)$"
        for gfield in gates_required gates_enforced; do
          while IFS= read -r v; do
            v_clean=$(echo "$v" | tr -d ' "'"'"'[],'  )
            [ -z "$v_clean" ] && continue
            if ! echo "$v_clean" | grep -qE "$valid_re"; then
              fail "$gfield: unknown value '$v_clean' (allowed: wp, integration, routing)"
            fi
          done < <(grep "^${gfield}:" "$file" | sed 's/^.*\[//;s/\].*//;s/,/\n/g')
        done
      
        local req_empty enf_empty
        req_empty=$(grep "^gates_required:" "$file" | grep -cE "\[\s*\]" || true)
        enf_empty=$(grep "^gates_enforced:" "$file" | grep -cE "\[\s*\]" || true)
        if [ "$req_empty" -gt 0 ] && [ "$enf_empty" -gt 0 ]; then
          local rationale
          rationale=$(grep "^gates_rationale:" "$file" | sed 's/^gates_rationale: *//' | tr -d '"' | xargs)
          if [ -z "$rationale" ]; then
            fail "both gates lists empty but gates_rationale is missing"
          else
            ok "gates_rationale present (no gates declared)"
          fi
        fi
      }
      
      check_bundled_resources() {
        local file="$1" skill_dir="$2"
        grep -qE "^## Bundled resources" "$file" || return 0
        while IFS= read -r line; do
          [[ "$line" =~ ^\-\ \`(scripts|assets)/[^\`]+\` ]] || continue
          local resource="${line#*\`}"
          resource="${resource%%\`*}"
          if [ -f "$skill_dir/$resource" ]; then
            ok "bundled resource exists: $resource"
          else
            fail "bundled resource missing: $skill_dir/$resource"
          fi
        done < "$file"
      }
      
      check_scaffold_templates() {
        local skill_dir="$1"
        for tmpl in "$skill_dir/assets/skill-scaffold-minimal.md" "$skill_dir/assets/skill-scaffold-full.md"; do
          local label
          label="template/$(basename "$tmpl")"
          if [ ! -f "$tmpl" ]; then
            fail "$label missing"
            continue
          fi
          check_frontmatter_fields "$tmpl" "$label"
          check_body_sections "$tmpl" "$label"
        done
      }
      
      check_l1_location() {
        local file="$1" skill_name="$2"
        local layer
        layer=$(grep "^layer:" "$file" | sed 's/^layer: *//' | tr -d '"' | xargs)
        [ "$layer" = "L1" ] || return 0
        local fmt_path="$HOME/IWE/FMT-exocortex-template/.claude/skills/$skill_name/SKILL.md"
        if [ -f "$fmt_path" ]; then
          ok "L1 skill present in FMT-exocortex-template"
        else
          fail "L1 skill not found in FMT ($fmt_path)"
        fi
      }
      
      # --- Main ---
      
      if [ ! -f "$SKILL_PATH" ]; then
        echo "FAIL: $SKILL_PATH not found"
        exit 1
      fi
      
      echo "=== verify-skill: $SKILL_NAME ==="
      
      check_frontmatter_fields "$SKILL_PATH" "skill"
      
      DESC_WORDS=$(grep -A 10 "^description:" "$SKILL_PATH" | sed '1d' | tr '\n' ' ' | wc -w | tr -d ' ')
      if [ "$DESC_WORDS" -ge 10 ]; then
        ok "description length ($DESC_WORDS words)"
      else
        fail "description too short ($DESC_WORDS words, need ≥10)"
      fi
      
      if grep -qE "^triggers:" "$SKILL_PATH"; then
        ok "triggers section"
      else
        fail "missing triggers section"
      fi
      
      check_body_sections "$SKILL_PATH" "skill"
      check_gates "$SKILL_PATH"
      check_bundled_resources "$SKILL_PATH" "$SKILL_DIR"
      [ "$SKILL_NAME" = "skill-creator" ] && check_scaffold_templates "$SKILL_DIR"
      check_l1_location "$SKILL_PATH" "$SKILL_NAME"
      
      echo ""
      if [ "$FAILED" -eq 0 ]; then
        echo "PASS: $SKILL_NAME — all checks passed"
        exit 0
      else
        echo "FAIL: $SKILL_NAME — one or more checks failed (see above)"
        exit 1
      fi
      
  • SKILL.md 10.5 KB
    ---
    name: skill-creator
    description: |
      Create a new IWE skill with proper frontmatter, gates, scaffold and verification.
      Use when the pilot says: /skill-creator or «создай скилл <name>».
      The skill enforces WP Gate precondition, Routing Gate, IntegrationGate hard-check,
      collects parameters in 4 short steps, generates a scaffold SKILL.md from a template,
      shows a draft, writes files, and reminds about verify-skill.sh.
    version: 0.3.2
    status: experimental
    browser_safe: false
    layer: L1
    agents: single
    interaction: multi-step
    gates_required: [wp]
    gates_enforced: [integration, routing]
    gates_rationale: "wp — создание скилла = нетривиальный артефакт (>15 мин), требует согласованного РП до начала (WP Gate precondition). integration — новый скилл-обёртка над инструментом/ролью требует существующих DP.SC.* + DP.ROLE.* до реализации (IntegrationGate hard-block). routing — размещение (Claude/Kimi, project/user, L1-L3) есть решение Routing Gate до scaffold."
    triggers:
      slash:
        - /skill-creator
      phrases:
        - "создай скилл <name>"
        - "новый скилл <name>"
    ---
    
    # /skill-creator — create an IWE skill
    
    > **Scope:** create a new skill OR guide an update to an existing skill in `.claude/skills/` or `.kimi/skills/`.
    > **Not in scope:** full re-scaffold without deleting the old `SKILL.md` first (delete manually, then call `/skill-creator` again); creating a WP; creating a Pack.
    > **Role:** ad-hoc content-role «Инженер скиллов»; formalize in Pack if ≥3 skills/year.
    
    ## When to use
    
    - Pilot wants a new skill for a repeated workflow.
    - A new tool/agent/system needs a Service Clause + Role + SKILL.md.
    - A skill needs promotion from author repo to `FMT-exocortex-template`.
    
    ## Preconditions (checked, not performed)
    
    1. **WP Gate precondition.** The task must be attached to an agreed WP in the weekly plan or explicitly named by the pilot. `/skill-creator` does not conduct the WP Gate ritual itself.
    2. **Routing Gate.** Decide target platform (Claude vs Kimi) and level (project vs user). Default: project-level `.claude/skills/` in the author repo.
    3. **IntegrationGate hard-check.** `DP.SC.*` and `DP.ROLE.*` must exist in the PACK repo. If not, the skill stops and offers to create them. Bypass only by explicit pilot instruction «пропусти gate» — no code flag.
    
    ## Algorithm
    
    ### Step 1 — Check WP Gate precondition
    
    Look up the current weekly plan (`current/WeekPlan W{N}.md`) or ask:
    
    ```
    К какому РП привязано создание скилла?
    ```
    
    If no WP is named and none matches the skill topic → stop:
    
    ```
    Создание скилла требует согласованного РП. Сначала откройте РП через WP Gate.
    ```
    
    ### Step 2 — Routing Gate
    
    Ask or infer:
    
    | Question | Default |
    |----------|---------|
    | Claude или Kimi? | Claude |
    | project-level или user-level? | project-level |
    | governance-репо для учёта? | `${IWE_GOVERNANCE_REPO:-DS-strategy}` |
    
    Target path:
    - Claude project: `.claude/skills/<name>/`
    - Kimi project: `.kimi/skills/<name>/`
    - User level: `~/.claude/skills/<name>/` or `~/.kimi/skills/<name>/`
    
    ### Step 2.5 — Detect existing skill
    
    Check whether `<target_path>/SKILL.md` already exists.
    
    **If it exists** → switch to update mode. Do NOT re-scaffold. Show the pilot:
    
    ```
    Скилл <name> уже существует (версия X.Y.Z).
    Что обновить?
      [ ] description
      [ ] slash / phrase triggers
      [ ] version bump (current: X.Y.Z → new: ?)
      [ ] algorithm step (add / edit)
      [ ] bundled resource (add scripts/ references/ assets/)
      [ ] полный пересоздать → удалите SKILL.md вручную, затем запустите /skill-creator снова
      [ ] отмена → ничего не менять
    ```
    
    Collect the pilot's choices. Apply changes directly to the existing `SKILL.md` via Edit.
    
    Skip Steps 3–6 **unless** the pilot selected "bundled resource" or any change that expands the skill's scope or gates — in that case, run **Step 3 (IntegrationGate)** before applying.
    
    For Step 7 (register + verify): run `verify-skill.sh` always. Run `generate-skills-catalog.sh` only if frontmatter changed (name, description, triggers, version).
    
    Version bump rule: bump patch for trigger / description edits; bump minor for algorithm changes **or adding a bundled resource**; bump major for gate or scope changes.
    
    **If it does not exist** → continue to Step 3 (normal creation flow).
    
    ### Step 3 — IntegrationGate
    
    Check PACK repo for files matching `DP.SC.*` and `DP.ROLE.*`. If missing:
    
    ```
    Service Clause (DP.SC.*) и Role (DP.ROLE.*) не найдены.
    Создайте их сейчас через /pack-new или соответствующий процесс.
    Для продолжения без них скажите явно: «пропусти gate».
    ```
    
    Stop until the gate is satisfied or explicitly bypassed by pilot words.
    
    ### Step 4 — Collect parameters (4 short steps)
    
    **4a. Name and description**
    
    ```
    Имя скилла (hyphen-case): <name>
    Краткое описание — что делает и когда использовать:
    ```
    
    **4b. Agents and interaction axes**
    
    ```
    agents: single | multi
    interaction: one-shot | multi-step
    ```
    
    **4c. Triggers**
    
    ```
    slash-команды (через запятую):
    фразовые триггеры (через запятую):
    ```
    
    Keep phrase triggers narrow: include a skill name placeholder to avoid accidental activation.
    
    **4d. Bundled resources**
    
    ```
    Какие bundled resources нужны?
    [ ] scripts/
    [ ] references/
    [ ] assets/
    ```
    
    Default: `assets/` for scaffold template, `scripts/` for verify script.
    
    ### Step 5 — Generate scaffold
    
    Choose scaffold template based on skill complexity:
    - **Minimal** (`assets/skill-scaffold-minimal.md`): single-step skills without external gates
    - **Full** (`assets/skill-scaffold-full.md`): multi-step skills with Preconditions and Bundled resources
    
    Copy chosen template to target path and substitute:
    - `{{name}}`, `{{description}}`, `{{version}}` (default `0.1.0`), `{{status}}` (default `experimental`)
    - `{{agents}}`, `{{interaction}}`, `{{layer}}`
    - `{{slash_triggers}}`, `{{phrase_triggers}}`
    - `{{gates_rationale}}` — required when `gates_required` and `gates_enforced` are both empty
    
    Create selected bundled resource directories with placeholder files.
    
    ### Step 6 — Show draft
    
    Print generated `SKILL.md` and file list to stdout. No P5 question. Pilot can cancel with:
    
    ```
    /skill-creator undo
    ```
    
    Undo works only before next commit or within 15 minutes.
    
    ### Step 7 — Write files, register, verify
    
    Write files to target path. Then regenerate the catalog and run verify:
    
    ```bash
    bash scripts/generate-skills-catalog.sh   # register in skills-catalog.yaml
    bash scripts/verify-skill.sh <name>       # 33-point structural check
    ```
    
    Both commands must pass before the skill is considered created.
    
    Tell the user where the new skill lives and that nothing preserves it (issue #873): a
    project-local skill under `.claude/skills/<name>/` is usually outside git and outside the
    `day-close.sh` backup, and `update.sh` neither erases nor carries it over. Until the template
    owner picks a backup model, suggest keeping a copy in a git repository the user controls.
    
    For skills with `interaction: multi-step`: run `/vdv audit` on the Algorithm section.
    Not a gate — does not block creation — but catches steps with missing Input/Output linkage
    before the skill is used in practice.
    
    ## Bundled resources
    
    - `assets/skill-scaffold-minimal.md` — scaffold for single-step skills without external gates
    - `assets/skill-scaffold-full.md` — scaffold for multi-step skills with Preconditions and Bundled resources
    - `scripts/verify-skill.sh` — validates frontmatter, gates fields, bundled resource existence, L1 location
    
    ## Known schema gaps
    
    Fields used by some existing skills but not yet in the standard frontmatter schema:
    
    - `argument-hint` — CLI-style hint for script-executor skills (e.g. agent-fault, apply-captures). Encodes the argument contract. Keep until schema is extended or absorbed into `description`.
    - `routing.executor` — indicates whether the skill runs via `script`, `sonnet`, or another executor. Useful for the dispatcher but not validated by `verify-skill.sh`. Candidate for standardization.
    
    Until standardized: leave these fields as-is in existing skills; do not remove during Step 2.5 updates.
    
    ## Known tool gaps
    
    - **`verify-skill.sh` L1 location check for `.kimi/skills/`**: `check_l1_location` only checks `FMT-exocortex-template/.claude/skills/`. For skills placed at `.kimi/skills/` (platform:kimi), the L1 location check is skipped when `layer: L2`, or produces a spurious FAIL when `layer: L1`. Until verify-skill.sh is extended with a `--platform kimi` flag, use `layer: L2` for `.kimi/skills/` test skills, and document any intentional L1 Kimi skills separately.
    - **`content-audit.sh` coverage (Ф9)**: audit script checks 5 structural criteria (gates_rationale, Algorithm section, step headings ≥3, step content ≥2 lines, When-to-use section). 7 YELLOW skills (single C3 issue) are simple alias/mode skills without numbered step headings. This is structural noise, not content error — these skills are functionally correct. See `scripts/content-audit.sh` for full output.
    
    ## Anti-patterns
    
    - Do not create a skill without a linked WP.
    - Do not bypass IntegrationGate with a code flag.
    - Do not put wide phrase triggers like «надо сделать скилл».
    - Run `generate-skills-catalog.sh` after writing files (Step 7) — not before, not manually.
    - Do not make the skill verify itself; use `scripts/verify-skill.sh`.
    - Do not skip `verify-skill.sh` after editing an existing skill — always run it after any update.
    - Do not re-scaffold for minor updates (triggers, description, version bump, algorithm); use Step 2.5 update mode instead. Exception: platform or layer change (e.g. Claude→Kimi, L1→L3) requires a new path and a fresh scaffold — delete old SKILL.md first.
    - Do not forget version bump when changing gates, scope, or algorithm steps (bump minor or major).
    
    ## Verification
    
    After creation, run:
    
    ```bash
    bash scripts/verify-skill.sh <skill-name>
    ```
    
    Expected result: PASS with checks for: valid YAML frontmatter, non-empty description, recognized triggers, `gates_required`/`gates_enforced` fields with valid enum values, bundled resource files exist, scaffold templates valid, L1 skills present in FMT.
    
    <!-- USER-SPACE -->
    <!-- /USER-SPACE -->
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related