Retain both Claude SDK admission and bounded Intel initial-install failure evidence. All25 focused consumer controls pass; no provider, build campaign, local Rust or Docker.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Preserve Claude v7 effort, lease ownership, historical readers, and Pi25 source binding while composing canonical16a and task-workspace masterf329. Protocol/surfaces noemit and all generation checks pass.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Preserve guarded test-home cleanup and both Storybook source reviews. Keep the installer deadline and all artifact/lifecycle/runtime assertions intact while retaining its failed npm progress.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Keep the qualified four-target selection and both Linux provider-pack assembly paths while carrying the current shared source.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Give tasks durable company-scoped workspace bindings independent of project assignment, channel defaults and authorized repository preparation. Reuse verified input seeds and sparse output recovery while preserving trust, privacy and controller provisioning boundaries.
Full CI and E2E, Superagent, legacy checks and Greptile Apex 5/5 passed on reviewed head 753680b61c. All review findings are resolved; the PR records focused verification and historical acceptance limits.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Preserve canonical startup ownership, scoped evidence, current Storybook IDs, and the Codex form controls while carrying Claude effort and immutable source bindings.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Extract the guided setup test fixture without dropping cases. Supply current settings/discovery contracts and Opus 5.5 in the isolated Storybook boundary.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Use the existing environment probe before native-generation Codex creation and inspect automatic server defaults. Include only the owned setup probe lease in the existing runtime estimator. Preserve explicit and Legacy cases, cleanup, unknown failure costs and reporting.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - Slack connects a person to an agent through an installed app and a
verified identity.
> - Independent installations must remain usable without Paperclip Cloud
or manager credentials.
> - Approved Cloud deployments can use Slack manager grants to create
and install each agent's app.
> - Both paths should share credential storage, identity checks,
recovery, and the existing runtime.
> - This pull request adds gated managed setup and keeps independent app
setup under Advanced.
> - It also makes ongoing connection settings and personal test messages
easier to use.
## Linked Issues or Issue Description
**Subsystem affected**
Slack setup, connection settings, tenant credential storage, and the
Cloud connector handoff.
**Problem or motivation**
Approved deployments need an installation flow without pasted
configuration tokens. Open-source users must retain their independent
Slack app flow. A connection manager also needs a simple way to check a
bot from Settings.
**Proposed solution**
Use the managed path when the instance is configured to support it.
Choose agent and Connect are the two visible stops. Continue starts
authorization or installation. Use your own app remains under Advanced
before creation. Save personal manager grants by company, Paperclip
user, Slack user, workspace, and manager app. Reuse only verified
identities for test messages. Unknown identities must complete a private
Slack connection challenge before linking and receiving the test DM.
**Alternatives considered**
A shared bot would change each agent's Slack identity. Requiring Slack
CLI or a hosted service for self-hosted users would remove independent
installation.
**Roadmap alignment**
This maintainer-requested change improves Connected Apps and
experimental Agent Chat. It adds provisioning and management controls to
the existing Slack runtime.
**Additional context**
The companion Cloud broker profile is a separate deployment
prerequisite. Managed setup remains gated. Existing-app adoption is
deferred.
## What Changed
- Extract Slack registration, provider requests, completion,
customer-owned setup, managed setup, and personal manager grants into
focused services. Preserve the compatibility facade and independent
removal cleanup.
- Add company-scoped manager grants and a registration reference through
an additive, idempotent migration after current master. Keep runtime
credentials separate from app-registration secrets.
- Add authenticated manager authorization, sealed handoff, serialized
refresh and revocation, app creation, managed installation, and
installer-bound OAuth fallback.
- Preserve creation intent, block automatic uncertain recreation, save
credentials before downstream checks, and validate app, workspace, bot,
scopes, and installer identity.
- Add the two-stop production wizard and ordered stories. Keep the
own-app, manual, existing-app, and legacy-draft paths.
- Simplify Settings. Open Slack configuration targets the saved app. The
test-message action has its own row. Remove the old manual-avatar
section, channel-message section, and broken permissions link.
- Add paginated account discovery and a private connection challenge for
unknown accounts. Expired invitations stop waiting and offer a new
private invitation. Save send receipts before provider dispatch and
preserve confirmed delivery when activity logging fails.
- Reinstall the saved managed app on explicit reconnect, replace revoked
credentials, and resume completion. Persist reconnect intent and
duplicate-request receipts without creating another app.
- Update provider browser tests, recovery tests, secret redaction, setup
documentation, and the agent prompt. Preserve current master's durable
verification scheduling.
## Verification
- Full workspace typecheck and repository build passed on `56d389d47a`.
The subsequent reconnect retry fix in `288364eada` also passed UI
typecheck and UI build.
- 114 focused Slack registration cases and 13 production managed-wizard
cases passed, including fresh-token reconnect, retry after installation
failure, and duplicate reconnect requests.
- All nine affected Slack browser cases passed against the production UI
and a disposable fixture server. They cover managed setup, automatic
setup, own-app selection, refresh, recovery, mobile behavior, and
connection settings.
- Eight focused real-database test-message cases passed. They cover a
private ownership challenge, saved grant reuse, account pagination,
revoked and conflicting links, workspace mismatch, disabled DMs, revoked
membership, audit failure, ambiguous dispatch, and secret canaries.
- UI token gates and the production Storybook build passed.
- Greptile reviewed exact head
`288364eada5d9c114fad991ff634612639d06672` at 5/5 with no actionable
findings or unresolved review threads.
- The full repository test suite and current-head CI are running. Their
final results will replace this line before merge.
- Earlier live feature previews created two bots in the authorized
Paperclip Slack workspace and reused one personal manager grant. Local
managed Continue created and installed a bot without a configuration
token or a separate Add to Slack action. Avatars, welcome DMs, signed
callbacks, and direct replies were observed. A Settings test DM also
arrived in the signed-in user's Slack account.
- Earlier staging thread qualification required manual publication
recovery for one bot. Current-head live qualification remains required
before enabling the production default. Fixture results do not establish
Slack approval behavior in other workspaces.
## Risks
- Personal manager tokens can create apps. They stay in scoped vault
entries. The manager client secret stays at the broker. Company,
actor/session, origin, and app identity checks apply throughout setup.
- The additive migration must also work on qualification instances that
applied earlier branch migrations. Table, column, index, and constraint
creation is idempotent.
- Creation and message timeouts can leave uncertain outcomes. Saved
request IDs prevent automatic duplicate dispatch.
- Unknown Slack identities must receive and complete their private
challenge while signed in. Account selection alone does not grant
Paperclip permissions. Existing revoked or conflicting links are not
overwritten.
- A development-only manager transport uses an explicitly configured
private credential file for local qualification. Production ignores this
transport; no manager credentials are bundled with open source.
- Managed rollout requires Slack approval, the companion broker
deployment, configured secrets, and final live qualification. Removing a
connection does not delete its Slack app.
## Model Used
OpenAI Codex, GPT-6 family, with reasoning, code execution, and browser
tools. The session does not expose the exact serving model ID or
context-window size.
## 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
- [ ] 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
- [ ] 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>
Extract the tested runtime and installed-package prerequisite without changing agent creation defaults or experimental gates.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Retain both hosted cache scopes. Use shared test-home teardown and restore owned directory permissions for the observed Mac ENOTEMPTY failure while keeping unrelated errors visible.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Version the shared Pi and pending Copilot source attestations without changing their executable closures or platform qualification.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Preserve Codex GNU libc eligibility and Linux ARM64 behavior; keep Claude automatic selection limited to Apple Silicon.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Isolate actual Codex resolver fixtures from global bridge lookup and preserve host qualification blockers with literal evidence.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - Its Skills library imports reusable instructions from GitHub.
> - Some skills depend on shared files and sibling skills outside their
folders.
> - Directory-only imports lose those dependencies.
> - This pull request keeps repository files together and lets users
select which skills appear in the library.
> - Agents receive the original files and paths through the existing
skill delivery system.
## Linked Issues or Issue Description
Refs #14713. Related: #13656.
**Current behavior**
GitHub imports copy independent skill directories. Shared scripts,
policies, helper skills, and credit files can be omitted. One
shared-file error can block every skill.
**Proposed behavior**
New imports keep repository files together at the scanned commit. Show
all skills with their folders and select every skill by default.
Collapse individual package files. Omit unsupported or oversized files
with a warning. Import available content without repair choices or an
extra confirmation. Keep warnings on the saved source.
**Reason and benefit**
Skills can read their shared repository files after Paperclip delivers
them to an agent. Original instructions stay unchanged. Users can
inspect included files and understand omissions before and after import.
## What Changed
- Store immutable company-scoped repository snapshots and associate them
with skill versions. Regenerate the migration after merging master.
- Preserve original bytes, binary encoding, and executable modes.
Shared-file changes version each usable selected skill. Pinned versions
retain their original files.
- Deliver a discovery wrapper with the original tree under
`.paperclip-repository/`. Preserve invocation policy when present. Fork
and create-from-existing retain repository files.
- Keep repository files together for new UI imports. Show every skill,
select all by default, and collapse package files. Remove the
packaging-mode menu. Keep the mobile import footer visible.
- Warn about symlinks, submodules, oversized files, missing references,
and invalid optional manifests. A malformed skill remains selected with
a Needs setup warning. Usable skills still publish, and its original
file remains repository support content. Source warnings persist through
refresh. Unsafe execution and secret-disclosure findings omit the
affected files before snapshot publication.
- Expose saved repository files in the installed skill viewer, including
binary encoding and executable flags. Reads use the immutable
company-scoped snapshot; relative instruction links resolve from their
original repository directory.
- Audit delivered inventories and derive trust from all repository
files. Accept evaluation prose while retaining dynamic-execution
findings. Read blobs in one bounded Git batch and check budgets before
reading support files. Imports never execute setup commands.
- Add scanner, database, delivery, UI, and browser regressions. Update
Storybooks, screenshots, and documentation.
## Verification
- 69 focused scanner, Git snapshot, delivery, and PostgreSQL lifecycle
tests passed. They cover partial imports, warning persistence, missing
references, binary files, executable modes, copies, pinned versions,
cancellation, company isolation, and batched Git reads.
- 110 import, skill-detail, selection-tree, saved-file link, and
Markdown renderer tests passed. A file-switch regression failed before
the resolver fix and passed afterward. Browser walkthroughs cover the
all-selected open tree, repository preview, non-blocking warnings,
missing references, setup problems, warning persistence, and mobile
layout.
- Full workspace typecheck and build passed. Runner E2E TypeScript
checks and design-token gates passed. The full serial local suite was
attempted and stopped after over an hour. The existing 40,000-file Git
streaming stress test failed after 303 seconds on macOS; the broad local
suite is not counted as passed. All 55 applicable PR checks passed on
the final commit, including the full sharded CI suite. Two optional
Storybook workflows were skipped; the five local Storybook walkthroughs
passed.
- On October 12, live campaigns imported the private Poteto repository
through the production GitHub Sources UI, selected architect and bro,
and invoked them with native Codex on local and Daytona. The source
connection was disabled before invocation. Independent filesystem
inspections matched every supported Git blob, size, and executable mode.
Both tasks completed and cleanup passed. Campaigns:
`local-2026-10-12T15-07-39-504Z` (both environments),
`local-2026-10-12T16-08-39-682Z` (local), and
`local-2026-10-12T16-03-33-938Z` (Daytona). Each of the two selected
skills received all 234 supported repository files. Later changes only
affect the installed-file viewer and documentation. This qualifies skill
delivery and instruction reads, not every Poteto workflow or adapter.
- A manual source-checkout test drive imported a synthetic private
GitHub repository with a symlink, an oversized file, a missing
reference, and malformed skill metadata. Available skills published with
their shared checklist. The walkthrough found duplicate warning text
after import; the final UI fix removes that duplicate. The file viewer
exposes saved repository dependencies and resolves authored relative
links without changing the instructions. A follow-up live refresh
omitted unsafe helper files with warnings, preserved every safe file
byte, and survived a server restart.
Screenshots below use the production UI with Storybook fixtures. They do
not replace the live GitHub and runtime checks.
<details>
<summary>All skills visible and selected by default</summary>

</details>
<details>
<summary>Import stays available with warnings</summary>

</details>
<details>
<summary>Repository file inspector</summary>

</details>
<details>
<summary>Mobile import</summary>

</details>
## Risks
- Each selected skill carries a repository copy in the runtime. The
database stores each snapshot once. Runtime transfer and storage
increase with the number of assigned skills.
- Runtime budgets remain: 9,990 repository entries, 1 MiB per file, and
61 MiB total. File omissions are recorded as warnings. Source-access or
download failures retain installed versions.
- Import success does not prove that every skill can run. Environment
dependencies, credentials, delegation tools, and schedules still need
configuration. Imported setup scripts are not executed.
- Live runtime coverage is native Codex on local and Daytona. Other
adapters use the shared delivery path but were not exercised in these
campaigns.
The roadmap marks Skills Manager as shipped. This extends the existing
importer. Related pull requests were checked.
## Model Used
OpenAI Codex, based on GPT-6, with repository inspection, code
execution, automated tests, and browser tools. The exact deployment
identifier and context-window size were 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
- [ ] 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
Preserve actual target selection, record the GNU libc baseline, and retain primary installed-startup failures for ARM qualification.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip runs agent tasks and preserves their managed agent files.
> - Heartbeat must prepare a private copy, collect stopped-provider
edits, and retain ownership during warm-session handoff.
> - That lifecycle is spread across preparation, adapter callbacks, and
cleanup.
> - A per-run controller can own the copy and receipt while the executor
retains teardown ordering.
> - This PR moves that coordination into a dedicated module.
> - Live getters preserve updated state and partially acquired
resources.
## Linked Issues or Issue Description
**What existing behavior does this improve?**
Maintenance of heartbeat instruction preparation. This is the second and
final PR in this batch, originally stacked on #15980. That dependency is
now merged; this PR is rebased onto its squash merge with an identical
patch and identical touched-file contents. Related-PR search found no
duplicate extraction.
**Current behavior**
After #15980, `heartbeat.ts` has 4,215 lines and 173,657 bytes. It
coordinates instruction-copy preparation, save receipts, warm handoffs,
and deferred cleanup inline.
**Proposed behavior**
`heartbeat/instruction-working-copy.ts` owns the per-run lifecycle in
233 lines. `heartbeat.ts` becomes 4,055 lines and 162,520 bytes. The
executor retains the outer release order, unavailable-copy reporting,
and environment/service cleanup policy.
**Reason and benefit**
The copy, save receipt, and warm ownership are readable together. The
remaining executor names preparation and dispatch phases without
obscuring teardown decisions.
**Breaking changes**
None intended. All 140 named public heartbeat exports remain unchanged.
## What Changed
- Extract copy preparation, save/checkpoint callbacks, warm
reservation/adoption, prompt guidance, and the deferred-release closure.
- Read the executor's current run row through a callback; expose current
copies, receipts, and acquired cleanup handles through live getters.
- Keep cleanup handles available after preparation failure, and preserve
release-before-retry on invalidated warm reuse.
- Add four public-path characterization tests with real disposable
PostgreSQL and files, plus four direct boundary tests.
- Add isolated browser acceptance with a real process that edits
instructions, completes its task, and reads the saved bytes on its next
task.
- Document the boundary and opt-in acceptance command.
## Verification
- **Before extraction:** four new public-path tests pass on the original
implementation, as do 108 existing
instruction-copy/directory/native-cleanup tests. The two-task browser
journey also passes on the baseline server.
- **After extraction:** all 112 baseline tests pass; all four new
boundary tests pass; 12 selected native-session ownership/retirement
cases pass (the other 670 cases were outside this focused selection).
- **Browser acceptance:** the fresh extracted-code server passes the
full two-task journey (25.9 seconds): real child-process edits,
saved/unchanged receipts, canonical bytes through the agent-file API,
next-task restore, completed task UI, and copy cleanup.
- `pnpm -r typecheck`, final server typecheck, and `pnpm build` pass.
Module-boundary and public-export checks pass.
- Normalized syntax comparison confirms all moved bodies and the
reconstructed executor match the base, accounting explicitly for live
run getters and delegation.
- Final rebased head: `a08872c97e587a21ffc0fc6b78f34b81e484e7b0`.
Combined entry-point and boundary regressions pass again (12/12); fresh
Greptile review is 5/5 with no findings. All 55 current-head checks pass
(two configured skips), including the hosted full-suite tests, build,
typecheck, and all eight browser shards. There are no open review
threads.
## Risks
- Acquisition can succeed before preparation throws. Boundary tests
verify that both the reservation and a transferred copy remain visible
to the cleanup owner.
- Callbacks can replace copy/save state during execution. Public tests
verify saved receipts; direct tests verify the current run row, warm
checkpoint receipt, and permission-root preservation.
- Missing edit authorization and cleanup failure must remain nonfatal.
Characterization tests revoke actual membership after dispatch admission
and inject a cleanup error while preserving the saved result.
- The browser uses a test-launcher-only instruction-capable wrapper
around the real process adapter. Production adapter capabilities are
unchanged. No live provider calls are made; native warm ownership is
covered by focused module and native-session tests rather than a live
provider browser run.
## 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>
Carry Claude effort through versioned native admission and recovery. Preserve existing connections and saved runner choices, and price Opus 5.5 API receipts.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Retire duplicate ACPX and Codex proof after migrating unique assertions to their behavioral owners. Consolidate repeated fixtures and exact case matrices while preserving lifecycle, protocol, company, credential, approval, and ordering contracts. Remove the unused runtime-controls compatibility path and document test ownership and preservation evidence.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
## 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>
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - Heartbeat runs stream adapter output and persist execution results.
> - Output recording currently sits inside the executor beside admission
and cleanup.
> - Log handles, sequence numbers, progress writes, and excerpt buffers
share one attempt lifetime.
> - This pull request moves that state and its callbacks into a
per-attempt recorder.
> - The executor keeps dispatch and finalization visible, while
finalization reads live output values.
## Linked Issues or Issue Description
**What existing behavior does this improve?**
Maintenance of heartbeat execution. This PR follows #15966, which is now
merged. The branch is rebased onto `master`; `git range-diff` confirms
that its extraction patch is unchanged.
**Current behavior**
`heartbeat.ts` has 4,740 lines and 195,258 bytes. It directly owns log
handles, excerpt buffers, output sequence numbers, progress flushes, and
adapter event callbacks.
**Proposed behavior**
`run-output.ts` owns the per-attempt recorder. The main file has 4,561
lines and 188,950 bytes; the recorder has 209 lines and 7,757 bytes.
**Reason and benefit**
Output state has one explicit lifetime and interface. The shared log
store and finalization policy retain their original owners. Related open
output work includes #12539 and #15524; this PR does not change
redaction policy.
**Breaking changes**
None intended. Public flush constants and log formatting exports remain
available from `heartbeat.ts`.
## What Changed
- Move log initialization, redaction, excerpts, progress persistence,
live delivery, and adapter callbacks into `createHeartbeatRunOutput`.
- Preserve the acquired log handle if later setup fails. Bind callbacks
to the execution-start run row.
- Pass live excerpt getters to success and failure completion so output
arriving during finalization remains visible.
- Add three real-database public-path tests. Extend browser acceptance
to inspect persisted worker stdout and output byte counts.
- Update the module map.
## Verification
- Before extraction: 23 tests pass, including all three new output
characterization cases.
- After extraction: 45 tests pass across output, log formatting, event
sequencing, and run completion. No skips.
- `pnpm -r typecheck` and `pnpm build` pass.
- Normalized syntax comparison confirms the moved bodies and
reconstructed executor match. Reviewed the factory ownership, callback
binding, getter wiring, and constant re-exports separately.
- Isolated browser acceptance: 2/2 pass, including persisted worker
stdout and matching final byte counts. The process worker completes
after recovery; persistent timeouts stop after three attempts. Both
terminal states survive reload.
- Hosted full-suite CI passes on
`d32c8fc40e72b9766bdd9e191d777e8dc554e3f2`; all 55 reported checks are
successful. Greptile is 5/5 with zero review threads.
- The initial chat shard timed out waiting for GitHub mention admission.
Its fixture mocks heartbeat wakeup and never calls the output recorder.
Both parameterized cases passed locally; the unchanged shard passed on
one rerun. No test or timeout changes.
- Merge preparation: all seven session-preparation and run-output
regression tests pass after rebasing onto `master`. Fresh full CI passes
for `60e2a49ce2879645a9f618a801e0ba0903ede161`: 55 successful checks and
two optional Storybook skips, including all eight browser shards,
typecheck, tests, and build. Greptile is 5/5 on this exact commit with
zero review threads.
## Risks
- A stale excerpt snapshot could lose output that arrives while
finalization awaits I/O. Passing-before/passing-after tests exercise
this for both successful and failed runs.
- Per-attempt state must not become service-wide. Each executor
constructs its own recorder and keeps the existing shared store.
- Browser acceptance uses a real process fixture and disposable data; it
makes 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>
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - Heartbeat execution prepares task context before it selects an
environment and starts an adapter.
> - This preparation still occupied 319 lines inside the executor after
the earlier extractions.
> - It combines continuation summaries, comments, prompt variants,
communication guidance, and redaction.
> - This pull request moves that responsibility into one typed module
under `services/heartbeat/`.
> - The executor keeps admission, resource ownership, dispatch, and
cleanup ordering together.
> - The result makes the preparation phase easier to find and test
without changing execution behavior.
## Linked Issues or Issue Description
Refs #15825, #15807. This continues the incremental heartbeat extraction
series. A search found no duplicate task-context extraction.
**What existing behavior does this improve?**
Maintenance and review of heartbeat task context preparation.
**Current behavior**
The executor assembles prompts and trust-filtered context inline. This
hides its execution phases among preparation details.
**Proposed behavior**
Call `prepareHeartbeatTaskContext` at the same point in execution.
Preserve statement order, prompt contents, public exports, and the
shared run context object.
## What Changed
- Move task context assembly to
`server/src/services/heartbeat/task-context.ts`. Inputs group task
state, policy, and two existing service methods. Results preserve the
continuation and wake values used by later runtime selection and
dispatch.
- Keep company-scoped loading, quarantined-content filtering, secret
redaction, and revision hashing in their original order. Add no
execution resource acquisition.
- Add four public-path integration tests before the move. Cover prompt
variants and redacted revisions, quarantined summaries/comments, a
mixed-company wake batch, and stale caller fields.
- Extend the real process worker in the opt-in browser suite to check
persisted prompt variants and the description revision before it
completes its task.
- Update the module map and acceptance-test documentation.
- Reduce `heartbeat.ts` from 5,314 lines / 220,784 bytes to 4,989 lines
/ 206,650 bytes. The new module has 376 lines / 15,912 bytes.
## Verification
- Before the move: 11 existing prompt tests and all four new
characterization tests passed against the inline implementation.
- Normalized syntax comparison passed for all 319 moved lines and the
remaining orchestrator, including public exports. Imports and the typed
boundary were reviewed separately.
- `pnpm -r typecheck` passed.
- `pnpm build` passed.
- The clean post-move focused run passed all 26 tests in five files,
with no skips: task-context characterization, task-markdown, Slack
invitation, accepted-plan workspace refresh, and run-preparation.
- The local `pnpm test:run` attempt was interrupted after database
failures while the Mac exhausted its shared-memory slots. All 15
affected native warm-ownership database cases passed in an isolated
rerun after the browser instance stopped; the other 666 cases in that
file were excluded by the test-name filter. The interrupted command is
not a full-suite pass. Full CI passed on
`6bf86cfdc07e7fe34015f7b719218639f4232510`: 55 successful checks and two
optional Storybook checks skipped. Greptile reviewed the latest commit
at 5/5; its one earlier worker-test finding is fixed and resolved.
- Browser E2E passed both scenarios on the final code: persistent
timeouts stop after three runs and survive reload; one timeout recovers
without manual Retry, verifies task-context prompt variants/revision and
preserved workspace files in a real process, then completes through the
run-scoped API. The first recovery attempt exposed an incorrect new test
assertion because the fixture title equals its description. The worker
now checks the description section specifically; the corrected recovery
scenario passed in 55.9 seconds. The original failure trace was
preserved. These tests use a deterministic process adapter and make no
live model calls.
## Risks
This is a behavior-preserving extraction. The main risks are changed
closure bindings, missing return values, or changed preparation order.
Typed inputs, public-path tests, and syntax comparison cover those
risks. The run context is still the same mutable object. The helper
acquires no leases or processes. It introduces no schema, API, or prompt
policy changes.
The first post-move database run skipped cases due to host resource
exhaustion. All 26 focused cases passed on the subsequent clean run.
Browser E2E passed after the worker assertion fix. The full local suite
remains incomplete. All 15 native warm-ownership database cases passed
on their isolated rerun; The full CI test suite passed on the final
commit.
## Model Used
OpenAI Codex, based on GPT-6, with reasoning, repository inspection,
code execution, and test tools. The host does not expose the exact
deployment model ID or context-window size.
## 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>
## Thinking Path
> - Paperclip helps people manage agent work and retain its context.
> - Task documents and attachments keep that context with the task.
> - The Artifacts panel showed output but could not accept a new file.
> - Uploading through a message can require resuming a paused task.
> - Existing document and attachment APIs can save files directly.
> - This PR adds direct uploads and a drop target to the task panel.
> - People can add context while keeping work paused and unassigned.
## Linked Issues or Issue Description
**What existing behavior does this improve?**
The task Artifacts panel and its existing document and attachment APIs.
**Subsystem affected**
ui/ — React board UI. No server, schema, or API changes.
**Current behavior**
The Artifacts panel cannot upload a file. It also excludes files
uploaded by people. The message composer can require a task to resume
before it submits attachments.
**Proposed behavior**
Use the upload icon or drop files anywhere in the open Artifacts panel.
The target includes the header, padding, and existing cards. Files save
directly to the task without a message or a pause change.
**Reason and benefit**
People can prepare a handoff on a paused, unassigned task without
starting agent work. Markdown becomes a task document. Other supported
files use attachment storage.
**Breaking changes**
Files from people now appear in Artifacts alongside agent output.
Promoted attachments still appear once. A repeated Markdown filename
creates a separate document instead of replacing an existing revision.
Existing APIs and limits stay the same.
**Additional context**
Related upload API work: Refs #7472 and Refs #7248. This PR adds the
missing task-panel entry point. ROADMAP.md lists Artifacts and Work
Products as available; this is a scoped UI improvement.
## What Changed
- Add an upload icon with no visible label or background.
- Accept file drops across the full task panel, including the desktop
portal header and mobile tabs.
- Show per-file progress and inline Retry and Dismiss actions.
- Import Markdown under a new document key and retain existing
revisions.
- Include files from people in Artifacts and dedupe promoted
attachments.
- Add component and task-journey stories for empty, populated, loading,
error, mobile, and drag-over states.
- Add real browser tests for persistence, pause preservation, duplicate
document names, full-panel drops, and partial failure recovery.
## Verification
- Five Playwright tests passed against an isolated instance started by
the source `test-drive` command. The document API, attachment storage,
pause holds, downloads, and task UI were real. Only the explicit upload
failure was injected.
- The browser tests verified desktop and mobile uploads, document
reading, persistence after reload, no task comments or runs, header
drops, preservation of original and hidden internal documents, reserved
filename handling, and upload retry.
- 163 focused UI tests passed.
- `pnpm -r typecheck` passed.
- `pnpm build` passed.
- `pnpm check:token-gates` passed.
- The full Vitest suite is running after repair of an exhausted local
PostgreSQL shared-memory pool. The initial run failed to initialize
PostgreSQL. Six unattached segments had no living creator or last-user
process; removing them restored free slots.
- CI and the current-head Greptile review are pending.
## Risks
- Artifacts now includes user files, so existing tasks can show more
cards.
- Uploads retain the server's authorization, file-type, size, and
revision checks. No migration is needed.
- Binary attachment uploads use the existing API. A transport failure
with an unknown save outcome can retain the existing API's retry
ambiguity.
## Model Used
OpenAI GPT-6 through Codex. The exact runtime snapshot ID and
context-window size were not exposed to this session. The model used
repository inspection, code editing, shell tools, and browser
automation.
## 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
- [ ] All Paperclip CI gates are green
- [ ] 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>