diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 77bd48f..75564bd 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -6,7 +6,7 @@ }, "metadata": { "description": "Claude skills for Dynamicweb 10 — organized by task domain, bundled by role.", - "version": "4.9.0" + "version": "4.10.0" }, "plugins": [ { diff --git a/CHANGELOG.md b/CHANGELOG.md index a392f63..2fe91fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to the Dynamicweb Skills plugin are recorded here. The `version` field in `.claude-plugin/marketplace.json` tracks these entries. +## [4.10.0] + +Retires the external scrub-list file: the fold-back's sanitize gate now derives the +engagement-token list in-session, from the material being folded, instead of reading a +per-engagement file that routinely did not exist at the documented path. + +### Changed +- **`dw-demo-base/references/iterate-plugin.md`** (Step 1a): the grep pack's token list is + enumerated in-conversation each fold — any token that could leak is by construction present + in the material being folded (notes, learnings file, demo folder, `CUSTOMISATIONS.md`). + The enumeration checklist now names the shapes to cover: brand names incl. misspellings and + slugs, hostnames, persona/account names, engagement domain vocabulary (field names, example + products), and demo-minted ids/paths/credentials. The constant packs (session-relative time, + customer-path shape) are unchanged. +- Added a mandatory **adversarial re-read** of the staged diff: for every concrete string, ask + "Dynamicweb-generic, or engagement-derived?" — the grep catches only enumerated tokens; the + re-read catches the rest. + +### Removed +- The `scrub-list.txt` file mechanism (location contract, stub-creation step, "when to expand + the known-names list" section) and its `Get-Content` in the final pre-commit grep. + ## [4.9.0] Splits the publish path into its own reference and folds a second hosted-publish build's diff --git a/skills/dw-demo-base/references/iterate-plugin.md b/skills/dw-demo-base/references/iterate-plugin.md index 950485b..85d0769 100644 --- a/skills/dw-demo-base/references/iterate-plugin.md +++ b/skills/dw-demo-base/references/iterate-plugin.md @@ -122,29 +122,28 @@ squash-merged to the integration branch the recovery is the expensive history re ### The grep pack — run BEFORE the file gets edited AND in the PR gate A learning's drafted text often sits in `./notes/skill-learnings-*.md` first; that's where to -scrub. The same grep runs against the staged edit before commit. The pack ships in a -per-engagement scrub-list file, NOT committed into the repo — keeping the actual tokens out of -public blobs. - -**Location of the scrub-list file:** `$DYNAMICWEB_SKILLS_REPO\..\..\scrub-list.txt` (one level -above the local clone, gitignored by construction since it lives outside the repo). One token -per line; blank lines and `#` comments allowed. The file ships seeded with the known -historical leaks from prior engagements + the current engagement's slug. - -If the file doesn't exist, the fold-back creates a stub on first run and asks the user to add -the current engagement's tokens before proceeding. +scrub. The same grep runs against the staged edit before commit. + +**There is no scrub-list file — the token list is derived in-session, every fold.** Any token +that could leak into the edit is, by construction, present in the material being folded (the +session notes, the learnings file, the demo folder, `CUSTOMISATIONS.md`). Before drafting, +enumerate the engagement's tokens explicitly and write the list out in the conversation so the +user can review it. Enumerate at least: + +- customer / brand / engagement names, **including misspellings and slugs** (folder names, + hostnames, `.mydwsiteN.com` subdomains); +- persona and account names (buyers, CSRs, admins, distributor/dealer accounts); +- engagement domain vocabulary — field names, category names, example products only this + customer would use. A winery demo's `GrapeVariety` field or a "Reserve Pinot" example + product identifies the engagement as surely as its name does; +- ids, paths, and credentials minted for the demo. ```powershell -# Build the regex pack from the external list (paths shown — adapt to where you cloned). -$scrubList = "$env:DYNAMICWEB_SKILLS_REPO\..\..\scrub-list.txt" -if (-not (Test-Path $scrubList)) { - Write-Error "Scrub-list missing at $scrubList — create it (one token per line) before folding." - return -} -$tokens = Get-Content $scrubList | Where-Object { $_ -and -not $_.StartsWith('#') } +# 1. Engagement tokens — enumerated from the session context above, never read from a file. +$tokens = @('BrandName', 'brand-slug', 'brand.mydwsiteN.com', 'Persona Name' <# … #>) $nameRx = ($tokens | ForEach-Object { [regex]::Escape($_) }) -join '|' -# 1. Source notes +# Source notes Select-String -Path .\notes\skill-learnings-*.md -Pattern $nameRx # Staged edit (run from $DYNAMICWEB_SKILLS_REPO before commit) git diff --staged | Select-String -Pattern $nameRx @@ -165,6 +164,13 @@ derivative learning that's vendor-generic — then carry only the vendor-generic the edit. Two paragraphs side-by-side in the conversation is fine: "what happened (named)" → "what's the durable lesson (generic)". Only the generic side gets committed. +**The grep only catches tokens you enumerated; the re-read catches the rest.** After drafting, +read the staged diff once as an outsider and ask of every concrete string — every name, field, +example value, path, id — "is this Dynamicweb-generic, or did it come from the engagement?" +Anything engagement-derived gets genericized even if it looks harmless in isolation. This +re-read is mandatory, not a nicety: enumeration misses exactly the tokens you didn't think of, +and those are the ones that leak. + ### When the structural learning seems to depend on the customer's name It almost never does. If the rule is "demo X did Y and learned Z", `Z` is the durable part. @@ -176,14 +182,6 @@ The same rule applies to vendor / partner / customer **individuals**. Architectu rewritten as "vendor-blessed by the `` (`` architecture call)". The provenance value is the role + date, not the person. -### When to expand the known-names list - -When a new customer engagement opens, add the customer slug (and any personal names in play) -to the off-repo scrub-list file BEFORE the first fold for that demo. The fold-back should ask -once per session: *"Any new customer/personal names to add to the scrub pack for this -engagement?"* — additions go to the scrub-list file, never into the repo. Future folds inherit -the expanded pack. - ## Step 1b — Content-hygiene gate (load-bearing — this is how the corpus stays correct) Sanitization protects the customer; this step protects the *corpus*. Fold-backs that skip it @@ -346,8 +344,7 @@ Do **not** add `Co-Authored-By` or any self-attribution line (repo rule, `CLAUDE staged change including the message): ```powershell -$tokens = Get-Content "$env:DYNAMICWEB_SKILLS_REPO\..\..\scrub-list.txt" | - Where-Object { $_ -and -not $_.StartsWith('#') } +$tokens = @('BrandName', 'brand-slug' <# the same in-session token list from Step 1a #>) $nameRx = ($tokens | ForEach-Object { [regex]::Escape($_) }) -join '|' $timeRx = "Today's |today's |This morning|this morning|Yesterday[^\s]"