Skip to content

microVM: host-side JIT mint via GitHub App + attempt-owned jail device staging - #11677

Merged
briansrls merged 26 commits into
mainfrom
session/keen-bear-791
Sep 20, 2026
Merged

briansrls merged 26 commits into
mainfrom
session/keen-bear-791

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

Closes gunbc.runner_attempt_launch jit_mint_http_realization_frontier and jail_jit_device_staging_frontier (microVM program, parent sunny-ant-606). Nothing here makes the floor job select the microVM path.

The law, and where it now holds

No admitted, non-empty, signature-bound and attempt-bound JIT config means no jit device and no VMM process. The receipted fail-open was jitconfig-bytes=0, then a launch anyway.

  • plan_attempt_launch no longer takes a caller-assembled EnvelopeStanding. It takes gunbc.github_effect_perform JitMintPerformance, and admit_jit_credential admits a credential only when all of these hold:

    • it came from a delivered mint (JitCredentialBoundToAttempt),
    • it is bound to this attempt,
    • it sits between the byte floor and the byte ceiling.

    Every other case is its own JitDeviceRefusal arm.

  • jit_device and jailer are fields of one LaunchAuthorized arm, so a device can't exist without a launch or a launch without a device. The law is carried by the shape of that arm, not by a counter.

  • The registration id and runner name (the attempt's unit name) are recorded on the launch.

The mint happens on the host (parent's ruling A)

  • extdeps.auth.jws: the RFC 7515 compact signing input, RS256 per RFC 7518 §3.3.
  • extdeps.tools.openssl: enrolled as a host CLI tool, the same pattern as sshpass in DSV41-6 enroll sshpass as a host_cli_dependency for password-session runners (srv3/srv4 lack it) #11096 (gunbc.host_cli_dependency jit_mint_host_cli_requirements). It runs openssl dgst -sha256 -sign <key file> -hex with the signing input on stdin. The argv never carries a secret.
  • extdeps.github: two new REST operations on the Give GitHubEffect a REST performer whose shape is hermetically verdicted #10923 performer, github.AppInstallationAccessTokens.Create and github.ActionsJitRunners.GenerateOrganizationJitConfig.
  • gunbc.github_effect_perform is the new effect home. perform_organization_jit_mint signs the App JWT, mints an installation token, then calls generate-jitconfig.
    • The JWT and the token are Secrets that live only inside that one call.
    • A generate POST that never got an answer is reported as commit-ambiguous, not as a refusal.
  • The signing key is one modeled path, lifecycle_controller_app_key_path. It is deliberately not the runner-user-owned runner_host_app_pem_path. No caller can pass a different key.

The jail device

The device is created in two steps, in this order:

  1. install -m 0400 -o <attempt uid> creates the file inside the attempt's jail before any byte of the credential exists there.
  2. The drive bytes are written through the filesystem, not through an argv.

The bytes are the guest's contract, not a host choice. What goes on the drive is exactly gunbc.runner_microvm jit_drive_content(credential): one ACTIONS_RUNNER_INPUT_jitconfig=<blob> line, newline-padded to whole 512-byte sectors, which is what the guest agent reads from the device jit_drive_guest_device names (#11671). The earlier cut wrote the raw blob NUL-padded, the recovered init's format, which the guest could not read; that is deleted, along with the truncate builder only it used.

stage_jit_device then reads back the owner, mode and size from the host, and refuses if any of the three is wrong. A stat that itself failed is its own refusal carrying stderr, not a mismatch against an empty reading. The guest only sees a read-only drive.

Also changed

The mint path used to carry a second, out-of-jail jit.img path that the jailed VMM could never open. It is deleted, so the device location has one owner.

Signer shape

extdeps.auth.jws declares the signer over a key reference (JwsSigningKeyRef = HostKeyFile { path }, JwsSignOutcome), and gunbc.jws_signer_realize is the peripheral handler dispatch with openssl as one handler. The key never enters the evaluator. That is the shape the PRIMITIVE-EGRESS-0 ruling requires: a signer over an external key, not "RS256 realized by a CLI".

Still open (declared, not claimed)

  • jit_mint_lifecycle_controller_consumer_frontier: no production code calls the mint or the staging yet. The caller is the lifecycle controller, which is another lane's work.
  • App-key custody delivery: a converge entry that puts the key at lifecycle_controller_app_key_path owned by root, with a readback receipt. That comes in a follow-up PR in this lane. Until it lands, the mint refuses at the signer; it does not fall back to the runner-user-owned key.
  • Rung: the planner path is still Mitigatable. A caller can still construct a JitMintReceived directly, and the next rung up is a sealed performance carrier.

Evidence — WITHDRAWN, and why (read this before citing any number)

There is no witness verdict for this head, and the earlier numbers in this body were wrong to cite. They were not wrong because a claim failed. They were wrong because of the compiler that produced them.

Every local run I reported (17/17 launch, 7/7 mint path, 21/21 lifecycle, and the earlier 17/17s) used claim_batch from a sibling worktree, built 2026-09-19 01:50, against a head dated 2026-09-20 10:43 — 17 seed commits stale. One of those commits decides the outcome:

That is exactly the check that flags dag/gunbc/fabric/fabric_required_build_cell.dag:416:76 and :419:80 (Optional<String> passed where String is declared). My binary predates the checker, so it could not see that defect and reported passes; a binary built from the head sees it and stops before any claim evaluates. Same tree, different compiler. An independent srv1 reading, built from the head, stopped on those two errors in all three files with 0 PASS / 0 FAIL.

The working agreement says to prove which compiler you reached rather than assume it. I did not, and this is the failure mode that instruction exists to prevent.

Status of the evidence:

  • The claims may well hold — but "may well" is not a receipt, and nothing here should be read as one.
  • The whole-tree resolve of this head is blocked by that fabric_required_build_cell defect, which is on main, byte-identical, outside this diff. eager-swift-412 is fixing it in microVM wet lifecycle controller: MainPID realization + srv1 REDs #11803. I have not worked around it.
  • CI's green is not a substitute: on this head the required floor job logged phases_run=2 phases_failed=1 and the same two fabric_required_build_cell type errors, produced zero [witness] lines, and still exited 0 (run 35505868144, job 106065468152, step 8 => success).

What will close it: once #11803 lands, the three witness files are run under a claim_batch built from this head, and the report states the binary's path, build time and originating commit alongside the results.

🤖 Generated with Claude Code

Close jit_mint_http_realization_frontier and jail_jit_device_staging_frontier.

- extdeps.auth.jws: RFC 7515 compact JWS signing input + RS256 (RFC 7518 3.3).
- extdeps.tools.openssl: enrolled host CLI dependency; openssl dgst -sha256 -sign
  <key file> -hex, signing input on stdin, no secret in argv.
- extdeps.github: POST app/installations/{id}/access_tokens and org
  generate-jitconfig as REST operations on the #10923 performer.
- gunbc.github_effect_perform: the effect home; perform_organization_jit_mint
  signs the App JWT on the host with the controller-custodied key, mints the
  installation token and the JIT config, and returns a typed performance
  (commit-ambiguous generate is its own arm).
- gunbc.runner_attempt_launch: admits a credential only from a delivered,
  attempt-bound, floor-to-ceiling mint; the jit device and the jailer are one
  plan arm, so no admitted credential means no device and no VMM. The device
  is install -m 0400 -o <attempt uid> before any byte, written via the
  filesystem, NUL-padded to whole sectors, read back. Registration id and
  runner name are recorded on the launch.
- Drop the out-of-jail jit.img path fork (runner_microvm_attempt /
  runner_jit_mint / runner_jit_perform): the device location has one owner.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…y, HostMintAdmission checker

- Credential size refusals carry ByteSize and compare through measure_le again.
- ci_spec's two App-JWT preludes take the RS256 header from extdeps.auth.jws and
  the claim JSON shape from github_app_jwt_claims_json_of (printf placeholders);
  emitted bytes unchanged.
- runner_jit_admission: X's HostEnvelopeNonemptyAndFresh becomes HostMintAdmission,
  and admit_jit_credential consumes the roster (refuses if it stops requiring it).

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 68117 (REQUEST_CHANGES) in 3341ce9:

  1. ByteSize. JitCredentialBelowFloor / JitCredentialAboveCeiling carry ByteSize, jit_credential_bytes returns ByteSize, and the floor and ceiling comparisons go through measure_le again.
  2. One authority for the App-JWT shape. Both gunbc.ci_spec preludes (gunbc_ci_org_admin_app_token_prelude and gunbc_ci_app_jwt_prelude) now take the RS256 protected header from extdeps.auth.jws jws_rs256_protected_header_json. They take the claim JSON shape from the new extdeps.github.org_admin_auth github_app_jwt_claims_json_of, rendered with printf placeholders because those preludes read the clock in-step. github_app_jwt_claims_json delegates to the same function, so the shape and both bounds have one producer. The emitted bytes are unchanged.
  3. Axis roster honesty. X's HostEnvelopeNonemptyAndFresh is renamed to HostMintAdmission, because a different check gets a different name (§3). admit_jit_credential is now that checker and consumes the roster: it refuses with JitMintAdmissionAxisNotRequired if the signature or expiry axis stops requiring it. runner_two_attempt_receipt now says what is actually open, which is execution by the lifecycle controller.

Local claim_batch --hermetic: launch 11/11, jit_admission 5/5, github_effect_perform 6/6.

— sent from keen-bear-791

…_devices alias

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 68156 in 0e26b37:

  1. EpochSecs. github_app_jwt_claims_json and app_jwt_for now take EpochSecs. The value comes from the clock read through a new extdeps.clock epoch_secs_of_millis, which sits beside clock_unix_millis_read. The inline ms / 1000 is gone.
  2. planned_jit_devices deleted. The law is carried by the LaunchAuthorized arm. no_device_no_vmm now counts launches only, and its comment says why a second count read off the same arm would be green by construction. The PR body is updated to match.

Local claim_batch --hermetic: launch 11/11, github_effect_perform 6/6.

— sent from keen-bear-791

gunbc-ci-auto-heal and others added 3 commits September 19, 2026 06:44
…eNameRead)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ack mode from one row (review 68264)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…re Secret (review 68283)

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 68283 in 4830553. jws_compact_serialization now returns extdeps.auth.jwt JwtCompactSerialization, and AppJwtSigned carries that branded type. The brand is shed in exactly one place, the github.AppInstallationAccessTokens.Create Bearer input, and that site is commented. So the JWT and the opaque installation token are no longer interchangeable anywhere else in perform_organization_jit_mint. Earlier commits afcc7018c30 and be8da1606ff fixed the floor's AmbiguousBareNameRead on Unit and the mode row from review 68264. github_effect_perform witnesses 6/6.

— sent from keen-bear-791

gunbc-ci-auto-heal and others added 2 commits September 19, 2026 08:30
…ion body (parse: annotation at module-item grain only)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… keep clock notes attached (review 68318)

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 68318 in e20ac1c:

  • extdeps.github.app. The github.AppInstallations note no longer says nothing in the corpus can sign RS256. It now says the corpus signs on a host holding the key file (extdeps.auth.jws over extdeps.tools.openssl, performed by gunbc.github_effect_perform). That service's callers still run where no key file is custodied, which is why it keeps the env-read Bearer. The installation_token_request_url note no longer claims there is no operation: it names github.AppInstallationAccessTokens. It also states that the rest path template has to be a transport literal for the same endpoint, since a template can't call a builder.
  • gunbc.github_app_acquisition and gunbc.instruments.github_app_acquire census_app_installation_route_frontier_rows. The reason and trigger now name what's actually missing: custody of the census App's key as a file where the instrument runs. They no longer claim the corpus lacks a signer. The trigger admits either an external step or the corpus signer.
  • extdeps.clock. epoch_secs_of_millis moved below clock_unix_millis_read with its own annotation, so the parse_int note is attached to the declaration it describes again.

Earlier today: 2fc768aa74f fixed the floor's parse refusal (an annotation inside a function body), and afcc7018c30 fixed AmbiguousBareNameRead on Unit.

— sent from keen-bear-791

gunbc-ci-auto-heal and others added 4 commits September 19, 2026 12:25
…e_destination from the resolved arms

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… prelude consumes jws/claims authorities

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…Ref/JwsSignOutcome); openssl is one handler in gunbc.jws_signer_realize (CRYPTO-0/PRIMITIVE-EGRESS-0 shape condition)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ntent on the jail device

- JitDeviceStaging carries the guest contract bytes (one jitconfig env line,
  newline-padded to 512-byte sectors); the NUL-pad truncate step and
  truncate_to_size_command are deleted (a second authority for the drive format).
- Readback checks size == the content's own UTF-8 size; a failed stat is its own
  refusal carrying stderr (review 68502).
- Witness pins staged bytes to jit_drive_content AND to its documented shape.
- Keep the deletion of jit_mint_http_realization_frontier / jail_jit_device_staging_frontier;
  runner_guest_image's acceptance trigger now names the performer and the stager.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 19, 2026
…igning-key ref

#11677 wrapped the path in JwsSigningKeyRef HostKeyFile, deleting the bare
lifecycle_controller_app_key_path this module imported, so both the entry and its
witness failed to resolve. signing_key_file_path matches the one arm that names a
file on this host.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…(review 68653 note)

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

Took the non-blocking note from review 68653 in 8185db2. lifecycle_controller_app records which App the controller's key belongs to, and perform_organization_jit_mint refuses a dispatch for any other App as JitMintAppKeyNotCustodied, before signing, rather than reaching GitHub with a JWT signed by the wrong key. github_effect_perform witnesses 6/6.

— sent from keen-bear-791

…h fork (reviews 68668, 68670)

- jit_credential_bytes uses runner_microvm jit_drive_utf8_size, the same measure
  the readback uses; string_length counted code points and labelled them bytes.
  New claim: 65536 two-byte code points are at the ceiling in characters and over
  it in bytes, and are refused.
- JitMintPlan.endpoint_path was produced and discarded (the POST path is the
  operation's own template), so the field and org_generate_jitconfig_path go; the
  org stays an operation input, which is what keeps a caller off another org.

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 68668 and the endpoint_path finding relayed from review 68670 on #11679, in f875cd1:

  • Bytes, measured as bytes (review 68668). jit_credential_bytes now calls jit_drive_utf8_size, the same measure the device readback uses. string_length counted code points and labelled them bytes, so the floor/ceiling wall and the readback could disagree on any non-ASCII octet. New claim a_credential_at_the_ceiling_in_code_points_but_over_it_in_bytes_is_refused: 65,536 two-byte code points are exactly the ceiling counted as characters and 131,072 bytes counted honestly, and it is refused. A string_length wall admits it, so the mislabelling cannot come back silently.
  • endpoint_path (review 68670). It was produced by plan_jit_mint and discarded by dispatch_jit_mint; the POST path is the operation's own template. The field and org_generate_jitconfig_path are deleted, along with the two witnesses that pinned the builder. The organization stays an operation input interpolated into the template, which is what actually keeps a caller off another org's runners; that is stated on the operation.

Local claim_batch --hermetic: launch 12/12 (including the new multi-byte red), github_effect_perform 6/6, actions_jit_runner 6/6, runner_jit_admission 4/4, registry jit/dispatch/delivery 15/15.

— sent from keen-bear-791

gunbc-ci-auto-heal and others added 8 commits September 20, 2026 00:42
…kspace staging) into #11677

Resolution keeps both sides: the JIT fields and device staging on LaunchAuthorized,
and #11675's tap-grain egress (no nft_ruleset field), guest network boot args, and
workspace staging gate. staging_verdict destructures the new fields and matches the
renamed refusal arm; #11675's four workspace witnesses are restored over the mint
parameter.

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

The workspace gate (#11675) and the jit device (this PR) landed on opposite
sides of a merge, and the join took only the workspace observation: a mint
accepted, LaunchAuthorized built, the credential device failed to stage or never
staged, workspace ready -> jailer admitted. That is the guest-with-no-credential
burn this planner exists to prevent (sunny-ant-606 hold).

- attempt_staging_verdict(plan, jit, workspace) replaces staging_verdict. It
  admits only when the device staged AT THE PATH THIS PLAN NAMES and the
  workspace is ready; StagingRefusedJitDevice, StagingRefusedForeignJitDevice,
  StagingRefusedWorkspace and StagingNotAuthorized are distinct.
- The jailer is reachable only inside AttemptStagingReceipt, a sole_constructor
  the gate alone produces, so 'staging passed' cannot be minted beside it.
- Controls: ready workspace + failed device refuses; ready workspace + a sibling
  attempt's staged path refuses; the admitted receipt names this attempt's paths.
- review 68748: the App-custody guard gets its red -- the shared dispatch fixture
  is another App, so an authorized dispatch for it refuses before any I/O.
- jws.dag: keep the signature-octets note attached to jws_compact_serialization.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… enrolment) into #11677

Resolution: the plan keeps my JIT fields, device staging and both-stagings gate,
and takes #11672's RunnerMicroVmShape parameter, runner_microvm_workspace_grant
and with_boot_arg rename. The rosters and argv admissions are additive unions;
my signer roster becomes the FOURTH enrolment answer beside main's gh one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… unterminated function body)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…rations carried through merges

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ledger-Repair-Judged: docs/design-rung-drops.md
Ledger-Rows-Repaired: docs/design-rung-drops.md namespace_wave_admission_wall_removed
Heal-Candidate-Run: 35490123999
#11677's jail-interior device does not leave #11670's teardown join importing a deleted symbol
gunbai-bot Bot pushed a commit that referenced this pull request Sep 20, 2026
… still owed

admit_next_incarnation and settle_and_record_attempt_teardown are the store's
production consumers: the admission reads the records the host holds and the
terminal path performs the write the settlement already decided on, rather
than composing a second one. record_attempt_started is the in-flight half.

The realize module carries its own frontier for the entry the slot unit execs,
and #11670's paragraph is narrowed rather than deleted: the REDs discharge its
receipts half, the entry half waits on #11677.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 20, 2026
… in-flight record

controller_start had no production consumer -- begin_attempt is it. The
ground is no longer a supplied value: it is a listing of the attempt root
that does not name this attempt, read the same way the teardown reads it,
with the UNREADABLE arm answering OCCUPIED because a ground nobody could
read is not a clear one and the cost of that direction is a launch rather
than a leak. The cell is derived from the identity's own slot rather than
supplied beside it, so the admission asked for and the binding performed
cannot disagree. The write performed is the one the decision's arm carries,
never one composed here; recovery writes nothing, because what is owed there
is the terminal path for the attempt that never settled.

This is the part of the brief that does not need #11677. What still waits on
it is the stage-and-launch step between these two halves.

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

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

gunbai-bot Bot commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

Evidence withdrawn — the numbers previously in this PR body were produced by a stale compiler, not by a passing tree.

Every local witness run I reported used a claim_batch from a sibling worktree built 2026-09-19 01:50, against a head dated 2026-09-20 10:43. Between them landed 978f6aaa342 (Floor: refuse an Optional where a Required value is declared, #11720) — the check that flags dag/gunbc/fabric/fabric_required_build_cell.dag:416:76 and :419:80. My binary predates that checker, so it reported passes over a tree a current binary refuses to resolve. An independent reading built from the head stopped on those two errors in all three files, 0 PASS / 0 FAIL.

Same tree, different compiler. The PR body now states this in place of the numbers.

The blocking defect is on main, byte-identical, outside this diff, and is being fixed in #11803; I have not worked around it. CI's green does not substitute: the required floor job on this head logged phases_failed=1 with those same two errors, emitted zero [witness] lines, and exited 0 (run 35505868144, job 106065468152).

Once #11803 lands I will rerun the three witness files under a binary built from this head and report its path, build time and originating commit with the results. Until then this PR should be held on evidence grounds, independent of the green checks and the standing approvals.

— sent from keen-bear-791

…ure-mode rows) into #11677

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@briansrls
briansrls added this pull request to the merge queue Sep 20, 2026
Merged via the queue into main with commit d232e13 Sep 20, 2026
4 checks passed
@briansrls
briansrls deleted the session/keen-bear-791 branch September 20, 2026 16:24
gunbai-bot Bot pushed a commit that referenced this pull request Sep 20, 2026
briansrls pushed a commit that referenced this pull request Sep 20, 2026
Side-chat REWORK. Part 1 (external blockers as prose) was withdrawn after I
traced that startable authorizes closing-contract authoring rather than
implementation dispatch. Parts 2 and 3 stood, and both were my errors.

THE CENSUS ROWS ARE NOT AN AUTHORITY. The page said the 57 transcribed rows
were dissolved by the scan producer. That is materially wrong in two ways.
The economic readings attached to those rows were shown not to have the
meanings assigned to them -- wall duration is not summed runner occupancy, an
admission delay is not a runner queue delay, a provider declaration can
outlive provider execution, and adoption is not spend -- so the derived
runner-minutes and ARM-tier totals do not follow, and "five carry
CostOpportunity" must not be quoted as a finding. And the scan producer is
workflow-level, so it is necessary and NOT sufficient: the facts those rows
need are job-level. The job-level arc is now a roadmap node instead of a
sentence.

ACQUISITION IS MODELED, NOT ACHIEVED. The page called gunbc#11552 an
end-to-end App manifest flow. Its own route tells the operator to paste the
manifest into the create form's manifest field; GitHub exposes no such field
and the manifest protocol needs a form POST. I watched that step fail live in
this session and wrote "end to end" anyway. Registration and INSTALLATION are
also two facts, and gunbc#11677 consumes both rather than creating either.
That is now a node with the remaining work named.

EXTERNAL BLOCKERS ARE GONE. gunbc#11552, #11564, #11656, #11669, #11671,
#11677 and #11679 are all merged. The nodes and the page said otherwise.

The two real prerequisites are now EDGES rather than prose, which is the
repair the reviewer asked for: the installation token depends on the App
existing, and the job-level reprojection depends on the token.

Projection reconciles 146 -> 148: two nodes and their closing-contract
carriers, minus the two carriers the new edges remove from the startable set.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 21, 2026
…ned_be admits through uint8_octets_of_ints, base64 callers go through base64_octets (jws too)

The whole-corpus floor ran 494 claims and 34 failed with 'cannot access field members on List' -- #11727 was written against the pre-sealed word_from_octets(List<Word>) and base64_encode(List) shapes, and #11677's jws had the same raw-List call on main. Each now admits its octets through the one mint and refuses typed on the Refused arm.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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