This repository is the executable downstream proof for Tsonic’s C# target. Every project is real TypeScript input, is checked through the selected source contract, emits C#, builds with the .NET SDK, and either runs to an exact finite result or passes an HTTP behavior contract.
Pure C# projects use the target’s default C#/.NET source profile:
import { Console } from "@tsonic/dotnet/System.js";
import { List } from "@tsonic/dotnet/System.Collections.Generic.js";
import type { int } from "@tsonic/csharp/types.js";
const values = new List<int>();
values.Add(42);
Console.WriteLine(values.Count);
@tsonic/dotnet/*, @tsonic/csharp/types.js, and @tsonic/core/lang.js are compiler-owned virtual source modules. They are not npm dependencies.
Projects that intentionally use JavaScript source APIs select the js surface in tsonic.json:
{
"targets": [{
"id": "csharp",
"surfaces": ["js"]
}]
}
const parts = "/todos/42".split("/");
console.log(parts.length);
Node is a capability package, not a source surface. A project importing node:* declares @tsonic/csharp-nodejs directly:
import { readFile } from "node:fs/promises";
Installing the Node capability does not select JavaScript globals. nodejs/packages/env-info proves this by using node:path and node:process under the pure C# source profile while printing through System.Console.
Each workspace is installed once at its workspace root. Each project directly declares only:
@tsonic/cli;@tsonic/target-csharp;@tsonic/csharp-nodejs when that project imports node:*.The C# target owns its runtime dependencies transitively. There are no direct proof dependencies on @tsonic/csharp-runtime, @tsonic/csharp-js, generated binding packages, or retired EF packages.
| Group | Proofs |
|---|---|
bcl | Hello World, calculator, Fibonacci, Span<T>/Memory<T>, CLR parallel execution, HttpListener todo API |
js | Hello World, calculator, Fibonacci, Promise-based concurrency, notes API, todo API |
nodejs | Pure-C# Node isolation, file I/O, Promise-based Node concurrency, HTTP server |
aspnetcore | Minimal API blog and EF Core/SQLite blog using dynamic @tsonic/dotnet/* provider declarations |
workspaces | Scoped and unscoped source-package consumption, each with a library and executable |
The inventory contains 22 tsonic.json projects. node scripts/check-architecture.mjs derives that count from the filesystem and fails if a project is missing from the verifier model.
Install from a workspace root, never from a child under packages/*:
cd bcl
npm install
npm run build
For a generated target project:
dotnet run --project packages/calculator/out/csharp/ProofBclCalculator.csproj
Advanced .NET configuration stays in user-owned .csproj files:
bcl/packages/hello-world/ProofBclHelloWorld.csproj owns NativeAOT publication;aspnetcore/packages/blog/ProofAspNetCoreBlog.csproj owns the ASP.NET framework reference;aspnetcore/packages/blog-ef/ProofAspNetCoreBlogEf.csproj owns NuGet versions, the NuGet lock, framework references, and the deterministic package-reference set used by provider reflection.Tsonic writes only out/csharp/**/*.cs in this mode. The user project explicitly includes that generated source; Tsonic does not rewrite the project file.
For the EF proof:
cd aspnetcore
npm install
npm run -w aspnetcore-blog-ef build
dotnet run --project packages/blog-ef/ProofAspNetCoreBlogEf.csproj
The package build first restores the locked NuGet graph and materializes its deterministic managed package-reference closure, then runs Tsonic.
bash scripts/verify-all.sh
The verifier follows one bounded model:
The default queue has at most eight workers and reserves at most 11,264 MiB across concurrent project tasks. Override those finite bounds with PROOF_JOBS and PROOF_MEMORY_MIB.
Every run uses a new .tests/verify-* directory. It never consumes an existing node_modules, generated C# tree, binary, provider cache, or prior report as semantic input. An OS file lock prevents two full verifiers from sharing state. The final report contains exact task counts, zero implicit skips/todos, package hashes, repository heads, elapsed time, CPU use, and peak memory for each command.
156 commits
TypeScript
55.5%
JavaScript
44.1%
This repository is the executable downstream proof for Tsonic’s C# target. Every project is real TypeScript input, is checked through the selected source contract, emits C#, builds with the .NET SDK, and either runs to an exact finite result or passes an HTTP behavior contract.
Pure C# projects use the target’s default C#/.NET source profile:
import { Console } from "@tsonic/dotnet/System.js";
import { List } from "@tsonic/dotnet/System.Collections.Generic.js";
import type { int } from "@tsonic/csharp/types.js";
const values = new List<int>();
values.Add(42);
Console.WriteLine(values.Count);
@tsonic/dotnet/*, @tsonic/csharp/types.js, and @tsonic/core/lang.js are compiler-owned virtual source modules. They are not npm dependencies.
Projects that intentionally use JavaScript source APIs select the js surface in tsonic.json:
{
"targets": [{
"id": "csharp",
"surfaces": ["js"]
}]
}
const parts = "/todos/42".split("/");
console.log(parts.length);
Node is a capability package, not a source surface. A project importing node:* declares @tsonic/csharp-nodejs directly:
import { readFile } from "node:fs/promises";
Installing the Node capability does not select JavaScript globals. nodejs/packages/env-info proves this by using node:path and node:process under the pure C# source profile while printing through System.Console.
Each workspace is installed once at its workspace root. Each project directly declares only:
@tsonic/cli;@tsonic/target-csharp;@tsonic/csharp-nodejs when that project imports node:*.The C# target owns its runtime dependencies transitively. There are no direct proof dependencies on @tsonic/csharp-runtime, @tsonic/csharp-js, generated binding packages, or retired EF packages.
| Group | Proofs |
|---|---|
bcl | Hello World, calculator, Fibonacci, Span<T>/Memory<T>, CLR parallel execution, HttpListener todo API |
js | Hello World, calculator, Fibonacci, Promise-based concurrency, notes API, todo API |
nodejs | Pure-C# Node isolation, file I/O, Promise-based Node concurrency, HTTP server |
aspnetcore | Minimal API blog and EF Core/SQLite blog using dynamic @tsonic/dotnet/* provider declarations |
workspaces | Scoped and unscoped source-package consumption, each with a library and executable |
The inventory contains 22 tsonic.json projects. node scripts/check-architecture.mjs derives that count from the filesystem and fails if a project is missing from the verifier model.
Install from a workspace root, never from a child under packages/*:
cd bcl
npm install
npm run build
For a generated target project:
dotnet run --project packages/calculator/out/csharp/ProofBclCalculator.csproj
Advanced .NET configuration stays in user-owned .csproj files:
bcl/packages/hello-world/ProofBclHelloWorld.csproj owns NativeAOT publication;aspnetcore/packages/blog/ProofAspNetCoreBlog.csproj owns the ASP.NET framework reference;aspnetcore/packages/blog-ef/ProofAspNetCoreBlogEf.csproj owns NuGet versions, the NuGet lock, framework references, and the deterministic package-reference set used by provider reflection.Tsonic writes only out/csharp/**/*.cs in this mode. The user project explicitly includes that generated source; Tsonic does not rewrite the project file.
For the EF proof:
cd aspnetcore
npm install
npm run -w aspnetcore-blog-ef build
dotnet run --project packages/blog-ef/ProofAspNetCoreBlogEf.csproj
The package build first restores the locked NuGet graph and materializes its deterministic managed package-reference closure, then runs Tsonic.
bash scripts/verify-all.sh
The verifier follows one bounded model:
The default queue has at most eight workers and reserves at most 11,264 MiB across concurrent project tasks. Override those finite bounds with PROOF_JOBS and PROOF_MEMORY_MIB.
Every run uses a new .tests/verify-* directory. It never consumes an existing node_modules, generated C# tree, binary, provider cache, or prior report as semantic input. An OS file lock prevents two full verifiers from sharing state. The final report contains exact task counts, zero implicit skips/todos, package hashes, repository heads, elapsed time, CPU use, and peak memory for each command.
156 commits
TypeScript
55.5%
JavaScript
44.1%