feat(skill-creator): six corrections a real update cycle exposed (1.22.0) - #195
Merged
Merged
Conversation
3 tasks
daymade
force-pushed
the
feat/skill-creator-registry-and-description-budget
branch
from
July 22, 2026 16:01
215e274 to
693db0d
Compare
daymade
force-pushed
the
feat/skill-creator-registry-and-description-budget
branch
from
August 4, 2026 12:32
8bd958a to
ee929aa
Compare
…2.0) Distilled from using this skill to ship consecutive updates to an existing skill. Each item is a place the guidance let a predictable mistake through — none are hypothetical improvements. 1. Description budget (Write the SKILL.md) The 1024-character ceiling was never stated anywhere, so an update adding trigger phrases for newly-covered scope blew past it and needed two rounds of compression to land. That ceiling is in direct tension with the existing "make it pushy" advice, and the tension deserves naming rather than discovery while fighting a validator. The sharper point: a mature description usually sits close to the limit, which makes adding a trigger zero-sum — you are deleting an existing one to pay for it. That is a real narrowing of when the skill fires, so it must be a conscious, recorded trade. Also ranks what to sacrifice: prose qualifiers are re-derivable from the body, distinct trigger phrases are not. 2. Registry minimal-diff (Step 8) The marketplace manifest is the single file every skill shares, so it is the likeliest place for two concurrent editors to collide — and the worst place to ship an unrelated formatting change. Scripted bumps silently normalize trailing newline, indent width, key order, unicode escaping. The step now requires a round-trip check that git diff shows only the intended fields. (A scripted bump once added a trailing newline to a manifest that never had one. This commit's own bump was round-tripped under the new rule: one line.) 3. Activation check (Edit Skills at Source Location) "Sync the installed copy" is frequently not work at all, and the workflow never said how to tell. A symlinked skills directory, or a marketplace with source: directory, reads the working tree — the edit is already live. Only cached/copied installs need the official update command. Verification must be by content, not by a recorded version string: one session read a plugin record naming a cache directory that had the new version in its path and nearly reported the update as live. That directory had never been created; the real runtime path was a symlink to the source. 4. Production-as-eval gains a second signal source (Capture Intent) When a skill's output is something that keeps running — a guard, a monitor, a scheduled job, a hook — its own telemetry is eval data, and the first false alarm is the highest-signal record in it. A user correction requires a user to notice and bother; a deployed mechanism reports on itself unprompted, often within a day. A false positive proves a rule you wrote is wrong in a way re-reading never would, so treat the first one as a scheduled eval result rather than an annoyance — the likely finding is that the instruction was too absolute. 5. Concurrency covers branch switching, not just a moved HEAD The existing rule said to re-check HEAD's SHA before committing. That is not the worst thing a parallel session does. A checkout is worktree-wide, so while one session edits on a feature branch, another running `checkout main` + pull silently relocates the whole worktree — and the next commit lands on main, violating the repo's never-commit-to-local-main rule, while the feature branch still points at the old base. Exactly that happened during this work. The pre-commit check gains `git branch --show-current`; `git reflog` is the authoritative post-mortem (it records every "checkout: moving from X to Y" in order); and the repair is deliberately ref-only — `checkout -B` then `branch -f` — because both move refs without touching the working tree, so unlike `reset --hard` they cannot destroy a parallel session's uncommitted work. 6. PR staleness, and the proof step everyone skips The property that makes a shared manifest a collision hotspot also makes any open PR touching it go stale. CONFLICTING is the expected state, not a surprise — this PR itself sat through 69 commits of main. Rebase (not merge) where the repo squash-merges. The conflicts are almost always additive: two authors appended an entry to the same section, so keep both, and --ours/--theirs would silently drop a colleague's line. What is missing from most workflows is the verification AFTER resolving: prove the only difference from the base is your own entry. The section ships a copy-paste check that diffs every version in the base manifest against yours. Finally --force-with-lease rather than bare --force, since its entire value is failing in the one case that matters: somebody else pushed to your branch. Rebased onto current main (69 commits ahead of the original base) and rebuilt without touching the working tree, because a sibling session had uncommitted work in the two files this touches — the plumbing route (temporary index + commit-tree) is the practice item 5 is about. Verified: quick_validate passes; audit_skill_regression compare/classify/verify passes with two candidates (production-as-eval and the HEAD-check rule, both extended in place) classified preserved_or_moved with the original clauses intact and locatable; security_scan clean; manual read-through of every added line for private paths/names; manifest bump round-tripped to a one-line diff. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F6FQSPAyXY9WZJYUToxXXY
daymade
force-pushed
the
feat/skill-creator-registry-and-description-budget
branch
from
August 4, 2026 16:55
ee929aa to
d806412
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Six corrections to
skill-creator, distilled from using it to ship consecutive updates to an existing skill. Every item is a place the guidance let a predictable mistake through — none are hypothetical improvements.1. Description budget (Write the SKILL.md)
The 1024-character ceiling was never stated anywhere, so an update adding trigger phrases for newly-covered scope blew past it and needed two rounds of compression to land. That ceiling is in direct tension with the existing "make it pushy" advice, and the tension deserves naming rather than discovery while fighting a validator.
The sharper point: a mature description usually sits close to the limit, which makes adding a trigger zero-sum — you are deleting an existing one to pay for it. That is a real narrowing of when the skill fires, so it must be a conscious, recorded trade. Also ranks what to sacrifice first: prose qualifiers are re-derivable from the body, distinct trigger phrases are not.
2. Registry minimal-diff (Step 8)
The marketplace manifest is the single file every skill shares, which makes it the likeliest place for two concurrent editors to collide — and therefore the worst place to ship an unrelated formatting change. Scripted bumps silently normalize trailing newline, indent width, key order, and unicode escaping. The step now requires a round-trip check that
git diffshows only the fields you meant to change.(A scripted bump once added a trailing newline to a manifest that had never had one. This PR's own bump was round-tripped under the new rule — its manifest diff is exactly one line.)
3. Activation check (Edit Skills at Source Location)
"Sync the installed copy" is frequently not work at all, and the workflow never said how to tell. A symlinked skills directory, or a marketplace with
source: directory, reads the working tree — the edit is already live. Only cached/copied installs need the official update command.Verification must be by content, not by a recorded version string: one session read a plugin record naming a cache directory that had the new version number in its path and nearly reported the update as live. That directory had never been created; the real runtime path was a symlink to the source.
4. Production-as-eval gains a second signal source (Capture Intent)
When a skill's output is something that keeps running — a guard, a monitor, a scheduled job, a hook — its own telemetry is eval data, and the first false alarm is the highest-signal record in it. A user correction requires a user to notice and bother; a deployed mechanism reports on itself unprompted, often within a day. A false positive proves a rule you wrote is wrong in a way re-reading never would, so treat the first one as a scheduled eval result rather than an annoyance — the likely finding is that the instruction was too absolute.
5. Concurrency covers branch switching, not just a moved HEAD
The existing rule said to re-check HEAD's SHA before committing. That is not the worst thing a parallel session does. A checkout is worktree-wide, so while one session edits on a feature branch, another running
checkout main+pullsilently relocates the whole worktree — and the next commit lands onmain, violating the repo's never-commit-to-local-mainrule, while the feature branch still points at the old base. Exactly that happened during this work.The pre-commit check gains
git branch --show-current;git reflogis the authoritative post-mortem (it records everycheckout: moving from X to Yin order); and the repair is deliberately ref-only —checkout -Bthenbranch -f— because both move refs without touching the working tree, so unlikereset --hardthey cannot destroy a parallel session's uncommitted work.6. PR staleness, and the proof step everyone skips
The property that makes a shared manifest a collision hotspot also makes any open PR touching it go stale.
CONFLICTINGis the expected state, not a surprise — this PR itself sat through 69 commits of main. Rebase (not merge) where the repo squash-merges.The conflicts are almost always additive: two authors appended an entry to the same section, so keep both, and
--ours/--theirswould silently drop a colleague's line. What is missing from most workflows is the verification after resolving: prove the only difference from the base is your own entry. The section now ships a copy-paste check that diffs every version in the base manifest against yours. Finally--force-with-leaserather than bare--force, since its entire value is failing in the one case that matters: somebody else pushed to your branch.Rebase note (items 5 and 6, dogfooded)
The original branch was 69 commits behind. A sibling session had uncommitted work in both files this PR touches (
marketplace.json,CHANGELOG.md), sogit checkoutto the PR branch would have been refused — and forcing it would have dragged their WIP along.Rebuilt via the plumbing route instead, which never touches the working tree: extract the current
origin/mainfiles → apply this PR's changes in a scratch dir →hash-object→ temporaryGIT_INDEX_FILE→write-tree→commit-tree→update-ref. The sibling session's 8 uncommitted files were byte-identical before and after.Version target moved
1.15.0→1.22.0(main advanced to 1.21.0 meanwhile). Verified none of the six items had been independently added upstream in the interim:1024,force-with-lease,branch --show-current,CONFLICTING,telemetryeach appear 0 times in main's currentSKILL.md.Verification
quick_validate— passesaudit_skill_regressioncompare → classify → verify — passes; two candidates (the production-as-eval bullet and the HEAD-check rule, both extended in place) classifiedpreserved_or_movedwith the original clauses intact and locatable in the current filesecurity_scan— clean; plus a manual read-through of every added line for private paths / project names{'daymade-skill': ('1.21.0', '1.22.0')}— nothing else, 58 plugin entries before and after,metadata.versionuntouched🤖 Generated with Claude Code
https://claude.ai/code/session_01F6FQSPAyXY9WZJYUToxXXY
Re-rebase (2026-08-05)
Rebased onto current
mainagain — cleanly, no conflicts. The version target is unchanged:mainis still atdaymade-skill 1.21.0, so this still lands 1.22.0. Re-verified that none of the six items had been added upstream meanwhile:1024,branch --show-current,force-with-lease,zero-sum,first false alarm,reflogeach appear 0 times in main's currentSKILL.md.Gates re-run against the new base:
quick_validatepasses; regression audit compare → classify → verify passes (2 candidates, both the production-as-eval bullet and the HEAD-check rule extended in place, classifiedpreserved_or_movedwith the original clauses located verbatim);security_scanclean plus a manual line-by-line read of every added line. A trial merge with #210 is conflict-free in both orders and yields the same tree.An independent fresh-context review of the rebase confirmed the patch payload is byte-identical to the pre-rebase branch (md5 match on both sides), the manifest changes exactly one line, and nothing from
mainwas lost.