@tangle-network/browser-agent-driver 0.30.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-ack-patch.d.ts +39 -0
- package/dist/cli-ack-patch.d.ts.map +1 -0
- package/dist/cli-ack-patch.js +47 -0
- package/dist/cli-ack-patch.js.map +1 -0
- package/dist/cli-design-audit.d.ts +12 -0
- package/dist/cli-design-audit.d.ts.map +1 -1
- package/dist/cli-design-audit.js +88 -0
- package/dist/cli-design-audit.js.map +1 -1
- package/dist/cli-jobs.d.ts +13 -0
- package/dist/cli-jobs.d.ts.map +1 -0
- package/dist/cli-jobs.js +262 -0
- package/dist/cli-jobs.js.map +1 -0
- package/dist/cli-patterns.d.ts +26 -0
- package/dist/cli-patterns.d.ts.map +1 -0
- package/dist/cli-patterns.js +49 -0
- package/dist/cli-patterns.js.map +1 -0
- package/dist/cli-reports.d.ts +12 -0
- package/dist/cli-reports.d.ts.map +1 -0
- package/dist/cli-reports.js +97 -0
- package/dist/cli-reports.js.map +1 -0
- package/dist/cli.js +29 -1
- package/dist/cli.js.map +1 -1
- package/dist/design/audit/attribution/aggregate.d.ts +16 -0
- package/dist/design/audit/attribution/aggregate.d.ts.map +1 -0
- package/dist/design/audit/attribution/aggregate.js +81 -0
- package/dist/design/audit/attribution/aggregate.js.map +1 -0
- package/dist/design/audit/attribution/store.d.ts +36 -0
- package/dist/design/audit/attribution/store.d.ts.map +1 -0
- package/dist/design/audit/attribution/store.js +108 -0
- package/dist/design/audit/attribution/store.js.map +1 -0
- package/dist/design/audit/attribution/types.d.ts +13 -0
- package/dist/design/audit/attribution/types.d.ts.map +1 -0
- package/dist/design/audit/attribution/types.js +10 -0
- package/dist/design/audit/attribution/types.js.map +1 -0
- package/dist/design/audit/classify-ensemble.d.ts +46 -0
- package/dist/design/audit/classify-ensemble.d.ts.map +1 -0
- package/dist/design/audit/classify-ensemble.js +207 -0
- package/dist/design/audit/classify-ensemble.js.map +1 -0
- package/dist/design/audit/ethics/check.d.ts +59 -0
- package/dist/design/audit/ethics/check.d.ts.map +1 -0
- package/dist/design/audit/ethics/check.js +137 -0
- package/dist/design/audit/ethics/check.js.map +1 -0
- package/dist/design/audit/ethics/loader.d.ts +21 -0
- package/dist/design/audit/ethics/loader.d.ts.map +1 -0
- package/dist/design/audit/ethics/loader.js +207 -0
- package/dist/design/audit/ethics/loader.js.map +1 -0
- package/dist/design/audit/ethics/rules/finance.yaml +37 -0
- package/dist/design/audit/ethics/rules/kids.yaml +37 -0
- package/dist/design/audit/ethics/rules/legal.yaml +35 -0
- package/dist/design/audit/ethics/rules/medical.yaml +36 -0
- package/dist/design/audit/evaluate.d.ts.map +1 -1
- package/dist/design/audit/evaluate.js +4 -1
- package/dist/design/audit/evaluate.js.map +1 -1
- package/dist/design/audit/first-principles-mode.d.ts +42 -0
- package/dist/design/audit/first-principles-mode.d.ts.map +1 -0
- package/dist/design/audit/first-principles-mode.js +77 -0
- package/dist/design/audit/first-principles-mode.js.map +1 -0
- package/dist/design/audit/modality/android.d.ts +14 -0
- package/dist/design/audit/modality/android.d.ts.map +1 -0
- package/dist/design/audit/modality/android.js +18 -0
- package/dist/design/audit/modality/android.js.map +1 -0
- package/dist/design/audit/modality/html.d.ts +22 -0
- package/dist/design/audit/modality/html.d.ts.map +1 -0
- package/dist/design/audit/modality/html.js +51 -0
- package/dist/design/audit/modality/html.js.map +1 -0
- package/dist/design/audit/modality/index.d.ts +8 -0
- package/dist/design/audit/modality/index.d.ts.map +1 -0
- package/dist/design/audit/modality/index.js +15 -0
- package/dist/design/audit/modality/index.js.map +1 -0
- package/dist/design/audit/modality/ios.d.ts +16 -0
- package/dist/design/audit/modality/ios.d.ts.map +1 -0
- package/dist/design/audit/modality/ios.js +19 -0
- package/dist/design/audit/modality/ios.js.map +1 -0
- package/dist/design/audit/modality/types.d.ts +9 -0
- package/dist/design/audit/modality/types.d.ts.map +1 -0
- package/dist/design/audit/modality/types.js +9 -0
- package/dist/design/audit/modality/types.js.map +1 -0
- package/dist/design/audit/patches/index.d.ts +8 -0
- package/dist/design/audit/patches/index.d.ts.map +1 -0
- package/dist/design/audit/patches/index.js +5 -0
- package/dist/design/audit/patches/index.js.map +1 -0
- package/dist/design/audit/patches/parse.d.ts +29 -0
- package/dist/design/audit/patches/parse.d.ts.map +1 -0
- package/dist/design/audit/patches/parse.js +153 -0
- package/dist/design/audit/patches/parse.js.map +1 -0
- package/dist/design/audit/patches/render.d.ts +20 -0
- package/dist/design/audit/patches/render.d.ts.map +1 -0
- package/dist/design/audit/patches/render.js +55 -0
- package/dist/design/audit/patches/render.js.map +1 -0
- package/dist/design/audit/patches/severity-enforcement.d.ts +23 -0
- package/dist/design/audit/patches/severity-enforcement.d.ts.map +1 -0
- package/dist/design/audit/patches/severity-enforcement.js +42 -0
- package/dist/design/audit/patches/severity-enforcement.js.map +1 -0
- package/dist/design/audit/patches/validate.d.ts +34 -0
- package/dist/design/audit/patches/validate.d.ts.map +1 -0
- package/dist/design/audit/patches/validate.js +53 -0
- package/dist/design/audit/patches/validate.js.map +1 -0
- package/dist/design/audit/patterns/match.d.ts +24 -0
- package/dist/design/audit/patterns/match.d.ts.map +1 -0
- package/dist/design/audit/patterns/match.js +48 -0
- package/dist/design/audit/patterns/match.js.map +1 -0
- package/dist/design/audit/patterns/mine.d.ts +31 -0
- package/dist/design/audit/patterns/mine.d.ts.map +1 -0
- package/dist/design/audit/patterns/mine.js +35 -0
- package/dist/design/audit/patterns/mine.js.map +1 -0
- package/dist/design/audit/patterns/store.d.ts +14 -0
- package/dist/design/audit/patterns/store.d.ts.map +1 -0
- package/dist/design/audit/patterns/store.js +53 -0
- package/dist/design/audit/patterns/store.js.map +1 -0
- package/dist/design/audit/patterns/types.d.ts +53 -0
- package/dist/design/audit/patterns/types.d.ts.map +1 -0
- package/dist/design/audit/patterns/types.js +13 -0
- package/dist/design/audit/patterns/types.js.map +1 -0
- package/dist/design/audit/pipeline.d.ts +12 -0
- package/dist/design/audit/pipeline.d.ts.map +1 -1
- package/dist/design/audit/pipeline.js +65 -3
- package/dist/design/audit/pipeline.js.map +1 -1
- package/dist/design/audit/rubric/anchor-loader.d.ts +44 -0
- package/dist/design/audit/rubric/anchor-loader.d.ts.map +1 -0
- package/dist/design/audit/rubric/anchor-loader.js +210 -0
- package/dist/design/audit/rubric/anchor-loader.js.map +1 -0
- package/dist/design/audit/rubric/anchors/blog.yaml +33 -0
- package/dist/design/audit/rubric/anchors/dashboard.yaml +35 -0
- package/dist/design/audit/rubric/anchors/docs.yaml +35 -0
- package/dist/design/audit/rubric/anchors/ecommerce.yaml +33 -0
- package/dist/design/audit/rubric/anchors/marketing.yaml +34 -0
- package/dist/design/audit/rubric/anchors/saas-app.yaml +38 -0
- package/dist/design/audit/rubric/anchors/social.yaml +33 -0
- package/dist/design/audit/rubric/anchors/tool.yaml +33 -0
- package/dist/design/audit/rubric/anchors/utility.yaml +33 -0
- package/dist/design/audit/rubric/fragments/audience-clinician.md +42 -0
- package/dist/design/audit/rubric/fragments/audience-developer.md +40 -0
- package/dist/design/audit/rubric/fragments/audience-kids.md +35 -0
- package/dist/design/audit/rubric/fragments/audience-vulnerability-minor-facing.md +37 -0
- package/dist/design/audit/rubric/fragments/first-principles.md +65 -0
- package/dist/design/audit/rubric/fragments/modality-mobile.md +39 -0
- package/dist/design/audit/rubric/fragments/modality-tablet.md +35 -0
- package/dist/design/audit/rubric/fragments/regulatory-coppa.md +32 -0
- package/dist/design/audit/rubric/fragments/regulatory-gdpr.md +33 -0
- package/dist/design/audit/rubric/fragments/regulatory-hipaa.md +36 -0
- package/dist/design/audit/rubric/loader.d.ts +26 -6
- package/dist/design/audit/rubric/loader.d.ts.map +1 -1
- package/dist/design/audit/rubric/loader.js +45 -26
- package/dist/design/audit/rubric/loader.js.map +1 -1
- package/dist/design/audit/rubric/rollup-weights.d.ts +25 -0
- package/dist/design/audit/rubric/rollup-weights.d.ts.map +1 -0
- package/dist/design/audit/rubric/rollup-weights.js +51 -0
- package/dist/design/audit/rubric/rollup-weights.js.map +1 -0
- package/dist/design/audit/types.d.ts +28 -0
- package/dist/design/audit/types.d.ts.map +1 -1
- package/dist/design/audit/v2/build-result.d.ts +47 -0
- package/dist/design/audit/v2/build-result.d.ts.map +1 -0
- package/dist/design/audit/v2/build-result.js +163 -0
- package/dist/design/audit/v2/build-result.js.map +1 -0
- package/dist/design/audit/v2/score.d.ts +49 -0
- package/dist/design/audit/v2/score.d.ts.map +1 -0
- package/dist/design/audit/v2/score.js +211 -0
- package/dist/design/audit/v2/score.js.map +1 -0
- package/dist/design/audit/v2/types.d.ts +431 -0
- package/dist/design/audit/v2/types.d.ts.map +1 -0
- package/dist/design/audit/v2/types.js +26 -0
- package/dist/design/audit/v2/types.js.map +1 -0
- package/dist/discover/index.d.ts +16 -0
- package/dist/discover/index.d.ts.map +1 -0
- package/dist/discover/index.js +25 -0
- package/dist/discover/index.js.map +1 -0
- package/dist/discover/wayback.d.ts +49 -0
- package/dist/discover/wayback.d.ts.map +1 -0
- package/dist/discover/wayback.js +123 -0
- package/dist/discover/wayback.js.map +1 -0
- package/dist/jobs/anti-bot.d.ts +19 -0
- package/dist/jobs/anti-bot.d.ts.map +1 -0
- package/dist/jobs/anti-bot.js +64 -0
- package/dist/jobs/anti-bot.js.map +1 -0
- package/dist/jobs/cost-estimate.d.ts +12 -0
- package/dist/jobs/cost-estimate.d.ts.map +1 -0
- package/dist/jobs/cost-estimate.js +21 -0
- package/dist/jobs/cost-estimate.js.map +1 -0
- package/dist/jobs/cost-history.d.ts +19 -0
- package/dist/jobs/cost-history.d.ts.map +1 -0
- package/dist/jobs/cost-history.js +42 -0
- package/dist/jobs/cost-history.js.map +1 -0
- package/dist/jobs/index.d.ts +31 -0
- package/dist/jobs/index.d.ts.map +1 -0
- package/dist/jobs/index.js +37 -0
- package/dist/jobs/index.js.map +1 -0
- package/dist/jobs/orchestrator.d.ts +42 -0
- package/dist/jobs/orchestrator.d.ts.map +1 -0
- package/dist/jobs/orchestrator.js +282 -0
- package/dist/jobs/orchestrator.js.map +1 -0
- package/dist/jobs/queue.d.ts +45 -0
- package/dist/jobs/queue.d.ts.map +1 -0
- package/dist/jobs/queue.js +114 -0
- package/dist/jobs/queue.js.map +1 -0
- package/dist/jobs/retry.d.ts +36 -0
- package/dist/jobs/retry.d.ts.map +1 -0
- package/dist/jobs/retry.js +77 -0
- package/dist/jobs/retry.js.map +1 -0
- package/dist/jobs/store.d.ts +31 -0
- package/dist/jobs/store.d.ts.map +1 -0
- package/dist/jobs/store.js +92 -0
- package/dist/jobs/store.js.map +1 -0
- package/dist/jobs/types.d.ts +106 -0
- package/dist/jobs/types.d.ts.map +1 -0
- package/dist/jobs/types.js +13 -0
- package/dist/jobs/types.js.map +1 -0
- package/dist/reports/aggregate.d.ts +38 -0
- package/dist/reports/aggregate.d.ts.map +1 -0
- package/dist/reports/aggregate.js +145 -0
- package/dist/reports/aggregate.js.map +1 -0
- package/dist/reports/index.d.ts +21 -0
- package/dist/reports/index.d.ts.map +1 -0
- package/dist/reports/index.js +15 -0
- package/dist/reports/index.js.map +1 -0
- package/dist/reports/narrate.d.ts +19 -0
- package/dist/reports/narrate.d.ts.map +1 -0
- package/dist/reports/narrate.js +40 -0
- package/dist/reports/narrate.js.map +1 -0
- package/dist/reports/templates.d.ts +43 -0
- package/dist/reports/templates.d.ts.map +1 -0
- package/dist/reports/templates.js +200 -0
- package/dist/reports/templates.js.map +1 -0
- package/dist/reports/tokens.d.ts +77 -0
- package/dist/reports/tokens.d.ts.map +1 -0
- package/dist/reports/tokens.js +88 -0
- package/dist/reports/tokens.js.map +1 -0
- package/dist/reports/tools.d.ts +76 -0
- package/dist/reports/tools.d.ts.map +1 -0
- package/dist/reports/tools.js +205 -0
- package/dist/reports/tools.js.map +1 -0
- package/dist/reports/types.d.ts +51 -0
- package/dist/reports/types.d.ts.map +1 -0
- package/dist/reports/types.js +9 -0
- package/dist/reports/types.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: audience-kids
|
|
3
|
+
title: Kids Audience
|
|
4
|
+
weight: critical
|
|
5
|
+
applies-when:
|
|
6
|
+
audience: [kids]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
This surface is used by or targeted at minors. Apply the following additional
|
|
10
|
+
lens. Note: ethics rules in Layer 7 enforce hard score floors independently
|
|
11
|
+
of rubric scoring — both layers apply simultaneously.
|
|
12
|
+
|
|
13
|
+
AGE-APPROPRIATE LANGUAGE AND IMAGERY
|
|
14
|
+
- Copy must be readable at the stated age level. Technical jargon, legalese,
|
|
15
|
+
or implicit social pressure ("Your friends are waiting!") are major findings
|
|
16
|
+
in `content_ia`.
|
|
17
|
+
- Imagery should be appropriate for the age group. Mature themes, even subtle
|
|
18
|
+
ones, are critical findings in `trust_clarity`.
|
|
19
|
+
|
|
20
|
+
FRICTION-SYMMETRIC FLOWS
|
|
21
|
+
- Actions that benefit the operator (in-app purchase, data sharing, account
|
|
22
|
+
creation) must have equal or greater friction than their reversal
|
|
23
|
+
(cancellation, data deletion, account closure).
|
|
24
|
+
- Any flow where it is easier to spend money / share data than to undo is a
|
|
25
|
+
critical finding in `workflow`.
|
|
26
|
+
|
|
27
|
+
PARENTAL CONTROLS VISIBILITY
|
|
28
|
+
- If the app collects data from minors, parental consent or control mechanisms
|
|
29
|
+
must be visible without buried navigation. If absent: major finding in
|
|
30
|
+
`trust_clarity`.
|
|
31
|
+
|
|
32
|
+
DO NOT penalize for:
|
|
33
|
+
- Simplified language and larger touch targets
|
|
34
|
+
- Reduced information density appropriate to age
|
|
35
|
+
- Bright color palettes and playful illustration styles
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: audience-vulnerability-minor-facing
|
|
3
|
+
title: Minor-Facing Audience Vulnerability
|
|
4
|
+
weight: critical
|
|
5
|
+
applies-when:
|
|
6
|
+
audienceVulnerability: [minor-facing]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
This surface directly interacts with users who are minors or who are
|
|
10
|
+
unaccompanied minors in a supervised context (e.g. school software, children's
|
|
11
|
+
gaming, education platforms). The vulnerability is that the minor may not fully
|
|
12
|
+
understand consent, financial consequence, or data implications. Apply this
|
|
13
|
+
lens in addition to audience-kids and regulatory-coppa fragments.
|
|
14
|
+
|
|
15
|
+
DARK PATTERN PROHIBITION — ENFORCED
|
|
16
|
+
Every dark pattern is a critical finding when directed at minors. Dark patterns
|
|
17
|
+
to look for:
|
|
18
|
+
- Confirmshaming ("No thanks, I don't want to save money")
|
|
19
|
+
- Fake urgency ("Only 2 left! Timer expires in 03:42")
|
|
20
|
+
- Hidden costs revealed at final checkout step
|
|
21
|
+
- Forced continuity (subscription auto-enrolled without explicit confirmation)
|
|
22
|
+
- Misdirection (styled "X" button that is actually an ad click)
|
|
23
|
+
|
|
24
|
+
IRREVERSIBILITY DISCLOSURE
|
|
25
|
+
- Any action that is irreversible (purchase, deletion, sharing to others) must
|
|
26
|
+
be labeled explicitly. "Delete" without "This cannot be undone" is a major
|
|
27
|
+
finding in `trust_clarity`.
|
|
28
|
+
|
|
29
|
+
SOCIAL COMPARISON AS PRESSURE
|
|
30
|
+
- Leaderboards, "Your friends have X" notifications, or streak-loss warnings
|
|
31
|
+
designed to create anxiety are major `trust_clarity` findings when the
|
|
32
|
+
audience is minors.
|
|
33
|
+
|
|
34
|
+
REPORTING AND BLOCKING CONTROLS
|
|
35
|
+
- If the surface allows social interaction (messaging, comments, reactions),
|
|
36
|
+
visible reporting and blocking controls are required. Absent: major finding
|
|
37
|
+
in `trust_clarity`.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: first-principles
|
|
3
|
+
title: First-Principles Fallback
|
|
4
|
+
weight: critical
|
|
5
|
+
applies-when:
|
|
6
|
+
universal: false
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You haven't seen this pattern before. Do not fabricate a classification.
|
|
10
|
+
Audit against the universal product principles only. Score per-dimension as
|
|
11
|
+
usual, but set `rollup.confidence = "low"` and emit a top-level
|
|
12
|
+
`novel_pattern_signal` describing what you observed, so this surface can be
|
|
13
|
+
mined into a new fragment after enough fleet exposure.
|
|
14
|
+
|
|
15
|
+
1. PRIMARY JOB CLARITY (5 sec test)
|
|
16
|
+
- Within 5 seconds, can a stranger name what this page is for?
|
|
17
|
+
- If no: severity major; finding category `product_intent`.
|
|
18
|
+
|
|
19
|
+
2. PRIMARY ACTION OBVIOUSNESS
|
|
20
|
+
- Is there one visually-dominant action this page is built around?
|
|
21
|
+
- Are competing actions visually subordinate?
|
|
22
|
+
- If equal-weight: severity major; finding category `product_intent`.
|
|
23
|
+
|
|
24
|
+
3. STATE PREVIEW
|
|
25
|
+
- Are empty/loading/error states designed, or browser-default / placeholder?
|
|
26
|
+
- Do empty states preview the real product, or show generic illustrations?
|
|
27
|
+
- If generic: severity major; finding category `product_intent`.
|
|
28
|
+
|
|
29
|
+
4. TRUST BEFORE COMMITMENT
|
|
30
|
+
- Does the page ask the user to commit (money, identity, deploy, share)?
|
|
31
|
+
- If yes: are price, permissions, scope, undo path visible BEFORE the
|
|
32
|
+
commit button?
|
|
33
|
+
- If no: severity critical; finding category `trust_clarity`.
|
|
34
|
+
|
|
35
|
+
5. RECOVERY FROM FAILURE
|
|
36
|
+
- Can the user undo their last action?
|
|
37
|
+
- Is there a clear path forward when something fails?
|
|
38
|
+
- If no: severity major; finding category `workflow`.
|
|
39
|
+
|
|
40
|
+
GUARDRAILS:
|
|
41
|
+
- Do not invent domain-specific findings ("this dashboard needs charts").
|
|
42
|
+
You don't know the domain. Stick to the five principles.
|
|
43
|
+
- Do not anchor on marketing-page heuristics (hero copy, illustrations,
|
|
44
|
+
social proof). They don't apply.
|
|
45
|
+
- If a principle simply doesn't apply (e.g. there is no commitment on this
|
|
46
|
+
page), say so explicitly rather than scoring it generically.
|
|
47
|
+
|
|
48
|
+
RESPOND WITH ONLY a JSON object of the form:
|
|
49
|
+
{
|
|
50
|
+
"scores": {
|
|
51
|
+
"product_intent": { "score": <1-10>, "range": [<lo>, <hi>], "confidence": "low", "summary": "<one sentence>", "primaryFindings": [] },
|
|
52
|
+
"visual_craft": { ... },
|
|
53
|
+
"trust_clarity": { ... },
|
|
54
|
+
"workflow": { ... },
|
|
55
|
+
"content_ia": { ... }
|
|
56
|
+
},
|
|
57
|
+
"rollup": { "score": <1-10>, "range": [<lo>, <hi>], "confidence": "low", "rule": "first-principles", "weights": { "product_intent": 0.30, "workflow": 0.25, "visual_craft": 0.20, "content_ia": 0.15, "trust_clarity": 0.10 } },
|
|
58
|
+
"findings": [ ... ],
|
|
59
|
+
"novel_pattern_signal": {
|
|
60
|
+
"observedSignals": [
|
|
61
|
+
{ "label": "<short-label>", "evidence": "<what you saw>", "confidence": <0..1> }
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
"first_principles_mode": true
|
|
65
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: modality-mobile
|
|
3
|
+
title: Mobile Modality
|
|
4
|
+
weight: medium
|
|
5
|
+
applies-when:
|
|
6
|
+
modality: [mobile]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
This surface is evaluated at a mobile viewport (≤480px wide). Apply the
|
|
10
|
+
following lens on top of page-type and domain fragments.
|
|
11
|
+
|
|
12
|
+
TOUCH TARGET SIZING
|
|
13
|
+
- Interactive elements must meet minimum 44×44pt touch targets (WCAG 2.5.5
|
|
14
|
+
AAA; Apple HIG minimum). Anything below 32pt is a major finding in
|
|
15
|
+
`workflow`. Count the number of undersized targets — if >3 on a single
|
|
16
|
+
screen, escalate to critical.
|
|
17
|
+
|
|
18
|
+
THUMB-ZONE REACHABILITY
|
|
19
|
+
- Primary actions must be reachable in the bottom 60% of a 375px screen
|
|
20
|
+
one-handed. A primary CTA pinned to the top of the viewport is a major
|
|
21
|
+
`workflow` finding.
|
|
22
|
+
|
|
23
|
+
HORIZONTAL SCROLL AVOIDANCE
|
|
24
|
+
- Content must not require horizontal scroll on a 375px viewport. Tables
|
|
25
|
+
that overflow without a scroll affordance are major `workflow` findings.
|
|
26
|
+
|
|
27
|
+
FONT LEGIBILITY
|
|
28
|
+
- Body text must be ≥16px (browser zoom notwithstanding). Text smaller than
|
|
29
|
+
14px is a major `visual_craft` finding. Text below 12px is critical.
|
|
30
|
+
|
|
31
|
+
FORM INPUT KEYBOARD
|
|
32
|
+
- Input fields must trigger the appropriate virtual keyboard type (numeric
|
|
33
|
+
for phone/postcode, email for email, tel for phone numbers). Wrong keyboard
|
|
34
|
+
type is a minor `workflow` finding per field.
|
|
35
|
+
|
|
36
|
+
DO NOT penalize for:
|
|
37
|
+
- Navigation patterns specific to mobile (hamburger, bottom tab bar)
|
|
38
|
+
- Reduced visible surface area compared to desktop
|
|
39
|
+
- Single-column layouts
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: modality-tablet
|
|
3
|
+
title: Tablet Modality
|
|
4
|
+
weight: low
|
|
5
|
+
applies-when:
|
|
6
|
+
modality: [tablet]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
This surface is evaluated at a tablet viewport (481–1024px wide). Apply this
|
|
10
|
+
lens on top of page-type and domain fragments.
|
|
11
|
+
|
|
12
|
+
LAYOUT ADAPTATION
|
|
13
|
+
- The layout must actually adapt between mobile and desktop — not simply
|
|
14
|
+
scale a mobile layout or stretch a desktop layout. A layout that is
|
|
15
|
+
identical to either breakpoint is a minor `visual_craft` finding.
|
|
16
|
+
|
|
17
|
+
SPLIT-VIEW AND SIDEBAR OPPORTUNITIES
|
|
18
|
+
- Tablet viewports often benefit from master-detail or sidebar-content
|
|
19
|
+
patterns rather than single-column stacks. If the content hierarchy would
|
|
20
|
+
benefit from a persistent sidebar and none is present, that is a minor
|
|
21
|
+
`workflow` finding.
|
|
22
|
+
|
|
23
|
+
TOUCH AND POINTER HYBRID
|
|
24
|
+
- Tablet users may use touch or pointer. Touch targets must still meet the
|
|
25
|
+
44pt minimum. Hover-only affordances without touch fallbacks are major
|
|
26
|
+
`workflow` findings.
|
|
27
|
+
|
|
28
|
+
LANDSCAPE AND PORTRAIT PARITY
|
|
29
|
+
- Key interactions must work in both orientations. If a primary action is
|
|
30
|
+
unreachable in landscape (below fold with no scroll), that is a major
|
|
31
|
+
`workflow` finding.
|
|
32
|
+
|
|
33
|
+
DO NOT penalize for:
|
|
34
|
+
- Adapting typography slightly smaller than mobile maximums
|
|
35
|
+
- Showing more information density than the mobile equivalent
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: regulatory-coppa
|
|
3
|
+
title: COPPA Regulatory Context
|
|
4
|
+
weight: critical
|
|
5
|
+
applies-when:
|
|
6
|
+
regulatoryContext: [coppa]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
This surface is subject to COPPA (Children's Online Privacy Protection Act).
|
|
10
|
+
Apply this lens when the audience includes or may include users under 13. The
|
|
11
|
+
ethics gate (Layer 7) independently enforces hard score floors for missing
|
|
12
|
+
age gates and dark patterns — both apply simultaneously.
|
|
13
|
+
|
|
14
|
+
VERIFIABLE PARENTAL CONSENT
|
|
15
|
+
- If this surface collects personal data from users who may be under 13,
|
|
16
|
+
a verifiable parental consent mechanism must be visible and functional.
|
|
17
|
+
Absent: critical finding in `trust_clarity`.
|
|
18
|
+
|
|
19
|
+
AGE GATE INTEGRITY
|
|
20
|
+
- Age gates must require date-of-birth entry, not a single yes/no question
|
|
21
|
+
("Are you 13 or older?"). A single-question age gate is a major finding —
|
|
22
|
+
it is trivially bypassed.
|
|
23
|
+
|
|
24
|
+
DATA COLLECTION DISCLOSURE
|
|
25
|
+
- A clear, plain-English summary of what data is collected and why must be
|
|
26
|
+
visible before any data collection begins. Buried in a privacy policy does
|
|
27
|
+
not satisfy this requirement. Absent: major finding in `content_ia`.
|
|
28
|
+
|
|
29
|
+
PROHIBITION ON BEHAVIORAL TARGETING
|
|
30
|
+
- No behavioral advertising or cross-site tracking may be enabled for users
|
|
31
|
+
under 13. If third-party tracking scripts are present without age-based
|
|
32
|
+
gating: critical finding in `trust_clarity`.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: regulatory-gdpr
|
|
3
|
+
title: GDPR Regulatory Context
|
|
4
|
+
weight: high
|
|
5
|
+
applies-when:
|
|
6
|
+
regulatoryContext: [gdpr]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
This surface is subject to GDPR. Apply the following lens in addition to other
|
|
10
|
+
applicable fragments. Note: the ethics gate (Layer 7) independently enforces a
|
|
11
|
+
score floor for missing consent mechanisms — both apply.
|
|
12
|
+
|
|
13
|
+
CONSENT MECHANISM QUALITY
|
|
14
|
+
- Cookie consent banners must offer granular controls (necessary / analytics /
|
|
15
|
+
marketing) with equal visual prominence. An "Accept all" button that is
|
|
16
|
+
larger or more prominent than "Manage preferences" is a major `trust_clarity`
|
|
17
|
+
finding.
|
|
18
|
+
- Pre-ticked checkboxes are a critical finding — they are unlawful under GDPR.
|
|
19
|
+
|
|
20
|
+
DATA SUBJECT RIGHTS ACCESS
|
|
21
|
+
- Users must be able to find their data rights (access, deletion, portability,
|
|
22
|
+
correction) without more than 2 navigation steps from any page. If the
|
|
23
|
+
privacy page is not reachable from the footer, that is a major finding in
|
|
24
|
+
`content_ia`.
|
|
25
|
+
|
|
26
|
+
LEGAL BASIS TRANSPARENCY
|
|
27
|
+
- If the page collects personal data, the legal basis (consent, legitimate
|
|
28
|
+
interest, contract) must be stated. Absent: minor finding in `trust_clarity`.
|
|
29
|
+
|
|
30
|
+
DATA RETENTION
|
|
31
|
+
- If retention periods are disclosed (they should be), they must be
|
|
32
|
+
understandable to a non-lawyer. Legal boilerplate with no plain-English
|
|
33
|
+
summary is a minor finding in `content_ia`.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: regulatory-hipaa
|
|
3
|
+
title: HIPAA Regulatory Context
|
|
4
|
+
weight: high
|
|
5
|
+
applies-when:
|
|
6
|
+
regulatoryContext: [hipaa]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
This surface handles Protected Health Information (PHI) and is subject to HIPAA
|
|
10
|
+
technical safeguards. Apply this lens in addition to domain-specific fragments.
|
|
11
|
+
|
|
12
|
+
SESSION SECURITY VISIBILITY
|
|
13
|
+
- Automatic session timeout must be visible to the user (countdown or clear
|
|
14
|
+
logout trigger). Invisible timeout with hard logout is a major `workflow`
|
|
15
|
+
finding.
|
|
16
|
+
- If the surface shows PHI and has no visible session indicator, that is a
|
|
17
|
+
major `trust_clarity` finding.
|
|
18
|
+
|
|
19
|
+
MINIMUM NECESSARY DATA
|
|
20
|
+
- Only the minimum necessary PHI should be visible on any given screen.
|
|
21
|
+
Dashboards that show full SSN, full DOB, or complete medication histories
|
|
22
|
+
when partial identifiers suffice are major `trust_clarity` findings.
|
|
23
|
+
|
|
24
|
+
AUDIT LOG ACCESS
|
|
25
|
+
- If this surface allows modification of PHI, a visible "audit log" or
|
|
26
|
+
"activity history" link must be accessible to the user. Absent: minor
|
|
27
|
+
finding in `trust_clarity`.
|
|
28
|
+
|
|
29
|
+
DATA EXPORT LABELING
|
|
30
|
+
- Export buttons (CSV, PDF, print) must label the output as PHI with a
|
|
31
|
+
handling reminder. Unlabeled PHI export is a minor finding.
|
|
32
|
+
|
|
33
|
+
DO NOT penalize for:
|
|
34
|
+
- Explicit data masking that adds cognitive load (masks protect PHI)
|
|
35
|
+
- Confirmation dialogs on irreversible PHI operations
|
|
36
|
+
- Conservative color coding that prioritizes legibility over aesthetics
|
|
@@ -6,6 +6,19 @@
|
|
|
6
6
|
* `~/.bad/rubrics/` for user fragments). No code changes required.
|
|
7
7
|
*/
|
|
8
8
|
import type { PageClassification, RubricFragment, ComposedRubric } from '../types.js';
|
|
9
|
+
import type { AudienceTag, ModalityTag, RegulatoryContextTag, AudienceVulnerabilityTag } from '../v2/types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Operator-supplied context for Layer 6 composable predicate matching.
|
|
12
|
+
* When provided, fragments whose `applies-when.audience | modality |
|
|
13
|
+
* regulatoryContext | audienceVulnerability` overlap with these values are
|
|
14
|
+
* included in the composed rubric alongside the classification-matched set.
|
|
15
|
+
*/
|
|
16
|
+
export interface RubricContext {
|
|
17
|
+
audience?: AudienceTag[];
|
|
18
|
+
modality?: ModalityTag[];
|
|
19
|
+
regulatoryContext?: RegulatoryContextTag[];
|
|
20
|
+
audienceVulnerability?: AudienceVulnerabilityTag[];
|
|
21
|
+
}
|
|
9
22
|
/**
|
|
10
23
|
* Parse a markdown fragment file into a RubricFragment.
|
|
11
24
|
* Frontmatter format:
|
|
@@ -25,22 +38,29 @@ export declare function parseFragment(filePath: string): RubricFragment;
|
|
|
25
38
|
*/
|
|
26
39
|
export declare function loadFragments(dir?: string): RubricFragment[];
|
|
27
40
|
/**
|
|
28
|
-
* Predicate evaluator. Returns true if the fragment applies to the classification
|
|
41
|
+
* Predicate evaluator. Returns true if the fragment applies to the classification
|
|
42
|
+
* or the optional Layer 6 context (audience / modality / regulatoryContext /
|
|
43
|
+
* audienceVulnerability hints).
|
|
29
44
|
*
|
|
30
45
|
* Universal fragments always apply.
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* fragment's allowed set.
|
|
46
|
+
* Predicate groups are OR-combined at the group level: a fragment fires if ANY
|
|
47
|
+
* one of its predicate groups matches. Within a group, list membership is used
|
|
48
|
+
* (the classification/context value must appear in the fragment's allowed set).
|
|
49
|
+
*
|
|
50
|
+
* Layer 6 predicates are additive: they can cause a fragment to fire even when
|
|
51
|
+
* no type/domain predicate matches, enabling composition across independent
|
|
52
|
+
* predicate dimensions.
|
|
34
53
|
*/
|
|
35
|
-
export declare function fragmentApplies(fragment: RubricFragment, classification: PageClassification): boolean;
|
|
54
|
+
export declare function fragmentApplies(fragment: RubricFragment, classification: PageClassification, ctx?: RubricContext): boolean;
|
|
36
55
|
/**
|
|
37
56
|
* Compose a rubric from a classification.
|
|
38
57
|
*
|
|
39
58
|
* @param classification - the page classification
|
|
40
59
|
* @param fragments - all loaded fragments (defaults to builtin)
|
|
41
60
|
* @param userFragmentsDir - optional path to user-supplied fragments
|
|
61
|
+
* @param ctx - optional Layer 6 context for audience/modality/regulatory predicates
|
|
42
62
|
*/
|
|
43
|
-
export declare function composeRubric(classification: PageClassification, fragments?: RubricFragment[], userFragmentsDir?: string): ComposedRubric;
|
|
63
|
+
export declare function composeRubric(classification: PageClassification, fragments?: RubricFragment[], userFragmentsDir?: string, ctx?: RubricContext): ComposedRubric;
|
|
44
64
|
/**
|
|
45
65
|
* Compose a rubric from an explicit profile name (for `--profile` override).
|
|
46
66
|
* Loads only the matching type fragment + universal fragments.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../../src/design/audit/rubric/loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EACV,kBAAkB,EAClB,cAAc,EACd,cAAc,EAEf,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../../src/design/audit/rubric/loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EACV,kBAAkB,EAClB,cAAc,EACd,cAAc,EAEf,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,oBAAoB,EACpB,wBAAwB,EACzB,MAAM,gBAAgB,CAAA;AAEvB;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAA;IACxB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAA;IACxB,iBAAiB,CAAC,EAAE,oBAAoB,EAAE,CAAA;IAC1C,qBAAqB,CAAC,EAAE,wBAAwB,EAAE,CAAA;CACnD;AAYD;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAiB9D;AAkED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,GAAE,MAA8B,GAAG,cAAc,EAAE,CAMnF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,cAAc,EACxB,cAAc,EAAE,kBAAkB,EAClC,GAAG,CAAC,EAAE,aAAa,GAClB,OAAO,CA2CT;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,cAAc,EAAE,kBAAkB,EAClC,SAAS,CAAC,EAAE,cAAc,EAAE,EAC5B,gBAAgB,CAAC,EAAE,MAAM,EACzB,GAAG,CAAC,EAAE,aAAa,GAClB,cAAc,CAgChB;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,iBAAiB,CAAC,EAAE,cAAc,EAAE,GACnC,cAAc,CA0BhB"}
|
|
@@ -124,41 +124,59 @@ export function loadFragments(dir = BUILTIN_FRAGMENTS_DIR) {
|
|
|
124
124
|
.map(f => parseFragment(path.join(dir, f)));
|
|
125
125
|
}
|
|
126
126
|
/**
|
|
127
|
-
* Predicate evaluator. Returns true if the fragment applies to the classification
|
|
127
|
+
* Predicate evaluator. Returns true if the fragment applies to the classification
|
|
128
|
+
* or the optional Layer 6 context (audience / modality / regulatoryContext /
|
|
129
|
+
* audienceVulnerability hints).
|
|
128
130
|
*
|
|
129
131
|
* Universal fragments always apply.
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
* fragment's allowed set.
|
|
132
|
+
* Predicate groups are OR-combined at the group level: a fragment fires if ANY
|
|
133
|
+
* one of its predicate groups matches. Within a group, list membership is used
|
|
134
|
+
* (the classification/context value must appear in the fragment's allowed set).
|
|
135
|
+
*
|
|
136
|
+
* Layer 6 predicates are additive: they can cause a fragment to fire even when
|
|
137
|
+
* no type/domain predicate matches, enabling composition across independent
|
|
138
|
+
* predicate dimensions.
|
|
133
139
|
*/
|
|
134
|
-
export function fragmentApplies(fragment, classification) {
|
|
140
|
+
export function fragmentApplies(fragment, classification, ctx) {
|
|
135
141
|
const w = fragment.appliesWhen;
|
|
136
142
|
if (w.universal)
|
|
137
143
|
return true;
|
|
138
|
-
|
|
139
|
-
|
|
144
|
+
// --- Layer 1 classification predicates (AND-combined when all set) ---
|
|
145
|
+
const classificationPredicateSet = !!w.type?.length || !!w.domain?.length || !!w.maturity?.length || !!w.designSystem?.length;
|
|
146
|
+
if (classificationPredicateSet) {
|
|
147
|
+
if (w.type?.length && !w.type.includes(classification.type))
|
|
140
148
|
return false;
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
149
|
+
if (w.domain?.length) {
|
|
150
|
+
const domainMatch = w.domain.some(d => classification.domain.toLowerCase().includes(d.toLowerCase()));
|
|
151
|
+
if (!domainMatch)
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
if (w.maturity?.length && !w.maturity.includes(classification.maturity))
|
|
145
155
|
return false;
|
|
146
|
-
|
|
147
|
-
if (w.maturity && w.maturity.length > 0) {
|
|
148
|
-
if (!w.maturity.includes(classification.maturity))
|
|
156
|
+
if (w.designSystem?.length && !w.designSystem.includes(classification.designSystem))
|
|
149
157
|
return false;
|
|
158
|
+
return true;
|
|
150
159
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
160
|
+
// --- Layer 6 context predicates (any overlap fires the fragment) ---
|
|
161
|
+
if (ctx) {
|
|
162
|
+
if (w.audience?.length && ctx.audience?.length) {
|
|
163
|
+
if (w.audience.some(a => ctx.audience.includes(a)))
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
if (w.modality?.length && ctx.modality?.length) {
|
|
167
|
+
if (w.modality.some(m => ctx.modality.includes(m)))
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
if (w.regulatoryContext?.length && ctx.regulatoryContext?.length) {
|
|
171
|
+
if (w.regulatoryContext.some(r => ctx.regulatoryContext.includes(r)))
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
if (w.audienceVulnerability?.length && ctx.audienceVulnerability?.length) {
|
|
175
|
+
if (w.audienceVulnerability.some(av => ctx.audienceVulnerability.includes(av)))
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
154
178
|
}
|
|
155
|
-
|
|
156
|
-
// If NO predicates were set and not universal, don't apply (be conservative).
|
|
157
|
-
const hasPredicate = !!w.type?.length ||
|
|
158
|
-
!!w.domain?.length ||
|
|
159
|
-
!!w.maturity?.length ||
|
|
160
|
-
!!w.designSystem?.length;
|
|
161
|
-
return hasPredicate;
|
|
179
|
+
return false;
|
|
162
180
|
}
|
|
163
181
|
/**
|
|
164
182
|
* Compose a rubric from a classification.
|
|
@@ -166,14 +184,15 @@ export function fragmentApplies(fragment, classification) {
|
|
|
166
184
|
* @param classification - the page classification
|
|
167
185
|
* @param fragments - all loaded fragments (defaults to builtin)
|
|
168
186
|
* @param userFragmentsDir - optional path to user-supplied fragments
|
|
187
|
+
* @param ctx - optional Layer 6 context for audience/modality/regulatory predicates
|
|
169
188
|
*/
|
|
170
|
-
export function composeRubric(classification, fragments, userFragmentsDir) {
|
|
189
|
+
export function composeRubric(classification, fragments, userFragmentsDir, ctx) {
|
|
171
190
|
const all = [
|
|
172
191
|
...(fragments ?? loadFragments(BUILTIN_FRAGMENTS_DIR)),
|
|
173
192
|
...(userFragmentsDir ? loadFragments(userFragmentsDir) : []),
|
|
174
193
|
];
|
|
175
194
|
const matched = all
|
|
176
|
-
.filter(f => fragmentApplies(f, classification))
|
|
195
|
+
.filter(f => fragmentApplies(f, classification, ctx))
|
|
177
196
|
.sort((a, b) => WEIGHT_ORDER[a.weight] - WEIGHT_ORDER[b.weight]);
|
|
178
197
|
const body = matched
|
|
179
198
|
.map(f => `## ${f.title}\n\n${f.body}`)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../../src/design/audit/rubric/loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../../src/design/audit/rubric/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rollup weights — Layer 1 of the world-class design-audit architecture.
|
|
3
|
+
*
|
|
4
|
+
* Per-page-type weights for combining the 5 dimension scores into a single
|
|
5
|
+
* rollup. Marketing surfaces emphasize visual + content; saas-app surfaces
|
|
6
|
+
* emphasize product_intent + workflow; docs lean on content_ia. The weights
|
|
7
|
+
* are evolvable via the GEPA target `pareto-rollup-weights`.
|
|
8
|
+
*
|
|
9
|
+
* Invariant: every weight set sums to 1.0 within 1e-6.
|
|
10
|
+
*/
|
|
11
|
+
import type { Dimension } from '../v2/types.js';
|
|
12
|
+
import type { PageType } from '../types.js';
|
|
13
|
+
export type RollupWeightKey = PageType | 'default';
|
|
14
|
+
export declare const ROLLUP_WEIGHTS: Record<RollupWeightKey, Record<Dimension, number>>;
|
|
15
|
+
/**
|
|
16
|
+
* Look up rollup weights for a page type, falling back to `default` when the
|
|
17
|
+
* type isn't in the table (forward-compat for new types).
|
|
18
|
+
*/
|
|
19
|
+
export declare function rollupWeightsFor(type: PageType | undefined): Record<Dimension, number>;
|
|
20
|
+
/**
|
|
21
|
+
* Render a human-readable formula for the audit report, e.g.
|
|
22
|
+
* "saas-app: product_intent*0.35 + workflow*0.30 + visual_craft*0.15 + trust_clarity*0.10 + content_ia*0.10"
|
|
23
|
+
*/
|
|
24
|
+
export declare function rollupFormula(type: PageType | undefined, weights: Record<Dimension, number>): string;
|
|
25
|
+
//# sourceMappingURL=rollup-weights.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollup-weights.d.ts","sourceRoot":"","sources":["../../../../src/design/audit/rubric/rollup-weights.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,SAAS,CAAA;AA0BlD,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAsB,CAAA;AAEpG;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAGtF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,MAAM,CAIpG"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rollup weights — Layer 1 of the world-class design-audit architecture.
|
|
3
|
+
*
|
|
4
|
+
* Per-page-type weights for combining the 5 dimension scores into a single
|
|
5
|
+
* rollup. Marketing surfaces emphasize visual + content; saas-app surfaces
|
|
6
|
+
* emphasize product_intent + workflow; docs lean on content_ia. The weights
|
|
7
|
+
* are evolvable via the GEPA target `pareto-rollup-weights`.
|
|
8
|
+
*
|
|
9
|
+
* Invariant: every weight set sums to 1.0 within 1e-6.
|
|
10
|
+
*/
|
|
11
|
+
const ROLLUP_WEIGHTS_RAW = {
|
|
12
|
+
marketing: { product_intent: 0.30, visual_craft: 0.30, content_ia: 0.25, trust_clarity: 0.10, workflow: 0.05 },
|
|
13
|
+
'saas-app': { product_intent: 0.35, workflow: 0.30, visual_craft: 0.15, trust_clarity: 0.10, content_ia: 0.10 },
|
|
14
|
+
dashboard: { product_intent: 0.30, workflow: 0.30, content_ia: 0.20, visual_craft: 0.15, trust_clarity: 0.05 },
|
|
15
|
+
docs: { content_ia: 0.45, workflow: 0.25, product_intent: 0.15, visual_craft: 0.15, trust_clarity: 0.0 },
|
|
16
|
+
ecommerce: { trust_clarity: 0.35, product_intent: 0.30, workflow: 0.20, visual_craft: 0.10, content_ia: 0.05 },
|
|
17
|
+
social: { product_intent: 0.30, workflow: 0.30, content_ia: 0.20, visual_craft: 0.15, trust_clarity: 0.05 },
|
|
18
|
+
tool: { workflow: 0.40, product_intent: 0.30, content_ia: 0.15, visual_craft: 0.10, trust_clarity: 0.05 },
|
|
19
|
+
blog: { content_ia: 0.50, visual_craft: 0.25, product_intent: 0.15, workflow: 0.10, trust_clarity: 0.0 },
|
|
20
|
+
utility: { workflow: 0.45, product_intent: 0.25, content_ia: 0.20, visual_craft: 0.10, trust_clarity: 0.0 },
|
|
21
|
+
unknown: { product_intent: 0.30, workflow: 0.25, visual_craft: 0.20, content_ia: 0.15, trust_clarity: 0.10 },
|
|
22
|
+
default: { product_intent: 0.30, workflow: 0.25, visual_craft: 0.20, content_ia: 0.15, trust_clarity: 0.10 },
|
|
23
|
+
};
|
|
24
|
+
const WEIGHT_SUM_TOLERANCE = 1e-6;
|
|
25
|
+
// Validate at module load — fail fast if a weight set drifts.
|
|
26
|
+
for (const [type, weights] of Object.entries(ROLLUP_WEIGHTS_RAW)) {
|
|
27
|
+
const sum = Object.values(weights).reduce((acc, n) => acc + n, 0);
|
|
28
|
+
if (Math.abs(sum - 1) > WEIGHT_SUM_TOLERANCE) {
|
|
29
|
+
throw new Error(`rollup weights for ${type} sum to ${sum}, expected 1.0 ± ${WEIGHT_SUM_TOLERANCE}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export const ROLLUP_WEIGHTS = ROLLUP_WEIGHTS_RAW;
|
|
33
|
+
/**
|
|
34
|
+
* Look up rollup weights for a page type, falling back to `default` when the
|
|
35
|
+
* type isn't in the table (forward-compat for new types).
|
|
36
|
+
*/
|
|
37
|
+
export function rollupWeightsFor(type) {
|
|
38
|
+
if (type && type in ROLLUP_WEIGHTS)
|
|
39
|
+
return ROLLUP_WEIGHTS[type];
|
|
40
|
+
return ROLLUP_WEIGHTS.default;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Render a human-readable formula for the audit report, e.g.
|
|
44
|
+
* "saas-app: product_intent*0.35 + workflow*0.30 + visual_craft*0.15 + trust_clarity*0.10 + content_ia*0.10"
|
|
45
|
+
*/
|
|
46
|
+
export function rollupFormula(type, weights) {
|
|
47
|
+
const entries = Object.entries(weights).sort(([, a], [, b]) => b - a);
|
|
48
|
+
const body = entries.map(([dim, w]) => `${dim}*${w.toFixed(2)}`).join(' + ');
|
|
49
|
+
return `${type ?? 'default'}: ${body}`;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=rollup-weights.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollup-weights.js","sourceRoot":"","sources":["../../../../src/design/audit/rubric/rollup-weights.ts"],"names":[],"mappings":"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"}
|