refactor(firecrawl): extract maintainer update/drift pipeline into a sibling skill - #743
Conversation
…sibling skill Move the maintainer-facing update/drift-gate pipeline out of the user-facing /firecrawl:firecrawl wrapper skill into a new sibling skill, /firecrawl:update, mirroring the playbooks:update standalone pattern and completing the lookup-vs-setup style split the issue asked for. Moved into plugins/firecrawl/skills/update/: UPSTREAM.md, scripts/update.sh (+ update.test.sh), context/update-flow.md, and the "Updating the skill and CLI" / "Safety" / Preservation-rules sections. The wrapper now carries only its user-facing scrape/search/crawl surface plus a pointer to the update skill; the invocation changes from /firecrawl:firecrawl update to /firecrawl:update. The new skill is user-invocable with disable-model-invocation: true (maintainer- only). No behavior change to the update flow itself. Registers the new update leaf-name collision with playbooks:update, bumps the plugin to 0.4.0, and updates the CHANGELOG and README. Closes #261 Co-Authored-By: Claude <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 3m 19s —— View job Security Review — PR #743
FindingsIMPORTANT —
|
|
Claude finished @kyle-sexton's task in 2m 45s —— View job PR Review —
|
Reword two update.sh log lines that still cited the old "Updating the skill and CLI" section title (that content is now the update skill's Preservation rules), and regenerate the root README.md catalog block so it reflects the firecrawl plugin.json description change. Co-Authored-By: Claude <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 3m 34s —— View job PR Review
|
|
Claude finished @kyle-sexton's task in 4m 10s —— View job Security Review — PR #743
FindingsIMPORTANT —
|
Post-green review classification (rule 8)
Re-run of |
|
Claude finished @kyle-sexton's task in 3m 22s —— View job Security Review — PR #743
Net security posture: improvement over the previous stateBefore this PR, the update action lived inside FindingsSUGGESTION —
|
|
Claude finished @kyle-sexton's task in 2m 34s —— View job PR Review —
|
Babysit classification pass — canonical-token table (current HEAD
|
| # | Finding | Classification | Evidence | Reacted |
|---|---|---|---|---|
| 1 | Security: user-invocable: true makes the maintainer-only skill picker-visible with an npm install -g path |
INCORRECT | Established repo convention: user-invocable: true + disable-model-invocation: true = picker-visible, auto-invoke-blocked. Identical pattern in plugins/context7/skills/setup/SKILL.md and plugins/playbooks/skills/update/SKILL.md. Flipping to false alongside disable-model-invocation: true makes the skill permanently unreachable per skill-frontmatter semantics. Security-review re-run (comment 5026328481) itself downgraded to SUGGESTION / "no action required — the previous reversal stands." |
👎 |
| 2 | Security: unquoted <<EOF heredoc in rewrite_upstream_md enables shell expansion |
INCORRECT | The heredoc must stay unquoted: it interpolates ${sha}/${ver}/${prev}/${today} into UPSTREAM.md. All sources are typed (hex digest, grep -oE '[0-9]+\.[0-9]+\.[0-9]+', date -u), so there is no injection path. Quoting (<<'EOF') would write literal ${...} and fail update.test.sh section-5 assertions, which assert the expanded values appear in the file. |
👎 |
| 3 | PR-review: stale section-name refs in update.sh lines 174/218 ('Updating the skill and CLI') |
VALID — already fixed | Resolved in current HEAD 893b627; both log lines now point at this update skill's own SKILL.md Preservation rules. PR-review re-run (comment 5026328993) confirms "RESOLVED by commit 893b627." |
👍 |
| 4 | PR-review: CHANGELOG [0.4.0] header missing a — YYYY-MM-DD date |
INCORRECT | The stated premise ("all prior entries include a date suffix per Keep-a-Changelog convention") is false. 0 of 358 version headers across every plugins/*/CHANGELOG.md in this repo carry a date suffix — firecrawl's own [0.3.0]/[0.2.2]/[0.2.1] are all dateless. Adding a date to [0.4.0] alone would make it the sole dated header in the repo, manufacturing the exact inconsistency the finding claims to prevent. The repo convention is deliberately dateless headers; no file-wide gap to defer. |
👎 |
| 5 | PR-review observation: allowed-tools glob may not cover the sed in the pre-computed pipeline |
INCORRECT | Non-issue by design. The pre-computed line ends in ` | |
| 6 | PR-review observation: check_prereqs calls exit 2 rather than return when sourced |
INCORRECT | Safe as written, as the reviewer itself noted. The source-guard (update.sh line 291) runs only main when sourced; update.test.sh never sources-then-invokes check_prereqs or main, so exit 2 cannot terminate the test harness. |
👍 |
No code change required at this HEAD — all findings are INCORRECT (with evidence) or already fixed in 893b627. CI is fully green and mergeStateStatus is CLEAN.
…l-update-split # Conflicts: # plugins/firecrawl/.claude-plugin/plugin.json # plugins/firecrawl/CHANGELOG.md
|
Claude finished @kyle-sexton's task in 2m 52s —— View job Security Review — PR #743
Net security posture: improvement over the previous stateThe update action was previously buried inside No security findingsInjection surfaces in
curl poisoning — both calls ( Path traversal — Temp cleanup —
Residual supply-chain risk (pre-existing, not introduced by this PR): Verdict: No security issues found. The refactor is clean and the net change is a security improvement. |
|
Claude finished @kyle-sexton's task in 2m 19s —— View job PR Review —
|
| Check | Conclusion |
|---|---|
ci |
✅ success |
pr-title |
✅ success |
pr-issue-linkage |
✅ success |
do-not-merge |
✅ success |
Prior findings — all resolved or correctly reversed
| # | Finding | Status |
|---|---|---|
Stale section-name refs in update.sh lines 174/218 |
Fixed in 893b627 — log lines now reference "this update skill's SKILL.md Preservation rules" |
|
Security: user-invocable: true on npm install -g path |
Correctly reversed — established repo pattern (user-invocable: true + disable-model-invocation: true); false + true makes the skill permanently unreachable |
|
Security: unquoted <<EOF heredoc |
Correctly reversed — must stay unquoted to interpolate ${sha}/${ver}/${prev} into UPSTREAM.md; quoting would break test assertions |
|
CHANGELOG [0.4.0] missing date |
Correctly reversed — zero entries across all plugins/*/CHANGELOG.md use a date suffix; adding one here would create the inconsistency the finding claimed to prevent |
Verdict: Approve. Merge conflict resolutions are correct, CI is clean, and all review findings from prior passes are either fixed or reversed with solid evidence. Ready to merge.

Summary
The firecrawl plugin bundled its maintainer-facing update/drift-gate pipeline (
UPSTREAM.md,scripts/update.sh,context/update-flow.md, and the "Updating the skill and CLI" / "Safety" / Preservation-rules sections) inside the user-facing/firecrawl:firecrawlwrapper skill. Issue #261 asks to extract it into its own sibling skill.Fix
Extracted the pipeline into a new sibling skill,
/firecrawl:update(user-invocable,disable-model-invocation: true— maintainer-only), modeled on the existingplugins/playbooks/skills/update/SKILL.mdstandalone pattern:git mv'dUPSTREAM.md,scripts/update.sh(+update.test.sh), andcontext/update-flow.mdintoplugins/firecrawl/skills/update/(history preserved).skills/update/SKILL.md; the wrapper now carries only its user-facing scrape/search/crawl surface plus a pointer to the update skill./firecrawl:firecrawl updateto/firecrawl:update; updated all references (wrapper skill,setupskill, the movedupdate.sh/update-flow.md, README). No behavior change to the update flow itself.updateskill-leaf-name collision withplaybooks:updateinscripts/skill-leaf-name-registry.txt(fixed verb per PLUGIN-PHILOSOPHY.md naming table).plugin.json0.3.0 → 0.4.0; top-inserted a CHANGELOG entry.Note: firecrawl already mirrored context7's lookup-vs-setup split (update was an action inside the main skill, as it still is in
context7:lookup). This change goes one step further per the issue's explicit "extract into a sibling" ask, adopting theplaybooks:updatestandalone pattern instead. Whethercontext7should follow suit for cross-plugin consistency is left as a deferred question.Verification
All run against changed files in the worktree:
plugins/firecrawl/skills/update/scripts/update.test.sh— 17/17 checks passedscripts/check-skill-leaf-names.sh --check— all 9 collisions registered (incl. newupdate)scripts/check-changed-skills.sh origin/main— 3 skills checked, 0 failed (firecrawl/setup/update all PASS)scripts/check-skill-portability.sh origin/main— no unexcused coupling tokensshellcheck -xonupdate.sh+update.test.sh— cleanmarkdownlint-cli2on changed.mdfiles — 0 errorsRelated
plugins/playbooks/skills/update/SKILL.mdstandalone maintainer-update pattern.plugins/firecrawl/skills/setup/SKILL.mdalready mirrorscontext7:setup.context7:lookup'supdateaction into acontext7:updatesibling for cross-plugin consistency.Closes #261