agentsclimarketplace

Accelerate learn

Skill humanmade/accelerate-ai-toolkit/skills/accelerate-learn

Update what the toolkit has learned about your site from A/B test results. Run periodically to improve future recommendations.From its SKILL.md

Install
npx -y skills add humanmade/accelerate-ai-toolkit --skill accelerate-learn

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 8 stars8 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its file declares

Copied from the file, not written here

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

15.9 KB, as published. Nobody here has run it

Accelerate -- Update your site's learning journal

You read the site's completed A/B test results, classify each experiment into a canonical suggestion pattern, and update the site's learning journal so every other skill can tailor future recommendations to what has worked here.

This skill is read-only on WordPress. You never create, modify, or stop experiments. You write two local files only.

Step 1 -- Fetch site context

Call accelerate/get-site-context with include_blocks: false. You need site.name, site.theme (when present), and site.url to derive the site key.

Site key derivation rule

This is the canonical rule. No other skill implements its own version. The key identifies one site's design — the thing we are optimizing — so it combines the site's name, its active theme, and a stable hash of its URL.

Key format: <site-name-slug>-<theme-slug>-<url-hash>

Build each segment:

  1. site-name-slug — slugify site.name from get-site-context: lowercase, replace any run of non-alphanumeric characters with a single hyphen, strip leading/trailing hyphens. Example: "Example Co." -> example-co.

  2. theme-slug — slugify site.theme from get-site-context the same way, if it is present. If get-site-context does not return a theme (older plugin versions don't expose it), omit this segment entirely and fall back to <site-name-slug>-<url-hash>. Never error or block on a missing theme — degrade gracefully.

  3. url-hash — a short, stable hash of the full site.url (including protocol, host, and port). Take the first 8 hex characters of its md5:

    printf '%s' "<site.url>" | md5sum | cut -c1-8   # or: md5 -q -s "<site.url>" | cut -c1-8 on macOS
    

Examples:

  • name "Example Co.", theme "twentytwentyfour", url https://www.example.com:8080 -> example-co-twentytwentyfour-3f9a2c11
  • same site on a plugin that doesn't expose the theme -> example-co-3f9a2c11

Why the theme is in the key: two sites can share a display name yet be different things we must not mix — a staging copy and its production original commonly share a name but run different themes, and the design (the palette, typography, and section vocabulary we optimize) is tied to the theme, not the name. Including the theme keeps their journals and brand context separate. The URL hash separates same-named sites that share a host (e.g. several local sites on localhost), which a bare hostname cannot.

The bare hostname is banned as the key. Deriving the key from site.url's host alone collides every site that shares a host (all local sites resolve to localhost) and silently cross-contaminates their learning history. Always use the name + theme + hash format above.

No migration of old flat files. Earlier toolkit versions stored flat journal-<hostname>.* and brand-<hostname>.md files keyed on the hostname. Those are abandoned, not migrated — on first run under the new key a fresh per-site journal starts. The old flat files can be deleted manually; the toolkit never reads them again.

Per-site store layout

Each site's files live in a per-site subdirectory keyed by the rule above:

  • ~/.config/accelerate-ai-toolkit/sites/<key>/journal.json — machine-readable journal (source of truth)
  • ~/.config/accelerate-ai-toolkit/sites/<key>/journal.md — human-readable summary, regenerated from the JSON
  • ~/.config/accelerate-ai-toolkit/sites/<key>/brand.md — brand context (design tokens; generated by accelerate-test)
  • ~/.config/accelerate-ai-toolkit/sites/<key>/palette.json — cached structure palette (surveyed by accelerate-test)

The shared ~/.config/accelerate-ai-toolkit/env credentials file stays where it is — it is not per-site.

Step 2 -- List completed experiments

Call accelerate/list-experiments with:

status: "completed"
type: "all"
per_page: 100
page: 1

If the response's total exceeds 100, paginate: increment page and repeat until all experiments are fetched.

Collect the full list of completed experiments. Each item includes experiment_id, block_id, has_winner, winner_variant_index, annotations, started_at, ended_at.

Step 3 -- Get detailed results

For each experiment from step 2, call accelerate/get-experiment-results with experiment_id (not block_id). This returns the full variant metrics: impressions, conversions, conversion_rate, probability_to_beat_control, is_winner per variant.

Step 4 -- Read the existing journal

Read ~/.config/accelerate-ai-toolkit/sites/<key>/journal.json if it exists.

  • File missing: Start with an empty journal structure. (This is expected on a site's first run under the new key — old flat journal-<hostname>.* files are not read or migrated.)
  • Invalid JSON / parse error: Do not overwrite. Stop and tell the user: "Your learning journal appears to be corrupted. You can delete it and I'll rebuild from scratch, or restore it from a backup." Do not proceed.
  • schema_version is newer than 3: Stop and tell the user: "Your learning journal was created by a newer version of the toolkit. Please update the toolkit to read it." Do not proceed. (A schema_version of 1 is a pre-subdirectory flat journal and will not appear at this path; start fresh. A schema_version of 2 is a valid older journal — read it, and add the iteration_counter field when you next write, see Step 6.)
  • Valid: Parse and continue.

Step 5 -- Classify each experiment

For each experiment:

5a. Determine the pattern

Read annotations['toolkit:pattern'] from the experiment's annotations object.

  • If present and matches a pattern_id in the taxonomy below: use that pattern.
  • If present but not in the taxonomy: classify as other and record the annotation value in the pattern's notes.
  • If annotations is missing or doesn't contain toolkit:pattern: classify as other.

No keyword fallback. No hypothesis text parsing. Classification is a pure dictionary lookup.

5b. Determine the outcome

ConditionResult
has_winner: true AND winner_variant_index > 0Win -- the tested change beat the control
has_winner: true AND winner_variant_index == 0Loss -- the control won
has_winner: false (experiment concluded without significance)Inconclusive -- does not count as win or loss

5c. Compute lift for wins

For wins: lift = ((winner_conversion_rate - control_conversion_rate) / control_conversion_rate) * 100. The control is always variant index 0. Store as a percentage.

Step 6 -- Merge into journal state

Update the iteration counter first. The journal tracks iteration_counter — the number of experiments recorded in this site's auto-research sequence. It does double duty: it is the test number accelerate-test puts at the front of each experiment title ("#<n> <Block>", where n = iteration_counter + 1), and it indexes the x-axis of the auto-research progress chart — so a card's #<n> and its point on the chart are the same number. Set iteration_counter to the count of completed experiments fetched in Step 2 (total_experiments_considered). This keeps the count stable across runs and global across rounds and blocks. If the existing journal had a higher counter than the fetched count (e.g. experiments created since the last list-experiments that haven't completed), keep the higher value — the counter only ever moves forward.

For each pattern that has at least one experiment:

  1. Update tests_won, tests_lost, tests_inconclusive
  2. tests_total = tests_won + tests_lost + tests_inconclusive
  3. hit_rate = tests_won / (tests_won + tests_lost) -- excludes inconclusive. If tests_won + tests_lost == 0, hit_rate is null.
  4. avg_lift_percent = mean of all winning lifts for this pattern. null if no wins.
  5. last_tested_at = most recent ended_at across all experiments for this pattern.
  6. Append to compositions_tried — for each experiment, add one entry recording the structural recombination tested (block_id, experiment_id, a short summary of the composition, the outcome, and ended_at). This is append-only: do not rewrite or drop prior entries. Carry forward and refine notes with any concept-level learning the stats don't capture, so the next run builds on this one.
  7. Apply the four-state classification:
StatusRule
inconclusivetests_won + tests_lost < 3
wontests_won + tests_lost >= 3 AND hit_rate >= 0.75
losttests_won + tests_lost >= 3 AND hit_rate <= 0.25
mixedtests_won + tests_lost >= 3 AND 0.25 < hit_rate < 0.75

The minimum threshold of 3 decisive tests (wins + losses, not counting inconclusive) is load-bearing. Do not lower it.

Step 7 -- Write the journal atomically

Write the JSON source of truth:

# Write to temp file first, then atomic rename
python3 -c "
import json, os, sys
data = json.loads(sys.argv[1])
path = os.path.expanduser(sys.argv[2])
tmp = path + '.tmp'
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(tmp, 'w') as f:
    json.dump(data, f, indent=2)
    f.write('\n')
os.chmod(tmp, 0o600)
os.rename(tmp, path)
" '<journal_json>' '~/.config/accelerate-ai-toolkit/sites/<key>/journal.json'

Then generate and write the markdown summary from the JSON (same atomic pattern).

JSON schema

{
  "schema_version": 3,
  "site": {
    "key": "<site key — see derivation rule>",
    "name": "<from get-site-context>",
    "theme": "<from get-site-context, or null if not exposed>",
    "url": "<from get-site-context>"
  },
  "last_updated": "<ISO 8601 timestamp — wall-clock UTC at the moment of the run>",
  "iteration_counter": 0,
  "stats": {
    "total_experiments_considered": 0,
    "concluded_with_winner": 0,
    "concluded_without_winner": 0,
    "patterns_with_signal": 0
  },
  "patterns": [
    {
      "pattern_id": "<from taxonomy>",
      "display_name": "<from taxonomy>",
      "status": "won|lost|mixed|inconclusive",
      "tests_total": 0,
      "tests_won": 0,
      "tests_lost": 0,
      "tests_inconclusive": 0,
      "hit_rate": null,
      "avg_lift_percent": null,
      "last_tested_at": null,
      "last_winning_block": null,
      "compositions_tried": [
        {
          "block_id": null,
          "experiment_id": null,
          "summary": "<short plain-English description of the structural recombination tested — e.g. 'hero + logo strip + single CTA'>",
          "outcome": "win|loss|inconclusive",
          "ended_at": null
        }
      ],
      "notes": null
    }
  ]
}

Field notes:

  • iteration_counter is the site's running experiment count, used by accelerate-test as the test number at the front of each experiment title ("#<n> <Block>", where n = iteration_counter + 1) and as the x-axis index of the auto-research progress chart. It is global across rounds and blocks and only moves forward. See Step 6.
  • patterns_with_signal counts distinct patterns with at least one decisive test recorded (tests_won + tests_lost >= 1) — regardless of the >=3 classification floor. total_experiments_considered counts every completed experiment fetched, including ones classified other.
  • compositions_tried is an append-only log of the structural recombinations that have been tested for this pattern — which sections were composed together and how that variant did. It lets run N see what run N-1 already tried so later passes build on prior structure instead of re-testing settled compositions. Append one entry per experiment as you classify it (step 5); never rewrite history. Keep each summary short and human-readable.
  • notes is free-text carry-forward context for the next run: what has been learned about this pattern on this site that the stats alone don't capture (e.g. "outcome framing wins; social-proof framing has lost twice"). Update it, don't blank it.

Markdown format

Regenerated from the JSON on every run. The user reads this; no skill parses it.

# Learning journal -- [Site Name]

Last updated: [date]

Summary: [X] experiments analysed, [Y] with a clear winner, [Z] inconclusive.

## Patterns that win on your site

### [Display name]
- Won [N] of [M] tests ([hit_rate]%)
- Average improvement: +[lift]%
- Last tested: [date]
- Compositions tried: [short summaries of the structural recombinations and how each did]

## Patterns that haven't worked here

### [Display name]
- Won [N] of [M] tests ([hit_rate]%)
- Last tested: [date]
- [advisory note -- this is site-specific, not a universal rule]

## Mixed results

### [Display name]
- Won [N] of [M] tests
- Works sometimes, not a default

## Not enough data yet

### [Display name]
- [N] tests so far, need at least 3 decisive results before drawing conclusions

Step 8 -- Print summary to user

Short, marketer-friendly. Follow the output style guide (docs/output-style.md). Example:

Learning journal updated for [site name].

🔴 New this week: "Rewrite headline to match what visitors searched for" has now won 4 of 5 tests with an average +23% improvement. I'll lean on this when suggesting A/B tests.

🟡 Still building evidence: "Move the main button higher on the page" has 2 wins out of 3 -- one more test and I'll have a clearer picture.

🟢 Not working here: "Add urgency language to buttons" has lost all 3 tests. I'll stop leading with it unless you ask.

"Want me to suggest what to test next based on what we've learned?"

Hard rules for this output:

  • Never show pattern_id values. Always use display_name.
  • Never say "journal file", "JSON", "schema", "parse", or "pattern taxonomy".
  • Never recommend specific test ideas -- hand off to accelerate-opportunities or accelerate-test.
  • If no patterns have enough data yet, say so plainly and encourage patience.

Pattern taxonomy

These are the 15 canonical suggestion patterns. The pattern_id is the machine key; the display_name is what the user sees.

pattern_iddisplay_name
headline_match_intentRewrite headline to match what visitors searched for
headline_clarityRewrite headline for clarity
cta_above_foldMove the main call-to-action higher on the page
cta_copyRewrite button or link text to be more specific
social_proofAdd social proof near the call-to-action
testimonialAdd a customer testimonial near the call-to-action
urgency_copyAdd urgency or scarcity language
simplify_heroSimplify the hero section (remove clutter)
pricing_displayChange how pricing is shown (default period, anchoring)
personalize_referrerPersonalise content by traffic source
personalize_geoPersonalise content by visitor location
personalize_devicePersonalise content by device type
hero_imageChange the hero image
form_fieldsChange form field count or layout
otherOther / unclassified

This taxonomy is fixed. Do not invent new pattern_ids during a run. If an experiment doesn't match a known pattern, it goes to other. The taxonomy grows only in toolkit releases.


Rules

  • Never create, modify, or stop experiments. This skill is read-only on WordPress.
  • Never recommend specific test ideas in the summary. Hand off to other skills.
  • Never overwrite a corrupted journal. Surface the error and let the user decide.
  • All per-site files are chmod 600. Same security posture as credentials.
  • Old flat journals are abandoned, not migrated. A site's first run under the new key starts a fresh journal in its sites/<key>/ subdirectory.
  • Write atomically. Temp file + rename. Never write directly to the target path.
  • Minimum 3 decisive tests before classification. The inconclusive floor is non-negotiable.

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.