paperclip/server/src/routes
Dotta b69b563aa8
[codex] Fix stale issue execution run locks (#4258)
## Thinking Path

> - Paperclip is a control plane for AI-agent companies, so issue
checkout and execution ownership are core safety contracts.
> - The affected subsystem is the issue service and route layer that
gates agent writes by `checkoutRunId` and `executionRunId`.
> - PAP-1982 exposed a stale-lock failure mode where a terminal
heartbeat run could leave `executionRunId` pinned after checkout
ownership had moved or been cleared.
> - That stale execution lock could reject legitimate
PATCH/comment/release requests from the rightful assignee after a
harness restart.
> - This pull request centralizes terminal-run cleanup, applies it
before ownership-gated writes, and adds a board-only recovery endpoint
for operator intervention.
> - The benefit is that crashed or terminal runs no longer strand issues
behind stale execution locks, while live execution locks still block
conflicting writes.

## What Changed

- Added `issueService.clearExecutionRunIfTerminal()` to atomically lock
the issue/run rows and clear terminal or missing execution-run locks.
- Reused stale execution-lock cleanup from checkout,
`assertCheckoutOwner()`, and `release()`.
- Allowed the same assigned agent/current run to adopt an unowned
`in_progress` checkout after stale execution-lock cleanup.
- Updated release to clear `executionRunId`, `executionAgentNameKey`,
and `executionLockedAt`.
- Added board-only `POST /api/issues/:id/admin/force-release` with
company access checks, optional `clearAssignee=true`, and
`issue.admin_force_release` audit logging.
- Added embedded Postgres service tests and route integration tests for
stale-lock recovery, release behavior, and admin force-release
authorization/audit behavior.
- Documented the new force-release API in `doc/SPEC-implementation.md`.

## Verification

- `pnpm vitest run server/src/__tests__/issues-service.test.ts
server/src/__tests__/issue-stale-execution-lock-routes.test.ts` passed.
- `pnpm vitest run
server/src/__tests__/issue-stale-execution-lock-routes.test.ts
server/src/__tests__/approval-routes-idempotency.test.ts
server/src/__tests__/issue-comment-reopen-routes.test.ts
server/src/__tests__/issue-telemetry-routes.test.ts` passed.
- `pnpm -r typecheck` passed.
- `pnpm build` passed.
- `git diff --check` passed.
- `pnpm lint` could not run because this repo has no `lint` command.
- Full `pnpm test:run` completed with 4 failures in existing route
suites: `approval-routes-idempotency.test.ts` (2),
`issue-comment-reopen-routes.test.ts` (1), and
`issue-telemetry-routes.test.ts` (1). Those same files pass when run
isolated and when run together with the new stale-lock route test, so
this appears to be a whole-suite ordering/mock-isolation issue outside
this patch path.

## Risks

- Medium: this changes ownership-gated write behavior. The new adoption
path is limited to the current run, the current assignee, `in_progress`
issues, and rows with no checkout owner after terminal-lock cleanup.
- Low: the admin force-release endpoint is board-only and
company-scoped, but misuse can intentionally clear a live lock. It
writes an audit event with prior lock IDs.
- No schema or migration changes.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex, GPT-5 coding agent (`gpt-5`), agentic coding with
terminal/tool use and local test execution.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-04-22 10:43:38 -05:00
..
access.ts [codex] Add structured issue-thread interactions (#4244) 2026-04-21 20:15:11 -05:00
activity.ts [codex] Harden heartbeat scheduling and runtime controls (#4223) 2026-04-21 12:24:11 -05:00
adapters.ts Harden API route authorization boundaries (#4122) 2026-04-20 10:56:48 -05:00
agents.ts [codex] Harden heartbeat scheduling and runtime controls (#4223) 2026-04-21 12:24:11 -05:00
approvals.ts [codex] harden authenticated routes and issue editor reliability (#3741) 2026-04-15 08:41:15 -05:00
assets.ts Use attachment-size limit for company logos 2026-03-16 10:13:19 -05:00
auth.ts feat: implement multi-user access and invite flows (#3784) 2026-04-17 09:44:19 -05:00
authz.ts feat: implement multi-user access and invite flows (#3784) 2026-04-17 09:44:19 -05:00
companies.ts Harden API route authorization boundaries (#4122) 2026-04-20 10:56:48 -05:00
company-skills.ts Address Greptile telemetry review comments 2026-04-03 14:11:11 -05:00
costs.ts Harden API route authorization boundaries (#4122) 2026-04-20 10:56:48 -05:00
dashboard.ts refactor: rename packages to @paperclipai and CLI binary to paperclipai 2026-03-03 08:45:26 -06:00
execution-workspaces.ts [codex] Respect manual workspace runtime controls (#4125) 2026-04-20 10:39:37 -05:00
goals.ts Add versioned telemetry events 2026-04-03 09:25:00 -05:00
health.ts [codex] Add backup endpoint and dev runtime hardening (#4087) 2026-04-20 06:08:55 -05:00
inbox-dismissals.ts Persist non-issue inbox dismissals 2026-04-09 06:16:05 -05:00
index.ts [codex] Add backup endpoint and dev runtime hardening (#4087) 2026-04-20 06:08:55 -05:00
instance-database-backups.ts [codex] Add backup endpoint and dev runtime hardening (#4087) 2026-04-20 06:08:55 -05:00
instance-settings.ts feat: implement multi-user access and invite flows (#3784) 2026-04-17 09:44:19 -05:00
issues-checkout-wakeup.ts Cut over OpenClaw adapter to strict SSE streaming 2026-03-05 15:54:55 -06:00
issues.ts [codex] Fix stale issue execution run locks (#4258) 2026-04-22 10:43:38 -05:00
llms.ts fix: harden heartbeat and adapter runtime workflows 2026-04-10 22:26:21 -05:00
org-chart-svg.ts Improve generated company org chart assets 2026-03-23 16:58:07 -05:00
plugin-ui-static.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugins.ts Harden API route authorization boundaries (#4122) 2026-04-20 10:56:48 -05:00
projects.ts [codex] Respect manual workspace runtime controls (#4125) 2026-04-20 10:39:37 -05:00
routines.ts Add draft routine defaults and run-time overrides 2026-04-09 10:19:52 -05:00
secrets.ts refactor: rename packages to @paperclipai and CLI binary to paperclipai 2026-03-03 08:45:26 -06:00
sidebar-badges.ts feat: implement multi-user access and invite flows (#3784) 2026-04-17 09:44:19 -05:00
sidebar-preferences.ts [codex] Improve workspace runtime and navigation ergonomics (#3680) 2026-04-14 12:57:11 -05:00
user-profiles.ts [codex] Add access cleanup and user profile page (#4088) 2026-04-20 06:10:20 -05:00
workspace-command-authz.ts [codex] harden authenticated routes and issue editor reliability (#3741) 2026-04-15 08:41:15 -05:00
workspace-runtime-service-authz.ts [codex] harden authenticated routes and issue editor reliability (#3741) 2026-04-15 08:41:15 -05:00