Skip to content

A serving turn's Work is what the caller asked for, not what a supplier loaded - #11410

Merged
briansrls merged 3 commits into
mainfrom
session/merry-eagle-325
Sep 16, 2026
Merged

briansrls merged 3 commits into
mainfrom
session/merry-eagle-325

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

What

product.fabric.work WorkContract could only describe a materialized program (program + source manifest + runtime closure). A serving turn was forced through that shape, so gunbc.serving.turn_demand built the turn's source manifest from the selected engine's loaded weights, tokenizer and runtime. That reversed the dependency: the requester's identity waited on the supplier's realization. And since nothing can observe loaded weight/tokenizer bytes (a declared boundary obligation, DESIGN 4b), every serving turn refused before admission, which is the first hard wall between the harness and a live Spark turn.

This PR fixes the boundary (DESIGN 3: interface, realization and policy are three facts):

  • product.fabric.work: WorkContract.execution: WorkExecution = MaterializedProgram { program, source, runtime_closure } | OfferedService { interface: ServiceInterfaceRef }. The arm is tagged into identity material, so a program and a service never share a key. work_contract_source had no consumer and is removed.
  • gunbc.serving.turn_demand: ServingTurnRequest { interface, inputs, effect_contract, output_contract }. serving_turn_contract is total, and serving_turn_work returns Work<P>. The model requirement (AnyAdmittedModel / ExactServingUnit) reaches identity through ExecutionRequirements.capabilities, as the harness already supplies it. The weights/tokenizer/runtime component standings, the manifest and the TurnWorkUnestablished arm are deleted, not kept beside the new shape (a replacement migration cut at the root).
  • gunbc.spark.serving_offer: spark_serving_turn_runtime (its only consumer was the deleted witness) is removed.
  • All 36 existing WorkContract constructions move to MaterializedProgram with no change in meaning -- but a change in KEY: see the identity schema note below.
  • Notes and the harness refusal text are updated to the real remaining frontier: harness_bind_seat receives no normalized turn request, so one Work and one Demand cannot yet be built at the request boundary for spark_first_party_admission → bind_candidate. That is the next PR.

Launch, unit, image and environment evidence is not discarded as a concept. It is offer provenance and admission policy (#11362's incarnation observation, a declared-unit digest, the usage-stats reader), and a demand that genuinely requires such a fact states it when one exists. No caller does today, so no such arm is declared (3c).

Evidence (executed)

Gunbc built from this head (dd82e963b4) on srv1 (aarch64), run with gunbc run:

  • test.claim.serving.turn_demand_witness, all 7 true:
    • an AnyAdmittedModel turn constructs as OfferedService with no engine observation
    • one AnyAdmittedModel Work is admissible on both DeepSeek and GLM units
    • RED exact DeepSeek ≠ exact GLM ≠ Any
    • RED different inputs are different Work
    • RED program vs service with every other field equal are different Work
    • opaque step / terminal result retained
  • Mutation control: removing the arm distinction from work_execution_material turns a_program_and_a_service_sharing_every_other_field_are_different_works red, and only that witness.
  • Every test fn (225) in the touched and adjacent witness files returned true: fabric capacity_class, grant_issuance, output_contract_resolution, selection, terminal_contract; fabric_m0 commit, completion, job_ending, job_ending_seal, origin_commit, publication; harness_seat; spark first_party_serving and serving_offer_route; serving turn_demand.
  • Private repo: git grep for WorkContract / runtime_closure / product.fabric.work on gunbc-private origin/main returned nothing.
  • The whole floor, compile-clean and clippy are left to CI.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Dj2o6GdkmLj52khY9XJCMW

Identity schema (side-chat hold, addressed)

The key preimage is now length-framed (label:length:bytes per field, steps included) under a leading schema tag, so a separator byte moved across a field boundary can no longer fold two contracts onto one key (a_separator_moved_across_a_field_boundary_is_different_work). This is a new key space: every materialized-program contract derives a different key than under the joined preimage. product.fabric.work work_identity_schema declares the transition and its census: derive_work_key is the only mint, work_for the only constructor, no production site rehydrates a WorkKey from stored text (git grep 'as WorkKey' has no production hit), so no persisted key re-enters a comparison; every in-process foreign-key join (completion, attempt graph, grant issue) refuses with a typed cause.

The either-unit witness is renamed to what it proves (the model screen over two unit values); the real one-Work-binds-on-either-offer control is owed by #11411 beside stable SupplierOffers.

…er loaded

product.fabric.work WorkContract gains an execution coproduct:
MaterializedProgram { program, source, runtime_closure } | OfferedService { interface }.
gunbc.serving.turn_demand builds a turn as an OfferedService from the request
alone, so Work no longer waits on observing the selected engine's loaded
weights, tokenizer and runtime (a boundary obligation nothing can discharge,
which refused every turn). Those facts are offer provenance and admission policy.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dj2o6GdkmLj52khY9XJCMW
Brian Searls and others added 2 commits September 15, 2026 14:34
…es its schema; the key-space transition is declared

A U+001F-joined preimage was not injective (a separator moved across a field
boundary derived one key for two contracts), and the new execution union added
a second such layer. Every field is now framed label:length:bytes, steps
included, under a leading schema tag. Schema 2 keys differ from schema 1 keys
for every contract; work_identity_schema declares that and carries the census
that makes it safe: no production site rehydrates a WorkKey from text, so no
persisted key re-enters a comparison, and every in-process foreign-key join
refuses with a typed cause.

The either-unit witness is renamed to the proposition it proves (the model
screen), and a separator RED is enrolled.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot
gunbai-bot Bot removed this pull request from the merge queue due to a manual request Sep 15, 2026
@gunbai-bot

gunbai-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Coordinating from session/bright-gull-790 (#11440, dashboard adhoc-cdb42732-d95).

Declared-unit digest durable store is at 27ae041ac58301d330b43564028701d2bbde3941. Placement reads target/spark-pair-declared-head-{group} and does not render/hash per collection round.

harness_seat.dag was touched only as the digest consumer (harness_declared_unit_digest). Please treat that as a known merge conflict once #11410/#11411 land; I will merge main after those PRs merge and drop consumed namespace_wave_admission rows then.

Do not merge #11440 from this comment.

@briansrls
briansrls added this pull request to the merge queue Sep 16, 2026
Merged via the queue into main with commit db22576 Sep 16, 2026
4 checks passed
@briansrls
briansrls deleted the session/merry-eagle-325 branch September 16, 2026 01:58
gunbai-bot Bot pushed a commit that referenced this pull request Sep 16, 2026
gunbai-bot Bot pushed a commit that referenced this pull request Sep 16, 2026
…rn runtime component deleted by #11410; the host join moved to first_party_serving)
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