85 lines
3.7 KiB
Markdown
85 lines
3.7 KiB
Markdown
# Internal: Workspace
|
|
|
|
## Purpose
|
|
|
|
Explain the helpers that construct local session and run paths, coordinate
|
|
single-writer access, and confine cleanup. The authoritative physical layout and
|
|
retention workflow belong in [Operations](../operations.md#local-state-layout).
|
|
|
|
## Path Ownership
|
|
|
|
`internal/artifacts` owns canonical session, run, spool, cache, and
|
|
previous-cache path construction. `SessionPathsFor` provides the session-scoped
|
|
path model, and layout creation goes through `EnsureLayoutFor`. Callers should
|
|
consume those helpers instead of rebuilding relative paths.
|
|
|
|
`internal/pathsafe` and application cleanup helpers enforce confinement for
|
|
relative destinations and deletion targets.
|
|
|
|
`internal/fileops` owns the ordinary workspace mode contract. On POSIX,
|
|
`WorkspaceDirectoryMode` is setgid `02775` and `WorkspaceFileMode` is `0664`.
|
|
`EnsureWorkspaceDirectory` reapplies the directory mode after creation so a
|
|
restrictive umask cannot remove group access, while retaining existing ownership
|
|
and group. Credential paths are outside this contract; the platform-specific
|
|
operational requirements are in [Operations](../operations.md#workspace-permissions).
|
|
|
|
## Run-Local Stage Layout
|
|
|
|
`internal/stage/run_local.go` maps stage outputs and diagnostics into an
|
|
invocation-scoped layout. Successful outputs are validated and atomically
|
|
materialized into canonical session paths before stage success. Managed
|
|
previous-session cache paths remain session-durable and are never redirected
|
|
into run-local output space.
|
|
|
|
Extraction uses run-local receipt, stderr, and output-root helpers, then
|
|
promotes the validated external bundle to the unique immutable Notarius bundle
|
|
path supplied by `internal/artifacts`. `internal/fileops.PromoteDirectory`
|
|
copies only regular files and directories to a same-filesystem temporary
|
|
sibling. Source traversal uses confined directory handles and identity checks
|
|
so replacing an inspected root, directory, or file is rejected rather than
|
|
followed. The completed tree is atomically renamed without replacing an
|
|
existing destination. Exact physical paths belong in
|
|
[Operations](../operations.md#extraction-workflow).
|
|
|
|
## Locking
|
|
|
|
`artifacts.LocalStore` enforces the single-writer session lock via `.lock`
|
|
(`ErrLockConflict` on contention).
|
|
|
|
## Cleanup Semantics
|
|
|
|
Automatic post-publish cleanup:
|
|
|
|
- only runs when publish actually executed and succeeded;
|
|
- requires `uploaded=true` and `current_pointer_written=true` metadata;
|
|
- consumes the resolved cleanup policy described in
|
|
[Configuration](../config.md);
|
|
- refuses unsafe deletes (root delete, out-of-root delete, symlink paths).
|
|
|
|
Manual cleanup uses the same scoped-target checks. Invocation syntax and exact
|
|
deletion scope belong in [CLI](../cli.md#clean) and
|
|
[Operations](../operations.md#cleanup).
|
|
|
|
## Invariants
|
|
|
|
- campaign-aware session root is mandatory.
|
|
- manifest-driven stage state is durable across runs.
|
|
- cleanup guardrails prevent destructive root/out-of-scope deletion.
|
|
- ordinary workspace paths retain group-writable directory and file modes across
|
|
nested creation, replacement, and Notarius promotion.
|
|
|
|
## Implementation And Tests
|
|
|
|
- Path model and local store: `internal/artifacts/paths.go`,
|
|
`internal/artifacts/local.go`
|
|
- Run-local materialization: `internal/stage/run_local.go`
|
|
- Immutable bundle promotion: `internal/fileops/directory.go`
|
|
- Workspace modes: `internal/fileops/modes.go`
|
|
- Cleanup confinement: `internal/app/cleanup_targets.go`,
|
|
`internal/app/post_publish_cleanup.go`
|
|
- Tests: `internal/artifacts/paths_model_test.go`,
|
|
`internal/artifacts/local_test.go`, `internal/stage/run_local_test.go`,
|
|
`internal/fileops/directory_test.go`, `internal/fileops/modes_posix_test.go`,
|
|
`internal/app/cleanup_targets_test.go`,
|
|
`internal/app/post_publish_cleanup_test.go`
|