Skip to content

feat(loop): GitHub-native gist artifact-hosting fallback for ui_review report#1332

Merged
mfittko merged 1 commit into
mainfrom
issue-1285
Jul 10, 2026
Merged

feat(loop): GitHub-native gist artifact-hosting fallback for ui_review report#1332
mfittko merged 1 commit into
mainfrom
issue-1285

Conversation

@mfittko

@mfittko mfittko commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Summary

Implements the GitHub-native artifact-hosting fallback for the ui_review report, so a non-Claude harness (Pi, or any run where Claude Code Artifacts are unavailable) gets a real working link instead of a fail-closed stated reason. The Claude Artifacts path (shipped in #1120) is unchanged and stays the enhancement; the GitHub-native path is the portable default off-Claude.

Mechanism (explicitly chosen + documented)

gh gist create — a secret gist of the self-contained HTML. A real per-run URL with zero repo pollution, no Pages setup, and deletable by Stage-5 teardown. Tradeoff documented honestly: a gist renders HTML as source (not a live page), so the review body links the gist page and appends the raw file URL (… : <url> (raw: <rawUrl>)) so the reader can open the plain file directly. Fail-closed: if gh gist create throws / exits non-zero / returns no URL, the publisher emits a stated reason — never a fake link. The "renders as source" caveat is gated on an actually-published gist, so an explicit --hosted-url self-hosted override falls through to the neutral artifact line rather than being mislabeled.

Scope and context

  • packages/core/src/loop/ui-review-report.mjs: decideHosting returns the portable github-gist strategy off-Claude — pure core, no harness-specific publisher; the core report flow does not depend on any harness's publisher.
  • scripts/loop/ui-review-report.mjs: the thin CLI publishes the HTML via gh gist create (reusing the existing gh runChild seam — no new dependency), links it in the review body, and fails closed with a stated reason if no URL comes back.
  • packages/core/src/loop/ui-review-teardown.mjs + scripts/loop/ui-review-teardown.mjs: Stage-5 teardown consumes the recorded gist id (new --report-result input) and prunes the gist (gh gist delete) under confirmation, recording the outcome in the always-emitted ledger (NONE / SKIPPED_UNCONFIRMED / DELETED / DELETE_FAILED).
  • docs/ui-review-recipe-contract.md: documents the gist gh scope a consuming repo must provide and the source-vs-rendered tradeoff.

Acceptance criteria

Satisfies #1285's ACs (checked off at merge): a documented GitHub-native fallback yielding a working link or a fail-closed stated reason; the core report flow is publisher-agnostic (Claude Artifacts stays an enhancement, gist is the portable default); the accreting gist is pruned by Stage-5 teardown via the ledger; the recipe doc documents the fallback hosting setup; a test asserts the fallback produces a link or fails closed without hitting the live API; npm run verify green.

Non-goals

Changing the Claude Artifacts path (shipped in #1120). Production/non-dev hosting targets.

Validation

  • node --test test/loop/ui-review-report.test.mjs test/loop/ui-review-teardown.test.mjs — 54 pass via makeGhMock (no live API): publish success / fail-closed-on-nonzero / fail-closed-on-no-URL; two report runCli integration tests (off-Claude gist happy-path body links the gist + raw URL; non-zero gh exit → unhosted stated-reason body, no fabricated link); the --hosted-url self-hosted line is neutral; teardown gist NONE / SKIPPED_UNCONFIRMED / DELETED / DELETE_FAILED / throwing-seam, plus a runCli test asserting gh gist delete <id> through an injected run mock.
  • npm run verify — green (test:assets 191, test:scripts 2706, test:core 2019, test:extension 81, test:docs, test:pack, test:dev-loop 32); generate-claude-assets --check clean.

Closes #1285

Copilot AI review requested due to automatic review settings July 10, 2026 23:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a GitHub-native hosting fallback for the ui_review report by publishing the self-contained HTML as a secret GitHub Gist off-Claude (while keeping Claude Artifacts as the on-Claude enhancement), and adds Stage-5 teardown support to prune the created gist.

Changes:

  • Core hosting selection now defaults to a portable github-gist strategy off-Claude (Claude Artifacts unchanged on-Claude).
  • The report CLI publishes the HTML via gh gist create, records gist metadata, and fails closed with a stated reason on publish failure.
  • The teardown core/CLI can consume a Stage-4 report result and (when confirmed) delete the recorded gist via gh gist delete, with ledger coverage + tests.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/core/src/loop/ui-review-report.mjs Switches off-Claude hosting to github-gist and updates review-body messaging for gist-hosted artifacts.
scripts/loop/ui-review-report.mjs Adds publishGist() and wires gist publishing into the report CLI with fail-closed behavior.
packages/core/src/loop/ui-review-teardown.mjs Adds gist-prune step, status enum, and ledger reporting to teardown orchestration.
scripts/loop/ui-review-teardown.mjs Adds --report-result handling, gist extraction, and gh gist delete seam wiring.
test/loop/ui-review-report.test.mjs Adds tests for gist publishing + updated hosting semantics and fail-closed behavior (mocked, no live API).
test/loop/ui-review-teardown.test.mjs Adds teardown tests for gist-pruning outcomes and CLI deletion wiring (mocked, no live API).
docs/ui-review-recipe-contract.md Documents gist fallback mechanics, required gh auth scope, and teardown pruning behavior.

Comment thread packages/core/src/loop/ui-review-report.mjs
Off-Claude, the Stage-4 report now publishes the self-contained HTML as a
secret GitHub Gist (gh gist create) — a real per-run URL with zero repo
pollution — instead of failing closed. decideHosting selects the portable
github-gist strategy in the pure core; the thin CLI performs the publish IO
and fails closed with a stated reason (never a fabricated link) when gist
creation yields no URL. The review body links the gist and states it renders
as source (open raw to view/download).

Stage-5 teardown prunes the accreting gist: the report result carries the
gist id, teardown consumes it via --report-result and deletes it (gh gist
delete) under confirmation, recording the outcome in the always-emitted
ledger. Recipe doc documents the gh gist scope a consuming repo must provide
and the source-vs-rendered tradeoff.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177JAWNT67FY6d48qQJeDwo
@mfittko mfittko requested a review from Copilot July 10, 2026 23:24
@mfittko mfittko marked this pull request as draft July 10, 2026 23:26
@mfittko mfittko marked this pull request as ready for review July 10, 2026 23:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@mfittko

mfittko commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

Gate review: pre_approval_gate

Reviewed head SHA: 99283ee4c7dbea835b7fdaa0ed4075062f39c9f6
Verdict: clean
Execution mode: fanout_fanin

Findings summary: 5 angles reviewed; 1 finding (see per-angle breakdown below).; Copilot review rounds exhausted (2/2); current head has zero unresolved threads and green or credibly green CI, so pre_approval_gate fallback is allowed without another Copilot re-request.

  • pr-checklist-matrix → clean
  • acceptance-criteria → clean
  • contradiction-lens → clean
  • correctness-final → clean
  • yagni → findings_present
    • [defer] publishGist takes an injectable ghCommand="gh" param no caller overrides (tests inject only the run seam); sibling deleteGist hardcodes "gh". Minor speculative-config inconsistency. (scripts/loop/ui-review-report.mjs:170) — deferred

Next action: Pre-approval gate clean at head 99283ee (5 distinct reviewers). 1 defer-only (yagni: unused ghCommand param). CI green; Copilot round-cap-clean on current head; draft gate reconciled clean. Proceed to merge.

@mfittko mfittko marked this pull request as draft July 10, 2026 23:36
@mfittko

mfittko commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

Gate review: draft_gate

Reviewed head SHA: 99283ee4c7dbea835b7fdaa0ed4075062f39c9f6
Verdict: clean
Execution mode: fanout_fanin

Findings summary: 7 angles reviewed; no findings (see per-angle breakdown below).

  • pr-description → clean
  • scope → clean
  • correctness → clean
  • coverage → clean
  • contract-surface → clean
  • code-conformance → clean
  • input-validation → clean

Next action: Draft gate clean at head 99283ee (7 distinct reviewers; scope + input-validation carried from 5ef3c04).

@mfittko mfittko marked this pull request as ready for review July 10, 2026 23:37
@mfittko mfittko merged commit b8c597e into main Jul 10, 2026
13 checks passed
@mfittko mfittko deleted the issue-1285 branch July 10, 2026 23:37
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.

feat(loop): GitHub-native artifact-hosting fallback for ui_review report (follow-up to #1120)

2 participants