Dependency publication now recovers interrupted config/facts changes before activation and leases live generations during collection. Receipts retain update correlation and failed steps across nested command boundaries. Doctor and desktop surfaces report those failures through shared owners. Move checkout updates out of the desktop facade. Stage a detached Windows relaunch waiter before shutdown, with bounded handshake and process-birth checks. Keep packaged lifecycle tests isolated from the installed app. Native verification exposed two production races: cron maintenance imported the interactive CLI and rewrote TERMINAL_CWD, and install-ID reads collided with first publication. Use the existing owners and locks. Plugin checks now run at startup and each due-gated housekeeping tick, not after 60 ticks. Share updater-test mutation boundaries and remove collection-root fixtures. Separate cold MCP startup from command latency and give the real HTTP drip test enough time to reach body handling. Root npm check passed, including packaging. The fixed-tree Windows Python run reported 44557 passed, one failed, and 1404 skipped, plus one retry-only HTTP test. Those final failures now pass in a 35-test bounded batch. A real isolated gateway wrote startup and periodic plugin-check receipts. Full final-tree CI, bundled Sandbox deployment, and actual App Installer relaunch remain unverified. docs/pm-audit-status.md records these limits.
35 lines
1.4 KiB
Python
35 lines
1.4 KiB
Python
"""Nested command boundaries and copied contexts cannot close an outer receipt."""
|
|
import contextvars
|
|
|
|
from hermes_cli import update_receipt as receipts
|
|
|
|
|
|
def test_command_scope_retains_outer_receipt(tmp_path, monkeypatch):
|
|
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
|
|
monkeypatch.setattr(receipts, "_code_identity", lambda **kw: {})
|
|
receipts.begin_update_receipt()
|
|
outer = receipts.current_correlation_id()
|
|
try:
|
|
with receipts.update_receipt_scope():
|
|
receipts.begin_update_receipt()
|
|
receipts.finalize_update_receipt("success")
|
|
assert receipts.finalize_pending_update_receipt(0) is None
|
|
assert receipts.current_correlation_id() == outer
|
|
assert receipts._current.get().data["outcome"] == "running"
|
|
finally:
|
|
receipts.finalize_update_receipt("success")
|
|
|
|
|
|
def test_copied_context_finalize_does_not_mutate_parent(tmp_path, monkeypatch):
|
|
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
|
|
monkeypatch.setattr(receipts, "_code_identity", lambda **kw: {})
|
|
receipts.begin_update_receipt()
|
|
try:
|
|
contextvars.copy_context().run(receipts.finalize_pending_update_receipt, 1, "child failed")
|
|
parent = receipts._current.get().data
|
|
assert parent["outcome"] == "running"
|
|
assert "exit_code" not in parent
|
|
assert "stop_reason" not in parent
|
|
finally:
|
|
receipts.finalize_update_receipt("success")
|