fix(build): exclude internal docs/superpowers and docs/plans from wheels-core artifact - #3186
Conversation
…els-core artifact The wheels-core ForgeBox artifact shipped internal AI planning documents (specs, draft PR.md/ISSUE.md files, patches under docs/superpowers/, plus docs/plans/) into every app's vendor/wheels/docs/ because prepare-core.sh did an unfiltered cp -r docs/*. Remove the internal trees from the build dir after the copy, and pin the contract with a structural guard spec. Fixes #3179 Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Wheels Bot — No doc updatesReviewed this PR's diff and found no docs that need updating (purely internal build tooling fix — removes |
There was a problem hiding this comment.
Wheels Bot — Reviewer
TL;DR: This PR stops the wheels-core ForgeBox artifact from shipping the internal docs/superpowers/ and docs/plans/ trees by deleting them from the build dir right after the cp -r docs/* in tools/build/scripts/prepare-core.sh, and pins the contract with a structural source-scan spec. The fix is correct and verified: I confirmed both internal trees exist in docs/, that prepare-core.sh:39 is the only cp -r docs/* site across the four prepare scripts, and that the new exclusion at prepare-core.sh:46 satisfies both of the spec's regexes (I replicated the spec's exact regex logic against all four scripts — prepare-core matches the copy gate and both exclusions; the three siblings correctly short-circuit). Every spec idiom has CI-passing prior art: the IIFE loop-capture, expandPath("/wheels/../.."), and [[:space:]] regexes mirror vendor/wheels/tests/specs/buildArtifactLicenseSpec.cfc:22-59 line-for-line, and [^\n]* inside reFindNoCase matches BotResolveConflictsLoopSafeSpec.cfc:62. Commit conforms to commitlint (fix(build), subject 87 chars, DCO sign-off present); the changelog fragment is in the right place with a valid type. Verdict: comment — no blocking findings, two non-blocking robustness nits on the guard spec below.
Tests
-
vendor/wheels/tests/specs/security/PackageDocsHygieneSpec.cfc:57-62— the guard asserts presence of the exclusion, not its position relative to the copy.var excludesTree = reFindNoCase( "rm[[:space:]]+-rf[^\n]*docs/" & tree, src ) > 0;A future refactor that moves the
rm -rfabove thecp -r docs/*(where it becomes a no-op against a not-yet-populated build dir) would still pass this guard while re-shipping the leak. SincereFindNoCasereturns a position, the check can pin ordering for free:var copyPos = reFindNoCase("cp[[:space:]]+-r[[:space:]]+docs/\*", src); var rmPos = reFindNoCase("rm[[:space:]]+-rf[^\n]*docs/" & tree, src); expect(rmPos > copyPos).toBeTrue(...);Non-blocking — the precedent spec (
buildArtifactLicenseSpec.cfc) is also presence-only, but there ordering doesn't matter, whereas here it does. -
PackageDocsHygieneSpec.cfc:50-53— the copy-detection gate is narrow, and a non-match passes silently.var copiesDocs = reFindNoCase( "cp[[:space:]]+-r[[:space:]]+docs/\*", src ) > 0;Variants like
cp -rf docs/*,cp -a docs/*, orrsync -a docs/wouldn't match the gate, so a script using one of them would take the vacuous-pass branch while still shipping the internal trees. Broadening the flag match (e.g.cp[[:space:]]+-[a-z]*r[a-z]*[[:space:]]+docs/) would close the most likely drift. Non-blocking — structural guards are inherently approximate and this pins the canonical form, but unlike the LICENSE precedent (where a non-match fails the assertion), here a non-match silently passes, so the gate's narrowness is the guard's weakest point.
Everything else checked out: the spec is BDD wheels.WheelsTest (not RocketUnit), ## is correctly escaped in string literals, there is no inline-closure-as-constructor-arg, no reserved-scope parameter names, and the PR body honestly discloses that the live CFML runner wasn't executed in the author sandbox (the regex logic was independently re-verified here against the actual scripts).
|
Superseded by #3194 (merged): a propose-fix draft that raced the ForgeBox path-repair campaign for the same issue; the campaign PR landed first and closed the underlying issue. Closing the duplicate. |
Summary
The published wheels-core ForgeBox artifact shipped internal AI planning documents into every app's
vendor/wheels/docs/.tools/build/scripts/prepare-core.shdid an unfilteredcp -r docs/*, sweepingdocs/superpowers/(planning specs, draftPR.md/ISSUE.mdfiles,.patchartifacts) anddocs/plans/into the package — 75 internal files in the 4.0.3 zip. These are working documents, not user documentation. This PR removes both internal trees from the build dir immediately after the docs copy and pins the contract with a structural guard spec so the exposure cannot reappear.Related Issue
Fixes #3179
Type of Change
What changed
tools/build/scripts/prepare-core.sh— aftercp -r docs/* "${BUILD_DIR}/wheels/docs/", addrm -rf "${BUILD_DIR}/wheels/docs/superpowers" "${BUILD_DIR}/wheels/docs/plans".vendor/wheels/tests/specs/security/PackageDocsHygieneSpec.cfc— structural source-scan guard (mirrors the existingbuildArtifactLicenseSpec.cfcpattern) asserting that any prepare script which copies the full docs tree also excludes the internal trees. The three sibling scripts (prepare-base.sh,prepare-cli.sh,prepare-starterApp.sh) do not copydocs/*today, so they pass vacuously — the guard covers them so a copy-paste can't reintroduce the leak.changelog.d/3179-core-package-internal-docs.fixed.md— changelog fragment.TDD: failing → passing
The spec is a pure source-scan, so the fail→pass transition was validated deterministically by running its exact regex logic against the script before and after the fix:
prepare-core.sh):cp -r docs/*present (line 39), norm -rf … docs/superpowersand norm -rf … docs/plans→ the two prepare-core assertions fail.rm -rf … docs/{superpowers,plans}present → prepare-core passes; siblings short-circuit (nodocs/*copy) → pass.Feature Completeness Checklist
Signed-off-by:PackageDocsHygieneSpec.cfc, failing-then-passing (validated via the spec's regex logic; see above)bot-update-docs.ymlbot-update-docs.ymlbot-update-docs.ymlchangelog.d/3179-core-package-internal-docs.fixed.mdwheelsCLI)Test Plan
bash tools/test-local.sh security(or full suite) —PackageDocsHygieneSpecpasses on the fixed script.docs/superpowersappears in any build dir. Left out here to keep scope tight; tracked as a follow-up.