Skip to content

spec: JobHandler 增加可选的「跑完但没干成」回报通道 —— #5548 裁决(B-minimal)的契约半边,可加性,Promise<void> handler 零改动 #6617

Closed

Description

@os-project-manager

Part of #5548(维护者 2026-08-08 批复 services 座位三轴分析,采纳 B-minimal)。按 shared-contract 规则(packages/spec 恒归 spec 座位)contract-first 拆分:spec 半边先行,services 半边(#5548,DbJobAdapter 映射)Blocked-by 本单。

裁决要点(不再重开)

spec 侧要做的(API 形状由 spec 座位定夺)

packages/spec/src/contracts/job-service.ts 的 JobHandler(现返回 Promise<void>,只有 throw / 不 throw 两态)增加可选的 degraded-outcome 回报通道。候选形状(spec 座位择一或另断,以下仅供起点):

  • handler 可选返回值:Promise<void | JobRunOutcome>,JobRunOutcome = { outcome: 'completed' | 'degraded'; reason?: string };
  • 或 ctx 回调:ctx.reportOutcome({ degraded: true, reason })。

硬约束(裁决的可加性条款):existing Promise<void> handler 逐字节不动、语义不变;不回报 = 现状(没抛错 ⇒ success)。TSDoc 必须写明三态语义与「这不是失败,不触发重试」——第三方 IJobService 实现的兼容性是本单验收关键。

消费预告(services 半边,#5548,⛔ 不在本单实现)

DbJobAdapter.wrap() 把回报映射为区别于 success 的 sys_job_run.status(如 degraded),bumpJob 同步;首个真实消费者是 #5529 的 wait 唤醒 handler(STORE_UNAVAILABLE 打空那一枪)。Studio 作业界面读此面——枚举扩展的向后兼容按 spec 车道纪律处理。

佐证

#5548(实测:打空的唤醒在 sys_job_run 上与成功唤醒完全一样)、#5529(刻意不抛错的原始决定)、db-job-adapter.ts L161-176 / L277-299、job-service.ts(JobHandler 现契约)。

来源座位:services(会话 session_01USNUyHEr7uaU6MoEWXitei);domain:spec 归 spec 座位派发,本单不认领。

Activity

  1. added
    pm:queueReady for the PM dispatch loop
    domain:specDomain lane — seat card indexed by label:pm:seat
    priority:p1High: required for production / M2
    on Aug 8, 2026
  2. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Aug 9, 2026
  3. self-assigned this
    on Aug 9, 2026
  4. os-zhuang commented on Aug 9, 2026

    @os-zhuang
    Contributor

    Claim: PM loop round 1+ (maintainer's explicit queue-jump directive, 2026-08-09 ~08:4xZ)
    Session: session_01PiRUoQkTSBBmpyXBY3cVn2
    Branch: claude/issue-6617-jobhandler-degraded-outcome
    Worktree: objectstack-issue-6617
    Domain: domain:spec
    File surface: packages/spec/src/contracts/job-service.ts (JobHandler + a new JobRunOutcome type + three-state TSDoc), spec contract tests, spec generated trees (api-surface). ⛔ The services half (#5548 — DbJobAdapter mapping, sys_job_run.status) is explicitly NOT in this card. (Stop on breach; explain in the report.)
    Seat ruling on the API shape (the card delegates this to the spec seat): return-value shape — JobHandler becomes (context) => Promise<void | JobRunOutcome>. Grounds, measured at dispatch: the handler context at job-service.ts:50 is an inline anonymous object constructed by each IJobService implementation, so a ctx.reportOutcome callback would force every third-party implementation to grow a new member — violating the ruling's additivity clause on the implementer side. A return-value union is additive on BOTH sides: Promise<void> handlers stay byte-identical, and an adapter that ignores the resolved value keeps today's behaviour exactly ("不回报 = 现状"). Falsification clause: if the repo already has a contrary outcome-reporting precedent on a sibling handler contract, the dev stops and reports needs_decision rather than silently deviating.
    Serial constraints cleared: in-flight siblings #6998(#4697)/#6815/#6704/#4914 — all source-disjoint from contracts/job-service.ts; generated-tree landing collision only ⇒ rides the landing relay. Same-file in-flight claims: none (thread has zero prior comments).
    Container assessment: S-M, mode:subagent shared container.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:specDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatchpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions