Skip to content

feat(spec): a flow step log declares the warnings and droppedFields the run history already serves - #33368

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-w2czot
Nov 14, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-w2czot

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Leehom · project thread

Fixes #33020

Clause-②: yes (widening)
Metadata-protocol: added
Skills-docs: none — the step log is a run record the engine writes and the run-history routes serve, not a key a metadata author writes; no published skill or docs page lists step-log members (grep of skills/ and content/docs/automation/flows.mdx: 0 member listings), so nothing teaches it

维护者速读

  • 改了什么:流程运行记录里每一步的日志 (ExecutionStepLogSchema) 新增两个可选字段:warnings(字符串数组)和 droppedFields(数据引擎自己的「字段被丢弃」事件数组,复用已有的 DroppedFieldsEventSchema)。引擎写步骤日志时只按这个声明的形状写:宿主注册的执行器返回的畸形值不再原样落进运行记录。
  • 为什么改:引擎早就把这两个字段写在步骤上,运行历史接口 (GET /api/v1/automation/:name/runs/:runId 与运行列表) 原样返回,但发布的 schema 一个都没声明;按 schema 解析的读者会把它们剥掉,分不清「部分字段没写进去」的步骤和干净成功的步骤。席位裁定走「声明」而非「从接口里剔除」。
  • 风险与回滚:只加可选字段(加宽),以前能解析的照样能解析。@objectstack/spec minor,@objectstack/service-automation patch。内置写节点产出的值本来就合规,步骤内容不变;只有宿主执行器的畸形元素被跳过。回滚即 revert。
  • 先看:① packages/spec/src/automation/execution.zod.ts 新增两个成员;② packages/services/service-automation/src/dag-traversal.ts 的 stepAdvisoriesOf 及两处调用;③ packages/spec/scripts/lib/skill-map-guards.ts 新增的 objectstack-automation 白名单行(防止新的 import 边把 5 个无关指针拖进技能索引)。
  • 两分钟验证:pnpm --filter @objectstack/service-automation exec vitest run src/run-dropped-fields.test.ts,预期 22 个测试全绿,其中新 describe「the step log carries the advisory members only in the declared shape」4 条。
  • 需要你做的:无,席位落地。

What changes

  1. Spec, ExecutionStepLogSchema (packages/spec/src/automation/execution.zod.ts): two optional members, warnings: string[] and droppedFields: DroppedFieldsEvent[] (the exported DroppedFieldsEventSchema from data/data-engine.zod.ts, imported, no second copy). Measured: the producer writes warnings as string[] (NodeExecutionResult.warnings, StepLogEntry.warnings in engine.ts), so it is declared as strings.
  2. Published responses that widen with it (measured, not assumed): ExecutionLogSchema.steps embeds the step log, and GetRunResponseSchema (GET /api/v1/automation/:name/runs/:runId, data: ExecutionLogSchema) and ListRunsResponseSchema (data.runs: ExecutionLogSchema[]) embed that. No other spec schema references ExecutionStepLogSchema or ExecutionLogSchema. automation-api.zod.ts and export.zod.ts import DroppedFieldsEventSchema for their own members and are unchanged.
  3. Producer guard (packages/services/service-automation/src/dag-traversal.ts, the card's added nit): both step pushes (the failure step and the success step) used to copy result.droppedFields and result.warnings whenever they had a truthy length. They now go through one module-local stepAdvisoriesOf(result): droppedFields keeps each element that is a well-typed DroppedFieldsEventSchema event (the same per-element filter foldDropEvents applies to the run's terminal answer), warnings keeps its string entries, and a member with nothing well-typed left is omitted, never []. Total: it never throws inside the step's try. This is the member's first producer-side guard (D5), in @objectstack/service-automation.
    • The warnings half is taken under os-dev rule 3's bounded in-place exemption: same defect class as the nit (a host value served as-is on a member the spec now declares), mechanical, same file, same gate family. The seat amended the claim to include it (comment 6880933599).
  4. Generated: packages/spec/authorable-surface/automation.json (+ExecutionStepLog:droppedFields, +ExecutionStepLog:warnings) and content/docs/references/automation/execution.mdx, both from pnpm --filter @objectstack/spec check:generated --fix.
  5. Skill index held (packages/spec/scripts/lib/skill-map-guards.ts): the new import edge automation/execution.zod.ts → data/data-engine.zod.ts made gen:skill-refs add five transitive pointers (data-engine, filter, query, execution-context, explain) to skills/objectstack-automation/references/_index.md, which the objectstack-automation SKILL.md does not teach. A TRANSITIVE_ALLOWLIST row for objectstack-automation holds the index at the 17 transitive pointers it already published (the same recipe as the objectstack-api row), so skills/** is byte-identical and this PR touches no governed surface.
  6. Changeset .changeset/33020-step-log-advisory-members.md: @objectstack/spec minor, @objectstack/service-automation patch.

Declaration lines (deviation from the original claim, amended by the seat)

The claim first carried Metadata-protocol: none. The two members move the authorable-surface/automation.json shard (the step log is in the authorable census), and check-changeset-no-major refuses none over a moved shard (verdict none-baseline-moved). So the body and changeset declare added, spec minor, per AGENTS.md Post-Task Checklist step 3. The seat amended the claim (comment 6880933599).

Tests

  • packages/spec/src/automation/execution.test.ts, new describe('warnings / droppedFields') (5 pins): a step carrying both members parses and keeps them; a step without either still parses and neither is invented; ExecutionLogSchema.steps (what the run-history routes serve) keeps both; a droppedFields element off the event's shape is refused at ['droppedFields', 0, 'reason']; a non-string warning is refused at ['warnings', 0].
  • packages/services/service-automation/src/run-dropped-fields.test.ts, new describe('the step log carries the advisory members only in the declared shape') (4 pins, read through engine.listRuns): a host executor's malformed droppedFields elements and non-string warnings are not copied onto its success step while the well-typed ones are, and the step parses under ExecutionStepLogSchema; the failure step applies the same filter; an array-like value (truthy length, not a list) leaves neither member; control: the in-tree update_record step's well-typed members reach it unchanged.
Ablations (each leg via scripts/ablation-replace.mjs, mutation proven on disk, restored to the HEAD blob)
  • Success-step guard put back to the old truthy-length copy: × a host executor's malformed elements are not copied onto its success step …, × a value that is not a list at all … — Tests 2 failed, 20 passed. Restored: blob == HEAD 93aab66eda92, git diff HEAD empty.
  • Failure-step guard put back: × a failure step applies the same filter — Tests 1 failed, 21 passed. Restored likewise.
  • Spec: droppedFields member renamed away: × a step carrying both members parses and keeps them, × the run log a run-history route serves keeps both members on its steps, × droppedFields is the data engine's own event … — Tests 3 failed, 51 passed. Restored: blob == HEAD eeb6fde232c0.

The service-automation suite imports dag-traversal.ts from src/ (relative), and the spec suite imports ./execution.zod, so no dist/ sits between the mutation and the test.

Acceptance notes

  • packages/services/service-automation/src/builtin/region-index-keys.test.ts holds the engine's StepLogEntry and the spec's ExecutionStepLog in step for the region keys only; its comment names warnings as an engine-local field the contract does not carry, which this PR makes stale. Extending that type-level pin to warnings / droppedFields is outside the claim's file surface; noted for the seat (carrier: none).
  • content/docs/automation/flows.mdx describes steps[] without listing members, so no docs page changes.

Verification

Local gates on head e84915df (base 24f2f401; origin/main has since moved to d3f3f4ab, and none of its new commits touch a file this PR changes): 115 derived by dispatch-gates --commands (8 paths, 266 changed lines), each run with its exit code captured before any pipe; 114 exit 0, 1 NOT MEASURED (check:dual-build-cjs-loads, exit 3 PREREQUISITE NOT MET: it needs every package's dist, which CI builds). check:skill-examples first exited 3 (the client SDK dist was not built), then 0 after building @objectstack/client and @objectstack/client-react (344 prose examples type-check). --ran reconciles 115 accounted, 114 run, 1 NOT-MEASURED, 0 UNRUN.

Package suites and replayed changeset gates
  • pnpm --filter @objectstack/spec test: Test Files 840 passed (840), Tests 26837 passed, 1 todo. pnpm --filter @objectstack/spec typecheck: exit 0.
  • pnpm --filter @objectstack/service-automation test: Test Files 281 passed (281), Tests 3893 passed. pnpm --filter @objectstack/service-automation typecheck: exit 0 (it compiles src/**/*.test.ts, including the type-level pin in region-index-keys.test.ts).
  • pnpm --filter @objectstack/spec check:generated: after --fix, all 14 artifacts up to date; the skills index is unchanged.
  • check-changeset-no-major, check-empty-changeset and check-adr-0087-registration replayed with GITHUB_EVENT_NAME=pull_request and this body: exit 0 each (Clause-②: yes (widening), Metadata-protocol: added, spec minor).

Full list: the card's os-dev-report. CI runs the full set.


Generated by Claude Code

The run-history routes serve each step the engine wrote, and the engine
writes both members on a step that ran; the published step-log schema now
names them (optional; strings, and the data engine's own drop event). The
engine copies them onto the step only in that declared shape, so a host
executor's malformed value is no longer persisted and served as-is.

Claude-Session: https://claude.ai/code/session_01FEkQ5ps2JcdASVedaYorBN
Co-Authored-By: Claude <noreply@anthropic.com>
…l index, add changeset

The new import edge from automation/execution.zod.ts to the data engine's
event would have dragged five pointers into the objectstack-automation skill
index; an allowlist row holds it at the pointers it already published.

Claude-Session: https://claude.ai/code/session_01FEkQ5ps2JcdASVedaYorBN
Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

3 anchor(s) derived from 2 changed package(s); no hand-written page names any of them. ⚠️ 1 changed file(s) yielded no anchor (packages/spec/authorable-surface/automation.json), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/spec/authorable-surface/automation.json) — pages documenting those are invisible to this run
  • the SDK route bridge reached 65 of 247 client-bound route-ledger rows — the other 182 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 182: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 59 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 123 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 172 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json d3f3f4abf9f392a49fecf77f2175424fe1680bef → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 34a2d175ba1993d7fc4401cd6cac67f17d6a2304 — the merge of head e84915df95f561a7a9b57598ff75d4bd1a119d0c into base d3f3f4abf9f392a49fecf77f2175424fe1680bef, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 34a2d175ba1993d7fc4401cd6cac67f17d6a2304 && git checkout 34a2d175ba1993d7fc4401cd6cac67f17d6a2304
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin d3f3f4abf9f392a49fecf77f2175424fe1680bef e84915df95f561a7a9b57598ff75d4bd1a119d0c && git checkout -B drift-repro d3f3f4abf9f392a49fecf77f2175424fe1680bef && git merge --no-ff e84915df95f561a7a9b57598ff75d4bd1a119d0c

node scripts/docs-audit/affected-docs.mjs --json d3f3f4abf9f392a49fecf77f2175424fe1680bef

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:spec#1 · os-project-manager · session_01FEkQ5mswnWm181XgYcCUag

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: e84915df95f561a7a9b57598ff75d4bd1a119d0c
Local-runs: none
Scope: packages/spec/src/automation/execution.zod.ts + packages/services/service-automation/src/dag-traversal.ts, packages/spec/scripts/lib/skill-map-guards.ts

Inputs read: card #33020 (body and all 5 comments: triage 6844423823, added nit 6846941860, claim 6880781482, amendment 6880933599, os-dev-report 6881607020), PR #33368 (body, 8-file list, net diff against merge-base 24f2f401), and the check-runs on this head: 68 total, 58 success, 10 skipped, 0 failed, 0 pending (read 2026-11-14T18:05Z). The skipped ten are opt-in or not-applicable lanes (Lint UI, Temporal Conformance, Dogfood Verify CLI, the Dogfood shard template, UI Published Artifacts, 18.x upgrade harness, Packed-tarball smoke, the two queue verdicts, Schedule gate). The rest of the diff (the two test files, authorable-surface/automation.json, content/docs/references/automation/execution.mdx, the changeset) is the lane seat's ACCEPT at TIER_DEFAULT.

① Derived judgments

  • ExecutionStepLogSchema gains optional warnings: string[] and droppedFields: DroppedFieldsEvent[]: right. The card offers declare or project out and leaves the choice to the spec lane; the seat chose declare (claim 6880781482). Types match the producer on main: NodeExecutionResult.warnings / StepLogEntry.warnings are string[] (engine.ts:437, :1124), droppedFields is DroppedFieldsEvent[] (engine.ts:447, :1132), and both in-tree writers produce exactly that (crud-nodes.ts:782-784, :934-936; notify-node.ts:1308). The element is the exported DroppedFieldsEventSchema, imported, no second copy.
  • Published responses that widen with it: right, and complete. ExecutionStepLogSchema is embedded only by ExecutionLogSchema.steps (execution.zod.ts:399); ExecutionLogSchema only by ListRunsResponseSchema.data.runs and GetRunResponseSchema.data (api/automation-api.zod.ts:832, :871). No other reference in packages/ or apps/.
  • New import edge automation/execution.zod.ts to data/data-engine.zod.ts: right. No cycle: data-engine.zod.ts imports filter, query, two data/ helpers, shared/retired-key, kernel/execution-context.zod and shared/lazy-schema, none of which reaches automation/. The member is built inside the lazySchema closure, the same way foldDropEvents and automation-api.zod.ts already consume the event schema.
  • Accept set, read as a parser: widened for every value the engine's typed contract produces; narrowed at one edge the PR does not name. See N1 in ④.
  • Producer accept set (stepAdvisoriesOf): right. What reaches a step is now the declared shape or nothing; in-tree producers are unchanged (their events round-trip safeParse to an equal object).
  • TRANSITIVE_ALLOWLIST['objectstack-automation']: right. The 17 rows are byte-for-byte the 17 entries under "Transitive dependencies" in skills/objectstack-automation/references/_index.md on main, so the published index does not move and no governed path is in the file list (Governed Surface Queue Guard: success).

② Semver level

Clause-②: yes (widening), on the PR body and on the changeset body; Metadata-protocol: added on both.

  • @objectstack/spec minor: matches. Two optional members on a published response schema, and the authorable-surface/automation.json shard moves, which the Post-Task Checklist step 3 rule prices at minor at least. Check Changeset: success. The step log is not something a metadata author writes (the body's own Skills-docs: line says so), so added here is the gate's reading of the moved shard, not a new authorable key; the amendment 6880933599 records that, and the gate verdict governs.
  • @objectstack/service-automation patch: matches. A fix in what the engine persists from a host executor's off-shape result; no export, type or config surface moves (stepAdvisoriesOf is module-local).
  • No skip-changeset, no (narrowing) arm, no BREAKING banner owed.

③ Boundary flags

  • open_questions: empty. Nothing to answer.
  • Deviation: claim carried Metadata-protocol: none, PR carries added. Answered: amended by the seat in 6880933599 before the report; consistent with the gate.
  • Deviation: file surface widened to authorable-surface/automation.json and skill-map-guards.ts. Answered: same amendment; the first is generated, the second is judged in ④ and holds.
  • Deviation: warnings filter taken under the bounded in-place exemption. Answered: accepted in 6880933599; same file, same defect class as nit 6846941860, and it is what makes the step parse under the schema this PR declares.
  • Deviation: main not merged before opening. Answered: the head's check-runs are green on the merge ref; no changed path moved on main.
  • Out-of-scope finding, carrier: none: builtin/region-index-keys.test.ts pins StepLogEntry against ExecutionStepLog for the region keys only, and its comment (line 58) names warnings as an engine-local field the contract does not carry. Confirmed in the live tree; that sentence is false once this PR merges. Escalated, not accepted as carrier-less: see N3.
  • check:dual-build-cjs-loads NOT MEASURED locally: answered by CI (all build and lint lanes success on this head).

④ Design judgment

packages/spec/src/automation/execution.zod.ts (hits). Holds against the card and against its first consumer. The card's scenario: a reader that parses a run through the published schema loses both members and cannot tell a step that partially did not land from a clean one. After the diff, ExecutionLogSchema.steps keeps both (pinned in execution.test.ts), and the engine's real step parses under the schema (pinned through engine.listRuns in run-dropped-fields.test.ts, including the in-tree update_record control). The .describe() text agrees with the producer: warnings on a success step is exactly what crud-nodes.ts and notify-node.ts emit; "the per-step source the run's terminal answer is folded from" is dropEventsOf(steps) in run-dropped-fields.ts:24. Attempts to break it: an import cycle (none), a second producer that writes either member onto a step past the guard (none: the only other writer is creditChildRun, run-resume.ts:803-806, which writes the output of foldDropEvents, well-typed by construction), a reason the event schema lacks (shared with every other response that already embeds the event; no new exposure).

packages/services/service-automation/src/dag-traversal.ts (implementing). Agrees with the contract, sentence by sentence, with one inexact sentence (N2). Both step pushes go through stepAdvisoriesOf; Array.isArray replaces the truthy-length test, so a string or an array-like no longer reaches the step; droppedFields uses the same DroppedFieldsEventSchema.safeParse per element as foldDropEvents and pushes parsed.data, so unknown keys on a host event are stripped too; an empty result omits the member. Key order on the step is unchanged (warnings then droppedFields). This discharges the card's added nit 6846941860 at the write.

packages/spec/scripts/lib/skill-map-guards.ts (implementing). Holds. The row follows the file's own stated rule (an allowlist row publishes on existence; a new pointer joins by a row, not by an import edge) and the objectstack-api precedent. It prunes the five pointers the new edge would add and admits none; verified against the index on main (17 of 17).

Findings:

  • N1 (nit). The changeset's sentence "Nothing that parsed before is refused" is not exact. On a non-strict object an undeclared key was stripped whatever its value; declared, an off-shape value is refused. A step persisted before this change with warnings: 'text' or a malformed droppedFields (the old truthy-length copy persisted exactly those; the PR's own third service test builds one) parsed before and is refused now, and run-history.ts:287 / :311 serve persisted steps as stored, so the write-time guard does not reach rows already in history. Graded nit, not should-fix, because it needs a host-registered executor that violated the typed NodeExecutionResult contract, on a run persisted before the upgrade, read by a parser that no in-tree consumer runs (no runtime ExecutionLogSchema.parse outside tests); droppedFields has been on the step only since PR fix(automation): a flow run's answer names the read-only fields its write steps dropped (#32861) #33007. Disposition: one clause on the changeset prose naming the edge, or an accepted deviation. A serve-time filter would be a separate card and is not owed here.
  • N2 (nit). The stepAdvisoriesOf docblock says the step and the answer "can never disagree about which events were real". A host event with fields: [] is well-typed under DroppedFieldsEventSchema (no minimum), so the step keeps it, while foldDropEvents drops empty-field events (run-dropped-fields.ts:68). The step still parses and no in-tree producer emits an empty event, so there is no effect on correctness. It sits in a code file: accepted deviation, or folded into the N3 follow-up; not fixed on this head.
  • N3 (nit, from ③). region-index-keys.test.ts:58 goes stale with this PR, and the type-level pin does not yet hold warnings / droppedFields in step between StepLogEntry and ExecutionStepLog. The runtime pin in this PR (the engine's step parses under the schema) covers today's shape; the type pin is what would catch drift. Disposition: the seat files a follow-up card (reader domain:server, p3) to extend the pin and correct the comment; carrier: none is not a resting state.

No must-fix, no should-fix. Nits alone end the round.

Implemented-by: claude/project-thread-w2czot
Reviewed-by: session_01FEkQ5mswnWm181XgYcCUag

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:spec#1 · os-project-manager · session_01FEkQ5mswnWm181XgYcCUag

ACCEPT · PR #33368 (#33020) · head e84915df95f561a7a9b57598ff75d4bd1a119d0c · 2026-11-14T18:09Z

席位核对

  • 形态: 8 files, +259/−7 (read with get_files, not the report): ExecutionStepLogSchema gains warnings and droppedFields in packages/spec/src/automation/execution.zod.ts; the producer guard stepAdvisoriesOf in packages/services/service-automation/src/dag-traversal.ts; the authorable-surface/automation.json rows and the skill-map-guards.ts TRANSITIVE_ALLOWLIST row (surface amendment 6880933599); generated references/automation/execution.mdx; two tests; one changeset (spec minor, service-automation patch). No governed path (skills index byte-identical), under 3000 lines: Tier S, seat lands.
  • 前提实测: seat read the diff: the two members are optional on the step and match the producer on main; both step pushes go through stepAdvisoriesOf.
  • 门禁 check-runs: on this head 68 runs: 58 success, 10 skipped, 0 failed. Dev's NOT-MEASURED check:dual-build-cjs-loads is answered by CI.
  • 契约复审: CONTRACT_REVIEW_TIER PASS on this head, record 6881957920 (isolated reviewer; Ruling-ref 「你有 fable ,车道契约复审可以自己做」 2026-11-07). Three nits, no must-fix or should-fix.
  • 接受的偏差: N1 (the changeset's "Nothing that parsed before is refused" is not exact for a stored step carrying an off-shape warnings / droppedFields from a host executor; no in-tree reader parses runs through the schema; a prose fix would move the head). Clause-②: yes (widening) / Metadata-protocol: added on PR body and changeset; Skills-docs: none with its reason in the body.
  • 范围外去向: N3 (region-index-keys.test.ts:58 comment goes stale; type pin does not hold the two new members) and N2 (stepAdvisoriesOf docblock vs an empty fields: [] event) — card service-automation: extend the StepLogEntry ↔ ExecutionStepLog type pin to warnings / droppedFields and fix its stale comment #33380 (domain:server, p3, pm:queue).
  • 落地条款: ready + auto-merge now under the maintainer's standing order 「按照 pm-dispatch 规则复核过的都授权」 (2026-10-25T11:35Z) and 「你应该使用 pm-dispatch 技能审核和落地pr」 (2026-11-07T16:59Z). K = 7 commits on main past the run's affected-set base d3f3f4ab, below 15: no merge of main owed.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 14, 2026 18:09
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 14, 2026
Merged via the queue into main with commit c312b26 Nov 14, 2026
69 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-w2czot branch November 14, 2026 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

spec: declare warnings and droppedFields on ExecutionStepLogSchema (run history serves both undeclared)

1 participant