fix(server): schedule Teams consent expiry from saved deadlines

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-25 06:01:32 -05:00
1 parent 9a06e4a6ba
commit 5ddb4543ed
12 files changed
+457 -68

No files matched your search

+61
View File
@@ -0,0 +1,61 @@
# Teams consent expiry and idle work
Unused Teams file consent now uses the shared delivery coordinator and scheduler.
Existing `chat_teams_file_transfers` rows own its state. There is no new table,
independent timer, provider request or external-wake capability.
## Obligation and trigger
Only `consent_pending`, `awaiting_consent` and `upload_pending` rows are eligible.
Each uses its saved `expiresAt`. Startup reconstructs these rows in 100-row UUID
pages. Committed writes reload the affected transfer ID. The service registers
intent before insertion and its central versioned update, within the existing
transaction. Nested savepoints wait for outer settlement. The shared work-signals
protocol retains ambiguous outcomes; callers do not manage recovery wrappers.
Configured endpoints, completed history, unknown outcomes and active transport
attempts do not keep this worker scanning. Pending consent retains its actual
future deadline. PostgreSQL submillisecond timestamps round up to the next
millisecond; checking a deadline does not extend it.
## Expiry and recovery
At the deadline, the worker reloads the current row and delegates to the existing
Teams protocol owner. That owner locks publication then transfer, verifies the
current authority digest, rechecks phase and expiry, and updates the transfer
and publication projection in the same transaction. It does not send a consent
card, upload data or send a file-info card. Lock waits remain bounded. A changed
phase is re-evaluated; a deleted or settled row removes the cached obligation.
A failed load, lock or projection retains retry work. Corrupt rows do not starve
other transfers or companies. Errors emitted by this worker are generic and do
not contain SQL parameters, private transfer envelopes or provider capabilities.
The shared worker owns coalescing, batching, dirty hints, drain/resume and shutdown.
Shutdown joins an in-flight expiry; restart reconstructs the saved deadline.
The explicit `expireAndRecover` diagnostic method retains combined behavior.
Production periodic maintenance now selects and executes abandoned attempts only.
Attempt recovery is a separate remaining migration. Unknown provider outcomes
remain quarantined; this change does not authorize a resend.
## Ownership and limitations
Provider phase selection and expiry live in the Teams module and existing Teams
transfer service. Shared app wiring only registers the owner and lifecycle gate.
The queue topic is a notification namespace, not a new durable queue. Other
providers and the shared scheduler receive no Teams protocol policy.
Supported producers use the process's owning DB client. Independent SQL writers
or another process require their own wake contract. On-use authorization remains
with the protocol. Cloud eligibility and external alarm coverage are unchanged:
a future in-process deadline cannot wake stopped compute. This proves the changed
worker can become quiet, not fleet savings or complete instance suspension.
## Verification
Real PostgreSQL protocol cases cover all three phases, producer activation,
rollback and held outer commit, restart, pre-deadline quiet, timestamp precision,
projection rollback, fairness, drain/resume and shutdown. Production integration
registers the worker before Board publication and proves expiry cancels the
publication without another provider call. Existing authority, publication and
consent suites remain covered. See the [audit and failure ledger](plans/2026-10-25-teams-consent-expiry-sleep-audit.md).
@@ -1358,3 +1358,16 @@ cleanup and retention workers had 37 passing cases. CI/reviews remain required.
Next owner audit splits Teams unused-consent expiry from abandoned send/upload
attempt recovery, preserving one reason per PR. Company deletion cleanup policy
and the earlier E2E failure remain unresolved completion duties.
## Slice 26: Teams unused-consent expiry
The Teams owner now selects existing unused-consent phases and their saved expiry
through scoped deadline work. Production maintenance retains only abandoned
attempts; these are the next distinct reason. No new table or Cloud alarm policy
is included. The [audit](2026-10-25-teams-consent-expiry-sleep-audit.md) records
222 unique selected passing cases, workspace types/build, and initial fixture
failures. Publication and fresh remote checks/review remain required.
Parent #17586 Actions/security/Greptile pass at 250fca6cff; Paperclip Review is
still running. The original full inventory, older E2E failure, deletion-policy
finding and master reconciliation remain outstanding. No stack PR is merged.
@@ -2,7 +2,7 @@
Baseline: voice call-report PR #17586 at 250fca6cff.
Branch: codex/sleep-26-teams-consent-expiry.
Status: audit; implementation, local acceptance, publication and remote gates pending.
Status: implemented and locally verified; publication and remote gates pending.
## Separate reasons
@@ -68,3 +68,54 @@ cannot expire consent. Full stack checks and master reconciliation remain requir
#17586 is published, attached, and locally verified; remote CI/reviews are pending.
#17580's company deletion policy finding and #17490's E2E cancellation failure are
still unresolved. No original recurring-server obligation is removed from scope.
## Implementation and acceptance
The Teams owner now registers a scoped deadline worker. The existing service
signals before issue/update writes, including caller-owned resolution transactions.
Startup pages eligible rows; transfer hints reload only that primary key. The
owner rechecks expiry with the original publication/transfer lock order and
atomic projection. The old periodic selection and execution now cover attempts
only. No schema or external wake contract changes are included.
Local verification at the slice-26 implementation:
- 65 transfer protocol cases pass on a fresh external PostgreSQL database.
These include 102-entry paging/fairness with one corrupt row, shutdown joining
a held projection, the three consent phases, precision, rollback, restart,
drain/resume, private-error redaction and the remaining maintenance boundary.
- The earlier five-suite run passed 206 cases: then-63 transfer cases and 143
publication, consent, consent-runtime and app-wiring cases. The final transfer
run adds two cases. The latest app-wiring assertions pass all 16 cases again.
- 14 selected real production integration cases pass. This includes registration
before an actual Board publication, post-commit wake, saved deadline, pre-expiry
SQL quiet, atomic expiry/publication cancellation, no extra provider requests,
and the existing Teams current-authority/Board-transfer group. The other 1,411
integration cases were skipped, not passed.
- Together these are 222 unique selected cases. Workspace `pnpm -r typecheck`
and `pnpm build` pass. Server typechecking excludes test files; it is not proof
that the test files were statically checked.
- Local full `pnpm test:run` remains unclaimed because this host's embedded
PostgreSQL setup failed earlier in the stack. Full remote gates are required.
No live Teams tenant or deployed host-suspension qualification is claimed.
Failure ledger: the first protocol run had two invalid fixtures. A direct phase
mutation set attempt expiry without its required paired attempt ID; another
assertion treated the public ISO expiry string as a Date. Both were corrected,
then all five suites passed on a fresh database. The first production expiry
assertion expected a failed publication; the existing correct expiry projection
is cancelled. The corrected test and the authority group pass. These were test
expectation/setup errors, not weakened production contracts or hidden retries.
Evidence logs: `/tmp/sleep26-teams-tests.log` (initial two fixture failures),
`/tmp/sleep26-teams-fixed-tests.log` (206 pass),
`/tmp/sleep26-teams-final-tests.log` (65 pass),
`/tmp/sleep26-producer-tests.log` (initial projection-state assertion),
`/tmp/sleep26-production-acceptance.log` (14 pass),
`/tmp/sleep26-final-wiring.log` (16 pass), and
`/tmp/sleep26-workspace-{types,build}.log` (pass).
Parent #17586 at 250fca6cff has passing Actions, security and Greptile checks;
Paperclip Review is still running at the latest inspection. This does not clear
older stack findings or imply merge authority. Refreshed master is b7dc594bfa;
final whole-stack reconciliation is still required.