fix(flows): retire demo_bootstrap, the platform claims seeded rows once at seed settle - #1988
Merged
objectstack-fleet[bot] merged 4 commits intoOct 2, 2026
Conversation
…ed rows once demo_bootstrap was a */10 schedule flow that re-filtered twelve objects for ownerless rows forever. On the 17.6.0 pin the platform re-runs its seed-ownership claim on app:seeded (objectstack#17872): a fresh dev boot with the sweep unable to fire leaves zero ownerless rows on all twelve objects, so the sweep is removed with its registration, its saas-composition exclusion, its exemption-register entry, its test pins and its docs rows. The #702 forecast ordering cases now run the platform's real claimSeedOwnership in both orders instead of the retired flow. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ER8ntXZhYebyQ66aXWdjfT
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ER8ntXZhYebyQ66aXWdjfT
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ER8ntXZhYebyQ66aXWdjfT
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
…rst boot The platform's seed-settle claim covers a new install's first boot only; seed rows a later upgrade adds to an existing install are not claimed yet, tracked upstream in objectstack-ai/objectstack#21486. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ER8ntXZhYebyQ66aXWdjfT
This was referenced Oct 2, 2026
hotlong
pushed a commit
that referenced
this pull request
Oct 3, 2026
Refresh of PR #1953 onto main 25cd8d7 (26 commits). The merge is clean: main touched none of the PR's four files. Its one README edit (31 -> 30 flows, #1988) is not a figure test/docs-readme-token-figures.test.ts pins, and that test stays green on the merged tree. Claude-Session: https://claude.ai/code/session_01ER8ntXZhYebyQ66aXWdjfT Co-authored-by: Claude <noreply@anthropic.com>
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 #1892
What changed
demo_bootstrapis retired. It was atype: 'schedule'flow on*/10 * * * *that, in every tenant, filtered twelvecrm_*objects forowner_id IS NULLand stamped the first user onto what it found, forever. On the 17.6.0 pin the platform re-runs its own seed-ownership claim onapp:seeded(claimSeedOwnershipin@objectstack/plugin-security, objectstack#17872, the change for objectstack#17628). Measurement 1 below shows that claim leaves zero ownerless rows on all twelve objects of a fresh boot with the sweep unable to fire. So the flow goes, together with its registration, the SaaS-composition filter that existed only to drop it, its exemption-register entry, its test pins and its docs rows. No scheduled job of any kind is added.Measurement 1: fresh boot on 17.6.0 with the sweep out
Recipe. Worktree at
origin/maincf422b83(pin 17.6.0), tree untouched.rm -rf .objectstack/data && pnpm buildunder the shared lock (VERDICT command-exit 0). Thenobjectstack dev -p 4892 --no-watch --log-level info, spawned by a small wrapper that holds an IPC channel soobjectstack:seed-settledis timestamped.OS_AUTOMATION_SCHEDULED_WORK_ENABLEDwas unset, which is the 17.6.0 default and arms no time trigger.The safety net was provably out. The boot log says
Flow 'demo_bootstrap' is not armed on trigger 'schedule' — disabled by deployment policy(22:09:35.626Z). At every reading,sys_automation_runandsys_jobheld 0 rows fordemo_bootstrap.The instrument is the same query the 17.4.0 run used (
owner_id IS NULL), on the same twelveCLAIMED_OBJECTS, read-only over.objectstack/data/objectstack.db.Timeline (2026-10-02, UTC):
Inline seed exceeded 8000ms budget … continuing in backgroundfirst user promoted to platform admin: admin@objectos.aihanded 195 seeded record(s) … PROVISIONAL: 1 seed source(s) were still writingobjectstack:seed-settled,inserted: 354app:seededclaimapp:seededclaim,handed 155 seeded record(s) … final(case 38, contract 4, event 29, knowledge_article 4, campaign_member 51, event_attendee 29)demo_bootstrapruns: 0Per object, ownerless / total:
Reading A is the positive control for the instrument. The same query sees exactly the four objects the 17.4.0 run lost (the event seed has grown from 27 to 29 rows since then). A second control comes at the end of the run: after planting
owner_id = NULLon onecrm_caserow and onecrm_contractrow, the query readscase 38/1 · contract 4/1.crm_taskgrowing from 7 to 11 is the claim's own update ofcrm_casefiringcase_escalationfour times, which then firedtask_urgent_alertfour times. The sweep'supdate_recordwrites fired record-change flows the same way.The acceptance on both trees, plus the upgrade path
All boots use the same recipe with
OS_AUTOMATION_SCHEDULED_WORK_ENABLED=true.sys_jobcf422b83flow-schedule:demo_bootstrap·*/10 * * * *·active: 1(the production symptom)approvals-sla-escalation), none fordemo_bootstrapfinalclaim at 22:26:30.8flow-schedule:demo_bootstraprow staysactive: 1, but nothing runs it:run_count 0and nosys_job_runrow across the 22:30:00 tick. Control on the same kernel:approvals-sla-escalationran at 22:32:04,success.Hypothesis 2: the claim was the flow's only job
Read on today's tree: every node was either the first-user lookup or a
get_record/update_recordpair onowner_idover the twelve objects. Nothing else was written. No runtime producer relied on the sweep either. Everycreate_recordon those objects stampsowner_iditself:contract_renewal,forecast_snapshot,opportunity_stagnation,quote_generation,lead_conversionandschedule_followup, plus the hook and action inserts. That matches the card's production reading ofacted 0over 100 retained runs.Files
Flow and registration:
src/sales/flows/demo-bootstrap.flow.ts(deleted),src/sales/flows/index.ts,objectstack.composition.ts,objectstack.config.ts. Both compositions now register the same 30 flows.Pins under
test/:flow-scheduled: bothdemo_bootstrapblocks removed. The forecast_snapshot 与启动重播种的互动:每次 dev 重启后,当季出现一条无 owner 的幻影快照行与 owner 键控行并存 #702 forecast ordering cases now run the platform's realclaimSeedOwnershipover the harness in both orders, in place of the retired flow.actions-flows-integrity: two pins removed.flow-scheduled-org-partition: the exemption register is now empty, and the composition-backed exemption block is removed.automation-docs-coverage: ledger row removed.flow-variable-conditions: the zero-user case is removed.saas-composition: the flow pins now assert that both shapes register the same flows. The engine measurement that justified the exclusion is removed with it.activity-seed-coverage,hooks-runtime-sales,ownership-modelandforecast-seeds: wording only.Docs that follow the code:
content/docs/administration/automation.mdxand its zh-Hans and zh-Hant pages: the row is removed, 31 flows becomes 30, nine scheduled becomes eight, and one sentence now says who owns seeded records.README.mdanddocs/STATUS.md: the flow count, transcribed from this run'spnpm validate.docs/feature-inventory.md: ADM-011 is marked removed, per the file's own rule.docs/architecture/module-split-inventory.json: the row is removed and a$hand_editsentry added, per its protocol.docs/MAINTENANCE.md.Comments that named the sweep as the current mechanism:
src/sales/data/(_shared.ts,activity.seed.ts,forecast.seed.ts,index.ts)src/sales/objects/(account.hook.ts,forecast.hook.ts,lead.hook.ts)src/sales/sharing/demo-staffing.tsbilling-handoff-closed-won,billing-handoff-contract-activatedandopportunity-won-alertflowsscripts/demo-staff.tse2e/fixtures.tsande2e/opportunity-lifecycle.spec.tsDated measurements ("measured on 17.4.0", "used to") are left as written.
.changeset/1892-demo-bootstrap-run-once.md(patch).Beyond the surface the claim listed,
objectstack.config.tsandobjectstack.composition.tswere touched because the build imports the flow there. The extra test files pin the retired flow.README.mdanddocs/STATUS.mdchanged because their count guards went red, and the comment files stated the retired sweep as the current mechanism. No governed path is touched.origin/mainc7c5fb7dis merged in, with no overlap with these files.Verification
pnpm verifyate5acc256:os-verify-lock: VERDICT command-exit 0.Logic: 30 Flows); typecheck, lint, lint:i18n-gate and hygiene passed.✓ source token ratchet clean; build passed.Test Files 174 passed (174)·Tests 3706 passed | 1 skipped (3707).pnpm verify, atb0ac3914, was red on two docs-count guards:README.mdanddocs/STATUS.mdstill said 31 flows.e5acc256updates both.c7c5fb7d:src/salesbusiness semantics: 54,323 → 53,433src/salesinteraction layer: 27,999 → 27,999src/salesauthored total: 97,801 → 96,911src/revenue: unchanged (comment-only edits)Acceptance notes
Platform gap found, not fixed here. On a boot where an admin already exists and the seed settles within the inline budget, the seed-ownership claim does not run at all. The
app:seededhook fires beforekernel:readyhas set the claim target, and thealready_have_adminpass does not claim. Measured on the base artifact by warm-booting the measurement-1 DB:crm_knowledge_articledeleted before the boot was re-inserted by the replay (inserted: 1) withowner_idnull;handed … seeded record(s)line appeared.So a seed row added by a later HotCRM version stays ownerless on an existing install. On deployments with scheduled work enabled, the
*/10sweep used to cover this within ten minutes. On the 17.6.0 default (scheduled work off) it never ran anyway. This is handed to the seat for an upstream card. It does not affect the fresh-install acceptance above.Upgraded installs keep the inert
flow-schedule:demo_bootstraprow (Boot D), and the changeset tells operators so.Left untouched on purpose:
src/sales/flows/forecast-snapshot.flow.ts:420("same constraint as demo_bootstrap / case_sla_monitor"), because the dispatch fenced that file;src/service/objects/case.hook.ts:102, which lists "demo bootstrap" among system writers, because it sat in a sibling claim's surface at dispatch time..changeset/objectstack-17-5-0.md, still pending, counts "nine scheduled flows … and demo bootstrap". That is true of that change. If both ship in one release, this changeset's eight is the later state.content/docs/administration/sharing-and-security.mdx:133says a seeded write "keeps first-install intake visible in the tab". Seeded cases are owned once the claim runs (38 of 38 measured), as they were within ten minutes under the sweep. This is pre-existing and not touched.The platform claim covers every object carrying
owner_id: 18 are eligible, includingcrm_productandcrm_event_attendee. The retired flow's header said those two had no column to stamp; measured, they do.Generated by Claude Code