@elitedcs/ghl-mcp 3.82.0 → 3.83.1

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.
@@ -0,0 +1,37 @@
1
+ // These pins are deliberately separate from the refreshable upstream catalogue.
2
+ export const HOUSE_RULE_PINS = Object.freeze({
3
+ AD02: Object.freeze({ source: 'house', check: 'measured', threshold: 18, unit: 'px', medium: 'web' }),
4
+ AD03: Object.freeze({ source: 'house', check: 'measured', threshold: 7, unit: 'contrast ratio', medium: 'web' }),
5
+ AD74: Object.freeze({ source: 'house', check: 'measured', threshold: 0, unit: 'characters', medium: 'both' }),
6
+ });
7
+ export const JUDGED_RULE_IDS = Object.freeze(['AD38', 'AD73', 'AD82', 'AD83']);
8
+ export const DUPLICATE_RULE_PINS = Object.freeze({ AD19: 'W11', AD20: 'W11', AD32: 'W6', AD69: 'W13' });
9
+
10
+ export function assertAntiDefaultContract(catalogue, webRules) {
11
+ const rules = catalogue?.rules;
12
+ if (!Array.isArray(rules) || rules.length !== 83) throw new Error('The anti-default catalogue must contain 83 rules.');
13
+ const byId = new Map(rules.map(rule => [rule.id, rule]));
14
+ for (let i = 1; i <= 83; i++) {
15
+ const id = `AD${String(i).padStart(2, '0')}`;
16
+ if (!byId.has(id)) throw new Error(`The anti-default catalogue is missing ${id}.`);
17
+ }
18
+ for (const [id, pin] of Object.entries(HOUSE_RULE_PINS)) {
19
+ for (const [key, value] of Object.entries(pin)) {
20
+ if (byId.get(id)?.[key] !== value) throw new Error(`House rule ${id} must retain ${key}: ${value}.`);
21
+ }
22
+ }
23
+ const judged = rules.filter(rule => rule.check === 'judged').map(rule => rule.id).sort();
24
+ if (JSON.stringify(judged) !== JSON.stringify(JUDGED_RULE_IDS)) throw new Error('The four judged rules must remain listed and unscored.');
25
+ for (const [id, canonical] of Object.entries(DUPLICATE_RULE_PINS)) {
26
+ if (byId.get(id)?.duplicateOf !== canonical || !webRules.some(rule => rule.id === canonical)) {
27
+ throw new Error(`${id} must reference the existing web rule ${canonical}.`);
28
+ }
29
+ }
30
+ for (const rule of rules) {
31
+ if (rule.duplicateOf && DUPLICATE_RULE_PINS[rule.id] !== rule.duplicateOf) throw new Error(`Unreviewed duplicate mapping for ${rule.id}.`);
32
+ if (!rule.group || !rule.rewrite || !rule.howMeasured) throw new Error(`${rule.id} must retain its measurement and rewrite instructions.`);
33
+ }
34
+ if (!catalogue.howToRead?.independence || !catalogue.boundary?.deliberateOverlap || !catalogue.provenance?.sources?.length) {
35
+ throw new Error('The catalogue must retain its independence, boundary and provenance metadata.');
36
+ }
37
+ }