Repository navigation
Conversation
…, tone curve and core version PRD-832 phases 1 and 2. scripts/lib/repo-inventory.mjs derives the kits, the brief genres, the workspace packages and the Node floor from disk, so the recall no longer rejects the puzzle, rts and runner kits it had never heard of. A drift spec fails on any render source that ships byte-identical in every kit that carries it and is not restamped: it named nine copies, not the seven the report counted, and all nine are now shared and restamped to no-op. debug.ts owns readLaunchFlag/readLaunchValue, replacing fourteen readers and three truthiness rules. WorldEnvironment delegates its tone curve to applyRendererToneMapping (the preset already made filmic the default), and the core version now has one source: the generated version.ts.
…from one manifest PRD-832 phase 3. api/web-frame-fields.json is the field table; generation writes the TypeScript constant, the C++ enum and the facade's stage tables from it. web_host.cpp switches on the enum names, and an id the manifest does not declare prints TN_WEB_FRAME_UNKNOWN_FIELD once and answers NaN rather than a zero a caller would read as a real measurement. A spec pins the three copies and digests the table, so a renumbered field goes red.
The drift guard grouped copies by hash, so a listed file one kit edited dropped out of the check; it now compares every shipped copy with the canonical one. The facade's debugRequested and core's readLaunchFlag follow one rule, held together by a parity spec, and bundlesAsked hears every naming seam again. The web frame table pins the published (name, id) pairs instead of a digest that could not tell an append from a renumber, and the generated header refuses an unknown id before a renderer exists. Reverted the spell tier reader (a verbatim upstream port), the invented TN_SHADOW_* environment seams, and a comment that ignored the Unreal-look harness's own tone map copy.
…order visual-gate hands repo-inventory the repository root, not the templates folder (its spec was red); the spell tier reader is byte-identical to the base commit again; the example's package.json gains one line instead of a re-sort; the parity cases carry the answer the rule gives, so two copies agreeing on a wrong answer still fail; and assertSupportedNodeVersion reads the floor from engines.node, where a range shorter than the running version is not 'below'.
… rewritten by a tool PRD-833 phase 3. One hash per kit said a tree moved without saying why, so a shared edit re-pinned sixteen rows and needed a paragraph of history to read. Each kit now carries a 'shared' hash (agent-files, template-assets, core's tables, the shared render sources and the generated AGENTS/CLAUDE routers) and a 'kit' hash (the kit's own files); `pnpm scaffold:pin` rewrites both and names which side moved. The classification is derived in __tests__/scaffold-tree.ts, not listed, so a new synthesized file lands in the right bucket. STARTER_PATHS, MINIMAL_RENDER_PATHS and PLATFORMER_PATHS are deleted: the two hashes catch a missing or changed file and the allowlist catches a new kind of file, which is the whole contract those lists carried.
…ce, in core PRD-833 phase 1. The seven render files every kit copied byte-for-byte (environment measure, sample, cache and provenance, the backlight lane and its controls) move to @threenative/core/render/environment, together with the admission gate they already depended on: that gate was the one cross-boundary import, twelve kits held their own copy of it, and it is the WebGL-fallback predicate the phase also asked to unify. 84 copies are deleted and each kit's quality.ts is a three-line re-export. Every moved export carries the @Situation tags a public capability needs. The charter checks were extended rather than bypassed: constraints.spec.ts admits the folder with a tighter assertion that it originates no material, light, colour or shader (only the sampling quad's material and the node twin of the game's own), and check-core-boundary admits the mechanism names with the same proof. looks.spec.ts and the RTS cost loader learned the one subpath.
…-commit hook regenerated
PRD-833 phase 2, box 2. template-assets/patches/manifest.json lists each patch once with its repository source; the prepack step (scripts/sync-patches.mjs) copies exactly those into the tarball and prunes the rest, copyFrameworkPatches resolves a kit's patchedDependencies through it, and framework-patches.spec.ts holds every kit to it. The filename was spelled in src, in the prepack one-liner and in sixteen kit manifests; a three-version bump needed all of them edited by hand.
A single-line pin was longer than the formatter's width, so biome wrapped it and the tool's reader stopped recognising its own table, which made every commit alternate between a re-pin and a format. Pins are one hash per line now, with the key quoted only when it is not a plain identifier, and the reader accepts both forms so a formatter pass cannot break it.
md5sum over all sixteen kits names four vite variants, three tsconfig variants and four main.ts variants, and the diff of each: minimal drops React and Tailwind, starter and shooter add a second worker entry, the rain group differs only by a missing comment, and adventure's Tab preventer is the one genuine per-kit statement. The next attempt starts from that table instead of a survey.
PRD-838 phase 2, the dead-script half (the box said five; the report was wrong about one). asset-pose-capture, realistic-ocean-budget, realistic-ocean-capture and verify-fog-exposure are referenced by nothing but the untangle report. release-native-local.mjs stays: release-native-local.ts imports it at runtime because it ships untranspiled, and its own spec covers it. The scaffold pin tool registers its temp-dir cleanup in the guard the repo keeps for that, and the orphan-gate audit (which gate is superseded, which produces cited evidence) is written into the PRD box that still owns the decision.
check-capability-examples is a library the engine-mcp spec imports, so pnpm test runs it; arm-census, asset-parity and playtest-pair are imported by their own specs inside the root vitest include and produce reports the docs cite. The suite is the gate, and pnpm budgets is for invariants rather than for writing evidence, so the box that asked to wire or delete them is deleted by decision.
PRD-837 phase 2, box 1. Four subsystems asked the facade's own info table whether the owned engine was behind it by spelling `"engine" in info\': game startup (which decides the velocity and matrix-world passes), WorldEnvironment twice (temporal AA and the SSGI cache fallback) and the bundle recorder. A rename in the engine's info table would have left all four reporting the wrong backend with nothing failing. rendererFacts() is the one reader, and it ships only the two fields its callers need: webglFallback already has an owner in the environment gate, and software has no caller.
# Conflicts: # packages/runtime-native/tests/embedded-js.mjs # packages/runtime-native/tests/scheduler-yield.test.mjs
…olden path exit 0
…(PRD-834 phase 3 box 1) defineGame takes one `renderer` key: the project's portable config (`config.renderer` from threenative.config.ts) beside the live renderer options. The retired `render` key throws TN_GAME_RENDER_KEY_RENAMED and names the field mapping, so a game that still passes it cannot silently lose its scale, sampling or Android overrides. The 16 kit templates, the in-repo examples, the fixtures and the guides migrate to the one key; the scaffold hashes are re-pinned. Core's own tests prove the throw at defineGame time and exercise the merged key through the scale, antialias and projection resolvers.
…e verify and starter perf windows green
…gh its exports map (PRD-840) `@threenative/core/render/environment` became a subpath when PRD-833 moved the module to `src/render-environment.ts`. The native player bundles source and read the last path segment as the file name, so every kit that imports that subpath failed its desktop build with `Cannot read file: …/@threenative/core/src/environment.ts`. coreSourcePath reads the package's own exports map: the published `./dist/<name>.js` is written from `src/<name>.ts`. core-subpath-source.test.mjs walks every declared subpath and fails on one that resolves to a file that is not shipped.
…-3 blocked by a loaded host
…the generated frame-op names, the config-key manifest
The shooter kit set both `renderer: config.renderer` and `renderer: { antialias: true }` after
the fold; it is one object now, with the kit's antialias default where the config leaves it unset.
`frame-op-stream.js` declares the 35 generated `OP_*` ids, so the naming rule does not apply to
that file (the names come from `frame-ops.json`), and `native-config-keys.json` is formatted.
pnpm lint: 0 errors, 2138 pre-existing warnings.
# Conflicts: # docs/verification/native-coverage-2026-08-28.md # packages/create-threenative/__tests__/scaffold.spec.ts
… seven launch checks pass, web-ui-missing-bundle does not refuse
…ith the chain's state table updated
…n CTest verify-native-contracts.mjs lists three invocations for threenative-shim-bootstrap-test (default, --worker-rollback, --callback-retention) and the coverage lane builds its execution list from the CTest inventory, so it failed with 'CTest registered 1 invocation(s), expected 3' and the native-coverage report could not be regenerated — which is the red the budgets job reports as a stale digest.
…w contract targets PRD-842 added shim-bootstrap, webgpu-wrapper-bag, image-decode-teardown, buffer-map-lifetime and platform-policy as contract targets without claiming them in build-matrix.json, so `pnpm budgets` fails on each one; the coverage report itself was stale for the same merge, and regenerating it needed the two extra shim-bootstrap CTest registrations committed just before. `pnpm budgets` → exit 0.
…e three defects fixed on the way
…n unknown double cast `pnpm quality` counts a new `as unknown as` as a fatal suppression finding, and the review lane's budgets job now reaches that step. The hook is still reached the same way; the carrier type says what the cast means. `pnpm quality` → exit 0.
…e host tests register their temp dirs Two unit contracts went red on the merge candidate and nowhere else: - ablation-flags-never-ship: PRD-859's TN_PLAYER_PRIORITY was read with std::getenv in engine/player/run.cpp, around the flags.h list PRD-840 put there. Declared Read::Live beside PlayerVsync and read through flags::read. - temp-dir-guard: embedded-script-enum, host-cli and host-window called mkdtempSync directly. They now use test-support/temp-dir.ts, which registers the cleanup the guard asks for.
build-ios-simulator only uploaded artifacts/ios after the verify step succeeded, so a failed launch threw away the log that says why: variant-web-ui.log is written by the throw itself. The evidence upload now also runs when an earlier step failed, and warns instead of failing when an early failure left nothing to upload.
The desktop capture verifier assembled its failure from stderr, which is an empty string rather than null when the runner says nothing, so every failed capture read 'runner failed: (empty stderr)' with no status and no pointer to artifacts/native/starter-desktop.log. PRD-840 AC-2 records the native half as still uncaptured; PRD-842 records the second build-ios-simulator run's real first failure (the web-ui variant's main-frame navigation neither finishing nor failing) and the evidence upload that now survives a failed step.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Status
The untangle batch (report): one owner per
value, so a change lands in one place and drift goes red. One PR for the batch, as the owner asked.
prd:100%docs/PRDs/done/prd:100%renderfolds intorendererwithTN_GAME_RENDER_KEY_RENAMEDprd:100%42533915867: 25 of 25 job names identical to the last comparable rungame.tsstops being the hubprd:100%prd:50%web-ui-missing-bundledoes not logTN_UI_BUNDLE_MISSINGprd:75%What this head adds over the last push
defineGametakesrendereronly; the portable block that wasrendermerged into it, and the retired key throwsTN_GAME_RENDER_KEY_RENAMEDnaming the fieldmapping. The 16 kits, the examples and the guides migrate; the scaffold is re-pinned.
RenderFeatures, oneflags.h, one CMake renderer link line and therenderer.cppsplit merged in.origin/developmerged (PRD-859, the threaded-engine startup fixes, the asset MCP pin), withthe scaffold re-pinned.
Found and fixed here, not asked for
@threenative/core/render/environmentwas broken.PRD-833 moved the module to
src/render-environment.ts, but the native player bundles source andread the last path segment as the file name, so it asked for
src/environment.tsand the builddied with
Cannot read file.coreSourcePathnow resolves the subpath through the package's ownexportsmap, andtests/core-subpath-source.test.mjswalks every declared subpath. Before thefix, the starter's
pnpm build:desktopfailed; after it, both capture arms build.rendererkeys after the fold; it is one object now, with the kit'santialias default where the config leaves it unset.
frame-op-stream.js's generatedOP_*names are exempt from the naming rule (they come fromframe-ops.json), andnative-config-keys.jsonis formatted, sopnpm lintis 0 errors.Verification run for this push (local, on this head)
pnpm typecheck→ 0 errors.pnpm lint→ 0 errors (2138 pre-existing warnings).npx vitest run packages/core/__tests__→ 4626 passed, 4 skipped.npx vitest run packages/playtest/__tests__→ 1974 passed.pnpm native:build→ exit 0;pnpm wasm:build→ exit 0.pnpm native:verify:desktop→ exit 0: desktop core gate 300 frames at 1280x720,native contract lane passed: 56 of 56 targets, audio/loading/physics/UI-frame proofs and the three host vitestfiles (23 passed).
pnpm scaffold:pin --check→ current;pnpm ci:fast→ agents, docs, lint, drift pass;pnpm check:docs→ 3813 links across 1637 files.pnpm parityon both arms — web 154/154 cases the same status, desktop 152/154 with onetiming-bound swap each way; the visual judge (fresh read-only
reviewer, two runs per arm,BEFORE/AFTER burned in) returned NEUTRAL on all five criteria, cross-arm RMSE 0.000598 against
a 0.000563 same-arm noise.
Not run to green, and why
load 25-50 on 24 cores;
bench:enginesrecordedhost load: 25.97 on 24 cores, absolutes invalid-absolute, so a frame-time A/B here is not evidence. An arm run did start and draw on theWasm engine at the real adapter, so what is missing is a quiet host (or CI's benchmark job).
TN_NATIVE_STARTER_SMOKE: runner failed:(empty stderr) on both arms afterpnpm build:desktop,and a direct playtest
--target desktoprun reaches the engine player(
TN_PLAYER_FIRST_PRESENT: runtime v8) but reportsframes: 0and no screenshot. The web half isjudged NEUTRAL; the renderer split is exercised by that same C++ renderer compiled for web.
release-proofrun built the simulator app and passedsix of seven launch checks; the seventh (
web-ui-missing-bundle) did not logTN_UI_BUNDLE_MISSING. Objective-C++ andxcrunare macOS-only, so the fix needs that lane.test-unit (1/1)is red with no failing test, twice. On headsd674d4f00and8bebd2f92the review lane's "Run impacted unit contracts" step printed passing specs, then its log ends
3.5 minutes before the step fails; the full
testjob on the same heads is green. The impact setis nearly the whole suite because this PR touches 596 files, and the earlier run showed
gh: server errorfrom a spec shelling out to the API. This needs the CI-harness owners: either thelane's timeout/output path or the spec that speaks to
gh.pnpm visualsstill cannot exit 0 on any branch: the model scores indocs/verification/visuals/scores.jsonmiss 10 kits and hold five below the floor. Owner input.