You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: INVARIANTS.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -34,4 +34,5 @@ materialization, messaging, DING, or presence must preserve them.
34
34
| **Parked tasks are visible and individually recoverable** | A parked task is reported alongside an unmodified runtime observation as a complete known fault; only an unbelievable marker fails closed. Park markers and unpark requests share the exact canonical catalog-folder plus host ownership scope, and the projected recovery argv carries both axes, so same-host supervisors cannot see, delete, consume, or advertise recovery into each other's channels even for the same task ID. A projected park whose supervisor generation is gone is positively not parked. An explicit per-task unpark clears that task's park and spent budget so it is launchable again and stays recovered past `interval`, releases no other parked task, restarts no healthy peer, and restores the agent's derived DING. | `src/flapping.rs::unpark_restores_a_launchable_task_not_just_a_cleared_flag`; `src/flapping.rs::unpark_is_per_task_and_reports_whether_it_changed_anything`; `src/park.rs::same_host_supervisors_isolate_markers_and_requests_by_catalog`; `src/park.rs::a_marker_from_a_dead_supervisor_reads_as_not_parked`; `src/park.rs::published_parks_are_readable_and_clear_when_the_task_recovers`; `src/park.rs::an_unbelievable_marker_is_indeterminate_not_absent`; `src/park.rs::a_request_is_consumed_exactly_once`; `src/task_inventory.rs::a_parked_task_reports_its_fault_alongside_a_truthful_runtime_state`; `src/task_inventory.rs::an_unbelievable_park_marker_makes_the_envelope_incomplete`; `tests/task_inventory_cli.rs::projected_recovery_targets_its_exact_catalog_and_host_despite_ambient_defaults`; `tests/run.rs::an_operator_recovers_one_parked_task_without_disturbing_a_healthy_peer`; `tests/run.rs::an_unpark_request_for_a_task_that_is_not_parked_says_so` |
35
35
|**Tracked workspaces fail closed**| Materialization simulates content operations before writing and refuses a real change to any Git-tracked target. Byte-identical tracked, untracked, and non-Git targets retain useful behavior. |`tests/materialize.rs::every_content_directive_refuses_to_change_a_tracked_target_before_any_write`; `tests/materialize.rs::byte_identical_tracked_target_is_allowed_without_modification`; `tests/materialize.rs::untracked_and_non_git_targets_remain_materializable`|
36
36
|**Native flat root**| Without an authored override, catalog tasks, eval messaging, shell helpers, and DING all use the catalog itself as `ST_ROOT`; no nested bus directory is synthesized. |`src/eval_run.rs::bus_root_expands_st_root_else_defaults`; `tests/eval_run_e2e.rs::st2_eval_runs_a_benign_folder_to_a_pass_verdict`; `tests/pty.rs`|
37
+
| **Demand observation is declared, fenced, settled, and clock-free** | `st2 resource refresh` reaches only the resident Resource Profile runtime and only when its catalog runtime declares `capability "demand"`. Every observe dispatch and settlement carries the exact owner, binding ID, and registration; one outstanding dispatch plus one latest trailing watermark coalesces bursts without losing in-flight arrivals. Only exact unchanged, published, failed, stale-generation, or provider-unavailable evidence closes accepted work. Writer backpressure retains queued demand, restart rescans after installing the watch, client disconnect does not cancel it, and the CLI wait bound never participates in correctness or provider scheduling. | `crates/st2-resource-protocol/src/lib.rs::host_frames_have_exact_json_shape_and_newline`; `crates/st2-resource-protocol/src/lib.rs::runtime_frames_have_exact_json_shape_and_padded_base64`; `src/resource_profile_supervisor.rs::demand_batches_coalesce_bursts_and_keep_one_trailing_watermark`; `src/resource_profile_supervisor.rs::full_writer_queue_is_reported_without_consuming_the_frame`; `tests/resource_profile_supervisor_e2e.rs::demand_observation_is_watermark_settled_coalesced_and_restart_safe`; `tests/agent_resource.rs::refresh_cli_reports_exact_receipts_and_wait_expiry_keeps_the_request` |
37
38
|**Proof references resolve**| Every qualified test named in this table exists in its named source file, so stale invariant claims fail the suite instead of silently surviving a refactor. |`tests/invariants.rs::qualified_proof_references_resolve`|
let unknown_settlement_field = b"{\"type\":\"observationSettled\",\"owner\":{\"incarnation\":\"i\",\"claim\":\"c\"},\"bindingId\":\"b\",\"registration\":\"r\",\"demandWatermark\":1,\"outcome\":\"unchanged\",\"extra\":true}\n";
736
+
assert!(matches!(
737
+
decode_runtime_line(unknown_settlement_field),
738
+
Err(ProtocolError::Json(_))
739
+
));
740
+
let zero_watermark = b"{\"type\":\"observationSettled\",\"owner\":{\"incarnation\":\"i\",\"claim\":\"c\"},\"bindingId\":\"b\",\"registration\":\"r\",\"demandWatermark\":0,\"outcome\":\"failed\"}\n";
741
+
assert!(matches!(
742
+
decode_runtime_line(zero_watermark),
743
+
Err(ProtocolError::InvalidDemandWatermark)
744
+
));
661
745
}
662
746
663
747
#[test]
@@ -758,6 +842,19 @@ mod tests {
758
842
decode_runtime_line(&health_line),
759
843
Err(ProtocolError::HealthDetailTooLarge{ .. })
760
844
));
845
+
let settlement = RuntimeMessage::ObservationSettled{
Copy file name to clipboardExpand all lines: docs/vrs/.decisions/0014-resource-profiles-are-state-first-read-and-observe-capabilities.md
+41-3Lines changed: 41 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,6 +22,11 @@ Two prototypes bounded the design. A synthetic 16-observation pull-request seque
22
22
6. The descriptor declares shared or per-binding runtime topology. Both use one normalized host protocol and the same per-binding delivery state.
23
23
7. When delivery is unavailable, st2 retains only `pending_relevant_change` beside current and last-delivered digests. Resume emits at most one invalidation for current state.
24
24
8. The initial capability set stops at read and observe. Provider mutations, actions, approvals, and a canonical event log require separate research and design.
25
+
9. st2 may carry a generic declared, fenced demand-observation scheduling hint
26
+
to the resident profile runtime. The profile still owns polling, push,
27
+
subscription, provider mechanism, cursor, rate limits, cache, and backoff.
28
+
Demand is neither a provider-specific reconcile command nor a provider
29
+
write, and exact settlement evidence rather than a host clock closes it.
25
30
26
31
## Options
27
32
@@ -71,7 +76,40 @@ claim, each binding registration receives a token, and host acceptance requires
71
76
both to match. A new claim fences all prior output and clears registrations.
72
77
Shared and per-binding topologies use the same reducer.
73
78
74
-
The normalized wire protocol contains only `register`, `unregister`, `publish`,
75
-
and `health`. EOF and existing supervisor lifecycle replace `shutdown`;
0 commit comments