Skip to content

Spark usage-stats: narrow typed observation at the host boundary; raw inspect never reaches policy - #11441

Closed
gunbai-bot[bot] wants to merge 31 commits into
mainfrom
session/gentle-bat-838
Closed

gunbai-bot[bot] wants to merge 31 commits into
mainfrom
session/gentle-bat-838

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Supersedes #11419 (carries its commits) and repairs the SOURCE HOLD: raw docker container inspect stdout no longer reaches first-party policy.

Boundary

  • Host operation boundary: gunbc.spark.serving_usage_stats_observe spark_serving_usage_stats_observe(launch, inspect_stdout, marker, receipt) is the single consumer of raw stdout. It returns only ServingUsageStatsObservation = ServingUsageStatsObserved { launch, container_id, standing: VllmUsageStatsLaunchStanding, receipt: ObservationReceiptRef } | ServingUsageStatsUnobserved { obligation }. The raw document is discarded there.
  • Policy: spark_first_party_admission(realization, usage_stats, scope, offer), spark_serving_usage_stats_standing, spark_usage_stats_telemetry_path and spark_first_party_route_facts take the typed observation. The raw carrier ServingContainerInspectStdout is deleted. The fold keeps the spark_incarnation_observation_agreement join, and it also requires the observation's launch and container to equal the agreed incarnation's. If they don't, the result is Unread (spark_usage_stats_observation_names_another_launch_obligation).
  • Conformance (§3b): this intentionally does not inhabit std.observation. Its ObservationSubject is a compiler-run containment path and cannot name a live container. Instead the observation follows the lane's existing EndpointIncarnationObservation shape (launch + ObservationReceiptRef), and it reuses upstream's VllmUsageStatsLaunchStanding rather than minting a second standing.
  • Declared frontier (§3c): the live producer is the one authorized inspect that Spark fabric integration: live-host observation producers (plan first, access question first) #11362 executes for the endpoint-incarnation observation. That single inspect yields both the incarnation identity and this observation. Trigger: Spark fabric integration: live-host observation producers (plan first, access question first) #11362's live inspect lands and is sufficient to hand its stdout to this function in the same operation. Until then the producer runs only in the witness.

Semantics kept

The decoder projects four env names: VLLM_NO_USAGE_STATS, VLLM_DO_NOT_TRACK, DO_NOT_TRACK, VLLM_USAGE_STATS_SERVER.

  • Only an exact "1" disables, and VLLM_DO_NOT_TRACK or DO_NOT_TRACK follows Python-or precedence.
  • An unread marker stays unread.
  • A present but empty server value is malformed.
  • An override destination is preserved.
  • Enabled telemetry is refused, and a non-default destination never inherits the default row's enrollment.

Every one of those witness controls is kept.

Grant

Authorized by gunbc.spark.managed_access_bootstrap InspectServingContainer. No new grant.

Test plan

  • All existing spark_serving_usage_stats_observe_witness_test arms now go through the typed observation. Admission and telemetry calls receive t_observe(...), never stdout.
  • New RED: an_observation_of_another_launch_does_not_absent_the_path.
  • Remote observe_witness_main at 3076736 under a cgroup memory.max exited 0 (a first run without a cgroup limit refused with HostBudgetUnreadable before evaluating anything)
  • CI floor

🤖 Generated with Claude Code

gunbc-ci-auto-heal and others added 14 commits September 15, 2026 08:13
… rest of Config.Env.

InspectServingContainer already authorizes docker container inspect; this decoder projects only VLLM_NO_USAGE_STATS, DO_NOT_TRACK and VLLM_USAGE_STATS_SERVER so first-party admission can resolve telemetry instead of treating every launch as unread.

Co-authored-by: Cursor <cursoragent@cursor.com>
…permanently-green Env-name check.

Declarations still claimed UsageStatsLaunchUnread on every arm and that no producer reads a running container; both are false once serving_usage_stats_observe exists. The decoder already refuses unrequested names, so a second filter could not go red.

Co-authored-by: Cursor <cursoragent@cursor.com>
…lation.

Empty inspect Env now witnesses ProviderPathLocated and first-party admit through the enrolled drop, plus RED without that enrollment. The first-party unread suite no longer claims the drop has no producer.

Co-authored-by: Cursor <cursoragent@cursor.com>
…fail-closed inspect Env.

Enabled standing no longer locates or admits. Incomplete Config/Env is unreadable, marker unread is unread, a present-empty server is malformed, and VLLM_DO_NOT_TRACK or-falls through to DO_NOT_TRACK exactly as envs.py at vllm_source_revision_read.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ed for enabled telemetry.

The typed row already had population []; the markdown ledger and sanctions/data_subject bases still described a Located enabled arm this PR refuses.

Co-authored-by: Cursor <cursoragent@cursor.com>
Inspect of a matching container Id must not Absent telemetry for a readback that disagrees with the declared pair-serving path. unread_cause runs first; a GLM fixture with VLLM_NO_USAGE_STATS=1 now refuses admission.

Co-authored-by: Cursor <cursoragent@cursor.com>
The remedy row listed three env names while vllm_usage_stats_inspect_env_names projects four. It now cites that roster.

Co-authored-by: Cursor <cursoragent@cursor.com>
…n obligation.

namespace-wave-admission refused NewUnresolvedness on spark_serving_incarnation_unobserved_obligation after the inspect import replaced serving_offer. The name still belongs to gunbc.spark.serving_offer.

Co-authored-by: Cursor <cursoragent@cursor.com>
Docker inspect and registry image-config were two copies of one array-of-strings reader; both now consume the same accessor.

Co-authored-by: Cursor <cursoragent@cursor.com>
The hoist rebinds one spelling in registry image-config; the consumed #11214 token-realizer rows come due on this roster touch and are deleted with it.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ion.

Telemetry was attributing inspect to observation.launch without the endpoint and host join serving_offer already owns; both consumers now share spark_incarnation_observation_agreement.

Co-authored-by: Cursor <cursoragent@cursor.com>
json_string_list is already admitted; the floor refused because those SCM rows were due the moment this file changed.

Co-authored-by: Cursor <cursoragent@cursor.com>
…tdout stops at the host boundary

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot mentioned this pull request Sep 15, 2026
6 tasks
…16; the json_string_list row stands alone)
@briansrls
briansrls added this pull request to the merge queue Sep 16, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Sep 16, 2026
Brian Searls and others added 7 commits September 16, 2026 02:30
…rn runtime component deleted by #11410; the host join moved to first_party_serving)
…ept side by side; the realization annotation carries both facts
…y of .dag rows (#11250); the json_string_list row moves there
…s the observation through admission (review 66882)

The observer's grant reads no do-not-track marker file, so a caller-supplied
DoNotTrackMarkerPresent was an unobserved disable that could green provider-use
admission; the parameter is gone and the marker is Unread by construction, with a
RED that the observer never disables without an observed env term. The production
caller (harness_admit_bound_offer) now passes the observation -- inspect-unread
until #11362's inspect feeds the producer -- so main and this change compose.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor Author

Review 66882: both findings fixed at 0e56511. (1) The production caller now composes: harness_admit_bound_offer takes and threads usage_stats into spark_first_party_admission, passing spark_usage_stats_inspect_unread() until #11362's inspect feeds the producer (the witness header names that as the frontier, not the threading). (2) spark_serving_usage_stats_observe no longer takes a marker standing — its grant observes no marker file, so a caller-supplied DoNotTrackMarkerPresent was an unobserved disable; the marker is Unread by construction, the_observer_never_disables_without_an_observed_env_term is the RED, and the rows that need the enabled arm drive the extdeps fold with a supplied marker. The posture prose that asserted the marker was always passed unread now states the construction.

— sent from merry-eagle-325

Brian Searls and others added 5 commits September 16, 2026 19:44
…ted only by the observer, and policy joins it to the incarnation with same_launch (side-chat hold)

A directly constructible Observed arm let a caller hand policy a Disabled standing
it never observed; ServingUsageStatsEvidence is a sole-constructor record whose
only mint is spark_serving_usage_stats_observe. The launch join was launch_wire +
container id -- group, invocation and container only -- so two readings
contradicting each other about one launch's unit or image digest could still
Absent the path; the join is now gunbc.spark.vllm_serving_launch same_launch,
with contradiction and turnover both Unread. REDs for both.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… decoder is unsealed; policy folds at the subject grain (side-chat hold)

spark_serving_usage_stats_observe(launch, stdout, receipt) was an unrestricted alternate
mint over caller-authored JSON. The sealed ServingUsageStatsEvidence now lives in
gunbc.spark.serving_incarnation_observe and is constructed there from the same
authorized inspect stdout the identity projection reads, beside the
EndpointIncarnationObservation; the harness carries both from one read per launch per
bind. gunbc.spark.serving_usage_stats_observe keeps only the unsealed decoder. Policy
delegates its join to a subject-grain fold so the refusal arms stay claimable with
authored subjects; the admitted positive control is a stated live-only frontier; a
source probe shows caller-authored evidence refuses to compile.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor Author

Side-chat hold (unrestricted alternate mint) addressed at 22c24ed. gunbc.spark.serving_usage_stats_observe is now only an unsealed decoder; ServingUsageStatsEvidence (sole-constructor record) lives in gunbc.spark.serving_incarnation_observe and is minted only inside incarnation_after_container from the same authorized inspect stdout the .Id/.Image projection reads — one inspect, two projections, the document dies with the call. The harness reads both from one observe_endpoint_incarnation per launch per bind (HarnessIncarnationRead, memoized) and carries the evidence into admission; refusal arms carry Unobserved with the operation's cause. Policy delegates its join to a subject-grain fold so the refusal REDs (turnover, contradiction, foreign endpoint/hosts, unmatched readback) still execute with authored subjects; the admitted positive control is a stated live-only frontier; spark_serving_usage_stats_evidence_seal_probe_test compiles a foreign module that authors evidence and asserts SoleConstructorViolation.

— sent from merry-eagle-325

Brian Searls added 3 commits September 16, 2026 23:56
…arried beside the declared-unit roster; spark_service_from_observation keeps the shared agreement join over the sealed digest
@briansrls
briansrls added this pull request to the merge queue Sep 17, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 17, 2026
@briansrls
briansrls added this pull request to the merge queue Sep 18, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 18, 2026
@gunbai-bot

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

Transition-admission migration for gunbc#11704. No action until the operator sequences #11704's landing.

gunbc#11704 moves namespace transition admissions out of the tree. Once it lands, any file under dag/gunbc/namespace/transition_admission/ refuses at this PR's own gate, and the admission has to be carried in a commit message on this branch instead. The block below was derived mechanically from this PR's 1 row file(s) at its current head. The only edits: deletion_follow_up, owner_pull_request and their now-unused imports are dropped, because those fields no longer exist. All 1 blocks load through the production fold (carried_admissions_from_messages) with no refusal.

To migrate (paste + delete), after #11704 is on main and merged into this branch:

git rm \
  dag/gunbc/namespace/transition_admission/gunbc_container_registry_image_config_container_image_config_env_from_json_json_string_list.dag
git commit -F msg.txt   # msg.txt = the text below, verbatim

-F keeps the lines exactly as they are. The squash merge carries the message into the queue run, and nothing lands in the tree. If a row is wrong later, a later block with the same stem supersedes it.

msg.txt
Move transition admissions into the commit message (gunbc#11704)

```transition-admission
module gunbc.namespace.transition_admission.gunbc_container_registry_image_config_container_image_config_env_from_json_json_string_list

import std.types { NonEmptyStr, List }
import std.decl_ref { decl_ref }
import gunbc.compiler_frontend_program_interlock { TargetChanged }
import gunbc.namespace.transition_admission { TransitionAdmission, Binding }

// gunbc#11441 json_string_list hoist: the spelling in container_image_config_env_from_json now
// binds extdeps.languages.json.parse, where both readers (docker inspect, OCI image config) take it.
// DISSOLVE-ON: gunbc#11441 merging.
data gunbc_container_registry_image_config_container_image_config_env_from_json_json_string_list: TransitionAdmission = TransitionAdmission {
  label: "gunbc#11441 json_string_list lives in json.parse" as NonEmptyStr,
  subject: Binding {
    enclosing: decl_ref("gunbc.container.registry_image_config", "container_image_config_env_from_json"),
    spelling: "json_string_list" as NonEmptyStr,
    expected_candidates: [decl_ref("extdeps.languages.json.parse", "json_string_list")],
  },
  disposition: TargetChanged,
}
```

@briansrls briansrls closed this Sep 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant