-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Merge train round 3 B6: direct MCP calls in code mode, attested live startup health (#5925 #5977) #6069
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merge train round 3 B6: direct MCP calls in code mode, attested live startup health (#5925 #5977) #6069
Changes from all commits
28906a3
bee2ea4
2a383cb
f2727be
6341da9
58395b5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # B6 — direct MCP calls in code mode, attested live startup health | ||
|
|
||
| Base: `dev` `7d8459388c` (after B5 #6066). Branch `codex/train3-b6`. | ||
|
|
||
| Previous D (B5): #5953 and #6027 landed with their review fixes; #5180 and the #4055 docs landed. Direction kept. | ||
|
|
||
| | Item | Plan | Review | | ||
| |---|---|---| | ||
| | #5925 (mdwsk88) | Carry head `06fa8855b` as is. A routed provider's undeclared `mcp__<server>__<tool>` call is folded into the client's declared custom `exec` code-mode tool instead of failing the turn with a 502. | Kimi review LAND; dedicated security review of the undeclared-tool admission: BLOCKER no (recovery needs a client-declared custom `exec` and an actual routed conversion; arguments stay JSON data; explicit and namespaced declarations win). | | ||
| | #5977 (RHODIZSECURITY) | Carry, then close the hold that kept it out of round 2: the server signs a local-read response with `LOCAL_ATTESTATION_PROOF_HEADER` over the request nonce, `fetchBoundLocalManagementRead` verifies it when a caller opts in, and `ocx status` opts in, so a listener that took the port cannot supply a `protected` startup verdict. | Kimi review: the bug is real on dev; the fix reuses the attestation already used by `/healthz` and system restart. | | ||
|
|
||
| Held from this round's reviews, with reasons, for the outcome ledger: #4177 (no loop exists on dev; the rest is a | ||
| feature), #4732 (perf rework against `snapshot-select.ts` and measurements needed from the author), #5539 (reverses | ||
| test-locked behavior without a reproduction), #4961 (issue withholds a design), #4143 (needs the reporter's desktop | ||
| routing details). | ||
|
|
||
| ## Build and evidence | ||
|
|
||
| | Commit | What | | ||
| |---|---| | ||
| | `bee2ea4357` | #5925 carried (four commits squashed, author kept) | | ||
| | `2a383cbc1f` | its layout entry moved onto a shared line (layout.json stays at 1993 lines) | | ||
| | `f2727befa8` | #5977 carried; the author's noreply identity replaces the placeholder address on the commit | | ||
| | `6341da9847` | #5977 response proof: the server signs local-read responses over the request nonce, the client verifies when asked, `ocx status` asks. New `tests/server/local-read-response-proof.test.ts` and a negative client test; both fail without the change | | ||
|
|
||
| Security: #5925 dedicated review BLOCKER no. #5977's remaining hold is closed by `6341da9847`, which reuses the | ||
| attestation that `/healthz` and system restart already use. | ||
|
|
||
| Aside: #5925 shows no open review; #5977 shows two approvals from before the response-proof commit. | ||
|
|
||
| Local proof at `6341da9847`: typecheck, structure and privacy exit 0; the seven local-read and status files plus the | ||
| three #5925 files 122 pass. Directory runs: `tests/adapters` 2371 pass, 107 fail on this branch and 2369 pass, 107 fail | ||
| on `dev` `7d8459388c` (same Anthropic cooldown and pool files, which pass alone), so the failures are pre-existing | ||
| directory-run interference; `tests/responses` shows the 13 known `responses-compaction-recovery` failures. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,8 @@ import { tokenCollidesWithAdmin } from "../lib/admin-secrets"; | |
| export { proxyHealthFailureReason, isConnectionRefused, isUncleanExitEvidence, probeUncleanExitState } from "./status-probes"; | ||
| export type { ListenTarget } from "./status-probes"; | ||
| import { checkProxyHealth, probeUncleanExitState, type ListenTarget } from "./status-probes"; | ||
| import { LOCAL_MANAGEMENT_READ_PATHS } from "../lib/local-management-capability"; | ||
| import { fetchBoundLocalManagementRead } from "../server/local-management-read-client"; | ||
|
|
||
| /** | ||
| * The state of the data-plane admission secret the SERVICE will use. State only -- never the value. | ||
|
|
@@ -235,6 +237,84 @@ function statusDashboardUrl(config: StatusListenConfig, hostname: string | undef | |
| return `http://${dashboardHostname}:${port}/`; | ||
| } | ||
|
|
||
| const STARTUP_HEALTH_BOOLEAN_FIELDS = [ | ||
| "routingInjected", "localRoutingDependency", "autostartEnabled", "rebootSafe", | ||
| "serviceInstalled", "serviceViable", "serviceEnabled", "serviceRunning", | ||
| "serviceStale", "serviceConflict", "shimInstalled", "shimHealthy", | ||
| "serviceSupported", "diagnosticStale", | ||
| ] as const; | ||
|
|
||
| export async function fetchLiveStartupHealth( | ||
| live: NonNullable<Awaited<ReturnType<typeof findLiveProxy>>>, | ||
| deps: Parameters<typeof fetchBoundLocalManagementRead>[2] = {}, | ||
| ): Promise<StartupHealth | null> { | ||
| const result = await fetchBoundLocalManagementRead( | ||
| live, LOCAL_MANAGEMENT_READ_PATHS.startupHealth, { timeoutMs: 1_500, ...deps, requireResponseProof: true }, | ||
| ); | ||
| if (result.kind !== "response" || !result.response.ok) return null; | ||
| let payload: unknown; | ||
| try { payload = await result.response.json(); } catch { return null; } | ||
| if (!payload || typeof payload !== "object" || Array.isArray(payload)) return null; | ||
| const row = payload as Record<string, unknown>; | ||
| if (row.status !== "native" && row.status !== "protected" && row.status !== "at-risk") return null; | ||
| if (row.protection !== "service" && row.protection !== "shim" && row.protection !== "none") return null; | ||
| if (row.routingKind !== "native" && row.routingKind !== "opencodex-local" | ||
| && row.routingKind !== "custom-local" && row.routingKind !== "custom-remote" && row.routingKind !== "unknown") return null; | ||
| if (row.shimCoverage !== "full" && row.shimCoverage !== "cli-only" && row.shimCoverage !== "none") return null; | ||
| if (typeof row.platform !== "string") return null; | ||
| if (row.recommendedCommand !== null && typeof row.recommendedCommand !== "string") return null; | ||
| if (!row.commands || typeof row.commands !== "object" || Array.isArray(row.commands)) return null; | ||
| for (const key of ["installService", "repairService", "installShim", "restoreNative"] as const) { | ||
| if (typeof (row.commands as Record<string, unknown>)[key] !== "string") return null; | ||
| } | ||
| if (row.routingAdoption !== undefined) { | ||
| if (!row.routingAdoption || typeof row.routingAdoption !== "object" || Array.isArray(row.routingAdoption)) return null; | ||
| const adoption = row.routingAdoption as Record<string, unknown>; | ||
| if (adoption.adoption !== "not-applicable" && adoption.adoption !== "adopted" | ||
| && adoption.adoption !== "pending-client-restart" && adoption.adoption !== "unknown") return null; | ||
| if (adoption.injectedAtMs !== null && typeof adoption.injectedAtMs !== "number") return null; | ||
| if (typeof adoption.observedClients !== "number" || !Array.isArray(adoption.staleClients)) return null; | ||
| for (const client of adoption.staleClients) { | ||
| if (!client || typeof client !== "object" || Array.isArray(client)) return null; | ||
| const row = client as Record<string, unknown>; | ||
| if (typeof row.pid !== "number" || typeof row.startedAtMs !== "number") return null; | ||
| } | ||
| } | ||
| for (const key of STARTUP_HEALTH_BOOLEAN_FIELDS) if (typeof row[key] !== "boolean") return null; | ||
| return payload as StartupHealth; | ||
| } | ||
|
|
||
| /** Prefer an attested live verdict and evaluate the local fallback only when live state is absent. */ | ||
| export function selectStatusStartupHealth( | ||
| liveStartup: StartupHealth | null, | ||
| fallback: () => StartupHealth, | ||
| ): StartupHealth { | ||
| return liveStartup ?? fallback(); | ||
| } | ||
|
|
||
| /** Build the service summary from the same startup source that `ocx status` selected. */ | ||
| export function statusServiceSummary( | ||
| liveStartup: StartupHealth | null, | ||
| service: Pick<ReturnType<typeof diagnoseService>, "installed" | "summary">, | ||
| live: boolean, | ||
| ): string { | ||
| if (liveStartup) { | ||
| if (liveStartup.protection === "service" && liveStartup.serviceViable) { | ||
| return `running under the live managed service (logs: ${serviceLogPath()})`; | ||
|
Comment on lines
+302
to
+303
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Do not claim that the live proxy runs under the service without checking process identity. If a managed service is running on one port and a separately started proxy is live on another, 🤖 Prompt for AI Agents |
||
| } | ||
| const state = [ | ||
| liveStartup.serviceInstalled ? "installed" : "absent", | ||
| liveStartup.serviceRunning ? "running" : "not running", | ||
| liveStartup.serviceViable ? "viable" : "not viable", | ||
| ].join(", "); | ||
| const action = liveStartup.recommendedCommand ? `; run '${liveStartup.recommendedCommand}'` : ""; | ||
| return `live startup reports service ${state}${action} (logs: ${serviceLogPath()})`; | ||
| } | ||
| return service.installed && !live | ||
| ? `${service.summary} — registered but NOT serving; see ${serviceLogPath()} and re-run 'ocx service repair'` | ||
| : service.summary; | ||
| } | ||
|
|
||
| /** | ||
| * The hub block, or null when this machine is not a hub. | ||
| * | ||
|
|
@@ -666,20 +746,19 @@ export async function collectStatus(): Promise<CliStatusView> { | |
| hostname: config.hostname, | ||
| }); | ||
| const bunRuntime = durableBunRuntime(); | ||
| const liveStartup = live ? await fetchLiveStartupHealth(live) : null; | ||
| const service = diagnoseService(); | ||
| // A service can be registered and still not serve: the manager reports the job | ||
| // either way. `live` was already identity-probed a few lines above, so cross-check | ||
| // rather than print registration as if it were service. | ||
| const serviceSummary = service.installed && !live | ||
| ? `${service.summary} — registered but NOT serving; see ${serviceLogPath()} and re-run 'ocx service repair'` | ||
| : service.summary; | ||
| // either way. When the identity-probed live proxy provides an attested startup verdict, | ||
| // prefer it over a shell-local service-manager probe that lacks the service environment. | ||
| const serviceSummary = statusServiceSummary(liveStartup, service, Boolean(live)); | ||
| const codexShim = diagnoseCodexShim(); | ||
| const codexShimSummary = codexShim.summary; | ||
| const startup = collectStartupHealth(config, { | ||
| const startup = selectStatusStartupHealth(liveStartup, () => collectStartupHealth(config, { | ||
| service, | ||
| shim: codexShim, | ||
| routingKind: getCodexRoutingKind(), | ||
| }); | ||
| })); | ||
| const codexPlugins = diagnoseCodexBundledPlugins(); | ||
| const lastClamp = loadLastEffortClamp(); | ||
| const clampActive = effortClampAppliesToRuntime(lastClamp, resolvedRuntime.runtime); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a cold startup-health cache,
/api/startup-healthwaits for the isolated service-manager probe, whose configured bound is 5.5 seconds on Linux/macOS and 15.5 seconds on Windows (src/server/startup-health-cache.ts). Aborting this read after 1.5 seconds therefore makes the firstocx statusorocx doctorfall back to the shell-local diagnostic whenever that probe takes longer than 1.5 seconds—the exact environment-dependent false negative this change is intended to avoid. Use a timeout that covers the endpoint's documented probe budget, or expose a nonblocking attested snapshot and retry after warming.Useful? React with 👍 / 👎.