6.7 KiB
created, status, requirements, system_design, legacy_specs
| created | status | requirements | system_design | legacy_specs | ||
|---|---|---|---|---|---|---|
| 2026-09-05 | done |
|
|
Implementation Plan: PR Walkthrough Description Integrity Fix
Overview
Make the walkthrough and preview description writers converge on one current pull request body, preserve each other's marker-owned sections, and verify their result. Add a non-generating reconciliation path for edited pull requests so an obsolete full-SHA walkthrough URL is repaired when its current short-SHA object is available.
The work is sequential. First, harden the shared description-write behavior and canonical URL enforcement. Then add the edited-event repair path on top of that protocol.
Root cause
PR #3427 exposed a mismatch between the public object key and the URL in the
pull request body. The publisher and successful link job used
pr/3427/990bca847b1c.html, while the body contained
pr/3427/990bca847b1c0c19c34f243df5a8b0a3b882a155.html. The short URL returns
the walkthrough; the full URL returns 404. The Sprites preview is independent
and healthy.
The current repository has no active walkthrough producer that intentionally emits the full-SHA URL. The body was changed after the successful link job by an unidentified writer or stale full-body update. The exact external writer is not recoverable from public GitHub history, but the current Kandev writers permit the recurrence: they read a body, merge one section, PATCH the complete body, and do not compare a fresh snapshot or verify the result.
The smallest reproduction is to publish the canonical short object, then replace the owned walkthrough block with the legacy full-SHA URL. The object lookup fails even though publication and the preview environment succeed.
Scope
In scope
- Enforce the 12-character public URL contract in every current walkthrough description path.
- Make walkthrough and preview body writes compare fresh snapshots, retry boundedly, preserve other marker-owned sections, and verify after PATCH.
- Serialize Kandev-controlled description writers with one per-PR concurrency group.
- Reconcile an existing stale walkthrough block on
pull_request_target'seditedevent when the current canonical object is available. - Add focused unit, workflow-contract, and Go HTTP tests for the regression.
Out of scope
- Identifying or changing an external GitHub App that may have overwritten the body; that requires organization or application audit access.
- Renaming or deleting existing full-SHA R2 objects.
- Replacing the PR description with a full template.
- Adding a Kandev application UI for walkthrough links.
- Adding a host-level legacy URL redirect. That remains optional defense in depth after the writer and reconciliation controls are deployed.
Technical approach
Description write protocol
Update scripts/pr-walkthrough-pr-body and
apps/backend/cmd/preview/github.go callers to follow the design's bounded
fresh-read, merge, compare, PATCH, and readback sequence. The walkthrough link
job continues to consume the publication job's validated URL and rejects any
URL that does not match the 12-character canonical form. The walkthrough link,
reconciliation, and short preview-description jobs use the shared
pr-description-<number> concurrency group with cancellation disabled for
the write section. Long-running preview lifecycle jobs do not hold that lock;
they pass their preview result to a trusted description job, which performs the
body write after deployment or cleanup.
The Go path will use an HTTP transport fake in tests and a bounded retry loop around the body snapshot protocol. The workflow path will keep the trusted helper and minimum GitHub permission boundary, but will stop retrying a stale payload blindly. Both paths will verify their owned marker after the PATCH and retry from the body that actually won.
Edited-event reconciliation
Add a base-controlled, non-generating reconciliation workflow or workflow
boundary for pull_request_target edited events. It will use trusted
repository files, no model or R2 credentials, and the existing authorization
rules. It will check the current canonical URL with a public HTML request,
read the live body, and invoke the walkthrough helper only when an existing
walkthrough marker block is present. Missing objects or missing markers are
no-ops. Malformed markers fail closed.
The canonical no-op result prevents a body PATCH from creating a repair loop. The reconciliation path uses the same post-write readback and shared per-PR description concurrency group as the normal link job.
Tests
scripts/pr-walkthrough-pr-body.test.pywill cover required-existing marker mode, legacy full-SHA replacement, canonical no-op behavior, and malformed-marker failure.apps/backend/cmd/preview/github_test.goor a focused sibling test will use a fake GitHub API to change the body between reads and to change it after PATCH. It will prove retry, marker preservation, cleanup behavior, and bounded failure..github/scripts/pr-walkthrough-workflow-contract_test.pywill assert the edited event boundary, non-generating reconciliation, trusted checkout, public-object check, canonical URL rule, shared concurrency group, fresh snapshot comparison, and post-write readback.- Existing workflow and action-pinning tests will continue to enforce trusted inputs and minimal permissions.
E2E tests
There is no Kandev UI flow. The workflow contract and fake GitHub API tests cover the local regression. A same-repository pull request after deployment must provide live evidence that an edited description with a legacy URL is repaired and that a concurrent preview update preserves the walkthrough callout.
Work orders
Verification results
Task 01 and Task 02 checks passed. The current Kandev writers are race-safe, and edited covered pull requests can repair an existing stale walkthrough callout when the canonical public object is available.
Risks
- GitHub body updates replace the complete body, so an external writer can still race after the final local read. Shared concurrency, compare/retry, readback, and edited-event reconciliation reduce this risk but cannot lock writers outside Kandev.
- A missing current object prevents repair by design. The next successful publication must create the object before reconciliation can link it.
- The preview fork path executes contributor code with deployment credentials; this fix does not widen or redesign that existing trust boundary.