Why this release exists
A fleet-wide census found that 32 of 34 recorded data/config paths — and 6 of 6 stray static paths — pointed at directories that did not exist. The root cause was structural: registration guessed sub-paths for every service, but most services were never deployed by this server, so the guesses became fiction that purge offered to delete and audits reported as real. v2 removes the possibility of that class of record.
Breaking changes
- Schema:
service_deploymentscolumnsapp_path/static_path/data_path/config_path/log_pathare removed, replaced bylayer(standard/nonstandard),project_root,deploy_root,workspace_url, andpath_overrides(JSON). Sub-paths are derived from roots by convention via a single resolver; only deviations are stored. register_serviceis now allocation-only (standard layer): it assigns roots thatdeploy_serviceconsumes. The five old path parameters are gone.update_servicefield set changed accordingly;layeris updatable, and promoting a record tostandardre-validates all effective paths.
New
record_service(tool #42): registers services that already exist and were not deployed by this server. Zero defaults — unknown facts stay null instead of being invented. Deploy refuses these records; purge never deletes their directories.scripts/migrate_resource_model.py: two-phase migration (add+backfill while old code runs → drop after new code is live), dry-run by default, per-record report, re-run-safe, refuses to drop columns on an unmigrated DB.- Health check now probes the deployments table, so a schema/DB regression turns
/healthunhealthy and the auto-deploy rollback can actually catch it (previously it only probed port allocations and reported healthy on a broken schema). - Test suite from zero to 50 tests (pytest + pytest-asyncio), covering the model, path resolution, both registration modes, deploy/purge guards, and the migration script against fixture DBs.
Docs
docs/MCP-API.md (allocation-vs-recording model, full record_service section), docs/Data-Models.md (new schema), README tool count.