fix(spec): os migrate meta guidance for the rest-*, analytics-*, view-*, package-*, object-*, sharing-*, audit-*, flow-* and http-* migration entries states each lesson in words, not tracker numbers (stage 6) - #20536
objectstack-fleet[bot] merged 3 commits into
Conversation
…t tracker numbers The reason / replacement / acceptanceCriteria text (and one surface) of the rest-, analytics-, view-, package-, object-, sharing-, audit-, flow- and http- ADR-0087 semantic entries, plus the two carry-overs from stage 5 (api-error-retry-after-unit-in-key names its 2026-09-05 population ruling; inline-grid-column-currency-scale-refused drops the ruling-record ids and batch numbers its field sibling already dropped). Text only. Claude-Session: https://claude.ai/code/session_01ARcDurZ5j34RdqsGgc4jgH Co-authored-by: Claude <noreply@anthropic.com>
… holds the stage-6 families registry.ts, spec-changes.json and docs/protocol-upgrade-guide.md are regenerated by their generators from the rewritten entries. The os migrate meta guidance pin covers rest-, analytics-, view-, package-, object-, sharing-, audit-, flow-, http- and inline-, and its REWRITTEN floor lists the 34 entries this stage rewrote for the first time. Claude-Session: https://claude.ai/code/session_01ARcDurZ5j34RdqsGgc4jgH Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ARcDurZ5j34RdqsGgc4jgH Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 6 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 1 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 137 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin f67b7d8098ead2d4094c185262977c70d4d179b3 && git checkout f67b7d8098ead2d4094c185262977c70d4d179b3
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 31d281d3b2b855a7c7d00e48d2ac2fb22aa5c84b 472ee29b8293041df4664be19fd38ab1a068c136 && git checkout -B drift-repro 31d281d3b2b855a7c7d00e48d2ac2fb22aa5c84b && git merge --no-ff 472ee29b8293041df4664be19fd38ab1a068c136
node scripts/docs-audit/affected-docs.mjs --json 31d281d3b2b855a7c7d00e48d2ac2fb22aa5c84b
|
Contract reviewServed-tier: Head unmoved across the review (re-read at the end: same sha, ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
Part of #20233
Stage 6: the rest-, analytics-, view-, package-, object-, sharing-, audit-, flow- and http- families.
Clause-②: no
Stage 6 of a staged card. The card stays open for later stages; this PR carries no closing keyword. Text only: no entry id,
from/to, conversion or matching logic moves, and the chain rewrites exactly what it rewrote before. Onesurfacemoves, under ruling A of the stage-1 ACCEPT (5858839916): it carried two tracker numbers.What this does
os migrate metaprints every ADR-0087 semantic entry it crosses as one block:⚠ [protocol N] SURFACE → REPLACEMENT, thenwhy:(the entry'sreason) andverify:(itsacceptanceCriteria). AGENTS.md's runtime-string rule applies to all of it: 「Runtime strings — refusal prose, prescriptions, anything an author is shown — carry no tracker number (pnpm check:doc-authoring): the lesson goes into the text.」 Form D of ruling C+D on card19123(5749154545) sets the shape: the lesson in words, and no number, dead or alive; a cross-repo number is still a tracker number.This stage covers the nine families
rest-,analytics-,view-,package-,object-,sharing-,audit-,flow-andhttp-: 122 sites → 0 in the three prose fields and 2 → 0 insurface, across 33 entry files. It also takes the two carry-overs the stage-5 record (5880299859) named:18.api-error-retry-after-unit-in-key: the clause on the ~16 runtime-emitted measurements andApiError.retryAfternow dates the ruling that decided it — "its 2026-09-05 population ruling" — instead of reading under ruling B's 2026-09-02 date alone.18.inline-grid-column-currency-scale-refused: the two ruling-record ids and the batch / item numbers are replaced by the rulings' dates and options, the same rewrite stage 5 gave itsfield-sibling.Each site now says what the cited ruling, measurement or fix decided. ADR ids stay, and so does
Prime Directive #10in18.package-manifest-version-grammar-enforced(a rule in AGENTS.md, as stages 2–5 kept#10/#12).registry.ts,spec-changes.jsonanddocs/protocol-upgrade-guide.mdare regenerated from the entries (gen:migration-registry,gen:spec-changes,gen:upgrade-guide), never hand-edited. The pin now holds twenty-seven families.Census — tracker ids in the author-shown fields
Instrument. The stage-4 / stage-5 TypeScript-AST census, the same script: for each entry object literal under
packages/spec/src/migrations/entries/**it evaluatesreplacement,reason,acceptanceCriteriaand (separately)surface, joining string literals with+, and counts#followed by 4 or 5 digits at a word boundary. On basefb386074it reads the whole tree at 461 sites / 5surface/ 50 short, which is the stage-5 record's after-count. Unevaluable fields: 0. 313 semantic entries.Controls, same run.
17.aggregation-node-distinct-retired.tsreads 7 sites (replacement 1, reason 6), before and after./// docblock lines in entry files carry a tracker id, and none is counted; 832 before and after. Comment lines are the sibling card's surface (the one that owns every comment and docblock line), and this PR touches none (proved below).Base
fb386074:rest-6 entries, 17 sites (0 / 17 / 0);view-10, 15 (0 / 13 / 2);analytics-6, 14 (2 / 12 / 0);audit-2, 14 (2 / 12 / 0);sharing-2, 14 (1 / 13 / 0);http-2, 13 (0 / 13 / 0);object-7, 13 (1 / 11 / 1);flow-6, 11 (0 / 11 / 0) plus 2 insurface;package-6, 11 (0 / 10 / 1). 122 sites (6 / 112 / 4) in 31 of the 47 entries; 91 distinct ids read (82 in this repository, 8 in objectui, 1hotcrm#), plus five ruling-record comment ids. Short numbers in the nine families: 9 (one kept, the Prime Directive).After this PR: all nine families 0,
surface0; the seventeen earlier families still 0; whole tree 461 → 339,surface5 → 3, short 50 → 40 (the twoinline-batch numbers included). The PM's rough line count (about 133 sites, about 30 files) is a wider line instrument; the AST reading is 122 in 31 files.17.analytics-query-request-envelope-retired17.audit-log-action-enum-retired17.audit-log-action-restore-retired17.flow-retry-max-retries-required17.http-request-errors-total-retired17.http-server-runtime-vocabulary-retired17.package-uninstall-explicit-all-tenants17.rest-server-openapi31-block-removed17.sharing-execution-context-retired17.sharing-rule-recipient-reconcile17.view-filter-rule-value-shaped-by-operator17.view-management-protocol-retired18.analytics-authorable-unknown-keys-refused18.analytics-date-range-array-two-bounds-required18.analytics-time-dimension-date-range-vocabulary-closed18.api-error-retry-after-unit-in-key18.flow-decision-branch-expression-absent-refused18.flow-decision-edge-branching-first-match18.flow-edge-condition-evaluated-slot-source-required18.flow-predicate-slot-blank-string-refused18.inline-grid-column-currency-scale-refused18.object-block-sort-item-array18.object-grid-data-view-data-converged18.object-grid-default-filters-rule-array18.object-index-unknown-keys-refused18.package-api-contracts-unmounted-entries-retired18.package-install-request-unknown-keys-refused18.package-rollback-response-retired18.rest-api-endpoint-handler-status-retired18.rest-api-plugin-durations-unit-in-key18.rest-server-config-dead-keys-retired18.view-filter-rule-absent-value-refused18.view-filter-rule-scalar-operator-array-refused18.view-overlay-options-bag-judged18.view-pagination-page-size-default-50The fourteen entries of these families that carried no number are untouched:
analytics-cube-public-default-visible-enforced,analytics-query-request-format-retired,flow-node-config-required-keys-refused,object-grid-default-sort-retired,object-kanban-quick-add-retired,object-tenancy-organization-field-retired,package-manifest-version-grammar-enforced(its one short number is the kept Prime Directive),package-version-row-semver-2-0-0,rest-api-config-dead-keys-retired,rest-api-documentation-version-retired(the new entry from the landedrest-change: its prose was read and is clean),view-filter-rule-operator-input-canonical,view-item-owner-hidden-retired,view-overlay-judged-by-viewkind-arm,view-overlay-owner-hidden-retired. Four of the 35 changed entries carried no four- or five-digit id:view-overlay-options-bag-judged(a provenance-only acknowledgement quote),package-install-request-unknown-keys-refused(a batch number and a ruling-record id) and the two carry-overs.Text only — proved by a base-vs-head AST comparison
For every entry file this PR changes, both versions (
fb386074and the head) are parsed and compared: every import declaration; every property other than the three prose fields, by evaluated value (soid,from/toand any matcher); every comment token in the file; and the code skeleton, token by token with each run of joined string literals collapsed to one.surfaceis allowed to differ only where the base value carried a tracker id and the head value carries none. 35 files compared, 0 with a non-prose change; one note, the ruling-Asurfaceof18.flow-edge-condition-evaluated-slot-source-required. The instrument is shown able to fail first: on an in-memory copy it reports DETECTED for a mutatedid, a mutated comment, a mutatedsurfacewhose base carried no tracker id, a mutated code token and a mutated import, and stays dark on a prose-only mutation. So none of the sibling card's comment lines moved, and no entry's identity or matching moved.registry.ts, compared the same way: comment tokens, imports and code skeleton identical; all 1,572 non-prose properties identical by value (container literals compared through their children); exactly the 35 changed ids differ; and all 313 head registry entries equal the head entry files onsurface/replacement/reason/acceptanceCriteria.Every citation read, and what the text now says
Each cited id was read with a single-card REST read (body plus the ruling, measurement or landing comments), resolved against the repository its sentence names: 82 in this repository and 8 in
objectstack-ai/objectui(one bare id resolves there: the sort ruling's consumer change8758is "objectui PR" in its sentence). The five ruling-record comment ids were read by id.hotcrm#1555answers 403 to this session and is rewritten from whatmainrecords. Ids are in code spans so this body posts no cross-references. 8 of this repository's ids answer 404 on the issues endpoint and again on the pulls endpoint (6206,6239,6511,6523,10004,14369,14691,17124; control6209answers 200); their sentences are rewritten from whatmainrecords, listed in Acceptance notes.rest-(14 ids)31974579openApi31declared, never enforced).openApi31precedent)"13823handlerStatuswith a tombstone; enforce excluded; the class direction recorded for two sibling cards.5384ApiEndpointSchemawas still an open object afterapibecame a registered metadata type; closed strictly.apibecame a registered metadata type"13808(PR)handlerStatusas working machinery.3950(PR)13612,13613EventNameSchema's binding schemas with no runtime consumer.14478,15677api/stack of that ruling.14369RestServerConfigsub-objects"11984normalizeConfigcast the four sub-objects instead of parsing them; it parses them since.1479614691analytics-(10 ids)3891/analytics/querywith no analytics service installed) dropped the caller's identity and the contract'swherefilter at its door.wherefilter at the door)"4001387810414MetricSchema.filterswas authorable with zero consumers; removed.metric-filters-removed"175981632217593(PR)17124160414614view-(10 ids)5869,6209(PR)in/not_inanswered 500; now a named 400 INVALID_FILTER.(5869)inacceptanceCriteriadropped56855948GET /ui/view/:object/:typeanswers, and its 2026-08-07 ruling, both readGetViewResponseSchema.GET /ui/view/:object/:typeanswers AND its 2026-08-07 maintainer ruling"; "the shapes that ruling meant"623919751,195146227ViewFilterRuleSchema.valueshaped by its operator (theview-filter-rule-value-shaped-by-operatorentry).objectui#9050objectui#9853view-overlay-options-bag-judgedoptions.KINDat the door.package-(8 ids and one ruling record)7705,7780#12(short)rest-requireauth-default-fliplived in protocol 12.1911618604HttpDispatcherover a realSchemaRegistry.18058installPackagerebound onto the servingPOST /api/v1/packages.5856869656(record)12038119253877object-(11 ids)objectui#8221sortclause retired, one spelling (the array); its fourth item routes theComponentPropsMappull-back here.sortclause"; "One item of that ruling"; the item's quote kept verbatim8758(objectui PR)convertSortToQueryParams.convertSortToQueryParams"7751object-*block family's props schemas enterComponentPropsMap.object-*blocks intoComponentPropsMap(the maintainer's ruling of 2026-08-12)"objectui#6207data's kind. Ruled 2026-08-25, option A.objectui#5090datawas aligned toViewData.objectui#4648staticDataamong them) are not published as authoring surface.staticDatashortcut that objectui's deprecated-alias carve-out already refuses to publish as authoring surface"19514,objectui#9050view-.view-objectui#4772IndexSchema, droppingwhere.IndexSchema"; "objectui then converged that editor"4001analytics-.5114sharing-(11 ids)62066430,65116511answers 404).6523,7068(PR)6523answers 404).7140(PR),7206(PR),7070721818786350audit-(8 ids)76758144,8145login/logoutwriters on the auth session hooks;config_changefrom the settings service.login/logouton the auth session hooks,config_changefrom the settings service)"8147,83151883,31468011flow-(11 ids and two ruling records)4247maxRetrieshad two defaults (schema 0, engine 3).19961hotcrm#155517322,17495(insurface)registerFlow, then atobjectstack validate.15807,15430,15662ast-only envelope no engine can evaluate refused; a non-string node predicate refused at registration rather than answered a silentfalse; carried to the edge.ast-only envelope no engine can evaluate, and refused a non-string node predicate at registration instead of letting the evaluator answer it a silentfalse"5550509137(record)ast-only envelope driven throughAutomationEngine.evaluateConditionanswersfalse.ast-only envelope throughAutomationEngine.evaluateConditiondirectly)"17493,5651023407(record)1557217322,15811config.conditionand every evaluatedsourcerefuse a blank.config.conditionand a blank evaluatedsource"http-(11 ids)9650,9835,9834,1000410004answers 404).5122,39779834,52954938system/http-server.zod.tsremoved.4834,4988,5055ui/interaction configs, the widget / i18n shapes — each removed by route 3.ui/interaction configs and the widget / i18n shapes"Beyond the four- and five-digit regex. Nine decision-batch numbers (
#27,#43,#57,#77,#117,#215,#217,#218,#227), their item numbers, the campaign's internal batch and site numbers,batch adjudication batch 4, 「五问一批」 and "C′ item 1" were dropped; each sentence now carries the ruling's date and content. The provenance-only acknowledgements 「同意」 (×2), 「其他同意」 (×2), 「217 同意」, 「其他接受」 and 「9853 默认页大小改为50」 (the ruling's content, 50, is stated in words; the quote itself carried a tracker number) were replaced by the ruling's date and content. The lesson-bearing quotes are kept verbatim: 「the differences are the protocol's to close」 (×2), the sort ruling's fourth item, 「every other operator takes a scalar」, 「lowers to a deep-equality comparand」, 「persistViewPatch只存 patch,不存 merged base」 and the audit ruling's 原则记录.Pin — widened, not weakened
packages/cli/test/migrate-meta-engine-guidance.test.ts:COVERED_PREFIXES17 → 27 (rest-,analytics-,view-,package-,object-,sharing-,audit-,flow-,http-, andinline-for the carry-over entry, theinline-family's only entry, now tracker-free);package-selects nopackages-entry.REWRITTEN113 → 147: the 34 ids this stage rewrote for the first time (the 33 nine-family entries plusinline-grid-column-currency-scale-refused;api-error-retry-after-unit-in-keywas already listed). The header comment names the new families; the threeitblocks and everyexpectare textually unchanged.Ablation, from committed HEAD
472ee29b82, one lock turn (scripts/ablation-replace.mjswrap mode, a restore trap by absolute path with a blob check,scripts/ablation-dist-preflight.mjs):registry.ts,http-server-runtime-vocabulary-retired'sreason, anchorbehind it, vocabulary second. ADR-0049.→behind it, vocabulary second. ADR-0049, #5295.(anchor 1 → 0, replacement 0 → 1, blob06c06741→702e7370). Mutate leg: spec build exit 0; the marker in 4distfiles; the pin RED, 1 failed | 2 passed:http-server-runtime-vocabulary-retired: the printed guidance cites a tracker id: expected '#5295' to be undefined. Restore proven by the tool (blob == HEAD06c06741,git diff HEADempty). Restore leg: spec build exit 0; the marker absent from all 224distfiles with the tree clean; the pin GREEN, 3 passed; whole tree 0 dirty paths.No other test pins a removed number: on
main, the tests naming any of the 35 entry ids (sys-audit-log-retired-actions,plugin-rest-api.handler-status-retirement,rest-api-config-dead-keys-retirement,inline-grid-column-currency-scale-refused,component-object-grid-default-filters.pin,view-overlay-owner-hidden-retirement, and two that name them in passing) assert ids, surfaces and prescriptions this PR does not move, not the prose it rewrites.Generated artifacts
registry.ts: 313 semantic, 232 retired-key, 206 retired-def; exactly the 35 ids differ (see the AST comparison above).spec-changes.jsonanddocs/protocol-upgrade-guide.md: only the protocol-17 entries appear in them, as the generators project; every changed line is a fragment of a changed entry's field..changeset/20233-rest-analytics-view-package-object-sharing-audit-flow-http-migration-guidance-tracker-free.md:'@objectstack/spec': patch,Clause-②: no.Verification (head
472ee29b82)Every heavy run through
scripts/pm/os-verify-lock.sh, each exit code written to disk before it was read.turbo run build --concurrency=2 --filter='@objectstack/cli^...'→ Tasks: 58 successful, 58 total (VERDICT command-exit 0); plus the 10 packages outside that closure for the dual-build gate → Tasks: 68 successful, 68 total.pnpm --filter @objectstack/cli exec vitest run --project integration --maxWorkers=2 test/migrate-meta-engine-guidance.test.ts test/migrate-meta-default-range.test.ts→ Test Files 2 passed (2), Tests 10 passed | 1 skipped (the default-range file's ownskipIf).spec-changes.json):spec-release-changes,meta.stored-flags,doctor-deprecation-hint-commands,vitest-tiers-partition→ Test Files 4 passed (4), Tests 48 passed (48).--project local→ Test Files 573 passed (573), Tests 16835 passed | 1 todo;--project repo→ Test Files 39 passed (39), Tests 701 passed (701);src/migrations/migrations.test.tsalone → Tests 150 passed (150).pnpm --filter @objectstack/spec typecheckexit 0 (test layer 53 files / 251 errors held);pnpm --filter @objectstack/cli typecheckexit 0 (3 files / 28 errors held).node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderives 89 families over this diff; all 89 run, all exit 0;--ran→ "89 derived, 89 run, 0 NOT-MEASURED, 0 UNRUN". Among them:check:doc-authoring("16759 customer-facing string(s) across 1172 spec sources clean"),check:generated("All 15 generated artifacts are up to date"),check:migration-registry("registry.ts is current (313 semantic, 232 retired-key, 206 retired-def)"),check:spec-changes,check:upgrade-guide,check:issue-citations("no issue citations added"),check:org-identifier,check:nul-bytes,check:api-surface,check:authorable-surface,check:dual-build-cjs-loads(104 require entry points across 66 packages load),check:type-check-debt,check:adr-0087-registration,check:changeset-no-major,check:empty-changeset.eslint --no-inline-config --format jsonover the 37 changed.tsfiles → 37 files, 0 errors, 0 warnings, no file-ignored notice. Population read fromeslint.config.mjs(**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}minusNEVER_LINTED); invariance: the config enables no type-aware linting (noparserOptions.project, no typed rules), so this diff cannot move any untouched file's verdict. The fullpnpm lintis CI's.origin/mainis1378ec7c, three commits past the base, none touching the migration ledger or its projections; a driver-free bare-clonemerge-tree --write-treeof the head against it exits 0 with no conflicted path.registry.tsis shared with open PRs20504,20460and20458, ordinary concurrency; no open PR touches any of the 35 entry files or the pin.Acceptance notes
404 and 403 ids, rewritten from what
mainrecords.6206(the share-link ruling of 2026-08-07):packages/core/src/security/assemble-execution-context.ts(the share-link copies omittedaccessible_org_ids; both surfaces converted to pass the whole envelope) andpackages/plugins/plugin-approvals/CHANGELOG.md("applying the ... ruling — enforcement adjudicates on the whole envelope, never a per-site subset").6523/6511: the same CHANGELOG ("converged 36 contract signatures onto the completeresolveAuthzContextenvelope");6430(200) names the share-link half.6239:packages/client/CHANGELOG.mdrecords it as this removal itself (retireViewProtocol's five viewId-addressed methods); dropped.8758as a bare id: its sentence names objectui, andobjectui#8758answers 200 (the stringsortclause retired).10004:packages/observability/src/semconv.tsand the observability CHANGELOG pair it with9834as the histogram's move to the transport seam.14369:docs/qa/platform-checklist/areas/api-backend.json("the liveness census that found the block read by nothing") and the14640changeset (it enrolled four of the five sub-objects).14691: the same file records it as this retirement; dropped.17124:.changeset/17124-daterange-array-arm-arity.mdrecords the measurement (one authored document, four faces, three readings).hotcrm#1555(403 cross-repo):.changeset/15429-decision-edge-branching-first-match.mdrecords the case and the node (lead_conversion.decision_duplicate).Observations, not filed.
surfacesites remain in the other families (the largest:actor-13,hot-12,external-11,query-11,delete-10,stack-10);stack-andturso-have entries in open PRs. The pin file keeps its stage-1 name while holding twenty-seven families.18.view-pagination-page-size-default-50.ts,18.view-overlay-options-bag-judged.ts,18.flow-decision-edge-branching-first-match.ts(hotcrm#1555) and18.analytics-authorable-unknown-keys-refused.ts.Implemented-by:
claude/issue-20233-migrate-meta-tracker-free-stage-6·domain:specseat 4 dispatch, sessionsession_01ARcDurZ5j34RdqsGgc4jgH.Generated by Claude Code