Distributed project state — verified landing

The monolithic project index was replaced as the write store by independently versioned semantic resources. Compatibility reads remain composed; aggregate writes are rejected after marker activation.

Project state decomposed into independently versioned sprint, milestone, blocker, timeline, and project resources.
The implementation follows the locked semantic-HTML, unique-active, and identity-only-manifest decisions.

Storage and composition

ResourceCanonical storeConcurrency
Sprintdocs/sprints/<id>.htmlIndependent version + narrow file lock
Milestonedocs/milestones/<id>.htmlIndependent version + narrow file lock
Blockerdocs/blockers/<id>.htmlIndependent version; reference count derived
Timelinedocs/state/<project>/timeline.htmlAppend-only events with deterministic ids
Projectdocs/state/<project>/project.jsonIdentity and presentation only

Sprint item lifecycle status and implementation fraction are resolved from live plan HTML. The active sprint id is derived from the unique active sprint; zero is valid and multiple active resources fail audit/composition.

Migration evidence

Verification

Independent review identified format-boundary, rollback, recovery-race, durability, HTTP symmetry, parity, and reference-validation gaps in the initial landing. Commit 40e6cd6 closes those findings with regression coverage.

Final review found three narrower boundaries: markerless discovery still preferred project.json, simultaneous activation could race across different sprint files, and a static projection suppressed discovery failures other than 404. Commit a837fc7 makes the legacy index exclusive, locks only transitions into active status, and behavior-tests explicit static-hosting fallback.

GateResult
Distributed storage/concurrency/migration tests41 included in full suite
Targeted concurrency and legacy precedence5 passed in 8.73 s
Executable SPA fallback scenarios2 passed in 0.58 s
Storage, typed-resource, MCP, edit, and build integration146 passed
Complete test suite1,349 passed in 29.86 s
Ruffclean
Schema regenerationcommitted parity
Legacy index preservationbyte-identical

Concurrent same-resource writers produce exactly one winner and one version conflict. Concurrent migrations serialize globally, concurrent recovery readers restore a prepared move exactly once, and committed journals are removed without rollback. HTTP, MCP, and SPA paths reject stale legacy fallback after distributed activation.