Skip to content

feat: verified share card — attested card.svg/card.png artifact #50

Description

@gkanitz

Context

Slice F of the v0.2 "Meaning" wave. Shared design context:
docs/superpowers/specs/2026-07-04-impact-roadmap-design.md (PR #47).

The report is a document; sharing it on LinkedIn or in a README needs a
compact, verifiable artifact. This slice adds an attested share card —
a static SVG/PNG with four fixed headline numbers and a QR link to the
verify page.

Goal (vertical slice)

card.svg rendered from the report struct → PNG conversion + Sigstore
attestation in CI → documented output, end to end.

In scope

  • render: produce card.svg, 1200×627 viewBox, fully self-contained
    (system font stack, no external references).
  • Card contents, fixed: subject username + platform; org context (single
    repo-owner name when all covered repos share one owner, otherwise
    "N orgs"); coverage window; exactly four headline numbers — PRs merged,
    reviews given, median time to merge, active days (a missing metric renders
    "—", never an invented value); QR encoding verification.verify_url
    (fallback: canonical verify-page URL), reusing the existing footer QR
    generator; verification mark — "Sigstore attested" only when
    verification.status == "verified", otherwise an explicit "unverified"
    variant.
  • CI: canonical reusable workflow + composite action convert card.svg
    card.png (existing headless-Chromium step) and attest the card
    (mirroring the existing HTML+PDF dual-attestation pattern); action outputs
    include the card paths.
  • README "Report output" table gains the card row.

Out of scope

  • New metrics, verify-page changes (the card is verified via
    gh attestation verify card.png like any artifact), LinkedIn API
    integrations, size variants beyond 1200×627.

Design constraints

Acceptance criteria — TDD

Success (write these tests first; all must pass)

  1. Golden card.svg for the full sample report: contains username,
    platform, owner/org string, window, the four headline values, QR, and
    the attested mark.
  2. Golden for a sparse report: missing metrics render "—"; nothing else
    invented.
  3. Golden for an unverified (local-run) report: "unverified" variant shown;
    attested mark absent.
  4. Multi-owner coverage fixture renders "N orgs", single-owner renders the
    owner name.
  5. QR payload equals verification.verify_url when set (decode the QR in
    the test or assert the generator's input), else the canonical verify URL.
  6. Self-containment: rendered SVG contains no http(s):// references except
    inside the QR payload/verify link text.
  7. Prohibited-strings test (seeded colleague names, PR titles, branch names,
    file paths) passes over card output.
  8. Card dimensions/viewBox exactly 1200×627.
  9. Workflow/action changes: card.png is produced and attested in the same
    step pattern as report.pdf; action outputs list the card. (Assert via
    workflow-file content tests/dry-run where the repo already tests
    action.yml wiring; otherwise document the manual CI verification steps in
    the PR description.)

Failure — QA red flags (any one observed → reject the PR)

  • Any metric on the card beyond the fixed four.
  • Attested mark rendered for an unverified report.
  • External resource references (fonts, images) in the SVG.
  • CI produces a card without attesting it in attested mode.
  • Colleague/repo-secret strings on the card (prohibited-strings failure).

Parallel-work contract

  • Territory: render/ (new card template/code + goldens), action.yml,
    .github/workflows/coderepute-report.yml, README output table.
  • Shared, additive-only: render/render.go (wiring only).
  • Depends on: nothing — start immediately.

Definition of done

TDD skill followed; all success criteria green; go test ./... passes;
PR references this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    blocked:humanNeeds a human decision before the loop can proceedreadyLoop-ready: this org's picker reads this labelready-for-agentTriage complete; ready for an agent to pick up

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions