Bound external result file reads

This commit is contained in:
2026-08-10 18:30:28 +00:00
parent 99b2e1cd81
commit ab5a7e8e3d
22 changed files with 215 additions and 84 deletions

View File

@@ -41,6 +41,9 @@ Run fails for:
- invalid processed transcript JSON (`segments` array required);
- invalid report JSON when reporting is enabled.
Processed transcript JSON is limited to 64 MiB and optional report JSON to 16
MiB. Both must be regular files without symlinked path components.
Failure results still include output/log/config/exit metadata for diagnostics.
## Deterministic Behavior

View File

@@ -46,6 +46,9 @@ Run behavior:
- `run` exit code `2` is mapped to `ValidationFailed=true`;
- successful subprocess still fails if output file is missing or empty.
Each artifact result is limited to 64 MiB and must be a regular file without
symlinked path components.
Render behavior:
- subprocess errors propagate;
- output file must exist and be non-empty.

View File

@@ -41,6 +41,8 @@ Invocation fails on:
- empty render output files.
When report paths are provided/enabled, report files must parse as JSON.
Each Seriatim JSON or rendered-text result is limited to 64 MiB and must be a
regular file without symlinked path components.
## Deterministic Behavior
- argument ordering is deterministic per command construction.

View File

@@ -34,10 +34,11 @@ successful. Command and post-publish policy remains owned by `internal/app`.
## Confined Reads
`ReadRegularFileUnderRoot` is the no-follow, bounded read primitive for a
caller-selected root and relative file path. It verifies the root and every
ancestor through directory handles, admits only a stable regular-file handle,
and lets the caller enforce its own byte limit and access policy. Credential
mode policy and environment precedence remain owned by `internal/app`.
caller-selected root and relative file path; `ReadRegularFile` is its
path-based convenience wrapper. They verify every ancestor through directory
handles and admit only a stable regular-file handle. Callers enforce their own
byte limits and access policy. Credential mode policy and environment
precedence remain owned by `internal/app`.
## Replacement Contract

View File

@@ -307,6 +307,11 @@ On POSIX, provision a credential directory as `0700` and credential files as
`0600`; Narratio rejects group- or other-readable configured credential paths.
On Windows, restrict the directory and files with ACLs to the credential owner.
External adapter results are individually bounded before Narratio validates or
materializes them. These per-file limits do not reserve disk space: prevent hard
disk exhaustion with filesystem, service, container, or volume quotas sized for
the session workload.
## Cleanup
Session-scoped cleanup:

View File

@@ -22,7 +22,7 @@ All stages are pending when this plan is created.
| 4 | Add confined destination and download/install capabilities | COR-003, DUP-003, TST-003 | Completed |
| 5 | Confine recursive cleanup and replace sentinel locks | RSK-003 | Completed |
| 6 | Harden API-key file acquisition | RSK-010 | Completed |
| 7 | Bound and verify external result acquisition | RSK-013, TST-007 | Pending |
| 7 | Bound and verify external result acquisition | RSK-013, TST-007 | Completed |
| 8 | Terminate owned subprocess trees | RSK-011 | Pending |
| 9 | Redact and cap subprocess diagnostics | RSK-012 | Pending |
| 10 | Confine publish archive reads | COR-005 | Pending |