mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-13 13:38:01 +02:00
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Heartbeat runs start workspace services and receive service reports from adapters. > - Service context updates and readiness notices are spread through the executor. > - These steps share a clear responsibility, while process and lease ownership already live elsewhere. > - This pull request puts service coordination in one module. > - The executor retains the same dispatch and cleanup order. ## Linked Issues or Issue Description **What existing behavior does this improve?** Maintenance of heartbeat execution. This is the first of two final focused extractions after #15973. Related #15653 changes runtime callback origins; this PR preserves that policy. **Current behavior** `heartbeat.ts` has 4,372 lines and 178,459 bytes. It validates service intents, starts services, persists adapter reports and primary URLs, and posts readiness notices inline. **Proposed behavior** `heartbeat/runtime-services.ts` owns those steps in 212 lines. `heartbeat.ts` becomes 4,215 lines and 173,657 bytes. Process registries and leases stay in `workspace-runtime.ts`. The executor still releases services in its original cleanup path. **Reason and benefit** Service coordination has named preparation and result phases. The execution path is easier to read without changing service lifetime or moving cleanup policy. **Breaking changes** None intended. All 140 named public heartbeat exports remain available, including `postWorkspaceReadyComment`. ## What Changed - Move service-intent validation, startup, adapter-result persistence, and readiness notices into one module. - Preserve mutable run context, primary URL selection, notice error handling, and release ordering. - Add four public-path tests using disposable PostgreSQL, real HTTP service processes, and a fixture adapter. - Extend browser recovery acceptance to fetch the actual service URL, check the readiness notice, and verify listener cleanup. - Update the module map and acceptance instructions. ## Verification - Before extraction: all five tests pass, including the four new characterization cases and existing notice formatting test. - After extraction: all 17 tests pass across service coordination, notice formatting, output recording, and runtime authorization. - Structural comparison confirms that all moved bodies and the reconstructed executor match the baseline. Module boundary checks pass. - `pnpm -r typecheck` and `pnpm build` pass. - Extended isolated browser acceptance: **2/2 pass** (3.7 minutes), covering actual service readiness, recovery, bounded failure, and cleanup. At `8e33e2032de681082f128470eb8ab0711b382afe`, all 55 current-head checks pass (two configured skips), including hosted full-suite tests. Greptile is 5/5 with no findings or review threads. ## Risks - Service context must be persisted before adapter dispatch and before run completion. The tests inspect both phases and preserve the first service URL when adapter reports arrive. - Notice failures must remain nonfatal. The public-path test checks both startup and result notices. - Shared services must survive run cleanup; ephemeral services must stop after success or failure. Tests use actual processes and HTTP requests. - The fixture supplies UUID service report IDs, as required by the database. The existing generated-ID fallback for reports without IDs is outside this extraction. - Test adapters and services are local fixtures; these tests make no live provider calls. ## Model Used OpenAI Codex, based on GPT-6, assisted with reasoning, code edits, tool execution, and verification. The exact deployment model ID and context-window size are not exposed in this session. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing>
41 lines
2.0 KiB
Markdown
41 lines
2.0 KiB
Markdown
# Workspace bootstrap recovery acceptance
|
|
|
|
This opt-in suite uses a disposable loopback instance, real Git repositories,
|
|
the real Git scan scheduler, durable retries, and the task UI. A deterministic
|
|
process adapter verifies the prepared files and completes its task through the
|
|
run-scoped API. It makes no model calls. The test Git executable injects a real
|
|
timeout only when the test explicitly arms a marker inside its repository.
|
|
|
|
From a development worktree, start the foreground instance:
|
|
|
|
```sh
|
|
node cli/node_modules/tsx/dist/cli.mjs tests/e2e/workspace-bootstrap/launch.ts
|
|
```
|
|
|
|
The launcher creates an isolated test-drive, installs the Git shim, and sets a
|
|
10-second snapshot deadline after test-drive clears inherited configuration.
|
|
Production's longer snapshot deadline would outlast the injected failure.
|
|
|
|
Set `BOOTSTRAP_REAL_GIT` to the absolute Git executable if it is not
|
|
`/usr/bin/git`. Do not point this fixture at a normal development or production
|
|
instance. The seeder checks the loopback host, trusted-local mode, and company
|
|
name. It does not create tasks; each test creates its task through the UI.
|
|
|
|
Use the ready URL printed by test-drive:
|
|
|
|
```sh
|
|
WORKSPACE_BOOTSTRAP_TEST_URL=http://127.0.0.1:3100 \
|
|
pnpm exec playwright test --config tests/e2e/workspace-bootstrap/playwright.config.ts
|
|
```
|
|
|
|
The tests prove that one timeout schedules a retry and completes without manual
|
|
Retry, that persistent timeouts stop after three total runs, and that the final
|
|
state survives reload. Source edits remain intact and ignored private files are
|
|
not copied. The worker also verifies that persisted task context contains the
|
|
assignment, the full and compact prompt variants, and the description revision.
|
|
Screenshots and failure traces go to `test-results/workspace-bootstrap`.
|
|
The successful worker also requests a real ephemeral runtime service over HTTP.
|
|
The browser checks its persisted URL and readiness notice, then verifies that
|
|
the listener stops after run cleanup.
|
|
Stop test-drive with Ctrl-C. Its disposable data directory remains for inspection.
|