Project resource and entry-point inventory

This inventory records the project boundary found in source inspection for T1. The original findings are retained below; the final verification result is at Final verification.

Scan evidence

The inventory was produced from the repository with these checks:

set -euo pipefail
project_tables=$(for f in packages/models/src/schema/*.ts; do
  if rg -q 'project_id' "$f"; then printf '%s\n' "$f"; fi
done)
test -n "$project_tables"
printf '%s\n' "$project_tables"
surface_files=$(rg -l 'projectId|project_id|useProjects|trpcClient\\.(project|asset|entity|workflow|thread|workspace)' \
  web/src electron/src mobile/src packages/agents/src packages/websocket/src || true)
test -n "$surface_files"
printf '%s\n' "$surface_files"

The first scan returned these 12 project-bearing tables: applications, assets, image_documents, jobs, js_scripts, predictions, scripts, storyboards, threads, timeline_sequences, workflows, and workspaces. The schema directory also contains dependent tables without their own project column, including messages, run_events, run_inbox_messages, workflow_versions, and workflow sharing tables. Those rows inherit ownership through their parent thread, job, or workflow and must be covered by the parent lifecycle.

Historical T1 resource inventory

Resource Storage and current ownership References and creation paths List/search paths Delete behavior Planned project boundary and migration
Storyboards storyboards.project_id in packages/models/src/schema/storyboards.ts; Storyboard model JSON shot refs include asset refs. Create/update via packages/websocket/src/trpc/routers/storyboards.ts, REST timeline/example helpers, and agent capabilities/storyboards.ts Storyboard.find, router procedures, listProjectDocuments and summarizeProject Model delete and router delete Project-owned. Keep existing IDs, assign null/legacy rows to Personal. Reads and writes must require the owning project. Copy must remap referenced assets.
Scripts scripts.project_id; Script model Script sections and takes reference media and entities. Create/update via routers/scripts.ts and agent capabilities/scripts.ts Script router/model and listProjectDocuments Model/router delete Project-owned. Migrate unassigned rows to Personal. Moving requires checking storyboard/timeline links and preserving or rewriting referenced dependencies.
Timelines timeline_sequences.project_id; TimelineSequence and version tables Timeline document contains clip asset refs, script links, and generated outputs. Create/update via routers/timeline.ts, REST routes/timelines.ts, and agent capabilities/timelines.ts Timeline router/model and listProjectDocuments Model/router delete; versions follow the sequence’s document lifecycle Project-owned. Migrate the sequence and versions together. Copy must include referenced assets and linked project documents or return an unsupported-dependency error.
Image documents / sketches image_documents.project_id; ImageDocument model Canvas document and versions reference assets. Create/update via routers/sketch.ts and agent capabilities/sketches.ts Sketch router/model and listProjectDocuments Model/router delete; versions follow the document Project-owned. Migrate document plus versions. Copy needs asset remapping.
Applications / mini-app documents applications.project_id; application document may reference workflows/assets. routers/applications.ts, routes/applications.ts, web/src/hooks/useApplications.ts, mobile services/api.ts and useApplications.ts, agent capabilities/apps.ts Application router/REST and mobile listApplications(projectId?) Application service/model delete Project-owned under D3. Migrate existing application rows. Mobile currently supports an optional project filter but defaults to default; pass explicit project context on every creation and list.
JavaScript scripts js_scripts.project_id; JsScript model and versions Create/update via routers/js-scripts.ts, REST routes/js-scripts.ts, web sync hook, and agent capabilities/js-scripts.ts Router/model and agent capability Router/model delete; versions are document-owned Project-owned. Migrate rows and versions. Agent and web calls need an originating project rather than a default fallback.
Entities Entity marker stored in an asset’s metadata; entity ownership is assets.project_id. Entity creation/update in agent capabilities/entities.ts and packages/models/src/entity.ts; mention picker useEntities.ts, entity capability; entity search currently has a shared-library path Asset delete; project move uses moveDocumentToProject(..., "entity", ...) Project-owned per D3. Migrate marked assets only. Search, mentions, and agent queries must filter by project. Do not treat unmarked assets as entities.
General assets and folders nodetool_assets; parent_id forms the asset folder tree. project_id defaults to default, but current code documents that only entities are shown per project. Upload/finalize through asset tRPC, REST routes/assets.ts, web AssetStore, workflow outputs and agent media/binary-output tools. Folder operations use asset parent IDs. Asset router list, recursive, search, web AssetStore and mobile asset screens Asset delete removes the asset row and stored file according to asset service behavior Project-owned under D3, including folders. Migrate every asset and preserve parent_id relationships. Define whether generated assets inherit the run’s project and make every asset list/search project-scoped.
Workflows nodetool_workflows.project_id owns saved workflows; workflow versions/shares/collaborators inherit through workflow_id and have no project column. Web workflow manager/editor, mobile graph editor and workflow screens, Electron api.ts/preload/tray, REST routes/workflows.ts, tRPC workflows router, agent capabilities/workflows.ts, imports/templates Workflow model/router, REST examples/public/tools/name endpoints, mobile and Electron workflow lists Workflow.deleteOwned removes the workflow and access grants; workspace deletion refuses linked workflows Project-owned under D3, while reusable templates and examples remain global under D5. Migrate default workflows to Personal and preserve parent ownership for versions and sharing rows. Public/collaborative access must not bypass the owning project boundary.
Threads and messages nodetool_threads.project_id owns thread containers; nodetool_messages.thread_id inherits that ownership. A project row still has one optional thread_id for its legacy agent conversation. Thread/message models and packages/websocket/src/trpc/routers/threads.ts; web GlobalChatStore, chat hooks/components; mobile ChatStore, ThreadsScreen; project ensureThread creates one agent thread Thread.paginate filters user and optional workflow but not project; message list is thread-scoped Thread router deletes messages and thread; agent tools are read-only for thread deletion Chats are project-owned. Migrate legacy projects.thread_id associations before claiming default threads, then add project-aware list and operation checks for multiple threads per project.
Runs and background jobs nodetool_jobs.project_id owns the execution record; run_events and inbox rows inherit through run_id. Job.create in packages/websocket/src/headless-job-runner.ts and session/job-execution.ts, workflow runner, job control routes, agent capabilities/jobs.ts, web WorkflowRunsStore/LiveRunStore, mobile Jobs screens Job model/router and live WebSocket events; prediction ledger queries Job cancellation stops execution, but Project.deleteOwned does not currently cancel or reassign jobs, events, or inbox rows Project-owned execution context. Keep the project ID through creation, events, retries, and activity routing. Deletion must wait for or cancel active runs and prevent retries from writing before removing or retaining their history.
Predictions / generated outputs predictions.project_id and document_id are nullable; asset_ids records generated asset IDs. Outputs are normally asset rows plus chat/message output refs. packages/execution/src/generation-tracker.ts, cost ledger, provider generation paths, agent media and binary-output tools, chat turn Prediction model/router/cost ledger and asset list; project summary only includes spend, not output resources Prediction rows are history. Project delete currently leaves rows with the deleted project ID; assets are reassigned by the broad asset update Project-owned when created by a project run or document. Migrate nullable legacy rows by thread/job/document where unambiguous, otherwise Personal. Keep output asset ownership and prediction ownership consistent; never leave a completed output pointing only at a deleted project.
Workspace files and folders nodetool_workspaces.project_id owns the workspace row; files live behind runtime Workspace (local directory or cloud object prefix), not in project tables. Web useWorkspaces, workspace components, tRPC routers/workspace.ts, REST download, agent capabilities/files.ts, CodeAct workspace.*, workflow workspace service, mobile app-runtime consumers Workspace.paginate currently filters only by user; listFiles/readFile operate through the selected workspace; agent workspace.list Workspace row delete is blocked for default and linked workflows; file delete is available through workspace APIs Project-owned files must be explicitly associated with a project. Preserve local/cloud parity through Workspace.read/write/list/stat/copy/move/delete, add project-aware workspace listing and cleanup, and do not use localDir as the ownership mechanism. Migrate existing default workspaces and their files to Personal.

Global resources

These remain outside project ownership under D5: account settings and personal-data tables (settings, credentials, secrets, OAuth tokens), installed model/provider metadata, and reusable workflow/template examples. A template import creates a new project-owned workflow/document. Dependent rows such as messages, run events, and workflow versions are not global just because they lack project_id; they inherit the parent resource’s project.

Cross-project references and move behavior

Q10 is partially resolved by the current migration. Project.migrateToPersonal claims default or null rows in all 12 project-bearing resource tables, restores legacy project-thread links, and assigns jobs from already-owned workflows before claiming remaining rows. It reports dangling non-default project ids without moving them. Document JSON and asset metadata can still name assets, workflows, timelines, scripts, or entities without a database-level project foreign key, so ambiguous cross-project references need an explicit repair result. Do not create a shared project as an accidental result.

Q11 is resolved as a copy boundary even though the implementation is still absent. A project-document copy must recursively include referenced assets and entity assets, plus linked project documents where the source format names one: storyboard shots, script media and entities, timeline clips and linked scripts, sketch canvas assets, application resources and workflows, JavaScript script dependencies, and workflow graph resources. Repeated references reuse one destination identity, all internal ids are rewritten before commit, and unsupported or missing dependencies fail the operation without a partial copy. Threads, jobs, predictions, and workspace files are not implicit document dependencies; copying a workspace file is an explicit Workspace.copy operation with the destination project’s workspace.

Q13 has a concrete current entry point: packages/models/src/project-membership.ts and packages/websocket/src/trpc/routers/projects.ts allow moving storyboard, script, timeline, sketch, application, JavaScript script, and entity resources. The move changes ownership without updating references and does not check dependents. Workflows, jobs, threads, and workspaces have project columns but are not in that move union. Future moves need either dependency-aware rewrites or a refusal with the affected references; a move must not silently break another project’s document.

Historical T1 gaps outside the project summary union

ProjectDocumentType covers storyboard, script, timeline, sketch, application, and JavaScript script. It does not cover workflows, folders/general assets, threads/messages, workspace files, jobs/runs, or generated output assets. Project.deleteOwned reassigns only the seven membership tables in project-membership.ts to default, including assets. It does not archive, cancel active work, delete workflows, threads, or workspace files, or reconcile prediction/output ownership. Project also has one thread_id, which cannot represent D9’s multiple independent conversations.

Electron had workflow-only consumers and no project selector or project argument in its workflow fetch/tray paths. Mobile had an application project filter and project-shaped app documents, but its document backends and most screens used default or unscoped lists. These clients needed the same project-scoped API contracts as web rather than separate ownership rules.

Final verification

The scan’s 12 direct ownership tables are all present in both Project.migrateToPersonal and Project.deleteOwned: applications, assets, image documents, jobs, JavaScript scripts, predictions, scripts, storyboards, threads, timeline sequences, workflows, and workspaces. Messages, run events, run inbox rows, workflow versions, and sharing rows inherit their parent’s ownership and lifecycle.

The scoped entry points are web project selection and resource queries, tRPC resource/document routers, agent capability runs, job and chat execution, Electron’s shared workspace shell, and mobile document transports. Mobile has no project selector in this release, but documentBackend(kind, projectId) forwards its supplied scope through every list and creation request. Unscoped callers retain their existing behavior. mobile/src/documents/__tests__/backends.test.ts verifies every document kind’s scoped list and creation path.

No additional project-owned type was omitted from this final scan. Existing mobile callers without project navigation retain their unscoped legacy path; they can pass ownership through the documented transport contract without a mobile navigation redesign. Global settings, credentials, installed models, and reusable templates remain deliberately outside the project boundary.