Initial server source import

This commit is contained in:
sashatrask
2026-09-30 20:30:56 +03:00
commit 170dd941b9
498 changed files with 261563 additions and 0 deletions
@@ -0,0 +1,182 @@
## ADDED Requirements
### Requirement: Shared strict document validation
Configuration and secrets preview, startup, and privileged apply SHALL use the same side-effect-free validator for bounded UTF-8 YAML, duplicate keys, mapping roots, strict scalar types and bounds, known keys, exact core profile, auth-pool schemas, unique entry names, reference integrity, package capabilities, and deployment paths.
#### Scenario: Valid configuration is previewed
- **WHEN** an operator submits a candidate satisfying the complete schema
- **THEN** preview returns normalized validation success and a bounded diff without activating the candidate
#### Scenario: Duplicate or unknown key is submitted
- **WHEN** a candidate contains a duplicate mapping key or unsupported field
- **THEN** validation fails before staging or restart and identifies the field without echoing secret values
#### Scenario: Secret reference is invalid
- **WHEN** configuration selects an auth-pool entry that does not exist in the candidate secrets
- **THEN** combined validation fails and neither document becomes active
### Requirement: Separate immutable package authority
Worker package manifests SHALL resolve only beneath a separate root-owned, non-writable package authority, while runtime-generated initialization state, locks, and PostgreSQL credentials SHALL remain in the private writable data volume rather than the active config/secrets bind.
#### Scenario: Package manifest uses the active-document directory
- **WHEN** configuration references a package manifest beneath the config/secrets authority or outside the fixed package root
- **THEN** validation fails before startup or privileged apply
#### Scenario: Runtime initializes with active documents mounted read-only
- **WHEN** the runtime initializes or restarts with the active config/secrets directory mounted read-only
- **THEN** its initialization marker, singleton lock, and generated PostgreSQL password remain writable only through fixed private data paths
### Requirement: Candidate revisions and compare-and-swap
The system SHALL stage validated candidate revisions separately from active files and SHALL require expected active and candidate SHA-256 identities when saving or applying them.
#### Scenario: Candidate is saved
- **WHEN** an operator saves valid bytes against the current active hash
- **THEN** the candidate is durably staged with a new hash and the active file is unchanged
#### Scenario: Active file changed through SSH
- **WHEN** the active hash differs from the expected hash submitted by a stale page
- **THEN** save or apply fails without replacing either active file
#### Scenario: Candidate changed concurrently
- **WHEN** the supplied candidate hash is no longer current
- **THEN** apply is rejected before host lifecycle changes begin
### Requirement: Plaintext secrets editing without persistence leakage
The protected secrets page SHALL allow authorized operators to view and edit the complete plaintext YAML document while responses remain no-store and secret values remain absent from browser persistence, application logs, diffs outside that page, operation status, and audit records.
#### Scenario: Operator opens secrets page
- **WHEN** an authenticated operator requests the dedicated secrets editor
- **THEN** the current document is rendered in a server-side form over the protected no-store response
#### Scenario: Secrets candidate is validated
- **WHEN** an operator previews or saves changed secrets
- **THEN** validation results name safe field paths and hashes but do not repeat credential values
#### Scenario: Operator leaves the page
- **WHEN** the browser navigates to another admin page
- **THEN** the application has written no secret value to local storage, session storage, service workers, or client-side application state
### Requirement: Closed host-agent protocol
The privileged host operations agent SHALL accept only a canonical operation UUID, one fixed action enum, expected active hashes, and expected candidate hashes from the authorized runtime peer over a local Unix socket. Deployment profile is root-installed host policy and SHALL NOT be added to that request.
#### Scenario: Valid apply request arrives
- **WHEN** the authorized runtime UID submits an exact valid request
- **THEN** the agent verifies the persisted operation and hashes before acquiring the singleton apply lock
#### Scenario: Request includes path or command data
- **WHEN** a request includes a service name, path, shell text, environment, Docker argument, or unknown field
- **THEN** the agent rejects it before any privileged action
#### Scenario: Request attempts topology selection
- **WHEN** a request includes a profile, ingress port, upstream, Caddy path, unit, service, command, environment, Compose file, or Compose argument
- **THEN** the agent rejects it before reading candidate documents or stopping the deployment
#### Scenario: Unauthorized local peer connects
- **WHEN** a process with an unapproved peer identity uses the socket
- **THEN** the agent rejects the request regardless of its JSON body
### Requirement: Coordinated apply with health verification
For config, secrets, or combined apply, the host agent SHALL revalidate fixed candidate files, verify compare-and-swap hashes, create byte-identical backups, stop the fixed Truf deployment, atomically replace active files, recreate the exact root-selected runtime and edge profile, attest its fixed topology, and wait for required health before reporting success. In shared-host mode it SHALL NOT stop, restart, reload, reconfigure, or remove host Caddy, X-UI, or another unrelated service.
#### Scenario: Combined apply succeeds
- **WHEN** both candidates validate and the restarted deployment reaches Supervisor ACTIVE, PostgreSQL READY, Worker API, ingester, and projector health
- **THEN** the operation completes successfully with resulting hashes and retained rollback evidence
#### Scenario: Validation changes between preview and apply
- **WHEN** host-side revalidation or hash verification differs from the accepted candidate operation
- **THEN** the agent aborts before stopping the healthy runtime
#### Scenario: Apply is requested while another is active
- **WHEN** the singleton operation lock is held
- **THEN** the second request is rejected or remains queued without overlapping lifecycle mutations
#### Scenario: Shared-host profile is healthy
- **WHEN** shared-host apply recreates a host-network runtime with no published ports and an edge bound only to fixed loopback, and all runtime and edge health checks pass
- **THEN** the operation succeeds without a host-Caddy or X-UI lifecycle action
#### Scenario: Shared-host topology drifts
- **WHEN** runtime publishes a port, edge binds a non-loopback address, profile metadata changes, or Compose labels, mounts, network, capabilities, or Caddyfile differ from the fixed profile
- **THEN** the agent rejects the deployment before candidate replacement or reports failed health without claiming success
#### Scenario: Shared-host rollback succeeds
- **WHEN** candidate health fails and the previous Truf runtime and edge are restored
- **THEN** rollback completes exactly once without changing host Caddy, X-UI, or another unrelated service
### Requirement: Automatic rollback and failed hold
If the new deployment fails its bounded health check, the agent SHALL restore byte-identical backups and verify the previous deployment; if rollback also fails, it SHALL stop retrying and retain a failed-hold state and all evidence for SSH recovery.
#### Scenario: New configuration fails startup
- **WHEN** the restarted runtime cannot reach required health within the deadline
- **THEN** the agent restores the prior active files and restarts the previous deployment
#### Scenario: Rollback succeeds
- **WHEN** the restored deployment reaches required health
- **THEN** the operation records rolled-back status and safe failure category without claiming apply success
#### Scenario: Rollback fails
- **WHEN** neither the candidate nor restored deployment becomes healthy
- **THEN** the agent enters failed hold, performs no replacement loop or forced authority release, and preserves backups and diagnostics
### Requirement: Logical managed roots
The generic file page SHALL address only configured logical roots with explicit read, create/replace, and delete permissions, and SHALL never accept an absolute root from a client.
#### Scenario: Operator lists a managed runtime root
- **WHEN** a valid logical root ID for logs, keycheck projections, or result projections and a canonical relative directory are requested
- **THEN** the service returns a bounded read-only listing of permitted regular files and directories under that root
#### Scenario: Operator downloads rotated result projections
- **WHEN** the operator requests a permitted active or rotated result projection within its configured file-size bound
- **THEN** the service returns that regular single-link file without granting mutation access or exposing the backing runtime path
#### Scenario: Result projection names are allowlisted
- **WHEN** the result-projection root is listed or read
- **THEN** only active `scan_results.jsonl` and `found_secrets.jsonl` files and their exact six-digit generation names are visible, while locks, databases, ledgers, scan errors, temporary/quarantine directories, malformed generations, and recovery artifacts remain unavailable
#### Scenario: Large result projection is downloaded
- **WHEN** an allowed result projection is within the larger result-root byte bound
- **THEN** the service copies and hashes an unchanged source revision into an anonymous same-volume snapshot using bounded chunks, permits only one such snapshot at a time, streams the snapshot with bounded memory, and releases the snapshot and concurrency slot after response completion or failure
#### Scenario: Operator requests excluded storage
- **WHEN** a request targets application code, config/secrets through the generic page, PostgreSQL storage, sockets, host-agent metadata, raw result bundles, or an unknown root
- **THEN** the service rejects it without revealing host paths or existence details
### Requirement: Descriptor-safe path containment
Managed-file traversal and mutation SHALL use a retained root directory descriptor, component-wise no-follow operations, canonical relative components, and regular single-link file checks.
#### Scenario: Relative traversal is attempted
- **WHEN** a path contains an empty, dot, dot-dot, absolute, drive-qualified, backslash, NUL, over-depth, or over-length component
- **THEN** the request is rejected before filesystem access outside the retained root
#### Scenario: Symlink is swapped during access
- **WHEN** a path component becomes a symlink between validation and open
- **THEN** no-follow descriptor traversal fails without accessing the link target
#### Scenario: Hardlink or special file is targeted
- **WHEN** the final object is multi-linked or is not a regular file
- **THEN** view, download, replace, and delete are rejected
### Requirement: Durable bounded file mutation
An allowed managed-file create or replace SHALL use an exclusive same-directory temporary regular file, bounded bytes, fsync, atomic descriptor-relative replacement, directory fsync, and final ownership/type/mode verification.
#### Scenario: File replacement succeeds
- **WHEN** an authorized bounded replacement is submitted against the current file hash
- **THEN** readers observe either the complete old file or complete new file and audit records the safe before/after hashes
#### Scenario: File is concurrently changed
- **WHEN** the current file hash differs from the expected hash
- **THEN** replacement fails without overwriting the concurrent change
#### Scenario: Upload exceeds the root limit
- **WHEN** submitted bytes exceed the configured bounded file size
- **THEN** the service rejects and removes temporary data without changing the target
### Requirement: Content-free operational audit
Configuration, secrets, and managed-file operations SHALL record actor, typed action, logical target, timestamps, result, safe category, byte counts where applicable, and before/after hashes, but SHALL NOT record file contents or credentials.
#### Scenario: Managed file is deleted
- **WHEN** an allowed delete succeeds against the expected hash
- **THEN** audit records the logical root/path and previous hash without retaining deleted content
#### Scenario: Secrets apply fails
- **WHEN** a secrets operation fails validation, startup, or rollback
- **THEN** status and audit expose only the bounded failure category and document hashes