content(blog): how to migrate a legacy internal system to metadata - #147
Open
hotlong wants to merge 2 commits into
Open
content(blog): how to migrate a legacy internal system to metadata#147hotlong wants to merge 2 commits into
hotlong wants to merge 2 commits into
Conversation
A staged, honestly-costed path off a legacy internal system, and the cases where the honest answer is to connect and never migrate. The artifact is a migrate-vs-connect decision tree asked per object rather than per system: connecting is stage one of migrating, not the alternative to it, so the call is made object by object once the read-only connection exists. Mints "the disagreement rate" — declare the rule you believe you have, run it over the rows the old system already produced, and count the disagreements. That is the stage every migration guide skips, and the platform does not compute it for you (os datasource validate diffs the remote schema, which is narrower). Platform claims verified against objectstack origin/main: schemaMode 'external', the boot validation gate, the double opt-in write gate (datasource external.allowWrites + object external.writable), the os datasource list-tables/introspect/validate CLI, and the two sequencing constraints — no cross-datasource join in one query and no transaction spanning datasources. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
This was referenced Sep 2, 2026
hotlong
marked this pull request as ready for review
September 2, 2026 11:47
…ags with the #78 vocabulary Closed vocabulary from PR #160: every tag is either one of the seven tier-2 canonicals in this locale's rendering, or the proper noun of a product / company / protocol the post actually compares against. None qualifies. The post is a four-stage migration path (connect, reconcile, move writes, cut over); AI agents and the open business ontology appear as closing framing, not as the post's subject, and the legacy systems it names (ERP, CRM, MES) are categories, not products it compares against. Empty is the measured outcome recorded on #158, not a gap to paper over. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
hotlong
pushed a commit
that referenced
this pull request
Sep 2, 2026
…ve design"
The closing "What Has Shipped vs. What Is Coming" section told readers that
one-step schema import, binding to externally owned schemas, and the
write-safety gates were still being designed under ADR-0015 (status:
Proposed). All three landed. Measured against objectstack origin/main:
- one-step schema import — `os datasource list-tables` and
`os datasource introspect <name> --table <table>`
(packages/cli/src/commands/datasource/)
- binding to externally owned schemas — `Datasource.schemaMode`
('managed' | 'external' | 'validate-only') and `Object.external`
(remoteName / remoteSchema / columnMap), in
packages/spec/src/data/{datasource,object}.zod.ts
- write-safety gates — the double opt-in `external.allowWrites` on the
datasource plus `external.writable` on the object
- ADR-0015 is "Accepted — backend/REST/CLI implemented; Studio UI + extra
dialect drivers pending"; ADR-0062 (Accepted 2026-06-22) supersedes its
runtime half
The paragraph now names what shipped and how to use it, keeps the
federation write gate distinct from a read-only GRANT on a managed
datasource (the FAQ's advice is unchanged), and states what is genuinely
still pending. The post's connect-not-rebuild argument is untouched.
Wording and facts kept consistent with
content/blog/how-to-move-an-internal-system-to-metadata (PR #147).
Correction to a live post: sets `updated`, leaves `date` alone. Carried
into all six authored locales; zh-Hant regenerated with `pnpm gen:zh-hant`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
This was referenced Sep 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #91
New English-original how-to: a staged, honestly-costed path off a legacy internal system, plus the cases where the honest answer is not to migrate at all.
New directory only —
content/blog/how-to-move-an-internal-system-to-metadata/.why-custom-systems-dieandextend-existing-systems-with-aiare linked, never edited (#130 is editing older posts' bodies in parallel).What it says
extend-existing-systems-with-aiboth be right: three of the tree's five endpoints are "connect and stop".why-custom-systems-die— 143 orders over the threshold, 25 disagreements, 17%, and the missing standing-contract clause that explains 22 of them. Labelled in the text as a worked example, not a customer measurement.#a-six-question-health-checkanchor was confirmed present in the built HTML.Premise check and platform verification
The issue's premise held, but one input did not, and it changed the article.
Every platform claim was verified against
objectstackorigin/main(7cbe705b), not against the docs site:schemaMode: 'external'forbids DDL; writes off by defaultpackages/spec/src/data/datasource.zod.ts, ADR-0015validation.onMismatch: 'fail'/validate-onlypackages/spec/src/data/datasource.zod.ts; ADR-0062 R6 shippedexternal.allowWrites+ objectexternal.writabledatasource.zod.ts,object.zod.ts(both gates required)os datasource list-tables/introspect --table/validatepackages/cli/src/commands/datasource/{list-tables,introspect,validate}.tscontent/docs/data-modeling/external-datasources.mdx; ADR-0062content/docs/data-modeling/import-mappings.mdxcontent/docs/releases/v17.mdx(#5351, #5696)The PM's mechanism assumption was confirmed on three of four points and corrected on the fourth. Read-only-first and per-object write enablement are real and stronger than assumed (they are platform-enforced gates, not just a read-only DB user). But "undocumented behaviour is discovered by diffing the declared model against observed data" is only half true:
os datasource validateand the boot gate diff declarations against the remote schema — a wrong column type, not a missing approval clause. Rule discovery is queries you write. The post says this in as many words rather than implying the platform does it for you, and that honesty is the reason stage two carries the article.ADR-0015 is no longer
Proposed. It is Accepted and shipped (ADR-0062 supersedes its runtime half and is also Accepted). Two published pages still describe this surface as unshipped — filed separately, not touched here.Gates
Union run after the final commit, on
11785d6, exit codes captured before any pipe:pnpm content:lint✓ content lint passed (335 files checked)pnpm checkResult (133 files): 0 errors, 0 warningspnpm build[build] Complete!pnpm seo:smokeSEO smoke test passed (866 HTML pages checked)One non-blocking lint warning, and it is the intended one:
Date is in the future: Thu Sep 17 2026— the assigned Thursday 2026-09-17 slot. Baseline onorigin/mainwas zero issues, so this is the only line this branch adds.Assets
cover-en.svg(the four stages, with the reversible boundary falling after stage three) and one body diagram,migrate-or-connect-en.svg(the decision tree). Both rendered standalone and inspected at full size. One real bug was caught that way and fixed: a CSStext{fill}rule outranks a presentation attribute, so the dark start box's label was rendering dark-on-dark and the two band labels were losing their colour — all colour overrides now go through classes.Frontmatter
date: 2026-09-17T10:00:00+08:00, noupdated. English original only;descriptionis 222 characters. Body is ~2,520 prose words.Tag reconciliation
Tags reconciled with the #78 closed vocabulary (#163): none — this post ends with
tags: []. It carries no tier-2 canonical by aboutness (AI agents and the open business ontology appear as closing framing, not as the subject) and compares against no named product; the legacy systems it names — ERP, CRM, MES — are categories, not proper nouns. That emptiness is the measured consequence recorded on #158.content:lintgreen at head6ea4deb;tags:is the only line that commit touches.🤖 Generated with Claude Code
https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
Generated by Claude Code