Skip to content

feat(spec-sync): WEEEK API spec-drift detector + tool drift fixes#2

Merged
notcodev merged 16 commits into
mainfrom
feat/spec-drift-detector
Jul 1, 2026
Merged

feat(spec-sync): WEEEK API spec-drift detector + tool drift fixes#2
notcodev merged 16 commits into
mainfrom
feat/spec-drift-detector

Conversation

@notcodev

Copy link
Copy Markdown
Owner

What & why

Adds an automated WEEEK API spec-drift detector so the class of bug fixed in d3417da (MCP tools sending request shapes that don't match the WEEEK API) is caught automatically instead of by manual live probing.

Note: this branch is stacked on d3417da (the task-write-tools alignment fix), which is not yet on main, so that commit is included in this PR.

How it works

  • Spec source — WEEEK ships its OpenAPI as a hashed ESM chunk (weeek.yaml-<hash>.js exporting schema/slugs). scripts/spec-sync/load-spec.ts discovers + imports it; the normalized doc is committed at spec/weeek-openapi.json (+ meta.json).
  • Code sidecapture-contract.ts drives the real tool handlers against a RecordingClient (fake MCP server + registry) to capture every {method, path, query, body} the code actually sends — no production-code changes for capture.
  • Matcher — compares each captured request to the matching OpenAPI operation: endpoint/verb existence, request-body fields, query params (one level into arrays for nested bodies).
  • Allowlistallowlist.ts records divergences verified valid against the live API but absent from WEEEK's (incomplete) spec. Allowlisted findings are printed ([accepted]) but don't fail CI. Structural findings (endpoint-missing, body-missing-required) can never be allowlisted — enforced at the type level.

Real bugs this found (and fixes, verified against the live API)

Tool Was sending WEEEK actually wants Effect of the bug
list_tasks limit perPage page-size silently ignored
list_tasks isCompleted (bool) completed (1/0) completed-filter silently ignored
create_task dateEnd dueDate due date silently dropped
update_task dateEnd dueDate due date silently dropped

The remaining 11 divergences (pagination params undocumented on some list ops; dueDate on create; description/userId on update) were confirmed valid against the live API and are allowlisted.

CI (.github/workflows/spec-drift.yml)

  • pr-drift (PR + push): pnpm spec:check — offline, code ↔ committed snapshot, fails on new drift.
  • upstream-drift (nightly + manual): pnpm spec:check:upstream — live ↔ snapshot; opens/updates a spec-drift issue when WEEEK changes.

Commands

  • pnpm spec:fetch — refresh the committed snapshot from live WEEEK.
  • pnpm spec:check — code ↔ snapshot (offline; the PR gate).
  • pnpm spec:check:upstream — live ↔ snapshot.

Verification

  • 179 tests pass (30 files); tsc clean for both src and scripts; lint clean.
  • pnpm spec:check11 accepted / 0 active / exit 0.
  • The live loader was exercised end-to-end against developers.weeek.net (integration test, opt-in).

Design + implementation plan: docs/superpowers/specs/2026-06-30-spec-drift-detector-design.md, docs/superpowers/plans/2026-06-30-spec-drift-detector.md.

🤖 Generated with Claude Code

notcodev and others added 16 commits June 30, 2026 17:08
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…reen

Adds scripts/spec-sync/allowlist.ts with 11 pre-verified entries (8 pagination
params on 4 list endpoints, dueDate on create_task, description+userId on
update_task). check-drift.ts now partitions findings into accepted/active,
prints accepted with reasons, and gates the exit code only on active findings.
spec:check exits 0 with 11 accepted / 0 active.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add "Spec-drift detector" section to CLAUDE.md (after Plugin layer) and
"Keeping in sync with the WEEEK API" note to README.md under Development.
Also fix lint issues across all spec-sync files introduced in this branch:
sort interface fields alphabetically (perfectionist/sort-interfaces), use \w
instead of [A-Za-z0-9_] (regexp/prefer-w), remove zero-width spaces and
non-breaking spaces from weeek-openapi.json (no-irregular-whitespace), and
apply prettier formatting throughout.

All checks green: 30 test files / 177 tests, typecheck (src + scripts),
lint exit=0, spec:check 11 accepted / 0 active / exit=0.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rmatters

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…oader-trust note

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@notcodev notcodev merged commit 9f30814 into main Jul 1, 2026
2 checks passed
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 1.2.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant