Normal parent merge; only the qualified queued-run fixture changes. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the qualified queued-run fixture changes. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the qualified queued-run fixture changes. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the qualified queued-run fixture changes. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the qualified queued-run fixture changes. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the qualified queued-run fixture changes. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the qualified queued-run fixture changes. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the qualified queued-run fixture changes. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the qualified queued-run fixture changes. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the qualified queued-run fixture changes. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Use tracked execution settlement and explicit adapter-entry barriers instead of independent short polls. Add a committed-read control proving the pre-registration drain gap while preserving durable state and concurrency assertions.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the two qualified card interval paths change. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the two qualified card interval paths change. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the two qualified card interval paths change. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the two qualified card interval paths change. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the two qualified card interval paths change. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Keep membership provenance from describing an interval-owned evaluation deadline; retain existing cadence and source handling.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the five qualified card/search paths change. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the five qualified card/search paths change. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the five qualified card/search paths change. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the five qualified card/search paths change. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the five qualified card/search paths change. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Add an internal result-kind constraint owned by company search, preserving all/comments/documents task matching and default mixed search. Apply it to card snapshots and preview without unrelated entity producer fanout.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the three qualified status-card paths change. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the three qualified status-card paths change. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the three qualified status-card paths change. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the three qualified status-card paths change. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normal parent merge; only the three qualified status-card paths change. Preserve every other owned and upstream blob.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Guard stale cleanup with the durable generation ledger and a transaction-bound canonical cancellation. Coalesce the original completed manual request, retain future manual work, and preserve one-connection and outer-commit effects.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Preserve scoped reconstruction cooldown alongside keyed concurrency and the current issue authorization and deletion boundaries.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Keep concurrent refreshes of one revision deduplicated while preventing a superseded refresh from cancelling a newer revision task before its claim.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Preserve confirmation candidates and notification ownership alongside the current routine, native, security, and retention changes.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip manages agent work and keeps its results available to
users.
> - Agent Chat needs a visible reply before the conversation can wait
for more input.
> - Native result commitment and reply presentation are separate
obligations.
> - A completed conversation can retain a valid final message without a
saved reply.
> - Existing reply recovery excludes these completed conversation turns.
> - This pull request repairs that persistence gap through the existing
recovery worker.
## Linked Issues or Issue Description
**What happened?**
A native Agent Chat turn completed successfully and saved its workspace.
Its accepted result and final assistant message were durable, but no
reply appeared in the conversation. The chat stayed active. The
deployment hiring journey in #18351 then reached its deadline while
waiting for the first reply.
**Expected behavior**
Recover the exact accepted turn's final reply once, then use normal
conversation settlement. Keep later user input active. Do not run the
agent again or replace a selected or deleted reply.
**Steps to reproduce**
1. Create an active conversation with one admitted native turn.
2. Commit an accepted DONE result and a final-channel assistant message
for that exact run, session and turn.
3. Finish workspace finalization before live heartbeat reply
presentation. Leave no saved reply.
4. Run normal response recovery. Before this fix it finds no
conversation candidate and leaves the chat active.
**Paperclip version or commit**
Reproduced with actual services at frozen master
`8bcc5a01edd5d87540401521e6f30d3df43e1848`. The production predicate
also exists in the deployed revision that exposed the failure.
Related work: #18351. The broader receipt and recovery work in #18118
and #18409 does not touch these source files.
## What Changed
- Discover unanswered committed Agent Chat turns through the existing
native response presentation worker.
- Recheck company, agent, responsible user, current execution and
conversation generation under the normal transaction locks.
- Require the accepted result digest and an exact final message from the
same native run, session and accepted turn. Keep external publication
authority separate.
- Commit the reply and presentation receipt before normal conversation
settlement. Later input stays active. Recovery does not repeat agent
work.
- Preserve skip decisions and selected or deleted replies. Add database
controls for foreign identity, stale sessions, partial commitment,
duplicates and ordinary internal task behavior.
- Document the recovery boundary in the developer guide.
## Verification
- Real-service RED/GREEN uses all 418 canonical migrations in isolated
PGlite and the exact new regression fixture. Before the fix: zero
candidates, no reply, recovery returns false and the chat stays active.
After the fix: one candidate, one exact reply, recovery returns true and
the chat waits. A repeat returns false and creates no second reply.
- All 20 canonical regression cases pass locally through a fixture-only
PGlite bridge. Only local database provisioning and `createDb` selection
differ from the normal embedded PostgreSQL fixture. Production services,
SQL queries, transactions, protocol validation and assertions remain
real. Linux embedded PostgreSQL CI is required before merge.
- Focused current-source no-emit typing passes for both production
modules and the new regression file, with normal Express augmentation
and source aliases. The broader local presentation/ownership and
conversation-settlement PGlite bridge run was interrupted before it
reported results; it is not counted as a pass. No repository-wide local
build is claimed from borrowed workspace dependencies. Clean-build CI
and canonical PostgreSQL consumer tests remain required.
- `git diff --check` and the scoped source/test secret scan pass. No
captured run data, credentials or private target identities are
committed.
- No live journey retry, deployment, configuration change or test-plan
admission was performed. The original failed journey remains failed;
this production fix still needs deployed qualification through the
unchanged journey.
- Current-head [canonical Linux
CI](https://github.com/paperclipai/paperclip/actions/runs/41207018345)
passed all 57 terminal checks with no failure or pending check. The new
20-case database regression actually passed in [server shard
8](https://github.com/paperclipai/paperclip/actions/runs/41207018345/job/124555006090),
at 13:59:25 UTC (2,643 ms). Typecheck, build and the existing consumer
lanes passed. Fresh [Greptile
review](https://github.com/paperclipai/paperclip/pull/18465#issuecomment-6544208002)
on exact `f32a432e10b377ae6277d6f728995d5fedcf9d7b` is 5/5; the
review-thread inventory is empty with no pagination. No live deployment
or journey pass is claimed by these checks.
## Risks
Eligible active conversations can gain a previously missing reply.
Recovery accepts only the exact saved final message under its accepted
result and current conversation identity. It does not run a model,
repeat hiring or change a prior test grade. Reply persistence precedes
waiting-state settlement; existing conversation recovery retains
ownership of a later interrupted settlement. No schema or public API
changes are included.
## Model Used
OpenAI Codex, GPT-6 family. The session does not expose a more specific
backend model ID or fixed context window. Used reasoning, repository
tools, TypeScript and real database 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 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
Carry only the final C1 test fixture and unrelated-process regression. Preserve all status-card, migration and runtime inputs.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
* commit '939b90abe3f455762185110e42918ae379af6e64':
test(server): observe restored Retry before draining unrelated work
Prove a completed saved Retry remains observable while another real process holds the global drain open. Preserve exact target completion, stdout, execution count, deadline and final quiet assertions, and always release the held provider before teardown. Align two inherited fixture literals with current types.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Preserve the published concurrent comment uniqueness and read-state backfill migration. Regenerate the combined schema as migration0420 with the repository workflow and retain five snapshots. Add both upgrade-path controls without changing status-card execution policy.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - Native runs keep Stop intent and retry state in durable records.
> - A provider error can leave a failed retry with an earlier
acknowledged Stop.
> - The replay path returned the existing receipt before it closed that
retry.
> - This pull request applies the existing retry fence to the validated
replay.
> - The same Stop can settle without another provider cancellation or a
new receipt.
## Linked Issues or Issue Description
Refs #14733 for the related caller-bound Stop contract. This change
covers a later retry that already has a Stop acknowledgement. The older
CI-only #14743 is not a production delivery PR.
**What happened?**
A failed native run can have a retryable coordinator and an earlier
audited Stop. A repeat Stop returns the old acknowledgement without
moving the coordinator to `terminal_failure`. The final
failed-to-cancelled transition requires that fence, so the Stop cannot
settle through that path.
**Expected behavior**
A valid replay closes the same retry and keeps the original intent and
acknowledgement. It does not send a second provider cancellation.
Physical stop and workspace cleanup still require their own evidence.
**Steps to reproduce**
1. Store a failed native run with a `retryable_failure` coordinator.
2. Store a matching run-scoped Stop with a dispatched acknowledgement
and audit IDs.
3. Call `cancelNativeSession` for that same run and inspect the
coordinator.
**Paperclip version or commit**
Reproduced on public master `f2db909393de124caf6a5380a52d4e0e1d621661`.
**Deployment mode**
Core native execution. The regression uses the real cancellation
executor with controlled persistence and provider boundaries.
## What Changed
- Reuse the existing guarded coordinator fence for a validated Stop
replay.
- Test repeated replay, unchanged receipts, one fence, and no second
provider cancellation.
- Reject foreign company, run, issue, scope, effect, and missing-audit
receipts before any write.
- Check that an acknowledged Stop with an unconfirmed remote lease still
fails the physical-stop guard.
- Document the separate retry fence and physical-cleanup requirements.
## Verification
- RED on the selected public base: the new executor case returned
success but left the coordinator in `retryable_failure` with a future
retry. One case executed and failed for that assertion.
- GREEN: 62 focused tests passed across
`native-session-executor.test.ts` and
`native-cancellation-request.test.ts`. These include ownership, caller
conflict, changed-phase, and receipt controls.
- Command from `server/`: `node ../node_modules/vitest/vitest.mjs run
src/services/native-runtime/native-session-executor.test.ts
src/services/native-runtime/native-cancellation-request.test.ts -t
'native session cancellation|caller-bound native cancellation|failed
native retry caller admission'`.
- Canonical Linux CI passed all 1,018 executor cases and all 32
caller-cancellation cases. The exact file completion lines are in
[server shard
2](https://github.com/paperclipai/paperclip/actions/runs/41203989386/job/124545366271)
and [server shard
10](https://github.com/paperclipai/paperclip/actions/runs/41203989386/job/124545366219).
- Node 24.22.2 and Vitest 5.0.3. Map contract checks and `git diff
--check` pass.
- Local dependencies are linked from an existing checkout. Full local
TypeScript validation reports older Runner/shared declarations that lack
current Kimi and continuity APIs. The changed ranges have no
diagnostics. The canonical clean CI Typecheck + Release Registry gate
passed.
- A broader two-file run was stopped when an unchanged integration case
tried to start embedded Postgres and hit the host listen restriction. It
is not a passing full-suite result. No host settings or other services
were changed.
- Repository-wide `pnpm -r typecheck`, `pnpm test:run`, and `pnpm build`
were not completed locally. Current-head CI passed against clean source
and dependencies.
- Fresh [Greptile
review](https://github.com/paperclipai/paperclip/pull/18457#issuecomment-6543772487)
on `dbc1c1a5b71450194d568725592969660864cb5a`: 5/5 with no actionable
findings. The review-thread inventory has no threads and no pagination.
Full [current-head
CI](https://github.com/paperclipai/paperclip/actions/runs/41203989386)
passed: 59 terminal checks, 55 successful, 3 skipped, and 1 neutral. No
failure or pending check remains. Merge status is CLEAN. No live
recovery, rollout, or physical termination is claimed.
## Risks
- A wrong or stale Stop must not close another retry. Existing
run/coordinator locks, caller checks, receipt binding, and the final
compare-and-set remain in place.
- This fix changes logical retry settlement only. Provider termination,
workspace preservation, lease cleanup, and continuation gates remain
separate.
- The regression controls persistence and provider boundaries. It does
not establish the physical state of a remote provider.
## Model Used
- OpenAI GPT-6 through Codex, with reasoning, code editing, and tool
use. The session does not expose an exact model build ID or
context-window capacity.
## 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 references)
- [x] My branch name describes the change 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>