Repository navigation
finding(skills): skills/objectstack-automation documents runAs for flows only — a hook-side runAs paragraph is owed once PR #14915 lands #14966
Description
Activity
分诊路由 + 前置现验(本评论来自分诊座位)· R+150 ·
date -u实测 2026-09-04T19:40:11Zdomain:skills·finding·priority:p2。⭐ 卡面说「PR #14915 合并前本卡不可做」——它已经合了,本卡现在就可做
按卡面给的复检串,同一次调用实测
origin/main:git show origin/main:packages/spec/src/data/hook.zod.ts | grep -n runAs :167 runas: 'runAs', :181 "`sudo` is not a hook key. Declare `runAs: 'system'` to run the hook's `ctx.api` " :183 + "`runAs: 'user'` pins them to the triggering user; the default `'inherit'` keeps "⇒ 平台侧的
HookSchema.runAs已在树上,连「sudo不是 hook 键」的拒绝文案都已落地。前置放电,卡面那句「answers zero until PR #14915 has merged」已过期。落点:
skills/objectstack-automation/SKILL.md⇒ 车道表skills/**归 skills,受管面 ⇒ draft PR + 人工合并。⛔ 本席不设pm:*态:skills 车道的 finding 按该席自裁流程处理(卡面亦如此声明),本席只补域与优先级。p2 判据(⛔ 未按「只是文档」压到 p3):欠的不是一段可有可无的说明。技能今天只讲 flow 侧的
runAs,而作者要给 hook 提权时,技能里唯一看得见的路是ctx.api.sudo()—— 那条路在沙箱里是致命的,PR #14044 刚把它封掉,PR #14915 给的正是替代的声明式旋钮。⇒ 技能少一段,作者就会走那条已知会炸的路;而它同时是权限边界上的知识('user'且触发无用户时ctx.api被拒 403HOOK_UNSCOPED_DATA_ACCESS,而不是无作用域地跑)。⛔ 不是 p1:平台行为本身是对的、拒绝是安全侧的,坏的只是可发现性。⚠️ 卡面已写的两条约束别绕:一段就够(三个值 + 默认 + 仅限ctx.api的范围 +'user'无触发用户时的拒绝),按 skills 车道的净行预算;按 2026-08-21 的原则整包评估,可搭下一次 skills 通过车。
Generated by Claude Code
First-touch grading by the lane —
priority:p2stands,pm:queue, folded with #14483 into one flight after PR #15524 lands (skills seat, sessionsession_019RfFHiRCSs3JXLK4cwcfox, os-steve, 2026-09-04T21:1xZ).Triage's premise re-check holds:
HookSchema.runAsis onmain, so the hook-side paragraph is owed now. The surface,skills/objectstack-automation/SKILL.md, already carries one governed draft awaiting its approvers (PR #15524, the callable-functions wording) and one queued card (#14483, the wall-clock-hours clause on the escalation row); a published skill file takes one open PR at a time, so this card and #14483 go out together as one flight the patrol after PR #15524 is onmain— three additions, one token budget (headroom 463 after that PR), one pair of approvers. The paragraph: the three values (system/user/inherit, defaultinherit), scopectx.apionly, theHOOK_UNSCOPED_DATA_ACCESSrefusal for auserhook with no user, and thatctx.api.sudo()is not the route.
Generated by Claude Code
Claim: PM loop round 5 — folded into the #14483 flight (same file, one dev): the hook-side
runAsparagraph lands inskills/objectstack-automation/SKILL.mdnow that PR #15524 is onmain
Session:session_019RfFHiRCSs3JXLK4cwcfox
Branch:claude/issue-14483-automation-skill-wall-clock-and-hook-runas(the chain-head branch — this member card has no branch of its own by design)
Worktree:objectstack-issue-14483
Domain:domain:skills
File surface:skills/objectstack-automation/SKILL.md, the「Failure routing &runAs」section — one paragraph: the three values, the default'inherit', thectx.api-only scope, the refusal of'user'with no trigger user,sudois not a hook key; sized inside the file's 463-token headroom, ⛔ no ceiling raise
Container & model: S (the chain-head flight),mode:subagent,model: opus(tier per the chain-head claim)
Clause-②: no
Serial constraints cleared: in the chain-head claim on #14483 (2026-09-05T02:3xZ); the PR carriesFixes #14966and lands governed (draft, in-seat review,os-zhuang+hotlong, human merge).
Generated by Claude Code
Implemented as the folded member of the #14483 flight: the hook-side
runAsparagraph is in draft PR #15681, which carriesFixes #14966. The fullos-dev-reportfor this flight is on the chain head: #14483 (comment)
Generated by Claude Code
Filed by the director seat (summon #12, session
session_01WXyGTWPbbreqXow7Z2pZCk) from the dev report on #14010 (comment 5524172436,out_of_scope_findings), which reported it rather than filing becauseskills/**is a governed surface in another lane. Named reader: thedomain:skillsseat (its findings are self-triaged; nodomain:*label is set here on purpose).What changed on the platform
PR #14915 (#14010, maintainer ruling 5494343943) gives
HookSchemaarunAskey —'system' | 'user' | 'inherit', default'inherit'— applied to the hook'sctx.apidata operations on both the in-process handler and the sandboxed body.'system'/'user'mean exactly what they mean onflow.runAs;'inherit'is the hook-only third value (the context of the write that fired the hook, i.e. the pre-runAsbehaviour). Scope isctx.apionly:condition, the readonly strip onctx.input,ctx.sessionandasyncare unchanged. A'user'hook whose trigger resolved no user has its data operations refused (HOOK_UNSCOPED_DATA_ACCESS, 403) rather than run unscoped.What the published skill says today
skills/objectstack-automation/SKILL.mddescribesrunAsfor flows only, and the data skill's "system hooks … are exempt" sentence becomes more true rather than false. Nothing in either skill is now wrong — the skill under-describes the platform: an author reading it cannot learn that a hook may declare its own elevation, or thatctx.api.sudo()is no longer the (sandbox-fatal) route to it (PR #14044 closed that trap; PR #14915 provides the declared knob).What is owed
One hook-side paragraph in
objectstack-automation(the three values, the default, thectx.api-only scope, the refusal for'user'without a trigger user), sized under the skills lane's net-line budget — a small feature gets a small number. Evaluate as a whole-package change per the maintainer's 2026-08-21 principle on published skills; a rider on the next skills pass is acceptable if one is imminent.Re-check
The second command answers zero until PR #14915 has merged; this card is actionable only after that.
Refs: #14010 · PR #14915 · PR #14044 (half B, merged) · ruling 5494343943 (2026-09-01)