FileSystemModule Migration Guide
Overview
FileSystemModule is a retired compatibility shell. Version 1.0 accepted absolute paths, caller-controlled base directories, and traversal segments before loading, saving, listing, deleting, copying, or moving files on the workflow worker. It allowed directory creation and overwrites without an approval boundary, logged host paths and raw exception details, exposed only one generic input in Workflow Studio, and incorrectly marked all operations idempotent.
Version 2.0 keeps the Java class and Spring bean loadable so saved workflows can be inspected and migrated, but hides the module from new Workflow Studio catalogs. Execution now fails closed with MODULE_RETIRED, performs no filesystem, ContentData, parsing, or serialization work, and never echoes a legacy path or content value.
Read-only workloads can migrate to WorkspaceFileReadModule, a remote capability-pack module that uses operator-configured workspace roots, safe relative paths, secret-path denial, symlink containment, and bounded UTF-8 reads and listings. There is no automatic replacement for legacy save, copy, move, or delete operations.
Usage
- Find saved workflow tasks whose module type is
FileSystemModule. - Classify each task as read-only inspection or mutation.
- Remove absolute paths,
..traversal, caller-controlledbaseDir, binary content, and any secret-bearing values. - For read, list, or stat behavior, configure an authorized workflow-engine workspace root and replace the task with
WorkspaceFileReadModule. - For save, copy, move, or delete behavior, use the domain API that owns the artifact or an explicitly governed module with its own authorization and approval contract. Do not translate the legacy operation into a shell command.
- Validate the replacement in sandbox or staging before enabling the workflow.
Inputs
The retired shell ignores every legacy input and never resolves a path.
The read-only replacement accepts:
| Name | Type | Required | Description |
|---|---|---|---|
operation | string | yes | read, list, or stat. |
rootIndex | integer | no | Index of an operator-configured authorized workspace root; defaults to 0. |
path | string | yes | Relative path inside the authorized root. |
maxBytes | integer | no | UTF-8 read ceiling from 1 through 1,048,576 bytes. |
maxDepth | integer | no | Directory-listing depth from 0 through 8. |
maxEntries | integer | no | Directory-listing ceiling from 1 through 1,000 entries. |
Outputs
The compatibility shell always returns:
| Name | Type | Description |
|---|---|---|
status | string | Always error. |
error | object | Safe MODULE_RETIRED, retryable:false, and migration guidance. |
WorkspaceFileReadModule returns a workspace-relative path, normalized operation, and one of bounded UTF-8 content, sanitized entries, or sanitized file metadata. It never returns absolute host paths.
IntegrationAccount Requirements
Neither module uses an IntegrationAccount. Filesystem access is controlled by the workflow execution node's configured workspace-root policy and capability assignment, not by storing host paths or filesystem credentials in workflow data.
Remove any token, password, private key, .env value, or credential path from legacy task input. Rotate a credential if version 1.0 could have read or copied it.
Configuration
The retired module has no active configuration. Saved baseDir, maxFileSize, allowedExtensions, and dryRun values are ignored.
The replacement requires an operator to configure one or more authorized workspace roots on the remote workflow engine. Workflow data selects only a root index and a safe relative path; it cannot supply a new root.
Example replacement payload:
{
"operation": "read",
"rootIndex": 0,
"path": "reports/daily-summary.json",
"maxBytes": 262144
}
Operations
FileSystemModule supports only one compatibility operation: reject execution and identify the read-only migration target.
WorkspaceFileReadModule supports:
read: return bounded valid UTF-8 text from one regular file.list: return a sorted, bounded directory listing without denied secret paths.stat: return sanitized type, size, and modification metadata.
It does not create directories, parse CSV/YAML/JSON, decode binary data, write backups, overwrite files, copy, move, or delete.
Errors and Failure Modes
| Failure | Behavior | Recovery |
|---|---|---|
| Any legacy execution | Returns MODULE_RETIRED with retryable:false. | Replace the task; retrying cannot restore worker-filesystem access. |
| No authorized root is configured | Replacement fails before path resolution. | Configure a bounded workspace root on the execution node. |
| Absolute, traversal, secret, or escaped symlink path | Replacement rejects the path without revealing the host location. | Use a permitted relative project path. |
File exceeds maxBytes | Replacement rejects the read before returning content. | Narrow the artifact or raise the ceiling within the one-megabyte limit. |
| File is not valid UTF-8 | Replacement rejects the read. | Use an owning API or a purpose-built binary parser outside this module. |
Listing reaches maxEntries | Replacement marks the result truncated. | Narrow the path or increase the bounded limit. |
| Legacy mutation has no governed equivalent | No write is attempted. | Use the domain service that owns the artifact and its explicit authorization contract. |
Example
A saved legacy task reaches the compatibility shell:
{
"operation": "delete",
"filePath": "/tmp/valkyrai/report.json"
}
Expected result:
{
"status": "error",
"error": {
"code": "MODULE_RETIRED",
"message": "FileSystemModule is retired; use WorkspaceFileReadModule for authorized read-only access",
"retryable": false,
"migrationTargets": ["WorkspaceFileReadModule"]
}
}
Notes
- Pagination: the compatibility shell does not paginate. Replacement listings are a single bounded result with a
truncatedmarker. - Limits: reads are capped at 1,048,576 bytes; list depth is capped at 8; listings are capped at 1,000 entries; at most 64 workspace roots can be configured.
- Idempotency: the compatibility response and all replacement operations are deterministic and read-only for a stable filesystem snapshot. The legacy v1 idempotency claim did not apply to writes, moves, or deletes.
- API constraints: the replacement is a remote-only capability-pack module and requires the
workspace.files.readcapability plus node-side workspace-root configuration. - Secret handling:
.ssh,.aws,.gnupg,.git,node_modules,.env*,credentials.json, and common key/certificate file extensions are denied. - Destructive behavior: the compatibility shell and replacement perform none. Legacy save, copy, move, and delete operations have no implicit migration.
- Runtime deployment: source, tests, and documentation can be merged and published independently, but live Workflow Studio will continue to show version 1.0 until a normal backend deployment includes version 2.0.
- Unverified boundary: deterministic tests prove fail-closed output, secret/path non-disclosure, repeatability, metadata discovery exclusion, and direct compatibility lookup. No real filesystem mutation is run because the retired module intentionally performs no file behavior.