feat(config): support human-readable durations with legacy compatibility
This commit is contained in:
22 files changed
+715
-151
No files matched your search
@@ -84,7 +84,7 @@ The agent keeps its terminal manager outside the control-WebSocket reconnect loo
|
||||
|
||||
Closing a session must terminate the entire PTY process group, not only the shell process. Cleanup should send a hangup first, then escalate to termination and forced kill after bounded grace periods. Explicit operator close, absolute session timeout, agent process exit, and machine reboot close the session.
|
||||
|
||||
The agent configuration sets `terminal.session_ttl_seconds` for newly created PTYs. The default is 43,200 seconds (12 hours); explicit zero disables automatic expiry. The agent owns and enforces this deadline locally because PTYs survive browser and control-plane disconnection. It advertises the policy to the control plane and includes the creation-time TTL in terminal inventory, allowing CC to mirror expiry and preserve it across CC restart. Missing fields from older agents retain the 12-hour default. Positive values are exact and values that cannot fit the platform timer are rejected rather than clamped.
|
||||
The agent configuration sets `terminal.session_ttl` (for example, `"12h"`) for newly created PTYs. The default is 12 hours; `"0s"` disables automatic expiry. Legacy `session_ttl_seconds` is accepted with a deprecation warning. The wire protocol still uses integer seconds, so fractional-second TTLs are rejected. The agent owns and enforces this deadline locally because PTYs survive browser and control-plane disconnection. It advertises the policy to the control plane and includes the creation-time TTL in terminal inventory, allowing CC to mirror expiry and preserve it across CC restart. Missing fields from older agents retain the 12-hour default. Positive values are exact and values that cannot fit the platform timer are rejected rather than clamped.
|
||||
|
||||
An agent process restart or machine reboot still ends every terminal session because PTY file descriptors cannot be recovered by a new process. Surviving that boundary would require an external session host such as `tmux` or a separate terminal daemon and is not part of this design.
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
# Configuration Durations
|
||||
|
||||
Agent and control-plane TOML duration settings use strings with explicit units.
|
||||
Runtime code receives `std::time::Duration`; API and WebSocket numeric fields
|
||||
such as `timeout_ms`, `session_ttl_seconds`, and `latency_ms` are unchanged.
|
||||
|
||||
## Agent
|
||||
|
||||
```toml
|
||||
reconnect_base = "1s"
|
||||
reconnect_max = "30s"
|
||||
observation_sync_interval = "60s"
|
||||
observation_retention = "7d"
|
||||
|
||||
[terminal]
|
||||
session_ttl = "12h"
|
||||
```
|
||||
|
||||
`observation_retention` prunes the agent's local hotplug memory during inventory
|
||||
collection. It does not delete the control plane's last snapshot for an agent.
|
||||
`"0d"` disables this local pruning. `terminal.session_ttl = "0s"` disables PTY
|
||||
expiry. Reconnect and sync timers must be positive and fit the platform timer.
|
||||
Terminal TTL and hook retention must resolve to whole seconds because their
|
||||
protocol/storage timestamps use seconds. Reconnect and sync intervals can use
|
||||
subsecond values.
|
||||
Reconnect scheduling retains its existing 100ms minimum backoff.
|
||||
|
||||
## Control Plane
|
||||
|
||||
```toml
|
||||
command_timeout = "30s"
|
||||
enroll_token_ttl = "1d"
|
||||
history_retention = "30d"
|
||||
```
|
||||
|
||||
All three settings must be positive. Enrollment TTL and history retention must
|
||||
resolve to whole seconds. Command timeout can use subsecond values.
|
||||
`history_retention` deletes old audit events and alert transitions, not device
|
||||
snapshots or saved identities. Device retention is a separate follow-up.
|
||||
|
||||
## Legacy Files
|
||||
|
||||
| Old Key | New Key | Numeric Legacy Unit |
|
||||
| --- | --- | --- |
|
||||
| Agent `reconnect_base_ms` | `reconnect_base` | milliseconds |
|
||||
| Agent `reconnect_max_ms` | `reconnect_max` | milliseconds |
|
||||
| Agent `observation_sync_interval_seconds` | `observation_sync_interval` | seconds |
|
||||
| Agent `observation_retention_days` | `observation_retention` | days |
|
||||
| Agent `terminal.session_ttl_seconds` | `terminal.session_ttl` | seconds |
|
||||
| CC `command_timeout_ms` | `command_timeout` | milliseconds |
|
||||
| CC `enroll_token_ttl_seconds` | `enroll_token_ttl` | seconds |
|
||||
| CC `observation_retention_seconds` | `history_retention` | seconds |
|
||||
|
||||
Old keys accept non-negative integers in their original units, or explicit
|
||||
duration strings, and produce a warning on stderr when loaded. New keys require
|
||||
strings; bare numbers are rejected. Supplying both keys for the same setting is
|
||||
an error, even when their values agree. Negative, malformed, and overflowing
|
||||
values are rejected; zero active timers are rejected rather than silently
|
||||
clamped. No secrets are included in deprecation warnings.
|
||||
|
||||
`init-config --from-config ...` reads legacy files and writes only canonical
|
||||
keys and formatted duration strings. Existing numeric CLI flags are unchanged
|
||||
in this slice, and their overrides also serialize in the new format.
|
||||
|
||||
For example, legacy `reconnect_base_ms = 1500` is read as 1500 milliseconds
|
||||
and written back as `reconnect_base = "1s 500ms"`. New-key
|
||||
`reconnect_base = 1500` is rejected: no implicit numeric unit is assigned.
|
||||
Serialization always writes duration strings, regardless of the accepted input
|
||||
format, using `humantime-serde`.
|
||||
|
||||
The parser is [humantime](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html).
|
||||
Examples include `"14d"`, `"168h"`, `"250ms"`, and `"1h 30m"`. These are elapsed
|
||||
durations, not calendar scheduling rules; use days/hours for retention rather
|
||||
than assuming calendar-month semantics.
|
||||
@@ -22,6 +22,8 @@ live browser recovery and shutdown behavior are not established by those checks.
|
||||
|
||||
## Device Management And Presentation
|
||||
|
||||
- [x] Endpoint-derived presence on snapshot writes and fleet reads; endpoint-less legacy rows retain their summary. CLI ordering matches the core signal order.
|
||||
|
||||
- [x] Make **forget remembered device** reachable in the frontend, with confirmation. The existing backend removes the known identity and its identifiers, not agent observations. An observed device may reappear as unknown.
|
||||
- [x] Add remembered-device rename support, with backend validation and frontend editing (`PATCH /api/v1/control/devices/{device_id}`). Pinned state and identifiers are preserved.
|
||||
- [ ] Check and complete editing of remembered-device notes.
|
||||
@@ -34,6 +36,8 @@ of remembered identifiers based on observation expiry.
|
||||
|
||||
## Telemetry Follow-Ups
|
||||
|
||||
- [x] Human-readable agent/CC config durations with unit-aware legacy loading, stderr deprecation warnings, and canonical init-config output. See [configuration durations](config-durations.md). History retention remains separate from future device expiry.
|
||||
|
||||
- [x] Separate console, OTLP log, and trace filters using per-layer filtering. Explicit signal config overrides `RUST_LOG`, then CLI verbosity supplies defaults. Unconfigured defaults remain info-level; exporter-failure logs stay local. Live validation pending.
|
||||
- [ ] Record hostname-resolution success/failure without exporting hostnames or resolved addresses. Current spans show timing but do not explicitly classify the result.
|
||||
- [ ] Investigate the slow resolver with a reproducible device-side check. Timing isolated the phase, not the cause; do not treat instrumentation as a fix.
|
||||
|
||||
Reference in new issue
Block a user