Skip to content

NativeAOT, Scoop packaging, signing hooks - #2

Merged
corecompiled merged 4 commits into
mainfrom
feat/aot-and-distribution
Aug 2, 2026
Merged

NativeAOT, Scoop packaging, signing hooks#2
corecompiled merged 4 commits into
mainfrom
feat/aot-and-distribution

Conversation

@corecompiled

Copy link
Copy Markdown
Owner

NativeAOT

08-decisions.md recorded AOT as "watching — the old reason is dead, only measurement remains". Measured:

Single-file NativeAOT
Size 43 MB 10.8 MB
Startup ~1–2 s cold ~0.16 s
Extracts to temp on first run yes no
Loose DLLs beside the exe 0

Every one of those lands on the same thing: this is software copied onto a USB stick and run on a machine with nothing installed.

Proven on both architectures in CI — arm64 needs a separate C++ component, which the trial workflow installs rather than leaving a release tag to discover — and the x64 binary was downloaded and run locally against a live model. Streaming, markdown rendering, the tokenizer, DPAPI key load and config persistence all work compiled. Markdig, the one library whose AOT behaviour was unverified, is fine.

.github/workflows/aot-trial.yml stays in the repo so this can be re-measured rather than re-argued.

The cost

dotnet publish now needs the MSVC linker from the Desktop C++ workload. build, test and run do not, so day-to-day work is unchanged — but cutting a release build requires a one-time install, documented in CONTRIBUTING.md and docs/06.

This was a genuine trade rather than a free win, so it's recorded as one.

Distribution

  • Scoop manifest with checkver/autoupdate, hashes pinned to v0.2.0. Installing via Scoop sidesteps SmartScreen entirely, which is much of the point.
  • Checksums asset per release, which is what Scoop's autoupdate reads.
  • Azure Trusted Signing wired into the release workflow behind a SIGNING_ENABLED flag and skipped until the secrets exist. Signing runs before checksums, since it changes the file.
  • packaging/README.md documents the free Microsoft reputation submission and the signing route — both need a human at a web form.

Also

Removed the CI sketch that had been copied into docs/06. A workflow reproduced in prose is a second source of truth that drifts from the real one — exactly the mistake the publish flags already made once.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WGcarVYpt1mfjk6iFkcDpZ

corecompiled and others added 4 commits August 3, 2026 05:46
AOT compiled cleanly here — zero IL warnings from the trim/AOT analyzers,
which retires the last open question about Markdig — but the native link
step needs the MSVC linker from the Desktop C++ workload, and this machine
does not have it registered (VsDevCmd sets no VCToolsInstallDir, and
`where link.exe` finds Git's unrelated link.exe).

Installing a multi-gigabyte workload to answer a sizing question is the
wrong trade when the GitHub Windows runners already have it. CI is also
where releases are actually built, so proving it there is worth more than
proving it locally.

Reports AOT size against the current single-file build and smoke-tests that
the native binary starts and renders, since AOT failures typically surface
as an immediate abort rather than a build error.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WGcarVYpt1mfjk6iFkcDpZ
Aborting first-run with no key is a correct non-zero exit, which failed the
step even though the binary had rendered fine. Now asserts on what was
drawn, and covers the first-run copy as well as startup so a Spectre
rendering break under AOT cannot pass silently.

Artifact uploads unconditionally — it is most wanted when a step failed and
someone needs to run the binary by hand.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WGcarVYpt1mfjk6iFkcDpZ
x64 AOT is 10.8 MB against 43 MB and starts in 0.16s, verified against a
real key. Before making that the shipping configuration, arm64 has to be
proven as well: cross-compiling needs the ARM64 C++ build tools, a separate
component from the x64 ones, and a release tag is the wrong place to
discover it is missing.

fail-fast off so one architecture failing still reports the other. The
smoke test stays x64-only, since an arm64 binary cannot execute on an x64
runner.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WGcarVYpt1mfjk6iFkcDpZ
AOT was recorded as "watching" with the note that its blocker had expired
and only measurement remained. Measured, via a trial workflow that stays in
the repo so this can be re-checked rather than re-argued:

    size     43 MB    -> 10.8 MB
    startup  ~1-2 s   -> ~0.16 s
    extracts to temp on first run: yes -> no
    loose DLLs beside the exe: 0

Every one of those lands on the same thing: software copied onto a USB
stick and run on a machine with nothing installed.

Proven on both architectures in CI — arm64 needs a separate C++ component,
which the trial installs rather than leaving a release tag to discover —
and the x64 binary was run locally against a live model. Streaming,
markdown, the tokenizer, DPAPI and config persistence all work compiled.
Markdig, the one library whose AOT behaviour was unverified, is fine.

The cost is real and is documented rather than buried: `dotnet publish` now
needs the MSVC linker from the Desktop C++ workload. `build`, `test` and
`run` do not, so day-to-day work is unchanged, but producing a release
build requires a one-time install.

Distribution:

  - Scoop manifest with checkver and autoupdate, hashes pinned to v0.2.0.
    Installing through Scoop sidesteps SmartScreen entirely, which is much
    of the point.
  - Release workflow emits a per-release checksums asset, which is what
    Scoop's autoupdate reads.
  - Azure Trusted Signing wired into the release workflow behind a
    SIGNING_ENABLED flag, skipped until the secrets exist. Signing runs
    before checksums, since it changes the file.
  - packaging/README.md documents the free Microsoft reputation submission
    and the signing route, since both need a human at a web form.

Also removed the CI sketch that had been copied into docs/06 — a workflow
reproduced in prose is a second source of truth that drifts from the real
one, which is exactly the mistake the publish flags already made once.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WGcarVYpt1mfjk6iFkcDpZ
@corecompiled
corecompiled merged commit 65df284 into main Aug 2, 2026
3 checks passed
@corecompiled
corecompiled deleted the feat/aot-and-distribution branch August 2, 2026 22:10
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