## Thinking Path > - Paperclip manages agent companies and their connected chat channels. > - A company deletion must remove dependent data in one transaction. > - Chat endpoints reference assigned agents with a restrictive foreign key. > - The current deletion order purges agents before those endpoints. > - This pull request removes company endpoint rows and chat history before issue and agent deletion. > - The existing lifecycle checks, company isolation, and rollback remain intact. ## Linked Issues or Issue Description **What happened?** Deleting a company with a chat endpoint fails on the endpoint's assigned-agent foreign key. The failure was found while verifying the company-deletion wake in #17557. **Expected behavior** Company deletion removes endpoint dependencies before their referenced issues and agents. It preserves other companies and global Discord ownership tombstones. A later failure rolls back the cleanup. **Steps to reproduce** Create a company, an agent, and a Discord endpoint assigned to that agent. Complete agent termination, then delete the company. The old order fails with the restrictive endpoint-to-agent foreign key. **Paperclip version or commit** This prerequisite includes merged #17554 at `94a780286f` and supports #17557. Only four cleanup-owned paths differ from that landed parent. Related #16465 covers the deletion feature flag, not dependency order. ## What Changed - Add a chat-owned company-deletion participant using the existing transaction contract. - Remove only the requested company's endpoints before issue deletion and the agent lifecycle participant. - Preserve namespace tombstones and existing restrictive foreign keys. - Add real PostgreSQL regressions for ordering, isolation, and rollback. - Migrate a validated disposable external database before fixture use, use the shared PostgreSQL bootstrap budget for setup, and remove fixture-owned Discord tombstones during test teardown. ## Verification Published head: `9766cc61c42fe0f73e241bbe99f9d9f145f4b11c`. Parent #17554 is merged. This branch reconciles the actual landed health squash `94a780286f` and targets master. Fresh reviews and CI are required for this exact head. - The latest review requested the repository's shared EMBEDDED_POSTGRES_TEST_TIMEOUT_MS (90 seconds) for bootstrap. This replaces the earlier suggested 30-second limit. All six existing cases pass on another initially empty database with that constant; no test assertion or production code changes. The documented contention budget is repository evidence, not a locally reproduced 40-second bootstrap failure. - All six complete cleanup-removal service cases pass on an initially empty dedicated PostgreSQL 17 database with the updated health parent. - The pre-fix real endpoint-deletion case failed with missing-table errors because external fixture setup skipped migrations. Applying pending migrations before client use fixes that failure; no assertion is removed or weakened. - An independent query after the complete suite finds zero fixture ownership tombstones. Production company deletion still preserves those records. - Cases cover endpoint removal before issue and agent references, other-company isolation, namespace ownership preservation, and rollback after a later failure. Both product regressions failed before the original ordering fix. - Server typecheck and build pass with the updated parent and fixture repair at `21be75d2b0`. The landed-parent reconciliation changes only the lockfile; all source and test bytes remain identical. All six cases pass again with the new installed dependency patch. The initial scope-proof command raced a shared `origin/master` update; a new proof pins the actual landed parent and confirms the four-file scope. A later native-checkpoint merge `09ad9adce2` has no overlap with these four files. - [Owning acceptance document](https://github.com/paperclipai/paperclip/blob/9766cc61c42fe0f73e241bbe99f9d9f145f4b11c/doc/company-chat-deletion.md#current-parent-acceptance-october-27) retains the failing baseline, parent scope, and limitations. No full local repository-suite or deployed suspension claim is made. Older inherited gateway/combined-stack evidence is separate from this four-file fix. ## Risks - The endpoint cleanup shares the caller's transaction. A later deletion failure must restore the endpoint; the regression verifies that boundary. - Existing retained voice-history restrictions and external provider teardown policy remain unchanged. This fix does not bypass restrictive foreign keys. - No migrations, lockfile changes, or workflow edits. ## Model Used OpenAI Codex, GPT-6 family, with repository inspection, code edits, and tool-assisted tests. The exact runtime variant 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 linked existing issues or described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id - [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>
3.7 KiB
Company deletion with chat endpoints
Company deletion must remove chat endpoints before deleting their referenced issues or assigned agents. The endpoint-to-agent foreign key uses RESTRICT, so waiting for the final company cascade fails while deleting agents. This was reproduced by the Discord scheduling producer test and by the owning company-removal suite.
The chat owner participates in the existing company-deletion transaction. It removes only the requested company's endpoint rows before issue deletion and before the agent lifecycle participant runs. Existing endpoint foreign keys remove their dependent records. The lifecycle owner still requires completed agent termination. The transaction still rolls back all SQL cleanup if a later participant fails. No external calls, new scheduler, schema change, or relaxed constraint is introduced.
Discord command ownership tombstones have no cascading foreign keys and remain unchanged. Deletion does not authorize a new endpoint to adopt an old application. Other retained-history constraints, including voice-session restrictions, still apply; this fix does not bypass them or change external provider teardown policy.
Both new PostgreSQL regressions failed before the change. All six cleanup-removal cases pass afterward, including deletion ordering, another company's untouched endpoint, preserved namespace ownership, and rollback after a later failure. The suite accepts a validated dedicated external PostgreSQL test database because embedded PostgreSQL cannot start on this host. Server typecheck/build and remote CI/review are tracked separately; this is not evidence of deployed host sleep.
Review expanded the fixture to include a conversation and publication linked to an issue. Both regressions then failed because cleanup ran after issue deletion. The chat participant now runs immediately after the company row is locked, before any referenced issue or agent is removed. The same transaction preserves history on rollback. This supplements the original endpoint-only proof; it does not claim to remove existing voice-session restrictions.
Current-parent acceptance, October 27
This slice normally integrates health parent #17554 at
8c1d293d1ae2b7db753ab20f5a2a2edec1fb0a62. Only the four company-cleanup
files differ from that parent; no database, workflow, or provider change is added.
The parent must land before this prerequisite can merge into master.
The remaining Ponytail finding reproduced on an initially empty dedicated PostgreSQL 17 database: the real endpoint-deletion case and its cleanup failed with missing-table errors. The external fixture now applies pending migrations before creating its client and uses the shared 90-second embedded-bootstrap setup budget. The six complete cleanup-removal cases pass on that same initially empty database. Test teardown also deletes the ownership tombstones it creates; an independent query after the complete suite finds zero rows. This fixture cleanup does not change the production rule that company deletion preserves those tombstones.
The failed fresh-database run remains part of the evidence. Server typecheck and build pass with this repair. Fresh current-head CI/reviews remain separate gates. No full local repository-suite or deployed suspension claim is made.
The final review identified that the previously suggested 30-second setup limit was below the repository's documented bootstrap budget under runner contention. The fixture now imports and uses EMBEDDED_POSTGRES_TEST_TIMEOUT_MS. It changes no assertion or production behavior. The earlier fresh-database failure and six-case acceptance remain recorded; the shared timeout addresses documented setup cost, not a reproduced production defect or a claim of measured CI contention here.