This commit is contained in:
@@ -0,0 +1,229 @@
|
||||
# Add workspace file provenance so agents can identify which task created or owns files
|
||||
|
||||
## Summary
|
||||
|
||||
Persistent workspaces make it harder to tell which task created, uploaded, or
|
||||
modified a file. This is especially confusing when multiple tasks share the same
|
||||
workspace tree. The agent may see a file and assume it belongs to the current
|
||||
task, even though it was an input or output from a different task.
|
||||
|
||||
Add a file provenance ledger so both users and agents can answer:
|
||||
|
||||
- Which task created this file?
|
||||
- Was this uploaded by the user or generated by an agent?
|
||||
- Which task last modified it?
|
||||
- Is it safe for the current task to edit, or should it be treated as read-only
|
||||
context?
|
||||
|
||||
## Problem
|
||||
|
||||
In persistent workspace mode, files can outlive a single task. That is useful,
|
||||
but it creates ambiguity:
|
||||
|
||||
- old input files remain visible to later tasks
|
||||
- previous task outputs look like current task artifacts
|
||||
- generated files and uploaded files are not clearly distinguished
|
||||
- agents may edit or rely on files that belong to unrelated tasks
|
||||
- users cannot easily audit why a file exists
|
||||
|
||||
Current workspace/runtime separation helps logs:
|
||||
|
||||
- `workspace_path` points to the shared files tree
|
||||
- `runtime_dir` separates per-task logs/checklists/raw outputs
|
||||
|
||||
But shared workspace files themselves do not have provenance metadata.
|
||||
|
||||
## Proposed Design
|
||||
|
||||
Add a sidecar provenance ledger for files in persistent workspaces.
|
||||
|
||||
Prefer a DB-backed table for queryability, with optional JSONL export for
|
||||
debugging. Do not write task tags into file contents.
|
||||
|
||||
### Schema
|
||||
|
||||
Suggested table:
|
||||
|
||||
```sql
|
||||
CREATE TABLE workspace_file_provenance (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
space_id TEXT,
|
||||
workspace_path TEXT NOT NULL,
|
||||
rel_path TEXT NOT NULL,
|
||||
created_by_task_id INTEGER,
|
||||
created_by_job_id TEXT,
|
||||
created_by_piece TEXT,
|
||||
created_by_movement TEXT,
|
||||
source_kind TEXT NOT NULL,
|
||||
first_seen_at TEXT NOT NULL,
|
||||
last_modified_by_task_id INTEGER,
|
||||
last_modified_by_job_id TEXT,
|
||||
last_modified_at TEXT,
|
||||
checksum TEXT,
|
||||
note TEXT,
|
||||
UNIQUE(workspace_path, rel_path)
|
||||
);
|
||||
```
|
||||
|
||||
Suggested `source_kind` values:
|
||||
|
||||
- `user_input`
|
||||
- `agent_output`
|
||||
- `agent_edit`
|
||||
- `bash_generated`
|
||||
- `subtask_output`
|
||||
- `imported_existing`
|
||||
- `unknown`
|
||||
|
||||
### Recording Rules
|
||||
|
||||
Record provenance at these boundaries:
|
||||
|
||||
- UI upload to `input/`
|
||||
- `source_kind=user_input`
|
||||
- `created_by_task_id=current task`
|
||||
|
||||
- `Write`
|
||||
- new file: `source_kind=agent_output`
|
||||
- existing file: update `last_modified_by_task_id`
|
||||
|
||||
- `Edit`
|
||||
- update `last_modified_by_task_id`
|
||||
- keep original `created_by_task_id`
|
||||
|
||||
- `Bash`
|
||||
- compare workspace file snapshot before/after command
|
||||
- new files: `source_kind=bash_generated`
|
||||
- changed files: update `last_modified_by_task_id`
|
||||
|
||||
- subtask outputs copied/visible to parent
|
||||
- `source_kind=subtask_output`
|
||||
- include parent task and subtask job id
|
||||
|
||||
- existing files in a persistent space before this feature ships
|
||||
- backfill as `source_kind=imported_existing` or `unknown`
|
||||
|
||||
### Agent-Facing Tools
|
||||
|
||||
Add META tools:
|
||||
|
||||
```ts
|
||||
GetFileProvenance({ path: string })
|
||||
```
|
||||
|
||||
Returns a compact provenance record for one file.
|
||||
|
||||
```ts
|
||||
ListWorkspaceFiles({
|
||||
path?: string;
|
||||
sourceKind?: string;
|
||||
createdByTaskId?: number;
|
||||
lastModifiedByTaskId?: number;
|
||||
includeUnknown?: boolean;
|
||||
})
|
||||
```
|
||||
|
||||
Returns bounded file listings with provenance summaries.
|
||||
|
||||
### Prompt Guidance
|
||||
|
||||
Update the system prompt / workspace guidance so the agent uses provenance
|
||||
before editing ambiguous files.
|
||||
|
||||
Candidate prompt copy:
|
||||
|
||||
```md
|
||||
## Workspace file provenance
|
||||
Persistent workspaces may contain files from older tasks. Before editing a file
|
||||
whose provenance shows `source_kind=user_input` or `created_by_task_id` differs
|
||||
from the current task, verify that it is relevant. Prefer creating a new output
|
||||
file when unsure. Use GetFileProvenance / ListWorkspaceFiles to inspect file
|
||||
origin.
|
||||
```
|
||||
|
||||
### UI
|
||||
|
||||
Show provenance in the file browser / preview:
|
||||
|
||||
- created by task id/title
|
||||
- source kind
|
||||
- last modified by task id/title
|
||||
- timestamp
|
||||
|
||||
This can be a small metadata row or tooltip; avoid cluttering the file list.
|
||||
|
||||
## Files Likely Involved
|
||||
|
||||
- `src/db/schema.sql`
|
||||
- add provenance table
|
||||
|
||||
- `src/db/migrate.ts`
|
||||
- migration for existing installations
|
||||
|
||||
- `src/db/repository.ts`
|
||||
- read/write/query provenance records
|
||||
- optional backfill helpers
|
||||
|
||||
- `src/engine/tools/core.ts`
|
||||
- hook `Write`, `Edit`, and `Bash` file changes
|
||||
- expose task/job/piece/movement context needed for provenance
|
||||
|
||||
- `src/engine/piece-runner.ts`
|
||||
- thread task id, job id, piece, movement into `ToolContext`
|
||||
|
||||
- `src/engine/tools/index.ts`
|
||||
- register provenance tools as META tools
|
||||
|
||||
- `src/engine/tools/file-provenance.ts`
|
||||
- implement `GetFileProvenance`
|
||||
- implement `ListWorkspaceFiles`
|
||||
|
||||
- `src/bridge/local-tasks-api.ts` / file APIs
|
||||
- record UI uploads
|
||||
- return provenance metadata with file listing/detail responses
|
||||
|
||||
- `ui/src/components/files/*`
|
||||
- display provenance metadata
|
||||
|
||||
- `src/engine/agent-loop/prompt.ts`
|
||||
- add concise workspace provenance guidance
|
||||
|
||||
- `ui/src/content/help/*.md`
|
||||
- document how provenance labels work
|
||||
|
||||
- `ui/src/content/help/00-changelog.md`
|
||||
- add user-facing changelog entry
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- New files created by `Write` record current task provenance.
|
||||
- Files changed by `Edit` preserve original creator and update last modifier.
|
||||
- Files created or changed by `Bash` are detected and recorded.
|
||||
- User-uploaded input files are recorded as `user_input`.
|
||||
- File listing or preview can show provenance metadata.
|
||||
- Agent can call `GetFileProvenance` for a file.
|
||||
- Agent can list files filtered by provenance.
|
||||
- Prompt guidance tells the agent to avoid editing unrelated/user-input files
|
||||
without checking relevance.
|
||||
- Existing persistent workspace files remain usable after migration.
|
||||
- Provenance output is bounded and does not dump large file contents.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Do not embed task tags into file contents.
|
||||
- Do not make files from other tasks globally read-only; the agent may still
|
||||
need to use shared workspace artifacts.
|
||||
- Do not block all edits to `user_input` files immediately. Start with warnings
|
||||
and guidance to avoid breaking existing workflows.
|
||||
- Do not use `UpdateUserMemory` for per-file task metadata.
|
||||
|
||||
## Suggested Implementation Order
|
||||
|
||||
1. Add DB schema and repository helpers.
|
||||
2. Record UI uploads and `Write`/`Edit` provenance.
|
||||
3. Add `Bash` before/after file change detection.
|
||||
4. Implement `GetFileProvenance`.
|
||||
5. Implement `ListWorkspaceFiles` with filters and caps.
|
||||
6. Add prompt guidance.
|
||||
7. Surface metadata in the file browser/preview.
|
||||
8. Update help docs and changelog.
|
||||
Reference in New Issue
Block a user