feat(autonomy): duration-ceiling watch leg, digest job, settled HostServicesOnly (P4) - #305
Merged
Merged
Conversation
…led HostServicesOnly The final phase of the post-merge plan - three small closures. Watch window (R5.2): WatchThresholds.MaxInvocationDuration is an ABSOLUTE per-invocation wall-clock ceiling, judged like the contract leg - no baseline, no minimum invocation count - because a first-generation deploy has no baseline for the relative legs and a pathological single invocation must not hide inside a healthy mean. Wall clock is the one per-invocation resource honestly measurable in a shared host process; per-brick memory or CPU attribution is not, and the doc says so instead of pretending. Configured via Nexo:Autonomy:WatchMaxInvocationSeconds (0 = off). Digest (spec 7): AddNexoAutonomyDigestJob retains swap provenance in a bounded ring (RecordingBrickSwapProvenanceSink - still logs every event, so R2.1 holds) and renders the human digest on cadence (DigestIntervalSeconds, 0 disables). The sink takeover is order-independent with AddNexoAutonomy, and a saturated ring names what fell off rather than presenting a truncated history as complete. Single-op controls stay on the authority services - a rendering job is not a control surface. HostServicesOnly: the fail-closed refusal is now documented as the settled posture, not a v1 gap. The one workload that seemed to need the mode - in-session package restore - was solved offline in P3, and a model server belongs on the proposer side of the boundary. The enum member stays for a backend that can genuinely realize per-session egress; none is planned. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
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 freeto 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
Phase 4, the final phase of the post-merge plan: three closures that finish what the honest assessment opened. Stacked on #304.
1. Absolute duration ceiling on the watch window
WatchThresholds.MaxInvocationDuration— an absolute per-invocation wall-clock ceiling, judged like the contract-conformance leg: no baseline, no minimum invocation count. The relative legs (error-rate delta, latency factor) judge against the previous generation's baseline, which means a first-generation deploy escapes them entirely, and a pathological single invocation can hide inside a healthy mean until enough samples accumulate. The absolute leg closes both holes.Scope honesty, stated in the docs: wall clock is the one per-invocation resource genuinely measurable in a shared host process. Per-brick memory/CPU attribution is not, and a fake ceiling would be worse than none. Configured via
Nexo:Autonomy:WatchMaxInvocationSeconds(0 = off, the default — additive, no behavior change unconfigured).2. The digest becomes a host job
AddNexoAutonomyDigestJob— swap provenance retained in a bounded ring (RecordingBrickSwapProvenanceSink, which still logs every event, so R2.1's no-unlogged-path holds) and rendered as the §7 human digest on cadence (DigestIntervalSeconds, default hourly, 0 disables).AddNexoAutonomyand this, the retaining sink serves — a theory pins both orders, because the failure mode (digest renders an empty history while the loop swaps away) would be silent.3.
HostServicesOnlyis settled, not pendingThe fail-closed refusal in the Docker backends is now documented as the permanent posture. The one workload that ever seemed to need the mode — package restore during the in-session build — was solved without network in P3 (offline restore from SDK packs, cleared sources). A model server, the other imagined consumer, belongs on the proposer side of the boundary, not inside a certification session. The enum member stays declared for a backend that can genuinely realize per-session egress rules; none is planned. Recorded under "Settled decisions" in the evidence doc.
Testing
GenerationWatchWindowTests(+SlowInvocation_BreachesTheAbsoluteDurationCeiling_WithoutNeedingABaseline),AutonomyDigestJobTests(new: bounded ring, saturation note, both composition orders, interval-0 quiet decline),AutonomyCompositionTests(+2 validator rows),AutonomousIterationHarnessTests(unchanged, regression guard)make kernel-coverage-gate— runs in CI (Infrastructure paths touched)🤖 Generated with Claude Code