Skip to content

Keel v2.0.0

Choose a tag to compare

@joseconti joseconti released this 16 Jul 14:21

Major release: verification becomes executable, and the lifecycle no longer ends at the release. Gates that were prose now demand evidence — commands with outputs, diffs, recomputed values, independent reviewers with fresh context — and the skill itself gains its own test, lint and CI infrastructure so the failure classes its own changelog documents (version drift, field-tested mechanism gaps) get caught before a tag instead of in the field.

Added

  • references/keel-maintenance.md — the update check, its 24-hour throttle, the lock-freshness check, version reporting, and the full UNBREAKABLE version change policy, extracted from the SKILL.md body (which drops roughly a third of its per-session weight). SKILL.md keeps a binding "read and execute first" block plus the policy's core paragraph, so the guarantee of execution survives the extraction. The throttle stamp now carries a consecutive-failure count, and at the fifth consecutive failed remote lookup the user is told once, briefly.
  • references/playground-recipes.md — per-platform verification environments, operable by the assistant so "exercise it for real" means commands with recordable output: wp-env pinned to the support matrix with WP-CLI smoke checks and Woo seed data; MCP Inspector plus registering the dev server in .mcp.json so the assistant calls the tools live; local server or docker compose with Playwright e2e for web; a clean consumer project installing the BUILT artifact for libraries. Synthetic seed data with a reset command is part of every recipe (an empty store proves nothing), and "gate zero" (clean build + lint + one trivial passing test) opens every scaffold.
  • references/maintenance.md — the post-release lifecycle the skill previously ended without: triage with reproduce-first, the hotfix path (branch from the release tag, regression test that fails before and passes after, the full Phase 7 gate compressed in time but never in content), rollback (WordPress.org Stable tag downgrade, redeploy, deprecate — never unpublish), dependency and CVE duty ("Tested up to" is never bumped untested), the recurring-feature cycle, the full-suite rule, and the site-freshness duty. Resume routes here when PROGRESS.md marks Phase 7 done.
  • references/security/website.md + a routing row for websites — the profile Phase 8 referenced six times but no rule ever loaded: transport and security headers verified with curl -sI on the live site, forms as the one dynamic surface (server-side validation, rate limit, honeypot + time-trap anti-spam, CAPTCHA only with an accessible alternative, SPF/DKIM/DMARC-aligned mail), zero mixed content with SRI on approved third parties, deploy integrity.
  • MCP profile: "Model-facing threats" — the section that makes an MCP server different from a classic API: tool results carrying third-party content are data, never instructions (the injection channel); tool descriptions are prompts whose integrity is release-controlled (poisoning/rug-pull); confused deputy (per-user credentials, never a master token any caller can drive); destructive tools gated behind human confirmation or dry-run by default; localhost binding and Origin validation on local transports (DNS rebinding). Plus matching test points and a malicious-content fixture.
  • WordPress profile: five verified gaps closed — SSRF via wp_remote_* with user-influenced URLs, object injection (unserialize across a trust boundary), identifier placeholders (%i / allow-lists for ORDER BY and column names), hash_equals() for tokens and license keys, and output-escaping of translated strings (a malicious .po is a real vector). The embedded MCP/OAuth section is now the WP mapping only and orders loading the full MCP profile.
  • Web-app profile: credential storage and recovery — argon2id/bcrypt, MFA available and required as an option for privileged accounts, single-use time-boxed hashed reset tokens, no account enumeration, rate limits.
  • "Verify with" blocks in all five security profiles — the checks now name their tools: phpcs with the WordPress security sniffs and the Plugin Check plugin; npm audit/composer audit/pip-audit; OWASP ZAP baseline; MCP Inspector with schema fuzzing; published-artifact inspection and public-API diff for libraries. At a test point, the command and its result are the evidence — an unrecorded check did not happen.
  • Four new project subagents in references/claude-config.md, and the existing three are now actually invoked. New: design-fidelity-auditor (fresh-context fidelity walk of the build vs BUILD-SPEC and handoff), playground-qa (follows docs/playground.md literally — an instruction gap is a defect), launch-verifier (crawls the deployed site from the sitemap and returns the pass/fail table), a11y-auditor (automated accessibility pass + the guided-loop script). Wired: code-reviewer reviews every slice diff before its commit (Phase 5 test-point confirmation (f)), docs-verifier runs at sprint closes, security-auditor before the Phase 7 tag — previously defined but never referenced by any phase. Plus an optional CI workflow piece built from the technical plan's exact verified commands, with gitleaks and scripts/keel-verify.
  • scripts/keel-verify — every project generates its own release linter at the Phase 5 scaffold: version touchpoints in sync, changelog order, docs/api/INDEX.md parity, no placeholder copy in distributable surfaces, and a WP i18n dry run where it applies. Runs at every sprint close and at the Phase 7 gate, output pasted as evidence.
  • Phase 5: the testing contract the user asked for — right the first time. Every acceptance criterion maps to a named automated test (unit / integration / e2e; browser-driven e2e required for web UI flows) or carries a recorded one-line justification; every test-point row records the exact commands, output summary and commit hash ("a result without its command and output is an empty cell"); after three failed attempts at the same test point the assistant STOPS and reports instead of looping; sprint closes run the FULL suite, docs-verifier, a cold playground-qa pass and keel-verify; the playground is re-booted from its documented commands at each session's first test point and stamped last verified; declared performance budgets are measured, with numbers. Two new principles seal it: anything a compile, a boot or a basic test would have caught is a process defect if it escapes; and a failing test is never deleted, skipped or weakened to pass.
  • Phase 4: the audit leaves evidence. BUILD-SPEC §1 becomes an evidence table mirroring every gate bullet (item / checked / evidence / result — "an item without evidence is not audited"); a deterministic mechanical pass checks the filesystem facts (assets exist, SVG+PNG pairs, screens covered, open questions empty); token origin and full target-surface coverage are now audited (they were contract terms nobody checked); declared contrast pairs are recomputed from the delivered hex values; re-deliveries are diffed against the previous delivery (byte-stable is verified, the BUILD-SPEC is updated, the second bounce of an item escalates to the user); checkboxes are ticked in the file at the moment of verification.
  • Fonts are first-class handoff assets, like logos and icons (handoff contract, rule 4). Design ships the actual self-hosted font files at their final paths — only the used weights/styles, woff2 first for the web, the @font-face rules already written against those paths — or, when licensing prevents shipping, a complete acquisition block per font: exact download source, license note, exact files, exact target path in the project structure, so the user drops them in and everything works and stays reusable. The Phase 4 audit checks it, the guided loop walks the acquisition one font at a time, and a font that is merely named is an incomplete handoff.
  • Phase 3: no more single point of failure on Design. An "If Claude Design is not available" playbook with three recorded branches (round-trip through another environment, the assistant produces the handoff under the same contract and audits it with no self-exemption, or a human designer); a brief approval gate (mechanical scan for unfilled brackets + the user approves a summary); the exact waiting position lands in PROGRESS.md; and visual references travel as annotated SCREENSHOTS, never URLs — if the user offers an address, the assistant explains that captures of what they want are far more effective than expecting Design to visit links (field-tested).
  • Phase 2: the spec defends itself. An adversarial fresh-context review before the firm estimate (six-part requirements, flow coverage, per-screen accessibility, acceptance-criterion completeness, empty/permission/double-submit ambiguities); the Testing block names frameworks and exact commands per layer, the playground recipe, seed data and the per-flow real-exercise command; the design split now carries foreseen external assets, per-screen accessibility requirements and exact target viewports/breakpoints all the way into the template (they previously died between the step and the brief).
  • Phase 1: the edges get playbooks. Zero-competitors handling (retry differently, then record "no competitors found" as analysis: new niche or no market); "partial" scan status defined; a closure protocol for the honest assessment (verdict + user decision on record; parked status when the project stops; proceeding against a negative verdict is a recorded decision); the competitive scan delegates to subagents when available; and the Client budget: question, asked once.
  • Phase 8: launch becomes auditable, and the site outlives it. <site-docs>/launch-report.md — every checklist item leaves a row (command/tool, result, date), with the page list derived from sitemap.xml and EVERY page checked (sampling one per template is called out as insufficient); a security headers and forms block verified live; the automated accessibility pass runs over the full sitemap list while the manual pass follows the guided loop; an accessibility-statement page is required in EU scope; the 404 page joins the section catalogue as a designed template; anti-spam is now defined (in the website profile) instead of referenced; and a new "After launch — operations" section produces <site-docs>/operations.md (renewal dates including security.txt Expires, uptime and backup decisions, Search Console submission, and the freshness duty every product release triggers).
  • Accessibility: the guided assistive-technology pass. The assistant cannot run a screen reader, so the real-AT pass is a one-instruction-at-a-time user loop with per-item recorded results; what cannot be verified is ⚠ unverified — and Phase 7 now closes every unverified item (re-attempt or explicit user acceptance on record). Automated tool passes are explicitly the assistant's to run, with commands and results recorded.
  • Project state: scope changes, deferred work, parked projects. A "Scope changes" playbook (decision entry → spec amendment → design delta with re-audit → BUILD-SPEC delta → sprint re-plan → estimate/budget recompute — never smuggled through a Design Request); a "Deferred items" list with severity and review triggers (the greenfield counterpart of adoption's triage); parked as a recognized status; the Client budget: card line; the token-ledger row wired into the continuation-prompt procedure so mid-work sessions stop losing theirs; and the cache-discipline list corrected (issues, token ledger and playground are routinely-updated files).
  • MANIFEST: Table 1 completed and Table 3 added. New parity rows the references already required but the "ABSOLUTE parity check" never listed: docs/security.md, docs/accessibility.md, the repo README, docs/design/design-handoff/, scripts/keel-verify, the optional CI workflow, and the Phase 8 site artifacts including launch-report.md and operations.md. Table 3 is the per-version action list — the reconciliation applies a delta instead of interpreting the changelog.
  • Every chat or tool boundary ships a ready-to-paste prompt (new operating principle). Code to Design: the brief's complete opening message is assembled and shown, and the Phase 4 return prompt is produced at the same moment — days may pass before the handoff comes back, and the user must not have to ask for the way back in. Design to Code: the kickoff prompt. Chat to chat: the continuation prompt, shown unprompted. External agents (e.g. a competitive scan run elsewhere): the full prompt, composed by the assistant. Telling the user "ask Design to fix X" without the exact prompt is now a defect — the user is the courier, never the composer.
  • Plan mode, sprint kickoffs, and user verification per sprint (Phase 5). The skill now says when to enter plan mode: at sprint-set creation (step 0) and at the start of EVERY sprint, where the kickoff also re-validates assumptions against the source — the current code, platform and dependency versions, external APIs/hooks/schemas — before building on them (a sprint built on a stale assumption is rework with extra steps). Every sprint closes with the full suite green and everything committed, then hands the user a numbered try-it script for exactly what the sprint implemented, points them at the debug log, and asks for the verdict either way; a reported failure reopens the sprint with its regression test. The continuation prompt is then SHOWN proactively with the instruction to paste it into a new chat — the user never has to ask for it.
  • Debug logging with a switch, built into the product itself (Phase 5 scaffold; decided in the Phase 2 plan; verified at the Phase 7 gate). Every runnable project ships a copy-paste-friendly debug log so the user can hand the assistant a debuggable failure in one round trip: platform-native where one exists — WooCommerce's WC_Logger read under WooCommerce → Status → Logs, a settings checkbox in WP/PrestaShop/panel apps, an env var or constant for servers/CLIs/libraries, stderr for MCP servers (never stdout) — with entries that never contain secrets or real personal data. ON during development, OFF by default at release, and the logging code is never stripped: a production incident with a switchable log is diagnosable the same day.
  • End-user HTML guide — guide/ at the repo root (Phase 6). docs/ serves developers; the end user gets a navigable HTML guide — a main index plus one page per topic — that is VERY detailed by contract: every capability the product has appears as a task with exact steps, every setting is explained, and the completeness check is mechanical (every v1 feature and every setting maps to its guide section — a gap blocks the phase). Two questions, asked with defaults: the language(s) — one directory per locale, English recommended as the principal when there are several — and whether the guide ships in the release package (yes → it is a distributable surface, placeholder-scanned and verified on the candidate; no → /guide/ is export-ignored). Vanilla self-contained HTML that works from disk, accessible per the a11y reference, troubleshooting section wired to the debug-log switch. Once it exists, nothing is left dangling: a slice or maintenance change that adds or changes user-visible behavior updates the guide in the SAME change, in every locale; and on a Keel update of an existing project, the reconciliation itself asks whether to create the full guide now. Recorded on the project card (User guide:).
  • The skill's own test infrastructure (repo-only, export-ignored): tests/lint-release.py — version sync across frontmatter/heading/changelog/manifest/README, description length within the 1024-character installer limit, changelog order oldest → newest, reference-index parity against disk, MANIFEST Table 2 parity against the tree, canonical lock-stamp freshness; tests/evals/ — six documented eval scenarios (vague idea, resume, stale embedded copy, version-bump bait, synthetic secret, trigger boundaries); and a GitHub Actions workflow that runs the linter on every tag and publishes the release with notes extracted from this changelog.

Changed

  • Frontmatter description rewritten under the 1024-character installer limit (the 1.13.0 text had grown to 1,133 characters — a packaging regression its own history warns about twice), trading the feature-catalog sentence for a negative trigger boundary ("Do NOT trigger for one-off scripts, quick code questions, or repos not managed by Keel unless the user wants to adopt them") and the maintenance triggers (hotfix, dependency updates).
  • Phase 7: the project's version is proposed, never decided. The assistant proposes patch/minor/major with reasoning and WAITS for explicit approval before writing any number — the same discipline that protects Keel's own version, now at project scale. The pre-release gate re-runs the entire suite on the exact release candidate (recorded), runs keel-verify, closes every ⚠ unverified item, verifies zero placeholder copy and the performance budgets, and hands the project to references/maintenance.md.
  • Phase 8 vanilla rule made consistent: the permitted exceptions are exactly the two the user approves and records — a static-site generator where it adds value, and the analytics decision from site discovery — replacing two contradictory "only exception" claims. A later explicit user request for the site supersedes a recorded Phase 1 "no", as a new decision entry.
  • robots.txt AI-crawler taxonomy corrected into two axes: assistants and answer engines that fetch or cite for users (Claude-User, Claude-SearchBot, PerplexityBot, Perplexity-User, OAI-SearchBot, ChatGPT-User, DuckAssistBot — usually allow) versus training crawlers (GPTBot, ClaudeBot, Google-Extended — which governs Gemini training/grounding and does NOT affect Google AI Overviews — Applebot-Extended, CCBot, meta-externalagent, Bytespider — a recorded user decision, never a silent default). The volatility hedge now orders verifying each vendor's current crawler documentation at launch. The previous grouping misclassified ClaudeBot as a citing answer engine.
  • Technical SEO gains an interoperability note for dedicated SEO skills: keyword/intent research and per-page briefs run BEFORE the section catalogue and feed the copy; this file remains the single writer of the technical artifacts.
  • Secrets carve-out across the whole design pipeline: SPEC/external-setup.md, the Design Request register, the brief and docs/BUILD-SPEC.md record descriptive placeholders for anything that is a secret; the real value is exchanged only inside the Phase 4 guided walkthrough. The previous text ordered secrets recorded into versioned files — in direct collision with the UNBREAKABLE confidential-data rule and the project's own pre-commit gate.
  • Client budget is conditional: asked once at Phase 1 ("is there a client to bill or a quote to produce?" — Client budget: card line); without a client, no docs/budget.md and none of the rate/currency/language questions. The estimate and the token ledger remain unconditional. MANIFEST Table 1 and SKILL.md's estimation section agree with the phases again.
  • build-spec-template.md produces docs/BUILD-SPEC.md (the canonical path every other file already used), represents multi-surface token mappings, and its §1 is the evidence table.
  • Phase 1 step 7's heading no longer calls the project website "a separate skill" (residual text from before the keel-web absorption; SKILL.md always said the opposite).
  • Version-policy text says "four locations" in both places (a "three" survived the 1.12.0 addition of the manifest); SKILL.md's examples use placeholders instead of literal version strings; NOTICE no longer carries its own version line (it pointed at 1.0.0 for thirteen releases); the canonical lock block's stamp is kept equal to the released version as release hygiene, linter-checked.
  • CHANGELOG history repaired: the initial feature set recorded under a duplicated "Added" heading in 1.1.0 now lives under 1.0.0 where it belongs.
  • .gitattributes: duplicate /.editorconfig export-ignore removed; the tests directory is real now.
  • README and INSTALL refreshed and de-drifted: version and phase table current (README had been a release behind for the third time); INSTALL's tree includes MANIFEST.md, its release-archive note describes the real tarball layout (a keel-skill-vX.Y.Z/ root containing keel/), and installation now covers Claude Code, Cowork, the Claude apps (claude.ai zip upload) and the API, plus the skills marketplace.