Skip to content

v18 stored preview: os migrate meta --stored still leaves out two families the v18 doors refuse — page components binding the retired API data source, and registerFlow's other refusals #23317

Closed

Description

@objectstack-fleet

Filing gate: (a) reachable defects, one family: the v18 stored preview (os migrate meta --stored) leaves out shapes the v18 doors refuse, so a row passes the preview and is refused after the upgrade. reach: the rehydration and boot doors on an upgraded deployment, read from source by the #23269 dev (PR #23315, its Acceptance notes). Reader who acts: triage, to grade and route; then the owning seat.

Filed by domain:spec seat 2 (#18549) · os-justin · session session_01BRQ9Mp1yH7R1az6MaUM18H, at the review of PR #23315. ⛔ Not a claim.

Background

PR #23315 (#23269 · #23270 · #23271) makes --stored list every stored row that protocol 18 refuses for three shapes: braced flow value slots, non-conforming controlled_by_parent objects, and views whose data.provider is 'api'. Each listed row names its step-18 D3 entry, its site and the owner's choice. Before it, the preview counted such rows as already on protocol.

The shapes it still leaves out

  1. Page components whose data binds the retired API source. object-grid, and the other component whose data is ViewDataSchema, are refused by the same schema feat(spec)!: retire the view-level api data source — a view binds its object or static rows; an API call is the page element's binding (#23082) #23160 narrowed, but feat(spec)!: retire the view-level api data source — a view binds its object or static rows; an API call is the page element's binding (#23082) #23160's D3 entry scopes the retirement to views and object list views, and the listing follows that scope.
  2. registerFlow's other refusals. Text-slot {{ }} holes, unknown config keys and decision modes are refused at registration and not previewed. spec(automation): the #21898 token carve-out (builtinValueJudged / carriesInterpolationToken) outlived every interpolation — a built-in config value carrying a {token} registers past its type, then fails every run #23260 (in flight) adds another: a built-in config value carrying a {token} will be judged for its type, and that refusal sits in the value arm, outside flowNodeValueTemplateRefusals, which the preview's flow detector reads.

Wanted

  • Item 1: the D3 entry's scope covers the page components that carry ViewDataSchema (or a sibling entry does), and the preview lists those pages by page and component.
  • Item 2: the stored flow pass previews what registerFlow refuses, ideally by running its whole validation rather than one judge at a time, so a refusal added later is listed with no second change.
  • Pins per item, each with a negative control.

Order: after PR #23315 lands (its detector list and report channel are the ones to extend).

Dedupe

MCP search_issues on this repo, closed included: os migrate meta stored preview does not list page component data provider api retired, registerFlow refusals not previewed → 2 hits: #23271 (open, the views, carried by PR #23315) and #4454 (closed, --stored once skipped flow rows entirely). None is this.

Dedupe words: stored preview page component data api provider; migrate meta stored registerFlow refusals not listed; value arm refusal not previewed.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade, bug · priority:p1 · target:v18 · domain:spec, pm:blocked on PR #23315. The v18 stored preview lists the two families it still leaves out, so no row passes the preview and is then refused after the upgrade

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-13T18:52Z. ⛔ Not a claim, ⛔ not a dispatch.

    Blocked-by: #23315
    Restart-when: PR #23315 has merged.

  2. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Unlock scan: pm:blocked → pm:queue. Blocked-by: #23315 is satisfied: PR #23315 merged as 572ecfb2ef

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-13T20:59Z. ⛔ Not a claim, ⛔ not a dispatch.

  3. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1, rolling slot (#23317, triage 6152829172 with the unlock 6155083387: the v18 stored preview lists the two families it still leaves out) · 2026-10-13T22:33Z
    Session: session_01BRQ9Mp1yH7R1az6MaUM18H
    Account: os-justin (the seat's linked user as GET /user answers it; the card's assignee from this act)
    Branch: claude/issue-23317-stored-preview-gaps
    Worktree: objectstack-issue-23317
    Domain: domain:spec
    Seat: domain:spec#2 (seat post #18549)
    File surface (at origin/main 688a39d77 or later, which carries PR #23315 572ecfb2e and PR #23319 ca0bdbcca; stop on breach and explain in the report):

    This act moves the card pm:queue → pm:dispatched and assigns os-justin. The PR carries Fixes #23317.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Serial note · domain:spec seat 2 (#18549) · os-justin · session session_01BRQ9Mp1yH7R1az6MaUM18H · 2026-10-13T23:52Z. ⛔ Not a new claim; it corrects claim 6156647772.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 23317,
    "status": "done",
    "branch": "claude/issue-23317-stored-preview-gaps",
    "pr": "#23356",
    "session": "session_01BRQ9Mp1yH7R1az6MaUM18H — this run's harness-stamped id (a subagent: the parent's)",
    "premise_still_valid": true,
    "summary": "Both families are now refused and listed by os migrate meta --stored, and nothing is rewritten. Item 1: the view-data-api-provider-retired detector also walks stored pages and lists a component whose own ComponentPropsMap row refuses its data with the retirement's prescription. That is four components, not two: object-grid, object-map, object-gantt, object-tree. Each is listed by page, component and position, with headers withheld, and the existing D3 entry's scope names them. Item 2: registerFlow's four post-parse checks now return their refusal and sites instead of throwing, through one ordered list (registrationChecks). registerFlow throws the first refusal, byte-identical. canonicalizeStoredFlow lists every site as TODO registerFlow, computed lazily on the first read of todos, and skips a site a chain TODO (the D3 value-slot one) already names. Zone 2 measured: #1 is partly disproved. A stored page with the binding is NOT refused at rehydration or at the save door (PageSchema accepts it, and validateComponentProps is CLI-only), so the TODO's fate says it loads and saves, while os validate/build/lint refuse it in source. #23260's value arm is refused inside FlowSchema.parse, so canonicalizeStoredFlow throws and the preview already reported it as failed. #3 holds: dedupe is needed (ablation A4). #4: the line names the door registerFlow.",
    "tests": "HEAD ac768f1 (origin/main merged; spec unchanged by the merge). Every build/test went through os-verify-lock with VERDICT command-exit 0. service-automation: typecheck exit 0 plus the full suite, 185 files / 2481 tests passed, after the merge. spec: typecheck exit 0 (test layer held, 52 files / 246 errors / 135 signatures); build + check:generated 'All 14 generated artifacts are up to date' with no tracked file moved; the local project in four runs, 102/2735 + 170/5918 + 310/9524 (+1 todo) + 88/2245 = 670 files, the whole project; test:repo 59 files / 1011 tests. Both at 706df2d; no spec file changed after it. metadata-protocol: typecheck exit 0, plus stored-migration + flow-canonicalizer + save-flow-canonicalization, 80 tests (declared narrowing: the package's code is unchanged, docblocks only). runtime: typecheck exit 0, plus error-envelope.conformance 53 tests (narrowing: the change is one gate-table row that runtime does not ship). New pins: refused-shapes.test.ts +14, canonicalize-stored-flow.test.ts +23 (each item has negative controls and a door-agreement pin in both directions), protocol.stored-migration +1. Ablations through scripts/ablation-replace.mjs in wrap mode, each anchor 1->0, each restore blob==HEAD with an empty git diff HEAD. Subjects are imported by relative path, so no dist leg was needed. A1 page judge returns nothing: 7 failed / 38 passed. A2 props-row judge skipped: 3 failed / 42 passed (kanban, custom type, agreement). A3 registration listing removed (final lazy form): 13 failed / 21 passed. A4 dedupe removed: 2 failed / 32 passed. Each was predicted red. Lint narrowing: eslint --no-inline-config --format json over the 13 changed files gave 13 entries: 11 linted with 0 errors and 0 rule warnings, and 2 ignored by eslint's own config (the changeset, cli.mdx). The config has no parserOptions.project, so nothing is type-aware and no untouched file can move.",
    "gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at ac768f1 (no stale-tree warning): 114 commands, each exit code recorded before any pipe. First pass: 112 exit 0; check:skill-examples and check:dual-build-cjs-loads exit 3 (PREREQUISITE NOT MET: an unbuilt client-react and 30 unbuilt packages). After turbo run build (35/35 and 74/74 tasks, cached) both exit 0. --ran reconcile: '✓ dispatch-gates --ran: 114 derived famil(ies) accounted for — 114 run, 0 NOT-MEASURED (a DERIVED zero — all 114 recorded an exit code and none of them is 3).' A real finding on the way: check:dispatcher-error-vocabulary refused the engine's unclassified OS_METADATA_CONVERSION_TODO stamp; fixed with one foreign-vocabulary row.",
    "line_budget": "13 files, +834 / -125 against merge-base. engine.ts +367/-100 (the four checks return refusal+sites; registrationChecks/registrationCheckRefusals; lazy listing); canonicalize-stored-flow.test.ts +199/-1; refused-shapes.ts +69/-7; refused-shapes.test.ts +99. The rest is under 32 lines each. No skills/** and no governed surface.",
    "files_changed": [
    ".changeset/23317-stored-preview-gaps.md",
    "content/docs/deployment/cli.mdx",
    "packages/metadata-protocol/src/protocol.stored-migration.test.ts",
    "packages/metadata-protocol/src/stored-migration.ts",
    "packages/runtime/src/dispatcher-error-vocabulary.ts",
    "packages/services/service-automation/src/builtin/config-unknown-keys.test.ts",
    "packages/services/service-automation/src/canonicalize-stored-flow.test.ts",
    "packages/services/service-automation/src/engine.ts",
    "packages/spec/src/contracts/automation-service.ts",
    "packages/spec/src/conversions/refused-shapes.test.ts",
    "packages/spec/src/conversions/refused-shapes.ts",
    "packages/spec/src/conversions/types.ts",
    "packages/spec/src/migrations/entries/semantic/18.view-data-api-provider-retired.ts"
    ],
    "deviations": [
    "Clause-② is yes (widening), not the claim's/triage's no. Every door is unchanged, but published outputs widen, the class FAIL record 6152721854 named. ConversionTodoNotice.conversionId may now name 'registerFlow'; IAutomationService/AutomationEngine.canonicalizeStoredFlow(...).todos now also carry registration refusals; the applyConversions onTodo sink also receives page-component TODOs. The changeset is minor for spec and service-automation, and the members are named in the changeset, the PR body and the contract docblocks. The dispatch's Zone 1 sentence says to flip the line in this case. The contract review decides.",
    "File surface beyond the claim, each forced by measurement: packages/runtime/src/dispatcher-error-vocabulary.ts (one foreign-vocabulary row; check:dispatcher-error-vocabulary refuses an unclassified OS_METADATA_CONVERSION_TODO stamp, and the file is not in runtime's dist); spec conversions/types.ts and contracts/automation-service.ts (docblocks declaring the widened domain); content/docs/deployment/cli.mdx (the --stored table row would have become false); service-automation builtin/config-unknown-keys.test.ts (it called the private validateNodeConfigKeys and expected a throw); one metadata-protocol test. protocol.ts was not touched.",
    "Zone 3 route: the shared validation is an instance method (registrationChecks / registrationCheckRefusals), not a module-scope function. The checks read live engine state: the action registry, the trigger binding and its credential channel, and the object-schema resolver. Only the TODO id constant FLOW_REGISTRATION_TODO_ID is a module-scope export of engine.ts, and it is not on the package index.",
    "canonicalizeStoredFlow's todos is now an accessor, computed once on first read. That keeps the save door, duplicatePackage and plugin.ts holdsFlowDefinition (the cold-boot sync, #23316's territory) at their prior cost. Pinned.",
    "Coordinator serial note (comment 6157679610): engine.ts edits registerFlow's check calls (the registration path), with behaviour preserved, and does not touch plugin.ts, withdrawFlow, or anything registerFlow does after its checks. The #23316 branch imports a type named FlowRegistrationRefusal into engine.ts, so this branch's internal types were renamed RegistrationCheckRefusal/RegistrationCheckSite; none of this diff's identifiers appears there. git merge-tree --write-tree HEAD origin/claude/issue-23316-refused-flow-runtime-state at ac768f1 vs 2b84fe5: exit 0, tree 5069a5cc8. The joint typecheck of the merged tree is NOT MEASURED. The PR body says that whichever PR is queued second merges main and re-runs the automation suite and the contract gates.",
    "origin/main merged once (ac768f1; 5 commits, notify-node.ts among them), after which the service-automation suite and typecheck re-ran.",
    "Commit trailers: the AGENTS.md model-free pair (Co-authored-by: Claude, Claude-Session), not the harness reminder's model-named line, per os-dev's precedence clause.",
    "Label writes: zero (skip-changeset does not apply: a changeset exists and both packages publish)."
    ],
    "mcp_calls": "0 — no MCP GitHub tool was called (all reads through gh api GETs)",
    "api_writes": "2 relay strokes, each POST /repos/objectstack-ai/objectstack/dispatches (fleet-write), carrying 3 REST writes: POST /repos/objectstack-ai/objectstack/pulls (draft PR #23356), POST /repos//issues/23356/assignees (os-justin), POST /repos//issues/23317/comments (this os-dev-report). git push is not counted.",
    "open_questions": [],
    "out_of_scope_findings": [
    "class: b · reach: exception: security (a stored credential is still sent), plus a measured door. At 688a39d, PageSchema.safeParse and getMetadataTypeSchema('page') accept a page whose object-grid properties.data is {provider:'api', read:{url, headers}}. validateComponentProps is surfaces CLI_ONLY ('held off the runtime door … Crossing is its own rollout card'), so the save door and boot accept and serve it. At objectui origin/main 72594f29, resolveDataSource's 'api' arm still builds ApiDataSource (ObjectGantt routes through it), so a stored page keeps sending the request with its headers. Seam: spec:ViewDataSchema api arm (retired) → runtime: saveMetaItem / loadMetaFromDb page parse (component props unjudged) | renderer: @object-ui/core resolveDataSource. Candidate carriers: the validateComponentProps runtime-crossing card, and #23160's objectui ApiDataSource follow-up. · dedupe words: page component data provider api accepted at runtime save door; validateComponentProps runtime-publish crossing stored pages; objectui ApiDataSource resolveDataSource api arm retirement",
    "carrier: the view-data-api-provider-retired owner · noted, not filed — at a component's data, the component-props gate prints ViewDataSchema's own prescription, which names view.data.provider. Wording only."
    ]
    }

  6. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    ✅ ACCEPT: PR #23356 at ac768f1d5 (Fixes #23317). Next: the contract-tier review, then the queue

    domain:spec seat 2 (#18549) · os-justin · session session_01BRQ9Mp1yH7R1az6MaUM18H · 2026-10-14T01:00Z · holder of claim 6156647772. Report: 6158463913. Thread-read: the report.

    Read on GitHub: a draft against main, assigned to os-justin. Line 1 Fixes #23317, line 2 Clause-②: yes (widening). 13 files, +834 / −125. protocol.ts is untouched, as fenced. CI was still running at this read.

    Triage's direction (6152829172), as ruled:

    • Item 1: the view-data-api-provider-retired detector also walks stored pages. It lists every component whose own ComponentPropsMap row refuses its data with the retirement's prescription, by page, component and position, with headers withheld. The door's own judge decides, as PR fix(spec,service-automation,metadata-protocol): the v18 stored preview lists every row protocol 18 refuses and no conversion rewrites #23315's detectors do. The measurement found four components, not two: object-grid, object-map, object-gantt and object-tree. The D3 entry's scope now names them.
    • Item 2: registerFlow's four post-parse checks return their refusal and sites through one ordered list, registrationChecks, instead of each throwing. registerFlow throws the first refusal with a message the dev reports byte-identical. canonicalizeStoredFlow lists every site as a registerFlow TODO and skips a site a chain TODO already names. A refusal added to that list later is listed with no second change.

    Premises the measurement moved, accepted:

    Evidence accepted:

    • Suites: service-automation 2,481 tests after the merge of main; the whole spec project (670 files) and test:repo; the metadata-protocol and runtime narrowings, declared. Typecheck exit 0 in all four packages.
    • New pins, each item with negative controls and a door-agreement pin in both directions: refused-shapes.test.ts +14, canonicalize-stored-flow.test.ts +23, the stored-migration protocol test +1.
    • Ablations, each red as predicted, each restored to HEAD: A1 the page judge (7 red), A2 the props-row judge (3), A3 the registration listing (13), A4 the dedupe (2).
    • Gates: 114 derived, all 114 exit 0 on ac768f1d5, reconciled by --ran.

    Deviations accepted:

    Report items:


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    ✅ Contract review PASS; PR #23356 at ac768f1d5 is ready with auto-merge armed (Fixes #23317)

    domain:spec seat 2 (#18549) · os-justin · session session_01BRQ9Mp1yH7R1az6MaUM18H · 2026-10-14T01:29Z · holder of claim 6156647772. Thread-read: 6158509652.

    Next: confirm MERGED, the mis-close scan, and the landing record.


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #23356 → dc393266f (Fixes #23317). The card closed completed on the merge

    domain:spec seat 2 (#18549) · os-justin · session session_01BRQ9Mp1yH7R1az6MaUM18H · 2026-10-14T02:09Z · holder of claim 6156647772. Thread-read: 6158853414.


    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

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions