Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
37ab51f
Observe the answering container's usage-stats env without reading the…
Sep 14, 2026
c034edd
Align first-party standing prose with the inspect reader, and drop a …
Sep 14, 2026
9b91227
Add an enabled-inspect Located control for the jurisdiction-drop popu…
Sep 15, 2026
b3cd4ef
Refuse enabled usage-stats egress; model vLLM disable precedence and …
Sep 15, 2026
df56772
Project an empty jurisdiction-drop population and stop claiming Locat…
Sep 15, 2026
2f8c5f7
Keep the realization-identity wall on the inspect admission path.
Sep 15, 2026
b2892c5
Name VLLM_DO_NOT_TRACK in the inspect-projection obligation.
Sep 15, 2026
31ff5d6
Restore the serving_offer import that binds the unobserved-incarnatio…
Sep 15, 2026
50b01de
Hoist json_string_list into the JSON parse module.
Sep 15, 2026
3544434
Admit the json_string_list TargetChanged on the required namespace wave.
Sep 15, 2026
abb8a52
Refuse usage-stats inspect unless the observation names this realizat…
Sep 15, 2026
0a2ab72
Delete consumed #10729 namespace admissions on this roster touch.
Sep 15, 2026
b032710
Spark usage-stats: policy receives a typed observation; raw inspect s…
Sep 15, 2026
3076736
Merge remote-tracking branch 'origin/main' into session/gentle-bat-838
Sep 15, 2026
979cde4
Merge origin/main into #11441; #11306's consumed admission rows come …
Sep 15, 2026
ff6ff37
Merge origin/main into #11441 (main's roster is empty after gunbc#113…
Sep 15, 2026
0097c8f
Merge origin/main into #11441: neither conflicted import survives (tu…
Sep 16, 2026
743af47
Merge origin/main into #11441; #11177's consumed admission rows come …
Sep 16, 2026
b624ba1
Merge origin/main (#11362 landed) into #11441: both inspect readers k…
Sep 16, 2026
e163be9
cli.dag: close the two readers the three-way merge split
Sep 16, 2026
bdba246
Merge origin/main into #11441 (main retired the #11177 rows itself in…
Sep 16, 2026
e8ab7d2
Merge origin/main into #11441: the admission roster is now a director…
Sep 16, 2026
0e56511
usage-stats observer takes no marker standing, and the harness thread…
Sep 16, 2026
4f77ba9
Merge remote-tracking branch 'origin/main' into me/11441
Sep 16, 2026
062abc7
usage-stats: the positive observation is a sealed evidence record min…
Sep 16, 2026
87a2501
Merge remote-tracking branch 'origin/main' into me/11441
Sep 16, 2026
2edaed6
usage-stats evidence is minted only inside the inspect operation; the…
Sep 16, 2026
22c24ed
seal probe: the census entry is a builtin, like the sibling probes
Sep 16, 2026
687cba7
first_party_serving witness: inspect-unread now lives in the observer…
Sep 16, 2026
30c9cca
Merge origin/main (#11440 landed) into #11441: usage-stats evidence c…
Sep 17, 2026
1a9d294
Retire the four consumed gunbc#11440 admission rows (landed as da6cd0…
Sep 17, 2026
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
172 changes: 171 additions & 1 deletion dag/extdeps/docker/cli.dag
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module extdeps.docker.cli

import v2.std.optional { Present, Absent }
import std.types { String, Bool, List, NonEmptyStr, FilePath, Int }
import std.nat { Nat }
import std.algebra { trim }
Expand All @@ -11,7 +12,7 @@ import extdeps.languages.json.emit { JsonValue, JsonNull, JsonBool, JsonNumber,
import extdeps.languages.json.parse {
parse_json_document, JsonDocumentParsed, JsonDocumentUnreadable, json_document_gap_text,
json_object_unique_member, JsonMemberFound, JsonMemberAbsent, JsonMemberDuplicated, JsonMemberNotAnObject,
json_string_value_or_empty,
json_string_value_or_empty, json_string_list,
}

data extdeps_external_authority_anchor: ExternalAuthority = ExternalAuthority {
Expand Down Expand Up @@ -296,6 +297,155 @@ fn docker_image_inspect_id_from_stdout(stdout: String) -> DockerImageInspectIdRe
}
}

// NARROW ENV PROJECTION FROM CONTAINER INSPECT STDOUT. `docker container inspect` prints the whole
// object, including Config.Env values that can carry secrets. This decoder keeps Id (identity) and
// only the requested names from Config.Env. It never returns the rest of the Env list. Duplicate
// requested names refuse rather than last-wins. The transport is docker_container_inspect_command;
// this is a decoder bound to that shape, not a second inspect verb.
type DockerContainerInspectNamedEnvRead
= DockerContainerInspectNamedEnv {
id: NonEmptyStr,
assignments: List<DockerEnvAssignment>,
}
| DockerContainerInspectNamedEnvUnreadable { cause: NonEmptyStr }

fn docker_env_assignment_from_wire(entry: String) -> DockerEnvAssignment? {
let parts = split(s: entry, delimiter: "=")
match parts |> get(0) {
Absent => none
Present { value: name } =>
if name.length() == 0 {
none
} else {
Present {
value: DockerEnvAssignment {
name: name as NonEmptyStr,
value: join(parts.skip(n: 1), "="),
},
}
}
}
}

fn docker_named_env_name_requested(name: NonEmptyStr, names: List<NonEmptyStr>) -> Bool {
any(names, n => (n as String) == (name as String))
}

type DockerNamedEnvAccumulate
= DockerNamedEnvAcc { assignments: List<DockerEnvAssignment> }
| DockerNamedEnvAccUnreadable { cause: NonEmptyStr }

fn docker_project_named_env(env: List<String>, names: List<NonEmptyStr>) -> DockerNamedEnvAccumulate {
fold(
env,
init: DockerNamedEnvAcc { assignments: [] },
f: (acc, entry) =>
match acc {
DockerNamedEnvAccUnreadable { cause: c } =>
DockerNamedEnvAccUnreadable { cause: c }
DockerNamedEnvAcc { assignments: accs } =>
match docker_env_assignment_from_wire(entry: entry) {
Absent =>
DockerNamedEnvAccUnreadable {
cause: "container inspect Config.Env entry is not a KEY or KEY=VALUE assignment" as NonEmptyStr,
}
Present { value: a } =>
if !docker_named_env_name_requested(name: a.name, names: names) {
acc
} else if any(accs, x => (x.name as String) == (a.name as String)) {
DockerNamedEnvAccUnreadable {
cause: join(["container inspect Config.Env names ", a.name as String, " more than once"], "") as NonEmptyStr,
}
} else {
DockerNamedEnvAcc { assignments: append(accs, items: [a]) }
}
}
},
)
}

fn docker_container_inspect_named_env_from_object(obj: JsonValue, names: List<NonEmptyStr>) -> DockerContainerInspectNamedEnvRead {
match json_object_unique_member(v: obj, key: "Id") {
JsonMemberAbsent =>
DockerContainerInspectNamedEnvUnreadable { cause: "docker container inspect JSON names no Id" as NonEmptyStr }
JsonMemberNotAnObject =>
DockerContainerInspectNamedEnvUnreadable { cause: "docker container inspect JSON element is not an object" as NonEmptyStr }
JsonMemberDuplicated { count: n } =>
DockerContainerInspectNamedEnvUnreadable {
cause: join(["docker container inspect JSON names Id ", to_string(n), " times"], "") as NonEmptyStr,
}
JsonMemberFound { value: idv } => {
let id = json_string_value_or_empty(v: idv)
if id == "" {
DockerContainerInspectNamedEnvUnreadable { cause: "docker container inspect JSON Id is not a nonempty string" as NonEmptyStr }
} else {
match json_object_unique_member(v: obj, key: "Config") {
JsonMemberAbsent =>
DockerContainerInspectNamedEnvUnreadable {
cause: "docker container inspect JSON names no Config" as NonEmptyStr,
}
JsonMemberNotAnObject =>
DockerContainerInspectNamedEnvUnreadable { cause: "docker container inspect JSON element is not an object" as NonEmptyStr }
JsonMemberDuplicated { count: n } =>
DockerContainerInspectNamedEnvUnreadable {
cause: join(["docker container inspect JSON names Config ", to_string(n), " times"], "") as NonEmptyStr,
}
JsonMemberFound { value: cfg } =>
match json_object_unique_member(v: cfg, key: "Env") {
JsonMemberAbsent =>
DockerContainerInspectNamedEnvUnreadable {
cause: "docker container inspect Config names no Env" as NonEmptyStr,
}
JsonMemberNotAnObject =>
DockerContainerInspectNamedEnvUnreadable { cause: "docker container inspect Config is not an object" as NonEmptyStr }
JsonMemberDuplicated { count: n } =>
DockerContainerInspectNamedEnvUnreadable {
cause: join(["docker container inspect Config names Env ", to_string(n), " times"], "") as NonEmptyStr,
}
JsonMemberFound { value: envv } =>
match envv {
JsonNull =>
DockerContainerInspectNamedEnvUnreadable {
cause: "docker container inspect Config.Env is null" as NonEmptyStr,
}
JsonBool { value: _ } =>
DockerContainerInspectNamedEnvUnreadable {
cause: "docker container inspect Config.Env is not a list of strings" as NonEmptyStr,
}
JsonNumber { lexeme: _ } =>
DockerContainerInspectNamedEnvUnreadable {
cause: "docker container inspect Config.Env is not a list of strings" as NonEmptyStr,
}
JsonString { value: _ } =>
DockerContainerInspectNamedEnvUnreadable {
cause: "docker container inspect Config.Env is not a list of strings" as NonEmptyStr,
}
JsonObject { members: _ } =>
DockerContainerInspectNamedEnvUnreadable {
cause: "docker container inspect Config.Env is not a list of strings" as NonEmptyStr,
}
JsonArray { elements: _ } =>
match json_string_list(v: envv) {
Absent =>
DockerContainerInspectNamedEnvUnreadable {
cause: "docker container inspect Config.Env is not a list of strings" as NonEmptyStr,
}
Present { value: env } =>
match docker_project_named_env(env: env, names: names) {
DockerNamedEnvAccUnreadable { cause: c } =>
DockerContainerInspectNamedEnvUnreadable { cause: c }
DockerNamedEnvAcc { assignments: asg } =>
DockerContainerInspectNamedEnv { id: id as NonEmptyStr, assignments: asg }
}
}
}
}
}
}
}
}
}

// THE CONTAINER'S TWO IDENTITY FIELDS, AND NOTHING ELSE OFF THE INSPECT OBJECT. `docker container
// inspect` returns the whole object extdeps.docker.container_inspect ContainerInspect models,
// including Config.Env, whose values can carry secrets. This reader takes exactly .Id -- the full
Expand All @@ -322,6 +472,26 @@ fn docker_inspect_nonempty_string_member(obj: JsonValue, key: String) -> String?
}
}

fn docker_container_inspect_named_env_from_stdout(stdout: String, names: List<NonEmptyStr>) -> DockerContainerInspectNamedEnvRead {
match parse_json_document(s: trim(s: stdout)) {
JsonDocumentUnreadable { gap: g } => {
let t = json_document_gap_text(gap: g)
DockerContainerInspectNamedEnvUnreadable {
cause: if t.length() == 0 { "docker container inspect JSON is unreadable" as NonEmptyStr } else { t as NonEmptyStr },
}
}
JsonDocumentParsed { value: v } =>
match docker_inspect_json_first_of_one(v: v) {
Absent =>
DockerContainerInspectNamedEnvUnreadable {
cause: "docker container inspect JSON is not a one-element array" as NonEmptyStr,
}
Present { value: obj } =>
docker_container_inspect_named_env_from_object(obj: obj, names: names)
}
}
}

fn docker_container_inspect_identity_from_stdout(stdout: String) -> DockerContainerInspectIdentityRead {
match parse_json_document(s: trim(s: stdout)) {
JsonDocumentUnreadable { gap: g } =>
Expand Down
34 changes: 34 additions & 0 deletions dag/extdeps/languages/json/parse.dag
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,40 @@ fn json_string_value_or_empty(v: JsonValue) -> String {
}
}

// AN ARRAY OF STRINGS, OR NONE. The six JsonValue arms are exhaustive: a non-array, or an array
// whose element is not a string, is unread rather than last-wins or stringify. Docker Config.Env
// and OCI image-config Env are two readers of this one accessor.
fn json_string_list(v: JsonValue) -> List<String>? {
match v {
JsonArray { elements: es } => json_string_list_from(es: es, index: 0, acc: [])
JsonNull => none
JsonBool { value: _ } => none
JsonNumber { lexeme: _ } => none
JsonString { value: _ } => none
JsonObject { members: _ } => none
}
}

fn json_string_list_from(es: List<JsonValue>, index: Int, acc: List<String>) -> List<String>? {
if index >= count(es) {
Present { value: acc }
} else {
match es |> get(index) {
Absent => none
Present { value: el } =>
match el {
JsonString { value: s } =>
json_string_list_from(es: es, index: index + 1, acc: append(acc, items: [s]))
JsonNull => none
JsonBool { value: _ } => none
JsonNumber { lexeme: _ } => none
JsonArray { elements: _ } => none
JsonObject { members: _ } => none
}
}
}
}

// RFC 8259 permits duplicate names in an object and does not say which one wins, so JsonObject
// keeps members as an authored LIST rather than a map. A reader that folds that list into last-wins
// silently picks a value the document never committed to - and for an identity field like schema or
Expand Down
Loading
Loading