@tangle-network/browser-agent-driver 0.30.0 → 0.32.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/brain/index.d.ts +12 -0
- package/dist/brain/index.d.ts.map +1 -1
- package/dist/brain/index.js +36 -8
- package/dist/brain/index.js.map +1 -1
- 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 +78 -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 +253 -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/build-result.d.ts +68 -0
- package/dist/design/audit/build-result.d.ts.map +1 -0
- package/dist/design/audit/build-result.js +243 -0
- package/dist/design/audit/build-result.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/generate.d.ts +45 -0
- package/dist/design/audit/patches/generate.d.ts.map +1 -0
- package/dist/design/audit/patches/generate.js +161 -0
- package/dist/design/audit/patches/generate.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 +40 -0
- package/dist/design/audit/patches/validate.d.ts.map +1 -0
- package/dist/design/audit/patches/validate.js +60 -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 +81 -5
- 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/score-types.d.ts +431 -0
- package/dist/design/audit/score-types.d.ts.map +1 -0
- package/dist/design/audit/score-types.js +26 -0
- package/dist/design/audit/score-types.js.map +1 -0
- package/dist/design/audit/score.d.ts +49 -0
- package/dist/design/audit/score.d.ts.map +1 -0
- package/dist/design/audit/score.js +211 -0
- package/dist/design/audit/score.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/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 +69 -0
- package/dist/reports/tokens.d.ts.map +1 -0
- package/dist/reports/tokens.js +74 -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/dist/run-state.d.ts +36 -1
- package/dist/run-state.d.ts.map +1 -1
- package/dist/run-state.js +36 -1
- package/dist/run-state.js.map +1 -1
- package/dist/runner/runner.d.ts.map +1 -1
- package/dist/runner/runner.js +73 -3
- package/dist/runner/runner.js.map +1 -1
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Patch validator — given a parsed patch and the page snapshot text, verify
|
|
3
|
+
* that the patch is grounded and applyable.
|
|
4
|
+
*
|
|
5
|
+
* Rules:
|
|
6
|
+
* - `diff.before` must appear as a case-sensitive substring of the snapshot.
|
|
7
|
+
* Agents apply patches literally; a hallucinated `before` is unfixable.
|
|
8
|
+
* - `target` must carry at least one locator (cssSelector | filePath |
|
|
9
|
+
* componentName). Without one the agent has nowhere to apply.
|
|
10
|
+
* - `estimatedDelta.delta` must be in [-3, 3]. Larger claims are almost
|
|
11
|
+
* always over-confident on a 1–10 scale.
|
|
12
|
+
*/
|
|
13
|
+
const DELTA_MIN = -3;
|
|
14
|
+
const DELTA_MAX = 3;
|
|
15
|
+
/**
|
|
16
|
+
* Validate a single patch against a page snapshot. Reports all issues in one
|
|
17
|
+
* pass so callers can surface every problem to the agent at once.
|
|
18
|
+
*
|
|
19
|
+
* Snapshot-anchoring rule: `diff.before` must appear verbatim in the page
|
|
20
|
+
* snapshot ONLY when the patch targets the snapshot itself — i.e. `target.scope`
|
|
21
|
+
* is `html` or `structural`. CSS / TSX / Tailwind patches modify source files
|
|
22
|
+
* the audit can't see, so the snapshot check would always fail for them. The
|
|
23
|
+
* agent verifies those patches at apply-time against the actual source file.
|
|
24
|
+
*/
|
|
25
|
+
export function validatePatch(patch, snapshot) {
|
|
26
|
+
const reasons = [];
|
|
27
|
+
const { target, diff, estimatedDelta } = patch;
|
|
28
|
+
if (!target.cssSelector && !target.filePath && !target.componentName) {
|
|
29
|
+
reasons.push('target-missing-locator');
|
|
30
|
+
}
|
|
31
|
+
const requiresSnapshotMatch = target.scope === 'html' || target.scope === 'structural';
|
|
32
|
+
if (diff.before.length === 0) {
|
|
33
|
+
reasons.push('before-empty');
|
|
34
|
+
}
|
|
35
|
+
else if (requiresSnapshotMatch && !snapshot.includes(diff.before)) {
|
|
36
|
+
reasons.push('before-not-in-snapshot');
|
|
37
|
+
}
|
|
38
|
+
if (estimatedDelta.delta < DELTA_MIN ||
|
|
39
|
+
estimatedDelta.delta > DELTA_MAX ||
|
|
40
|
+
!Number.isFinite(estimatedDelta.delta)) {
|
|
41
|
+
reasons.push('estimated-delta-out-of-range');
|
|
42
|
+
}
|
|
43
|
+
return { valid: reasons.length === 0, reasons };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Validate a list of patches and partition into valid / invalid.
|
|
47
|
+
*/
|
|
48
|
+
export function validatePatches(patches, snapshot) {
|
|
49
|
+
const valid = [];
|
|
50
|
+
const invalid = [];
|
|
51
|
+
for (const patch of patches) {
|
|
52
|
+
const result = validatePatch(patch, snapshot);
|
|
53
|
+
if (result.valid)
|
|
54
|
+
valid.push(patch);
|
|
55
|
+
else
|
|
56
|
+
invalid.push({ patch, reasons: result.reasons });
|
|
57
|
+
}
|
|
58
|
+
return { valid, invalid };
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../src/design/audit/patches/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAeH,MAAM,SAAS,GAAG,CAAC,CAAC,CAAA;AACpB,MAAM,SAAS,GAAG,CAAC,CAAA;AAEnB;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,KAAY,EAAE,QAAgB;IAC1D,MAAM,OAAO,GAAuB,EAAE,CAAA;IACtC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,KAAK,CAAA;IAE9C,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAA;IACxC,CAAC;IAED,MAAM,qBAAqB,GAAG,MAAM,CAAC,KAAK,KAAK,MAAM,IAAI,MAAM,CAAC,KAAK,KAAK,YAAY,CAAA;IAEtF,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;IAC9B,CAAC;SAAM,IAAI,qBAAqB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACpE,OAAO,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAA;IACxC,CAAC;IAED,IACE,cAAc,CAAC,KAAK,GAAG,SAAS;QAChC,cAAc,CAAC,KAAK,GAAG,SAAS;QAChC,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,EACtC,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAA;IAC9C,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,OAAO,EAAE,CAAA;AACjD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAgB,EAChB,QAAgB;IAEhB,MAAM,KAAK,GAAY,EAAE,CAAA;IACzB,MAAM,OAAO,GAAyD,EAAE,CAAA;IACxE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;QAC7C,IAAI,MAAM,CAAC,KAAK;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;;YAC9B,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAA;IACvD,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAA;AAC3B,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 5 — Pattern matching.
|
|
3
|
+
*
|
|
4
|
+
* Fuzzy-matches a page against catalogued patterns. When patterns exist (post
|
|
5
|
+
* fleet accumulation), findings include `matchedPatterns[]` so agents can cite
|
|
6
|
+
* fleet evidence rather than applying novel patches.
|
|
7
|
+
*
|
|
8
|
+
* Currently returns [] (cold-start). The interface is stable.
|
|
9
|
+
*/
|
|
10
|
+
import type { PatternMatch } from './types.js';
|
|
11
|
+
import type { PageType, Dimension } from '../score-types.js';
|
|
12
|
+
export interface MatchContext {
|
|
13
|
+
pageType: PageType;
|
|
14
|
+
weakDimensions: Dimension[];
|
|
15
|
+
dir?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Match patterns against the current page context. Returns the top-N matches
|
|
19
|
+
* ordered by expected leverage (weakest dim × pattern's median delta for that dim).
|
|
20
|
+
*
|
|
21
|
+
* Cold-start: returns [] until patterns are mined.
|
|
22
|
+
*/
|
|
23
|
+
export declare function matchPatterns(ctx: MatchContext, topN?: number): Promise<PatternMatch[]>;
|
|
24
|
+
//# sourceMappingURL=match.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"match.d.ts","sourceRoot":"","sources":["../../../../src/design/audit/patterns/match.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAW,YAAY,EAAgB,MAAM,YAAY,CAAA;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAG5D,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,QAAQ,CAAA;IAClB,cAAc,EAAE,SAAS,EAAE,CAAA;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,YAAY,EACjB,IAAI,GAAE,MAAU,GACf,OAAO,CAAC,YAAY,EAAE,CAAC,CA+BzB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 5 — Pattern matching.
|
|
3
|
+
*
|
|
4
|
+
* Fuzzy-matches a page against catalogued patterns. When patterns exist (post
|
|
5
|
+
* fleet accumulation), findings include `matchedPatterns[]` so agents can cite
|
|
6
|
+
* fleet evidence rather than applying novel patches.
|
|
7
|
+
*
|
|
8
|
+
* Currently returns [] (cold-start). The interface is stable.
|
|
9
|
+
*/
|
|
10
|
+
import { queryPatterns } from './store.js';
|
|
11
|
+
/**
|
|
12
|
+
* Match patterns against the current page context. Returns the top-N matches
|
|
13
|
+
* ordered by expected leverage (weakest dim × pattern's median delta for that dim).
|
|
14
|
+
*
|
|
15
|
+
* Cold-start: returns [] until patterns are mined.
|
|
16
|
+
*/
|
|
17
|
+
export async function matchPatterns(ctx, topN = 5) {
|
|
18
|
+
const query = {
|
|
19
|
+
pageType: ctx.pageType,
|
|
20
|
+
minApplications: 5,
|
|
21
|
+
minSuccessRate: 0.5,
|
|
22
|
+
};
|
|
23
|
+
const candidates = await queryPatterns(query, ctx.dir);
|
|
24
|
+
if (candidates.length === 0)
|
|
25
|
+
return [];
|
|
26
|
+
const scored = candidates.map(p => {
|
|
27
|
+
const leverage = ctx.weakDimensions.reduce((sum, dim) => {
|
|
28
|
+
return sum + (p.fleetEvidence.medianDimDelta[dim] ?? 0);
|
|
29
|
+
}, 0);
|
|
30
|
+
return { pattern: p, leverage };
|
|
31
|
+
});
|
|
32
|
+
return scored
|
|
33
|
+
.sort((a, b) => b.leverage - a.leverage)
|
|
34
|
+
.slice(0, topN)
|
|
35
|
+
.map(({ pattern, leverage }) => {
|
|
36
|
+
const expectedDelta = {};
|
|
37
|
+
for (const dim of ctx.weakDimensions) {
|
|
38
|
+
expectedDelta[dim] = pattern.fleetEvidence.medianDimDelta[dim] ?? 0;
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
pattern,
|
|
42
|
+
matchConfidence: Math.min(1, leverage / 10),
|
|
43
|
+
expectedDelta,
|
|
44
|
+
applicationGuidance: `Apply ${pattern.scaffold.description}. Key decisions: ${pattern.scaffold.keyDecisions.join('; ')}.`,
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=match.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"match.js","sourceRoot":"","sources":["../../../../src/design/audit/patterns/match.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAQ1C;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAiB,EACjB,OAAe,CAAC;IAEhB,MAAM,KAAK,GAAiB;QAC1B,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,eAAe,EAAE,CAAC;QAClB,cAAc,EAAE,GAAG;KACpB,CAAA;IACD,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAA;IACtD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IAEtC,MAAM,MAAM,GAAkD,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;QAC/E,MAAM,QAAQ,GAAG,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YACtD,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA;QACzD,CAAC,EAAE,CAAC,CAAC,CAAA;QACL,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAA;IACjC,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM;SACV,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;SACvC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;SACd,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC7B,MAAM,aAAa,GAA8B,EAA+B,CAAA;QAChF,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,cAAc,EAAE,CAAC;YACrC,aAAa,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACrE,CAAC;QACD,OAAO;YACL,OAAO;YACP,eAAe,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,EAAE,CAAC;YAC3C,aAAa;YACb,mBAAmB,EAAE,SAAS,OAAO,CAAC,QAAQ,CAAC,WAAW,oBAAoB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;SAC1H,CAAA;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 5 — Pattern mining (scaffold).
|
|
3
|
+
*
|
|
4
|
+
* In production this runs as a Cloudflare Worker cron job on accumulated
|
|
5
|
+
* PatchApplication telemetry. The mining threshold (N≥30, ≥5 tenants,
|
|
6
|
+
* replicationRate≥0.7) prevents false patterns from premature data.
|
|
7
|
+
*
|
|
8
|
+
* Until fleet data accumulates this module is a scaffold. Run:
|
|
9
|
+
* pnpm patterns:mine --dir ~/.bad
|
|
10
|
+
*
|
|
11
|
+
* TODO: implement clustering algorithm once sufficient attribution data exists.
|
|
12
|
+
*/
|
|
13
|
+
import type { PatchApplication } from '../attribution/types.js';
|
|
14
|
+
export interface MineOptions {
|
|
15
|
+
minApplications?: number;
|
|
16
|
+
minTenants?: number;
|
|
17
|
+
minReplicationRate?: number;
|
|
18
|
+
dir?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Mine patterns from accumulated PatchApplication records.
|
|
22
|
+
*
|
|
23
|
+
* Currently a stub — returns 0 mined until clustering is implemented.
|
|
24
|
+
* The interface is stable; consumers can call it safely in tests via synthetic
|
|
25
|
+
* data without triggering real fleet operations.
|
|
26
|
+
*/
|
|
27
|
+
export declare function minePatterns(applications: PatchApplication[], opts?: MineOptions): Promise<{
|
|
28
|
+
mined: number;
|
|
29
|
+
skipped: number;
|
|
30
|
+
}>;
|
|
31
|
+
//# sourceMappingURL=mine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mine.d.ts","sourceRoot":"","sources":["../../../../src/design/audit/patterns/mine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAI/D,MAAM,WAAW,WAAW;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAQD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,YAAY,EAAE,gBAAgB,EAAE,EAChC,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAQ7C"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 5 — Pattern mining (scaffold).
|
|
3
|
+
*
|
|
4
|
+
* In production this runs as a Cloudflare Worker cron job on accumulated
|
|
5
|
+
* PatchApplication telemetry. The mining threshold (N≥30, ≥5 tenants,
|
|
6
|
+
* replicationRate≥0.7) prevents false patterns from premature data.
|
|
7
|
+
*
|
|
8
|
+
* Until fleet data accumulates this module is a scaffold. Run:
|
|
9
|
+
* pnpm patterns:mine --dir ~/.bad
|
|
10
|
+
*
|
|
11
|
+
* TODO: implement clustering algorithm once sufficient attribution data exists.
|
|
12
|
+
*/
|
|
13
|
+
import { savePattern } from './store.js';
|
|
14
|
+
const DEFAULTS = {
|
|
15
|
+
minApplications: 30,
|
|
16
|
+
minTenants: 5,
|
|
17
|
+
minReplicationRate: 0.7,
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Mine patterns from accumulated PatchApplication records.
|
|
21
|
+
*
|
|
22
|
+
* Currently a stub — returns 0 mined until clustering is implemented.
|
|
23
|
+
* The interface is stable; consumers can call it safely in tests via synthetic
|
|
24
|
+
* data without triggering real fleet operations.
|
|
25
|
+
*/
|
|
26
|
+
export async function minePatterns(applications, opts = {}) {
|
|
27
|
+
void applications;
|
|
28
|
+
void opts;
|
|
29
|
+
void DEFAULTS;
|
|
30
|
+
void savePattern;
|
|
31
|
+
// TODO: implement structural clustering by (scope, target.cssSelector pattern,
|
|
32
|
+
// diff similarity) once N≥30 fleet data is available. See RFC §Layer 5.
|
|
33
|
+
return { mined: 0, skipped: applications.length };
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=mine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mine.js","sourceRoot":"","sources":["../../../../src/design/audit/patterns/mine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AASxC,MAAM,QAAQ,GAAuC;IACnD,eAAe,EAAE,EAAE;IACnB,UAAU,EAAE,CAAC;IACb,kBAAkB,EAAE,GAAG;CACxB,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,YAAgC,EAChC,OAAoB,EAAE;IAEtB,KAAK,YAAY,CAAA;IACjB,KAAK,IAAI,CAAA;IACT,KAAK,QAAQ,CAAA;IACb,KAAK,WAAW,CAAA;IAChB,+EAA+E;IAC/E,wEAAwE;IACxE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,CAAA;AACnD,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 5 — Pattern store.
|
|
3
|
+
*
|
|
4
|
+
* Reads/writes patterns from a JSONL file. In production this is backed by a
|
|
5
|
+
* Cloudflare D1 or R2 store; the JSONL backend is for local dev and tests.
|
|
6
|
+
*
|
|
7
|
+
* Cold-start: the pattern library is empty until fleet data accumulates.
|
|
8
|
+
* The store returns [] for all queries until patterns are mined (Layer 5 mine.ts).
|
|
9
|
+
*/
|
|
10
|
+
import type { Pattern, PatternQuery } from './types.js';
|
|
11
|
+
export declare function loadPatterns(dir?: string): Promise<Pattern[]>;
|
|
12
|
+
export declare function savePattern(pattern: Pattern, dir?: string): Promise<void>;
|
|
13
|
+
export declare function queryPatterns(query: PatternQuery, dir?: string): Promise<Pattern[]>;
|
|
14
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../src/design/audit/patterns/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAKvD,wBAAsB,YAAY,CAAC,GAAG,GAAE,MAAoB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAQhF;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,GAAE,MAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5F;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,YAAY,EACnB,GAAG,GAAE,MAAoB,GACxB,OAAO,CAAC,OAAO,EAAE,CAAC,CAapB"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 5 — Pattern store.
|
|
3
|
+
*
|
|
4
|
+
* Reads/writes patterns from a JSONL file. In production this is backed by a
|
|
5
|
+
* Cloudflare D1 or R2 store; the JSONL backend is for local dev and tests.
|
|
6
|
+
*
|
|
7
|
+
* Cold-start: the pattern library is empty until fleet data accumulates.
|
|
8
|
+
* The store returns [] for all queries until patterns are mined (Layer 5 mine.ts).
|
|
9
|
+
*/
|
|
10
|
+
import * as fs from 'node:fs';
|
|
11
|
+
import * as fsp from 'node:fs/promises';
|
|
12
|
+
import * as path from 'node:path';
|
|
13
|
+
import * as os from 'node:os';
|
|
14
|
+
const DEFAULT_DIR = path.join(os.homedir(), '.bad', 'patterns');
|
|
15
|
+
const PATTERNS_FILE = 'patterns.jsonl';
|
|
16
|
+
export async function loadPatterns(dir = DEFAULT_DIR) {
|
|
17
|
+
const filePath = path.join(dir, PATTERNS_FILE);
|
|
18
|
+
if (!fs.existsSync(filePath))
|
|
19
|
+
return [];
|
|
20
|
+
const lines = fs.readFileSync(filePath, 'utf-8').split('\n').filter(Boolean);
|
|
21
|
+
return lines.flatMap(line => {
|
|
22
|
+
try {
|
|
23
|
+
return [JSON.parse(line)];
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
export async function savePattern(pattern, dir = DEFAULT_DIR) {
|
|
31
|
+
await fsp.mkdir(dir, { recursive: true });
|
|
32
|
+
await fsp.appendFile(path.join(dir, PATTERNS_FILE), JSON.stringify(pattern) + '\n', 'utf-8');
|
|
33
|
+
}
|
|
34
|
+
export async function queryPatterns(query, dir = DEFAULT_DIR) {
|
|
35
|
+
const all = await loadPatterns(dir);
|
|
36
|
+
return all.filter(p => {
|
|
37
|
+
if (query.category && p.category !== query.category)
|
|
38
|
+
return false;
|
|
39
|
+
if (query.pageType && p.classification.type !== query.pageType)
|
|
40
|
+
return false;
|
|
41
|
+
if (query.minApplications && p.fleetEvidence.applications < query.minApplications)
|
|
42
|
+
return false;
|
|
43
|
+
if (query.minSuccessRate && p.fleetEvidence.successRate < query.minSuccessRate)
|
|
44
|
+
return false;
|
|
45
|
+
if (query.weakDimension) {
|
|
46
|
+
const delta = p.fleetEvidence.medianDimDelta[query.weakDimension] ?? 0;
|
|
47
|
+
if (delta <= 0)
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
return true;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../../src/design/audit/patterns/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAA;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAG7B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,CAAA;AAC/D,MAAM,aAAa,GAAG,gBAAgB,CAAA;AAEtC,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAc,WAAW;IAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAA;IAC9C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,CAAA;IACvC,MAAM,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAC5E,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QAC1B,IAAI,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC,CAAA;QAAC,CAAC;QAC5C,MAAM,CAAC;YAAC,OAAO,EAAE,CAAA;QAAC,CAAC;IACrB,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAgB,EAAE,MAAc,WAAW;IAC3E,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACzC,MAAM,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAA;AAC9F,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAmB,EACnB,MAAc,WAAW;IAEzB,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAA;IACnC,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;QACpB,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAA;QACjE,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC,cAAc,CAAC,IAAI,KAAK,KAAK,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAA;QAC5E,IAAI,KAAK,CAAC,eAAe,IAAI,CAAC,CAAC,aAAa,CAAC,YAAY,GAAG,KAAK,CAAC,eAAe;YAAE,OAAO,KAAK,CAAA;QAC/F,IAAI,KAAK,CAAC,cAAc,IAAI,CAAC,CAAC,aAAa,CAAC,WAAW,GAAG,KAAK,CAAC,cAAc;YAAE,OAAO,KAAK,CAAA;QAC5F,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,CAAC,CAAC,aAAa,CAAC,cAAc,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;YACtE,IAAI,KAAK,IAAI,CAAC;gBAAE,OAAO,KAAK,CAAA;QAC9B,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 5 — Pattern library type contract.
|
|
3
|
+
*
|
|
4
|
+
* Patterns are mined from accumulated PatchApplication data once a cluster
|
|
5
|
+
* meets: N≥30 applications across ≥5 distinct tenants, replicationRate≥0.7.
|
|
6
|
+
* Until fleet data accumulates (≥6 weeks), the pattern library is empty.
|
|
7
|
+
*
|
|
8
|
+
* This module defines the stable query API so agents can code against it now.
|
|
9
|
+
* The mining and matching implementations are scaffolded; real clustering runs
|
|
10
|
+
* as a Cloudflare Worker cron once the attribution data accumulates.
|
|
11
|
+
*/
|
|
12
|
+
export type { PageType, Dimension } from '../score-types.js';
|
|
13
|
+
import type { PageType, Dimension } from '../score-types.js';
|
|
14
|
+
export interface PatternScaffold {
|
|
15
|
+
description: string;
|
|
16
|
+
referenceTsx?: string;
|
|
17
|
+
referenceCss?: string;
|
|
18
|
+
keyDecisions: string[];
|
|
19
|
+
}
|
|
20
|
+
export interface PatternFleetEvidence {
|
|
21
|
+
applications: number;
|
|
22
|
+
successRate: number;
|
|
23
|
+
medianDimDelta: Record<Dimension, number>;
|
|
24
|
+
sampleTenants: number;
|
|
25
|
+
}
|
|
26
|
+
export interface Pattern {
|
|
27
|
+
patternId: string;
|
|
28
|
+
category: string;
|
|
29
|
+
classification: {
|
|
30
|
+
type: PageType;
|
|
31
|
+
tags: string[];
|
|
32
|
+
};
|
|
33
|
+
scaffold: PatternScaffold;
|
|
34
|
+
scores: {
|
|
35
|
+
whenFollowed: Record<Dimension, number>;
|
|
36
|
+
};
|
|
37
|
+
fleetEvidence: PatternFleetEvidence;
|
|
38
|
+
fixtures: string[];
|
|
39
|
+
}
|
|
40
|
+
export interface PatternQuery {
|
|
41
|
+
category?: string;
|
|
42
|
+
pageType?: PageType;
|
|
43
|
+
weakDimension?: Dimension;
|
|
44
|
+
minApplications?: number;
|
|
45
|
+
minSuccessRate?: number;
|
|
46
|
+
}
|
|
47
|
+
export interface PatternMatch {
|
|
48
|
+
pattern: Pattern;
|
|
49
|
+
matchConfidence: number;
|
|
50
|
+
expectedDelta: Record<Dimension, number>;
|
|
51
|
+
applicationGuidance: string;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/design/audit/patterns/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAE5D,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IACzC,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;IAClD,QAAQ,EAAE,eAAe,CAAA;IACzB,MAAM,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;KAAE,CAAA;IACnD,aAAa,EAAE,oBAAoB,CAAA;IACnC,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,aAAa,CAAC,EAAE,SAAS,CAAA;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAA;IAChB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IACxC,mBAAmB,EAAE,MAAM,CAAA;CAC5B"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 5 — Pattern library type contract.
|
|
3
|
+
*
|
|
4
|
+
* Patterns are mined from accumulated PatchApplication data once a cluster
|
|
5
|
+
* meets: N≥30 applications across ≥5 distinct tenants, replicationRate≥0.7.
|
|
6
|
+
* Until fleet data accumulates (≥6 weeks), the pattern library is empty.
|
|
7
|
+
*
|
|
8
|
+
* This module defines the stable query API so agents can code against it now.
|
|
9
|
+
* The mining and matching implementations are scaffolded; real clustering runs
|
|
10
|
+
* as a Cloudflare Worker cron once the attribution data accumulates.
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/design/audit/patterns/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -11,6 +11,7 @@ import type { Brain } from '../../brain/index.js';
|
|
|
11
11
|
import { PlaywrightDriver } from '../../drivers/playwright.js';
|
|
12
12
|
import { type AuditPassId, type AuditOverrides } from './evaluate.js';
|
|
13
13
|
import type { PageAuditResult } from './types.js';
|
|
14
|
+
import type { AudienceTag, ModalityTag, RegulatoryContextTag, AudienceVulnerabilityTag } from './score-types.js';
|
|
14
15
|
export interface AuditOnePageOptions {
|
|
15
16
|
brain: Brain;
|
|
16
17
|
driver: PlaywrightDriver;
|
|
@@ -35,6 +36,17 @@ export interface AuditOnePageOptions {
|
|
|
35
36
|
* candidate prompts; production runs leave them undefined.
|
|
36
37
|
*/
|
|
37
38
|
overrides?: AuditOverrides;
|
|
39
|
+
/**
|
|
40
|
+
* Layer 7 — bypass the ethics gate entirely. Audited + warned. Test-only.
|
|
41
|
+
*/
|
|
42
|
+
skipEthics?: boolean;
|
|
43
|
+
/** Override directory containing ethics `*.yaml` rule files. */
|
|
44
|
+
ethicsRulesDir?: string;
|
|
45
|
+
/** Layer 6 hints used by ethics + composable predicates. */
|
|
46
|
+
audience?: AudienceTag[];
|
|
47
|
+
modality?: ModalityTag[];
|
|
48
|
+
regulatoryContext?: RegulatoryContextTag[];
|
|
49
|
+
audienceVulnerability?: AudienceVulnerabilityTag[];
|
|
38
50
|
}
|
|
39
51
|
/**
|
|
40
52
|
* Audit one page through the full Gen 2 pipeline.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../../src/design/audit/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AAI9D,OAAO,EAAgB,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AACnF,OAAO,KAAK,EAAE,eAAe,EAAsB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../../src/design/audit/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AAI9D,OAAO,EAAgB,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AACnF,OAAO,KAAK,EAAE,eAAe,EAAsB,MAAM,YAAY,CAAA;AAOrE,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,oBAAoB,EACpB,wBAAwB,EAGzB,MAAM,kBAAkB,CAAA;AAEzB,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,KAAK,CAAA;IACZ,MAAM,EAAE,gBAAgB,CAAA;IACxB,IAAI,EAAE,IAAI,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;IACX,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,WAAW,EAAE,CAAA;IAC3B,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAA;IAC1B;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,gEAAgE;IAChE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,4DAA4D;IAC5D,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;AAqBD;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,eAAe,CAAC,CAyOtF"}
|
|
@@ -7,11 +7,16 @@
|
|
|
7
7
|
* a pure function elsewhere in this module — easy to unit test in isolation.
|
|
8
8
|
*/
|
|
9
9
|
import * as path from 'node:path';
|
|
10
|
-
import {
|
|
10
|
+
import { defaultClassification } from './classify.js';
|
|
11
11
|
import { composeRubric, composeRubricFromProfile } from './rubric/loader.js';
|
|
12
12
|
import { gatherMeasurements } from './measure/index.js';
|
|
13
13
|
import { evaluatePage } from './evaluate.js';
|
|
14
14
|
import { getTelemetry, shortHash } from '../../telemetry/index.js';
|
|
15
|
+
import { loadEthicsRules } from './ethics/loader.js';
|
|
16
|
+
import { checkEthics, pageTextBlob } from './ethics/check.js';
|
|
17
|
+
import { classifyEnsemble } from './classify-ensemble.js';
|
|
18
|
+
import { loadAnchors } from './rubric/anchor-loader.js';
|
|
19
|
+
import { buildAuditResult } from './build-result.js';
|
|
15
20
|
const COOKIE_BANNER_SELECTORS = [
|
|
16
21
|
'button:has-text("Accept all")',
|
|
17
22
|
'button:has-text("Accept")',
|
|
@@ -33,7 +38,7 @@ async function dismissCookieBanners(page) {
|
|
|
33
38
|
* Audit one page through the full Gen 2 pipeline.
|
|
34
39
|
*/
|
|
35
40
|
export async function auditOnePage(opts) {
|
|
36
|
-
const { brain, driver, page, url, profileOverride, screenshotDir, userRubricsDir, auditPasses, runId, parentRunId, provider, model, overrides } = opts;
|
|
41
|
+
const { brain, driver, page, url, profileOverride, screenshotDir, userRubricsDir, auditPasses, runId, parentRunId, provider, model, overrides, skipEthics, ethicsRulesDir, audience, modality, regulatoryContext, audienceVulnerability, } = opts;
|
|
37
42
|
const startedAt = Date.now();
|
|
38
43
|
try {
|
|
39
44
|
// ── 1. Load the page ──
|
|
@@ -51,17 +56,36 @@ export async function auditOnePage(opts) {
|
|
|
51
56
|
await page.screenshot({ path: screenshotPath, fullPage: false });
|
|
52
57
|
}
|
|
53
58
|
// ── 3. Classify (or use profile override) ──
|
|
59
|
+
// Layer 1 always produces an ensemble classification — either from the
|
|
60
|
+
// ensemble classifier (URL + DOM + LLM) or synthesized from an explicit
|
|
61
|
+
// profile override. The audit-result builder needs an ensemble shape;
|
|
62
|
+
// restricting it to non-override runs would silently drop the entire
|
|
63
|
+
// multi-dim scoring + patches contract whenever --profile is passed.
|
|
54
64
|
let classification;
|
|
65
|
+
let ensemble;
|
|
55
66
|
if (profileOverride) {
|
|
56
|
-
|
|
57
|
-
classification = {
|
|
67
|
+
const base = {
|
|
58
68
|
...defaultClassification(),
|
|
59
69
|
type: profileOverride,
|
|
60
70
|
confidence: 1,
|
|
61
71
|
};
|
|
72
|
+
ensemble = {
|
|
73
|
+
...base,
|
|
74
|
+
signals: [{
|
|
75
|
+
source: 'llm',
|
|
76
|
+
type: base.type,
|
|
77
|
+
confidence: 1,
|
|
78
|
+
rationale: `operator-supplied profile=${profileOverride}`,
|
|
79
|
+
}],
|
|
80
|
+
signalsAgreed: true,
|
|
81
|
+
ensembleConfidence: 1,
|
|
82
|
+
firstPrinciplesMode: false,
|
|
83
|
+
};
|
|
84
|
+
classification = ensemble;
|
|
62
85
|
}
|
|
63
86
|
else {
|
|
64
|
-
|
|
87
|
+
ensemble = await classifyEnsemble({ brain, state, url });
|
|
88
|
+
classification = ensemble;
|
|
65
89
|
}
|
|
66
90
|
// ── 4. Compose rubric ──
|
|
67
91
|
const rubric = profileOverride
|
|
@@ -89,8 +113,56 @@ export async function auditOnePage(opts) {
|
|
|
89
113
|
auditPasses,
|
|
90
114
|
overrides,
|
|
91
115
|
});
|
|
116
|
+
// ── 7. Ethics gate (Layer 7) — apply rollup floor when rules fire ──
|
|
117
|
+
if (skipEthics) {
|
|
118
|
+
console.warn(`[ethics] --skip-ethics: gate bypassed for ${url} (test-only)`);
|
|
119
|
+
result.ethicsViolations = [];
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
const rules = loadEthicsRules(ethicsRulesDir);
|
|
123
|
+
const ethicsViolations = await checkEthics(rules, {
|
|
124
|
+
pageText: pageTextBlob(state.snapshot, { url, title: state.title }),
|
|
125
|
+
snapshot: state.snapshot,
|
|
126
|
+
classification,
|
|
127
|
+
audience,
|
|
128
|
+
modality,
|
|
129
|
+
regulatoryContext,
|
|
130
|
+
audienceVulnerability,
|
|
131
|
+
}, { brain });
|
|
132
|
+
if (ethicsViolations.length > 0) {
|
|
133
|
+
const minCap = Math.min(...ethicsViolations.map((v) => v.rollupCap));
|
|
134
|
+
if (typeof result.score === 'number' && result.score > minCap) {
|
|
135
|
+
result.preEthicsScore = result.score;
|
|
136
|
+
result.score = minCap;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
result.ethicsViolations = ethicsViolations;
|
|
140
|
+
}
|
|
141
|
+
// ── 8. Layer 1 — multi-dim scoring + rollup ──
|
|
142
|
+
try {
|
|
143
|
+
const anchors = loadAnchors();
|
|
144
|
+
const anchor = anchors.get(ensemble.type);
|
|
145
|
+
const auditResult = await buildAuditResult({
|
|
146
|
+
brain,
|
|
147
|
+
state,
|
|
148
|
+
pageRef: url,
|
|
149
|
+
ensemble,
|
|
150
|
+
rubric,
|
|
151
|
+
measurements,
|
|
152
|
+
v1Result: result,
|
|
153
|
+
anchor,
|
|
154
|
+
runId,
|
|
155
|
+
});
|
|
156
|
+
result.auditResult = auditResult;
|
|
157
|
+
result.ensembleClassification = ensemble;
|
|
158
|
+
}
|
|
159
|
+
catch (buildErr) {
|
|
160
|
+
// Don't let the audit-result builder break the legacy summary. Log + move on.
|
|
161
|
+
console.warn(`[audit] failed to build result for ${url}: ${buildErr.message}`);
|
|
162
|
+
}
|
|
92
163
|
if (runId) {
|
|
93
164
|
const findings = result.findings ?? [];
|
|
165
|
+
const ethicsViolations = result.ethicsViolations ?? [];
|
|
94
166
|
getTelemetry().emit({
|
|
95
167
|
kind: 'design-audit-page',
|
|
96
168
|
runId,
|
|
@@ -127,6 +199,9 @@ export async function auditOnePage(opts) {
|
|
|
127
199
|
contrastAaPassRate: measurements.contrast.summary.aaPassRate,
|
|
128
200
|
a11yViolations: measurements.a11y.violations.length,
|
|
129
201
|
tokensUsed: result.tokensUsed ?? 0,
|
|
202
|
+
ethicsViolations: ethicsViolations.length,
|
|
203
|
+
ethicsCriticalFloor: ethicsViolations.filter((v) => v.severity === 'critical-floor').length,
|
|
204
|
+
ethicsMajorFloor: ethicsViolations.filter((v) => v.severity === 'major-floor').length,
|
|
130
205
|
},
|
|
131
206
|
tags: {
|
|
132
207
|
pageType: classification.type,
|
|
@@ -159,6 +234,7 @@ export async function auditOnePage(opts) {
|
|
|
159
234
|
summary: 'Audit failed',
|
|
160
235
|
strengths: [],
|
|
161
236
|
findings: [],
|
|
237
|
+
ethicsViolations: [],
|
|
162
238
|
error,
|
|
163
239
|
};
|
|
164
240
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../../src/design/audit/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAIjC,OAAO,
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../../src/design/audit/pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anchor loader — Layer 1 of the world-class design-audit architecture.
|
|
3
|
+
*
|
|
4
|
+
* Loads per-page-type calibration anchors from `anchors/<type>.yaml`. Each
|
|
5
|
+
* anchor encodes score-band criteria + reference fixtures so the LLM scores
|
|
6
|
+
* an saas-app like Linear's app, not like Linear's marketing site.
|
|
7
|
+
*
|
|
8
|
+
* Schema:
|
|
9
|
+
* type: <PageType>
|
|
10
|
+
* score_9_10: { criteria: string[], fixtures: string[] }
|
|
11
|
+
* score_7_8: { criteria: string[], fixtures: string[] }
|
|
12
|
+
* score_5_6: { criteria: string[], fixtures: string[] }
|
|
13
|
+
* score_3_4: { criteria: string[], fixtures: string[] }
|
|
14
|
+
*/
|
|
15
|
+
import type { PageType } from '../types.js';
|
|
16
|
+
export interface AnchorBand {
|
|
17
|
+
criteria: string[];
|
|
18
|
+
fixtures: string[];
|
|
19
|
+
}
|
|
20
|
+
export interface CalibrationAnchor {
|
|
21
|
+
type: PageType;
|
|
22
|
+
score_9_10: AnchorBand;
|
|
23
|
+
score_7_8: AnchorBand;
|
|
24
|
+
score_5_6: AnchorBand;
|
|
25
|
+
score_3_4: AnchorBand;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parse one anchor YAML. Uses a minimal YAML reader that handles the shape:
|
|
29
|
+
* type: saas-app
|
|
30
|
+
* score_9_10:
|
|
31
|
+
* criteria:
|
|
32
|
+
* - line one
|
|
33
|
+
* - line two
|
|
34
|
+
* fixtures:
|
|
35
|
+
* - fixture:linear-app
|
|
36
|
+
*
|
|
37
|
+
* Avoids pulling in a YAML dep for ~9 small files. Throws on malformed input.
|
|
38
|
+
*/
|
|
39
|
+
export declare function parseAnchorFile(filePath: string): CalibrationAnchor;
|
|
40
|
+
/** Load all anchors from `anchors/` into a map keyed by PageType. */
|
|
41
|
+
export declare function loadAnchors(dir?: string): Map<PageType, CalibrationAnchor>;
|
|
42
|
+
/** Render an anchor as a markdown block for prompt injection. */
|
|
43
|
+
export declare function renderAnchor(anchor: CalibrationAnchor): string;
|
|
44
|
+
//# sourceMappingURL=anchor-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anchor-loader.d.ts","sourceRoot":"","sources":["../../../../src/design/audit/rubric/anchor-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAK3C,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,CAAA;IACd,UAAU,EAAE,UAAU,CAAA;IACtB,SAAS,EAAE,UAAU,CAAA;IACrB,SAAS,EAAE,UAAU,CAAA;IACrB,SAAS,EAAE,UAAU,CAAA;CACtB;AAID;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAuBnE;AAED,qEAAqE;AACrE,wBAAgB,WAAW,CAAC,GAAG,GAAE,MAAoB,GAAG,GAAG,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CASvF;AAED,iEAAiE;AACjE,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAU9D"}
|