You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
packages: DELETE /api/v1/packages/:id deletes unattributed (no actor), and the in-process deletePackage leaves the per-environment disable record behind #31023
Filing gate: (b) a defect with a named consumer, measured by the objectstack-ai/cloud#3656 dev (PR objectstack-ai/cloud#3686, report on that card). Platform defects go to the platform: 「平台的问题应该在平台处理」 (objectstack#30765).
维护者速读
在 Studio 里删除一个应用时,审计日志记不下是谁删的:删除接口没有把操作人传下去,而发布、回滚等其他包操作都传了。另外,从平台内部调用删除(cloud 的 AI 工具、本地安装、导入都走这条路),不会清掉「此包在本环境已停用」的记录,以后重装同一个包时可能一装上就是停用状态。
Measured (pin c50e0dfa, code read)
runtime/src/domains/packages.ts ~3068: the DELETE arm calls protocol.deletePackage({ packageId, keepData }) with no actor. resolvePackageWriteActor (packages.ts:408, ADR-0146 D1) is used by publish-drafts, discard-drafts, revert, rollback, adopt-orphans and duplicate. The sys_packages delete (package service delete(id)) carries no actor either.
protocol.deletePackage does not clear the per-environment disable record (setPackageDisabled); only the HTTP door clears it.
Expected
The DELETE door resolves the actor as its siblings do, and both the metadata deletes and the sys_packages delete are attributed in sys_audit_log.
Clearing the disable record moves into the uninstall verb, so every caller gets it.
Acceptance
Tests: a Studio delete writes audit rows naming the person; an in-process delete followed by a reinstall leaves the package enabled.
Consumer: objectstack-ai/cloud#3656 (its tool passes an actor and calls the in-process verb).
Suggested-grade: p2.
Dedupe (2026-11-06): package delete actor audit → 363 hits, the top 3 QA runs; deletePackage disable → 22, the top 3 closed (#28408, #27395, #26857 are other uninstall defects). None covers this.
DELETE /api/v1/packages/:id deletes with no actor, while its sibling package doors use resolvePackageWriteActor (ADR-0146 D1). The in-process deletePackage leaves the per-environment disable record behind, so a reinstall can come up disabled. Code read (cloud#3656).
Claim: PM loop round 1
Session: session_017ihL2dLQEXWGsE2SZ3Qn5F
Account: marchtian
Branch: claude/issue-31023-package-delete-actor
Worktree: objectstack-issue-31023
Domain: domain:server
Seat: domain:server#4
File surface: packages/runtime/src/domains/packages.ts (the DELETE /packages/:id arm only), packages/metadata-protocol/src/protocol-package-uninstall.ts (the uninstall verb), packages/runtime/src/package-state-store.ts only if the disable-record clear moves through it, the package service's delete call site that writes sys_packages, their tests, .changeset/ (stop on breach; explain in the report)
Container & model: M, mode:subagent (in-seat background subagent, the project's standing dev form), model: default (dispatch-gates --tier: no path-derived mandate; PM judgment, default tier), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: objectstack (packages/runtime DELETE door + packages/metadata-protocol uninstall verb; platform card per cross-repo rule 1) | no platform path covers it today: sibling doors attribute via resolvePackageWriteActor, this one does not; only the HTTP door clears the disable record | reached by every Studio delete and every in-process deletePackage caller (cloud AI tool, install-local, import — cloud#3656)
Thread-read: 6692904021
Premise: holds
Serial constraints cleared: #31067 / PR #31157 (seat 4) touches packages.ts only at the two exported function declarations and index.ts — region disjoint from the DELETE arm; #30999 (uninstall dependent-rule refusal, same door) is held behind this card; no other open PR touches these files (open-PR file scan, 17 PRs)
{
"pr": {
"number": 31183,
"url": "https://github.com/objectstack-ai/objectstack/pull/31183",
"head": "a6f017e7a7e98df4d7ba715480f0b77c1427f4b5",
"draft": true,
"base_merged": "origin/main at 56baf78e0, merged once before the PR"
},
"premise_still_valid": true,
"files_changed": [
".changeset/31023-package-delete-actor.md",
"packages/runtime/src/app-plugin.ts",
"packages/runtime/src/domains/packages.ts",
"packages/runtime/src/package-state-host-store.ts",
"packages/runtime/src/package-state-host-store.test.ts",
"packages/runtime/src/package-uninstall-store-refusal.integration.test.ts",
"packages/runtime/src/domains/packages-write-actor-session.test.ts",
"packages/runtime/src/domains/packages-write-flag-arity.test.ts",
"packages/runtime/src/domains/packages-write-doors-closed-query.test.ts",
"packages/runtime/src/domains/packages-uninstall-refuse-before-mutate.test.ts",
"packages/runtime/src/domains/packages-orgless-grants-capability-gate.test.ts"
],
"line_budget": "319 changed lines (+303 / -16) in 11 files vs merge base 56baf78e0, under the 3000 human-merge threshold (dispatch-gates reading at a6f017e7a)",
"gates": {
"head": "a6f017e7a",
"derived_local_union": [
"node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0",
"node scripts/check-adr-0087-registration.mjs --self-test :: exit 0",
"node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0",
"node scripts/check-closing-keyword-parity.mjs :: exit 0",
"node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0",
"node scripts/check-comment-mask-adoption.mjs :: exit 0",
"node scripts/check-comment-mask-adoption.mjs --self-test :: exit 0",
"node scripts/check-comment-mask-corpus.mjs :: exit 0",
"node scripts/check-dts-emitted.mjs --self-test :: exit 0",
"node scripts/check-empty-changeset.mjs --base origin/main :: exit 0",
"node scripts/check-empty-changeset.mjs --self-test :: exit 0",
"node scripts/check-issue-citations.mjs :: exit 0",
"node scripts/check-plugin-teardown-shape.mjs :: exit 0",
"node scripts/check-plugin-teardown-shape.mjs --self-test :: exit 0",
"node scripts/ci/assert-turbo-remote-cache.mjs --self-test :: exit 0",
"node scripts/ci/plan-test-core-shards.mjs --self-test :: exit 0",
"node scripts/ci/prune-turbo-cache.mjs --self-test :: exit 0",
"node scripts/ci/snapshot-next.mjs --self-test :: exit 0",
"node scripts/docs-audit/check-affected-docs.mjs :: exit 0",
"node scripts/docs-audit/check-drift-comment.mjs :: exit 0",
"node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0",
"node scripts/release-pending-publish.mjs --self-test :: exit 0",
"pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0",
"pnpm check:changeset-gate-self-tests :: exit 0",
"pnpm check:ci-filter-parity :: exit 0",
"pnpm check:closed-ceremony-text :: exit 0",
"pnpm check:cross-package-test-inputs :: exit 0",
"pnpm check:dispatcher-error-vocabulary :: exit 0",
"pnpm check:doc-authoring :: exit 0",
"pnpm check:driver-memory-census :: exit 0",
"pnpm check:dts-closure :: exit 0",
"pnpm check:dual-build-cjs-loads :: exit 0",
"pnpm check:durability-log-level :: exit 0",
"pnpm check:engine-double-contract :: exit 0",
"pnpm check:error-status-conformance :: exit 0",
"pnpm check:gitlink-declared :: exit 0",
"pnpm check:issue-citations :: exit 0",
"pnpm check:keyed-text-bounds :: exit 0",
"pnpm check:lean-entry-closure :: exit 0",
"pnpm check:logger-receiver-detach :: exit 0",
"pnpm check:nul-bytes :: exit 0",
"pnpm check:objectql-double-limit :: exit 0",
"pnpm check:org-identifier :: exit 0",
"pnpm check:page-declaration-shape :: exit 0",
"pnpm check:platform-object-tenancy-census :: exit 0",
"pnpm check:published-files :: exit 0",
"pnpm check:query-options-erasure :: exit 0",
"pnpm check:refd-timer-probe :: exit 0",
"pnpm check:registry-log-declared :: exit 0",
"pnpm check:rest-log-spy-declared :: exit 0",
"pnpm check:route-envelope :: exit 0",
"pnpm check:slot-lookup :: exit 0",
"pnpm check:sourcemap-no-sources-content :: exit 0",
"pnpm check:stack-collection-maps :: exit 0",
"pnpm check:swallow-census-controls :: exit 0",
"pnpm check:system-context-census :: exit 0",
"pnpm check:test-source-alias :: exit 0",
"pnpm check:tier-file-adoption :: exit 0",
"pnpm check:type-check-coverage :: exit 0",
"pnpm check:type-check-debt :: exit 0",
"pnpm check:undeclared-dep-imports :: exit 0",
"pnpm check:vouch-for-reference-callers :: exit 0",
"pnpm check:watch-hint-literal :: exit 0",
"pnpm check:where-matcher :: exit 0"
],
"ran_reconciliation": "node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ran.txt :: exit 0 -- 64 derived, 64 run, 0 NOT-MEASURED, 0 UNRUN",
"package": [
"pnpm --filter @objectstack/runtime test :: exit 0 (554 files, 8923 passed, 19 skipped; lock VERDICT command-exit 0)",
"pnpm --filter @objectstack/runtime typecheck :: exit 0",
"eslint packages/runtime --no-inline-config (root lint config, touched package) :: exit 0"
],
"first_run_reds_fixed": [
"pnpm check:dual-build-cjs-loads :: exit 3 (PREREQUISITE NOT MET, 36 packages without dist) -> pnpm build :: exit 0 -> rerun exit 0",
"pnpm check:query-options-erasure :: exit 1 (test surface 236 -> 237, an as-any query bag in the new pin) -> cast removed -> exit 0",
"pnpm check:test-source-alias :: exit 1 (edited test files reach a lazy metadata import) -> module-top import added -> exit 0",
"pnpm --filter @objectstack/runtime test :: exit 1 (9 failed in 4 files: exact deletePackage request pins now carrying the signed-in actor) -> fixtures updated -> exit 0"
],
"ci": "PR check-runs at a6f017e7a: 18 in_progress, 3 skipped at report time"
},
"deviations": [
"File surface: app-plugin.ts, package-state-host-store.ts and its test are outside the claim's declared surface (the claim says stop on breach). The order's measure-first clause asked for a seam the verb already runs; registering it needs a plugin lifecycle (AppPlugin.start) and the store resolution lives in package-state-host-store.ts. Four existing test files outside the surface carry stale-fixture updates. Seat to confirm.",
"protocol-package-uninstall.ts (named in the claim) is NOT edited: the verb already forwards actor to each deleteMetaItem and already runs the uninstall-cleanup registry.",
"Lint ran as the root eslint config over packages/runtime with --no-inline-config, not repo-wide pnpm lint (CI-owned).",
"test:repo (vitest repo project) not run locally; CI Test Core carries it.",
"Dogfood battery not run: no ! in the title and no (narrowing) arm."
],
"open_questions": [
{
"question": "The card's Expected also asks that the sys_packages delete be attributed in sys_audit_log. sys_packages is not an object: service-package deletes the row with raw SQL through engine.execute, which runs no hooks, so no sys_audit_log row exists for that delete with or without an actor. How should that half land?",
"options": [
"A: accept the metadata-row attribution as this card's audit acceptance (each removed row names the person) and file a separate card for a package-lifecycle audit row (install/uninstall/enable/disable)",
"B: widen this PR: an actor on PackageService.delete plus a new audit writer for the sys_packages delete (a signature change and a new audited surface; Clause-2 would need re-declaring)",
"C: keep Fixes as is but re-word the PR to Part of #31023 and leave the card open for that half"
],
"recommendation": "A, because the half cannot be met by passing an actor (there is no audited write to attribute), the person is already named on every metadata row the uninstall removes, and a package-lifecycle audit row is a design question of its own"
},
{
"question": "With the clear in the verb, a DELETE of an id that is neither installed nor stored (the door answers 404) now clears a disable record naming that id; before, a 404 wrote nothing. Accept?",
"options": [
"A: accept: by the #18877 item-3 ruling a package that no longer exists has no lifecycle state",
"B: guard it: needs an existence signal on the uninstall-cleanup arguments (a contract change on an exported type)"
],
"recommendation": "A, because B widens an exported type for a record that names nothing installed"
}
],
"out_of_scope_findings": [
"carrier: none · noted, not filed: the package-door unit pins whose deletePackage double answers no cleanups (packages-write-flag-arity, packages-write-doors-closed-query) make the door write the disable-state file under the real OS_HOME, since neither file sets OS_HOME; pre-existing test hygiene, not a product defect"
],
"mcp_calls": "0",
"api_writes": "2 -- relay pr_create (POST /repos/objectstack-ai/objectstack/pulls + POST /repos/objectstack-ai/objectstack/issues/31183/assignees), and this comment via post-stamped (POST /repos/objectstack-ai/objectstack/issues/31023/comments)",
"security_findings": "none"
}
Landed · PR #31183 merged by the merge queue as 4c3182140e4e8de389613befb17a871c49f46ee5.
Reading
Value
PR state
merged, merged_at from the pulls API
Card state
closed completed by Fixes #31023
origin/main content
PACKAGE_STATE_UNINSTALL_CLEANUP in packages/runtime/src/package-state-host-store.ts
pm:dispatched removed with this record. The sys_packages audit half is #31186. #30999 (uninstall dependent-rule refusal on the same door) is unblocked.
Activity
objectstack-fleet commentedon Nov 6, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: audit · p2 kept ·
domain:server· 2026-11-06T18:57Z⛔ Not a claim.
DELETE /api/v1/packages/:iddeletes with no actor, while its sibling package doors useresolvePackageWriteActor(ADR-0146 D1). The in-processdeletePackageleaves the per-environment disable record behind, so a reinstall can come up disabled. Code read (cloud#3656).domain:server,pm:queuekept. It touches the same door as runtime: uninstalling a package (DELETE /packages/:id) withdraws its extension fields with no scan, so another package's active validation rule that reads one breaks every write (#30379 follow-up) #30999 (an uninstall dependent-rule refusal). The two are independent, but whichever seat takes the second should re-read the first's PR.Generated by Claude Code
objectstack-fleet commentedon Nov 7, 2026
domain:server#4 · marchtian · session_017ihL2dLQEXWGsE2SZ3Qn5F
Claim: PM loop round 1
Session:
session_017ihL2dLQEXWGsE2SZ3Qn5FAccount:
marchtianBranch:
claude/issue-31023-package-delete-actorWorktree:
objectstack-issue-31023Domain:
domain:serverSeat:
domain:server#4File surface:
packages/runtime/src/domains/packages.ts(theDELETE /packages/:idarm only),packages/metadata-protocol/src/protocol-package-uninstall.ts(the uninstall verb),packages/runtime/src/package-state-store.tsonly if the disable-record clear moves through it, the package service'sdeletecall site that writessys_packages, their tests,.changeset/(stop on breach; explain in the report)Container & model:
M,mode:subagent(in-seat background subagent, the project's standing dev form),model: default(dispatch-gates --tier: no path-derived mandate; PM judgment, default tier),effort: highClause-②: no
Metadata-protocol: none
Responsibility: objectstack (
packages/runtimeDELETE door +packages/metadata-protocoluninstall verb; platform card per cross-repo rule 1) | no platform path covers it today: sibling doors attribute viaresolvePackageWriteActor, this one does not; only the HTTP door clears the disable record | reached by every Studio delete and every in-processdeletePackagecaller (cloud AI tool, install-local, import — cloud#3656)Thread-read: 6692904021
Premise: holds
Serial constraints cleared: #31067 / PR #31157 (seat 4) touches
packages.tsonly at the two exported function declarations andindex.ts— region disjoint from the DELETE arm; #30999 (uninstall dependent-rule refusal, same door) is held behind this card; no other open PR touches these files (open-PR file scan, 17 PRs)objectstack-fleet commentedon Nov 7, 2026
domain:server#4 · marchtian · session_017ihL2dLQEXWGsE2SZ3Qn5F
os-dev-report
{ "pr": { "number": 31183, "url": "https://github.com/objectstack-ai/objectstack/pull/31183", "head": "a6f017e7a7e98df4d7ba715480f0b77c1427f4b5", "draft": true, "base_merged": "origin/main at 56baf78e0, merged once before the PR" }, "premise_still_valid": true, "files_changed": [ ".changeset/31023-package-delete-actor.md", "packages/runtime/src/app-plugin.ts", "packages/runtime/src/domains/packages.ts", "packages/runtime/src/package-state-host-store.ts", "packages/runtime/src/package-state-host-store.test.ts", "packages/runtime/src/package-uninstall-store-refusal.integration.test.ts", "packages/runtime/src/domains/packages-write-actor-session.test.ts", "packages/runtime/src/domains/packages-write-flag-arity.test.ts", "packages/runtime/src/domains/packages-write-doors-closed-query.test.ts", "packages/runtime/src/domains/packages-uninstall-refuse-before-mutate.test.ts", "packages/runtime/src/domains/packages-orgless-grants-capability-gate.test.ts" ], "line_budget": "319 changed lines (+303 / -16) in 11 files vs merge base 56baf78e0, under the 3000 human-merge threshold (dispatch-gates reading at a6f017e7a)", "gates": { "head": "a6f017e7a", "derived_local_union": [ "node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0", "node scripts/check-adr-0087-registration.mjs --self-test :: exit 0", "node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0", "node scripts/check-closing-keyword-parity.mjs :: exit 0", "node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0", "node scripts/check-comment-mask-adoption.mjs :: exit 0", "node scripts/check-comment-mask-adoption.mjs --self-test :: exit 0", "node scripts/check-comment-mask-corpus.mjs :: exit 0", "node scripts/check-dts-emitted.mjs --self-test :: exit 0", "node scripts/check-empty-changeset.mjs --base origin/main :: exit 0", "node scripts/check-empty-changeset.mjs --self-test :: exit 0", "node scripts/check-issue-citations.mjs :: exit 0", "node scripts/check-plugin-teardown-shape.mjs :: exit 0", "node scripts/check-plugin-teardown-shape.mjs --self-test :: exit 0", "node scripts/ci/assert-turbo-remote-cache.mjs --self-test :: exit 0", "node scripts/ci/plan-test-core-shards.mjs --self-test :: exit 0", "node scripts/ci/prune-turbo-cache.mjs --self-test :: exit 0", "node scripts/ci/snapshot-next.mjs --self-test :: exit 0", "node scripts/docs-audit/check-affected-docs.mjs :: exit 0", "node scripts/docs-audit/check-drift-comment.mjs :: exit 0", "node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0", "node scripts/release-pending-publish.mjs --self-test :: exit 0", "pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0", "pnpm check:changeset-gate-self-tests :: exit 0", "pnpm check:ci-filter-parity :: exit 0", "pnpm check:closed-ceremony-text :: exit 0", "pnpm check:cross-package-test-inputs :: exit 0", "pnpm check:dispatcher-error-vocabulary :: exit 0", "pnpm check:doc-authoring :: exit 0", "pnpm check:driver-memory-census :: exit 0", "pnpm check:dts-closure :: exit 0", "pnpm check:dual-build-cjs-loads :: exit 0", "pnpm check:durability-log-level :: exit 0", "pnpm check:engine-double-contract :: exit 0", "pnpm check:error-status-conformance :: exit 0", "pnpm check:gitlink-declared :: exit 0", "pnpm check:issue-citations :: exit 0", "pnpm check:keyed-text-bounds :: exit 0", "pnpm check:lean-entry-closure :: exit 0", "pnpm check:logger-receiver-detach :: exit 0", "pnpm check:nul-bytes :: exit 0", "pnpm check:objectql-double-limit :: exit 0", "pnpm check:org-identifier :: exit 0", "pnpm check:page-declaration-shape :: exit 0", "pnpm check:platform-object-tenancy-census :: exit 0", "pnpm check:published-files :: exit 0", "pnpm check:query-options-erasure :: exit 0", "pnpm check:refd-timer-probe :: exit 0", "pnpm check:registry-log-declared :: exit 0", "pnpm check:rest-log-spy-declared :: exit 0", "pnpm check:route-envelope :: exit 0", "pnpm check:slot-lookup :: exit 0", "pnpm check:sourcemap-no-sources-content :: exit 0", "pnpm check:stack-collection-maps :: exit 0", "pnpm check:swallow-census-controls :: exit 0", "pnpm check:system-context-census :: exit 0", "pnpm check:test-source-alias :: exit 0", "pnpm check:tier-file-adoption :: exit 0", "pnpm check:type-check-coverage :: exit 0", "pnpm check:type-check-debt :: exit 0", "pnpm check:undeclared-dep-imports :: exit 0", "pnpm check:vouch-for-reference-callers :: exit 0", "pnpm check:watch-hint-literal :: exit 0", "pnpm check:where-matcher :: exit 0" ], "ran_reconciliation": "node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ran.txt :: exit 0 -- 64 derived, 64 run, 0 NOT-MEASURED, 0 UNRUN", "package": [ "pnpm --filter @objectstack/runtime test :: exit 0 (554 files, 8923 passed, 19 skipped; lock VERDICT command-exit 0)", "pnpm --filter @objectstack/runtime typecheck :: exit 0", "eslint packages/runtime --no-inline-config (root lint config, touched package) :: exit 0" ], "first_run_reds_fixed": [ "pnpm check:dual-build-cjs-loads :: exit 3 (PREREQUISITE NOT MET, 36 packages without dist) -> pnpm build :: exit 0 -> rerun exit 0", "pnpm check:query-options-erasure :: exit 1 (test surface 236 -> 237, an as-any query bag in the new pin) -> cast removed -> exit 0", "pnpm check:test-source-alias :: exit 1 (edited test files reach a lazy metadata import) -> module-top import added -> exit 0", "pnpm --filter @objectstack/runtime test :: exit 1 (9 failed in 4 files: exact deletePackage request pins now carrying the signed-in actor) -> fixtures updated -> exit 0" ], "ci": "PR check-runs at a6f017e7a: 18 in_progress, 3 skipped at report time" }, "deviations": [ "File surface: app-plugin.ts, package-state-host-store.ts and its test are outside the claim's declared surface (the claim says stop on breach). The order's measure-first clause asked for a seam the verb already runs; registering it needs a plugin lifecycle (AppPlugin.start) and the store resolution lives in package-state-host-store.ts. Four existing test files outside the surface carry stale-fixture updates. Seat to confirm.", "protocol-package-uninstall.ts (named in the claim) is NOT edited: the verb already forwards actor to each deleteMetaItem and already runs the uninstall-cleanup registry.", "Lint ran as the root eslint config over packages/runtime with --no-inline-config, not repo-wide pnpm lint (CI-owned).", "test:repo (vitest repo project) not run locally; CI Test Core carries it.", "Dogfood battery not run: no ! in the title and no (narrowing) arm." ], "open_questions": [ { "question": "The card's Expected also asks that the sys_packages delete be attributed in sys_audit_log. sys_packages is not an object: service-package deletes the row with raw SQL through engine.execute, which runs no hooks, so no sys_audit_log row exists for that delete with or without an actor. How should that half land?", "options": [ "A: accept the metadata-row attribution as this card's audit acceptance (each removed row names the person) and file a separate card for a package-lifecycle audit row (install/uninstall/enable/disable)", "B: widen this PR: an actor on PackageService.delete plus a new audit writer for the sys_packages delete (a signature change and a new audited surface; Clause-2 would need re-declaring)", "C: keep Fixes as is but re-word the PR to Part of #31023 and leave the card open for that half" ], "recommendation": "A, because the half cannot be met by passing an actor (there is no audited write to attribute), the person is already named on every metadata row the uninstall removes, and a package-lifecycle audit row is a design question of its own" }, { "question": "With the clear in the verb, a DELETE of an id that is neither installed nor stored (the door answers 404) now clears a disable record naming that id; before, a 404 wrote nothing. Accept?", "options": [ "A: accept: by the #18877 item-3 ruling a package that no longer exists has no lifecycle state", "B: guard it: needs an existence signal on the uninstall-cleanup arguments (a contract change on an exported type)" ], "recommendation": "A, because B widens an exported type for a record that names nothing installed" } ], "out_of_scope_findings": [ "carrier: none · noted, not filed: the package-door unit pins whose deletePackage double answers no cleanups (packages-write-flag-arity, packages-write-doors-closed-query) make the door write the disable-state file under the real OS_HOME, since neither file sets OS_HOME; pre-existing test hygiene, not a product defect" ], "mcp_calls": "0", "api_writes": "2 -- relay pr_create (POST /repos/objectstack-ai/objectstack/pulls + POST /repos/objectstack-ai/objectstack/issues/31183/assignees), and this comment via post-stamped (POST /repos/objectstack-ai/objectstack/issues/31023/comments)", "security_findings": "none" }objectstack-fleet commentedon Nov 7, 2026
domain:server#4 · marchtian · session_017ihL2dLQEXWGsE2SZ3Qn5F
Landed · PR #31183 merged by the merge queue as
4c3182140e4e8de389613befb17a871c49f46ee5.merged_atfrom the pulls APIcompletedbyFixes #31023origin/maincontentPACKAGE_STATE_UNINSTALL_CLEANUPinpackages/runtime/src/package-state-host-store.tspm:dispatchedremoved with this record. Thesys_packagesaudit half is #31186. #30999 (uninstall dependent-rule refusal on the same door) is unblocked.