Claude Cursor Skill

skmtc-retro

Run a self-retrospective on a SKMTC-related session — generator authoring, CLI configuration, debugging, or any sustained interaction involving `@skmtc/core`, `@skmtc/cli`, or `@skmtc/gen-*` packages. Captures three distinct outputs: (1) friction entries (mistakes, surprises, ove

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

Full trust report

Download skmtc-skmtc-deno_docs_skills_skmtc-retro-e3abffc.zip · 12 KB
skmtc/skmtc 19 0 forks Apache-2.0 Updated 7d ago
Part of skmtc/skmtc — 12 skills

Install

skills CLI npx skills add https://github.com/skmtc/skmtc/tree/main/deno/docs/skills/skmtc-retro
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install skmtc-skmtc@llmmart
Git git clone https://github.com/skmtc/skmtc.git

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

Skill manifest

SKMTC retro

Capture the three categories of output only the LLM can produce — friction entries, knowledge acquired, and a priority ranking — and write them to a per-session file so they can be reviewed and acted on. The primary goal is actionable signal: what broke, what was unknown, and where to spend effort next. Wins are secondary and only worth logging when they identify something uncodified.

1. When to invoke

Run a retro after substantive SKMTC work:

  • Authoring a new generator (scaffold → working output)
  • Cloning a stock generator and editing it
  • Multi-step debugging of a failing generation
  • Non-trivial CLI configuration (multi-generator setup, complex enrichments)
  • Any session that involved 3+ generate-test cycles

Skip retros for:

  • Quick lookups or single-command tasks
  • Sessions that ended in immediate success with no friction
  • Re-runs of work already covered by an earlier retro file

Always retro when:

  • The user explicitly invokes this skill (any session length)
  • The user asks "what did we learn?", "retro this", or similar

2. Locate the friction-log directory and pick a filename

The canonical location:

<skmtc-root>/skmtc/deno/docs/friction-log/

<skmtc-root> is the directory containing skmtc/ and skmtc-generators/. To resolve:

  1. Walk up from the current working directory looking for a skmtc/deno/docs/friction-log/ directory.
  2. If <skmtc-root> cannot be located, ask the user where the friction log lives or whether to create one. Do not silently default to a fallback path.

Filename convention

Each retro produces one file per session, named:

<YYYY-MM-DD>-<short-summary>.md
  • <YYYY-MM-DD> — ISO date (today's date in the session's local time).
  • <short-summary> — 3-4 word kebab-case description of the session's primary topic. Lowercase, hyphen-separated, no trailing date or numbers unless needed for disambiguation.

Examples:

  • 2026-05-12-create-retro-skill.md
  • 2026-05-13-shadcn-form-clone.md
  • 2026-05-14-enrichment-design-spike.md
  • 2026-05-15-debug-empty-output.md

The summary should capture what makes this session distinct from others on the same date. Pick the dominant topic if a session covered multiple areas; entries inside the file can still span several concerns.

Same-date collisions

If a file with the proposed name already exists (same date, same topic), append entries to that file rather than creating a duplicate. If a session on the same date has a genuinely different topic, use a different summary so the filenames differ naturally (e.g., 2026-05-12-create-retro-skill.md and 2026-05-12-shadcn-form-spike.md coexist).

One session = one file. No batches inside a file.

Entries are added continuously as observations occur, not batched into rounds. Do not introduce ## Round N: <topic> or ## Pass N: <topic> sections inside an entry file — they impose a chronological-batch structure on top of the already-stable per-entry numbering and make the file harder to skim.

When work genuinely splits into distinct phases — different scope, different day's focus, different audit pass — that's a signal you have separate sessions, and each warrants its own file with a distinct <short-summary> slug. Examples for the same date:

  • 2026-05-12-tutorial-docs-audit.md
  • 2026-05-12-claude-md-audit.md
  • 2026-05-12-how-to-docs-audit.md

This is preferable to one 2026-05-12-docs-audit.md carved into ## Round 1, ## Round 2, ## Round 3. Each file remains self-contained, its index reflects only its own entries, and cross-file references (<filename>#<N>) handle any genuine linkage between sessions.

The rule is forward-looking — existing legacy files that use round-N sections do not need to be retroactively split unless their content is being substantially edited.

Reading existing files

Before writing, read any existing file you'll be appending to to match its numbering and avoid duplicate observations. You do not need to read every file in the directory — each file is self-contained and entries don't cross-reference unless explicitly stated.

3. The reflection prompts

The most valuable observations are ones a human reviewer of the final code cannot reconstruct. Before drafting entries, work through these questions explicitly. They are the leverage of this skill.

For friction

  • What surprised you? (API shapes, method-vs-property, error messages, behaviour that didn't match expectation)
  • Where did you override a default suggestion from training data? (E.g., you almost wrote a config flag, but cloned instead.)
  • What did you have to guess about? (Naming conventions, file layout, where a helper lives, which method to call.)
  • Where did you spend multiple cycles fighting the same thing?
  • What did you write that felt non-idiomatic — a sense that SKMTC has a better way that you couldn't find?
  • Where was an error message unhelpful for diagnosing the cause?
  • What invariant did you almost violate and have to back out from?

For wins (high bar — codification candidates only)

Win entries are not "this felt smooth." They are "I observed a pattern that should be the prescribed approach and isn't written down yet." Log a win only when you can answer yes to: If another agent did this task tomorrow without this observation, would they likely do it wrong?

  • What pattern did you use that isn't yet codified in a skill or doc, but clearly should be?
  • Where did the architecture or type system enforce a correct approach in a way worth teaching explicitly?

If nothing passes this bar, omit the wins section entirely. A session with zero wins is normal and preferable to fabricated signal.

For knowledge acquired

This is the highest-value section for improving docs. Ask: What do I now know about SKMTC that I did not know at the start of this session? These are not friction entries — they are knowledge-gap closures.

  • What API shape, method signature, or runtime behaviour did you have to discover by trial or reading source, rather than from docs or training data?
  • What naming convention, file layout, or configuration key was absent from training data and had to be inferred?
  • Where did you rely on analogy from another framework that turned out to be wrong or only partially correct?
  • What constraint or invariant did you not know existed until you hit it (e.g., single-base rule, location-independence requirement)?
  • What would you want to tell the next agent doing this task that isn't written anywhere?

Capture each item concisely — the table format in §4 is designed for this. Include the implication for docs: "this belongs in the generator skill," "this needs a how-to doc," "this is a missing API reference entry," etc.

4. File format

The session file structure:

# <YYYY-MM-DD> — <Session topic>

<1-2 sentences describing what work was happening in this session.>

## Knowledge acquired

<1 sentence framing what domain this session operated in.>

| # | What I learned | Doc implication |
|---|----------------|-----------------|
| K1 | <concise fact — API shape, constraint, naming rule, invariant> | <skill / how-to doc / API reference / none> |
| K2 | ... | ... |

*If nothing genuinely new was learned, write: "No new SKMTC knowledge
acquired this session — all patterns matched prior training or
existing documentation."*

## Index

| # | Entry | Severity | Status |
|---|-------|----------|--------|
| 1 | <Entry heading> | friction | open |
| 2 | <Entry heading> | win | open |

---

### 1. <Entry heading> [severity]
...

### 2. <Entry heading> [severity]
...

---

## Priority for docs/skills

Top findings from this session, ranked by leverage for improving docs,
skills, or SKMTC itself. The user uses this list to decide what to act
on first — be specific about the action path.

| Rank | Entry | Why it matters | Action path |
|------|-------|----------------|-------------|
| 1 | #N — <heading> | <one sentence> | skill update / how-to doc / API reference / SKMTC code |
| 2 | ... | ... | ... |

Limit to 3 entries. If fewer than 3 stand out, list only those that do.

The Index

The ## Index block sits between the session description and the first --- divider. Its purpose is to let a reader (agent or human) scan the file's contents and the status of every entry in seconds, without paging through the body.

Index rules:

  • One row per entry, in the same order as the entries themselves.
  • # column matches the entry's stable number from §"Numbering".
  • Entry column is the entry's heading text without the trailing [severity] tag (severity gets its own column). Truncate with … if the heading exceeds ~80 characters; the body is the authoritative version.
  • Severity column is the bare tag (blocker, friction, polish, win) — no brackets.
  • Status column mirrors the entry's **Status:** field verbatim, but condensed. Typical values:
    • open — unresolved
    • resolved <YYYY-MM-DD> — resolved on that date (optionally with a commit/PR ref, e.g., resolved 2026-05-15 (PR #142))
    • superseded by <filename>#<N> — observation rolled into a later entry
    • wontfix — explicitly closed without action

The index is derived data: every value must match what's in the body. When the two disagree, the body is the source of truth and the index is wrong — fix the index.

Maintaining the index

The index must be updated every time the body changes:

  • Adding an entry: append a new row with the next sequential #, matching heading, severity, and Status: open.
  • Resolving an entry: update the body's **Status:** line first, then mirror the change to the matching index row.
  • Editing an entry's heading or severity: update both places in the same edit. The body and index must never drift.

If you only have time to update one of the two, update the body. A correct body with a stale index is recoverable; a stale body is not.

Entry format

### N. <Descriptive heading> [severity]

<Concise context — what part of the work this was observed in.>

**What happened:** <concrete description, with code/commands where
relevant>

**What was expected:** <the assumption that turned out wrong; omit if
not applicable, e.g., for wins>

**Why it matters:** <the underlying principle the friction violates,
or the pattern the win exemplifies. This is the highest-value field —
spend the most effort here.>

**Possible fixes:** <open-ended; 1–3 suggestions if obvious, or
"unresolved — needs reflection" if not. **Do NOT pre-commit to a
category of fix** (skill change vs doc change vs code change). Leaving
this open encourages contemplation during periodic review rather than
locking in the first idea.>

**Version anchor:** `@skmtc/core@<version>`, `@skmtc/gen-<name>@<version>`
(record whatever generators and core version the observation was made
against)

**Status:** open

Severity tags

  • [blocker] — no workaround found; session got stuck
  • [friction] — workaround exists; cost real time/cycles
  • [polish] — annoying but not blocking
  • [win] — a pattern worth codifying that isn't already in a skill or doc. Not "this worked well" — only "another agent would likely do this wrong, and the correct approach isn't written down."

Apply [win] sparingly. A session with no wins is normal. If everything that worked smoothly is already codified, don't log it.

Numbering

Entries within a single file are numbered sequentially starting at 1. Numbers are stable within the file — once assigned, they don't change. Cross-file references use <filename>#<N> format, e.g., "see 2026-05-12-create-retro-skill.md #2".

There is no global numbering across files. Each session file is self-contained.

5. What NOT to log

  • Operational principles already documented in llms.md or the skmtc-cli / skmtc-generator skills — those are already captured; logging them is noise. Exception: if the doc exists but you couldn't find it, log that as a discoverability gap in ## Knowledge acquired — the doc's existence doesn't mean it's working.
  • Trivial typos or one-line corrections that aren't part of a pattern.
  • Domain-specific decisions from the consumer project (e.g., the naming of a field in someone's app) — only observations about SKMTC itself.
  • Things the user already explicitly flagged during the session.
  • "I made a mistake" without a SKMTC-level lesson — a tutorial gap, a skill gap, an API surprise, or a generalisable pattern is what makes an observation worth logging.

If a session genuinely produced no new observations beyond what's already in the log or the skills, say so explicitly rather than inventing entries to fill the retro. False signal is worse than no signal.

6. Entry length

Trivial observations: 1 paragraph. Subtle patterns: 2–3 paragraphs, sometimes with a code example or comparison table. The log's value comes from specificity, not brevity. Length should match what's needed to make the entry reproducible by someone reading it months later.

7. Composing the retro

The full flow:

  1. Generate the filename for this session: <YYYY-MM-DD>-<short-summary>.md using today's date and a 3-4 word kebab-case description of the session's primary topic.
  2. Check if the file already exists (same-date, same-topic continuation):
    • If yes: read the existing file, note the highest entry number and the current state of the ## Index block, prepare to append.
    • If no: prepare to create a new file with the session header and an empty ## Index table (§4 "File format").
  3. Reflect — mentally walk through the session, applying the reflection prompts from §3. Distinguish genuinely new observations from things already captured.
  4. Draft the ## Knowledge acquired table — what you now know that you didn't know at session start (see §3 "For knowledge acquired"). Be concise per row. Include doc implication. If nothing qualifies, write the explicit "nothing new" note from §4.
  5. Draft entries — friction first, then wins (only if they pass the codification bar from §3) — using the format from §4. Number sequentially from the current high-water mark (1 if new file).
  6. Draft the ## Priority for docs/skills table — pick the top 2-3 entries (friction or knowledge items) by leverage. One sentence per entry on why it matters. Specify the action path.
  7. Write the file (create or append). Do not modify earlier entries. Update the ## Index block in the same write to include a row for every new entry. If you're appending to an existing file whose index is missing or out of date, rebuild it from the body in the same pass — the index must always match the body when you finish.
  8. Summarise to the user in one short message: Logged N entries (X friction, Y wins) to <filename>. Knowledge acquired: K items. Top priority: <entry heading>.

8. Examples

High-value knowledge acquired row

## Knowledge acquired

Working on a cloned `gen-shadcn-form`, registering imports and fields.

| # | What I learned | Doc implication |
|---|----------------|-----------------|
| K1 | `register({ imports })` accepts string OR object `{ name, alias?, isType? }` per import. String and object are NOT equivalent — object form always produces `name as alias` output even when alias is omitted. | Missing from generator skill §import-registration; needs a note + example |
| K2 | The single-base rule (one factory base per package) applies to cloned generators too — cloning doesn't grant an exception. | Already in memory, but not in SKILL.md; add to §generator-constraints |

High-value entry (LLM-unique observation)

6. ImportNameArg shape is overloaded with no warning [friction]

Working on a cloned gen-shadcn-form, registering imports for field components.

What happened: The register({ imports }) API accepts either a plain string or an object { name, alias?, isType? } per import. I assumed the object shape was a richer-spec-string — passed { name: 'TextField', isType: false } to mark a plain non-type export. The output became import {name as TextField} from '...' instead of import {TextField}.

What was expected: that { name: 'TextField', isType: false } would be equivalent to the bare string 'TextField'.

Why it matters: the object shape is a footgun for the most common case (plain non-type import). The semantic difference between string and object is invisible from the type signature.

Possible fixes: unresolved — the engine could normalize { name: 'X', isType: false } to 'X', or the skill could warn against this shape, or the type could be tightened so only isType: true is acceptable in object form.

Version anchor: @skmtc/core@^0.3.7, @skmtc/gen-shadcn-form@0.0.55

Status: open

Low-value entry (already documented; don't log)

7. as casts not allowed in production code [friction]

Tried to use as Schema to satisfy types. The user pointed out the codebase prefers type guards.

This is already in the skmtc-generator skill's operational principles table. Logging it adds noise without signal.

9. After the retro

Retro files are append-only for entry bodies. The user reviews them daily and decides whether each entry becomes a skill update, a doc update, a SKMTC code change, or a deferred reflection point. Do not pre-commit to those resolutions in the entry — leave the "Possible fixes" section open-ended. When an entry is resolved, the user (or the skill, on its next pass through the file) updates two places with the resolution date and a link to the relevant commit or PR:

  1. The entry's **Status:** line in the body.
  2. The matching row in the ## Index table.

The index and body must remain in lockstep — see §4 "Maintaining the index".

If you notice during the retro that the skill itself has a gap (a missing reflection prompt, an unclear instruction, a case the format doesn't handle well), log that as a retro entry too — the recursive case is high-leverage. The skill should improve from its own output.

Files (skmtc)
  • commands
    • CLAUDE.md 324 B
      <claude-mem-context>
      # Recent Activity
      
      <!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
      
      ### May 12, 2026
      
      | ID | Time | T | Title | Read |
      |----|------|---|-------|------|
      | #20765 | 11:41 AM | 🔄 | Relocated skmtc-retro skill to unified docs structure | ~437 |
      </claude-mem-context>
    • skmtc-retro.md 2.4 KB
      ---
      description: Run a SKMTC retrospective on the current session — capture friction and wins to the friction log
      argument-hint: "[topic-summary]"
      ---
      
      Run a SKMTC retrospective on this session.
      
      **If `$ARGUMENTS` is non-empty**, use it as the session-topic hint for
      the filename. Normalize it to lowercase kebab-case (e.g.,
      `"Shadcn form clone"` → `shadcn-form-clone`). Use as the
      `<short-summary>` portion of the filename described in step 2 below.
      
      **If `$ARGUMENTS` is empty**, infer the topic from the session content
      yourself — pick the 3-4 word kebab-case description that captures what
      made this session distinct from others on the same date.
      
      Then follow the standard retro flow (full details in the `skmtc-retro`
      skill's `SKILL.md`):
      
      1. **Locate the friction-log directory.** Walk up from the current
         working directory looking for `skmtc/deno/docs/friction-log/`. If
         you can't find a SKMTC root, ask the user where to log to — do not
         silently default.
      
      2. **Pick a filename for this session** following the convention
         `<YYYY-MM-DD>-<short-summary>.md` using today's date and the topic
         summary from `$ARGUMENTS` (or inferred).
      
      3. **Check for an existing file** with the same name:
         - If it exists, read it and prepare to append at the next
           sequential entry number.
         - If not, prepare to create a new file with the session header
           (see the skill's §4 "File format").
      
      4. **Reflect on the session** using the prompts from the skill's §3.
         Capture both friction (surprises, default overrides, multi-cycle
         struggles, idiomatic gaps) and wins (patterns worth preserving).
      
      5. **Draft entries** in the skill's standard format: severity tag,
         what happened, what was expected, why it matters, possible fixes
         (open-ended — **do not pre-commit to a category of fix**), version
         anchor, status.
      
      6. **Write the file** (create or append). Append-only — do not modify
         earlier entries.
      
      7. **Summarise to the user** in one short line:
         `Logged N entries (X friction, Y wins) to <filename>. Headings: ...`
      
      If the session genuinely produced no new observations beyond what's
      already captured in the skills or the existing friction log, **say so
      explicitly** rather than inventing entries. False signal is worse than
      no signal.
      
      For full conventions, format details, reflection prompts, and worked
      examples, defer to the `skmtc-retro` skill's `SKILL.md`.
      
  • CLAUDE.md 324 B
    <claude-mem-context>
    # Recent Activity
    
    <!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
    
    ### May 12, 2026
    
    | ID | Time | T | Title | Read |
    |----|------|---|-------|------|
    | #20765 | 11:41 AM | 🔄 | Relocated skmtc-retro skill to unified docs structure | ~437 |
    </claude-mem-context>
  • design.md 5.5 KB
    # skmtc-retro skill — design document
    
    > Brief design document for the retro skill, written retroactively for
    > symmetry with the other skills in this directory.
    >
    > The loadable skill is [`SKILL.md`](SKILL.md); the slash command is
    > [`commands/skmtc-retro.md`](commands/skmtc-retro.md).
    
    ## Purpose
    
    Capture observations only the LLM can see — guesses, default
    overrides, surprises, idiomatic gaps, and patterns worth preserving —
    from a SKMTC session, and write them to a per-session dated file in
    the project's friction log so they can be reviewed and acted on later.
    
    Distinct from the other three skills by being **meta-work**:
    `skmtc-cli`, `skmtc-generator`, and `skmtc-debug` guide doing
    something. `skmtc-retro` guides reflecting *on* what was done.
    
    ## Audience
    
    Anyone who's just completed a substantive SKMTC session. Not
    role-specific; applies to users, authors, and debuggers alike.
    
    The defining trigger is **end-of-session reflection**, not a kind of
    work. The skill is explicitly not for ordinary work flow.
    
    ## Triggers
    
    - "retro" / "skmtc retro"
    - "log friction"
    - "reflect on this session"
    - "what did we learn"
    - "run a retrospective"
    - Slash command: `/skmtc-retro [topic-summary]`
    
    Should not auto-load during ordinary work — only at session
    boundaries or on explicit invocation.
    
    ## Scope boundary
    
    ### In skill
    
    - The reflection prompts (the questions to ask before drafting entries)
    - The per-session-file naming convention (`<YYYY-MM-DD>-<short-summary>.md`)
    - The entry format (severity tag, what-happened, what-expected,
      why-it-matters, possible-fixes, version anchor, status)
    - The "no category-of-fix tag" constraint (per user preference)
    - Examples of high-value vs low-value entries
    - The "say nothing if there's nothing new" rule
    
    ### Deferred
    
    - The friction log conventions doc: [`../../friction-log/README.md`](../../friction-log/README.md)
    - The full operational principles (in [`../../llms.md`](../../llms.md))
    - Per-skill anti-patterns (in each skill's SKILL.md)
    
    ### Boundary with other skills
    
    - **skmtc-cli / skmtc-generator / skmtc-debug**: the doing-skills. The
      retro skill activates only after one of these has produced
      observable session content worth reflecting on.
    
    ## Design decisions
    
    A few choices that were made deliberately during the skill's authoring:
    
    ### Per-session files, not a single growing log
    
    Files named `<YYYY-MM-DD>-<short-summary>.md`. Reasoning: ISO date
    prefix sorts chronologically; per-file numbering is simpler than
    global; concurrent sessions don't conflict; topic-distinct sessions
    on the same date coexist via the summary portion.
    
    ### No category-of-fix tag
    
    Per explicit user direction. Auto-tagging "this is a skill gap" the
    moment friction is observed forecloses contemplation about the *best*
    fix in favor of the *obvious* fix. Leaving "Possible fixes"
    open-ended encourages reflection during periodic review rather than
    locking in the first idea.
    
    ### Severity tags
    
    Four tiers (`[blocker]`, `[friction]`, `[polish]`, `[win]`). The
    `[win]` tag has a high bar: not "this felt smooth" but "another agent
    would likely do this wrong, and the correct approach isn't written
    down." Sessions with zero wins are normal and preferable to fabricated
    signal. The review skill handles pattern-level "what to preserve"
    analysis across sessions.
    
    ### Skip-criteria for trivial sessions
    
    Explicit "skip retros for" rules — quick lookups, single-command
    tasks, sessions with no friction. Counters the risk that embedded
    retro practice produces noise from every interaction. Substantive
    work only.
    
    ### False signal is worse than no signal
    
    The skill explicitly empowers the LLM to produce *nothing* if there's
    nothing genuinely new to log. Counters the default LLM behavior of
    "produce output to fill the request."
    
    ### The recursive case
    
    If the skill itself has a gap (a missing reflection prompt, an
    unclear instruction, a case the format doesn't handle well), the LLM
    logs that as a retro entry. The skill should improve from its own
    output.
    
    ## Open design questions
    
    ### Should the friction-log file location be discovered or hardcoded?
    
    Currently the skill walks up from CWD looking for
    `skmtc/deno/docs/friction-log/`. This is portable across machines
    but adds discovery cost. Alternative: project-relative path in a
    config file. Defer until the discovery cost becomes a problem.
    
    ### Mid-session retros
    
    Currently the skill is positioned as end-of-session. Could also be
    useful as a mid-session checkpoint ("log this observation before we
    keep going"). The skill's wording supports this; explicit invocation
    overrides the "substantive work" filter.
    
    ### Cross-session pattern surfacing
    
    Addressed by the `skmtc-retro-review` skill: it reads all session
    files for a period, clusters entries by root cause, and reports the
    Friction Recurrence Rate. See
    [`../skmtc-retro-review/design.md`](../skmtc-retro-review/design.md).
    
    ### Wins vs friction balance
    
    The retro skill raises the bar for wins (codification candidates only)
    to reduce noise. Pattern-level "wins" — approaches worth prescribing
    across sessions — are surfaced by the `skmtc-retro-review` skill
    during periodic review, not per-session. The review monitors whether
    wins appear at all; if not, the bar may need recalibrating.
    
    ## Cross-references
    
    - Skill: [`SKILL.md`](SKILL.md)
    - Slash command: [`commands/skmtc-retro.md`](commands/skmtc-retro.md)
    - Review skill (actuator): [`../skmtc-retro-review/SKILL.md`](../skmtc-retro-review/SKILL.md)
    - Friction log conventions: [`../../friction-log/README.md`](../../friction-log/README.md)
    - LLM doc operational reference: [`../../llms.md`](../../llms.md)
    
  • SKILL.md 19.5 KB
    ---
    name: skmtc-retro
    version: 0.2.0
    description: |
      Run a self-retrospective on a SKMTC-related session — generator
      authoring, CLI configuration, debugging, or any sustained interaction
      involving `@skmtc/core`, `@skmtc/cli`, or `@skmtc/gen-*` packages.
      Captures three distinct outputs: (1) friction entries (mistakes,
      surprises, overridden defaults, multi-cycle struggles), (2) a
      "knowledge acquired" block recording facts the agent learned during
      the session that weren't in its training — the primary signal for doc
      gaps — and (3) a closing priority list ranking the top 2-3 findings
      for docs/skills triage. Wins are logged only when they identify a
      pattern worth codifying that isn't already in a skill.
    
      Use this skill when the user asks to "retro", "skmtc retro", "log
      friction", "reflect on this session", "what did we learn", "run a
      retrospective", or after substantive SKMTC work (generator authoring,
      multi-step debugging, non-trivial CLI configuration) where capturing
      observations would help improve skills, docs, or SKMTC itself.
    
      Distinct from the `skmtc-cli` and `skmtc-generator` skills — those
      guide *doing* the work; this skill captures observations *about* the
      work. Do not invoke this skill during ordinary work; it is end-of-
      session (or mid-session-checkpoint) only.
    allowed-tools:
      - Read
      - Write
      - Edit
      - Glob
      - Grep
      - Bash
    metadata:
      internal: true
    ---
    
    # SKMTC retro
    
    Capture the three categories of output only the LLM can produce —
    friction entries, knowledge acquired, and a priority ranking — and
    write them to a per-session file so they can be reviewed and acted on.
    The primary goal is actionable signal: what broke, what was unknown,
    and where to spend effort next. Wins are secondary and only worth
    logging when they identify something uncodified.
    
    ## 1. When to invoke
    
    **Run a retro after substantive SKMTC work:**
    
    - Authoring a new generator (scaffold → working output)
    - Cloning a stock generator and editing it
    - Multi-step debugging of a failing generation
    - Non-trivial CLI configuration (multi-generator setup, complex enrichments)
    - Any session that involved 3+ generate-test cycles
    
    **Skip retros for:**
    
    - Quick lookups or single-command tasks
    - Sessions that ended in immediate success with no friction
    - Re-runs of work already covered by an earlier retro file
    
    **Always retro when:**
    
    - The user explicitly invokes this skill (any session length)
    - The user asks "what did we learn?", "retro this", or similar
    
    ## 2. Locate the friction-log directory and pick a filename
    
    The canonical location:
    
    ```
    <skmtc-root>/skmtc/deno/docs/friction-log/
    ```
    
    `<skmtc-root>` is the directory containing `skmtc/` and `skmtc-generators/`.
    To resolve:
    
    1. Walk up from the current working directory looking for a
       `skmtc/deno/docs/friction-log/` directory.
    2. If `<skmtc-root>` cannot be located, ask the user where the
       friction log lives or whether to create one. Do not silently
       default to a fallback path.
    
    ### Filename convention
    
    Each retro produces **one file per session**, named:
    
    ```
    <YYYY-MM-DD>-<short-summary>.md
    ```
    
    - `<YYYY-MM-DD>` — ISO date (today's date in the session's local time).
    - `<short-summary>` — 3-4 word kebab-case description of the session's
      primary topic. Lowercase, hyphen-separated, no trailing date or
      numbers unless needed for disambiguation.
    
    Examples:
    
    - `2026-05-12-create-retro-skill.md`
    - `2026-05-13-shadcn-form-clone.md`
    - `2026-05-14-enrichment-design-spike.md`
    - `2026-05-15-debug-empty-output.md`
    
    The summary should capture **what makes this session distinct** from
    others on the same date. Pick the dominant topic if a session covered
    multiple areas; entries inside the file can still span several
    concerns.
    
    ### Same-date collisions
    
    If a file with the proposed name already exists (same date, same
    topic), **append entries to that file** rather than creating a
    duplicate. If a session on the same date has a genuinely different
    topic, use a different summary so the filenames differ naturally
    (e.g., `2026-05-12-create-retro-skill.md` and
    `2026-05-12-shadcn-form-spike.md` coexist).
    
    ### One session = one file. No batches inside a file.
    
    Entries are added **continuously** as observations occur, not
    batched into rounds. Do **not** introduce `## Round N: <topic>` or
    `## Pass N: <topic>` sections inside an entry file — they impose a
    chronological-batch structure on top of the already-stable
    per-entry numbering and make the file harder to skim.
    
    When work genuinely splits into distinct phases — different scope,
    different day's focus, different audit pass — that's a signal you
    have **separate sessions**, and each warrants its own file with a
    distinct `<short-summary>` slug. Examples for the same date:
    
    - `2026-05-12-tutorial-docs-audit.md`
    - `2026-05-12-claude-md-audit.md`
    - `2026-05-12-how-to-docs-audit.md`
    
    This is preferable to one `2026-05-12-docs-audit.md` carved into
    `## Round 1`, `## Round 2`, `## Round 3`. Each file remains
    self-contained, its index reflects only its own entries, and
    cross-file references (`<filename>#<N>`) handle any genuine
    linkage between sessions.
    
    The rule is forward-looking — existing legacy files that use
    round-N sections do not need to be retroactively split unless their
    content is being substantially edited.
    
    ### Reading existing files
    
    Before writing, **read any existing file you'll be appending to** to
    match its numbering and avoid duplicate observations. You do **not**
    need to read every file in the directory — each file is self-contained
    and entries don't cross-reference unless explicitly stated.
    
    ## 3. The reflection prompts
    
    The most valuable observations are ones a human reviewer of the final
    code cannot reconstruct. Before drafting entries, work through these
    questions explicitly. They are the leverage of this skill.
    
    ### For friction
    
    - What **surprised** you? (API shapes, method-vs-property, error
      messages, behaviour that didn't match expectation)
    - Where did you **override a default suggestion** from training data?
      (E.g., you almost wrote a config flag, but cloned instead.)
    - What did you have to **guess** about? (Naming conventions, file
      layout, where a helper lives, which method to call.)
    - Where did you **spend multiple cycles** fighting the same thing?
    - What did you write that **felt non-idiomatic** — a sense that SKMTC
      has a better way that you couldn't find?
    - Where was an **error message unhelpful** for diagnosing the cause?
    - What **invariant** did you almost violate and have to back out from?
    
    ### For wins (high bar — codification candidates only)
    
    Win entries are not "this felt smooth." They are "I observed a pattern
    that should be the prescribed approach and isn't written down yet." Log
    a win only when you can answer yes to: *If another agent did this task
    tomorrow without this observation, would they likely do it wrong?*
    
    - What pattern did you use that **isn't yet codified** in a skill or
      doc, but clearly should be?
    - Where did the architecture or type system **enforce a correct
      approach** in a way worth teaching explicitly?
    
    If nothing passes this bar, omit the wins section entirely. A session
    with zero wins is normal and preferable to fabricated signal.
    
    ### For knowledge acquired
    
    This is the highest-value section for improving docs. Ask: *What do I
    now know about SKMTC that I did not know at the start of this session?*
    These are not friction entries — they are knowledge-gap closures.
    
    - What **API shape, method signature, or runtime behaviour** did you
      have to discover by trial or reading source, rather than from docs or
      training data?
    - What **naming convention, file layout, or configuration key** was
      absent from training data and had to be inferred?
    - Where did you rely on **analogy from another framework** that turned
      out to be wrong or only partially correct?
    - What **constraint or invariant** did you not know existed until you
      hit it (e.g., single-base rule, location-independence requirement)?
    - What would you want to **tell the next agent** doing this task that
      isn't written anywhere?
    
    Capture each item concisely — the table format in §4 is designed for
    this. Include the implication for docs: "this belongs in the generator
    skill," "this needs a how-to doc," "this is a missing API reference
    entry," etc.
    
    ## 4. File format
    
    The session file structure:
    
    ```markdown
    # <YYYY-MM-DD> — <Session topic>
    
    <1-2 sentences describing what work was happening in this session.>
    
    ## Knowledge acquired
    
    <1 sentence framing what domain this session operated in.>
    
    | # | What I learned | Doc implication |
    |---|----------------|-----------------|
    | K1 | <concise fact — API shape, constraint, naming rule, invariant> | <skill / how-to doc / API reference / none> |
    | K2 | ... | ... |
    
    *If nothing genuinely new was learned, write: "No new SKMTC knowledge
    acquired this session — all patterns matched prior training or
    existing documentation."*
    
    ## Index
    
    | # | Entry | Severity | Status |
    |---|-------|----------|--------|
    | 1 | <Entry heading> | friction | open |
    | 2 | <Entry heading> | win | open |
    
    ---
    
    ### 1. <Entry heading> [severity]
    ...
    
    ### 2. <Entry heading> [severity]
    ...
    
    ---
    
    ## Priority for docs/skills
    
    Top findings from this session, ranked by leverage for improving docs,
    skills, or SKMTC itself. The user uses this list to decide what to act
    on first — be specific about the action path.
    
    | Rank | Entry | Why it matters | Action path |
    |------|-------|----------------|-------------|
    | 1 | #N — <heading> | <one sentence> | skill update / how-to doc / API reference / SKMTC code |
    | 2 | ... | ... | ... |
    
    Limit to 3 entries. If fewer than 3 stand out, list only those that do.
    ```
    
    ### The Index
    
    The `## Index` block sits between the session description and the
    first `---` divider. Its purpose is to let a reader (agent or human)
    scan the file's contents and the status of every entry in seconds,
    without paging through the body.
    
    Index rules:
    
    - **One row per entry**, in the same order as the entries themselves.
    - **`#` column** matches the entry's stable number from §"Numbering".
    - **`Entry` column** is the entry's heading text **without** the
      trailing `[severity]` tag (severity gets its own column). Truncate
      with `…` if the heading exceeds ~80 characters; the body is the
      authoritative version.
    - **`Severity` column** is the bare tag (`blocker`, `friction`,
      `polish`, `win`) — no brackets.
    - **`Status` column** mirrors the entry's `**Status:**` field
      verbatim, but condensed. Typical values:
      - `open` — unresolved
      - `resolved <YYYY-MM-DD>` — resolved on that date (optionally with
        a commit/PR ref, e.g., `resolved 2026-05-15 (PR #142)`)
      - `superseded by <filename>#<N>` — observation rolled into a later
        entry
      - `wontfix` — explicitly closed without action
    
    The index is **derived data**: every value must match what's in the
    body. When the two disagree, the body is the source of truth and the
    index is wrong — fix the index.
    
    ### Maintaining the index
    
    The index must be updated **every time the body changes**:
    
    - **Adding an entry:** append a new row with the next sequential `#`,
      matching heading, severity, and `Status: open`.
    - **Resolving an entry:** update the body's `**Status:**` line first,
      then mirror the change to the matching index row.
    - **Editing an entry's heading or severity:** update both places in
      the same edit. The body and index must never drift.
    
    If you only have time to update one of the two, update the body. A
    correct body with a stale index is recoverable; a stale body is not.
    
    ### Entry format
    
    ```markdown
    ### N. <Descriptive heading> [severity]
    
    <Concise context — what part of the work this was observed in.>
    
    **What happened:** <concrete description, with code/commands where
    relevant>
    
    **What was expected:** <the assumption that turned out wrong; omit if
    not applicable, e.g., for wins>
    
    **Why it matters:** <the underlying principle the friction violates,
    or the pattern the win exemplifies. This is the highest-value field —
    spend the most effort here.>
    
    **Possible fixes:** <open-ended; 1–3 suggestions if obvious, or
    "unresolved — needs reflection" if not. **Do NOT pre-commit to a
    category of fix** (skill change vs doc change vs code change). Leaving
    this open encourages contemplation during periodic review rather than
    locking in the first idea.>
    
    **Version anchor:** `@skmtc/core@<version>`, `@skmtc/gen-<name>@<version>`
    (record whatever generators and core version the observation was made
    against)
    
    **Status:** open
    ```
    
    ### Severity tags
    
    - `[blocker]` — no workaround found; session got stuck
    - `[friction]` — workaround exists; cost real time/cycles
    - `[polish]` — annoying but not blocking
    - `[win]` — a pattern worth codifying that isn't already in a skill
      or doc. Not "this worked well" — only "another agent would likely
      do this wrong, and the correct approach isn't written down."
    
    Apply `[win]` sparingly. A session with no wins is normal. If
    everything that worked smoothly is already codified, don't log it.
    
    ### Numbering
    
    Entries within a single file are numbered sequentially starting at 1.
    Numbers are stable **within the file** — once assigned, they don't
    change. Cross-file references use `<filename>#<N>` format, e.g.,
    "see `2026-05-12-create-retro-skill.md` #2".
    
    There is no global numbering across files. Each session file is
    self-contained.
    
    ## 5. What NOT to log
    
    - Operational principles already documented in `llms.md` or the
      `skmtc-cli` / `skmtc-generator` skills — those are already captured;
      logging them is noise. **Exception:** if the doc exists but you
      couldn't find it, log that as a discoverability gap in `## Knowledge
      acquired` — the doc's existence doesn't mean it's working.
    - Trivial typos or one-line corrections that aren't part of a pattern.
    - Domain-specific decisions from the consumer project (e.g., the
      naming of a field in someone's app) — only observations about SKMTC
      itself.
    - Things the user already explicitly flagged during the session.
    - "I made a mistake" without a SKMTC-level lesson — a tutorial gap, a
      skill gap, an API surprise, or a generalisable pattern is what makes
      an observation worth logging.
    
    If a session genuinely produced no new observations beyond what's
    already in the log or the skills, **say so explicitly** rather than
    inventing entries to fill the retro. False signal is worse than no
    signal.
    
    ## 6. Entry length
    
    Trivial observations: 1 paragraph. Subtle patterns: 2–3 paragraphs,
    sometimes with a code example or comparison table. The log's value
    comes from specificity, not brevity. Length should match what's
    needed to make the entry reproducible by someone reading it months
    later.
    
    ## 7. Composing the retro
    
    The full flow:
    
    1. **Generate the filename** for this session: `<YYYY-MM-DD>-<short-summary>.md`
       using today's date and a 3-4 word kebab-case description of the
       session's primary topic.
    2. **Check** if the file already exists (same-date, same-topic
       continuation):
       - If yes: read the existing file, note the highest entry number
         and the current state of the `## Index` block, prepare to append.
       - If no: prepare to create a new file with the session header and
         an empty `## Index` table (§4 "File format").
    3. **Reflect** — mentally walk through the session, applying the
       reflection prompts from §3. Distinguish genuinely new observations
       from things already captured.
    4. **Draft the `## Knowledge acquired` table** — what you now know
       that you didn't know at session start (see §3 "For knowledge
       acquired"). Be concise per row. Include doc implication. If nothing
       qualifies, write the explicit "nothing new" note from §4.
    5. **Draft entries** — friction first, then wins (only if they pass
       the codification bar from §3) — using the format from §4. Number
       sequentially from the current high-water mark (1 if new file).
    6. **Draft the `## Priority for docs/skills` table** — pick the top
       2-3 entries (friction or knowledge items) by leverage. One sentence
       per entry on why it matters. Specify the action path.
    7. **Write** the file (create or append). Do not modify earlier
       entries. **Update the `## Index` block in the same write** to
       include a row for every new entry. If you're appending to an
       existing file whose index is missing or out of date, rebuild it
       from the body in the same pass — the index must always match the
       body when you finish.
    8. **Summarise to the user** in one short message:
       `Logged N entries (X friction, Y wins) to <filename>. Knowledge acquired: K items. Top priority: <entry heading>.`
    
    ## 8. Examples
    
    ### High-value knowledge acquired row
    
    ```markdown
    ## Knowledge acquired
    
    Working on a cloned `gen-shadcn-form`, registering imports and fields.
    
    | # | What I learned | Doc implication |
    |---|----------------|-----------------|
    | K1 | `register({ imports })` accepts string OR object `{ name, alias?, isType? }` per import. String and object are NOT equivalent — object form always produces `name as alias` output even when alias is omitted. | Missing from generator skill §import-registration; needs a note + example |
    | K2 | The single-base rule (one factory base per package) applies to cloned generators too — cloning doesn't grant an exception. | Already in memory, but not in SKILL.md; add to §generator-constraints |
    ```
    
    ### High-value entry (LLM-unique observation)
    
    > ### 6. `ImportNameArg` shape is overloaded with no warning [friction]
    >
    > Working on a cloned `gen-shadcn-form`, registering imports for field
    > components.
    >
    > **What happened:** The `register({ imports })` API accepts either a
    > plain string or an object `{ name, alias?, isType? }` per import. I
    > assumed the object shape was a richer-spec-string — passed
    > `{ name: 'TextField', isType: false }` to mark a plain non-type
    > export. The output became `import {name as TextField} from '...'`
    > instead of `import {TextField}`.
    >
    > **What was expected:** that `{ name: 'TextField', isType: false }`
    > would be equivalent to the bare string `'TextField'`.
    >
    > **Why it matters:** the object shape is a footgun for the most
    > common case (plain non-type import). The semantic difference between
    > string and object is invisible from the type signature.
    >
    > **Possible fixes:** unresolved — the engine could normalize
    > `{ name: 'X', isType: false }` to `'X'`, or the skill could warn
    > against this shape, or the type could be tightened so only `isType:
    > true` is acceptable in object form.
    >
    > **Version anchor:** `@skmtc/core@^0.3.7`, `@skmtc/gen-shadcn-form@0.0.55`
    >
    > **Status:** open
    
    ### Low-value entry (already documented; don't log)
    
    > ### 7. `as` casts not allowed in production code [friction]
    >
    > Tried to use `as Schema` to satisfy types. The user pointed out the
    > codebase prefers type guards.
    
    This is already in the `skmtc-generator` skill's operational
    principles table. Logging it adds noise without signal.
    
    ## 9. After the retro
    
    Retro files are append-only for **entry bodies**. The user reviews
    them daily and decides whether each entry becomes a skill update, a
    doc update, a SKMTC code change, or a deferred reflection point. Do
    not pre-commit to those resolutions in the entry — leave the
    "Possible fixes" section open-ended. When an entry is resolved, the
    user (or the skill, on its next pass through the file) updates **two
    places** with the resolution date and a link to the relevant commit
    or PR:
    
    1. The entry's `**Status:**` line in the body.
    2. The matching row in the `## Index` table.
    
    The index and body must remain in lockstep — see §4 "Maintaining the
    index".
    
    If you notice during the retro that **the skill itself** has a gap (a
    missing reflection prompt, an unclear instruction, a case the format
    doesn't handle well), log that as a retro entry too — the recursive
    case is high-leverage. The skill should improve from its own output.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related