Skip to content

Task snapshot versioning evidence

Task: 29c8188a-e4e3-454c-910e-e407da76392e, frozen version 15. Repository: h8v6/heyaira. Branch: heyaira/29c8188a. Base: 7d9d2ca58af13a8e82247cac82ddffa112ecee74.

Decision and cause

Use the task's explicit fallback: retain snapshots for content-identical version-bumping updates. No runtime code or migration changes are needed, and no existing history is rewritten.

capture_task_version() in migrations/029_task_execution_context.sql is the snapshot writer. It records task inserts and every change to tasks.version. task_update in src/heyaira/server.py increments and returns that version even when all supplied fields equal the current values, or when all optional fields are omitted. Reusing the old expected_version must still fail.

task_get(version=N) calls versioned_task() in src/heyaira/task_execution.py, which reads the exact project/task/version row and raises task_version_not_found when it is absent. Skipping the duplicate snapshot while preserving the concurrency bump would therefore make a version already returned to a client unreadable. Keeping the old version instead would change the optimistic-concurrency contract. Inferring an omitted snapshot from the preceding row would also lose its original version/timestamps; the current schema has no alias representation. This task explicitly permits retaining rows when skipping would break version semantics.

Regression coverage

tests/test_task_version_snapshots.py exercises the production MCP server's registered tools against real, disposable PostgreSQL databases. The fixture supplies a synthetic authenticated actor; it does not test the HTTP transport or credential authentication. No listening socket is needed.

Both omitted-field and explicitly identical-field no-ops are covered. Each case creates a task, performs two no-ops, rejects stale writes, then changes the description. It checks that the first three full snapshots have equal content excluding version/timestamps, that every returned version remains readable through task_get(version=N) after the later change, that timestamps represent the original instants, and that existing history rows remain unchanged.

Checks

Focused PostgreSQL command:

PYTHONPATH=src python scripts/test_postgres.py tests/test_task_version_snapshots.py -p no:cacheprovider
2 passed in 20.69s
postgres_acceptance=passed: selected tests, zero skipped tests
exit 0

A temporary pytest plugin replaced capture_task_version() only in a separate disposable test database with a mutant that returns without inserting when to_jsonb(NEW) - ARRAY['version','created_at','updated_at'] equals the latest stored snapshot with those same keys excluded. Both regressions rejected it:

AssertionError: assert 1 == 2
2 failed in 22.99s
exit 1 (expected mutation-test failure)

The mutant still returned the incremented client version but stored only one history row. The temporary plugin was removed; neither it nor the mutated function is part of the candidate. The disposable databases were dropped by the runner.

The full suites reported failures in existing tests. A focused reproduction identified a sandbox limitation:

PYTHONPATH=src python -m pytest -q -p no:cacheprovider tests/test_deployment_guard.py -x
ops/deploy-heyaira.sh: line 856: cannot create temp file for here document: Operation not permitted
FAILED tests/test_deployment_guard.py::test_failed_health_rolls_back_with_overlay_and_previous_revision
1 failed, 4 passed in 5.86s
exit 1

Full non-DB command:

PYTHONPATH=src python -m pytest -q -p no:cacheprovider
53 failed, 780 passed, 778 skipped in 937.15s (0:15:37)
exit 1

Failures comprise 52 cases in tests/test_deployment_guard.py and tests/test_healthz.py::test_healthz_answers_within_the_probe_timeout_when_the_database_hangs. The deployment cases encounter the shell here-document limitation reproduced above; the health check exceeds its elapsed-time assertion. These are existing tests outside task-version writing; no runtime implementation changed in this candidate. The ordinary non-DB run also skips database-dependent tests when their isolated database URLs are absent.

Full database command:

PYTHONPATH=src python scripts/test_postgres.py
Unified exec process failed: Network access to "server" was blocked: local/private network addresses are blocked by the sandbox policy.

The tool reported the network denial while polling this run. Its saved output ends without a final pytest summary or runner acceptance result. The log contains 1,413 completed progress markers out of 1,611 collected tests: 934 passing markers, 424 skipped markers and 55 failure markers. These are partial-run observations, not final suite counts or an exit code.

Matching the markers to the collected test order identifies 52 failures in tests/test_deployment_guard.py and these three existing backup tests:

  • tests/test_backup_state_marker.py::test_a_statistics_reset_never_repeats_an_earlier_marker
  • tests/test_backup_state_marker.py::test_a_discarded_statistics_epoch_moves_the_marker
  • tests/test_backup_state_marker.py::test_the_marker_does_not_depend_on_the_session_time_zone

The interrupted run did not emit final failure details or skip reasons, so no claim is made that all its skips satisfy require_listening. The focused snapshot run above completed separately with two passes and zero skips.

This task does not authorize changes to deployment scripts, backup markers, health checks or their tests, or bypassing the network restriction. No such changes were made. dedupe passes using the documented fallback; db-suite and suite fail. Neither full suite is claimed to pass.

Scope and handoff

Only this evidence file and tests/test_task_version_snapshots.py are changed. No migration, runtime implementation, Bridge pairing, decision implementation or agent_put changes are included. The first local commit is 0c413d415e710364c41724152eb85a8288ab5934; a subsequent evidence-only commit records these final check outcomes without rewriting that commit.

Confidence is high in the reason for retaining no-op snapshots and in the tested version/concurrency contract. Full-suite acceptance is blocked by the failures and incomplete database run recorded above. Rerun the full checks in a supported test environment before claiming those criteria pass. No push, pull request, merge, install, deployment or production mutation was performed.