feat(r5c-lab): cycle scorecard Markdown render + /v1 endpoint + summary link - #180
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… invariant Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…escaping Task 1 of the R5c-lab slice: renderCycleScorecardMarkdown plus inlineCode/tableCell escaping helpers. Pure/presentation only, no routes/DB/wiring — downstream tasks consume this renderer.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…eligible/considered reverse test Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
R5c-lab — Cycle Scorecard Markdown (Lab side)
Renders a closed-cycle
CycleScorecard(R5a/R5b,cycle-scorecard-v1) as human-readable Russian Markdown and surfaces it Lab-side. Deterministic, LLM-free, no migration, no new env var.Durable contract:
docs/superpowers/specs/2026-07-15-r5c-lab-cycle-scorecard-markdown-spec.md. Plan:docs/superpowers/plans/2026-07-15-r5c-cycle-scorecard-markdown.md.What ships
renderCycleScorecardMarkdown(sc): string+ escaping helpers (inlineCode/tableCell/codeCell). Covers all four terminal states (accepted / rejected / skipped / abandoned), the "выбрано N из {eligible}" line, independenteligible/consideredrendering (each with its own unavailable-reason), the aggregate baseline/candidate/Δ table with the fourRevisionEvaluatorPolicythresholds (R5a explainability), trade-split veto detail, holdout robustness +lowConfidenceGET /v1/cycles/:correlationId/scorecard?format=markdown→text/markdownon 200; the JSON 404 error envelope is preserved byte-identically (markdown never emitted on 404); default (noformat) unchanged JSON./v1path contract —src/read-api/paths.ts(READ_API_V1_PREFIX,CYCLE_SCORECARD_ROUTE,cycleScorecardMarkdownUrl). Route registration,read-app.tsV1_PATHS+ mount, and the URL builder all derive from the same constants (real centralization, proven by an e2e drift test that drives the built URL through the mounted app).RunCycleCompletionSummary.links.scorecardUrl, built unconditionally from the requiredtask.correlationId(relative canonical/v1/...path). Not gated on a scorecard-row read (the summary is emitted before the async row lands) and notsafe()-wrapped.Out of scope → R5d (Office consumer, separate PR)
Office rendering the markdown into the chat needs its own work (DTO mirror gains
scorecardUrl, authenticatedtext/markdownfetch, launch moment + bounded retry on 404, chat render) and a retry-lifecycle design. The spec pins the R5d obligations, including the security invariant: Office treatsscorecardUrlas a relative canonical/v1/cycles/...path + configured Lab base URL, never an arbitrary absolute URL from the DTO.Verification
pnpm typecheckexit 0; read-boundary guard green.inlineCodenot stripping newlines (spec Contract-3 deviation + latent markdown-injection for prose code spans) — is fixed and re-reviewed; golden snapshot unchanged.Follow-ups (accepted Minor, non-blocking)
signedNum(0)renders+0(cosmetic);?format=<other>→JSON and holdoutmode:'trade_based'withtabsent are untested paths (both safe by construction).🤖 Generated with Claude Code