release: actor-bound application runtime v0.7.0-rc.30 - #348
Conversation
…light; git-dep animus-plugin-protocol; drop in-tree copy + protocol_drift test Kernel-side consumption of the multi-kind protocol change. Protocol dep currently points at the feat branch; will repoint to animus-protocol main on 0.7 integration.
…ce) — multi-kind on release/0.7 Repoint all animus-protocol deps that touch animus_actor to v0.7.0-rc.1 (= v0.1.26 + additive multi-kind), unifying the actor rev (no duplicate-crate E0308). Keep the pre-actor old-wire aliases (subject-protocol-v05 + queue-protocol) at v0.5.10 as a distinct rev. In-tree animus-plugin-protocol dropped earlier; kernel now consumes plugin_kinds/serves_kind. Workspace builds; 0.6.33 fixes + actor foundation intact.
…lities InitializeResult/PluginInfo/PluginManifest test constructors gain the new multi-kind fields. Workspace builds; plugin-host 190+ tests + preflight 23 green.
One plugin process can now serve multiple roles. Introduce a process-global ResidentHostRegistry keyed by (canonical binary path, mtime, spawn-context fingerprint) that unifies the previously per-role host caches so a binary resolved by several resident-style roles is spawned + handshaked once and shared. LRU-bounded with lease-pinned eviction (a host with an outstanding lease is never reaped mid-RPC / mid-watch). Rewire the three resident spawn sites onto the shared registry: - subject_backend (subject_router LazyHosts): host lookup/spawn moved into the registry; per-router cache/LRU removed. Each subject spec fingerprints its own spawn context (manifest-only env + project-root cwd), keeping it distinct from the full-env config/journal slot (preserves the v0.4.x secret trust boundary). - config_source (config_source_client): resident cache replaced by the registry; retry/backoff + handshake-error cleanup preserved; lease held across the RPC. - workflow_journal (journal_client): same. The spawn-context fingerprint is load-bearing: config_source and workflow_journal (both forward the full parent env) share one process, while a subject_backend spawn of the same binary stays separate. In-place upgrades (new mtime) reap the stale-mtime process. Legacy ANIMUS_SUBJECT_HOST_CACHE_MAX honored as a fallback to the new ANIMUS_RESIDENT_HOST_CACHE_MAX. Tests: registry cross-role sharing (one spawn/handshake, shared process + distinct-context isolation), LRU skips leased hosts, stale-mtime reap on upgrade; existing subject_router lazy tests ported to the shared registry.
…time + cli fixtures
…id (TASK-158) resolve_auto now prefers ANIMUS_SECRET_KEY / key_file (user-key), then ANIMUS_SECRET_PASSPHRASE (passphrase), and only falls back to device-id on interactive local hosts (with a one-time warning). On server/headless hosts (ANIMUS_SECRET=1 or no TTY on any std stream) the device-id fallback is a hard error, since it is decryptable by any local user. Also hardens the device store: temp files are created O_EXCL + 0600 with collision retry (no world-readable window), and dir chmod failures propagate instead of being swallowed.
…OFU (TASK-159) Make the plugin signature policy context-aware and stop animus install from silently downgrading trust on hostile repos. - effective_policy_mode now resolves in precedence order: explicit per-call flag > ANIMUS_PLUGIN_SIGNATURE_POLICY env > plugins.signature_policy global config > Warn default. Local default is unchanged (Warn) so the fix is inert until a host opts into strict. resolve_cli_signature_policy returns Option so a flag-less plugin install also inherits env/config. - Publisher TOFU fails closed off a TTY: enforce_org_trust no longer lets yes/force auto-trust an unknown org in a non-interactive/server context, and the release-source gate now runs BEFORE download + --manifest probe so no untrusted binary is fetched or executed before rejection. animus install and the MCP install tool gain --allow-org / allow_org escape hatches; locked installs thread the operator allowlist through. - Cosign preflight: strict + missing cosign fails fast with an actionable error before any download/probe instead of a confusing per-plugin block. - Pure, injectable resolver seams (resolve_signature_policy_layers, parse_signature_policy_layer, resolve_org_trust_gate, cosign_preflight_error, enforce_org_trust_with) with unit tests for precedence, env/config layers, fail-closed TOFU, and the cosign preflight message. - Docs: ANIMUS_PLUGIN_SIGNATURE_POLICY + plugins.signature_policy + ANIMUS_SERVER and the TOFU fail-closed behavior in cli/index.md and configuration.md.
…l-closed TOFU (TASK-159)
… slug-in-flavor Fixes two codex findings on the discovery pre-probe scope gate: P1 (project-registry binary: vector): under an unrestricted (`all`) scope the effective admit set is everything, so the pre-probe scope gate never fired and `<project>/.animus/plugins.yaml` `binary:` entries were probed (EXECUTED) even on the server-safe path. A cloned hostile repo could commit a plugins.yaml pointing at `./.animus/plugins/evil` and get it run during discovery. The project registry is repo-shippable (UNTRUSTED), so it is now gated behind `probe_project_local_plugins` exactly like the project-local directory scan — the server-safe `discover_plugins` leaves the whole project-local tier OFF and never executes a repo-shipped binary. P2 (renamed installed plugins): the pre-probe gate skipped any candidate whose filename slug was outside the flavor admit set, so a plugin installed with `--name custom` under a flavor-required manifest name was dropped before `PluginScope::admits`'s post-probe manifest-name fallback could match it. The pre-probe skip now fires ONLY on UNTRUSTED (`DiscoverySource:: ProjectLocal`) candidates; TRUSTED installed candidates (global registry, global install dir, $PATH) are always probed and filtered post-probe, so renamed required plugins keep discovering. Adds `DiscoverySource::is_untrusted()`; new regression tests: hostile project registry not executed on the server-safe path under `all` scope, and a renamed trusted install still probed+admitted under flavor-only scope.
…nal preflight role (v0.7 foundation) - repoint animus-protocol crates v0.7.0-rc.1 -> rc.2 (old-wire v0.5.10/v0.5.5 aliases untouched) - add animus-environment-protocol dep; re-export as orchestrator_core::environment (client-types seam for follow-on EnvironmentClient) - surface workspaces / environment_routing + per-workflow/phase environment/workspace through WorkflowConfig compilation (auto via config-protocol re-export); YAML roundtrip test - add pure resolve_environment() resolver in orchestrator-config with full precedence unit tests (phase > rule > workflow > default > none) - register optional RequiredRole::Environment + is_environment() helper (reported by preflight/plugin status, never required) - docs: workflow-yaml #workspaces/#environment_routing/#environment + configuration.md optional-role note
… + streaming buffer/starvation fixes (v0.7) - ping_is_dead: interpret liveness by transport state, not classify() retry semantics — any RPC error (structured, method-not-supported) or a Timeout is ALIVE; only ConnectionLost/ProcessExited (closed transport) is dead. Prevents reaping a busy shared host out from under a concurrent in-flight exec. - exec_stream: honor the manifest notification_buffer_size in both the spawn options and the resident-host fingerprint (environment is the streaming role); fair (non-biased) select so a concurrent handle's output flood cannot starve the request future; bound the post-response drain to the count buffered at response time so cleanup cannot spin on a neighbor's stream. - Fix the two failing ping tests (liveness interpretation + dead-host fake reads the follow-up $/ping before closing so the handshake completes cleanly).
…to environment plugin ensure_execution_cwd (BuiltinTaskSubjectAdapter) can delegate ONLY the `git worktree add` step to an installed `environment` plugin, keeping branch/path/base-ref selection, existing-worktree reuse, task-record persistence, and .mcp.json sync in-tree. Gated behind ANIMUS_ENVIRONMENT_DELEGATE so the DEFAULT stays the byte-for-byte in-tree path; a missing/unresolvable/broken/wrong-path/wrong-branch plugin falls back to the in-tree add. Cleanup on a delegation miss is restricted to the kernel-owned managed target (never a plugin-supplied path). Adds a both-paths test via an injectable prepare seam.
…-kind + host-sharing + security trio + environment kernel) Cut from release/0.7 off v0.6.33 + actor foundation. Crates bumped to 0.7.0-rc.1; animus-protocol pinned v0.7.0-rc.2. RC for staged portal verification before v0.7.0 final.
… plugins When an agent run resolves to a NON-LOCAL environment (config environment_routing or the ANIMUS_ENVIRONMENT_EXEC override), the harness command that would have been spawned on the host is prepared + executed inside that environment via EnvironmentClient (prepare -> exec_stream -> teardown), with streamed stdout/stderr surfaced through the same SessionEvent channel the local provider path uses. Default resolution is None: the local spawn path is byte-for-byte unchanged. - gate: env-var kill-switch/override + environment_routing (kind=None, harness=tool); 'local'/'worktree' ids stay on the host path - launch: contract cli.launch wins, else the built-in launch table; machine-output flags stripped (plain-text exec transport), permission mode + codex reasoning effort re-applied, system prompt mapped per tool (claude flag / prompt merge / fail-closed), prompt_via_stdin honored - spec: project root as primary repo pinned to the current checkout ref; routing-rule spec overrides (image/resources/env/opaque metadata) merged - failure posture: no silent local fallback once an env is resolved; kernel-mediated approvals fail closed; missing exit code and timeouts are terminal errors; buffered-exec fallback only on METHOD_NOT_SUPPORTED - teardown always runs once a handle exists (success or failure) Workflow-phase exec stays a runner-side follow-up: phase execution machinery is plugin-private in the out-of-tree workflow_runner.
…MENT_EXEC, default off)
- Repin animus-protocol git deps v0.7.0-rc.2 -> v0.7.0-rc.3 (adds WorkflowConfigSource::Plugin). - config_source label fix: the plugin runtime load path (load_workflow_config_with_metadata) now stamps source=Plugin instead of the misleading source=Yaml, so team_config_get reports the real config_source (postgres) rather than 'yaml'. Cosmetic; no behavior change. The genuine YAML-library compile path keeps source=Yaml. - Carries the TASK-166 Phase 2 env-routed agent exec seam already on release/0.7 (gated ANIMUS_ENVIRONMENT_EXEC, default off). - orchestrator-cli 0.7.0-rc.1 -> 0.7.0-rc.2. Fixes TASK-177. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… health last_error clear (#298) Three changes on the v0.7 plugin/discovery path. 1. DiscoverySource::DbRegistry tier (TASK-194) Adds an opt-in discovery tier that resolves the desired plugin set from the Postgres plugin_registry (served by the animus-postgres BaaS) against the binaries present on the volume. New db_registry module defines the stable in-kernel contract: DbRegistryEntry {name, version, source, sha256, target, enabled, scope} plus a PluginRegistrySource trait (the read seam) and a StaticRegistrySource stub for tests and pre-schema wiring. orchestrator-plugin-host takes no Postgres dependency; the SQL lives behind the trait in a daemon-side adapter to be added once the BaaS schema is finalized. Bootstrap paradox is respected: the tier is off until a source is wired via PluginDiscovery::with_db_registry, which the daemon only calls after the bootstrap DB-backend plugin is up. The tier slots after the explicit/project registry tiers (a hand-pinned config entry still wins) and before the unconditional global-dir scan. Enabled rows whose binary is missing surface a warning; a registry read error degrades to a single warning instead of sinking discovery. 2. noarch / any install target (TASK-200 sub-item) Release-asset resolution now falls back to a platform-independent <name>-noarch.tar.gz (or -any) asset when no triple-specific asset exists, so a JS-bundle plugin publishes ONE asset instead of duplicating bytes under every triple. A triple-specific asset always wins; noarch is strictly a fallback. target_triple_from_asset_name and the SHA256SUMS parser recognize the noarch archive under a synthetic noarch target so the integrity claim keys consistently. 3. Health last_error clear (cosmetic) PluginStatusRegistry::record_rpc now clears last_error on a successful RPC round-trip. A transient connection-lost captured during the ~4s boot window (e.g. subject_backend unroutable) latched forever and kept daemon health reading as degraded long after the subject router resolved; a successful round-trip is definitive proof the handshake completed and supersedes the stale error. Unit tests added for all three. cargo build + test + clippy pass for orchestrator-plugin-host, orchestrator-cli, orchestrator-daemon-runtime.
…ervability (#299) Part of REQUIREMENT-024 (platform correctness). Lands the in-tree slices of three linked tasks; cross-repo remainders (animus-protocol wire types and the animus-workflow-runner-default plugin) are called out as deferred. TASK-201 subjectless / ad-hoc runs: - animus queue enqueue --adhoc dispatches a run with NO bound subject (requires --workflow-ref). The wire SubjectRef is non-optional, so a subjectless run is represented as a custom-kind subject with a unique adhoc:<nanos> id, keeping each run's queue subject_key distinct so a burst of subjectless runs (relate on repo events) is never deduped into one. - Regression test proving the run-loop binds an ad-hoc subject via the built-in custom adapter instead of dying with no subject adapter registered. TASK-202 de-privilege task/requirement (also closes TASK-185 mark-running): - subject get/update/status/delete now resolve the kind from a kind-qualified id (transcript:TRANSCRIPT-001 to kind transcript) before any config default, so a qualified id never falls through to the task-favoring default. - default_subject_repo_for_kind generalized to the uniform animus-subject-<kind> convention (sqlite/markdown/linear resolve too), no longer only task/requirement. - Preflight auto-install for at_least_one_subject_backend now uses a kind-agnostic default_subject_backend_repo starter instead of the task backend, so no code path privileges task/requirement. Preflight already requires only AtLeastOneSubjectBackend, so a deployment with neither installed still boots. TASK-203 command-phase observability: - Journal wire mapping now surfaces phase_failed events in journal_events (previously dropped as unmapped). It folds into PhaseCompleted with an explicit failed status; the command exit-code + stderr snippet ride along in the event detail so failures are visible in the event stream, not only in the checkpoint snapshot decision history. Deferred (cross-repo, out of this worktree): - True Option-subject end to end and the command-phase fail-fast on an empty or unresolved template both live in animus-protocol wire types and the animus-workflow-runner-default plugin. - Emitting phase_failed for a non-zero command exit (the runner currently emits PhaseCompleted+rework) is a runner-plugin change; the in-tree journal mapping is ready to surface it once emitted. Tests, clippy, and fmt pass on orchestrator-core and orchestrator-cli.
#300) Re-pin the animus-protocol git dep to v0.7.0-rc.4 (Cargo.toml + Cargo.lock), which makes the wire subject optional (Option<SubjectRef>) on SubjectDispatch, WorkflowRunInput, and OrchestratorWorkflow. With that, replace PR 299's custom-kind adhoc:<nanos> sentinel with a genuinely absent subject. - ops_queue: adhoc_subject_dispatch (built a unique custom sentinel) is replaced by subjectless_dispatch, which builds SubjectDispatch::subjectless (subject = None). Its PR 299 tests now assert true-None behavior: no subject, no subject id/kind, and no subject_key. - Run loop: the None subject is threaded end-to-end. Bootstrap and phase-success advance bind a None subject context (no subject resolution, subject template vars simply absent) instead of a sentinel id. The runner command builder emits no subject selector for a subjectless dispatch; reattach builds a subjectless execute request. - Adapt every Option<SubjectRef> call site across orchestrator-core / orchestrator-cli / orchestrator-daemon-runtime: subject_id / subject_kind / subject_key accessors now return Option; task_id / requirement_id / schedule_id thread through the Option; journal/index/reconciliation reads fall back cleanly when the subject is absent. - Daemon within-batch queue dedup is now correlated by dispatch INDEX (via an ordered spawn-outcome vector) instead of subject_key, so subjectless entries (which have no key) reconcile correctly. Legacy queue boundary: the queue plugin RPC stays pinned to the v0.5 line for deployed-plugin wire compatibility, and that SubjectDispatch still requires a subject. queue enqueue --adhoc therefore now fails fast with a clear message (dispatch subjectless runs directly); completing subjectless enqueue needs the queue protocol to take up the optional-subject 0.7 line. The direct dispatch / control path already carries subjectless runs end-to-end. Incidental base fix (release/0.7 did not compile before this change due to a merge gap between PR 298 and PR 299): thread the plugin scope through discover_db_registry into resolve_manifests, handle the resulting SkippedOutOfScope outcome, and include the probe_project_local_plugins field in the manual PluginDiscovery Debug impl. cargo build -p orchestrator-core -p orchestrator-cli, workspace clippy, and fmt are clean. Two pre-existing decision-gate test failures (unrelated to subjects; present on the pristine base) remain.
…rm kinds), DbRegistry discovery tier, daemon-health last_error clear Cut from release/0.7: TASK-201/202/203 (dispatch), TASK-204 (Option SubjectRef, protocol rc.4), TASK-194 (DbRegistry discovery), TASK-200 noarch, plus the daemon-health last_error clear. Protocol pinned at v0.7.0-rc.4.
…ble custom verdict keys (TASK-207) (#301) * TASK-210: fix latent decision_gate resume-guard tests on release/0.7 Two decision_gate tests failed on a pristine release/0.7 (hidden until PR 300 made the crate compile): - workflow_yaml_phase_definition_with_decision_contract_blocks - workflow_on_verdict_routing_blocks_resume_advance Root cause is incomplete test fixtures, not a gating-logic bug. After the config_source plugin extraction the kernel sources config through the full validate path: - Test 1 omitted tools_allowlist, so load_agent_runtime_config failed validation (tools_allowlist must include at least one non-empty command) and _or_default fell back to the builtin config with no security-audit phase, hiding its decision_contract. The workflow config itself loaded fine with the phase_definition present. - Test 2 referenced phase research without defining it, so workflow validation rejected gated-research (references unknown phase research) and the config fell back to the builtin base with empty routing. Fix the fixtures: add tools_allowlist to both, and define the research phase (gate-free) in test 2 so validation passes. The resume gate then correctly honors the YAML-supplied decision_contract and on_verdict routing. All 7 decision_gate tests pass. * TASK-207: extensible decision keys + conditional on_verdict routing Let an agent or command phase emit a custom (non-builtin) verdict key that the workflow executor routes through the per-phase on_verdict map to any target phase, forward or backward, with the existing loop/attempt guards intact. Built-in advance/rework/skip/fail behavior is unchanged. Carrier: PhaseDecision gains verdict_key (added in animus-protocol v0.7.0-rc.5-dev.decision-keys, re-pinned here). A non-builtin verdict string now parses to verdict = Unknown with the raw key on verdict_key instead of being dropped, in both producers: - agent structured output (payload_traversal::try_parse_decision) - command / persisted decisions (phase_output::read_persisted_decision), which also persists the key verbatim so it round-trips through crash recovery rather than collapsing to unknown. Routing (lifecycle_executor): - new GateEvaluationResult::Route and build_route_effect. On an Unknown verdict carrying a key, resolve_verdict_target / resolve_agent_selected_target look the key up in the phase on_verdict map. A forward jump drives the advance-with-target machine path; a backward or self jump drives the retry path and is counted against the target rework budget. - a custom key with no on_verdict mapping is an explicit failure (clear error naming the key), not a silent advance. - a genuinely empty/absent key preserves the historical tolerant pass. The on_verdict map is both the declaration of valid custom keys and their wiring, so no separate config-protocol contract field was needed. Tests: forward jump, backward jump, unmapped-key failure, and backward-jump rework-budget guard at the executor level; custom-key preservation in the agent parser; and a persisted round-trip for the command path. * TASK-212: re-pin animus-protocol dev tag -> v0.7.0-rc.5 The verdict_key field is now landed on animus-protocol release/0.7 (PR #3) and cut as the real tag v0.7.0-rc.5 (commit 7a5ef89). Re-pin all six animus-protocol git deps across the workspace + the two per-crate manifests (orchestrator-cli, orchestrator-daemon-runtime) from the interim dev tag v0.7.0-rc.5-dev.decision-keys to v0.7.0-rc.5. Lock reconciled to the canonical rc.5 commit; cargo check --workspace --locked clean.
…ugin backend (#302) queue enqueue --task-id / --requirement-id resolved the subject through the legacy file-backed in-tree task store (hub.tasks().get() -> load_task -> local SQLite) before building the dispatch. On a deployment whose subjects live in a subject_backend plugin (e.g. animus-postgres on the portal), that in-tree store is empty, so enqueue returned "task not found: TASK-XXX" for subjects that demonstrably exist and resolve fine through subject get/list/status and the generic --subject-id enqueue path (all of which route through the SubjectRouter plugin). The daemon and workflow run --task-id were unaffected because they already fall back to the plugin resolver; only the enqueue path did a bare in-tree lookup with no fallback. Route the --task-id and --requirement-id existence check through the subject router (RouterSubjectProbe), the same plugin store the rest of the subject surface uses, and build a backend-qualified dispatch. This makes enqueue-by-id consistent with the --subject-id path. The task default workflow_ref now comes from the project's configured default_workflow_ref (matching --subject-id and --title) instead of the tag-derived heuristic, which relied on in-tree task metadata the plugin-backed subject does not carry. Adds unit tests over a stub probe covering the resolved-task and not-found cases. Removes the now-unused hub argument from resolve_enqueue_dispatch.
… conditional on_verdict) + enqueue-by-id store-routing fix Cut from release/0.7 on top of rc.3. Adds: TASK-207/210 extensible custom decision keys and conditional routing (protocol rc.5 verdict_key), and TASK-215 fix routing queue enqueue --task-id/--requirement-id through the subject router instead of the legacy in-tree store. Protocol pinned at v0.7.0-rc.5.
…#303) The Protocol Drift check has failed on every release/0.7 PR since before rc.1. The real cause is not a stale STANDALONE_TAG: on release/0.7 the in-tree animus-plugin-protocol crate and the protocol_drift integration test were deleted when the crate moved to a git dependency (commit 7b8f46a, "drop in-tree copy + protocol_drift test"). ao-cli release/0.7 now consumes animus-plugin-protocol exclusively as a git dependency pinned to a release tag, so there is no second in-tree source of truth to drift against. The workflow still runs cargo test -p orchestrator-plugin-host --test protocol_drift, which errors with "no test target named protocol_drift" and exits 101 before any comparison happens. STANDALONE_TAG v0.1.27 is never even read. Bumping the tag would not change the outcome. Removing the workflow on release/0.7 is the correct fix: with no in-tree mirror, the in-tree-vs-published drift concept no longer applies to this line. The main branch keeps its own copy of the workflow, where the in-tree crate and the protocol_drift test still exist and the check passes against v0.1.27. TASK-120 is a duplicate of this and can be closed once this lands.
The animus.subject.update MCP tool schema advertised a title parameter path but neither the MCP arg builder nor the animus subject update clap command forwarded it, so any caller trying to rename a subject got a clap UnknownArgument error at parse time and title edits could only be done via admin SQL. This adds --title to SubjectUpdateArgs (clap) and maps it into the update patch in handle_subject_update, rejecting an empty title. It also adds a title field to the MCP SubjectUpdateInput and forwards it as --title in build_subject_update_args. The subject router forwards the patch verbatim to the backend, so a backend that accepts a title in its update patch (animus-postgres does) now applies the rename. Docs updated: mcp-tools.md subject.update parameter list and the CLI reference subject update entry. Tests added: a clap parse test that subject update --title lands in SubjectUpdateArgs.title, and an MCP arg-builder test that the title input forwards as --title. Resolves TASK-192.
…305) The CLI standalone queue-client discovered the queue plugin by exact primary plugin_kind equality (find_plugin_for_kind used manifest.plugin_kind == kind). On a consolidated-BaaS deployment the queue role is served by animus-postgres, whose primary kind is subject_backend and which advertises queue as one of its additional plugin_kinds. Exact-match discovery returned None, so every manual CLI/MCP queue op (enqueue, list, stats, hold, release, drop, reorder) failed with no queue plugin installed even though the daemon resolved the same role fine. Switch find_plugin_for_kind and probe_active_plugin_roles to PluginManifest::serves_kind, matching the primary kind OR any additional plugin_kinds. This mirrors how the daemon resolves roles via orchestrator_plugin_host::discover_by_kind, so a multi-role plugin now satisfies the queue (and workflow_runner) role for standalone CLI calls. Adds a unit test that registers a stub plugin whose primary kind is subject_backend but which advertises the queue role, and asserts both find_plugin_for_kind and probe_active_plugin_roles resolve it.
…fixes queue page + manual dispatch on consolidated BaaS) Cut from release/0.7 on top of rc.4. Adds TASK-228: the CLI queue-client now resolves the queue backend by serves_kind (primary OR additional kinds) like the daemon, so animus-postgres (primary subject_backend, additional queue) satisfies it. Fixes all manual queue ops (enqueue/list/stats/hold/release/ drop/reorder), the portal Queue page, and manual run_workflow dispatch.
The kernel OAuth broker caches HTTP-transport MCP bearer/refresh tokens under the per-scope state dir. On an ephemeral host (e.g. a Railway container whose HOME is wiped on redeploy) that cache is lost, forcing a fresh re-auth on every deploy. Add an ANIMUS_MCP_OAUTH_CACHE_DIR override so the cache can live on a mounted persistent volume, surviving redeploys independent of HOME and the per-scope state symlink. Also finalize a dead refresh grant (cached rotation chain AND env-var seed both rejected with invalid_grant) with an explicit re-authentication-required signal, so a connection-state reader can classify needs-reauth versus a transient failure that stays retryable. Tests cover the override path, the reauth signal on a dead grant, and the absence of that signal on a transient 5xx.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
VERDICT: CHANGES REQUESTED
README.md:86(alsodocs/getting-started/installation.md:31anddocs/guides/deployment.md:18) — the executable install examples now sayANIMUS_VERSION=v0.7.0-rc.30, but the PR body says thev0.7.0-rc.30release tag will only be created after this PR merges, so those commands currently resolve to a nonexistent release andscripts/install.shexits withDownload failed. REQUIRED CHANGE: keep executable install/deployment examples pinned to the latest release that already has downloadable assets (currentlyv0.6.33) in this PR, then update them in a post-release docs change afterv0.7.0-rc.30and its assets exist; alternatively, change the examples to use the installer's unpinned latest-release path instead of naming an unpublished tag. Verify withcurl -fsS https://api.github.com/repos/launchapp-dev/animus-cli/releases/tags/v0.7.0-rc.30(expected HTTP 200 before any docs instruct users to pin it) andANIMUS_VERSION=v0.7.0-rc.30 scripts/install.shon macOS (expected archive download and successful install).
The release consolidation is otherwise well documented: the protocol pin is coherent across the workspace, the nine-crate inventory matches Cargo.toml, and the current rustfmt, cargo-check, docs-sync, clippy, and Rust-only guardrail jobs shown so far are passing. I also cannot authorize merge while the PR aggregate remains red: the Vercel deployment status is failing and the remaining synchronized CI jobs have not all completed.
There was a problem hiding this comment.
VERDICT: CHANGES REQUESTED
README.md:86(alsodocs/getting-started/installation.md:31anddocs/guides/deployment.md:18) — the current head still publishes executable examples pinned toANIMUS_VERSION=v0.7.0-rc.30/ARG ANIMUS_VERSION=v0.7.0-rc.30, while the release contract says that tag will only be created after merge; the GitHub Releases API currently returns HTTP 404 for that tag, so these commands fail before installation. REQUIRED CHANGE: keep every executable installer and deployment example pinned to an already-published release with downloadable assets (currentlyv0.6.33), or use the installer's unpinned latest-release path; update the examples tov0.7.0-rc.30only after that tag and its assets exist. Verify withcurl -fsS https://api.github.com/repos/launchapp-dev/animus-cli/releases/tags/v0.7.0-rc.30(expected HTTP 200 before any example pins it), then runANIMUS_VERSION=v0.7.0-rc.30 scripts/install.shand build the deployment Dockerfile (expected archive downloads and successful installs).
The synchronized commit cleanly repairs the CLI-reference Markdown code spans, and the completed rustfmt, cargo-check, docs-sync, clippy, and Vercel checks are green. The remaining checks are still pending, so this head is not mergeable yet even after the documentation blocker is resolved.
Summary
v0.7.0-rc.12and bump the CLI tov0.7.0-rc.30Release contract
0.7.0-rc.30v0.7.0-rc.12atad39f6aba986a2ccd0adcd26c829f6c8ff0e956cv0.2.2Verification
cargo fmt --all -- --checkcargo check --workspace --all-targets --locked --offlinecargo clippy --workspace --all-targets --locked --offline -- -D warningscargo test --workspace --locked --offline(passes with loopback access; sandbox-only OAuth callback binds were separately identified)Tracks TASK-970, TASK-971, TASK-998, TASK-1000, TASK-1001, and TASK-1014.