mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-10-26 21:47:47 +00:00
acfcb5567b
* fix(gitops): keep an application addressable when its evidence cannot be read A remote application whose evidence this hub cannot walk answered 404, the same as one that does not exist, so an operator's only signal was an application that had vanished. It now answers 503 with an `evidence_unavailable` code when the row names the application but the projection cannot be read, and the view says evidence is unavailable and offers a retry. A row that never named the application still answers 404, and an unreadable row stays 404 so the two cannot be told apart. Validating that answer meant walking the projection properly. The detail endpoint and the portfolio now check the same evidence: an artifact qualification the facet and its latest evidence disagree on, a blank generation or identity standing in for a real one, and a status from a newer node all read as unknown evidence rather than as a convergence claim. Convergence itself is now proven from the target evidence rather than read off the rollout status, an Inline Blueprint no longer inherits a Blueprint's claim, and a target the intent withdrew no longer keeps an application in the attention queue. Reading a remote row also authorizes it against the node that owns it rather than the node the caller is viewing, and the phone portfolio says partial when the merge cap dropped rows, not only when a node failed. * fix(gitops): grade unfamiliar evidence as unknown instead of unavailable Two shape validators rejected a vocabulary this build does not recognize, which made a whole projection unusable rather than merely unfamiliar. An unusable projection costs the operator its row: the portfolio shows an evidence unavailable placeholder and the detail route answers 503. That claims the evidence is unavailable, which is a stronger statement than an unfamiliar word supports. A last-known-good unavailable reason is now accepted on its structure and graded as unknown evidence instead, on both sides of the wire. The browser refusing the reason the server had already graded would only have replaced the honest answer with a total read failure, and the two validators would have disagreed about the same payload. A drift identity kind is accepted the same way, so one unfamiliar kind costs that row its label instead of the whole application. The label names the kind it cannot read instead of rendering nothing. The kind list is a total record over the identity union, so adding a kind without wording for it is a compile error, and the lookup is own-property, so an inherited key reads as unfamiliar. A blank reason is still rejected, and the mirror consistency rules still reject an incoherent last-known-good record. Verified: backend and frontend tsc clean; seven backend GitOps suites pass (446 tests); full frontend suite passes (3597 tests); frontend lint reports 0 errors. * fix(gitops): restore the recovery-required rollback scope and drop a dead import The conflict resolution carried this branch's three-member failed-runtime set over the four-member set on the main branch, because this branch had reordered the same three entries and the two edits merged without a conflict marker. A target whose recovery is restoring or compensating reports recovery_required, so it stopped counting as a failed target and the rollback dialog stopped offering the failed-targets scope for exactly the stacks that need recovery. The set now matches the main branch, with the type annotation kept. The existing test covered recovery_failed only, so the scope is now asserted for both recovery states. Also removes a type import the same resolution orphaned. The type checker does not report unused imports, so this surfaced only in the backend lint job.