Skip to content

Commit f9b7ee7

Browse files
committed
Improve checkout raster commerce corroboration
1 parent d759d54 commit f9b7ee7

File tree

4 files changed

+78
-5
lines changed

4 files changed

+78
-5
lines changed

docs/AI_DESIGN_SYSTEM_ROADMAP.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ Current status:
119119
- local semantic cue families now also separate editor/canvas, catalog/store, profile/community, activity/feed, document/review, map/navigation, media/player, capture/scan, schedule/calendar, commerce/checkout, secure-access, support/help, and rewards/loyalty screenshots from those broader buckets, reducing more note/filename-driven non-OCR false positives without bundling built-in model dependencies
120120
- screenshot analysis now persists semantic-family labels plus confidence for those local cue families, and stronger raster-only ambiguity guards reject weak special-family matches when generic settings/control evidence dominates
121121
- screenshot analysis now also persists semantic-family rationale, competing family candidates, and review-needed flags so weak local matches are easier to inspect before they steer planning
122-
- raster-family structural scoring now also helps more distinctive non-OCR profile/document/editor/catalog/map/media/capture layouts plus support/help-style list flows resolve into the right semantic family without OCR text, and stronger settings/paywall ambiguity guards now block more weak profile/reward/commerce family overreads from filenames or terse notes alone
122+
- raster-family structural scoring now also helps more distinctive non-OCR profile/document/editor/catalog/map/media/capture layouts plus support/help-style list flows resolve into the right semantic family without OCR text, surfaces checkout-style summary/price-rail rows as stronger reviewed commerce contenders, and stronger settings/paywall ambiguity guards still block more weak profile/reward/commerce family overreads from filenames or terse notes alone
123123
- preview sessions now support manual semantic-family override/reset with session persistence, surfaced rationale/ambiguity diagnostics, and bulk family-review actions for flagged screenshots, so borderline local screenshot classification can be corrected faster during review without adding a built-in model dependency
124124
- reviewed semantic-family state can now also feed forward into deterministic replanning/materialization through `appframe_plan_variant_set` reviewed-analysis input and `appframe_rebuild_autopilot_session_from_review`, so saved review metadata is no longer preview-only
125125
- variant plans now emit explicit per-concept frame strategies plus per-screen/per-frame crop plans, including text-occupied-region avoidance and focal-point anchoring

docs/NEXT_STEPS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ AppFrame now has an initial autopilot pipeline implemented:
6161
- screenshot analysis now also broadens deterministic non-OCR understanding for workflow/action and discovery/browse screens, and local ambiguity guards reduce some raster-only false positives where wide panels previously collapsed into settings or reporting
6262
- screenshot analysis now also uses stronger local cue families for editor/canvas, catalog/store, profile/community, activity/feed, document/review, map/navigation, media/player, capture/scan, schedule/calendar, commerce/checkout, secure-access, support/help, and rewards/loyalty screenshots, widening deterministic understanding and cutting more raster-only settings/reporting/editor/media/paywall false positives without bundling built-in model dependencies
6363
- screenshot analysis now persists explicit semantic-family metadata plus confidence for those local cue families, and stricter raster-only ambiguity guards keep generic settings/control surfaces from over-triggering special family treatments off weak filename/note cues alone
64-
- screenshot analysis now also uses broader raster-family structural scoring for more distinctive non-OCR profile/document/editor/catalog/map/media/capture-like layouts, now gives support/help-style list flows stronger raster corroboration, and keeps checkout/paywall ambiguity more conservative so weak profile/reward/commerce hints do not override generic control or premium CTA structure as often
64+
- screenshot analysis now also uses broader raster-family structural scoring for more distinctive non-OCR profile/document/editor/catalog/map/media/capture-like layouts, now gives support/help-style list flows stronger raster corroboration, surfaces checkout-style summary/price-rail rows as stronger reviewed commerce contenders, and keeps checkout/paywall ambiguity conservative so weak profile/reward/commerce hints do not override generic control or premium CTA structure as often
6565
- dynamic individual planning/materialization now reacts more explicitly to onboarding, paywall, settings, chat, and reporting-style screens with role-aware composition/background strategies instead of only generic frameStrategy/cropPlan behavior
6666
- dynamic individual planning/materialization now also reacts more explicitly to workflow and discovery screens with dedicated composition/background treatments instead of folding them back into generic proof-grid behavior
6767
- dynamic planning/materialization now also reacts more explicitly to editor/profile/catalog/activity/document/map/media/capture/schedule/commerce/security/support/reward-style screens with dedicated individual backgrounds, copy guidance, family-aware panoramic pacing, and richer panoramic tool-ribbon / profile-spotlight / activity-wave / folio-stack / browse-strip / route-arc / playback-marquee / capture-focus / timeline-band / checkout-lane / trust-shield / support-beacon / reward-ribbon treatments
@@ -262,7 +262,7 @@ Recommended order:
262262
- [x] data-heavy dashboard/reporting
263263
- [x] workflow/action
264264
- [x] discovery/browse/template-library
265-
Status: OCR/layout semantics now improve these cases when text enrichment is available, raster/non-OCR deterministic logic now covers the same families plus workflow/discovery and local editor/profile/catalog/activity/document/map/media/capture/schedule/commerce/security/support/reward cue families, raster-family scoring now helps more structurally distinctive non-OCR profile/document/editor/catalog/map/media/capture screens plus support/help-style list flows resolve into the right semantic family even with generic filenames, and ambiguity guards now cut more settings/reporting/profile/reward/commerce/media/paywall false positives; broader scene-graph understanding is still incomplete.
265+
Status: OCR/layout semantics now improve these cases when text enrichment is available, raster/non-OCR deterministic logic now covers the same families plus workflow/discovery and local editor/profile/catalog/activity/document/map/media/capture/schedule/commerce/security/support/reward cue families, raster-family scoring now helps more structurally distinctive non-OCR profile/document/editor/catalog/map/media/capture screens plus support/help-style list flows resolve into the right semantic family even with generic filenames, checkout-style summary/price-rail rows now surface stronger reviewed commerce contenders, and ambiguity guards still cut more settings/reporting/profile/reward/commerce/media/paywall false positives; broader scene-graph understanding is still incomplete.
266266
- [x] Add raster-only occupied-region heuristics when OCR/text enrichment is absent.
267267
Status: screenshot analysis now infers top/bottom/left/right/center occupancy from local PNG structure, and those regions feed crop avoidance plus copy/planning guidance even without OCR sidecars.
268268
- [x] Add screenshot ordering inference from filenames, timestamps, and roles.

packages/mcp-server/src/tools/design-planning.test.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,6 @@ describe('design planning helpers', () => {
537537
{ path: detailPath, note: 'Order detail and delivery status' },
538538
]);
539539
const settingsAnalysis = analysis.find((entry) => entry.path === settingsPath);
540-
541540
expect(settingsAnalysis?.role).toBe('settings');
542541
expect(settingsAnalysis?.semanticFlavor).toBeUndefined();
543542

@@ -683,6 +682,37 @@ describe('design planning helpers', () => {
683682
expect(supportAnalysis?.semanticFlavorReason?.some((line) => line.includes('raster structure'))).toBe(true);
684683
});
685684

685+
it('surfaces commerce as a reviewed contender for checkout-like raster screens without OCR or descriptive filenames', async () => {
686+
const commercePath = await makePngFile('screen-7.png', 120, 200, (x, y) => {
687+
if (y < 10) return [255, 251, 235, 255];
688+
if (x > 18 && x < 102 && y > 20 && y < 70) return [254, 215, 170, 255];
689+
if (
690+
((x > 18 && x < 90) && (y > 86 && y < 102))
691+
|| ((x > 18 && x < 90) && (y > 110 && y < 126))
692+
) {
693+
return [148, 163, 184, 255];
694+
}
695+
if (
696+
((x > 96 && x < 110) && (y > 86 && y < 102))
697+
|| ((x > 96 && x < 110) && (y > 110 && y < 126))
698+
) {
699+
return [30, 64, 175, 255];
700+
}
701+
if (x > 28 && x < 92 && y > 150 && y < 172) return [37, 99, 235, 255];
702+
return [255, 247, 237, 255];
703+
});
704+
705+
const analysis = await analyzeScreenshotSet([
706+
{ path: commercePath },
707+
]);
708+
709+
const commerceAnalysis = analysis.find((entry) => entry.path === commercePath);
710+
expect(commerceAnalysis?.role).not.toBe('paywall');
711+
expect(commerceAnalysis?.semanticFlavor).not.toBe('support');
712+
expect(commerceAnalysis?.semanticFlavorNeedsReview).toBe(true);
713+
expect(commerceAnalysis?.semanticFlavorAlternatives?.some((entry) => entry.flavor === 'commerce')).toBe(true);
714+
});
715+
686716
it('rejects weak profile and reward family matches when generic settings structure dominates', async () => {
687717
const profileSettingsPath = await makePngFile('screen-4.png', 120, 200, (x, y) => {
688718
if (y < 28) return [248, 250, 252, 255];

packages/mcp-server/src/tools/design-planning.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,7 @@ function inferSemanticFlavorDetails(args: {
780780
const profileScore = (signals.profileSignalCount * 2)
781781
+ (args.role === 'detail' || args.role === 'communication' || args.role === 'discovery' ? 1 : 0)
782782
+ rasterFlavorBonus(profileRasterScore)
783+
+ (profileRasterScore >= 4 ? 1 : 0)
783784
+ (profileRasterScore > activityRasterScore ? 1 : 0)
784785
- (signals.settingsConflictCount >= 2 ? 3 : signals.settingsConflictCount);
785786
const editorScore = (signals.editorSignalCount * 2)
@@ -796,6 +797,7 @@ function inferSemanticFlavorDetails(args: {
796797
? (signals.documentSignalCount * 2)
797798
+ (args.role === 'detail' ? 2 : args.role === 'workflow' ? 1 : 0)
798799
+ rasterFlavorBonus(documentRasterScore)
800+
+ (documentRasterScore >= 5 ? 1 : 0)
799801
+ (signals.scheduleSignalCount >= 1 ? 1 : 0)
800802
- Math.min(2, signals.reportingConflictCount)
801803
- Math.min(1, signals.editorSignalCount)
@@ -804,6 +806,7 @@ function inferSemanticFlavorDetails(args: {
804806
- Math.min(1, signals.paywallConflictCount)
805807
: ((args.role === 'detail' ? 2 : args.role === 'workflow' ? 1 : 0)
806808
+ rasterFlavorBonus(documentRasterScore)
809+
+ (documentRasterScore >= 5 ? 1 : 0)
807810
- (editorRasterScore > documentRasterScore ? 2 : 0));
808811
const mapScore = (signals.mapSignalCount * 2)
809812
+ (args.role === 'discovery' || args.role === 'home' ? 2 : args.role === 'detail' ? 1 : 0)
@@ -819,7 +822,9 @@ function inferSemanticFlavorDetails(args: {
819822
+ (args.role === 'detail' || args.role === 'workflow' ? 2 : args.role === 'discovery' || args.role === 'home' ? 1 : 0)
820823
+ rasterFlavorBonus(commerceRasterScore)
821824
+ (commerceRasterScore >= 6 ? 2 : commerceRasterScore >= 5 ? 1 : 0)
825+
+ (commerceRasterScore >= 6 && (args.role === 'detail' || args.role === 'workflow') ? 2 : commerceRasterScore >= 6 ? 1 : 0)
822826
+ (commerceRasterScore > scheduleRasterScore ? 1 : 0)
827+
+ (commerceRasterScore > supportRasterScore ? 2 : 0)
823828
+ (signals.catalogSignalCount >= 1 ? 1 : 0)
824829
- (signals.paywallConflictCount > signals.commerceSignalCount && commerceRasterScore < 6 ? 2 : 0)
825830
- Math.min(1, signals.settingsConflictCount);
@@ -2634,6 +2639,7 @@ function inferRasterSemanticSignals(args: {
26342639
let feedRows = 0;
26352640
let upperHeroPanelRows = 0;
26362641
let agendaRows = 0;
2642+
let priceRailRows = 0;
26372643
let previousBubbleSide: 'left' | 'right' | null = null;
26382644

26392645
for (let row = 0; row < args.blockRows; row += 1) {
@@ -2731,6 +2737,36 @@ function inferRasterSemanticSignals(args: {
27312737
) {
27322738
agendaRows += 1;
27332739
}
2740+
2741+
if (
2742+
segments.length === 3
2743+
&& rowCenter >= 0.22
2744+
&& rowCenter <= 0.86
2745+
&& segments[0]!.start <= 1
2746+
&& segments[0]!.width >= 1
2747+
&& segments[0]!.width <= 2
2748+
&& segments[1]!.width >= 3
2749+
&& segments[1]!.width <= 7
2750+
&& segments[2]!.end >= args.blockColumns - 2
2751+
&& segments[2]!.width >= 1
2752+
&& segments[2]!.width <= 2
2753+
) {
2754+
priceRailRows += 1;
2755+
}
2756+
2757+
if (
2758+
segments.length === 2
2759+
&& rowCenter >= 0.22
2760+
&& rowCenter <= 0.86
2761+
&& segments[0]!.start <= 2
2762+
&& segments[0]!.width >= 5
2763+
&& segments[0]!.end <= args.blockColumns - 3
2764+
&& segments[1]!.end >= args.blockColumns - 2
2765+
&& segments[1]!.width >= 1
2766+
&& segments[1]!.width <= 2
2767+
) {
2768+
priceRailRows += 1;
2769+
}
27342770
}
27352771

27362772
const occupiedRegions = mergeOccupiedRegions(
@@ -2869,10 +2905,15 @@ function inferRasterSemanticSignals(args: {
28692905
+ (splitRows >= 2 ? 1 : 0)
28702906
);
28712907
const commerceFlavorScore = (
2872-
(agendaRows >= 3 ? 2 : agendaRows >= 2 ? 1 : 0)
2908+
(agendaRows >= 4 ? 3 : agendaRows >= 3 ? 2 : agendaRows >= 2 ? 1 : 0)
2909+
+ (priceRailRows >= 3 ? 3 : priceRailRows >= 2 ? 2 : priceRailRows >= 1 ? 1 : 0)
28732910
+ (lowerCtaRows >= 1 ? 2 : 0)
28742911
+ (upperHeroPanelRows >= 2 ? 1 : 0)
28752912
+ (topInsetBarRows >= 1 ? 1 : 0)
2913+
+ (agendaRows >= 2 && centeredPanelRows >= 3 ? 1 : 0)
2914+
+ (agendaRows >= 2 && centeredPanelRows >= 3 && lowerCtaRows >= 1 ? 2 : 0)
2915+
+ (agendaRows >= 2 && fullWidthRows >= 2 ? 1 : 0)
2916+
- (agendaRows <= 1 && args.averageLuminance <= 148 ? 1 : 0)
28762917
);
28772918
const securityFlavorScore = (
28782919
(centeredPanelRows >= 4 ? 2 : centeredPanelRows >= 3 ? 1 : 0)
@@ -2891,6 +2932,8 @@ function inferRasterSemanticSignals(args: {
28912932
+ (feedRows <= 2 ? 1 : 0)
28922933
+ (cardGridRows <= 1 ? 1 : 0)
28932934
+ (splitRows >= 2 ? 1 : 0)
2935+
- (priceRailRows >= 1 ? 2 : 0)
2936+
- (agendaRows >= 2 && centeredPanelRows >= 3 && lowerCtaRows >= 1 ? 2 : 0)
28942937
);
28952938
const rewardFlavorScore = (
28962939
(upperHeroPanelRows >= 3 ? 2 : upperHeroPanelRows >= 2 ? 1 : 0)

0 commit comments

Comments
 (0)