Skip to content

v0.6.0 — verbatim filter extraction + per-flag probe gate - #6

Merged
codeyogi911 merged 1 commit into
mainfrom
v0.6.0-filter-probe
Apr 30, 2026
Merged

v0.6.0 — verbatim filter extraction + per-flag probe gate#6
codeyogi911 merged 1 commit into
mainfrom
v0.6.0-filter-probe

Conversation

@codeyogi911

Copy link
Copy Markdown
Owner

Closes #5.

Summary

Fixes the generator-side drift where generated CLIs blanket-mark list
filters as BROKEN after a single probe with the wrong name. The fix
lands in all three layers — instructions, runtime substrate, and the
validator gate — so guidance, behavior, and enforcement stay aligned.

Generator instructions

  • skills/clify/SKILL.md and references/scaffold-pipeline.md promote list-filter handling from a one-liner to its own subsection of Phase 2 + Phase 5.
  • Five rules now spelled out: verbatim flag extraction (no collapsing *_startswith / *_contains into bare names), enum surfacing, auto-emit sort_column / sort_order, per-flag probe protocol, probe log to .clify.json.filterProbes.
  • New anti-pattern entry: don't normalize away suffix variants — the suffix IS the filter mode.

Substrate (examples/exemplar-cli/)

  • lib/quirks.mjspickBrokenFilters returns { name: { value, match } } so client-side fallback honors documented match modes (equals, startswith, contains). Backwards-compatible with the v0.5 string-list form.
  • lib/help.mjs — renders flags.<name>.enum inline: --filter_by <All|NotShipped|Shipped>.
  • lib/args.mjs — new checkEnum helper; bin runtime rejects out-of-enum values with a validation_error.
  • knowledge/query-flags-and-broken-list-filters.md — full discovery checklist with the Zoho Inventory packages list worked example.

Validator gate (lib/validate.mjs)

New filter-coverage check, in the coverage category:

  • HARD-FAIL: list action declares filter-shaped flags but .clify.json.filterProbes has zero entries for the resource (Phase 5 skipped the probe step).
  • HARD-FAIL: every filter on a list action is in brokenListFilters AND no probe verified ANY filter (the blanket-mark anti-pattern).
  • WARN: a filter is status: "untested" (probe was skipped at gen time).

Path parameters (e.g. itemId in /items/:itemId/variants) are excluded from the filter-shaped set so sub-resource list actions don't false-positive.

Tests

  • examples/exemplar-cli/test/integration.test.mjsfilter-probe pattern test asserting the wire URL carries the filter AND the row count differs from baseline. This is the test pattern any generated CLI inherits — would have caught the Zoho miss at gen time.
  • examples/exemplar-cli/test/quirks.test.mjs — per-filter match-mode tests for the new substrate.
  • test/clify.test.mjs — four new validator tests: pass, missing probes, blanket-mark, untested-warn.

Version

Bumped to 0.6.0 in package.json + .claude-plugin/plugin.json + .claude-plugin/marketplace.json (npm test enforces consistency via scripts/check-plugin-version.mjs).

Test plan

  • cd examples/exemplar-cli && npm test — 56/56 pass
  • npm test (clify root) — 19/19 pass, includes 4 new filter-coverage tests
  • npm run validate-exemplar — 27/27 checks pass, 0 warnings
  • Plugin manifest version drift check passes (chained into npm test)

🤖 Generated with Claude Code

Closes #5: generated CLIs were systematically blanket-marking list
filters as broken from a single failed probe with the wrong name.

The fix lands in three layers: instructions, substrate, and validator.

Generator instructions (skills/clify/SKILL.md, references/scaffold-pipeline.md)
- Promote list-filter handling to its own subsection of Phase 2 + 5.
- Five rules: verbatim flag extraction (no collapsing *_startswith /
  *_contains into bare names), enum surfacing in flag specs, auto-emit
  sort_column/sort_order, per-flag probe protocol, probe log written to
  .clify.json.filterProbes.

Substrate (examples/exemplar-cli/)
- lib/quirks.mjs: pickBrokenFilters now returns { name: { value, match } }
  so the client-side fallback honors documented match modes (equals,
  startswith, contains). Backwards-compatible with the v0.5 string-list
  form (defaults to equals-or-contains).
- lib/help.mjs: render flags.<name>.enum inline as
  --filter_by <All|NotShipped|Shipped>.
- lib/args.mjs: new checkEnum helper; bin runtime rejects out-of-enum
  values with a validation_error.
- knowledge/query-flags-and-broken-list-filters.md: full discovery
  checklist with the Zoho Inventory packages.list worked example.

Validator gate (lib/validate.mjs)
- New filter-coverage check (HARD-FAIL):
  * list action declares filter-shaped flags but .clify.json.filterProbes
    has zero entries for the resource → fail (Phase 5 skipped probe).
  * every filter on a list action is in brokenListFilters AND no probe
    verified ANY filter → fail (the blanket-mark anti-pattern).
  * a filter status:"untested" → warn, not fail.
- Path params (e.g. itemId in /items/:itemId/variants) are excluded from
  the filter-shaped set.

Tests
- examples/exemplar-cli/test/integration.test.mjs: filter-probe pattern
  asserting the wire URL carries the filter and the row count differs.
- examples/exemplar-cli/test/quirks.test.mjs: per-filter match-mode tests.
- test/clify.test.mjs: four new validator tests covering pass, missing
  probes, blanket-mark, and untested-warn cases.

Version bumped to 0.6.0 in package.json + .claude-plugin/plugin.json +
.claude-plugin/marketplace.json (npm test enforces consistency).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@codeyogi911
codeyogi911 merged commit 7bc52f0 into main Apr 30, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generated CLIs blanket-mark list filters as BROKEN — drift from real API specs

1 participant