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
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,11 +9,11 @@ materialization, messaging, DING, or presence must preserve them.
9
9
|**Transport-decoupled lifecycle**| Each task is isolated from a supervisor/transport process-group or cgroup cascade. |`tests/transport_isolation.rs`; `tests/transport_isolation_macos.rs`|
10
10
|**Clean exec teardown**| Killing an exec task reaps its whole process group. |`tests/exec_backend.rs::exec_kill_reaps_the_whole_process_group_not_just_the_leader`|
11
11
|**Bounded restart diagnostics**| Relaunching an exec task preserves the just-finished log as one prior generation while bounding retained diagnostics to current plus prior. Final retirement removes the PID and both logs. |`tests/exec_backend.rs::exec_restart_reap_keeps_bounded_diagnostics_and_final_remove_cleans_them`; `tests/run.rs::up_once_finally_removes_dead_retired_tasks_without_restarting_them`|
12
-
|**Exactly-once-safe native bus**| Messages use stable `<unix-ms>-<rand6>.md` files. An archive filename is a durable receipt that suppresses restored inbox replicas and makes repeated archive cleanup idempotent. |`src/message.rs::filename_grammar`; `src/message.rs::archive_receipt_suppresses_and_idempotently_cleans_a_restored_inbox_copy`; `tests/message.rs`|
13
-
|**Generic delayed-submit native DING**| Each post-start unread message becomes one normalized `[DING]` frame sent as one exact PTY sequence: literal notice bytes, a fixed 500 ms pause, then Return. DING does not inspect renderer or pane state and never sends Escape. Startup backlog is silent; new arrivals remain FIFO; archive receipts suppress re-DING; `busy` and `dnd` defer delivery without loss. |`src/ding.rs::poke_text_normalizes_and_bounds_untrusted_fields`; `src/ding.rs::malicious_controls_cannot_escape_the_single_paste_frame`; `src/ding.rs::pty_send_is_one_exact_delayed_sequence_without_inspection_or_escape`; `src/ding.rs::session_watch_has_startup_grace_debounce_and_live_reset`; `src/ding.rs::new_arrivals_is_fifo_and_archive_receipts_prevent_reding`; `src/ding.rs::pending_delivery_respects_status_fifo_archive_and_transport_retry`; `src/ding.rs::startup_backlog_is_silent_and_only_post_start_arrivals_poke`|
14
-
|**Agent-declared delivery gate**| The shipped bus contract requires agents to declare `busy` before executing work, use `available` only while yielding or ready, and reserve `dnd` for an explicit hold. Both native harnesses materialize that contract; DING relies on those declarations rather than renderer inspection. |`tests/compile_agent.rs::compile_agent_generates_claude_then_materializes_verbatim_persona`; `tests/compile_agent.rs::compile_agent_generates_codex_then_materializes_composed_agents_md`; `src/ding.rs::pending_delivery_respects_status_fifo_archive_and_transport_retry`|
12
+
|**Exactly-once-safe native bus**| Messages use stable `<unix-ms>-<rand6>.md` files. An archive filename is a durable receipt that shadows and cleans restored inbox replicas and makes repeated archive cleanup idempotent. |`src/message.rs::filename_grammar`; `src/message.rs::archive_receipt_suppresses_and_idempotently_cleans_a_restored_inbox_copy`; `tests/message.rs`|
13
+
| **Generic delayed-submit native DING** | Each post-start unread message becomes one normalized `[DING]` frame sent as one exact PTY sequence: literal notice bytes, a fixed 500 ms pause, then Return. DING does not inspect renderer or pane state and never sends Escape. Startup backlog becomes one generic recovery DING; new arrivals remain FIFO; archive receipts suppress re-DING; `busy` delivers immediately; only fresh `dnd` defers; failed sends retry in memory. | `src/ding.rs::poke_text_normalizes_and_bounds_untrusted_fields`; `src/ding.rs::malicious_controls_cannot_escape_the_single_paste_frame`; `src/ding.rs::pty_send_is_one_exact_delayed_sequence_without_inspection_or_escape`; `src/ding.rs::session_watch_has_startup_grace_debounce_and_live_reset`; `src/ding.rs::new_arrivals_is_fifo_and_archive_receipts_prevent_reding`; `src/ding.rs::pending_delivery_ignores_busy_but_respects_fresh_dnd_archive_and_retry`; `src/ding.rs::startup_recovery_notice_retries_in_memory`; `src/ding.rs::startup_backlog_gets_one_generic_recovery_then_new_arrivals_poke` |
14
+
|**Agent-declared presence discipline**| The shipped bus contract requires agents to declare `busy` before executing work, use `available` only while yielding or ready, and reserve `dnd` for an explicit hold. Both native harnesses materialize that contract. Busy remains observable but does not suppress DING; fresh `dnd` is the only delivery gate. |`tests/compile_agent.rs::compile_agent_generates_claude_then_materializes_verbatim_persona`; `tests/compile_agent.rs::compile_agent_generates_codex_then_materializes_composed_agents_md`; `src/ding.rs::pending_delivery_ignores_busy_but_respects_fresh_dnd_archive_and_retry`|
15
15
|**Stable roster JSON**|`st2 agents --json [--enrich]` preserves field names, order, null handling, presence, explicit retirement state, activity, and inbox counts. Human output marks retired declarations without changing active rows. |`src/agents.rs::agents_json_has_stable_wire_shape`; `tests/status_agents.rs::roster_json_and_human_output_distinguish_retirement_from_presence`|
16
-
|**Agent-declared presence**| Refresh preserves the agent's declared status and only advances liveness; a missing status starts as `available`, while an unrefreshed declaration ages to `unknown`. |`src/status.rs::refresh_preserves_value_and_bumps_mtime`; `src/status.rs::refresh_missing_writes_available_default`; `src/status.rs::stale_mtime_reads_as_unknown_regardless_of_contents`|
16
+
|**Agent-declared presence**| Refresh preserves non-DND declared status and only advances liveness; a missing status starts as `available`, while `dnd` is never refreshed and an unrefreshed declaration ages to `unknown`. |`src/status.rs::refresh_preserves_value_and_bumps_mtime`; `src/status.rs::refresh_leaves_dnd_to_age_out`; `src/status.rs::refresh_missing_writes_available_default`; `src/status.rs::stale_mtime_reads_as_unknown_regardless_of_contents`|
17
17
|**Retirement health**| A retired declaration is healthy only after every declared task ID is absent. Any live or dead declared task record reports incomplete retirement; retired declarations do not require presence. Live declarations retain their existing task and presence checks. |`tests/doctor.rs::retired_declaration_is_healthy_when_tasks_and_presence_are_absent`; `tests/doctor.rs::retired_declaration_is_unhealthy_while_a_declared_task_is_alive`; `tests/doctor.rs::retired_declaration_is_unhealthy_while_a_dead_task_record_remains`|
18
18
|**Crash loops surface**| A task parked by a fail-mode restart policy notifies its supervisor once over the bus. |`tests/run.rs::surface_crash_loop_notifies_the_supervisor_over_the_bus`|
19
19
|**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`|
0 commit comments