diff --git a/.github/PULL_REQUEST_TEMPLATE/marketplace_loop.md b/.github/PULL_REQUEST_TEMPLATE/marketplace_loop.md new file mode 100644 index 0000000..099cec9 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/marketplace_loop.md @@ -0,0 +1,18 @@ +## New marketplace loop + +**Loop:** `marketplace/loops/.loop` +**What it does (one line):** + +### Checklist — [the bar](../../marketplace/CONTRIBUTING.md) + +- [ ] Parses — `node market/validate-marketplace.mjs` passes locally +- [ ] At least one **machine-checkable** `done when` (test / command / skill eval — not prose, not human-only) +- [ ] Reflect back-edge → has an `after N tries` ceiling +- [ ] Attribution header (`# original — …` or `# concept via … — `) +- [ ] Project-specific commands marked `# TODO` +- [ ] No secrets, no credentials, no internal URLs + +### Attribution + +- Author / handle: +- If adapted: source concept + link: diff --git a/.github/workflows/marketplace.yml b/.github/workflows/marketplace.yml new file mode 100644 index 0000000..fa6e2c8 --- /dev/null +++ b/.github/workflows/marketplace.yml @@ -0,0 +1,32 @@ +name: Marketplace + +# Validates every marketplace submission with the real parser: the bar is +# parse + a machine-checkable done-when + a thrash guard + attribution +# (market/validate-marketplace.mjs). A PR that fails here never reaches review. +on: + pull_request: + paths: + - "marketplace/**" + - "market/**" + push: + branches: [master] + paths: + - "marketplace/**" + - "market/**" + +jobs: + validate: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + - run: npm ci + - run: npm run build -w @loop-lang/parser # the validator imports the real parser + - run: node market/validate-marketplace.mjs + - run: node market/build-catalog.mjs # the catalog must still build from the tree + - run: node market/check-site.mjs diff --git a/docs/index.html b/docs/index.html index 6b132c0..157aad5 100644 --- a/docs/index.html +++ b/docs/index.html @@ -245,6 +245,7 @@
  • Go deeper
  • 📖 Full manual →
  • 📖 Keyword reference →
  • +
  • 🛒 Loop market →
  • ⚡ Playground →
  • 🛠️ Workshop →
  • 🎮 LoopFlow Lab →
  • diff --git a/docs/market/catalog.json b/docs/market/catalog.json new file mode 100644 index 0000000..be15139 --- /dev/null +++ b/docs/market/catalog.json @@ -0,0 +1,412 @@ +{ + "built": "loop-market", + "count": 29, + "entries": [ + { + "slug": "accessibility-repair-loop", + "title": "accessibility repair", + "shape": "loop", + "glyph": "↻", + "goal": "every target page passes the accessibility scan with zero violations at the chosen standard", + "doneWhen": "\"npx pa11y-ci\" finds nothing", + "category": "design", + "author": "Eric Lott", + "source": "https://signals.forwardfuture.com/loop-library/loops/accessibility-repair-loop/", + "concept": "Use this when a website or app has a defined accessibility target and you can repeatedly test the relevant pages, components, or tasks for p", + "keywords": "accessibility repair loop design loop", + "text": "# The accessibility repair loop — drive the a11y scanner to zero, for real.\n# concept via Eric Lott — https://signals.forwardfuture.com/loop-library/loops/accessibility-repair-loop/\n# `finds nothing` is the right predicate: the scanner must report zero violations on\n# every target page. The suite stays green so fixes don't break behavior, and\n# suppressing rules to get to zero is gated — that's cheating, not repairing.\n\nloop \"accessibility repair\":\n goal: every target page passes the accessibility scan with zero violations at the chosen standard\n done when \"npx pa11y-ci\" finds nothing # TODO: your page list + standard (WCAG2AA) in .pa11yci\n done when \"npm test\" passes\n\n look at: the scanner's violation list grouped by rule, the components generating them, and the last failure\n allow edits automatically, but ask me before disabling or downgrading any scanner rule\n\n each cycle: plan, then act, then observe\n when it fails: reflect on the rule with the most remaining violations, then plan again\n after 8 tries: stop and warn \"a11y repair stuck — remaining violations may need design changes\"\n" + }, + { + "slug": "cold-load-trimmer-loop", + "title": "cold-load trimmer", + "shape": "loop", + "glyph": "↻", + "goal": "the first-visit payload is under budget with all features intact", + "doneWhen": "\"node scripts/bundle-budget.mjs --max 250kb\" passes", + "category": "engineering", + "author": "Christian Katzmann", + "source": "https://signals.forwardfuture.com/loop-library/loops/cold-load-trimmer-loop/", + "concept": "Use this when a web app feels heavy on its first visit because it downloads too much code, styling, media, or other data before showing the", + "keywords": "cold load trimmer loop engineering loop", + "text": "# The cold-load trimmer — a first visit that doesn't download the world.\n# concept via Christian Katzmann — https://signals.forwardfuture.com/loop-library/loops/cold-load-trimmer-loop/\n# A bundle-size budget the build must clear, plus a green suite so trimming never\n# breaks behavior. Gate dependency removal — dropping a package is the classic\n# fast-but-wrong trim.\n\nloop \"cold-load trimmer\":\n goal: the first-visit payload is under budget with all features intact\n done when \"node scripts/bundle-budget.mjs --max 250kb\" passes # TODO: your budget + bundler stats source\n done when \"npm test\" passes\n\n look at: the bundler's stats output, the heaviest chunks, lazy-load boundaries, and the last failure\n allow edits automatically, but ask me before removing a dependency or a feature flag\n\n each cycle: plan, then act, then observe\n when it fails: reflect on the single heaviest remaining chunk, then plan again\n after 8 tries: stop and warn \"cold load stuck — remaining weight may be product surface\"\n" + }, + { + "slug": "dependency-cve-burndown-loop", + "title": "dependency CVE burndown", + "shape": "loop", + "glyph": "↻", + "goal": "zero high or critical CVEs in the dependency tree with the suite still green", + "doneWhen": "\"npm audit --audit-level=high\" finds nothing", + "category": "engineering", + "author": "hungtv27 (@hungtv27)", + "source": "https://signals.forwardfuture.com/loop-library/loops/dependency-cve-burndown-loop/", + "concept": "Use this when dependency scans report high or critical CVEs and remediation should reflect whether vulnerable code is actually reachable in", + "keywords": "dependency cve burndown loop engineering loop", + "text": "# The dependency-CVE burndown — high/critical vulnerabilities to zero, with proof.\n# concept via hungtv27 (@hungtv27) — https://signals.forwardfuture.com/loop-library/loops/dependency-cve-burndown-loop/\n# The audit must come back empty AND the suite must stay green — upgrading your way\n# into a broken build is not a fix. Major-version bumps are gated: breaking-change\n# review is a human call.\n\nloop \"dependency CVE burndown\":\n goal: zero high or critical CVEs in the dependency tree with the suite still green\n done when \"npm audit --audit-level=high\" finds nothing\n done when \"npm test\" passes\n\n look at: the audit report, the lockfile entries it names, upstream changelogs for candidate versions, and the last failure\n allow edits automatically, but ask me before any major-version bump or dependency replacement\n\n each cycle: plan, then act, then observe\n when it fails: reflect on whether the remaining CVE has a fixed version or needs a workaround, then plan again\n when blocked: ask a human\n after 6 tries: stop and warn \"CVE burndown stuck — remaining advisories may have no upstream fix\"\n" + }, + { + "slug": "dependency-triage-loop", + "title": "dependency triage", + "shape": "loop", + "glyph": "↻", + "goal": "zero open dependency PRs — each merged after a green run or closed with a written reason", + "doneWhen": "\"node scripts/dep-queue-check.mjs\" passes", + "category": "operations", + "author": "Damian Galarza (@dgalarza)", + "source": "https://signals.forwardfuture.com/loop-library/loops/dependency-triage-loop/", + "concept": "Use this when a repository has several open Dependabot pull requests and an authorized maintainer wants them reviewed safely without stale c", + "keywords": "dependency triage loop operations loop", + "text": "# The dependency triage loop — the Dependabot queue to zero, each PR proven first.\n# concept via Damian Galarza (@dgalarza) — https://signals.forwardfuture.com/loop-library/loops/dependency-triage-loop/\n# Every open dependency PR gets a decision backed by a green run: merge it, or close\n# it with a reason. The checker fails while any PR sits undecided. Majors are gated —\n# breaking-change review is human work.\n\nloop \"dependency triage\":\n goal: zero open dependency PRs — each merged after a green run or closed with a written reason\n done when \"node scripts/dep-queue-check.mjs\" passes # TODO: lists open dep PRs; fails unless queue is empty\n\n look at: each dependency PR's changelog and diff, the CI run for its branch, and the last failure\n allow edits automatically, but ask me before merging any major-version bump\n\n each cycle: plan, then act, then observe\n when it fails: reflect on the PR that failed its run or resists a decision, then plan again\n when blocked: ask a human\n after 6 tries: stop and warn \"dep triage stuck — remaining PRs conflict with each other\"\n" + }, + { + "slug": "devils-advocate-design-loop", + "title": "devil's advocate", + "shape": "loop", + "glyph": "↻", + "goal": "the design document withstands adversarial review — risks named, alternatives compared, failure modes addressed", + "doneWhen": "the skill \"design-skeptic\" approves by 3 judges", + "category": "evaluation", + "author": "Anonymous contributor", + "source": "https://signals.forwardfuture.com/loop-library/loops/devils-advocate-design-loop/", + "concept": "Use this before committing to an architecture, interface, rollout plan, or other consequential design that benefits from structured adversar", + "keywords": "devils advocate design loop evaluation loop", + "text": "# The devil's-advocate loop — a design must survive three independent skeptics.\n# concept via an anonymous contributor — https://signals.forwardfuture.com/loop-library/loops/devils-advocate-design-loop/\n# LoopFlow's judge panel is this concept as a primitive: `approves by 3 judges`\n# collects three independent verdicts and takes the majority, so one generous\n# reviewer can't wave a weak design through. The bar tells the skeptics what\n# survival means.\n\nloop \"devil's advocate\":\n goal: the design document withstands adversarial review — risks named, alternatives compared, failure modes addressed\n done when the skill \"design-skeptic\" approves on the output by 3 judges\n the bar: every major risk has a mitigation or an explicit acceptance; at least two alternatives compared honestly; no unexamined single point of failure\n\n look at: the design document, the constraints it must satisfy, prior art it cites, and the last failure\n allow edits automatically\n\n each cycle: plan, then act, then observe\n when it fails: reflect on the strongest objection the panel raised, then plan again\n after 5 tries: stop and warn \"design can't convince the panel — the objections may be right\"\n\n a human reviews before stopping\n" + }, + { + "slug": "error-message-rewrite-loop", + "title": "error-message rewrite", + "shape": "loop", + "glyph": "↻", + "goal": "every user-facing error message states what happened and what the user can do, in the product's voice", + "doneWhen": "\"node scripts/lint-error-messages.mjs\" passes", + "category": "engineering", + "author": "Will Undrell (@WillUndrll)", + "source": "https://signals.forwardfuture.com/loop-library/loops/error-message-rewrite-loop/", + "concept": "Use this when a product exposes raw, internal, inconsistent, or unhelpful error messages and the complete user-facing error surface needs a", + "keywords": "error message rewrite loop engineering loop", + "text": "# The error-message rewrite loop — every user-facing error says what happened and what to do.\n# concept via Will Undrell (@WillUndrll) — https://signals.forwardfuture.com/loop-library/loops/error-message-rewrite-loop/\n# A lint pass enforces the mechanical bar (no raw internals, no codes without text,\n# actionable phrasing patterns); a human reviews the voice before the loop may stop —\n# tone is judgment, structure is a checker.\n\nloop \"error-message rewrite\":\n goal: every user-facing error message states what happened and what the user can do, in the product's voice\n done when \"node scripts/lint-error-messages.mjs\" passes # TODO: your checker — flags raw stack traces, bare codes, non-actionable phrasing\n done when \"npm test\" passes\n\n look at: the error catalog or the surfaces that raise user-facing errors, the product's voice guide, and the last failure\n allow edits automatically, but ask me before changing error codes that external clients match on\n\n each cycle: plan, then act, then observe\n when it fails: reflect on which messages the linter still flags, then plan again\n after 6 tries: stop and warn \"error rewrite stuck\"\n\n a human reviews before stopping\n" + }, + { + "slug": "exhaustive-logging-coverage-loop", + "title": "logging coverage", + "shape": "loop", + "glyph": "↻", + "goal": "every flow in the logging manifest emits structured logs at entry, exit, and error paths", + "doneWhen": "\"node scripts/check-logging.mjs\" passes", + "category": "engineering", + "author": "Matthew Berman", + "source": "https://signals.forwardfuture.com/loop-library/loops/exhaustive-logging-coverage-loop/", + "concept": "Use this when important user flows, service boundaries, background jobs, or failure paths are difficult to trace because the system's loggin", + "keywords": "exhaustive logging coverage loop engineering loop", + "text": "# The logging coverage loop — every critical flow observable before you need it.\n# concept via Matthew Berman — https://signals.forwardfuture.com/loop-library/loops/exhaustive-logging-coverage-loop/\n# Declare the flows that must be traceable (user journeys, service boundaries,\n# background jobs, failure paths) in a manifest; a checker walks them and fails on\n# any flow with no log line at entry, exit, or error.\n\nloop \"logging coverage\":\n goal: every flow in the logging manifest emits structured logs at entry, exit, and error paths\n done when \"node scripts/check-logging.mjs\" passes # TODO: your checker over the flow manifest\n done when \"npm test\" passes # added logging must not change behavior\n\n look at: the logging manifest, the flows it names, the logger module, and the last failure\n allow edits automatically, but ask me before changing log levels in production config\n\n each cycle: plan, then act, then observe\n when it fails: reflect on which flow the checker flagged, then plan again\n after 6 tries: stop and warn \"logging coverage stuck\"\n" + }, + { + "slug": "fresh-clone-loop", + "title": "fresh clone", + "shape": "loop", + "glyph": "↻", + "goal": "a clean clone can install, build, and test using only what the README says", + "doneWhen": "\"bash scripts/fresh-clone-check.sh\" passes", + "category": "engineering", + "author": "0xUmbra", + "source": "https://signals.forwardfuture.com/loop-library/loops/fresh-clone-loop/", + "concept": "Use this to test whether a repository's onboarding instructions work in a clean environment without undocumented help.", + "keywords": "fresh clone loop engineering loop", + "text": "# The fresh-clone loop — your onboarding docs, proven in a clean room.\n# concept via 0xUmbra — https://signals.forwardfuture.com/loop-library/loops/fresh-clone-loop/\n# Clones the repo into a throwaway directory and follows the README setup verbatim.\n# If a fresh machine couldn't do it, the loop can't stop — undocumented steps get\n# documented, broken steps get fixed.\n\nloop \"fresh clone\":\n goal: a clean clone can install, build, and test using only what the README says\n done when \"bash scripts/fresh-clone-check.sh\" passes # TODO: clone to a temp dir, run the documented setup + test commands, exit non-zero on any step\n\n look at: README.md, the setup scripts the README names, and the last failure\n allow edits automatically, but ask me before adding new required system dependencies\n\n each cycle: plan, then act, then observe\n when it fails: reflect on the first step that failed in the clean room, then plan again\n after 6 tries: stop and warn \"fresh clone still failing — environment assumptions run deep\"\n" + }, + { + "slug": "full-product-evaluation-loop", + "title": "full product evaluation", + "shape": "loop", + "glyph": "↻", + "goal": "every user-facing surface exercised end to end with each finding fixed or filed with a reproduction", + "doneWhen": "\"npm run test:e2e\" passes", + "category": "evaluation", + "author": "Matthew Berman", + "source": "https://signals.forwardfuture.com/loop-library/loops/full-product-evaluation-loop/", + "concept": "Use this for an exhaustive, end-to-end application QA pass when a production-like local environment and complete interactive-surface coverag", + "keywords": "full product evaluation loop evaluation loop", + "text": "# The full product evaluation loop — an end-to-end QA pass that ends in evidence.\n# concept via Matthew Berman — https://signals.forwardfuture.com/loop-library/loops/full-product-evaluation-loop/\n# Deterministic e2e suite for what code can check; a review skill judges the\n# report's completeness (every declared surface exercised, every finding traced).\n# A human signs the final verdict — release judgment stays yours.\n\nloop \"full product evaluation\":\n goal: every user-facing surface exercised end to end with each finding fixed or filed with a reproduction\n done when \"npm run test:e2e\" passes # TODO: your e2e suite\n done when the skill \"qa-report-review\" approves on the output # judges the evaluation report: coverage of surfaces, findings traced\n the bar: every surface in the product map appears in the report; no finding without a reproduction or a filed issue\n\n look at: the product surface map, the e2e suite, open bug reports, and the last failure\n allow edits automatically, but ask me before changing test infrastructure or seeding production-like data\n\n each cycle: plan, then act, then observe\n when it fails: reflect on the surface with the weakest evidence, then plan again\n when blocked: ask a human\n after 8 tries: stop and warn \"evaluation stuck — remaining findings need triage\"\n\n a human reviews before stopping\n" + }, + { + "slug": "literature-search-verification-loop", + "title": "literature-search verification", + "shape": "loop", + "glyph": "↻", + "goal": "every paper in the result set resolves to a real publication and is relevant to the research question", + "doneWhen": "\"node scripts/verify-citations.mjs\" passes", + "category": "evaluation", + "author": "Nathan Nguyen", + "source": "https://signals.forwardfuture.com/loop-library/loops/literature-search-verification-loop/", + "concept": "Use this when a literature search must produce a high-precision, auditable paper set rather than an unverified list of citations.", + "keywords": "literature search verification loop evaluation loop", + "text": "# The literature-search verification loop — a paper set where every entry is real and on-topic.\n# concept via Nathan Nguyen — https://signals.forwardfuture.com/loop-library/loops/literature-search-verification-loop/\n# LLM search hallucinates citations; this loop makes the bibliography earn its place.\n# A checker resolves every DOI/URL and validates metadata; a judge screens relevance\n# against the research question. High precision beats high volume.\n\nloop \"literature-search verification\":\n goal: every paper in the result set resolves to a real publication and is relevant to the research question\n done when \"node scripts/verify-citations.mjs\" passes # TODO: resolves each DOI/URL, checks title+authors match the entry\n done when the skill \"relevance-screen\" approves on the output\n the bar: every retained paper addresses the stated question; every exclusion has a one-line reason\n\n look at: the research question, the candidate bibliography, the verification log, and the last failure\n allow edits automatically\n\n each cycle: plan, then act, then observe\n when it fails: reflect on which entries failed to resolve or screen, then plan again\n after 6 tries: stop and warn \"verification stuck — remaining candidates may not exist\"\n" + }, + { + "slug": "multi-llm-convergence-loop", + "title": "multi-LLM convergence", + "shape": "loop", + "glyph": "↻", + "goal": "the artifact reaches a version independent reviewers agree is sound", + "doneWhen": "the skill \"artifact-review\" approves by 3 judges", + "category": "evaluation", + "author": "Donn Felker (@donnfelker)", + "source": "https://signals.forwardfuture.com/loop-library/loops/multi-llm-convergence-loop/", + "concept": "Use this when an important plan, specification, design, document, or code change benefits from two independent AI perspectives rather than o", + "keywords": "multi llm convergence loop evaluation loop", + "text": "# The multi-LLM convergence loop — ship the version independent judges agree on.\n# concept via Donn Felker (@donnfelker) — https://signals.forwardfuture.com/loop-library/loops/multi-llm-convergence-loop/\n# For consequential artifacts (a spec, a migration plan, a public document): iterate\n# until a panel of independent judges converges. Majority-of-3 is the convergence\n# test; the bar makes the judges argue about substance rather than style.\n\nloop \"multi-LLM convergence\":\n goal: the artifact reaches a version independent reviewers agree is sound\n done when the skill \"artifact-review\" approves on the output by 3 judges\n the bar: internally consistent; no factual errors a reviewer can name; every objection from prior rounds addressed or rebutted in the text\n\n look at: the artifact, the requirements it must satisfy, objections from earlier rounds, and the last failure\n allow edits automatically\n\n each cycle: plan, then act, then observe\n when it fails: reflect on the objection the dissenting judge raised, then plan again\n after 6 tries: stop and warn \"no convergence — the disagreement is substantive and needs a human call\"\n" + }, + { + "slug": "nightly-changelog-sweep", + "title": "nightly changelog sweep", + "shape": "loop", + "glyph": "↻", + "goal": "the changelog accounts for every user-facing change merged since its last entry, in the product's voice", + "doneWhen": "\"node scripts/check-changelog.mjs\" passes", + "category": "content", + "author": "Matthew Berman", + "source": "https://signals.forwardfuture.com/loop-library/loops/nightly-changelog-sweep/", + "concept": "Use this when a project changes frequently enough that user-facing release notes can drift from merged pull requests, commits, deployments,", + "keywords": "nightly changelog sweep content loop", + "text": "# The nightly changelog sweep — release notes that never drift from what actually merged.\n# concept via Matthew Berman — https://signals.forwardfuture.com/loop-library/loops/nightly-changelog-sweep/\n# A checker diffs merged PRs since the last entry against the changelog: every\n# user-facing change accounted for, in the changelog's voice, nothing invented.\n# Run it nightly (schedule:) or before each release.\n\nloop \"nightly changelog sweep\":\n goal: the changelog accounts for every user-facing change merged since its last entry, in the product's voice\n done when \"node scripts/check-changelog.mjs\" passes # TODO: merged-PRs-since-last-entry vs changelog diff; fails on any gap\n\n look at: CHANGELOG.md, the merged PRs since the last entry with their labels, and the last failure\n allow edits automatically, but ask me before rewriting entries older than the current release\n\n each cycle: act, then observe\n when it fails: reflect on which merged change the checker found unaccounted, then plan again\n after 4 tries: stop and warn \"changelog sweep stuck — a merged PR may need a human summary\"\n" + }, + { + "slug": "overnight-docs-sweep", + "title": "docs sweep", + "shape": "loop", + "glyph": "↻", + "goal": "every README, setup guide, and example matches the current code — no dead links, no stale commands, no renamed flags", + "doneWhen": "\"npx markdown-link-check README.md docs/**/*.md\" passes", + "category": "engineering", + "author": "Matthew Berman", + "source": "https://signals.forwardfuture.com/loop-library/loops/overnight-docs-sweep/", + "concept": "Use this whenever implementation changes may have left READMEs, setup guides, API references, examples, or runbooks behind.", + "keywords": "overnight docs sweep engineering loop", + "text": "# The docs sweep — keep every doc true to the code it describes.\n# concept via Matthew Berman — https://signals.forwardfuture.com/loop-library/loops/overnight-docs-sweep/\n# Run it after a stretch of implementation work (or on a schedule): it hunts drift\n# between code and READMEs/setup guides/examples, fixes what it finds, and can only\n# stop when the link checker and the drift checker both report clean.\n\nloop \"docs sweep\":\n goal: every README, setup guide, and example matches the current code — no dead links, no stale commands, no renamed flags\n done when \"npx markdown-link-check README.md docs/**/*.md\" passes # TODO: your doc globs\n done when \"node scripts/check-doc-drift.mjs\" passes # TODO: your drift checker (commands in docs actually run, flags exist)\n\n look at: README.md, docs/, the public CLI surface, and the last failure\n allow edits automatically, but ask me before changing any public API to match a doc\n\n each cycle: plan, then act, then observe\n when it fails: reflect on which doc drifted and why, then plan again\n when blocked: ask a human\n after 6 tries: stop and warn \"docs sweep stuck — the drift may be a code bug rather than a doc bug\"\n" + }, + { + "slug": "pixel-safe-css-trim-loop", + "title": "pixel-safe CSS trim", + "shape": "loop", + "glyph": "↻", + "goal": "the stylesheet is measurably smaller and every reference route renders pixel-identical to the baseline", + "doneWhen": "\"node scripts/visual-diff.mjs --baseline .baseline --threshold 0\" passes", + "category": "design", + "author": "Christian Katzmann", + "source": "https://signals.forwardfuture.com/loop-library/loops/pixel-safe-css-trim-loop/", + "concept": "Use this when a website's styling files may contain unused declarations, duplicated rules, or old overrides and representative pages and int", + "keywords": "pixel safe css trim loop design loop", + "text": "# The pixel-safe CSS trim — a smaller stylesheet that renders identically.\n# concept via Christian Katzmann — https://signals.forwardfuture.com/loop-library/loops/pixel-safe-css-trim-loop/\n# Two checks lock the contract: the visual diff must be pixel-identical on every\n# reference route, AND the stylesheet must actually shrink. Remove a rule, screenshot,\n# compare — any pixel moved means the rule was live.\n\nloop \"pixel-safe CSS trim\":\n goal: the stylesheet is measurably smaller and every reference route renders pixel-identical to the baseline\n done when \"node scripts/visual-diff.mjs --baseline .baseline --threshold 0\" passes # TODO: your capture + diff harness\n done when \"node scripts/css-size.mjs --smaller-than-baseline\" passes # TODO: fails unless bytes went down\n\n look at: the coverage report of unused selectors, the stylesheet's oldest sections, and the last failure\n allow edits automatically\n\n each cycle: act, then observe\n when it fails: reflect on which route's pixels moved and which rule did it, then plan again\n after 8 tries: stop and warn \"trim plateaued — the remaining CSS is all load-bearing\"\n" + }, + { + "slug": "post-release-baseline-loop", + "title": "post-release baseline", + "shape": "loop", + "glyph": "↻", + "goal": "a complete, versioned baseline artifact exists for this release — perf, sizes, error rate, coverage — tied to the release SHA", + "doneWhen": "\"node scripts/capture-baseline.mjs && node scripts/validate-baseline.mjs\" passes", + "category": "operations", + "author": "Matthew Berman", + "source": "https://signals.forwardfuture.com/loop-library/loops/post-release-baseline-loop/", + "concept": "Use this immediately after a release when future regressions or improvements need to be measured against the exact version now in production", + "keywords": "post release baseline loop operations loop", + "text": "# The post-release baseline — freeze the numbers the next regression will be measured against.\n# concept via Matthew Berman — https://signals.forwardfuture.com/loop-library/loops/post-release-baseline-loop/\n# Run immediately after a release: capture performance, bundle sizes, error rates,\n# and coverage into a versioned baseline artifact. A validator proves the snapshot\n# is complete and tied to the release SHA — future loops diff against it.\n\nloop \"post-release baseline\":\n goal: a complete, versioned baseline artifact exists for this release — perf, sizes, error rate, coverage — tied to the release SHA\n done when \"node scripts/capture-baseline.mjs && node scripts/validate-baseline.mjs\" passes # TODO: capture + completeness check\n\n look at: the release tag and SHA, the previous baseline for shape, the metric sources, and the last failure\n allow edits automatically\n\n each cycle: act, then observe\n when it fails: reflect on which metric failed to capture, then plan again\n after 4 tries: stop and warn \"baseline incomplete — a metric source is unavailable\"\n" + }, + { + "slug": "pre-publish-source-check-loop", + "title": "pre-publish source check", + "shape": "loop", + "glyph": "↻", + "goal": "every factual claim in the draft carries a source that resolves, and no claim ships unsourced", + "doneWhen": "\"node scripts/check-sources.mjs draft.md\" passes", + "category": "content", + "author": "Ryan Banze (@RyanBanze)", + "source": "https://signals.forwardfuture.com/loop-library/loops/pre-publish-source-check-loop/", + "concept": "Use this immediately before publishing an article, newsletter, post, report, or other factual draft whose claims, quotations, and attributio", + "keywords": "pre publish source check loop content loop", + "text": "# The pre-publish source check — no claim ships without a living source.\n# concept via Ryan Banze (@RyanBanze) — https://signals.forwardfuture.com/loop-library/loops/pre-publish-source-check-loop/\n# The last gate before publishing anything factual: a checker resolves every cited\n# link and flags every unsourced factual claim; a judge reads for claims smuggled in\n# without citations. The fix is a source or a softer sentence — never a dead link.\n\nloop \"pre-publish source check\":\n goal: every factual claim in the draft carries a source that resolves, and no claim ships unsourced\n done when \"node scripts/check-sources.mjs draft.md\" passes # TODO: extracts claims+links; fails on dead links or bare claims\n done when the skill \"fact-screen\" approves on the output\n the bar: no factual assertion without a citation or an explicit \"author's estimate\" marker; quoted figures match their sources\n\n look at: the draft, its citation list, the checker's flag list, and the last failure\n allow edits automatically, but ask me before deleting a claim central to the piece\n\n each cycle: act, then observe\n when it fails: reflect on the flagged claims — source them or soften them, then plan again\n after 5 tries: stop and warn \"source check stuck — remaining claims may be unverifiable\"\n" + }, + { + "slug": "production-error-sweep", + "title": "production error sweep", + "shape": "loop", + "glyph": "↻", + "goal": "the production error feed for the last 24h contains no unexplained, unfixed errors", + "doneWhen": "\"node scripts/error-feed.mjs --window 24h --max 0\" passes", + "category": "engineering", + "author": "Matthew Berman", + "source": "https://signals.forwardfuture.com/loop-library/loops/production-error-sweep/", + "concept": "Use this as a scheduled reliability pass when an agent can read production telemetry, trace failures into the repository, run the relevant t", + "keywords": "production error sweep engineering loop", + "text": "# The production error sweep — burn the live error feed down to quiet.\n# concept via Matthew Berman — https://signals.forwardfuture.com/loop-library/loops/production-error-sweep/\n# Point it at your telemetry (Sentry/PostHog/logs): trace each error to its cause,\n# fix, and stop only when the query over the recent window comes back clean.\n# Deploys stay human-gated — the loop fixes; you ship.\n\nloop \"production error sweep\":\n goal: the production error feed for the last 24h contains no unexplained, unfixed errors\n done when \"node scripts/error-feed.mjs --window 24h --max 0\" passes # TODO: your telemetry query; non-zero when errors remain\n done when \"npm test\" passes # fixes must not break the suite\n\n look at: the telemetry dashboard export, the traced stack for the top error, and the last failure\n allow edits automatically, but ask me before deploys or config changes in production\n\n each cycle: plan, then act, then observe\n when it fails: reflect on the top remaining error's stack trace, then plan again\n when blocked: ask a human\n after 6 tries: stop and warn \"error sweep stuck — remaining errors need a human read\"\n" + }, + { + "slug": "promise-to-proof-loop", + "title": "promise to proof", + "shape": "loop", + "glyph": "↻", + "goal": "every public claim about the product maps to a passing proof — a test, a benchmark, or a scripted demo", + "doneWhen": "\"node scripts/check-claims.mjs\" passes", + "category": "evaluation", + "author": "Felix Haeberle (@felixhaberle)", + "source": "https://signals.forwardfuture.com/loop-library/loops/promise-to-proof-loop/", + "concept": "Use this when what a product says it does may no longer match what it actually does across marketing, documentation, demos, support answers,", + "keywords": "promise to proof loop evaluation loop", + "text": "# The promise-to-proof loop — what the product claims is what the product does.\n# concept via Felix Haeberle (@felixhaberle) — https://signals.forwardfuture.com/loop-library/loops/promise-to-proof-loop/\n# Extract every claim from marketing pages, docs, and README into a manifest; a\n# checker maps each claim to a passing test or a reproducible demo. Claims with no\n# proof get one — or get rewritten to what's true.\n\nloop \"promise to proof\":\n goal: every public claim about the product maps to a passing proof — a test, a benchmark, or a scripted demo\n done when \"node scripts/check-claims.mjs\" passes # TODO: your claims manifest → proof mapping; fails on any unproven claim\n done when \"npm test\" passes\n\n look at: the claims manifest, marketing copy and README, the proofs directory, and the last failure\n allow edits automatically, but ask me before weakening any public claim to make it pass\n\n each cycle: plan, then act, then observe\n when it fails: reflect on the boldest unproven claim, then plan again\n after 6 tries: stop and warn \"promise gap remains — some claims need a product decision\"\n" + }, + { + "slug": "propagation-compliance-loop", + "title": "propagation compliance", + "shape": "loop", + "glyph": "↻", + "goal": "the old value appears nowhere in the repo and every surface carries the new one", + "doneWhen": "\"grep -rn 'OLD_VALUE' --exclude-dir=node_modules --exclude-dir=.git .\" finds nothing", + "category": "engineering", + "author": "@iamTristan", + "source": "https://signals.forwardfuture.com/loop-library/loops/propagation-compliance-loop/", + "concept": "Use this after changing something that appears in several files—such as a version number, feature name, count, rule, setting, or identifier—", + "keywords": "propagation compliance loop engineering loop", + "text": "# The propagation compliance loop — change a value once, prove it changed everywhere.\n# concept via @iamTristan — https://signals.forwardfuture.com/loop-library/loops/propagation-compliance-loop/\n# For version numbers, renamed features, changed counts, updated copy — anything that\n# lives in several files. `finds nothing` is the perfect predicate: the loop stops\n# only when no trace of the old value survives anywhere.\n\nloop \"propagation compliance\":\n goal: the old value appears nowhere in the repo and every surface carries the new one\n done when \"grep -rn 'OLD_VALUE' --exclude-dir=node_modules --exclude-dir=.git .\" finds nothing # TODO: the value being retired\n done when \"npm test\" passes # replacements must not break anything\n\n look at: every file the initial grep flags, and the last failure\n allow edits automatically\n\n each cycle: act, then observe\n when it fails: reflect on which surfaces still carry the old value, then plan again\n after 4 tries: stop and warn \"propagation stuck — some occurrences may be intentional history\"\n" + }, + { + "slug": "quality-streak-loop", + "title": "quality streak", + "shape": "loop", + "glyph": "↻", + "goal": "the quality gate holds a streak — consecutive green runs with every failure turned into a permanent fix", + "doneWhen": "\"npm run quality:check\" passes 7 times", + "category": "evaluation", + "author": "Matthew Berman", + "source": "https://signals.forwardfuture.com/loop-library/loops/quality-streak-loop/", + "concept": "Use this when product quality needs a strict consecutive-success bar and failures should permanently improve the test and benchmark suite.", + "keywords": "quality streak loop evaluation loop", + "text": "# The quality streak loop — done means N consecutive greens, and a failure resets the streak.\n# concept via Matthew Berman — https://signals.forwardfuture.com/loop-library/loops/quality-streak-loop/\n# LoopFlow's flake guard implements the streak natively: `passes 7 times` requires\n# seven consecutive green runs inside one observe — any failure short-circuits and\n# sends the loop back through reflect, which must harden the check that broke.\n\nloop \"quality streak\":\n goal: the quality gate holds a streak — consecutive green runs with every failure turned into a permanent fix\n done when \"npm run quality:check\" passes 7 times # TODO: your gate (tests + lint + typecheck in one command); streak length to taste\n\n look at: the last streak-breaking failure and the code path it implicates, and the last failure\n allow edits automatically, but ask me before loosening any threshold the gate enforces\n\n each cycle: plan, then act, then observe\n when it fails: reflect on what broke the streak and how to make it impossible again, then plan again\n when blocked: ask a human\n after 10 tries: stop and warn \"streak keeps breaking — the gate may be measuring noise\"\n" + }, + { + "slug": "recovery-proof-loop", + "title": "recovery proof", + "shape": "loop", + "glyph": "↻", + "goal": "the latest backup restores into a clean environment and passes the integrity suite, with the drill recorded as evidence", + "doneWhen": "\"bash scripts/restore-drill.sh\" passes", + "category": "operations", + "author": "Eric Lott", + "source": "https://signals.forwardfuture.com/loop-library/loops/recovery-proof-loop/", + "concept": "Use this when backup existence is not enough and the organization needs repeatable proof that required systems can be restored from document", + "keywords": "recovery proof loop operations loop", + "text": "# The recovery proof loop — a backup you haven't restored is a rumor.\n# concept via Eric Lott — https://signals.forwardfuture.com/loop-library/loops/recovery-proof-loop/\n# The drill is the verification: restore the latest backup into a clean environment,\n# run the integrity suite against the restored system, and record the evidence.\n# Anything touching live systems is gated — the drill must never become the incident.\n\nloop \"recovery proof\":\n goal: the latest backup restores into a clean environment and passes the integrity suite, with the drill recorded as evidence\n done when \"bash scripts/restore-drill.sh\" passes # TODO: restore to an isolated env + integrity checks + write the drill record\n\n look at: the backup manifest, the restore runbook, the last drill record, and the last failure\n allow edits automatically, but ask me before touching any production system or live credential\n\n each cycle: plan, then act, then observe\n when it fails: reflect on which restore step or integrity check failed, then plan again\n when blocked: ask a human\n after 5 tries: stop and warn \"recovery drill failing — treat as an incident because the backups may be bad\"\n" + }, + { + "slug": "repository-cleanup-loop", + "title": "repository cleanup", + "shape": "loop", + "glyph": "↻", + "goal": "the repo audit reports zero stale branches, worktrees, or unresolved PRs", + "doneWhen": "\"node scripts/repo-audit.mjs --stale-days 30\" finds nothing", + "category": "engineering", + "author": "Matthew Berman", + "source": "https://signals.forwardfuture.com/loop-library/loops/repository-cleanup-loop/", + "concept": "Use this when abandoned branches, old worktrees, unclear pull requests, or unmerged commits make it difficult to know which repository state", + "keywords": "repository cleanup loop engineering loop", + "text": "# The repository cleanup loop — no abandoned branches, stale worktrees, or zombie PRs.\n# concept via Matthew Berman — https://signals.forwardfuture.com/loop-library/loops/repository-cleanup-loop/\n# An audit script defines \"clean\" (merged branches deleted, worktrees pruned, PRs\n# labeled or closed, no unmerged work older than the threshold); the loop works the\n# list until the audit finds nothing. Deletions are gated — recovery is expensive.\n\nloop \"repository cleanup\":\n goal: the repo audit reports zero stale branches, worktrees, or unresolved PRs\n done when \"node scripts/repo-audit.mjs --stale-days 30\" finds nothing # TODO: your audit; prints one line per problem\n\n look at: the audit output, branch/PR history for anything it flags, and the last failure\n allow edits automatically, but ask me before deleting any branch with unmerged commits\n\n each cycle: plan, then act, then observe\n when it fails: reflect on the oldest item the audit still flags, then plan again\n when blocked: ask a human\n after 6 tries: stop and warn \"cleanup stuck — remaining items need an owner's decision\"\n" + }, + { + "slug": "research-to-artifact-loop", + "title": "research to artifact", + "shape": "loop", + "glyph": "↻", + "goal": "the research lands as a complete artifact — required sections filled, every claim sourced, decision-ready", + "doneWhen": "\"node scripts/validate-artifact.mjs docs/brief.md\" passes", + "category": "content", + "author": "Hiten Shah (@hnshah)", + "source": "https://signals.forwardfuture.com/loop-library/loops/research-to-artifact-loop/", + "concept": "Use this when research should end in a specific decision, brief, recommendation, specification, page, or other artifact rather than a pile o", + "keywords": "research to artifact loop content loop", + "text": "# The research-to-artifact loop — research that must end as a decision-ready artifact.\n# concept via Hiten Shah (@hnshah) — https://signals.forwardfuture.com/loop-library/loops/research-to-artifact-loop/\n# Research without a deliverable sprawls. Fix the artifact's shape up front (brief,\n# spec, recommendation — with required sections); a validator checks the shape and\n# the citations, a judge checks it would actually support the decision.\n\nloop \"research to artifact\":\n goal: the research lands as a complete artifact — required sections filled, every claim sourced, decision-ready\n done when \"node scripts/validate-artifact.mjs docs/brief.md\" passes # TODO: your artifact + required-sections/citations validator\n done when the skill \"artifact-review\" approves on the output\n the bar: answers the motivating question directly; recommendation follows from the cited evidence; open questions listed rather than hidden\n\n look at: the motivating question, the source notes, the artifact template, and the last failure\n allow edits automatically\n\n each cycle: plan, then act, then observe\n when it fails: reflect on which section is weakest against the bar, then plan again\n after 6 tries: stop and warn \"artifact not converging — the question may need narrowing\"\n" + }, + { + "slug": "stale-safe-batch-release-loop", + "title": "stale-safe batch release", + "shape": "loop", + "glyph": "↻", + "goal": "every branch in the release queue is rebased on current main and green, with none merged stale", + "doneWhen": "\"node scripts/release-queue-check.mjs\" passes", + "category": "operations", + "author": "Matthew Berman", + "source": "https://signals.forwardfuture.com/loop-library/loops/stale-safe-batch-release-loop/", + "concept": "Use this when several branches or pull requests may be ready at once and the release must avoid stale worktrees, partial overlays, and incom", + "keywords": "stale safe batch release loop operations loop", + "text": "# The stale-safe batch release — merge a queue of ready branches without a stale one slipping through.\n# concept via Matthew Berman — https://signals.forwardfuture.com/loop-library/loops/stale-safe-batch-release-loop/\n# The classic batch-release failure: branch B was green against main-as-of-Tuesday.\n# The checker demands every queued branch be rebased on CURRENT main and green after\n# the rebase. Merges themselves stay human-gated.\n\nloop \"stale-safe batch release\":\n goal: every branch in the release queue is rebased on current main and green, with none merged stale\n done when \"node scripts/release-queue-check.mjs\" passes # TODO: per queued branch — up to date with main AND CI green post-rebase\n\n look at: the release queue, each branch's diff against main, CI status per branch, and the last failure\n allow edits automatically, but ask me before merging anything and before force-pushing a rebase\n\n each cycle: plan, then act, then observe\n when it fails: reflect on which branch went stale or red after rebase, then plan again\n when blocked: ask a human\n after 6 tries: stop and warn \"release queue unstable — branches keep invalidating each other\"\n" + }, + { + "slug": "sub-50ms-page-load-loop", + "title": "sub-50ms page load", + "shape": "loop", + "glyph": "↻", + "goal": "every route in the perf manifest renders under its latency budget, measured by the harness, reliably", + "doneWhen": "\"npm run perf:check\" passes 3 times", + "category": "engineering", + "author": "Matthew Berman", + "source": "https://signals.forwardfuture.com/loop-library/loops/sub-50ms-page-load-loop/", + "concept": "Use this when a product has a defined set of routes, a stable performance harness, and a 50 ms target that maps to a specific metric and env", + "keywords": "sub 50ms page load loop engineering loop", + "text": "# The sub-50ms page-load loop — drive every route under a hard latency budget.\n# concept via Matthew Berman — https://signals.forwardfuture.com/loop-library/loops/sub-50ms-page-load-loop/\n# Needs a stable perf harness that exits non-zero when any route misses the budget.\n# The flake guard matters here: performance numbers wobble, so one lucky run is not \"done\".\n\nloop \"sub-50ms page load\":\n goal: every route in the perf manifest renders under its latency budget, measured by the harness, reliably\n done when \"npm run perf:check\" passes 3 times # TODO: your harness; exits non-zero on any budget miss\n\n look at: the perf manifest, the slowest route's code path, and the last failure\n allow edits automatically, but ask me before removing features or changing caching semantics\n\n each cycle: plan, then act, then observe\n when it fails: reflect on the single worst route in the harness output, then plan again\n when blocked: ask a human\n after 8 tries: stop and warn \"perf budget stuck — remaining routes may need architectural work\"\n" + }, + { + "slug": "test-stabilizer-loop", + "title": "test stabilizer", + "shape": "loop", + "glyph": "↻", + "goal": "the suite passes reliably — flakes fixed at their root cause, not silenced", + "doneWhen": "\"npm test\" passes 5 times", + "category": "engineering", + "author": "hungtv27 (@hungtv27)", + "source": "https://signals.forwardfuture.com/loop-library/loops/test-stabilizer-loop/", + "concept": "Use this when a test suite produces inconsistent results across otherwise comparable runs and the failures may come from shared state, timin", + "keywords": "test stabilizer loop engineering loop", + "text": "# The test stabilizer — flaky tests fixed at the cause, proven by repetition.\n# concept via hungtv27 (@hungtv27) — https://signals.forwardfuture.com/loop-library/loops/test-stabilizer-loop/\n# The flake guard IS the verification: one green run proves nothing about a flaky\n# suite, so the loop must produce five consecutive green runs. Weakening or skipping\n# a test to \"stabilize\" it is gated.\n\nloop \"test stabilizer\":\n goal: the suite passes reliably — flakes fixed at their root cause, not silenced\n done when \"npm test\" passes 5 times\n\n look at: the flakiest tests from recent CI history, their shared fixtures and timing assumptions, and the last failure\n allow edits automatically, but ask me before skipping, deleting, or loosening any test\n\n each cycle: plan, then act, then observe\n when it fails: reflect on whether the failure is the same flake or a new one, then plan again\n when blocked: ask a human\n after 8 tries: stop and warn \"stabilizer stuck — the remaining flake may be infrastructure\"\n" + }, + { + "slug": "test-suite-speed-loop", + "title": "test-suite speed", + "shape": "loop", + "glyph": "↻", + "goal": "the full test suite runs under the time budget with every test still passing and none weakened", + "doneWhen": "\"node scripts/time-budget.mjs --max 120s -- npm test\" passes", + "category": "engineering", + "author": "Matthew Berman", + "source": "https://signals.forwardfuture.com/loop-library/loops/test-suite-speed-loop/", + "concept": "Use this when slow tests are delaying local feedback or continuous integration and the project has stable commands for measuring runtime and", + "keywords": "test suite speed loop engineering loop", + "text": "# The test-suite speed loop — make the suite fast without making it weaker.\n# concept via Matthew Berman — https://signals.forwardfuture.com/loop-library/loops/test-suite-speed-loop/\n# Two checks on purpose: the time budget AND the full suite green — so \"faster by\n# deleting tests\" can never satisfy the loop. Pair with a trajectory eval if you\n# want a judge confirming no test was weakened.\n\nloop \"test-suite speed\":\n goal: the full test suite runs under the time budget with every test still passing and none weakened\n done when \"node scripts/time-budget.mjs --max 120s -- npm test\" passes # TODO: budget + your suite\n done when \"npm test\" passes\n\n look at: the slowest test files from the runner's timing report, test setup/teardown, and the last failure\n allow edits automatically, but ask me before deleting or skipping any test\n\n each cycle: plan, then act, then observe\n when it fails: reflect on the top item in the timing report, then plan again\n after 8 tries: stop and warn \"suite speed stuck — remaining time may be irreducible setup\"\n" + }, + { + "slug": "ui-ux-score-loop", + "title": "UI/UX score", + "shape": "loop", + "glyph": "↻", + "goal": "the chosen user task is completable and scores well on the experience of completing it", + "doneWhen": "\"npm run test:e2e -- --grep signup\" passes", + "category": "design", + "author": "Hayden Cassar (@hcassar93)", + "source": "https://signals.forwardfuture.com/loop-library/loops/ui-ux-score-loop/", + "concept": "Use this for a real task such as signup, login, onboarding, checkout, sharing, or creating and editing an item when the entire experience ca", + "keywords": "ui ux score loop design loop", + "text": "# The UI/UX score loop — a real user task, judged on the journey rather than the screenshot.\n# concept via Hayden Cassar (@hcassar93) — https://signals.forwardfuture.com/loop-library/loops/ui-ux-score-loop/\n# Pick one task (signup, checkout, share). The e2e run proves it works; the\n# trajectory eval judges what it was LIKE — steps, dead ends, unclear states —\n# because a flow can pass and still be miserable.\n\nloop \"UI/UX score\":\n goal: the chosen user task is completable and scores well on the experience of completing it\n done when \"npm run test:e2e -- --grep signup\" passes # TODO: your task's e2e spec\n done when the skill \"ux-review\" scores 8 or more on the trajectory\n the bar: no step where the next action is unclear; errors explain recovery; no more steps than the task inherently needs; loading and empty states present\n\n look at: the task's screens and copy, the e2e trace of the journey, and the last failure\n allow edits automatically, but ask me before changing the task's scope or removing steps users rely on\n\n each cycle: plan, then act, then observe\n when it fails: reflect on the worst moment in the journey the judge described, then plan again\n after 8 tries: stop and warn \"UX score plateaued — remaining friction may be structural\"\n\n a human reviews before stopping\n" + }, + { + "slug": "war-loops-frontend-designer", + "title": "frontend reconstruction", + "shape": "loop", + "glyph": "↻", + "goal": "the rebuilt interface matches the reference in layout, spacing, type, and interaction feel", + "doneWhen": "\"npm run build && node scripts/capture.mjs\" passes", + "category": "design", + "author": "Swayam", + "source": "https://signals.forwardfuture.com/loop-library/loops/war-loops-frontend-designer/", + "concept": "Use War Loops when an authorized interface must be rebuilt from a URL or image and judged on appearance, motion, and responsive behavior.", + "keywords": "war loops frontend designer design loop", + "text": "# War Loops: frontend reconstruction — rebuild an interface until a judge can't tell it apart.\n# concept via Swayam — https://signals.forwardfuture.com/loop-library/loops/war-loops-frontend-designer/\n# For authorized rebuilds (your own legacy UI, a licensed design): implement, capture\n# a screenshot, and let a judge score the match against the reference. Deterministic\n# checks keep it honest; the judge scores what pixels can't diff — motion, feel, spacing rhythm.\n\nloop \"frontend reconstruction\":\n goal: the rebuilt interface matches the reference in layout, spacing, type, and interaction feel\n done when \"npm run build && node scripts/capture.mjs\" passes # TODO: builds + captures screenshots of the target routes\n done when the skill \"visual-match\" scores 8 or more on the output\n the bar: layout and hierarchy match the reference; spacing rhythm and type scale consistent; interactive states present; deductions listed with screen regions\n\n look at: the reference captures, the current build's captures side by side, and the last failure\n allow edits automatically\n\n each cycle: plan, then act, then observe\n when it fails: reflect on the region with the biggest visual gap, then plan again\n after 10 tries: stop and warn \"reconstruction plateaued — remaining gaps need the reference's assets\"\n\n a human reviews before stopping\n" + } + ] +} \ No newline at end of file diff --git a/docs/market/index.html b/docs/market/index.html new file mode 100644 index 0000000..a001057 --- /dev/null +++ b/docs/market/index.html @@ -0,0 +1,199 @@ + + + + + + +Loop market — verified .loop workflows + + + + + + + + + + + + + + +
    + +

    Loop market

    + verified .loop workflows — every entry parses, checks itself, and shipped through a reviewed PR + + ← the tutorial + + Submit your loop +
    + +
    +

    The bar for every loop here: parses + a machine-checkable done when + attribution — CI enforces it on every submission.

    +
    + +
    +
    +
    +
    + +
    +
    No loops match —
    + +
    +

    Built a loop worth sharing?

    +

    Uploads are pull requests: add a .loop under marketplace/loops/, CI runs the same validator you see above, a maintainer reviews, merge = published. Attribution required, prose-only verification rejected.

    + Read the bar → CONTRIBUTING.md +
    + + + + diff --git a/market/build-catalog.mjs b/market/build-catalog.mjs new file mode 100644 index 0000000..b13f3f4 --- /dev/null +++ b/market/build-catalog.mjs @@ -0,0 +1,66 @@ +// Build docs/market/catalog.json from marketplace/loops/*.loop. +// The validator gates entry: a loop that fails the bar never reaches the catalog — +// which is why the market UI needs no "broken loop" state (design.md → states). +// Metadata (category/author/source/concept) joins from market/curated.yaml by slug; +// loops not in curated.yaml (future submissions) fall back to their attribution header. +import { readdirSync, readFileSync, writeFileSync, mkdirSync } from "node:fs"; +import { join } from "node:path"; +import { execFileSync } from "node:child_process"; +import { parse } from "@loop-lang/parser"; + +// 1. the bar +execFileSync("node", [new URL("./validate-marketplace.mjs", import.meta.url).pathname], { stdio: "inherit" }); + +// 2. curated metadata by slug +const curated = {}; +{ + const text = readFileSync(new URL("./curated.yaml", import.meta.url), "utf8"); + let cur = null; + for (const line of text.split("\n")) { + const m = line.match(/^ - slug: (.+)$/); + if (m) { cur = { slug: m[1].trim() }; curated[cur.slug] = cur; continue; } + const kv = line.match(/^ (\w+): "?(.*?)"?$/); + if (kv && cur) cur[kv[1]] = kv[2]; + } +} + +const GLYPH = { loop: "↻", pipeline: "▶", flow: "→" }; +const dir = new URL("../marketplace/loops/", import.meta.url).pathname; +const entries = []; + +for (const f of readdirSync(dir).filter((x) => x.endsWith(".loop")).sort()) { + const src = readFileSync(join(dir, f), "utf8"); + const slug = f.replace(/\.loop$/, ""); + const spec = parse(src); + const def = spec.definitions[0]; + const loop = def.kind === "pipeline" ? def.stages[0].loop : def; + + // first machine-checkable predicate, reconstructed as display text + const pred = (loop.doneWhen ?? []).find((p) => p.type !== "human"); + let doneWhen = ""; + if (pred?.type === "test") doneWhen = `the test "${pred.target}" passes${pred.runs > 1 ? ` ${pred.runs} times` : ""}`; + else if (pred?.type === "command") doneWhen = `"${pred.command}" ${pred.expect === "empty" ? "finds nothing" : "passes"}${pred.runs > 1 ? ` ${pred.runs} times` : ""}`; + else if (pred?.type === "skill") doneWhen = `the skill "${pred.skill}" ${pred.minScore ? `scores ${pred.minScore}+` : "approves"}${pred.judges > 1 ? ` by ${pred.judges} judges` : ""}`; + + const meta = curated[slug] ?? {}; + const header = src.match(/^# concept via (.+?) — (https:\/\/\S+)/m); + entries.push({ + slug, + title: def.name ?? slug, + shape: def.kind, + glyph: GLYPH[def.kind] ?? "↻", + goal: loop.goal ?? "", + doneWhen, + category: meta.category ?? "engineering", + author: meta.author ?? header?.[1] ?? "community", + source: meta.source ?? header?.[2] ?? "", + concept: meta.concept ?? "", + keywords: [slug.replace(/-/g, " "), meta.category ?? "", def.kind].join(" "), + text: src, + }); +} + +const outDir = new URL("../docs/market/", import.meta.url).pathname; +mkdirSync(outDir, { recursive: true }); +writeFileSync(join(outDir, "catalog.json"), JSON.stringify({ built: "loop-market", count: entries.length, entries }, null, 1)); +console.log(`✓ catalog.json — ${entries.length} loops`); diff --git a/market/check-curated.mjs b/market/check-curated.mjs new file mode 100644 index 0000000..2cecc35 --- /dev/null +++ b/market/check-curated.mjs @@ -0,0 +1,30 @@ +// Validates market/curated.yaml — the curate stage's done-when. +// 20–30 entries; every entry carries slug/title/category/author/source/concept/verify_as; +// slugs unique; categories from the known set; source URLs well-formed. +import { readFileSync } from "node:fs"; + +const text = readFileSync(new URL("./curated.yaml", import.meta.url), "utf8"); +const entries = []; +let cur = null; +for (const line of text.split("\n")) { + const m = line.match(/^ - slug: (.+)$/); + if (m) { cur = { slug: m[1].trim() }; entries.push(cur); continue; } + const kv = line.match(/^ (\w+): "?(.*?)"?$/); + if (kv && cur) cur[kv[1]] = kv[2]; +} + +const REQUIRED = ["slug", "title", "category", "author", "source", "concept", "verify_as"]; +const CATS = new Set(["engineering", "evaluation", "operations", "content", "design"]); +const fail = (msg) => { console.error("✗ " + msg); process.exitCode = 1; }; + +if (entries.length < 20 || entries.length > 30) fail(`expected 20–30 entries, found ${entries.length}`); +const seen = new Set(); +for (const e of entries) { + for (const k of REQUIRED) if (!e[k]) fail(`${e.slug ?? "?"}: missing ${k}`); + if (seen.has(e.slug)) fail(`duplicate slug ${e.slug}`); + seen.add(e.slug); + if (e.category && !CATS.has(e.category)) fail(`${e.slug}: unknown category ${e.category}`); + if (e.source && !/^https:\/\//.test(e.source)) fail(`${e.slug}: source is not an https URL`); +} +if (process.exitCode) process.exit(1); +console.log(`✓ curated.yaml valid — ${entries.length} entries, all attributed`); diff --git a/market/check-design.mjs b/market/check-design.mjs new file mode 100644 index 0000000..29034aa --- /dev/null +++ b/market/check-design.mjs @@ -0,0 +1,15 @@ +// design.loop's done-when: market/design.md must carry a Decision + Rationale +// for every UI/UX axis the loop names. +import { readFileSync } from "node:fs"; + +const AXES = ["layout", "card", "discovery", "detail view", "copy action", "submit", "states", "brand", "a11y"]; +const md = readFileSync(new URL("./design.md", import.meta.url), "utf8"); + +let failed = 0; +for (const axis of AXES) { + const section = md.split(new RegExp(`^## ${axis}$`, "m"))[1]?.split(/^## /m)[0] ?? ""; + if (!/\*\*Decision:\*\*/.test(section)) { console.error(`✗ ${axis}: no Decision`); failed++; } + if (!/\*\*Rationale:\*\*/.test(section)) { console.error(`✗ ${axis}: no Rationale`); failed++; } +} +if (failed) process.exit(1); +console.log(`✓ design.md — a decision and rationale for all ${AXES.length} axes`); diff --git a/market/check-site.mjs b/market/check-site.mjs new file mode 100644 index 0000000..e734201 --- /dev/null +++ b/market/check-site.mjs @@ -0,0 +1,31 @@ +// site.loop's done-when (second half): the catalog artifact and the gallery page +// are complete and consistent. +import { readFileSync } from "node:fs"; +import { parse } from "@loop-lang/parser"; + +const fail = (m) => { console.error("✗ " + m); process.exitCode = 1; }; + +let cat; +try { cat = JSON.parse(readFileSync(new URL("../docs/market/catalog.json", import.meta.url), "utf8")); } +catch { fail("docs/market/catalog.json missing or invalid"); process.exit(1); } + +if (cat.count < 20) fail(`catalog has ${cat.count} loops — expected ≥ 20`); +for (const e of cat.entries) { + for (const k of ["slug", "title", "goal", "doneWhen", "category", "author", "text"]) { + if (!e[k]) fail(`${e.slug ?? "?"}: missing ${k}`); + } + try { parse(e.text); } catch (err) { fail(`${e.slug}: embedded source no longer parses — ${err.message}`); } +} + +const html = readFileSync(new URL("../docs/market/index.html", import.meta.url), "utf8"); +for (const [needle, why] of [ + ['id="q"', "search input"], + ['id="chips"', "category chips"], + ["Submit your loop", "submit CTA"], + ["catalog.json", "catalog fetch"], + ["aria-pressed", "a11y chips"], + ["CONTRIBUTING.md", "the bar link"], +]) if (!html.includes(needle)) fail(`market page missing ${why}`); + +if (process.exitCode) process.exit(1); +console.log(`✓ market site — catalog ${cat.count} loops, page carries search/chips/submit/a11y hooks`); diff --git a/market/convert-template.loop b/market/convert-template.loop new file mode 100644 index 0000000..8a258b2 --- /dev/null +++ b/market/convert-template.loop @@ -0,0 +1,17 @@ +# Per-entry template — the for-each hands one curated entry (slug, title, author, +# source, concept) in as context. Write an ORIGINAL .loop implementing the concept: +# a real machine-checkable `done when` (never prose), scoped look-at, a reflect +# back-edge, a thrash guard, gates where the concept touches anything risky. +# Header comment must attribute: concept via , . +# Follow the authoring order: contract → boundaries → engine → safety net. + +loop "convert one concept to a verified .loop": + goal: marketplace/loops/.loop exists, implements the entry's concept with a real done-when, carries the attribution header, and passes the marketplace validator + done when "node market/validate-marketplace.mjs" passes + + look at: the curated entry in context, AGENTS.md, templates/bugfix.loop, and the last failure + allow edits automatically + + each cycle: plan, then act, then observe + when it fails: reflect on the validator output, then plan again + after 3 tries: stop and warn "conversion stuck on this entry" diff --git a/market/curate.loop b/market/curate.loop new file mode 100644 index 0000000..aaa46a2 --- /dev/null +++ b/market/curate.loop @@ -0,0 +1,18 @@ +# Stage 1 — pick the best 20–30 concepts from the scanned library and write the +# work list the for-each will iterate. Selection criteria: verifiable with a real +# command (our whole edge), category spread, no duplicates of our templates/. +# Each entry carries attribution (author, source URL) — we implement the CONCEPT +# as an original .loop; we do not copy their prose. + +loop "curate the conversion list": + goal: market/curated.yaml lists 20-30 entries picked from market/ff-loops.json, each with slug, title, category, author, source url, and a one-line concept note — plus market/check-curated.mjs that validates exactly that shape + done when "node market/check-curated.mjs" passes + + look at: market/ff-loops.json, templates/README.md, and the last failure + allow edits automatically + + a human approves the plan first + + each cycle: plan, then act, then observe + when it fails: reflect on what the checker rejected, then plan again + after 4 tries: stop and warn "curation stuck — pick the list by hand" diff --git a/market/curated.yaml b/market/curated.yaml new file mode 100644 index 0000000..00caf9d --- /dev/null +++ b/market/curated.yaml @@ -0,0 +1,207 @@ +# curated.yaml — 29 concepts selected from the Forward Future Loop Library scan +# (market/ff-loops.json, 2026-07-03). Approved by Idan. Each becomes an ORIGINAL +# .loop implementing the concept with a real done-when; attribution required. +entries: + - slug: overnight-docs-sweep + title: "The docs sweep" + category: engineering + author: "Matthew Berman" + source: "https://signals.forwardfuture.com/loop-library/loops/overnight-docs-sweep/" + concept: "Use this whenever implementation changes may have left READMEs, setup guides, API references, examples, or runbooks behind." + verify_as: "doc-drift checker + resolving links (finds nothing)" + - slug: sub-50ms-page-load-loop + title: "The sub-50 ms page-load loop" + category: engineering + author: "Matthew Berman" + source: "https://signals.forwardfuture.com/loop-library/loops/sub-50ms-page-load-loop/" + concept: "Use this when a product has a defined set of routes, a stable performance harness, and a 50 ms target that maps to a specific metric and env" + verify_as: "perf harness budget passes" + - slug: production-error-sweep + title: "The production error sweep" + category: engineering + author: "Matthew Berman" + source: "https://signals.forwardfuture.com/loop-library/loops/production-error-sweep/" + concept: "Use this as a scheduled reliability pass when an agent can read production telemetry, trace failures into the repository, run the relevant t" + verify_as: "telemetry error count under threshold" + - slug: exhaustive-logging-coverage-loop + title: "The logging coverage loop" + category: engineering + author: "Matthew Berman" + source: "https://signals.forwardfuture.com/loop-library/loops/exhaustive-logging-coverage-loop/" + concept: "Use this when important user flows, service boundaries, background jobs, or failure paths are difficult to trace because the system's loggin" + verify_as: "logging-coverage checker over key flows" + - slug: test-suite-speed-loop + title: "The test-suite speed loop" + category: engineering + author: "Matthew Berman" + source: "https://signals.forwardfuture.com/loop-library/loops/test-suite-speed-loop/" + concept: "Use this when slow tests are delaying local feedback or continuous integration and the project has stable commands for measuring runtime and" + verify_as: "suite wall-clock under budget" + - slug: repository-cleanup-loop + title: "The repository cleanup loop" + category: engineering + author: "Matthew Berman" + source: "https://signals.forwardfuture.com/loop-library/loops/repository-cleanup-loop/" + concept: "Use this when abandoned branches, old worktrees, unclear pull requests, or unmerged commits make it difficult to know which repository state" + verify_as: "branch/worktree audit finds nothing" + - slug: fresh-clone-loop + title: "The fresh-clone loop" + category: engineering + author: "0xUmbra" + source: "https://signals.forwardfuture.com/loop-library/loops/fresh-clone-loop/" + concept: "Use this to test whether a repository's onboarding instructions work in a clean environment without undocumented help." + verify_as: "clean-env clone, setup, test all pass" + - slug: propagation-compliance-loop + title: "The propagation compliance loop" + category: engineering + author: "@iamTristan" + source: "https://signals.forwardfuture.com/loop-library/loops/propagation-compliance-loop/" + concept: "Use this after changing something that appears in several files—such as a version number, feature name, count, rule, setting, or identifier—" + verify_as: "grep for the stale value finds nothing" + - slug: cold-load-trimmer-loop + title: "The cold-load trimmer loop" + category: engineering + author: "Christian Katzmann" + source: "https://signals.forwardfuture.com/loop-library/loops/cold-load-trimmer-loop/" + concept: "Use this when a web app feels heavy on its first visit because it downloads too much code, styling, media, or other data before showing the" + verify_as: "bundle-size budget passes" + - slug: test-stabilizer-loop + title: "The test stabilizer loop" + category: engineering + author: "hungtv27 (@hungtv27)" + source: "https://signals.forwardfuture.com/loop-library/loops/test-stabilizer-loop/" + concept: "Use this when a test suite produces inconsistent results across otherwise comparable runs and the failures may come from shared state, timin" + verify_as: "flake guard: the suite passes 5 times" + - slug: error-message-rewrite-loop + title: "The error-message rewrite loop" + category: engineering + author: "Will Undrell (@WillUndrll)" + source: "https://signals.forwardfuture.com/loop-library/loops/error-message-rewrite-loop/" + concept: "Use this when a product exposes raw, internal, inconsistent, or unhelpful error messages and the complete user-facing error surface needs a" + verify_as: "error-string lint + human review" + - slug: dependency-cve-burndown-loop + title: "The dependency-CVE burndown loop" + category: engineering + author: "hungtv27 (@hungtv27)" + source: "https://signals.forwardfuture.com/loop-library/loops/dependency-cve-burndown-loop/" + concept: "Use this when dependency scans report high or critical CVEs and remediation should reflect whether vulnerable code is actually reachable in" + verify_as: "dependency audit finds no high/critical" + - slug: quality-streak-loop + title: "The quality streak loop" + category: evaluation + author: "Matthew Berman" + source: "https://signals.forwardfuture.com/loop-library/loops/quality-streak-loop/" + concept: "Use this when product quality needs a strict consecutive-success bar and failures should permanently improve the test and benchmark suite." + verify_as: "the check passes N times in a row" + - slug: full-product-evaluation-loop + title: "The full product evaluation loop" + category: evaluation + author: "Matthew Berman" + source: "https://signals.forwardfuture.com/loop-library/loops/full-product-evaluation-loop/" + concept: "Use this for an exhaustive, end-to-end application QA pass when a production-like local environment and complete interactive-surface coverag" + verify_as: "e2e suite green + review skill approves" + - slug: devils-advocate-design-loop + title: "The devil's-advocate loop" + category: evaluation + author: "Anonymous contributor" + source: "https://signals.forwardfuture.com/loop-library/loops/devils-advocate-design-loop/" + concept: "Use this before committing to an architecture, interface, rollout plan, or other consequential design that benefits from structured adversar" + verify_as: "a judge panel: approves by 3 judges" + - slug: promise-to-proof-loop + title: "The promise-to-proof loop" + category: evaluation + author: "Felix Haeberle (@felixhaberle)" + source: "https://signals.forwardfuture.com/loop-library/loops/promise-to-proof-loop/" + concept: "Use this when what a product says it does may no longer match what it actually does across marketing, documentation, demos, support answers," + verify_as: "claims-vs-behavior checker + eval" + - slug: multi-llm-convergence-loop + title: "The multi-LLM convergence loop" + category: evaluation + author: "Donn Felker (@donnfelker)" + source: "https://signals.forwardfuture.com/loop-library/loops/multi-llm-convergence-loop/" + concept: "Use this when an important plan, specification, design, document, or code change benefits from two independent AI perspectives rather than o" + verify_as: "independent judges converge (majority)" + - slug: literature-search-verification-loop + title: "The literature-search verification loop" + category: evaluation + author: "Nathan Nguyen" + source: "https://signals.forwardfuture.com/loop-library/loops/literature-search-verification-loop/" + concept: "Use this when a literature search must produce a high-precision, auditable paper set rather than an unverified list of citations." + verify_as: "every citation resolves (checker)" + - slug: war-loops-frontend-designer + title: "War Loops: frontend reconstruction" + category: design + author: "Swayam" + source: "https://signals.forwardfuture.com/loop-library/loops/war-loops-frontend-designer/" + concept: "Use War Loops when an authorized interface must be rebuilt from a URL or image and judged on appearance, motion, and responsive behavior." + verify_as: "judge scores the rebuild 8+ vs reference" + - slug: ui-ux-score-loop + title: "The UI/UX Score Loop" + category: design + author: "Hayden Cassar (@hcassar93)" + source: "https://signals.forwardfuture.com/loop-library/loops/ui-ux-score-loop/" + concept: "Use this for a real task such as signup, login, onboarding, checkout, sharing, or creating and editing an item when the entire experience ca" + verify_as: "eval judges the task on the trajectory" + - slug: pixel-safe-css-trim-loop + title: "The pixel-safe CSS trim loop" + category: design + author: "Christian Katzmann" + source: "https://signals.forwardfuture.com/loop-library/loops/pixel-safe-css-trim-loop/" + concept: "Use this when a website's styling files may contain unused declarations, duplicated rules, or old overrides and representative pages and int" + verify_as: "pixel-diff identical AND stylesheet smaller" + - slug: accessibility-repair-loop + title: "The accessibility repair loop" + category: design + author: "Eric Lott" + source: "https://signals.forwardfuture.com/loop-library/loops/accessibility-repair-loop/" + concept: "Use this when a website or app has a defined accessibility target and you can repeatedly test the relevant pages, components, or tasks for p" + verify_as: "accessibility scan finds nothing" + - slug: stale-safe-batch-release-loop + title: "The stale-safe batch release loop" + category: operations + author: "Matthew Berman" + source: "https://signals.forwardfuture.com/loop-library/loops/stale-safe-batch-release-loop/" + concept: "Use this when several branches or pull requests may be ready at once and the release must avoid stale worktrees, partial overlays, and incom" + verify_as: "each branch rebased + green before merge" + - slug: post-release-baseline-loop + title: "The post-release baseline loop" + category: operations + author: "Matthew Berman" + source: "https://signals.forwardfuture.com/loop-library/loops/post-release-baseline-loop/" + concept: "Use this immediately after a release when future regressions or improvements need to be measured against the exact version now in production" + verify_as: "baseline artifact exists and validates" + - slug: recovery-proof-loop + title: "The Recovery Proof loop" + category: operations + author: "Eric Lott" + source: "https://signals.forwardfuture.com/loop-library/loops/recovery-proof-loop/" + concept: "Use this when backup existence is not enough and the organization needs repeatable proof that required systems can be restored from document" + verify_as: "restore drill passes end to end" + - slug: dependency-triage-loop + title: "The dependency triage loop" + category: operations + author: "Damian Galarza (@dgalarza)" + source: "https://signals.forwardfuture.com/loop-library/loops/dependency-triage-loop/" + concept: "Use this when a repository has several open Dependabot pull requests and an authorized maintainer wants them reviewed safely without stale c" + verify_as: "each dep PR: CI green then merged or closed" + - slug: nightly-changelog-sweep + title: "The nightly changelog loop" + category: content + author: "Matthew Berman" + source: "https://signals.forwardfuture.com/loop-library/loops/nightly-changelog-sweep/" + concept: "Use this when a project changes frequently enough that user-facing release notes can drift from merged pull requests, commits, deployments," + verify_as: "changelog matches merged PRs (diff check)" + - slug: research-to-artifact-loop + title: "The research-to-artifact loop" + category: content + author: "Hiten Shah (@hnshah)" + source: "https://signals.forwardfuture.com/loop-library/loops/research-to-artifact-loop/" + concept: "Use this when research should end in a specific decision, brief, recommendation, specification, page, or other artifact rather than a pile o" + verify_as: "artifact validator + review skill" + - slug: pre-publish-source-check-loop + title: "The pre-publish source-check loop" + category: content + author: "Ryan Banze (@RyanBanze)" + source: "https://signals.forwardfuture.com/loop-library/loops/pre-publish-source-check-loop/" + concept: "Use this immediately before publishing an article, newsletter, post, report, or other factual draft whose claims, quotations, and attributio" + verify_as: "every cited source resolves (checker)" diff --git a/market/design.loop b/market/design.loop new file mode 100644 index 0000000..a37d45b --- /dev/null +++ b/market/design.loop @@ -0,0 +1,27 @@ +# Stage 2.5 — the UI/UX decisions, decided BEFORE the page is built and approved +# by a human. The artifact is market/design.md; site.loop builds from it, not from +# improvisation. Decisions the file must nail down: +# layout — gallery grid vs list; card size; how many per row; mobile stacking +# card — anatomy: title, goal line, done-when line, shape glyph (↻/▶/→), +# category badge, author attribution, votes placeholder, Copy / View +# discovery — search behavior (fields indexed), category filter chips, sort order +# detail view — inline expand vs per-loop page; what "View source" shows +# copy action — what exactly gets copied (raw .loop text), success feedback +# submit — where "Submit your loop" sits and what it opens (prefilled PR) +# states — empty search, loading, a loop that fails to parse (never render it) +# brand — tutorial's tokens: #0b0d12 field, teal #34e0c4, Ubuntu/Ubuntu Mono, +# the gap-ring mark; must feel like loopflow.live, not a bolt-on +# a11y — keyboard nav through cards, focus states, contrast on badges + +loop "decide the marketplace UI/UX": + goal: market/design.md records a decision for every item in the checklist above, each as "decision — rationale", concrete enough that site.loop needs no design judgment + done when "node market/check-design.mjs" passes + + look at: docs/playground.html, docs/index.html, the tutorial's hands-on cards, and the last failure + allow edits automatically + + each cycle: plan, then act, then observe + when it fails: reflect on which decision the checker found missing, then plan again + after 4 tries: stop and warn "design decisions stuck" + + a human reviews before stopping diff --git a/market/design.md b/market/design.md new file mode 100644 index 0000000..28d1989 --- /dev/null +++ b/market/design.md @@ -0,0 +1,39 @@ +# Marketplace UI/UX — the decisions + +Every axis from `design.loop`, decided before code. `site.loop` implements this file. + +## layout +**Decision:** responsive card grid — `repeat(auto-fill, minmax(360px, 1fr))`; 3 columns on desktop, 2 on tablet, 1 under 720px. Cards equal-height per row. +**Rationale:** loops are scannable one-liners + a code payload; a grid maximizes concepts-per-viewport, and 360px fits the longest `done when` line in Ubuntu Mono 13px without wrapping twice. + +## card +**Decision:** anatomy top-to-bottom — category badge + shape glyph (↻ loop / ▶ pipeline / → flow) on one row · title (18px, 700) · goal line (muted, 2-line clamp) · `done when` first predicate in mono teal (1-line, ellipsis) · footer: `concept via ` (small, muted) + [Copy] [View] buttons. **No votes in v1** — no backend; leave no placeholder UI (dead chrome reads as broken). +**Rationale:** the `done when` line IS the differentiator vs Forward Future — it earns card real estate. Attribution visible on every card honors the source library. + +## discovery +**Decision:** client-side search over title + goal + author + keywords (from catalog.json); category chips All/Engineering/Evaluation/Design/Operations/Content with counts; sort fixed: category → title A-Z. A live "N loops" count under the search box. +**Rationale:** 29 items — client-side is instant; fixed sort keeps browsing stable until votes exist to rank by. + +## detail view +**Decision:** inline expand — [View] toggles the card open to the full `.loop` source in a `
    ` (loopflow syntax colors), plus the use-when note and a link to the source concept. No per-loop pages in v1.
    +**Rationale:** one page = one deploy artifact; per-loop pages are an SEO project for phase 2 (FF has 30 crawl pages — that's their moat to copy later, not launch-blocking).
    +
    +## copy action
    +**Decision:** [Copy] puts the raw `.loop` file text (attribution header included) on the clipboard; button text flips to "✓ copied" for 1.2s. Keyboard: the button is a real `