feat: resilient system-manifest deploy — continue-on-error + partial-success report (trinity-enterprise#125) - #1760
Conversation
|
Resolve by running |
/review report —
|
…success report (trinity-enterprise#125)
POST /api/systems/deploy is best-effort by default: a per-agent create
failure is collected into failed[] ({name, short_name, template, reason,
status_code}) and the remaining agents still deploy, instead of the first
failure aborting the whole fleet as an opaque 500.
- Tri-state status: "deployed" (all created, 200) / "partial" (some
failed, 200) / "failed" (none created, 500 with the full report body so
code-only callers don't read total failure as success); "valid" (dry_run)
unchanged.
- strict: true restores abort-on-first-error, preserving the failing
agent's ORIGINAL status code (4xx no longer flattened to 500).
- Post-create config (folders/permissions/schedules/tags) scoped to the
survivor map, and each phase individually degrades to a warning — a
config failure after successful creates can no longer void the report.
- trinity_prompt write moved post-loop, gated on >=1 created agent, so a
totally-failed deploy never mutates the platform-wide prompt.
- failed[].reason normalized (dict detail -> error field), credential-
sanitized + URL-userinfo-redacted (git errors embed PAT-bearing remote
URLs, learnings 2026-07-14) + truncated; new shared
redact_url_userinfo() in utils/credential_sanitizer.
- Warnings: partial deploys flag the _N-suffix duplicate-on-redeploy trap
(converge deferred to trinity-enterprise#124); orchestrator-workers
preset with a failed orchestrator flags a possibly non-functional fleet.
- MCP deploy_system: strict param + failed[] response typing (Invariant #13).
- Tests: 14 hermetic unit tests (router mounted alone, collaborators
patched at the module binding) + 3 integration tests using the
deterministic pre-side-effect cpu:"3" failure vector.
Follow-up filed: #1759 (absent local: template silently creates a blank
agent — discovered during review).
Prerequisite for trinity-enterprise#124 (first-run seed) and
trinity-enterprise#126 (UI manifest install).
Refs Abilityai/trinity-enterprise#125
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
b7db148 to
80f29bc
Compare
Summary
POST /api/systems/deploybecomes best-effort by default: a per-agent create failure is collected intofailed: [{name, short_name, template, reason, status_code}]and the remaining agents still deploy — instead of the first failure aborting the whole fleet as an opaque 500 (already-created agents left behind with no report).status=deployed(all created, HTTP 200) /partial(some failed, HTTP 200) /failed(none created, HTTP 500 with the full report as the body socurl -f-style callers don't read total failure as success);valid(dry_run) unchanged.strict: truerestores abort-on-first-error, preserving the failing agent's original status code (4xx no longer flattened to 500).warningsentry — a config failure after successful creates can no longer void the promised report.trinity_promptis written only when ≥1 agent was created.failed[].reasonis treated as a disclosure surface: dict details normalized to theirerrorfield, credential-sanitized, URL-userinfo-redacted (git errors embed PAT-bearing remote URLs — learnings 2026-07-14), truncated at 500 chars. New sharedredact_url_userinfo()inutils/credential_sanitizer.py._N-suffix duplicate-on-redeploy trap (converge/on_conflictdeferred to trinity-enterprise#124); anorchestrator-workersdeploy whose orchestrator failed flags a possibly non-functional fleet.deploy_system(Invariant feat: SMARTS trading pipeline with Telegram notifications and Miro visualization #13):strictparam +failed[]response typing + best-effort description.Prerequisite for trinity-enterprise#124 (first-run starter-fleet seed) and trinity-enterprise#126 (UI manifest install). Epic: trinity-enterprise#122.
Changes
src/backend/routers/systems.py— best-effort create loop,_failure_reasonnormalization chokepoint, survivor scoping, guarded config phases, post-loop prompt write, 500-with-report on total failuresrc/backend/models.py—SystemDeployFailure,SystemDeployResponse.failed,SystemDeployRequest.strictsrc/backend/utils/credential_sanitizer.py— additiveredact_url_userinfo()(mirrors agent-side bug: git auto-gc can never complete inside agent containers — unbounded, silent workspace .git bloat (273GB observed; 97%-garbage repos) #1595 helper)src/mcp-server/src/tools/systems.ts—strictparam,failed[]typing, descriptiontests/unit/test_ent125_resilient_system_deploy.py— 14 hermetic router tests (partial/total/strict/all-success/dry-run, survivor scoping, config-phase degradation, dict-detail normalization, PAT-URL redaction, truncation, prompt-write gating, orchestrator warning)tests/test_systems.py— 3 integration tests using the deterministic pre-side-effectresources: {cpu: "3"}failure vectorrequirements/roadmap.md§16.5,feature-flows/system-manifest.md,learnings.md(silent blank-agent pitfall),tests/registry.jsonTest Plan
pytest tests/unit/test_ent125_resilient_system_deploy.py -v— 14/14 pass; also green combined with the sys.modules-churning neighbors (test_1081_pull_endpoints.py) in both orderstest_models_centralized.py(Invariant Add internal health route, without which main didn't start #14) +test_1661_sanitizer_linear.pypass (61 total)pytest tests/test_systems.py::TestResilientDeploy -vagainst a running stack — written but not yet executed (local Docker was down during development); please run at next stack-up or via test-runnertsc --noEmit— only pre-existing unrelatedyaml-types noise in pipelines.ts)Notes for review
local:template silently creates a blank agent (pre-existing; discovered while designing the failure vector — it invalidatedlocal:nonexistentas a test failure trigger). Filed as bug: absent local: template silently creates a blank agent (no error) #1759 with the evidence; matters for the ent#124 seed.RefsnotFixes— the private tracker issue (trinity-enterprise#125) is closed manually at release per working agreement.Refs abilityai/trinity-enterprise#125
🤖 Generated with Claude Code