Skip to content

feat(approvals): ADR-0042 SLA auto-escalation + ADR-0041 trigger-* landing - #1749

Merged
os-zhuang merged 1 commit into
mainfrom
feat-approvals-sla-escalation-adr-0041-0042
Jun 12, 2026
Merged

feat(approvals): ADR-0042 SLA auto-escalation + ADR-0041 trigger-* landing#1749
os-zhuang merged 1 commit into
mainfrom
feat-approvals-sla-escalation-adr-0041-0042

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Summary

Closes#1742. Two ADRs land together with their implementations.

ADR-0042 — SLA auto-escalation (docs/adr/0042-approval-sla-escalation.md)

  • plugin-approvals owns a jobs-backed scanner (per ADR-0041's boundary: a plugin clock is a job, not a trigger): interval job approvals-sla-escalation (5 min default) + a catch-up sweep at kernel:ready — the job service starts after this plugin, which the first live run caught.
  • Single-shot idempotency: the escalate audit row is the marker, written audit-first. Crash between audit and mutation degrades to "logged but not executed" — never a double machine decision; concurrent decisions are additionally guarded by decide()'s pending check.
  • Actions: notify (default), reassignescalateTo, auto_approve/auto_reject as reserved actor system:sla — the timeline always shows escalate + the decision row, so policy decisions are visibly machine-made. Clock = created_at + timeoutHours, no request_info pause in v1 (future option recorded).

ADR-0041 mechanical landing

  • plugin-trigger-record-change / plugin-trigger-schedule@objectstack/trigger-record-change / @objectstack/trigger-schedule (serve's nameMatch already accepted both spellings).
  • ActionDescriptor.maturity ('ga' | 'beta' | 'reserved', default ga) so Studio can grey out contract-ahead-of-runtime surfaces.

Test plan

  • plugin-approvals: 60 tests (5 new: notify audience + single-shot, auto_approve resumes flow as system:sla, auto_reject, reassign replaces approver set, not-due/no-SLA skip) ✅
  • spec: 6528 ✅ · trigger-record-change 17 ✅ · trigger-schedule 17 ✅ · CLI builds ✅
  • Live e2e on showcase (boot catch-up sweep): three overdue requests escalated — auto_approve → status approved with timeline submit → escalate(system:sla, "auto_approve") → approve(system:sla); reassign → approver set replaced by ada@example.com; notify → escalate audited, request stays pending. Renamed trigger-record-change verified live (budget PATCH still opens requests). Console renders "SLA 升级 · 系统(SLA)" with a red timeline dot (companion objectui PR).

🤖 Generated with Claude Code

…anding
SLA escalation (ADR-0042, closes#1742): plugin-approvals owns a
jobs-backed scanner — interval job 'approvals-sla-escalation' (5 min
default, escalationScanIntervalMs option) plus a catch-up sweep at
kernel:ready (the job service starts after this plugin, so wiring
defers to the ready hook). Each overdue pending request escalates AT
MOST ONCE: the 'escalate' audit row is the idempotency marker, written
audit-first, so a crash between audit and mutation degrades to
"logged but not executed" rather than a double machine decision.
Actions: notify (default; approvers + escalateTo), reassign (replace
approver set with escalateTo), auto_approve / auto_reject via decide()
as the reserved actor 'system:sla' — the timeline always shows two
rows (escalate, then the decision) so policy decisions are
distinguishable from human ones. The clock is created_at +
escalation.timeoutHours with no request_info pause in v1 (recorded as
a future option in the ADR).
ADR-0041 mechanical landing: plugin-trigger-record-change and
plugin-trigger-schedule drop the plugin- prefix and become the
trigger-* family (@objectstack/trigger-record-change,
@objectstack/trigger-schedule); serve's nameMatch already accepted
both spellings. ActionDescriptor gains maturity ('ga'|'beta'|
'reserved', default ga) so designers can grey out
contract-ahead-of-runtime surfaces instead of letting authors build
on them.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercelBot commented Jun 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specErrorErrorJun 12, 2026 2:48am

Request Review

@os-zhuang
os-zhuang merged commit 29efff4 into mainJun 12, 2026
1 of 2 checks passed
@os-zhuang
os-zhuang deleted the feat-approvals-sla-escalation-adr-0041-0042 branch June 12, 2026 02:44
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation dependencies Pull requests that update a dependency file tests tooling size/xl labels Jun 12, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependenciesPull requests that update a dependency filedocumentationImprovements or additions to documentationsize/xlteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(approvals): SLA auto-escalation — scheduler pass executing escalation.action

1 participant

@os-zhuang