Skip to content

Commit 228dcd7

Browse files
feat: super-productivity asserting journey GREEN both lanes — all pins measured-true
Drove executeAngularSuperProductivityWitnessRun end-to-end on both bound lanes RED-first, correcting five pins only to measured values: taskLists 2→1 (done list only mounts with a completed task); leg-d checkbox counted after the collapsible expand; theme.control → mat-select[id*=huePrimary] (bare selector matched all 3 hue selects; numeric prefix 17/15 unstable across lanes); trackEvents re-armed after the leg-e reload (page.reload destroys the tracking global); and the behavior-digest projection aligned to properties-only so Material's pre-MDC→MDC geometry deltas (header 48/56, side-nav 199/196, all CSS properties equal) don't break parity. Both lanes pass, pageErrors 0, 4 navigations, shared digest a38d983e (equality also proves per-run determinism); the split regression is gone under the full drive. Geometry-invariance test added; calibration note written. 2099/2099.
1 parent d0d0909 commit 228dcd7

6 files changed

Lines changed: 296 additions & 11 deletions

File tree

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
{
2+
"schemaVersion": "versionless.angular-super-productivity-asserting-journey-green.v1",
3+
"unit": "lrapr-t006/u20c2q-asserting-journey-green",
4+
"consentId": "VL-LEGACY-CORPUS-2026-08-10",
5+
"result": "asserting-journey-drives-green-both-lanes-one-shared-behavior-digest",
6+
"supersedes": {
7+
"record": "none",
8+
"note": "This is not a build record and rebuilds nothing. It records the calibration of the five-leg ASSERTING witness journey (executeAngularSuperProductivityWitnessRun) against the two bound lanes, and every JOURNEY pin the asserting run corrected from a value the calibration driver had only measured, not asserted."
9+
},
10+
"premise": {
11+
"found": "a5366f7 added the runner scaffolding and found the asserting journey RED-fails at boot (taskLists=2). The 'five legs green' claim came from the CALIBRATION driver, not the asserting journey, so every JOURNEY pin needed validation against a real asserting run.",
12+
"method": "RED-first drive of the real asserting journey on baseline dist-run2 AND migrated dist-25, each pin the asserting run contradicted corrected ONLY to the measured value, measured on both lanes.",
13+
"lanes": {
14+
"baseline": ".versionless/cache/angular-super-productivity-v2-13-15-baseline/dist-run2",
15+
"migrated": ".versionless/stage/angular-super-productivity-v2-13-15-u18b/dist-25"
16+
},
17+
"driver": "packages/cli/src/fixture/angular-super-productivity-u20c2q-drive.ts (asserting drive) + angular-super-productivity-u20c2q-dom-probe.ts (raw-DOM measurement of leg-d theme section)"
18+
},
19+
"pinCorrections": [
20+
{
21+
"pin": "WITNESS_ANGULAR_SUPER_PRODUCTIVITY_JOURNEY.taskLists",
22+
"from": 2,
23+
"to": 1,
24+
"measuredOn": ["baseline", "migrated"],
25+
"measurement": "the asserting boot assertion read exactly 1 `task-list` element throughout on both lanes; the done-tasks list is a second `task-list` the work view mounts only once a task is marked done, which this journey never does.",
26+
"kind": "app-shape-fact-pin-correction",
27+
"recordedComment": "receipts constant + drive-side comment + assertion string + wiring test updated"
28+
},
29+
{
30+
"pin": "leg-(d) drive order: count(theme.autoContrastControl) vs page.click(theme.expandControl)",
31+
"from": "counted the theme-section mat-checkbox BEFORE expanding the collapsible section",
32+
"to": "count AFTER the expand",
33+
"measuredOn": ["baseline", "migrated"],
34+
"measurement": "the config-section is a collapsible whose body is not in the DOM while collapsed; the asserting drive read 0 checkboxes before the expand and 1 after, on both lanes. The calibration driver already expanded before reading; the asserting journey had the two steps out of order.",
35+
"kind": "drive-order-correction (real-app-run.ts)"
36+
},
37+
{
38+
"pin": "WITNESS_ANGULAR_SUPER_PRODUCTIVITY_SETTINGS.theme.control and JOURNEY.settingsChange.theme.control",
39+
"from": "section.config-section:nth-of-type(2) mat-select",
40+
"to": "section.config-section:nth-of-type(2) mat-select[id*=\"huePrimary\"]",
41+
"measuredOn": ["baseline", "migrated"],
42+
"measurement": "unchecking isAutoContrast reveals THREE hue selects (huePrimary, hueAccent, hueWarn); the bare `mat-select` selector matched 3, not 1. formly stamps the field key into a stable id substring — `formly_17_select_huePrimary_4` (era) / `formly_15_select_huePrimary_4` (migrated); the numeric prefix differs by lane, the `huePrimary` substring does not — so `mat-select[id*=\"huePrimary\"]` uniquely resolves the primary control whose threshold moves `--palette-primary-contrast-50`.",
43+
"kind": "mis-calibrated-selector-correction"
44+
},
45+
{
46+
"pin": "leg-(e) drive: event tracking across the document reload",
47+
"from": "trackEvents armed once at boot; the final outcome assertion observed 0 input and 0 keydown",
48+
"to": "re-arm page.trackEvents('click','input','keydown') immediately after page.reload()",
49+
"measuredOn": ["baseline", "migrated"],
50+
"measurement": "a full document reload replaces the page and destroys the witness event-tracking global (syncTrackedEvents reads the CURRENT global). Re-arming after the reload makes leg-(d)'s genuine input (typing the new project title) and keydown (the `w` shortcut), both after the reload, the occurrences the end-of-journey outcome assertion measures. Not a navigation; the navigations=4 pin is unchanged.",
51+
"kind": "drive-correction (real-app-run.ts)"
52+
},
53+
{
54+
"pin": "witnessAngularSuperProductivityBehaviorDigest renderedStyleProjection: probe geometry",
55+
"from": "the shared behavior digest folded in each agreeing probe's full geometry (width/height)",
56+
"to": "the digest projects only each agreeing probe's {label, selector, properties}",
57+
"measuredOn": ["baseline", "migrated"],
58+
"measurement": "with all four other legs green, the two lanes' behavior digests diverged on exactly one field: renderedStyles.agreeing. Every CSS property both probes read resolved identically, but the Angular Material pre-MDC->MDC lift moves the main-header geometry (height 48 era / 56 migrated; width 1080 / 1083) and the scrollbar-driven side-nav width (199 / 196). The schema's own rendered-style parity (assertRenderedStyleDifferences) compares `properties` alone, and the declared-difference mechanism can only speak about a probe whose properties differ — these probes' properties agree, so they cannot be declared. The geometry is lane-dependent rendered appearance, not behaviour; the digest is aligned to the schema's properties-only parity definition. Geometry stays in the run and assertRenderedStyles still bounds it non-negative per probe.",
59+
"kind": "digest-projection-alignment (packages/core, properties-only, matching assertRenderedStyleDifferences)",
60+
"notADeclaredDifference": "side-navigation is the typeface anchor (WITNESS_ANGULAR_SUPER_PRODUCTIVITY_TYPEFACE_PROBE) and its font-family agrees across lanes; it must NOT be a declared difference, and its properties agree, so declaring it was both forbidden and impossible."
61+
}
62+
],
63+
"legsDrivenGreen": [
64+
"(a) create a task through the app's own add-task bar into today's list (not the backlog)",
65+
"(b) genuine dragula reorder reversing the created pair, store agreeing with the rendered list",
66+
"(c) header play-button timer flip play_arrow->pause->play_arrow with one current task then cleared",
67+
"(d) settings-change: second project created + switched (title flips), huePrimary threshold driven to flip --palette-primary-contrast-50 dark->light, `w` shortcut back to the work view",
68+
"(e) real document reload rehydrating the two tasks in drag-settled order from IndexedDB, key census grown by the four default-project state documents"
69+
],
70+
"finalGreenMeasurements": {
71+
"sharedBehaviorDigest": "a38d983e921fd5dec9e3d18e0726d75f3c011deea1b389ffd0d4291c3f26f8b8",
72+
"behaviorDigestParity": "baseline == migrated (identical; lane-to-lane equality also proves the digest carries no per-run nondeterminism)",
73+
"baseline": {
74+
"result": "pass",
75+
"cleanPage": true,
76+
"pageErrors": 0,
77+
"consoleErrors": 0,
78+
"failedRequests": 0,
79+
"successfulNonLoopback": 0,
80+
"routes": ["/#/work-view", "/#/work-view", "/#/project-settings", "/#/work-view"],
81+
"rawDigest": "08adced8fcaaa8ad14f4196c7f5e1b6d06a46dd5fe9c2ebb64217c2fe26de5c0"
82+
},
83+
"migrated": {
84+
"result": "pass",
85+
"cleanPage": true,
86+
"pageErrors": 0,
87+
"consoleErrors": 0,
88+
"failedRequests": 0,
89+
"successfulNonLoopback": 0,
90+
"routes": ["/#/work-view", "/#/work-view", "/#/project-settings", "/#/work-view"],
91+
"rawDigest": "91ed08ee84073cffc5b920b782d1b836963c864b0e4e6f0a3786afa6d68a932d"
92+
},
93+
"rawDigestNote": "rawDigests differ by construction — the two lanes' byte inventories are eight majors of bundler apart; only the lane-independent behavior digest is required to agree, and it does."
94+
},
95+
"migratedLaneRegressionStatus": {
96+
"regression": "the u20c2a split.component Ivy-input-order TypeError (classList)",
97+
"status": "gone on the served dist-25",
98+
"evidence": "the migrated asserting journey drove all five legs with pageErrors 0 and cleanPage true — the template-binding-reorder capability (u20c2c) that u20c2e proved on the rebuilt dist-25 holds under the full asserting drive."
99+
},
100+
"declaredPerLaneDifferencesUnchanged": [
101+
"typeface anchored on side-navigation resolves 'Roboto, sans-serif' identically in both lanes; the two font-family style differences (header-icon-button, document-body) stay in WITNESS_ANGULAR_SUPER_PRODUCTIVITY_MEASURED_STYLE_DIFFERENCES",
102+
"leg-(d) theme rgb format is per-lane (baseline bare triple '0,0,0'->'255,255,255'; migrated 'rgba(0, 0, 0, .87)'->'rgba(255, 255, 255, 1)') — only the FACT of the shift travels in the behavior digest"
103+
],
104+
"notEstablished": [
105+
"This unit publishes no witness receipt; the deliverable is the green asserting journey, the corrected pins and this calibration record. The publish is the next unit.",
106+
"The asserting journey was driven pass 1 on each lane by the u20c2q driver; the lane-to-lane behavior-digest equality demonstrates freedom from per-run nondeterminism, which is what a second pass would otherwise establish."
107+
]
108+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/**
2+
* The Super Productivity ASSERTING-journey drive (u20c2q).
3+
*
4+
* Unlike the calibration driver, this launches the real asserting journey
5+
* `executeAngularSuperProductivityWitnessRun` against BOTH bound lanes and
6+
* prints, per lane: whether it drove to green, the page-error count, the raw
7+
* and behavior digests, and — on a RED — the assertion message, which carries
8+
* the measured reading the pin disagreed with.
9+
*
10+
* It publishes nothing and is not part of any receipt. Its only output is
11+
* stdout; it is how each JOURNEY pin is calibrated against a real asserting run.
12+
*/
13+
14+
import { writeFileSync } from 'node:fs';
15+
import { basename, join, resolve } from 'pathe';
16+
import { canonicalize } from '../../../core/src/receipts/canonicalize.ts';
17+
import {
18+
WITNESS_ANGULAR_SUPER_PRODUCTIVITY_MEASURED_STYLE_DIFFERENCES,
19+
witnessAngularSuperProductivityBehaviorDigest,
20+
witnessAngularSuperProductivityRawDigest,
21+
type WitnessAngularSuperProductivityRun,
22+
} from '../../../core/src/receipts/witness-angular-super-productivity.ts';
23+
import { executeAngularSuperProductivityWitnessRun } from '../witness/real-app-run.ts';
24+
25+
const root = resolve(import.meta.dirname, '../../../..');
26+
27+
const laneRoots = {
28+
baseline: join(
29+
root,
30+
'.versionless/cache/angular-super-productivity-v2-13-15-baseline/dist-run2',
31+
),
32+
migrated: join(root, '.versionless/stage/angular-super-productivity-v2-13-15-u18b/dist-25'),
33+
} as const;
34+
35+
const declaredDifferenceLabels = WITNESS_ANGULAR_SUPER_PRODUCTIVITY_MEASURED_STYLE_DIFFERENCES.map(
36+
(difference) => difference.label,
37+
);
38+
39+
async function driveLane(
40+
lane: 'baseline' | 'migrated',
41+
pass: 1 | 2,
42+
): Promise<void> {
43+
process.stdout.write(`\n===== ${lane} pass ${pass} =====\n`);
44+
try {
45+
const raw = await executeAngularSuperProductivityWitnessRun({
46+
lane,
47+
pass,
48+
laneRoot: laneRoots[lane],
49+
receiptRoot: join(root, '.versionless/stage/witness-super-productivity-u20c2q/receipts'),
50+
});
51+
const run = raw as WitnessAngularSuperProductivityRun;
52+
const rawDigest = witnessAngularSuperProductivityRawDigest(run);
53+
const behaviorDigest = witnessAngularSuperProductivityBehaviorDigest(
54+
run,
55+
declaredDifferenceLabels,
56+
);
57+
if (process.env.SP_DUMP)
58+
writeFileSync(
59+
join(process.env.SP_DUMP, `${lane}-run.json`),
60+
`${canonicalize(run)}\n`,
61+
);
62+
process.stdout.write(
63+
`${canonicalize({
64+
result: run.result,
65+
cleanPage: run.cleanPage,
66+
pageErrors: run.witnessRecord.pageErrors,
67+
consoleErrors: run.witnessRecord.consoleErrors,
68+
failedRequests: run.witnessRecord.failedRequests,
69+
successfulNonLoopback: run.successfulNonLoopback,
70+
routes: run.routes,
71+
rawDigest,
72+
behaviorDigest,
73+
})}\n`,
74+
);
75+
} catch (error) {
76+
process.stdout.write(
77+
`RED: ${error instanceof Error ? error.message : String(error)}\n`,
78+
);
79+
if (error instanceof Error && error.stack) process.stdout.write(`${error.stack}\n`);
80+
}
81+
}
82+
83+
export async function main(args = process.argv.slice(2)): Promise<void> {
84+
const only = args[0] as 'baseline' | 'migrated' | undefined;
85+
const lanes: ReadonlyArray<'baseline' | 'migrated'> =
86+
only === 'baseline' || only === 'migrated' ? [only] : ['baseline', 'migrated'];
87+
for (const lane of lanes) await driveLane(lane, 1);
88+
}
89+
90+
if (basename(process.argv[1] ?? '') === 'angular-super-productivity-u20c2q-drive.ts')
91+
main().catch((error: unknown) => {
92+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
93+
process.exitCode = 1;
94+
});

packages/cli/src/witness/real-app-run.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5374,8 +5374,9 @@ const angularSuperProductivitySpec: AppSpec = {
53745374
await page.trackEvents('click', 'input', 'keydown');
53755375

53765376
// The application as it boots: the work view's own host tag — `work-view`,
5377-
// not the component's file name — its two task lists, and no task in
5378-
// either of them. Nothing has been seeded; this application starts empty.
5377+
// not the component's file name — its one task list (the undone list; the
5378+
// done list only mounts once a task is completed, which this journey never
5379+
// does), and no task in it. Nothing has been seeded; this app starts empty.
53795380
await context.expect.page.count(page, SUPER_PRODUCTIVITY_JOURNEY.hostTag, 1);
53805381
await context.expect.page.count(
53815382
page,
@@ -5473,6 +5474,14 @@ const angularSuperProductivitySpec: AppSpec = {
54735474
// store, and what comes back — read off the re-rendered list — is the store
54745475
// list, which is what makes it the store's own agreement with the drag.
54755476
await page.reload();
5477+
// The reload replaces the document, so the event tracking armed at boot is
5478+
// gone with it (the witness stores tracked occurrences in a page global that
5479+
// a full reload destroys, and the outcome sync reads the CURRENT global).
5480+
// Re-arm it here so leg (d)'s genuine input and keydown — typing the new
5481+
// project's title and pressing the `w` shortcut, both after this reload — are
5482+
// the occurrences the end-of-journey outcome assertion measures. This is not
5483+
// a navigation and does not change the pinned navigation count.
5484+
await page.trackEvents('click', 'input', 'keydown');
54765485
await context.expect.page.count(page, SUPER_PRODUCTIVITY_JOURNEY.taskListTask, 2);
54775486
const storeOrderAfter = await readOrder();
54785487
if (canonicalize(storeOrderAfter) !== canonicalize(renderedOrderAfter))
@@ -5571,11 +5580,16 @@ const angularSuperProductivitySpec: AppSpec = {
55715580
// Into the current project's settings through the header control, and the theme
55725581
// config-section expanded so its own controls render. The scroll on this route
55735582
// is measured like every other stage; the application pins its drawer container
5574-
// to the viewport here too, so it records as absence.
5583+
// to the viewport here too, so it records as absence. The auto-contrast
5584+
// checkbox is counted AFTER the expand, not before: the config-section is a
5585+
// collapsible whose body is not in the DOM while it is collapsed (measured
5586+
// u20c2q — the asserting drive read 0 for the checkbox before the expand and 1
5587+
// after, on both lanes), so the assertion that the theme section carries its
5588+
// one checkbox is the post-expand reading.
55755589
await page.click(settingsChange.settingsNav);
5576-
await context.expect.page.count(page, settingsChange.theme.autoContrastControl, 1);
55775590
await measure('/#/project-settings (the settings-change leg)');
55785591
await page.click(settingsChange.theme.expandControl);
5592+
await context.expect.page.count(page, settingsChange.theme.autoContrastControl, 1);
55795593

55805594
// The before-read: the contrast custom property as it resolves under the
55815595
// default auto-contrast theme — a dark contrast.
@@ -5699,7 +5713,7 @@ const angularSuperProductivitySpec: AppSpec = {
56995713
};
57005714
return {
57015715
assertions: [
5702-
'the work view rendered on the application own declared `#/work-view` route, under its own `work-view` host tag, with two task lists and no task in either',
5716+
'the work view rendered on the application own declared `#/work-view` route, under its own `work-view` host tag, with one task list and no task in it',
57035717
'a task created through the application own add-task bar by typing a title and committing it with Enter, landing in today list rather than in the backlog',
57045718
'the created task rendered in the task list with the typed title read back off the page',
57055719
'a second task created the same way, the two rendering first-created on top, which is the order leg (b) reorders from',

packages/cli/test/witness-angular-super-productivity-run.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ describe('the two journey legs', () => {
197197
expect(journey.taskListTask.startsWith(`${journey.taskList} `)).toBe(true);
198198
expect(journey.taskTitle.startsWith(`${journey.taskListTask} `)).toBe(true);
199199
expect(journey.taskTitleText.length).toBeGreaterThan(0);
200-
expect(journey.taskLists).toBe(2);
200+
expect(journey.taskLists).toBe(1);
201201
});
202202
});
203203

0 commit comments

Comments
 (0)