diff --git a/docs/review/device-qa/README.md b/docs/review/device-qa/README.md index fd1fcbf..f87449a 100644 --- a/docs/review/device-qa/README.md +++ b/docs/review/device-qa/README.md @@ -286,5 +286,15 @@ Each note records one fact about bytes or draw calls already on main. None of th | [expansion-gate-2026-11-05.md](expansion-gate-2026-11-05.md) | The expansion gate, computed | | [draw-pass-2026-11-05.md](draw-pass-2026-11-05.md) | The world pass, in call order | | [device-sample-2026-11-05.md](device-sample-2026-11-05.md) | The phone sample, beside the frames | +| [playtest-gates-2026-11-05.md](playtest-gates-2026-11-05.md) | The playtest gates, five and four | +| [device-run-gates-2026-11-05.md](device-run-gates-2026-11-05.md) | The device-run gates, and the nil atlas | +| [peak-density-2026-11-05.md](peak-density-2026-11-05.md) | The peak the profiler keeps | +| [ceiling-status-2026-11-05.md](ceiling-status-2026-11-05.md) | The ceiling, measured then settled | +| [replay-matrix-2026-11-05.md](replay-matrix-2026-11-05.md) | The replay matrix, three times | +| [asset-intake-2026-11-05.md](asset-intake-2026-11-05.md) | The intake, against the files | +| [bundle-filter-2026-11-05.md](bundle-filter-2026-11-05.md) | The bundle, reachable ids | +| [pacing-window-2026-11-05.md](pacing-window-2026-11-05.md) | The pacing windows | +| [env-groups-2026-11-05.md](env-groups-2026-11-05.md) | A group, fully backed | +| [seam-checks-2026-11-05.md](seam-checks-2026-11-05.md) | The seam checks | Next session: follow [retest-checklist.md](retest-checklist.md) (D-105 allows device checks on any build). diff --git a/docs/review/device-qa/asset-intake-2026-11-05.md b/docs/review/device-qa/asset-intake-2026-11-05.md new file mode 100644 index 0000000..e535358 --- /dev/null +++ b/docs/review/device-qa/asset-intake-2026-11-05.md @@ -0,0 +1,15 @@ +# Asset intake + +Read 2026-11-05 from `AssetIntake.validate` on `ef68565`. No file was hashed. + +The catalog refusal stays in [catalog-gate-2026-11-05.md](catalog-gate-2026-11-05.md). + +`PNGHeader.parse` returns nil when the data is shorter than 26 bytes, the first 8 bytes are not the PNG signature, bytes 12 through 15 are not `IHDR`, or the width or height is below 1. Width is the big-endian integer at bytes 16 through 19. Height is the big-endian integer at bytes 20 through 23. The color type is byte 25. + +A runtime path that starts with `ArtSources/` appends `artSourcesInRuntimePath`. An accepted record with an empty runtime path appends `acceptedWithoutFile`. An accepted `.png` path that fails the delivery grammar appends `invalidDeliveryName`. A delivery name ends in `.png`, has an `@` in the stem, a scale of digits that starts at 1 through 9 and ends in `x`, and at least two `_` parts. The first character is lowercase or a digit. Each part is non-empty and uses letters and digits. + +Records whose source starts with `ArtSources/` are read under the evidence root. A missing file appends `missingEvidenceFile`. A size at or below 0 appends `emptyFile`. A recorded sha256 that already belongs to another asset id appends `duplicateHash`. The file bytes are not hashed. A `.png` whose header does not parse appends `emptyFile`. Recorded dimensions that differ from the header append `dimensionMismatch`. A recorded color space other than `sRGB` appends `colorSpace`. Color type 4 or 6 with recorded alpha `opaque` appends `colorSpace`. + +Regular files under `ArtSources/legacy-evidence`, other than `README.md`, append `undeclaredEvidenceFile` when that relative path is not one of the declared sources. + +This does not admit an asset. diff --git a/docs/review/device-qa/bundle-filter-2026-11-05.md b/docs/review/device-qa/bundle-filter-2026-11-05.md new file mode 100644 index 0000000..77e1dbb --- /dev/null +++ b/docs/review/device-qa/bundle-filter-2026-11-05.md @@ -0,0 +1,15 @@ +# Bundle filter + +Read 2026-11-05 from `RuntimeBundleFilter.project` on `ef68565`. No asset was added. + +The admission shapes stay in [catalog-gate-2026-11-05.md](catalog-gate-2026-11-05.md). The clip frame ids stay in [clip-gate-2026-11-05.md](clip-gate-2026-11-05.md). + +`reachableAssetIds` is the presentation contract's `requiredAssetIds`, `audioEventIds`, and `musicAssetIds`, plus `environmentAssetIds` when that array is present. It also includes every `frameIds` entry in `clip-metadata-001`. An absent environment array contributes nothing. + +An entry is bundle-eligible when its decision is `plannedOriginal`, `adaptedAdmitted`, or `originalAccepted`, it is runtime-required, its id is reachable, and its runtime path does not start with `ArtSources/`. `project` sorts the eligible ids and the excluded ids. + +`validate` appends `duplicateBundleAsset` for a repeated eligible id. An ineligible entry whose decision is outside those three, and which has a runtime path or is runtime-required, appends `legacyEvidenceInBundle`. That same entry appends `nonSanFranciscoInBundle` when the id contains `_atlanta_` or the decision is `excluded`, and a runtime path is present. A runtime-required entry in the three decisions whose id is not reachable appends `unreachableRuntimeRequired`. A runtime path that starts with `ArtSources/` appends `sourceEvidenceInBundle`. + +`PresentationAssetRegistry.bundled` stores that projection's ids, and copies the three presentation arrays from `presentation-assets-003`. `require` throws `unreachable` when the id is not in the bundle list. + +This does not admit an asset. diff --git a/docs/review/device-qa/ceiling-status-2026-11-05.md b/docs/review/device-qa/ceiling-status-2026-11-05.md new file mode 100644 index 0000000..74b383f --- /dev/null +++ b/docs/review/device-qa/ceiling-status-2026-11-05.md @@ -0,0 +1,11 @@ +# Ceiling status + +Read 2026-11-05 from `D021Ceilings.fromSimulation` on `ef68565`. No ceiling was changed. + +The scenarios that feed it stay in [peak-density-2026-11-05.md](peak-density-2026-11-05.md). The byte fields that settle a device run stay in [device-run-gates-2026-11-05.md](device-run-gates-2026-11-05.md). The expansion decision stays in [expansion-gate-2026-11-05.md](expansion-gate-2026-11-05.md). + +The schema is `d021-ceilings-001`. `fromSimulation` copies the report's aggregate peaks and sets the status to `simulationMeasured`. Resident bytes and atlas bytes stay nil, so `isSettled` is false. `withDeviceProfiling` stores both byte counts and sets the status to `settled`. `pendingDeviceProfiling` is the third status string. + +`metricsWithinCeilings` requires each of the seven peaks to be at most the stored ceiling. `sampleWithinSimulationCeilings` uses the same seven comparisons on one sample. `gateC011PassesSimulationBounds` requires every scenario in the report to sit within the ceilings. + +This does not settle a device. diff --git a/docs/review/device-qa/device-run-gates-2026-11-05.md b/docs/review/device-qa/device-run-gates-2026-11-05.md new file mode 100644 index 0000000..f4921c6 --- /dev/null +++ b/docs/review/device-qa/device-run-gates-2026-11-05.md @@ -0,0 +1,13 @@ +# Device-run gates + +Read 2026-11-05 from `DeviceRunEvidence.gateResults` on `ef68565`. No gate was changed. + +The filename stays in [evidence-names-2026-11-05.md](evidence-names-2026-11-05.md). Gate C's thresholds stay in [frame-times-2026-11-05.md](frame-times-2026-11-05.md). The phone sample stays in [device-sample-2026-11-05.md](device-sample-2026-11-05.md). The streak stays in [run-streak-2026-11-05.md](run-streak-2026-11-05.md). The three-success bundle stays in [retest-checklist.md](retest-checklist.md). + +The schema is `device-run-evidence-001`. The task id is `T905`. `performanceFloor` counts a thermal state of `serious` or `critical` as one event, and every other string as zero. Its device-class parameter defaults to the string `iPhone 12`. The session call passes `hardwareModel`. + +`C-001` passes when the consecutive count is at least 3, frame time passes Gate C, memory warnings are 0, and thermal events are 0. `C-002`, `C-003`, `C-004`, `C-005`, and `C-006` pass when frame time passes Gate C. `C-007` passes when thermal events are 0. The source on each record is `deviceCapture`. + +`settledD021Ceilings` returns nil unless both resident bytes and atlas bytes are present. When both are present it returns the simulation ceilings after `withDeviceProfiling`. The session passes nil for the atlas bytes. The detached task returns before `exportReleaseCandidateWithBundledPlaytests` when those settled ceilings are nil. + +This does not label a phone. diff --git a/docs/review/device-qa/env-groups-2026-11-05.md b/docs/review/device-qa/env-groups-2026-11-05.md new file mode 100644 index 0000000..da46265 --- /dev/null +++ b/docs/review/device-qa/env-groups-2026-11-05.md @@ -0,0 +1,13 @@ +# Environment groups + +Read 2026-11-05 from `EnvironmentLibrary.isBacked` on `ef68565`. No texture was replaced. + +Nearest filtering stays in [env-filter-2026-11-05.md](env-filter-2026-11-05.md). The ground ids stay in [tiled-planes-2026-11-02.md](tiled-planes-2026-11-02.md). Clip backing stays in [frame-backing-2026-11-05.md](frame-backing-2026-11-05.md). + +The groups are `env_ground_`, `env_solid_`, `env_camera_`, `env_camera_captain_`, `env_prop_`, `env_motif_`, and `env_fog_`. The group of an id is the longest matching prefix, so a captain id is `captain` rather than `camera`. `isBacked` is true when the group has at least one declared id and every one of them has a delivered path. `path` returns nil unless that group is backed. + +A solid id `solid-04-civic-west` becomes `env_solid_04_civic_west`, by prefixing `env_` and replacing each `-` with `_`. The housing ids are `env_camera_municipal_dome`, `env_camera_storefront`, `env_camera_traffic_reader`, `env_camera_ornamental_civic`, and `env_camera_temporary_mast`. + +`bundled` reads `environmentAssetIds` from `presentation-assets-003`, or an empty list when that array is absent. It stores a path only for a declared id whose decision is `adaptedAdmitted` or `originalAccepted` and which has a runtime path. `coverage` counts delivered keys that are also declared, over the declared count. + +This does not replace a texture. diff --git a/docs/review/device-qa/pacing-window-2026-11-05.md b/docs/review/device-qa/pacing-window-2026-11-05.md new file mode 100644 index 0000000..58deac8 --- /dev/null +++ b/docs/review/device-qa/pacing-window-2026-11-05.md @@ -0,0 +1,11 @@ +# Pacing window + +Read 2026-11-05 from `PacingTimeline.observe` on `ef68565`. No window was changed. + +The zone names stay in [tiled-planes-2026-11-02.md](tiled-planes-2026-11-02.md). The tick rate stays on `SimulationClock.ticksPerSecond`, which is 60. + +This type does not write simulation state. `spawnAlley` starts at tick 0. A later observe records a segment only on its first start. `cameraCorridor` starts when the player zone is `Z-02`. `civicPlaza` starts on `waveStarted` for `M-A`, `pressureRoute` on `M-B`, and `lockdownRing` on `M-C`. `captainCourt` starts on `bossActivated`. `extraction` starts on `extractionArmed`. `endTick` is the first `runSucceeded`. + +Start seconds are the start tick divided by 60. `segmentsOffTarget` includes a segment that never started, and a segment whose start second, after `rounded()`, is outside its window. The windows are `spawnAlley` 0 through 5, `cameraCorridor` 5 through 30, `civicPlaza` 30 through 65, `pressureRoute` 65 through 110, `lockdownRing` 110 through 240, `captainCourt` 240 through 330, and `extraction` 330 through 360. `runWithinTarget` is nil until `runSucceeded`, and then it is whether that end second, after `rounded()`, is inside 300 through 480. + +This does not close T903 or T904. diff --git a/docs/review/device-qa/peak-density-2026-11-05.md b/docs/review/device-qa/peak-density-2026-11-05.md new file mode 100644 index 0000000..468a0f5 --- /dev/null +++ b/docs/review/device-qa/peak-density-2026-11-05.md @@ -0,0 +1,15 @@ +# Peak density + +Read 2026-11-05 from `PeakDensityProfiler.profile` on `ef68565`. No ceiling was changed. + +The digest prefix on the release-candidate filename stays in [evidence-names-2026-11-05.md](evidence-names-2026-11-05.md). `totalLive` on a phone sample stays in [device-sample-2026-11-05.md](device-sample-2026-11-05.md). + +`profile` runs one complete-run scenario for each upgrade, under the key `complete-run-`, then `civic-pool-stress`. The report schema is `peak-density-001`. Each scenario keeps the max of cameras, enemies, projectiles, mines, civic-pool live, allocator next, and `totalLive`. Those maxes are independent. The aggregate is the same field-wise max across the scenarios. Canonical scenario keys are sorted. + +A complete run uses `Simulation.make(seed: 1)`. It samples, completes encounter `M-A`, samples, arms upgrade selection, samples, steps a command whose axes are 0 and whose upgrade index is that upgrade, samples, completes the combat graph, samples, steps a neutral command, samples, places the player on the extraction center, and samples after every later neutral step while the outcome is `playing`. + +The stress run uses seed 1, completes `M-A`, selects `ricochetPulse`, completes the combat graph, and fills the civic pool to `PerformanceThresholds.civicPoolCapacity`. It then takes 120 steps with `moveX` 32767, `moveY` 0, and dodge clear, and samples after each step. The full-stick limit stays in [player-movement-2026-11-04.md](player-movement-2026-11-04.md). + +Ordinary play does not call `profile`. + +This does not change a pool. diff --git a/docs/review/device-qa/playtest-gates-2026-11-05.md b/docs/review/device-qa/playtest-gates-2026-11-05.md new file mode 100644 index 0000000..072a17a --- /dev/null +++ b/docs/review/device-qa/playtest-gates-2026-11-05.md @@ -0,0 +1,11 @@ +# Playtest gates + +Read 2026-11-05 from `PlaytestEvidence.gateResults` on `ef68565`. No gate count was changed. + +The file load stays in [playtest-load-2026-11-05.md](playtest-load-2026-11-05.md). The directory stays in [evidence-names-2026-11-05.md](evidence-names-2026-11-05.md). + +The schema is `playtest-evidence-001`. For `T903`, `G-001` passes when the session count is at least 5 and at least 4 sessions completed onboarding without instruction. `G-002` passes when the session count is at least 5 and at least 4 sessions described exposure correctly. For `T904`, `G-004` passes when the session count is at least 5 and at least 3 sessions began a voluntary replay. Any other task id returns an empty list. The source on each of those records is `playtest`. + +The canonical session stores `competentRunDurationMinutes` as the integer of `rounded()`, or null when the minutes are absent. + +This does not close T903 or T904. diff --git a/docs/review/device-qa/replay-matrix-2026-11-05.md b/docs/review/device-qa/replay-matrix-2026-11-05.md new file mode 100644 index 0000000..0152bd7 --- /dev/null +++ b/docs/review/device-qa/replay-matrix-2026-11-05.md @@ -0,0 +1,13 @@ +# Replay matrix + +Read 2026-11-05 from `ReplayMatrix.tripleRunDigest` on `ef68565`. No digest was changed. + +The envelope load stays in [replay-commands-2026-11-04.md](replay-commands-2026-11-04.md). + +The fixture version is `replay-matrix-001`. `load` requires that version and an `entries` array. Each entry needs an id, a fixture name, and an `expectedFinalDigest` of 64 characters. `tripleRunRequired` is the bool on the entry, or true when the value is absent or not a bool. + +`execute` loads the fixture. When that envelope's expected digest is nil, the run uses the entry's digest, and an `invalid` outcome throws `digestMismatch` with the result digest. When the envelope already carries an expected digest, a result digest that differs from the entry's digest throws `digestMismatch`. A failed execute throws `executionFailed`. + +`tripleRunDigest` runs `execute` three times. It throws `tripleRunMismatch` unless the three digests are equal, and then it returns that digest. + +This does not change a fixture. diff --git a/docs/review/device-qa/seam-checks-2026-11-05.md b/docs/review/device-qa/seam-checks-2026-11-05.md new file mode 100644 index 0000000..cef6dc8 --- /dev/null +++ b/docs/review/device-qa/seam-checks-2026-11-05.md @@ -0,0 +1,15 @@ +# Seam checks + +Read 2026-11-05 from `CivicSeamIdentity` on `ef68565`. No zone was moved. + +The seven zone names stay in [tiled-planes-2026-11-02.md](tiled-planes-2026-11-02.md). Bundle issues stay in [bundle-filter-2026-11-05.md](bundle-filter-2026-11-05.md). + +`zoneNamesMatchContract` requires each of those ids to carry that table's name on the manifest. The spine landmarks are `Z-02`, `Z-03`, `Z-06`, and `Z-07`. + +`threeGridCollision` requires the court to share the plaza's y and sit to its east, the service zone to sit north and east of the plaza, and the service zone to sit north and east of the spawn. `wedgeParcels` requires `Z-01` and `Z-04` each to have a half-size whose x differs from its y. `landmarkSightlines` requires the plaza east of transit, the court east of the plaza, the plaza north of transit, the court on the plaza's y, and Phoenix south of the court on the court's x. + +The prohibited labels are `golden gate`, `sutro`, `karl`, `market street`, `civic center`, `soma`, `chinatown`, and `cable car`. The label check lowercases the tutorial copy, the supplied captions, and the zone names, and rejects a string that contains one of those labels. The default captions are `Phoenix Steps open`. + +`catalogRejectsLiteralLandmarks` requires `legacy_san_francisco_landmark_bridge_distant_01` to be `rejected` with a nil runtime path. The content audit adds `literal-bridge-not-rejected` when that fails. It adds a token for each bundle issue. A runtime path whose id contains `_atlanta_` adds `non-sf-runtime-`. A runtime path whose id contains `landmark_bridge`, `_seal_`, or `_logo_` adds `prohibited-runtime-`. Notes that contain `copied artwork`, on a record with a runtime path, add `copied-artwork-runtime-`. The audit list is sorted. + +This does not close T802 or T807.