Skip to content

Handoff: continue Plumb dogfood and noise reduction after PRs #309-#313 #314

Description

@aram-devdocs

Handoff: continue Plumb real-project dogfood and noise reduction after PRs #309-#313

Context

This issue is the stopping-point handoff for the ongoing goal:

Iterate Plumb toward: hand an AI agent a short, correct, actionable list of rendered design-system violations it can fix in a loop.

Plumb is a deterministic design-system linter for rendered websites:

  • CLI: plumb lint <url>
  • MCP server: plumb mcp
  • Core source of truth: docs/local/prd.md
  • Project rules: AGENTS.md and .agents/rules/*.md

Read first:

  1. docs/local/handoff_to_codex.md
  2. docs/local/prd.md
  3. AGENTS.md
  4. .agents/rules/*.md

Current main at handoff:

  • SHA: 8c2a3bf02aa684e11784b6a187818bd5f2099935
  • Local Plumb worktree was clean at handoff.
  • Dogfood ports used during the session (3210, 3220, 3230) were stopped before handoff.
  • docs/local/*.md logs are gitignored local evidence on this machine. This issue repeats the important context so the next agent is not blocked if local scratch docs are unavailable.

Estimated plan completion: about 60-65%. The core CDP/MCP stability and first real init --from fixes are merged. The remaining work is mostly more real-project dogfood coverage, config inference gaps, spacing/touch-target noise, and release follow-through.

Merged during this workstream

All code changes were merged via PRs into main.

  • fix(cdp,mcp): stabilize page linting noise #309 fix(cdp,mcp): stabilize page linting noise

    • Merge: 627c4ec2689a9195114903e93d200cd9695c99c9
    • Stabilized CDP/MCP page linting and noise-scoreboard behavior.
  • fix(cdp): keep default raw readiness best effort #310 fix(cdp): keep default raw readiness best effort

    • Merge: 8c952d5de87734fa80ed686a08aa812bfe02ffa4
    • Kept raw readiness best-effort by default, avoiding macOS readiness regressions.
  • feat(codegen): infer workspace token modules #311 feat(codegen): infer workspace token modules

    • Merge: ab126c975e860ae240c3ef84a3b9b875a5938de9
    • plumb init --from apps/web now discovers workspace token modules under conventional packages/*/src/tokens/**/*.{ts,tsx,js,jsx}.
    • Adds conservative literal object parsing for exported object constants.
    • Infers colors, spacing, radii, type sizes, families, and weights from literal TS/JS token modules.
    • Rejects unsupported numeric forms instead of truncating them.
  • fix(codegen): prefer light token exports #312 fix(codegen): prefer light token exports

    • Merge: 8be27ec8011ca4f46aeeab608ff589ab046321fe
    • Fixes a real IMR dogfood bug where dark exports sorted before light, so duplicate keys generated dark defaults.
    • plumb init --from apps/web now emits light/default values first, e.g. IMR background = "#faf7f7", foreground = "#3f5965", primary = "#007068".
  • fix(codegen): parse rem token lengths #313 fix(codegen): parse rem token lengths

    • Merge: 8c2a3bf02aa684e11784b6a187818bd5f2099935
    • Parses rem and em string lengths in literal token modules using the same 16px convention as the Tailwind adapter.
    • IMR radius.base = "0.75rem" now produces [radius] scale = [12].

Validation used before the codegen PRs:

cargo fmt --all -- --check
cargo test -p plumb-codegen
cargo test -p plumb-cli --test init_from
cargo clippy -p plumb-codegen -p plumb-cli --all-targets --all-features -- -D warnings
cargo build -p plumb-cli
RUSTDOCFLAGS='-Dwarnings' cargo doc --workspace --no-deps
just validate
PLUMB_CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" scripts/noise-scoreboard.sh --live

Scoreboard baseline after #312/#313:

  • kitchen-sink: 24
  • example.com: 0
  • ui.shadcn.com: 299
  • news.ycombinator.com: 410

Dogfood evidence

IMR agent

Project:

  • /Users/aramhammoudeh/dev/vertice-labs/imr/imr-agent
  • App: apps/web
  • Commands used:
    • pnpm --filter @repo/web build
    • PORT=3210 pnpm --filter @repo/web start
    • plumb init --from /Users/aramhammoudeh/dev/vertice-labs/imr/imr-agent/apps/web
    • plumb lint http://127.0.0.1:3210/app --format json

Results:

Finding classification:

  • a11y/touch-target on a small inline forgot-password style link: likely false positive/noise. WCAG 2.5.8 has an inline target exception.
  • negative margin -1px / -2px spacing findings: noise/layout artifacts.
  • 6px spacing findings: real but low-actionability; this codebase intentionally uses Tailwind half-step spacing such as mb-1.5 / py-1.5.

Remaining IMR gaps:

  • calc(var(--radius) - 2px) and calc(var(--radius) - 4px) derived radius aliases are still not inferred.
  • typography.ts uses var(--font-geist-sans), so the type family is not inferred.
  • Spacing rules still produce noisy/non-actionable reports for tiny negative layout artifacts and intentional half-steps.

Treasure

Project:

  • /Users/aramhammoudeh/dev/vertice-labs/treasure
  • Turborepo, Next.js 15, Tailwind v4.
  • Apps include apps/web-pos and apps/web-vendor.

Build:

  • Initial build failed due missing Next package payload; pnpm install --frozen-lockfile --ignore-scripts repaired deps.
  • Production build then failed on an existing app TypeScript error:
    • packages/api/modules/accounts/active-vendor.ts:101:37
    • Parameter 'sv' implicitly has an 'any' type.
  • This is outside Plumb scope; use dev server for rendered dogfood.

Important init --from blocker:

/Users/aramhammoudeh/dev/plumb/target/debug/plumb init \
  --from /Users/aramhammoudeh/dev/vertice-labs/treasure

Failed with:

failed to parse CSS file
`/Users/aramhammoudeh/dev/vertice-labs/treasure/packages/ui/storybook-static/assets/preview-DSFCuGKh.css`:
unterminated string

Classification:

  • High-value Plumb bug. The walker treats generated Storybook static CSS as a fatal token-source parse error.
  • Likely first next PR: skip storybook-static in the codegen walker, or make generated CSS parse failures non-fatal with deterministic warnings. The smaller safer fix is probably adding storybook-static to crates/plumb-codegen/src/walk.rs SKIPPED_DIRS with a test.

App-root init --from:

  • apps/web-pos and apps/web-vendor succeed, but emit a comment-only config with just tailwind.config.ts.
  • Gap: actual design tokens live in shared CSS imported from workspace packages such as @treasure/ui/theme/globals.css and tooling/tailwind/theme.css. The app-root walker does not follow workspace package CSS token imports.

MCP dogfood

Used a real stdio JSON-RPC client against:

PLUMB_CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
  /Users/aramhammoudeh/dev/plumb/target/debug/plumb mcp

Requests:

  • initialize
  • notifications/initialized
  • tools/list
  • tools/call with lint_url
  • tools/call with lint_page_html

Results:

  • tools/list exposed:
    • compare_viewports
    • echo
    • explain_rule
    • get_config
    • lint_page_html
    • lint_url
    • list_rules
  • lint_url with plumb-fake://hello returned compact structured content:
    • total: 1
    • spacing/grid-conformance: 1
  • lint_page_html with embedded CSS rendered through Chromium and returned:
    • total: 6
    • color/contrast-aa: 1
    • spacing/grid-conformance: 5

Classification:

  • lint_url fake finding: expected smoke result.
  • lint_page_html authored margin-left: 3px, padding-top: 5px, and borderline contrast were true positives.
  • Extra button UA default padding findings (6px, 1px) were noise for snippet use. Consider docs/examples that include reset CSS, or a carefully designed snippet-mode reset. Be careful: lint_page_html promises real computed styles, so silently changing UA styles could hide defects.

Pickleball Ventures

Project:

  • /Users/aramhammoudeh/dev/vertice-labs/pickleball-ventures
  • App observed: apps/marketing
  • Server on port 3230 responded with HTTP 200 at /.

State:

  • A generated plumb.toml artifact was removed before handoff.
  • The repo was clean after cleanup.
  • The dogfood log did not survive the interrupted subagent. Redo this target if needed.

Highest-impact remaining work

Work in small PRs, with golden/unit tests first where appropriate, and merge each PR after CI.

  1. Fix Treasure root init --from blocker.

    • File likely: crates/plumb-codegen/src/walk.rs.
    • Add storybook-static to skipped generated dirs, or implement deterministic non-fatal CSS parse handling.
    • Add regression test that a storybook-static/assets/*.css parse trap is skipped and does not abort inference.
    • Dogfood command to prove it:
      cd /tmp
      /Users/aramhammoudeh/dev/plumb/target/debug/plumb init \
        --from /Users/aramhammoudeh/dev/vertice-labs/treasure --force
  2. Improve app-root config usefulness for Tailwind v4 workspace CSS tokens.

    • Treasure app roots emit comment-only config.
    • Investigate following workspace package CSS imports or discovering conventional workspace CSS token files under package theme/style dirs.
    • Keep determinism: sorted paths, no JS evaluation, no network.
    • Watch for generated output dirs.
  3. Reduce spacing/touch-target noise from real pages.

    • Inline text links should not trip a11y/touch-target when they meet the WCAG inline exception.
    • Tiny negative margins from borders/rings/layout artifacts should probably be suppressed or made lower priority.
    • Tailwind half-step spacing (1.5 -> 6px) should be understood via generated config or rule tolerance, not reported as noisy off-grid findings.
    • Add golden tests before rule changes.
  4. Continue dogfood coverage.

    • Redo Pickleball Ventures fully and write a log.
    • Continue with the remaining known targets from the original handoff:
      • /Users/aramhammoudeh/dev/vertice-labs/homesite
      • /Users/aramhammoudeh/dev/solace-candidate-assignment-main
      • any other real ~/dev/* web apps available.
    • For each target: build or serve, run plumb init --from, run CLI lint, run MCP tools (lint_url / lint_page_html), classify every finding as true positive / false positive / noise / miss.
  5. Release follow-through.

Required gates before each PR

Follow the handoff discipline:

cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace --all-features
RUSTDOCFLAGS='-Dwarnings' cargo doc --workspace --no-deps
just validate
PLUMB_CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" scripts/noise-scoreboard.sh --live

Use narrower tests while developing, but do not skip the full gate before PR.

Chrome path:

/Applications/Google Chrome.app/Contents/MacOS/Google Chrome

If Chromium hits a SingletonLock error:

rm -rf "$TMPDIR/chromiumoxide-runner"

Process expectations for the next agent

  • Start from main at or after 8c2a3bf02aa684e11784b6a187818bd5f2099935.
  • Create codex/... branches.
  • Use conventional commit scopes that pass the hook.
  • Open PRs, wait for CI, and merge them.
  • Keep docs/local/dogfood-<project>.md logs locally for every real project.
  • Do not touch unrelated dirty work in external projects. IMR had a large unrelated dirty tree at handoff.
  • Do not use bypasses or skip validation.
  • Keep plumb-core deterministic and layer-clean.

Definition of done for this issue

This handoff issue is not the finish line for the product goal. It is done when the next agent has:

  • Fixed the Treasure root init --from blocker.
  • Continued at least one more real-project dogfood loop end to end.
  • Shipped at least one more high-impact noise/inference fix through PR and merge.
  • Updated this issue or opened follow-up issues with current evidence and remaining gaps.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions