Context
PR #15765 (merged 2026-07-23T19:46Z, resolves #15762) added response-side identity verification to the Docker-socket holder: after the label-filtered lookup, assertTargetIdentity requires the returned container to prove the requested (composeProject, composeService) pair, else a bounded compose-project-mismatch / compose-service-mismatch error aborts before inspect/logs/stats/restart. The cycle-1 review (4767442988, Depth Floor finding 1) identified a guard slip in that new verification layer; this ticket converts the watch-item into tracked work. Priority context: cloud-deployment stability is the current prio-zero goal, and bounded runtime-access diagnostics are exactly what deployment troubleshooting routes on.
The Problem
assertTargetIdentity normalizes malformed responses via:
const labels = container && typeof container.Labels === 'object'
? container.Labels
: {};typeof null === 'object', so a response carrying Labels: null selects null and the next property read throws a raw TypeError instead of the bounded error. The failure remains fail-closed — the exception still aborts the operation and no privileged call proceeds — but it degrades the bounded-diagnostics contract: snapshot.bridgeDiagnostics and the Troubleshooting guide's reason ladder route operators by reason strings, and this exact malformed-response class (the one the assert exists to catch) surfaces as an unclassified crash instead of compose-project-mismatch. Reachability is edge-only: an honest Docker response to a label-filtered query carries populated Labels; the assert's entire purpose is dishonest/malformed responses, and it currently mishandles one shape of them.
Sibling cosmetic nit from the same review (optional, same file): resolveComposeProject() trims the configured value for query and verification, while createEffectiveConfigSummary() diagnostics echo the raw untrimmed string.
The Architectural Reality
ai/daemons/orchestrator/services/DeploymentRuntimeAccessService.mjs — assertTargetIdentity (on dev since PR #15765).
- Bounded-reason consumers:
DeploymentStateBridgeService snapshot diagnostics; learn/agentos/cloud-deployment/Troubleshooting.md reason ladder (which now documents compose-project-mismatch / compose-service-mismatch as the holder's rejection contract).
- The redaction property (mismatch details never echo the foreign label value, enforced by
createLookupDetails) must be preserved — and per the review, deserves a line in the method JSDoc.
The Fix
- Precise normalization, e.g.
const labels = container && typeof container.Labels === 'object' && container.Labels !== null ? container.Labels : {};
- Add a malformed-response fixture: a label-filter-matched container with
Labels: null (and one with Labels absent) must yield the bounded compose-project-mismatch error — for BOTH readObserve and applyLifecycle — with exactly one socket call and no raw TypeError.
- State the bounded-error + redaction contract in the
assertTargetIdentity JSDoc.
- Optional: align the trim asymmetry (or document it as intentional).
Acceptance Criteria
Out of Scope
- Any change to the mandatory-project semantics, the operation allowlists, or the error-reason taxonomy beyond routing this malformed class into the existing reasons.
Related
- #15762 / PR #15765 — the parent verification layer this hardens; review anchor 4767442988 (Depth Floor finding 1).
- ADR 0026 — aligned-with (bounded constrained-actuator diagnostics discipline).
Decision Record impact: aligned-with ADR 0026; no ADR change.
Release classification: not release-blocking (edge-hardening on an already fail-closed path; boardless).
Live latest-open sweep: checked latest 20 open issues at 2026-07-23T19:47:02Z; no equivalent found. A2A claim sweep (all-status, last 30): no overlapping [lane-claim]/[lane-intent].
Origin Session ID: 9af3c9a5-efc2-4716-bb5c-19289e22ddcc
Retrieval Hint: assertTargetIdentity null Labels typeof object bounded mismatch TypeError
Context
PR #15765 (merged 2026-07-23T19:46Z, resolves #15762) added response-side identity verification to the Docker-socket holder: after the label-filtered lookup,
assertTargetIdentityrequires the returned container to prove the requested(composeProject, composeService)pair, else a boundedcompose-project-mismatch/compose-service-mismatcherror aborts before inspect/logs/stats/restart. The cycle-1 review (4767442988, Depth Floor finding 1) identified a guard slip in that new verification layer; this ticket converts the watch-item into tracked work. Priority context: cloud-deployment stability is the current prio-zero goal, and bounded runtime-access diagnostics are exactly what deployment troubleshooting routes on.The Problem
assertTargetIdentitynormalizes malformed responses via:const labels = container && typeof container.Labels === 'object' ? container.Labels : {};typeof null === 'object', so a response carryingLabels: nullselectsnulland the next property read throws a rawTypeErrorinstead of the bounded error. The failure remains fail-closed — the exception still aborts the operation and no privileged call proceeds — but it degrades the bounded-diagnostics contract:snapshot.bridgeDiagnosticsand the Troubleshooting guide's reason ladder route operators byreasonstrings, and this exact malformed-response class (the one the assert exists to catch) surfaces as an unclassified crash instead ofcompose-project-mismatch. Reachability is edge-only: an honest Docker response to a label-filtered query carries populatedLabels; the assert's entire purpose is dishonest/malformed responses, and it currently mishandles one shape of them.Sibling cosmetic nit from the same review (optional, same file):
resolveComposeProject()trims the configured value for query and verification, whilecreateEffectiveConfigSummary()diagnostics echo the raw untrimmed string.The Architectural Reality
ai/daemons/orchestrator/services/DeploymentRuntimeAccessService.mjs—assertTargetIdentity(ondevsince PR #15765).DeploymentStateBridgeServicesnapshot diagnostics;learn/agentos/cloud-deployment/Troubleshooting.mdreason ladder (which now documentscompose-project-mismatch/compose-service-mismatchas the holder's rejection contract).createLookupDetails) must be preserved — and per the review, deserves a line in the method JSDoc.The Fix
const labels = container && typeof container.Labels === 'object' && container.Labels !== null ? container.Labels : {};Labels: null(and one withLabelsabsent) must yield the boundedcompose-project-mismatcherror — for BOTHreadObserveandapplyLifecycle— with exactly one socket call and no rawTypeError.assertTargetIdentityJSDoc.Acceptance Criteria
Labels: nullandLabels-absent fixtures yield the boundedcompose-project-mismatcherror on both read and lifecycle paths; no rawTypeErrorescapes the holder.assertTargetIdentityJSDoc states the bounded-error contract, including that mismatch details never echo the foreign label value.Out of Scope
Related
Decision Record impact: aligned-with ADR 0026; no ADR change.
Release classification: not release-blocking (edge-hardening on an already fail-closed path; boardless).
Live latest-open sweep: checked latest 20 open issues at 2026-07-23T19:47:02Z; no equivalent found. A2A claim sweep (all-status, last 30): no overlapping
[lane-claim]/[lane-intent].Origin Session ID: 9af3c9a5-efc2-4716-bb5c-19289e22ddcc
Retrieval Hint:
assertTargetIdentity null Labels typeof object bounded mismatch TypeError