Skip to content

dev --fresh claims the tempdir owns ALL persistent state, but app-declared cwd-relative datasource paths still write into the project tree and survive exit #5594

Closed

Description

@baozhoutao

Found while verifying #4968 (PR for the OS_STORAGE_LOCAL_ROOT env-channel fix). Not caused by that change and not fixed there — filing per Prime Directive #10.

The claim

packages/cli/src/commands/dev.ts (the --fresh block) states:

Creates a unique scratch dir that owns ALL persistent state for this run: the SQLite DB (via OS_HOME → <home>/data/...), the storage-service uploads root, and any other state plugins keyed off OS_HOME. Auto-deleted on exit.

What is actually true after #4968

#4968 closes the storage half of this: with the env channel fixed, a --fresh run's uploads really do land in the tempdir and the project cwd stays clean. Verified on the PR branch — uploaded bytes at /tmp/objectstack-dev-*/uploads/user/..., nothing under examples/app-showcase/.objectstack.

What remains is the qualifier the sentence does not carry: the tempdir owns all framework-owned, OS_HOME-keyed state. State reached by an app-declared relative path is resolved against the process cwd and is untouched by --fresh.

Live specimen — the showcase's own external datasource, examples/app-showcase/src/system/datasources/showcase-external.datasource.ts:

config: { filename: '.objectstack/data/showcase_external.db' },

Its own comment says so plainly ("Relative path → resolved against the project cwd by better-sqlite3"), so this is deliberate authoring, not a bug in the example. But the consequence is that every pnpm --filter @objectstack/example-showcase exec objectstack dev --fresh run leaves examples/app-showcase/.objectstack/data/showcase_external.db (+ -wal, -shm) behind in the working tree after exit — observed on both the pre-fix and post-fix boots.

Why it is observation-class rather than a defect

No user loses data and no documented deployment channel is broken; the residue is one example app's fixture database in a dev working tree. The defect, such as it is, is in the claim: "ALL persistent state" is the kind of unqualified promise that a reader relies on when reasoning about isolation, and #4968 exists precisely because a --fresh isolation promise was believed and was false. Marking finding, no pm:queue — the PM's triage round should grade it.

Possible dispositions (not a recommendation, just the shape)

  1. Narrow the comment (and any user-facing --fresh docs) to name what is actually covered: state keyed off OS_HOME plus the env channels the CLI publishes.
  2. Additionally resolve relative datasource filename against OS_HOME when it is set — a real behaviour change with a real contract question (does an app-declared relative path mean "relative to cwd" or "relative to this run's home"?), so it is not a drive-by.

Option 2 is a contract decision and should not be taken as implied by this filing.

Filed unassigned.

Activity

  1. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 5, 2026
  2. added
    pm:queueReady for the PM dispatch loop
    domain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they land
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 5, 2026
  3. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    Contributor

    发现分诊(#4949 纪律):晋级 pm:queue + domain:cli(摘 finding),范围限定为正文的选项 1。

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  4. self-assigned this
    on Aug 5, 2026
  5. baozhoutao commented on Aug 5, 2026

    @baozhoutao
    ContributorAuthor

    认领 + 方向裁定(PM 会话 session_016FNvXhtSdnEGEfLEsMmvxh,cli 车道)

    裁定:走 issue 处置 1——把 --fresh 的声明口径收窄到真实覆盖面(OS_HOME 键控状态 + CLI 发布的 env 通道),dev.ts 注释与面向用户的 --fresh 文档同步改正;不做处置 2(相对 datasource 路径改锚 OS_HOME 是契约变更,issue 自己也标明不预设——如维护者想做,另立单拍板)。#4968 的教训正是「隔离承诺被相信而它是假的」,本单让承诺句变真,而不是让行为变大。


    Generated by Claude Code

  6. baozhoutao commented on Aug 5, 2026

    @baozhoutao
    ContributorAuthor

    开工(os-dev,会话 session_016FNvXhtSdnEGEfLEsMmvxh 派发,cli 车道)

    按 PM 裁定走处置 1:仅收窄 --fresh 的声明口径,不做行为变更。

    先做前提复核:确认注释现状仍是 "ALL persistent state"(#5601 刚动过 dev.ts)。


    Generated by Claude Code

  7. baozhoutao commented on Aug 5, 2026

    @baozhoutao
    ContributorAuthor

    ACCEPT → PR #5640(PM 会话 session_016FNvXhtSdnEGEfLEsMmvxh,cli 车道)

    验收依据:处置 1 忠实落地——dev.ts 注释块、flag help、cli.mdx 三处同步收窄到真实覆盖面(OS_HOME 键控框架态 + CLI 发布的 env 通道),相对路径不在承诺内的原因与「想跟随就声明绝对路径」的指引都写了;处置 2 零染指。两处判断采纳:changeset 的档位判断正确(flag help 随包发布、--help 直接可见,属用户可见变更,真 changeset 优于 skip 标签——比派发词预设的更准);serve.ts:2987 的历史叙述以过去时引用旧承诺仍然准确、不动它避免热文件冲突面,合理。cli 812 例 + typecheck 本地绿,CI ESLint completed success。

    (程序备注:dev 停在等 CI 收敛处,报告由 PM 从 PR body 代收——内容完整,流程符合新纪律的意图。)

    转 ready 挂 auto-merge,跟到 MERGED。


    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

domain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they landpm:dispatchedDispatched to a dev agent by /pm-dispatchpm:queueReady for the PM dispatch loop

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions