feat(pdf): quote remediation on the report cover, priced from its findings - #116
Merged
Merged
Conversation
…dings
Puts a "want us to fix this for you?" offer at the top of every audit PDF,
with the price estimated from that report's own findings rather than a
flat figure — billed at $100/hour and split into the two kinds of work:
AI-assisted metadata, schema, alt text, template variables, placeholder
copy, dead links — the same class of change the GitHub
auto-fix agent already opens PRs for
Manual DNS/registrar records, infra and performance work, and
anything needing facts only the client has: real metrics,
customer quotes, product screenshots, positioning calls
lib/audit/quote.ts maps each check_key to an hours-per-occurrence pair via
ordered rules, so a content-heavy report prices differently from a
markup-heavy one of the same size. A warn costs 0.6 of a fail. Fixed
baseline overhead (intake, plan, verification re-scan, handoff) means a
nearly-clean site still quotes something that covers confirming it is
clean, and a 120-hour ceiling flags catastrophic reports for a scoping
call instead of printing an absurd number.
Two things that would otherwise overbill:
- Findings are deduplicated by check_key, keeping the worst status. A
consolidated scan-run PDF carries one findings set per engine, and
several engines flag the same defect — a missing meta description is
one fix whether one engine noticed or five did.
- rec.*/todo.*/slop.score/slop.coverage/crawl.* are non-billable; they
restate or summarise defects counted elsewhere.
Per-page slop findings are priced cheaply and shared-template fixes
(slop.systemic.*) more richly, so the quote reflects "fix the template
once" rather than "fix thirty pages".
Rendered on the cover by htmlDocument, so it reaches all three PDF paths:
the per-engine email, the consolidated scan-run email, and the on-demand
/pdf endpoint (which now accepts a quote in its payload; the app route
computes it from audit_findings). The lookup is best-effort — if it fails
the PDF still renders, just without the offer.
Calibration against live reports: crawlproof.com (score 58) $2,500 /
24.5h; news.ycombinator.com (38) $4,100 / 41h; example.com (37) $4,400 /
44h; a Slop-Score-only report $1,800 / 18h.
21 tests cover the classification, dedupe, guardrails and rounding.
Verified by rendering a real PDF and inspecting the cover.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
vu1nz Security Review0 finding(s) in PR #? No security issues found. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Puts a "Want us to fix this for you?" offer at the top of every audit PDF. The price is estimated from that report's own findings rather than being a flat figure — billed at $100/hour, split into the two kinds of work:
How it prices
lib/audit/quote.tsmaps eachcheck_keyto an hours-per-occurrence pair through ordered rules, so a content-heavy report prices differently from a markup-heavy one of the same size. Awarncosts 0.6 of afail. Per-page slop findings are cheap; shared-template fixes (slop.systemic.*) cost more, so the quote reflects "fix the template once" instead of "fix thirty pages".Guardrails:
$X,XXX+rather than an absurd numbercheck_key, worst status wins — a consolidated scan-run PDF carries one findings set per engine and several engines flag the same defect. A missing meta description is one fix whether one engine noticed or five did. Without this the same work was billed per-engine.rec.*,todo.*,slop.score,slop.coverage,crawl.*restate or summarise defects counted elsewhereCalibration against live reports
Where it renders
On the cover via
htmlDocument, so it reaches all three PDF paths: the per-engine email, the consolidated scan-run email, and the on-demand/pdfendpoint (which now accepts aquotein its payload; the app route computes it fromaudit_findings). The lookup is best-effort — if it fails the PDF still renders, just without the offer.Verification
21 new tests cover classification, dedupe, guardrails and rounding. Full suite 493 passing,
tsc --noEmitclean, production build clean. I also rendered a real PDF and inspected the cover page rather than trusting the markup.Copy is in one place (
quoteBlockinlib/markdown.ts) and the rate/target are constants (HOURLY_RATE_USD,TARGET_SCORE) if you want to tune the offer.🤖 Generated with Claude Code