Skip to content

fix(spec): stop teaching the retired ETL layer as a live retry surface in flow.zod.ts (#6630, part 2) - #6753

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-6630-part2-flow-etl-prose
Aug 8, 2026
Merged

fix(spec): stop teaching the retired ETL layer as a live retry surface in flow.zod.ts (#6630, part 2)#6753
os-project-manager merged 1 commit into
mainfrom
claude/issue-6630-part2-flow-etl-prose

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes #6630

Part 2 of 2 — the closing half. Part 1 is PR #6701 (shared/retry-policy.zod.ts + conversions/registry.ts), which deliberately carried no Fixes line so the issue stayed open for this one; see the claim-amendment comment for the split and the part-2 claim for the re-anchored line numbers. automation/flow.zod.ts was inside #5593's in-flight surface when part 1 ran; #5593 has merged (PR #6595), so the file is released.

What was wrong

#6414 retired the whole L2 ETL layer — automation/etl.zod.ts, 9 defs / 27 exported names, with the export absence pinned in automation/sync-retirement.test.ts. ETLPipeline.retry was one of the four surfaces that carried the converged RetryPolicySchema contract. Three sentences in automation/flow.zod.ts still said it was one of four.

What changed

Three prose sites, one file, text only. Re-verified on origin/main @ 61282f906 before editing — the audit's anchors (:665/:745/:752) had drifted; the real ones are below.

Site Was Now
:640 errorHandling TSDoc "shared with job.retryPolicy, a try_catch node's retry and an ETL pipeline's retry" shared with the two that survive; ETL "did the same until #6414 retired the L2 ETL layer"
:720 "a key added to the policy lands on all four surfaces at once" all three surfaces
:727 "the flow surface has a reading the other three do not" the other two

The arithmetic is measured, not assumed: retryPolicyShape() / RetryPolicySchema have exactly three consumers on mainsystem/job.zod.ts:141 (job.retryPolicy), automation/control-flow.zod.ts:318 (a try_catch node's retry) and automation/flow.zod.ts:722 (flow.errorHandling, the spread). system/worker.zod.ts's TaskRetryPolicySchema is a separate declaration and was never part of this count.

Wording matches part 1's landed choices, which was the point of splitting rather than forking: enumerations name only surviving surfaces, the retired mention becomes explicitly historical in part 1's own words ("did the same until #6414 retired the L2 ETL layer" — the exact sentence part 1 put on RetryPolicySchema's TSDoc), counts corrected in place. Two files in one package correcting the same defect two different ways would have been its own small drift.

Zero acceptance-surface bytes. No schema key, bound, default, .describe() or retiredKey() guidance string is touched. check:authorable-surface is green with no baseline edit.

Out of scope, untouched: everything else in flow.zod.ts; both files part 1 already fixed; content/docs/releases/.

Mechanism assumptions — both verified, both held

The dispatch flagged two predictions and asked for them to be falsified if wrong. This time neither was.

1. Zero regen (predicted; held — unlike part 1). Part 1 falsified the same prediction because a retiredKey() .describe() reached two reference pages. Nothing here is a render input: :640 is a TSDoc block and :720/:727 are // comments. Measured rather than argued —

✓ All 10 generated artifacts are up to date.
  ✓ check:docs                 content/docs/references/**
  ✓ check:api-surface          api-surface/
  ✓ check:authorable-surface   authorable-surface/ + authorable-defaults/ + JSON schemas

check:api-surface reads the built dist, so packages/spec was built first — before that it fails as "stale" in any fresh worktree, which is a phantom, not a finding. The .d.ts carries none of the changed text (only the bundled .js does, as a preserved comment), which is why the API surface is byte-identical.

2. A pin asserting the four-surface arithmetic or the ETL mention (predicted possible; none exists). Swept, including the file the dispatch named specifically. automation/flow.test.ts:1578 matches the prescription'was removed in @objectstack/spec 17.0.0', 'backoffMs', 'flow.errorHandling' — never the enumeration or the count, exactly as part 1 measured for the rest of this family. automation/sync-retirement.test.ts:152 asserts export absence of ETL and is unaffected. Nothing needed flipping.

Why this PR adds no pin

Asked explicitly by the dispatch, so answering explicitly.

Nothing in this diff is runtime-observable. flow.errorHandling emits the tombstone by spreading retryPolicyShape(), so the only string a test can reach through FlowSchema is the very string part 1 already pinned in both directions in shared/retry-policy.test.ts (every live surface named / no retired surface named / prescription intact). A second assertion on that same string reached via FlowSchema would pin the spread, not the enumeration — and flow.test.ts:1578 already pins the spread.

The remaining two sites are // comments. Pinning those means asserting source text. That idiom does exist in this package (shared/expression-dialect-docs.pin.test.ts, ui/notification.test.ts), so this is a choice and not an impossibility — but a general "a retirement updated some mentions and not others" detector is precisely the gate idea the PM split out as #6635 and asked not to be re-bundled. A one-off readFileSync regex over flow.zod.ts would stake out that design in the wrong place.

Honest consequence, stated rather than dressed up: reverse verification has no red direction here. Restoring the old sentences turns nothing red, because no assertion reads comment text — which is not a gap this PR left, it is the measurement that motivates #6635.

Changeset: none — the skip-changeset route

Deliberate, decided from what the diff contains. Part 1 carried @objectstack/spec: patch and justified it precisely: "the tombstone guidance is author-visible, so it is a release-noted change rather than a docs-only one." That justification does not transfer. Every byte here is a comment: it reaches no reference page (check:docs green), no .d.ts and no published type surface (check:api-surface green), no error message and no parse. There is nothing for a release note to tell a consumer.

Per the dispatch, the label is the PM's to apply at acceptance; this PR does not apply it.

Verification

  • pnpm --filter @objectstack/spec test345 files / 8844 tests passed (8844 is main's count; part 1 adds the 8845th)
  • pnpm --filter @objectstack/spec typecheck — green: tsc --noEmit, check:scripts-typecheck, check:test-typecheck (58 files / 267 errors held, ledger unchanged)
  • pnpm --filter @objectstack/spec check:generated10/10 artifacts up to date, nothing regenerated, nothing committed
  • Every gate in the ESLint job, enumerated one by one from .github/workflows/lint.yml33/33 pass, including pnpm lint, check:nul-bytes, check:doc-authoring, check:docs-audit-scope, check:release-notes, check:engine-double-contract, check:route-envelope, check:error-code-casing, check:spec-parsed-alias
  • Byte discipline: node scripts/check-nul-bytes.mjs OK over 6258 tracked files, plus a direct grep -naP control-byte scan of the changed file — no hits

Filed, not fixed

Filed as #6750: content/docs/automation/flows.mdx:977 is a hand-written guide page (not generated — content/docs/references/** is the generated tree) that inherited the same sentence and still teaches an ETL pipeline's retry as a live surface, plus content/docs/data-modeling/formulas.mdx:52, which names both retired layers (ETL, sync) as cron consumers. #6630 explicitly scopes content/docs/** out as the docs seat's surface, so both are filed rather than slipped in here. A third hit, content/docs/protocol/knowledge.mdx:49, is the generic industry term and is not a defect.


Generated by Claude Code

…e in flow.zod.ts (#6630, part 2)

Part 2 of 2 for #6630, closing out the three `automation/flow.zod.ts` prose
sites that part 1 (PR #6701) deferred while the file was inside #5593's
in-flight surface.

#6414 retired the whole L2 ETL layer, so `ETLPipeline.retry` is no longer one
of the surfaces that carry the converged `RetryPolicySchema` contract. Three
places in this file still said it was:

- the `errorHandling` TSDoc enumerated it as a live sibling of
  `job.retryPolicy` and a `try_catch` node's `retry`;
- "a key added to the policy lands on all four surfaces at once" — three;
- "the flow surface has a reading the other three do not" — the other two.

Text only. No schema key, bound, default, `.describe()` or `retiredKey()`
guidance string changes, so nothing regenerates: all 10 of spec's generated
artifacts stay green, including `check:docs` and `check:api-surface`.

Wording matches part 1's landed choices — enumerations name only surviving
surfaces, the retired mention becomes explicitly historical ("did the same
until #6414 retired the L2 ETL layer"), counts corrected in place.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018ffcE95NaMJcL9XJ9VDYgk
@vercel

vercel Bot commented Aug 8, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 8, 2026 2:14pm

Request Review

@github-actions github-actions Bot added the size/s label Aug 8, 2026
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec.

112 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via @objectstack/spec)
  • content/docs/automation/connectors.mdx (via @objectstack/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via @objectstack/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/cli.mdx (via @objectstack/spec)
  • content/docs/deployment/tenancy-modes.mdx (via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via @objectstack/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/data-service.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/examples.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via @objectstack/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/spec)
  • content/docs/permissions/authorization.mdx (via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/rls.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/http-protocol.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx (via @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v16.mdx (via @objectstack/spec)
  • content/docs/releases/v17.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)
  • content/docs/ui/actions.mdx (via @objectstack/spec)
  • content/docs/ui/apps.mdx (via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/spec)
  • content/docs/ui/field-grouping-and-order.mdx (via @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/spec)
  • content/docs/ui/translations.mdx (via @objectstack/spec)
  • content/docs/ui/views.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@os-project-manager os-project-manager added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 8, 2026 — with Claude
@os-project-manager
os-project-manager marked this pull request as ready for review August 8, 2026 17:27
@os-project-manager
os-project-manager added this pull request to the merge queue Aug 8, 2026
Merged via the queue into main with commit 32cb5ad Aug 8, 2026
31 of 32 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-6630-part2-flow-etl-prose branch August 8, 2026 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants