Project resource and entry-point inventory
This inventory records the project boundary found in source inspection for T1. It is an implementation input for AC11, not a claim that all rows are already scoped.
Scan evidence
The inventory was produced from the repository with these checks:
for f in packages/models/src/schema/*.ts; do
rg -q 'project_id' "$f" && echo "$f"
done
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
The first scan returned these eight project-bearing tables: applications, assets, image_documents, js_scripts, predictions, scripts, storyboards, and timeline_sequences. The schema directory also contains non-project tables for threads, messages, jobs, run_events, run_inbox_messages, workflows, workflow_versions, and workspaces, so the scan found actual candidates outside the current project summary union.
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; web project section and mention picker |
useEntities.ts, entity capability, ProjectEntitiesSection.tsx; 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 has workspace_id but no project_id; workflow versions/shares/collaborators also 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 workflow and access grants; workspace deletion refuses linked workflows |
Project-owned under D3, while reusable templates remain global under D5. Add an explicit project owner for saved workflows, migrate existing rows to Personal, and keep example/templates as global copy sources. Shared/public workflow semantics need an explicit project rule. |
| Threads and messages | nodetool_threads has workflow_id only; nodetool_messages.thread_id only. A project row has one optional thread_id. |
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, 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 and must support multiple threads. Add project_id to threads, migrate projects.thread_id to a project association without losing history, and require thread project context for message and tool operations. |
| Runs and background jobs | jobs is keyed by workflow_id and execution IDs; run_events and inbox rows key off run_id; no project column. Runtime run types and generation tracker carry optional project IDs. |
Workflow runner, packages/execution/src/service/workflow-run.ts, session/cost ledger/generation tracker, websocket job routes, web WorkflowRunsStore/LiveRunStore, mobile Jobs screens |
Jobs router and live WebSocket events; prediction ledger queries | Job cancellation removes/stops execution; run events/inbox are execution records and are not project-deleted by Project.deleteOwned |
Project-owned execution context. Persist project ID at job/run creation, carry it through events and retries, and use it to route activity after a project switch. Deletion must wait for or cancel active runs and prevent retries from writing. |
| 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 stores user/path/default; 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 list/listFiles/readFile and agent workspace.list; local and cloud implementations share the runtime interface |
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 or rooted in a project namespace. Preserve local/cloud parity through Workspace.read/write/list/stat/copy/move/delete; do not use localDir as the ownership mechanism. Migrate existing files to Personal or record an explicit mapping. |
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. Workspace rows are not global merely because they are user-owned today; their project-file role needs the boundary above.
Cross-project references and move behavior
Q10 is unresolved in the current implementation. Document JSON and asset metadata can name assets, workflows, timelines, scripts, or entities without a database-level project foreign key. Existing rows therefore need a migration audit: retain assigned ownership, map unassigned references to Personal when the target is unambiguous, and mark ambiguous cross-project references for an explicit compatibility decision. Do not create a shared project as an accidental result.
Q11 is also unresolved. There is no generic document dependency copier in the inspected paths. workspace.copy copies files only, while Project.assignDocument moves one document/entity by changing project_id. A copy implementation must walk each supported document’s references, deduplicate repeated asset/entity dependencies within one operation, rewrite internal IDs, and fail before committing when a dependency type cannot be copied.
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. Future moves need either dependency-aware rewrites or a refusal with the affected references; a move must not silently break another project’s document.
Current gaps that are 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 all seven membership tables, including all assets, to default, but does not archive, cancel active work, delete threads, remove workspace files, or reconcile prediction/output ownership. Project also has one thread_id, which cannot represent D9’s multiple independent conversations.
Electron has workflow-only consumers and no project selector or project argument in its workflow fetch/tray paths. Mobile has an application project filter and project-shaped app documents, but its document backends and most screens still use default or unscoped lists. These clients must consume the same project-scoped API contracts as web rather than inventing separate ownership rules.