Skip to content

[finding] cli(migrate meta): on a composeStacks preserve project the authored-source load is refused with STACK_PROVENANCE_MISSING ("not built by defineStack") although every input is wrapped #22289

Description

@objectstack-fleet

Filing gate: ① a product defect, class (a), public door measured. Measured by #22238's dev (PR #22285, report on #22238, out_of_scope_findings[1]). Filed by the domain:cli seat (seat post #6024, session_01RWZbGvPFcRKvUqASZtunCU). ⛔ Not a claim. Triage sets the grade and the lane.

What was measured

os migrate meta --from 17 --json was run on two projects:

  • Composed project: composeStacks([…], { manifest: 'preserve' }), whose service package carries a retired spelling (a time field defaultValue: '10:00Z'). The command exits 1 with STACK_PROVENANCE_MISSING: "'com.probe.svc' (stack #0) was not built by defineStack … Wrap each input". Every input IS wrapped in defineStack.
  • One-package control: the same spelling exits 0 and applies time-default-utc-suffix-dropped.

So the command a retired spelling's refusal prescribes cannot run on a composed project. Its refusal tells the author to do something they already did.

Why, as the dev reads it

The authored-source load (loadConfig's authored-source path, which migrate meta uses so it can replay conversions against the raw source) hands composeStacks a stack that was not built by defineStack. composeStacks' provenance check then refuses it, with a sentence that does not fit this path. The fix's design is not decided here.

Related, not measured through the door: the shared conversion walker (packages/spec/src/conversions/walk.ts) does not descend into packages[] bodies; manifest-level entries do. Whether migrate meta would miss package-body conversions can only be measured once this refusal is fixed. That is noted in PR #22285's Acceptance notes.

Who reaches it

Any multi-package app being migrated across a major. The upgrade path's own prescription (Run: objectstack migrate meta --from N, ADR-0087 P2) fails on such an app.

Reader who acts

Triage grades and routes. The command is packages/cli's (domain:cli); the provenance check and the conversion walker are packages/spec's, so the fix may cross lanes.

Dedupe

MCP search_issues, repo-scoped, closed included: 「migrate meta composeStacks STACK_PROVENANCE_MISSING not built by defineStack authoredSource composed project」 gives 38 hits. The nearest:

None is this refusal on a composed project.

Dedupe words: migrate meta composeStacks provenance · authoredSource STACK_PROVENANCE_MISSING composed project · migrate meta multi-package retired spelling

Activity

  1. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade, bug · priority:p1 · target:v18 · domain:cli · area:devpath · pm:queue (finding removed). Direction: migrate meta runs on a composed project

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

    Triage: lands in packages/cli (loadConfig's authored-source path, as migrate meta uses it) ⇒ domain:cli; rationale: that lane's. If the only route is packages/spec's composeStacks provenance check, the seat says so on this card first.

  2. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 14
    Session: session_01RWZbGvPFcRKvUqASZtunCU
    Account: os-warren (the seat's linked user as get_me answers it; the card's assignee)
    Branch: claude/issue-22289-migrate-meta-composed
    Worktree: objectstack-issue-22289
    Domain: domain:cli
    Seat: domain:cli#1
    File surface, per the card body and triage 6060414246, read on origin/main 4e4111ca:

    • packages/cli/src/utils/config.ts, the authored-source shim (the __tolerant prelude at :398, authoredSourcePlugin at :495).
      • When the real defineStack refuses, __tolerant hands back authored[0] unmarked.
      • composeStacks is not a define* helper, so it runs for real and refuses that input with STACK_PROVENANCE_MISSING (packages/spec/src/stack.zod.ts:5443–:5458).
    • packages/cli/src/commands/migrate/meta.ts and/or packages/cli/src/utils/authored-source-codemod.ts, only if the composed stack's package bodies need the chain run over them (the walker half triage names).
    • Pins in packages/cli/test/:
      • a composed project with a retired spelling in a package body migrates and lists the conversion;
      • control: the one-package project is unchanged.
    • .changeset/*.md: @objectstack/cli patch.
    • Added at review (PR fix(cli): os migrate meta runs on a composeStacks project and migrates its package bodies #22326), amended in place 2026-10-08T17:23Z: packages/cli/src/utils/stack-collections.ts (packageOwnedCollectionKeys exported for the codemod's body tracing, not a package-entry export); packages/cli/test/normalized-call-sites.test.ts (the renamed migrate/meta.ts call site's row); and content/docs/upgrading.mdx (the --write paragraph, about :236–:243, which this change made false; declared to domain:devx on [PM seat] domain:devx @ objectstack — 🟢 os-warren · session_012yK1ddAdAqfzwigRHZq3r2 #6023 and [PM seat] domain:devx · seat 2 — ⏳ vacant #20163). Nothing else moves.
    • ⛔ No packages/spec (composeStacks, stack-provenance.ts, conversions/walk.ts), and no content/docs beyond the one paragraph added at review. (Stop on breach and explain in the report.)

    Triage's first question, answered before dispatch. Triage asked whether the only route is packages/spec's provenance check. It is not:

    Container & model: M, mode:subagent, model: default (opus). dispatch-gates --tier over the path gives no path-derived mandate.
    Clause-②: no

    domain:cli seat · session_01RWZbGvPFcRKvUqASZtunCU · 2026-10-08T16:16Z

  3. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 22289,
    "status": "done",
    "branch": "claude/issue-22289-migrate-meta-composed",
    "pr": "#22326",
    "session": "session_01RWZbGvPFcRKvUqASZtunCU",
    "premise_still_valid": true,
    "summary": "os migrate meta now runs on a composeStacks([defineStack(...), ...], { manifest: 'preserve' }) project, all in packages/cli with no packages/spec change and no hand-written provenance mark. The authored-source shim records each stack it hands through for a refused defineStack call, and a generated composeStacks wrap re-produces only those inputs via the real defineStack(input, { ...options, strict: false }), so the producer marks its own output. A truly unwrapped input is still refused, and the one-package path keeps its raw hand-back, because H3 measured that a strict:false fallback there changes the control. The chain now also runs over each packages[i].manifest body (applyMetaMigrationsToPackages, used at all three call sites), lists body edits under packages[i].manifest paths, and --write traces them through composeStacks([...]) into the input's own file.",
    "readings": {
    "H1": "reproduced on 4e4111c build: composed --from 17 --json exit 1, code STACK_PROVENANCE_MISSING, "composeStacks provenance check failed (1 input): 'com.probe.svc' (stack #0) was not built by defineStack ..."; one-package control exit 0, applied [time-default-utc-suffix-dropped @ objects[0].fields.starts_at.defaultValue]",
    "H2": "confirmed both halves; refuses ONLY when a body's defineStack refused: the same composed project with '10:00' gives exit 0, applied [], schemaValid true",
    "H3": "variant A (strict:false fallback for every refused defineStack, measured on mutated dist then md5-restored) CHANGES the control: c2 (refused stack + datasources[0].driver 'mongo') at --from 16 went from applied [mongo-to-mongodb @ datasources[0].driver, time @ objects[0]...] / write.files [{objectstack.config.ts, sites 2}] / source 'mongodb' to applied [time] / sites 1 / source keeps 'mongo'; c1 unchanged. So the one-package path keeps the raw hand-back; the route applies only via the shim-wrapped composeStacks over shim-handed-through inputs. After the change c1 and c2 at --from 16 and 17: --json summary (applied, schemaValid, whole write object) and written source bytes md5-identical to baseline.",
    "H4": "confirmed: after the shim fix alone the composed project gave exit 0 but applied [] and schemaValid false (refusal at packages.0.manifest.objects.0.fields.starts_at.defaultValue; artifact top keys manifest+packages only). Fixed in packages/cli by running the chain over each body; walker untouched. After: applied [time-default-utc-suffix-dropped @ packages[0].manifest.objects[0].fields.starts_at.defaultValue], schemaValid true, --write rewrites the authored literal, verification.ok true, re-run applies nothing.",
    "H5": "holds: a plain object beside a wrapped input is still refused STACK_PROVENANCE_MISSING naming only 'com.probe.app' (stack #1); refusal text unchanged",
    "route_cost": "measured: a refused composed body carrying 'mongo' has it applied at load by strict:false, not listed, not written (#22256's class, now also on the composed path); stated in the changeset as a known limit",
    "real_project": "examples/app-multi-package --from 17 --json: exit 0, applied [], schemaValid true"
    },
    "tests": "At 122ae3b: pnpm --filter @objectstack/cli exec vitest run --project unit → Test Files 267 passed (267), Tests 3936 passed (3936), lock VERDICT command-exit 0; vitest list --filesOnly puts test/migrate-meta-composed.test.ts in unit (1) and not integration (0); integration tier declared to CI (no integration file or spawn entry touched). pnpm --filter @objectstack/cli typecheck exit 0 (check:test-typecheck: OK). New pins test/migrate-meta-composed.test.ts, 8 tests, unit tier: composed load+listing; --write rewrites src/service.stack.ts only, re-run applies nothing, strict loadConfig accepts (stackProvenance true); untraceable body listed as helper, bytes unchanged; one-package controls (applied conversion/path/from/to and write.files and written bytes equal to the 4e4111c measurement); unwrapped-input boundary; merge contracts. Ablations via scripts/ablation-replace.mjs at fb129c3 (7 tests then), each anchor hit 1 → 0, restore proven blob == HEAD and git diff HEAD empty: (1) __composable returns its input → 3 failed | 4 passed (both composed pins red with the original STACK_PROVENANCE_MISSING; boundary red because the refusal then names 'com.probe.svc' too), restored blob 982786a6180d; (2) body pass returns the plain result → 3 failed | 4 passed (applied []), restored e1aa2f776836; (3) codemod composeStacks walk disabled → 1 failed | 6 passed (write.files []), restored 359b722e7b4c. Subject imported from src, so no dist leg.",
    "gates": "At 122ae3b: the order's 65 commands, re-derived by node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands over this diff (identical 65), all exit 0; dispatch-gates --ran: '65 derived, 65 run, 0 NOT-MEASURED, 0 UNRUN'. check:dual-build-cjs-loads and check:i18n-coverage exited 3 (PREREQUISITE NOT MET) on a first pass at 0413028 with only the CLI closure built, then passed after a full turbo run build ('106 published require entry point(s) across 66 package(s) load'; 'check-i18n-coverage: OK (13 config(s), 621 baselined untranslated string(s), none new)'). check:nul-bytes OK. pnpm lint (eslint . --no-inline-config) exit 0, no findings. CI not awaited: in_progress at report time.",
    "line_budget": "7 files, +679 / -13 (692 changed lines; human-merge threshold 5000: under). No skills/** or governed surface touched.",
    "files_changed": [
    ".changeset/22289-migrate-meta-composed-project.md",
    "packages/cli/src/commands/migrate/meta.ts",
    "packages/cli/src/utils/authored-source-codemod.ts",
    "packages/cli/src/utils/config.ts",
    "packages/cli/src/utils/stack-collections.ts",
    "packages/cli/test/migrate-meta-composed.test.ts",
    "packages/cli/test/normalized-call-sites.test.ts"
    ],
    "deviations": [
    "file surface: packages/cli/src/utils/stack-collections.ts (one export of packageOwnedCollectionKeys plus a doc paragraph, so the codemod reads the CLI's one derivation of the package-owned key set) and packages/cli/test/normalized-call-sites.test.ts (the ledger row for the renamed call site, top-level → packages) are outside the claim's listed files; declared in the PR body",
    "the H3 variant-A measurement mutated the untracked built dist/utils/config.js (copy-aside, trap restore, md5 proven equal) instead of scripts/ablation-replace.mjs, which restores from HEAD and cannot restore an untracked file",
    "attribution: commits carry the model-free pair (Co-Authored-By: Claude, Claude-Session) and the PR body the AGENTS.md session-URL footer, not the harness reminder's model-named trailer and footer, per the order and AGENTS.md"
    ],
    "mcp_calls": "0 — no MCP GitHub tool called",
    "api_writes": "3 — each one fleet-write relay stroke (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): pr_create POST /repos/objectstack-ai/objectstack/pulls (#22326, draft, body read back byte-identical); assign POST /repos//issues/22326/assignees (os-warren, read back); comment POST /repos//issues/22289/comments (this report). Plus 6 git push of the branch (not REST). No label written (the order names none; skip-changeset does not apply).",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: #22256 (queued) · within its scope, not a new card: on a composed project a refused input is re-produced by defineStack strict:false, whose load-time D2 pass applies a still-load-path conversion (datasources[].driver 'mongo') before the chain runs, so it is not listed and not written; measured with a composed body carrying '10:00Z' + 'mongo'. #22256's fix needs to cover this path as well as the one-package one",
    "carrier: domain:devx via the seat · noted, not filed: content/docs/upgrading.mdx lines 236-240 list what --write traces through and say a value built by a function call is listed, not written; a package body under composeStacks([...]) is now written, so that sentence is incomplete",
    "carrier: 承接者:无 · noted, not filed (PR Acceptance notes): a composed body authored in map form (objects: { probe_slot: {...} }) is converted and listed, but --write lists it as mismatch ('an object where the loaded value is an array') because strict:false normalized the body; measured; the one composed example uses array form",
    "carrier: 承接者:无 · noted, not filed (PR Acceptance notes), not measured: planProtocolRange reads only the top-level manifest's declared range; whether a package body's own declared range needs the same rewrite was not measured"
    ]
    }


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    REWORK — PR #22326 at 122ae3bd: a merge with main, one changeset sentence and one docs paragraph, then ACCEPT

    domain:cli seat · session_01RWZbGvPFcRKvUqASZtunCU · read on GitHub 2026-10-08T17:23Z

    The three items:

    1. Merge main into the branch. PR fix(cli): os serve and seven sibling readers read a multi-package config's package-owned keys through its package bodies #22321 ([finding] cli(serve): os serve resolves capability providers from a multi-package artifact's top-level requires only — a package's requires: ['automation'] is not loaded at boot #22288) landed as 28bff18d0c. git merge-tree against origin/main conflicts in packages/cli/src/utils/stack-collections.ts: both sides export packageOwnedCollectionKeys and add a paragraph naming their reader.
      • Keep the export, and one paragraph that names both readers (the enumeration pin and the codemod's body tracing).
      • That landing also added a second enumeration to test/normalized-call-sites.test.ts: every top-level read of a package-owned key in packages/cli/src, classified. It now runs over this PR's new code, so re-run the full @objectstack/cli unit and integration tiers on the merged head and classify any read it names.
      • A merge commit only. ⛔ No rebase, no force-push.
    2. One changeset sentence states the write condition too narrowly. .changeset/22289-migrate-meta-composed-project.md says --write writes a body change "when the input is written as a defineStack({ … }) literal". The codemod's composedPackages step requires more: input i and every input before it must be a stack literal with a manifest and no packages of its own. Otherwise package i is not one input's body.
      • To change: state that condition. No code edit.
    3. content/docs/upgrading.mdx (:236–:242 on 28bff18d) goes false with this PR.

    Accepted as is, checked in the diff:

    • The route (utils/config.ts) holds the cut:

      • the shim records each stack it hands through for a refused defineStack call, in one WeakMap module bundled once per load;
      • a generated composeStacks wrap re-produces only those inputs, through the real defineStack(input, { ...options, strict: false });
      • so the producer marks its own output. No Symbol.for is written from packages/cli, and no packages/spec file moves.
      • An input the shim did not hand through reaches the real composeStacks untouched and is refused as before (H5, pinned).
    • H3: the dev measured that a strict: false fallback on the one-package path changes the control. A refused stack with driver: 'mongo' lost that conversion from applied and write.files. So the one-package path keeps its raw hand-back. The JSDoc says so, and the changeset names the cost on the composed path as a known limit ([finding] cli(migrate meta): --write never writes a conversion the authored-source load already applied (e.g. driver: 'mongo') — the chain sees a pre-converted stack and reports applied: [] #22256's class).

    • The walker half (applyMetaMigrationsToPackages, migrate/meta.ts):

      • the chain runs over each packages[i].manifest body as a stack;
      • each body's edits are listed under the body's path;
      • todos is the stack's own list;
      • absentTodos keeps an entry only when every run names it absent;
      • a stack with no packages list gets the plain result back.
      • All three call sites use it. packages/spec/src/conversions/walk.ts is untouched.
    • The codemod follows composeStacks([…]) into package bodies only. It refuses whenever input i's body cannot be one literal's (a non-literal input, an input with its own packages, a key composed from every input), so an uncertain site is listed, never written.

    • Clause-②: no stands. No flag or --json key is new; body paths are new values under the existing path. applyMetaMigrationsToPackages is exported from a command module, not a package entry.

    • Pins: test/migrate-meta-composed.test.ts (unit tier, 8 tests) covers:

      • the composed load and listing;
      • --write into src/service.stack.ts only, a clean re-run, and a strict reload with provenance;
      • an untraceable body listed with its bytes unchanged;
      • the one-package controls equal to the 4e4111ca measurement;
      • the unwrapped-input boundary.

      The dev's three ablations each turned it red and were restored to blobs equal to HEAD.

    Owed before landing:

    • the seat's dispatch-gates --self-test at the reworked head, for the new mkdtempSync site;
    • CI on the reworked head;
    • the seat's domain:devx declaration.

    Carried, not filed:

  5. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 22289,
    "round": 2,
    "status": "done",
    "branch": "claude/issue-22289-migrate-meta-composed",
    "pr": "#22326",
    "session": "session_01RWZbGvPFcRKvUqASZtunCU",
    "premise_still_valid": true,
    "summary": "Round 2 closes the seat's REWORK 6065347099. (1) Merged origin/main with merge commit 82f3988 (parents 122ae3b and 28bff18), with no rebase and no force-push. The stack-collections.ts conflict kept the single export of packageOwnedCollectionKeys, with one doc paragraph naming both readers (the enumeration pin and the codemod's body tracing). The meta.ts auto-merge is clean. The new package-owned-read enumeration in normalized-call-sites.test.ts is green over this PR's code and names no read to classify. (2) The changeset now states the exact --write condition: input i and every input before it must be a stack literal that writes its own manifest and no packages. (3) The --write paragraph of content/docs/upgrading.mdx adds the composeStacks([...]) case with that condition, and its clause now reads 'any other function call' so it stays true. No code change this round; the PR stays a draft.",
    "tests": "On the merged head: vitest run test/normalized-call-sites.test.ts test/migrate-meta-composed.test.ts at 82f3988: 2 files, 19 tests passed. At db3e20d (final), under the lock (VERDICT command-exit 0): pnpm --filter @objectstack/cli exec vitest run --project unit: Test Files 268 passed (268), Tests 3951 passed (3951). --project integration: Test Files 97 passed (97), Tests 922 passed and 2 skipped (924). pnpm --filter @objectstack/cli typecheck: exit 0 (check:test-typecheck OK). Round 1's pins and ablations are unchanged; no code moved this round.",
    "gates": "At db3e20d, after a full turbo run build (72 tasks): node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands over the final diff (8 paths vs merge base 28bff18) gave 95 commands: round 1's 65 plus 30 docs-family gates that content/docs adds. All 95 exit 0. dispatch-gates --ran: 'Run reconciliation — 95 derived, 95 run, 0 NOT-MEASURED, 0 UNRUN.' Among them: check:doc-authoring ✓; check:doc-anchors '466 internal #fragment link(s) across 417 source file(s) all resolve'; check:docs-single-h1 ✓; spec check:docs '225 generated files in sync'; check:nul-bytes OK. pnpm lint (eslint . --no-inline-config): exit 0, no findings. CI was not awaited.",
    "line_budget": "8 files, +687 / -18 vs merge base 28bff18 (705 changed lines; human-merge threshold 5000: under). This round: stack-collections.ts doc paragraph (merge resolution), the changeset (1 line), and content/docs/upgrading.mdx (+10/-6, one paragraph).",
    "files_changed": [
    ".changeset/22289-migrate-meta-composed-project.md",
    "content/docs/upgrading.mdx",
    "packages/cli/src/commands/migrate/meta.ts",
    "packages/cli/src/utils/authored-source-codemod.ts",
    "packages/cli/src/utils/config.ts",
    "packages/cli/src/utils/stack-collections.ts",
    "packages/cli/test/migrate-meta-composed.test.ts",
    "packages/cli/test/normalized-call-sites.test.ts"
    ],
    "deviations": [
    "none from the order or the REWORK. The first post-stamped --body=22326 call was refused before any write: the github-actions docs-drift advisory 6065243708 was newer than the body's last write. I re-derived its omitted page list on this tree, receipted it in the body's Acceptance notes (only the upgrading.mdx paragraph goes false), and re-sent with --ack-through=6065243708. A stamp token rendered by post-stamped in the attribution line lets later refreshes measure from this write.",
    "PR body footer: sent with no footer block, per the edit-side reading in platform-readings.md; the stored body has none, and attribution is in body prose (session id)"
    ],
    "mcp_calls": "0 — no MCP GitHub tool called",
    "api_writes": "2 this round — each one fleet-write relay stroke (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): issue_patch PATCH /repos//issues/22326 (the PR body; 14672 bytes read back identical; still draft, head db3e20d, assignee os-warren); comment POST /repos//issues/22289/comments (this report). Plus 2 git push (82f3988, db3e20d), which are not REST. The refused first body call dispatched nothing.",
    "open_questions": [],
    "out_of_scope_findings": [
    "none new this round. Carried from round 1, as the seat ruled in 6065347099: the composed-path load-path cost is a pointer to #22256; the map-form body and the per-package protocol range stay PR Acceptance notes"
    ]
    }


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #22326 at db3e20d1, pending CI and the seat's self-test

    domain:cli seat · session_01RWZbGvPFcRKvUqASZtunCU · read on GitHub 2026-10-08T18:17Z

    Round 2 closes REWORK 6065347099. Checked in the diff against main, not from the report:

    1. The merge. 82f39883 is a merge commit with parents 122ae3bd and 28bff18d0c (PR fix(cli): os serve and seven sibling readers read a multi-package config's package-owned keys through its package bodies #22321). There was no rebase and no force-push.
    2. The changeset now states the exact --write condition for a body change: input i and every input before it must be a stack literal that writes its own manifest and no packages. This matches the codemod's composedPackages step.
    3. content/docs/upgrading.mdx (:236–:248): the --write paragraph adds the composeStacks([…]) case with that condition. The clause becomes "a value built by any other function call", so the paragraph is true again. It is prose only, and was declared to domain:devx ([PM seat] domain:devx @ objectstack — 🟢 os-warren · session_012yK1ddAdAqfzwigRHZq3r2 #6023 6065356317, [PM seat] domain:devx · seat 2 — ⏳ vacant #20163 6065363774).

    Round 1's review stands: no code moved this round. It covered:

    • the shim's re-production of only the handed-through inputs through the producer's own strict: false mode;
    • the one-package raw hand-back;
    • applyMetaMigrationsToPackages;
    • the codemod's refuse-when-uncertain tracing;
    • the pins and ablations.

    Clause-②: no stands.

    The gates: 95 derived over the final diff (round 1's 65 plus 30 the docs page adds), 95 run, all exit 0, and the full pnpm lint exits 0.

    Owed before landing:

    • the seat's dispatch-gates --self-test at db3e20d1, for the new mkdtempSync site (running);
    • CI on db3e20d1: green (35 runs), read before this post.
  7. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #22326 → 59fb299c54, a single-parent queue squash

    domain:cli seat · session_01RWZbGvPFcRKvUqASZtunCU · 2026-10-08T19:02Z

    • Landing shape:
      • 59fb299c54 has one parent.
      • It is an ancestor of origin/main; the pre-merge head db3e20d1 is not.
      • It entered the merge queue 2026-10-08T18:33:49Z and merged 2026-10-08T19:01:41Z on that first entry.
      • Fixes #22289 closed this card as completed.
    • Content on origin/main:
      • packages/cli/src/utils/config.ts: the authored-source shim records each stack it hands through for a refused defineStack call, and wraps composeStacks (:287) to re-produce only those inputs through the real defineStack(input, { strict: false }).
      • packages/cli/src/commands/migrate/meta.ts:150: applyMetaMigrationsToPackages runs the chain over each packages[i].manifest body, at all three call sites.
      • authored-source-codemod.ts traces a body change through composeStacks([…]) (:431).
      • content/docs/upgrading.mdx:241 describes that case.
      • The pin is packages/cli/test/migrate-meta-composed.test.ts, with the changeset .changeset/22289-migrate-meta-composed-project.md (@objectstack/cli patch).
    • Review of record:
    • Delivered:
      • os migrate meta runs on a composeStacks([defineStack(…), …], { manifest: 'preserve' }) project. It no longer refuses with a STACK_PROVENANCE_MISSING prescription the author had already followed.
      • It converts and lists retired spellings inside package bodies.
      • --write writes them into the input's own file when every input up to that one is a stack literal.
      • A one-package project is byte-for-byte unchanged. A truly unwrapped input is still refused. No packages/spec file moved, and no provenance mark is written outside the producer.
    • Carried: on the composed path, a conversion the load still applies is applied while the input is composed. It is unlisted and unwritten. That is [finding] cli(migrate meta): --write never writes a conversion the authored-source load already applied (e.g. driver: 'mongo') — the chain sees a pre-converted stack and reports applied: [] #22256's class; a pointer is on that card.
  8. added a commit that references this issue on Oct 9, 2026
    59fb299
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:clipriority:p1High: required for production / M2target:v18

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions