Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "StateDiffDefaultMount",
"image": "debian:bookworm-slim",
"workspaceFolder": "/workspace",
"containerEnv": { "DM_ENV": "yes" }
}
17 changes: 13 additions & 4 deletions conformance/migration/mapping.json
Original file line number Diff line number Diff line change
Expand Up @@ -1116,17 +1116,26 @@
{
"unit": "parity_state_diff::compose-parity-with-feature-mount-gap",
"disposition": "residual",
"residualId": "res-state-diff-cross-cli-snapshot"
"residualId": "res-state-diff-compose-command-override"
},
{
"unit": "parity_state_diff::compose-sidecar-and-named-volume",
"disposition": "residual",
"residualId": "res-state-diff-cross-cli-snapshot"
"residualId": "res-state-diff-compose-command-override"
},
{
"unit": "parity_state_diff::default-workspace-mount-target-parity",
"disposition": "residual",
"residualId": "res-state-diff-cross-cli-snapshot"
"disposition": "migrated",
"caseIds": [
"case-state-default-mount",
"case-state-default-mount-target"
],
"fixtureMapping": [
{
"from": "inline:state_diff_default_workspace_mount_target_parity",
"to": "conformance/fixtures/fx-state-default-mount"
}
]
},
{
"unit": "parity_state_diff::dockerfile-build-and-nonroot-user",
Expand Down
10 changes: 10 additions & 0 deletions conformance/registry/behaviors/observable-state.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@
"decision": "follow-spec",
"notes": "Backed by case-observable-state (parity_observable_state)."
},
{
"id": "bhv-state-default-workspace-mount-target",
"area": "observable-state",
"statement": "With `workspaceFolder` set and no explicit `workspaceMount`, the workspace is bound at the spec default `/workspaces/<basename>` — never at `workspaceFolder`, which is the working directory rather than a mount target.",
"applicability": [],
"spec": "conformant",
"reference": "aligned",
"decision": "follow-spec",
"notes": "deacon mounted the workspace at `workspaceFolder` until #273 aligned it. This is an ABSOLUTE claim about each side, not an agreement claim: a live differential would pass if deacon and the reference regressed together, which is why it is evidenced by the spec-expectation case case-state-default-mount-target while its differential twin case-state-default-mount carries the agreement half. Both sides were measured at the pinned oracle 0.87.0. Asserted through the observer's DERIVED `workspaceBindTargets` field, so no quantified assertion predicate was needed."
},
{
"id": "bhv-state-diff-parity",
"area": "observable-state",
Expand Down
133 changes: 133 additions & 0 deletions conformance/registry/cases.json
Original file line number Diff line number Diff line change
Expand Up @@ -1881,6 +1881,139 @@
},
"notes": "Migrated from parity_state_diff::appport-published-ports (024 Phase 5). `appPort: [3000]` publishes the same container port in both CLIs. This case was unmigratable before 024 Phase 3: with a FIXED host port both sides collided, because deacon's container was still running while the oracle's `up` ran. The side sequencing fix (capture deacon's evidence, reclaim, then run the oracle) is what makes a fixed-host-port differential expressible at all. Image pinned to debian:bookworm-slim (V18)."
},
{
"id": "case-state-default-mount",
"behaviors": [
"bhv-container-identity-labels",
"bhv-container-keepalive-command",
"bhv-container-metadata-label-authored",
"bhv-state-diff-parity"
],
"context": [],
"oracleType": "live-differential",
"resourceGroup": "docker-shared",
"operations": [
{
"id": "op-up",
"subcommand": "up",
"argv": [
"--workspace-folder",
"${WORKSPACE}"
],
"fixtures": [
"fx-state-default-mount"
]
}
],
"expected": [
{
"channel": "chan-container-state",
"operation": "op-up"
}
],
"allowedDifferences": [
{
"behavior": "bhv-container-identity-labels",
"context": [],
"observablePath": "chan-container-state.labels.devcontainer.configHash",
"rationale": "deacon sets `devcontainer.configHash`; the reference sets no such label (measured against the pinned oracle 0.87.0). One named key, never the `devcontainer.*` namespace.",
"divergenceId": "ext-container-identity-labels"
},
{
"behavior": "bhv-container-identity-labels",
"context": [],
"observablePath": "chan-container-state.labels.devcontainer.config_name",
"rationale": "deacon sets `devcontainer.config_name`; the reference sets no such label (measured against the pinned oracle 0.87.0). One named key, never the `devcontainer.*` namespace.",
"divergenceId": "ext-container-identity-labels"
},
{
"behavior": "bhv-container-identity-labels",
"context": [],
"observablePath": "chan-container-state.labels.devcontainer.name",
"rationale": "deacon sets `devcontainer.name`; the reference sets no such label (measured against the pinned oracle 0.87.0). One named key, never the `devcontainer.*` namespace.",
"divergenceId": "ext-container-identity-labels"
},
{
"behavior": "bhv-container-identity-labels",
"context": [],
"observablePath": "chan-container-state.labels.devcontainer.source",
"rationale": "deacon sets `devcontainer.source`; the reference sets no such label (measured against the pinned oracle 0.87.0). One named key, never the `devcontainer.*` namespace.",
"divergenceId": "ext-container-identity-labels"
},
{
"behavior": "bhv-container-identity-labels",
"context": [],
"observablePath": "chan-container-state.labels.devcontainer.workspaceHash",
"rationale": "deacon sets `devcontainer.workspaceHash`; the reference sets no such label (measured against the pinned oracle 0.87.0). One named key, never the `devcontainer.*` namespace.",
"divergenceId": "ext-container-identity-labels"
},
{
"behavior": "bhv-container-keepalive-command",
"context": [],
"observablePath": "chan-container-state.cmd",
"rationale": "The keep-alive command strings differ; the observable behavior is measured equal (`docker stop` 245 ms / exit 0 vs 215 ms / exit 0). Scoped to `cmd`; `entrypoint` and every other field stay compared.",
"divergenceId": "bhv-container-keepalive-command"
}
],
"cleanup": {
"containers": true,
"images": false,
"networks": true,
"volumes": true,
"tempdir": true
},
"notes": "Migrated from parity_state_diff::default-workspace-mount-target-parity (024 Phase 5b). A config with `workspaceFolder` but NO explicit `workspaceMount`: both CLIs must produce equivalent container state, including where the workspace is bound. The legacy unit wrote NO report fragment at all (its `assert_parity` call was absent), so migrating it is a coverage GAIN, not a transfer. Its `∄ /workspace ∧ ∃ /workspaces/*` claim is an ABSOLUTE claim about each side, which a differential cannot express — that half lives in the spec-expectation twin `case-state-default-mount-target` (the T072 pattern). Image pinned to debian:bookworm-slim (V18)."
},
{
"id": "case-state-default-mount-target",
"behaviors": [
"bhv-state-default-workspace-mount-target"
],
"context": [],
"oracleType": "spec-expectation",
"resourceGroup": "docker-shared",
"operations": [
{
"id": "op-up",
"subcommand": "up",
"argv": [
"--workspace-folder",
"${WORKSPACE}"
],
"fixtures": [
"fx-state-default-mount"
]
}
],
"expected": [
{
"channel": "chan-exit-code",
"operation": "op-up",
"assertion": {
"equals": 0
}
},
{
"channel": "chan-container-state",
"operation": "op-up",
"assertion": {
"jsonSubset": {
"workspaceBindTargets": [
"/workspaces/<WORKSPACE_NAME>"
]
}
}
}
],
"cleanup": {
"containers": true,
"images": false,
"networks": true,
"volumes": true,
"tempdir": true
},
"notes": "The spec-expectation twin of case-state-default-mount (024 Phase 5b), carrying the half a differential structurally cannot: the legacy unit asserted an ABSOLUTE fact about each side — NEITHER CLI mounts the workspace at `workspaceFolder` (/workspace), BOTH mount it at the spec default /workspaces/<basename> (#273) — and a differential would pass if both regressed together. `workspaceBindTargets` is the observer's DERIVED field (the destinations of binds rooted at the workspace), so the quantified `∄ ∧ ∃` claim becomes plain equality with no new assertion predicate: a single-element list at the spec default is exactly '∃ the right one and ∄ any other', including /workspace. `<WORKSPACE_NAME>` is the `workspace_basename_token` rewrite. Image pinned to debian:bookworm-slim (V18)."
},
{
"id": "case-state-diff",
"behaviors": [
Expand Down
26 changes: 13 additions & 13 deletions conformance/registry/residuals.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"parity_exec::env-propagation"
],
"blockedCarrier": "parity_exec",
"missingCapability": "a declarative case for `parity_exec::env-propagation`. NOTE: the previously recorded need for per-side argument vectors was DISPROVEN in 024 planning \u2014 deacon's `exec` declares `--remote-env` as the primary flag with `--env` as a legacy alias, so the single shared argv `--remote-env FOO=BAR` runs on both CLIs and no runner capability is missing. Only the case itself is outstanding.",
"missingCapability": "a declarative case for `parity_exec::env-propagation`. NOTE: the previously recorded need for per-side argument vectors was DISPROVEN in 024 planning deacon's `exec` declares `--remote-env` as the primary flag with `--env` as a legacy alias, so the single shared argv `--remote-env FOO=BAR` runs on both CLIs and no runner capability is missing. Only the case itself is outstanding.",
"followUp": "specs/024-drain-parity-residuals/tasks.md#P6",
"behaviors": [
"bhv-exec-command-parity"
Expand Down Expand Up @@ -86,7 +86,7 @@
"parity_harness_faults::q_stale_snapshot_is_reported_naming_the_drifted_field"
],
"blockedCarrier": "parity_harness_faults",
"missingCapability": "fault injection against the harness itself: these units assert how the COMPARISON MACHINERY reports a missing oracle, a version mismatch, a crash, a timeout, a malformed output, a waived difference, a stale waiver, each difference class (ref-only / deacon-only / value / accept-vs-reject with direction) and each declarative outcome (allowed-difference / no-reference-for-platform / stale) \u2014 they observe the harness, not a devcontainer, so they have no observable channel and no oracle to compare against",
"missingCapability": "fault injection against the harness itself: these units assert how the COMPARISON MACHINERY reports a missing oracle, a version mismatch, a crash, a timeout, a malformed output, a waived difference, a stale waiver, each difference class (ref-only / deacon-only / value / accept-vs-reject with direction) and each declarative outcome (allowed-difference / no-reference-for-platform / stale) they observe the harness, not a devcontainer, so they have no observable channel and no oracle to compare against",
"disposition": "permanent",
"outOfScopeRationale": "These units observe the COMPARISON MACHINERY, not a devcontainer: they assert how the harness reports a missing oracle, a crash, a timeout, a stale waiver and each difference class. A declarative case compares deacon to a reference across an observable channel, so a self-test of the comparator has no oracle and no observable channel to name. Out of scope structurally, not pending a feature.",
"behaviors": []
Expand All @@ -102,9 +102,9 @@
"parity_registry_check::waivers_live_in_conformance_registry_not_legacy_locations"
],
"blockedCarrier": "parity_registry_check",
"missingCapability": "structural self-checks of the repository's own test wiring: these units assert registry-to-test-file agreement, nextest profile selection, corpus minimums and the no-silent-skip idiom scan \u2014 repository structure, not consumer behavior, so no declarative case can express them",
"missingCapability": "structural self-checks of the repository's own test wiring: these units assert registry-to-test-file agreement, nextest profile selection, corpus minimums and the no-silent-skip idiom scan repository structure, not consumer behavior, so no declarative case can express them",
"disposition": "permanent",
"outOfScopeRationale": "These units assert repository structure \u2014 registry-to-test-file agreement, nextest profile selection, corpus minimums, the no-silent-skip idiom scan. That is a property of the repository, not consumer behavior against the spec, so no observable channel and no reference exist. Out of scope structurally, not pending a feature.",
"outOfScopeRationale": "These units assert repository structure registry-to-test-file agreement, nextest profile selection, corpus minimums, the no-silent-skip idiom scan. That is a property of the repository, not consumer behavior against the spec, so no observable channel and no reference exist. Out of scope structurally, not pending a feature.",
"behaviors": []
},
{
Expand All @@ -127,7 +127,7 @@
"blockedCarrier": "parity_observable_state",
"missingCapability": "reference-CLI feature-authoring interop: the unit feeds a deacon-generated lockfile to the reference's `features resolve-dependencies`, and the declarative operation surface is deliberately restricted to the consumer subcommands (Principle II)",
"disposition": "permanent",
"outOfScopeRationale": "Constitution II: feature authoring is permanently out of scope for deacon, and this unit needs deacon `upgrade` plus the reference's `features resolve-dependencies` \u2014 both outside the consumer subcommand surface a declarative operation may name. The principle forbids it, so no capability will ever unblock it.",
"outOfScopeRationale": "Constitution II: feature authoring is permanently out of scope for deacon, and this unit needs deacon `upgrade` plus the reference's `features resolve-dependencies` both outside the consumer subcommand surface a declarative operation may name. The principle forbids it, so no capability will ever unblock it.",
"behaviors": [
"bhv-state-container-parity"
]
Expand Down Expand Up @@ -198,19 +198,18 @@
],
"missingCapability": "vendored fixtures for the pinned third-party workspaces: the manifest fetches 33 public workspace snapshots over the network on demand, and vendoring third-party content into this repository is deliberately out of scope, so no case can materialize them",
"disposition": "permanent",
"outOfScopeRationale": "Vendoring third-party content into this repository is out of scope by decision (research D8): the manifest names 33 public workspace snapshots fetched over the network on demand, and a declarative fixture must be committed, content-hashed input. These entries are inventoried as a recorded coverage SOURCE, never executed, so there is no capability to add \u2014 only a decision already taken.",
"outOfScopeRationale": "Vendoring third-party content into this repository is out of scope by decision (research D8): the manifest names 33 public workspace snapshots fetched over the network on demand, and a declarative fixture must be committed, content-hashed input. These entries are inventoried as a recorded coverage SOURCE, never executed, so there is no capability to add only a decision already taken.",
"behaviors": []
},
{
"id": "res-state-diff-cross-cli-snapshot",
"id": "res-state-diff-compose-command-override",
"units": [
"parity_state_diff::compose-parity-with-feature-mount-gap",
"parity_state_diff::compose-sidecar-and-named-volume",
"parity_state_diff::default-workspace-mount-target-parity"
"parity_state_diff::compose-sidecar-and-named-volume"
],
"blockedCarrier": "parity_state_diff",
"missingCapability": "cross-CLI container-state snapshot comparison: a normalized whole-container state snapshot taken on both sides and diffed field-by-field, which the per-channel `chan-container-state` observer does not provide",
"followUp": "specs/023-migrate-parity-to-conformance/tasks.md#T103",
"missingCapability": "not a missing capability — a deacon DEFECT the replacement cases would surface as an uncharacterized `stricter` verdict: on the compose path deacon replaces the service's declared `command` with its keep-alive instead of honoring `overrideCommand`'s compose default of false, so the compose service's own process never runs. Measured against pinned oracle 0.87.0: a service whose command touches a marker file and then sleeps creates that marker under the reference and not under deacon. The cases are held back until deacon is fixed, rather than migrated with a tolerance that would characterize a spec violation as intentional",
"followUp": "specs/023-migrate-parity-to-conformance/tasks.md#T117",
"behaviors": [
"bhv-state-diff-parity",
"bhv-state-container-parity"
Expand All @@ -223,10 +222,11 @@
],
"blockedCarrier": "parity_state_diff",
"missingCapability": "a reference-free comparison mode that diffs two DEACON runs against each other (single-container versus compose for the same logical configuration), with no reference side involved",
"followUp": "specs/023-migrate-parity-to-conformance/tasks.md#T103",
"behaviors": [
"bhv-state-diff-parity"
]
],
"disposition": "queued",
"followUp": "specs/023-migrate-parity-to-conformance/tasks.md#T103"
}
]
}
10 changes: 10 additions & 0 deletions conformance/registry/sources/spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@
"bhv-state-diff-parity"
]
},
{
"id": "src-spec-default-workspace-mount",
"inventory": "spec",
"revision": "rev-spec-113500f4",
"locator": "devcontainerjson-reference.md workspaceFolder / workspaceMount",
"summary": "`workspaceFolder` sets the path to open inside the container; `workspaceMount` overrides the default workspace mount. With no `workspaceMount` the default source-to-`/workspaces/<basename>` bind applies, so `workspaceFolder` is a working directory, not a mount target.",
"behaviors": [
"bhv-state-default-workspace-mount-target"
]
},
{
"id": "src-spec-exec-command",
"inventory": "spec",
Expand Down
Loading
Loading