Persist image assets and add Craft service discovery - #3
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Storage contract
The configurable managed data root contains:
Manifest schema version 1 stores strict immutable source records and output records. Source records retain display metadata, decoded format/MIME/dimensions, a stable seed, UTC creation time, and a server-ID-derived relative path. Output records retain the source ID, display filename, dimensions, MIME type, UTC creation time, and the exact strict Recipe v1 snapshot and seed used for export.
Only normalized managed relative POSIX paths are persisted. Absolute paths, traversal, unknown fields, unsupported kinds, inconsistent IDs, non-UTC dates, mismatched format/MIME/extension metadata, invalid dimensions, and invalid embedded recipes are rejected. Public APIs never return managed or absolute paths.
Every mutation validates and serializes the complete next manifest, writes and flushes a same-filesystem temporary file, uses
fsyncwhere supported, preserves a last-known-good backup, and atomically replaces the primary. In-memory state advances only after persistence succeeds. Newly installed files are removed if manifest persistence fails.At startup, a missing manifest initializes cleanly. A corrupt/missing primary with a valid backup is restored and readiness is degraded for that process. If both primary and backup are invalid, neither is overwritten: health remains available, readiness returns 503/not-ready, and persistent asset operations return controlled 503 responses.
Reconciliation removes records for missing managed files while leaving existing output files usable if their source is missing. Orphans are reported and never deleted automatically. Recovery reports remain private in the recovery area.
Output deletion removes one record/file. Source deletion conflicts while outputs reference it unless
cascade=trueapplies one logical manifest mutation. Active leases return 409. Persistent images are never age-expired. Cleanup defaults to dry-run; temporary cleanup is age-based and orphan deletion requires explicit opt-in plus a minimum age.Library APIs
GET /api/image-sourcesGET /api/image-sources/{source_id}DELETE /api/image-sources/{source_id}?cascade=trueGET /api/image-outputsGET /api/image-outputs/{output_id}/metadataDELETE /api/image-outputs/{output_id}GET /api/storagePOST /api/storage/cleanupExisting upload, original, preview, export, inline-output, and download URLs remain compatible.
Craft discovery
GET /app-manifest.jsonprovides static GlitchCraft identity, version0.1.0, truthfulhttp://127.0.0.1:5000defaults, endpoint links, capability slugs, and a provisional SVG markGET /metadataprovides request-derived runtime addresses, schema versions, supported formats, effect types, library counts, and redacted linksGET /healthprovides lightweight process/route liveness onlyGET /readyreportsready,degraded, ornot_readywith redacted storage, image, registry, reconciliation, FFmpeg, and optional FFprobe checksGET /api/capabilitiesdistinguishes implemented, currently available, and optional capabilitiesGET /api/storagereports redacted counts, bytes, writability, free space when available, and reconciliation stateThe service remains unauthenticated and loopback-only. No broad CORS, analytics, cloud processing, external media service, executable paths, disk paths, commands, environment values, or tracebacks are exposed.
Compatibility
Validation
python check.py: 169 tests passedgit diff --checkpassedok, readiness returned HTTP 503/not_ready, and both invalid files remained byte-for-byte unchangedKnown limitations