Auto-archive design specs when PRs finalize them #11

Merged
arne merged 9 commits from feat/spec-finalization into main 2026-04-05 16:01:11 +02:00
Owner

Finished design specs used to linger in the Design stage forever — the
spec would stay visible even after its implementation had shipped. This
PR makes them archive automatically: add a
Finalizes: 2026-04-05-foo.md line to a PR's body, and when you create
the PR, orbit's webhook handler deletes the spec file from the PR branch
via the Forgejo contents API. The deletion becomes part of the feature
PR's diff, so the spec disappears atomically with the work that finalized
it.

Deletion, not a move to docs/archive

Git is already the archive — every byte is retrievable via
git log --follow or Forgejo's commit browser forever. A second on-disk
location would be redundant maintenance.

Orbit-side, not AI-side

The design-folder guardrail (#2) blocks Claude from editing design/
outside a design session, but the guardrail only applies to Claude Code
tool calls. Orbit-the-server running in systemd calls the Forgejo API
directly and sidesteps the hook entirely. The guardrail stays unmodified.

Convention

A line in the PR body starting with Finalizes: (case-insensitive), then
one or more comma-separated spec references. Accepts bare filenames
(foo.md), specs/foo.md, or design/specs/foo.md — all normalize to
design/specs/<basename>. Basenames are validated against
^[A-Za-z0-9._-]+\.md$ to reject path traversal attempts and unexpected
extensions.

Also

Filters README.md out of the Design stage at the designs.Source
boundary — the scaffold's placeholder was cluttering the list.

Known cuts

  • No edited/synchronize action handling; only opened. To add a
    Finalizes: line after the PR exists, close and reopen.
  • No git blob fallback for deleted specs in the design-preview route —
    once gone from HEAD, the preview 404s on that path. Forgejo's commit
    browser remains the retrieval path.
  • Label-based triggers are deliberately out of scope. PR body only.
Finished design specs used to linger in the Design stage forever — the spec would stay visible even after its implementation had shipped. This PR makes them archive automatically: add a `Finalizes: 2026-04-05-foo.md` line to a PR's body, and when you create the PR, orbit's webhook handler deletes the spec file from the PR branch via the Forgejo contents API. The deletion becomes part of the feature PR's diff, so the spec disappears atomically with the work that finalized it. ## Deletion, not a move to docs/archive Git is already the archive — every byte is retrievable via `git log --follow` or Forgejo's commit browser forever. A second on-disk location would be redundant maintenance. ## Orbit-side, not AI-side The design-folder guardrail (#2) blocks Claude from editing `design/` outside a design session, but the guardrail only applies to Claude Code tool calls. Orbit-the-server running in systemd calls the Forgejo API directly and sidesteps the hook entirely. The guardrail stays unmodified. ## Convention A line in the PR body starting with `Finalizes:` (case-insensitive), then one or more comma-separated spec references. Accepts bare filenames (`foo.md`), `specs/foo.md`, or `design/specs/foo.md` — all normalize to `design/specs/<basename>`. Basenames are validated against `^[A-Za-z0-9._-]+\.md$` to reject path traversal attempts and unexpected extensions. ## Also Filters `README.md` out of the Design stage at the `designs.Source` boundary — the scaffold's placeholder was cluttering the list. ## Known cuts - No `edited`/`synchronize` action handling; only `opened`. To add a `Finalizes:` line after the PR exists, close and reopen. - No git blob fallback for deleted specs in the `design-preview` route — once gone from HEAD, the preview 404s on that path. Forgejo's commit browser remains the retrieval path. - Label-based triggers are deliberately out of scope. PR body only.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wire handlePRFinalize into handleWebhook: when action=="opened" and
s.forgejo != nil, call handlePRFinalize to delete spec files referenced
in the PR body. Guarded by nil-check matching the existing handlePRMerge
pattern. Add TestWebhookPullRequestOpened_NoForgejoClient to anchor the
no-op behaviour when no Forgejo client is configured.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
arne merged commit da026a3bbe into main 2026-04-05 16:01:11 +02:00
arne changed title from feat: automate design-spec finalization via PR webhook to Auto-archive design specs when PRs finalize them 2026-04-05 22:08:31 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
arne/orbit!11
No description provided.