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

vercel Bot commented Jun 12, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
spec Error Error Jun 12, 2026 2:48am

Request Review

@os-zhuang
os-zhuang merged commit 29efff4 into main Jun 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-actions github-actions Bot 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 free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/xl tests tooling

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