@mmnto/totem 1.14.10 → 1.14.11

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.
Files changed (47) hide show
  1. package/dist/compile-lesson.d.ts +19 -0
  2. package/dist/compile-lesson.d.ts.map +1 -1
  3. package/dist/compile-lesson.js +193 -43
  4. package/dist/compile-lesson.js.map +1 -1
  5. package/dist/compile-lesson.test.js +277 -1
  6. package/dist/compile-lesson.test.js.map +1 -1
  7. package/dist/compiler-schema.d.ts +31 -0
  8. package/dist/compiler-schema.d.ts.map +1 -1
  9. package/dist/compiler-schema.js +7 -0
  10. package/dist/compiler-schema.js.map +1 -1
  11. package/dist/config-schema.d.ts +41 -0
  12. package/dist/config-schema.d.ts.map +1 -1
  13. package/dist/config-schema.js +33 -0
  14. package/dist/config-schema.js.map +1 -1
  15. package/dist/config-schema.test.js +87 -0
  16. package/dist/config-schema.test.js.map +1 -1
  17. package/dist/index.d.ts +3 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +2 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/ledger.d.ts +10 -0
  22. package/dist/ledger.d.ts.map +1 -1
  23. package/dist/ledger.js +8 -0
  24. package/dist/ledger.js.map +1 -1
  25. package/dist/lesson-pattern.d.ts.map +1 -1
  26. package/dist/lesson-pattern.js +6 -9
  27. package/dist/lesson-pattern.js.map +1 -1
  28. package/dist/pack-merge.d.ts +73 -0
  29. package/dist/pack-merge.d.ts.map +1 -0
  30. package/dist/pack-merge.js +117 -0
  31. package/dist/pack-merge.js.map +1 -0
  32. package/dist/pack-merge.test.d.ts +2 -0
  33. package/dist/pack-merge.test.d.ts.map +1 -0
  34. package/dist/pack-merge.test.js +238 -0
  35. package/dist/pack-merge.test.js.map +1 -0
  36. package/dist/regex-utils.d.ts +5 -0
  37. package/dist/regex-utils.d.ts.map +1 -1
  38. package/dist/regex-utils.js +6 -1
  39. package/dist/regex-utils.js.map +1 -1
  40. package/dist/regex-utils.test.js +15 -2
  41. package/dist/regex-utils.test.js.map +1 -1
  42. package/dist/rule-engine.d.ts.map +1 -1
  43. package/dist/rule-engine.js +3 -0
  44. package/dist/rule-engine.js.map +1 -1
  45. package/dist/rule-engine.test.js +29 -0
  46. package/dist/rule-engine.test.js.map +1 -1
  47. package/package.json +1 -1
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/ledger.d.ts CHANGED
@@ -14,6 +14,14 @@ export declare const LedgerEventSchema: z.ZodObject<{
14
14
  justification: z.ZodDefault<z.ZodString>;
15
15
  /** Source of the event */
16
16
  source: z.ZodEnum<["lint", "shield", "bot"]>;
17
+ /**
18
+ * True when the bypassed rule was shipped by a pack with
19
+ * `immutable: true`. Audit consumers can filter
20
+ * `events.ndjson | jq 'select(.immutable == true)'` to surface every
21
+ * attempt to silence an enforced security rule (ADR-089,
22
+ * mmnto-ai/totem#1485). Absent on events from non-immutable rules.
23
+ */
24
+ immutable: z.ZodOptional<z.ZodBoolean>;
17
25
  }, "strip", z.ZodTypeAny, {
18
26
  type: "suppress" | "override" | "exemption";
19
27
  file: string;
@@ -21,6 +29,7 @@ export declare const LedgerEventSchema: z.ZodObject<{
21
29
  source: "lint" | "shield" | "bot";
22
30
  timestamp: string;
23
31
  ruleId: string;
32
+ immutable?: boolean | undefined;
24
33
  line?: number | undefined;
25
34
  }, {
26
35
  type: "suppress" | "override" | "exemption";
@@ -28,6 +37,7 @@ export declare const LedgerEventSchema: z.ZodObject<{
28
37
  source: "lint" | "shield" | "bot";
29
38
  timestamp: string;
30
39
  ruleId: string;
40
+ immutable?: boolean | undefined;
31
41
  line?: number | undefined;
32
42
  justification?: string | undefined;
33
43
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,iBAAiB;IAC5B,yBAAyB;;IAEzB,uHAAuH;;IAEvH,0DAA0D;;IAE1D,mDAAmD;;IAEnD,8BAA8B;;IAE9B,gHAAgH;;IAEhH,0BAA0B;;;;;;;;;;;;;;;;;;EAE1B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAS5D;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,WAAW,EAClB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC7B,IAAI,CAaN;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,WAAW,EAAE,CAwBhG"}
1
+ {"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,iBAAiB;IAC5B,yBAAyB;;IAEzB,uHAAuH;;IAEvH,0DAA0D;;IAE1D,mDAAmD;;IAEnD,8BAA8B;;IAE9B,gHAAgH;;IAEhH,0BAA0B;;IAE1B;;;;;;OAMG;;;;;;;;;;;;;;;;;;;;EAEH,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAS5D;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,WAAW,EAClB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC7B,IAAI,CAaN;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,WAAW,EAAE,CAwBhG"}
package/dist/ledger.js CHANGED
@@ -17,6 +17,14 @@ export const LedgerEventSchema = z.object({
17
17
  justification: z.string().default(''),
18
18
  /** Source of the event */
19
19
  source: z.enum(['lint', 'shield', 'bot']),
20
+ /**
21
+ * True when the bypassed rule was shipped by a pack with
22
+ * `immutable: true`. Audit consumers can filter
23
+ * `events.ndjson | jq 'select(.immutable == true)'` to surface every
24
+ * attempt to silence an enforced security rule (ADR-089,
25
+ * mmnto-ai/totem#1485). Absent on events from non-immutable rules.
26
+ */
27
+ immutable: z.boolean().optional(),
20
28
  });
21
29
  // ─── Constants ──────────────────────────────────────
22
30
  const LEDGER_DIR = 'ledger';
@@ -1 +1 @@
1
- {"version":3,"file":"ledger.js","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ledger.js","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"lesson-pattern.d.ts","sourceRoot":"","sources":["../src/lesson-pattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,GAAG,KAAK,GAAG,UAAU,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,2FAA2F;IAC3F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA0B5E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA6CrF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAclE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAiEhC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAsDvE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAItE;AAED,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAKrE;AAID,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAyBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAK3E"}
1
+ {"version":3,"file":"lesson-pattern.d.ts","sourceRoot":"","sources":["../src/lesson-pattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,GAAG,KAAK,GAAG,UAAU,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,2FAA2F;IAC3F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA0B5E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA6CrF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAclE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CA6DhC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAsDvE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAItE;AAED,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAKrE;AAID,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAyBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAK3E"}
@@ -11,6 +11,7 @@
11
11
  */
12
12
  import YAML from 'yaml';
13
13
  import { TotemParseError } from './errors.js';
14
+ import { escapeRegex } from './regex-utils.js';
14
15
  export function extractField(body, field) {
15
16
  // Match all common bold/colon variants (#1282 — caught by Shield AI as a
16
17
  // partial-fix consequence of extending extractMultilineField):
@@ -31,7 +32,7 @@ export function extractField(body, field) {
31
32
  // silently rejecting `**Pattern:**foo` (no space) and `**Pattern:**` (empty value).
32
33
  // Caught by gemini-code-assist on PR #1282 as another instance of the
33
34
  // cross-helper-consistency cascade pattern documented in lesson-400fed87.
34
- const safeField = field.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
35
+ const safeField = escapeRegex(field);
35
36
  const re = new RegExp(`^(?:\\*{2})?${safeField}(?:\\*{2})?:(?:\\*{2})?[ \\t]*(.*)$`, 'im');
36
37
  const match = body.match(re);
37
38
  // Trim and treat empty as "no value" so callers' `if (!value)` checks fire correctly.
@@ -54,7 +55,7 @@ export function extractField(body, field) {
54
55
  * Returns the trimmed value, or `undefined` if the field is absent.
55
56
  */
56
57
  export function extractMultilineField(body, field) {
57
- const safeField = field.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
58
+ const safeField = escapeRegex(field);
58
59
  // Match the field's first line. Supports four common forms:
59
60
  // **Field:** ← canonical totem (asterisks both sides of colon)
60
61
  // **Field**: ← alternative markdown convention (asterisks before colon)
@@ -153,11 +154,7 @@ export function extractBadExample(body) {
153
154
  * rules ahead of the 1.15.0 Pack Distribution milestone.
154
155
  */
155
156
  export function extractYamlRuleAfterField(body, field) {
156
- // Replacer function — `'\\$&'` would still parse correctly because `$&`
157
- // expanding to the matched char is exactly the intent, but the function
158
- // form is the safer idiom in substitution-sensitive contexts (matches the
159
- // broader repo convention, GCA catch on mmnto/totem#1454).
160
- const safeField = field.replace(/[.*+?^${}()|[\]\\]/g, (ch) => '\\' + ch);
157
+ const safeField = escapeRegex(field);
161
158
  const startRe = new RegExp(`^(?:\\*{2})?${safeField}(?:\\*{2})?:(?:\\*{2})?.*$`, 'i');
162
159
  // Section terminator — any bold field marker OR any markdown heading stops
163
160
  // the YAML scan. CR catch on mmnto/totem#1454: without the heading guard,
@@ -277,7 +274,7 @@ export function extractManualPattern(body) {
277
274
  * `**Field**:`, `**Field:`, and plain `Field:`.
278
275
  */
279
276
  export function extractAllFields(body, field) {
280
- const safeField = field.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
277
+ const safeField = escapeRegex(field);
281
278
  const re = new RegExp(`^(?:\\*{2})?${safeField}(?:\\*{2})?:(?:\\*{2})?[ \\t]*(.*)$`, 'gim');
282
279
  return Array.from(body.matchAll(re), (m) => m[1].trim());
283
280
  }
@@ -301,7 +298,7 @@ export function extractRuleExamples(body) {
301
298
  * Used internally by extractBadGoodSnippets.
302
299
  */
303
300
  function extractCodeBlock(body, field) {
304
- const safeField = field.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
301
+ const safeField = escapeRegex(field);
305
302
  // Try fenced code block after **Field:** or **Field**: (colon required, inside or outside bold)
306
303
  const fencedRe = new RegExp(`(?:^|\\n)\\*{0,2}${safeField}\\*{0,2}\\s*:[^\\n]*\\n(?:\\s*\\n)*(\`\`\`|~~~)[^\\n]*\\n([\\s\\S]*?)\\1`, 'i');
307
304
  const fencedMatch = body.match(fencedRe);
@@ -1 +1 @@
1
- {"version":3,"file":"lesson-pattern.js","sourceRoot":"","sources":["../src/lesson-pattern.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lesson-pattern.js","sourceRoot":"","sources":["../src/lesson-pattern.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Pack rule merge primitive (ADR-085 + ADR-089, mmnto-ai/totem#1485).
3
+ *
4
+ * The default pack-merge semantic from ADR-085 Resolved Decision 3 is
5
+ * "Local Supreme Authority": when a repo's local `compiled-rules.json`
6
+ * declares the same `lessonHash` as an inherited pack rule, the local
7
+ * entry wins. This preserves the "my repo, my rules" principle.
8
+ *
9
+ * ADR-089 carves out a narrow exception: rules shipped by a pack with
10
+ * `immutable: true` AND `severity: 'error'` cannot be locally downgraded
11
+ * or archived. Security packs like `@totem/pack-agent-security` rely on
12
+ * this contract to guarantee that enforcement cannot be silently weakened
13
+ * by a motivated local override.
14
+ *
15
+ * This module is the pure primitive that encodes both rules. It does
16
+ * NOT know about pack install paths, config resolution, or the filesystem —
17
+ * callers hand it two arrays and receive the merged array back. Phase C
18
+ * will wire a consumer (`totem install` + pack-config resolution) around
19
+ * this primitive. Until then the logic is fully unit-tested in memory so
20
+ * the enforcement contract is ready the day pack distribution lands.
21
+ */
22
+ import type { CompiledRule } from './compiler-schema.js';
23
+ /**
24
+ * Explains why a local override was refused. Accumulated into the merge
25
+ * result so callers can surface every blocked attempt without swallowing
26
+ * the detail. Useful for `totem install` diagnostics and for the Trap
27
+ * Ledger snapshot a future pack-build flow may capture.
28
+ */
29
+ export interface ImmutableOverrideBlock {
30
+ /** The lessonHash of the immutable pack rule whose local override was rejected. */
31
+ lessonHash: string;
32
+ /** Human-readable name for log output. */
33
+ lessonHeading: string;
34
+ /** Which aspect of the local rule the merge refused to honor. */
35
+ attemptedChange: 'severity-downgrade' | 'archive' | 'both';
36
+ /** The severity the local rule tried to set. Absent for archive-only overrides. */
37
+ attemptedSeverity?: 'warning' | 'error';
38
+ /** The severity the pack enforces. Always 'error' — immutable is currently error-only. */
39
+ enforcedSeverity: 'error';
40
+ }
41
+ export interface MergeRulesResult {
42
+ /** The merged rule array. One entry per unique `lessonHash`. */
43
+ rules: CompiledRule[];
44
+ /**
45
+ * Immutable overrides the merge blocked. Empty when no local rule tried
46
+ * to downgrade or archive an immutable pack rule. Callers that want a
47
+ * hard error on any blocked override can check `blocks.length > 0`.
48
+ */
49
+ blocks: ImmutableOverrideBlock[];
50
+ }
51
+ /**
52
+ * Merge local and pack rule arrays according to ADR-085 + ADR-089 semantics.
53
+ *
54
+ * Precedence:
55
+ * - When a `lessonHash` appears in both arrays, local wins (ADR-085
56
+ * Local Supreme Authority)
57
+ * - EXCEPT when the pack rule carries `immutable: true` AND
58
+ * `severity: 'error'`: the pack's severity is preserved and any local
59
+ * `status: 'archived'` is cleared back to active. The rest of the
60
+ * local rule's shape (pattern, message, fileGlobs, badExample) is
61
+ * still honored — immutable protects the enforcement knob, not the
62
+ * rule body. A pack author that needs to freeze the pattern as well
63
+ * should simply ship the rule without a matching local entry.
64
+ *
65
+ * Non-immutable pack rules follow pure local precedence: the local entry
66
+ * replaces the pack entry byte-for-byte.
67
+ *
68
+ * Rules that appear only in `packRules` are appended as-is. Rules that
69
+ * appear only in `localRules` are emitted as-is. Pure function — does
70
+ * not mutate its inputs.
71
+ */
72
+ export declare function mergeRules(localRules: readonly CompiledRule[], packRules: readonly CompiledRule[]): MergeRulesResult;
73
+ //# sourceMappingURL=pack-merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-merge.d.ts","sourceRoot":"","sources":["../src/pack-merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIzD;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,mFAAmF;IACnF,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,eAAe,EAAE,oBAAoB,GAAG,SAAS,GAAG,MAAM,CAAC;IAC3D,mFAAmF;IACnF,iBAAiB,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IACxC,0FAA0F;IAC1F,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,gEAAgE;IAChE,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB;;;;OAIG;IACH,MAAM,EAAE,sBAAsB,EAAE,CAAC;CAClC;AAID;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,UAAU,CACxB,UAAU,EAAE,SAAS,YAAY,EAAE,EACnC,SAAS,EAAE,SAAS,YAAY,EAAE,GACjC,gBAAgB,CAoFlB"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Pack rule merge primitive (ADR-085 + ADR-089, mmnto-ai/totem#1485).
3
+ *
4
+ * The default pack-merge semantic from ADR-085 Resolved Decision 3 is
5
+ * "Local Supreme Authority": when a repo's local `compiled-rules.json`
6
+ * declares the same `lessonHash` as an inherited pack rule, the local
7
+ * entry wins. This preserves the "my repo, my rules" principle.
8
+ *
9
+ * ADR-089 carves out a narrow exception: rules shipped by a pack with
10
+ * `immutable: true` AND `severity: 'error'` cannot be locally downgraded
11
+ * or archived. Security packs like `@totem/pack-agent-security` rely on
12
+ * this contract to guarantee that enforcement cannot be silently weakened
13
+ * by a motivated local override.
14
+ *
15
+ * This module is the pure primitive that encodes both rules. It does
16
+ * NOT know about pack install paths, config resolution, or the filesystem —
17
+ * callers hand it two arrays and receive the merged array back. Phase C
18
+ * will wire a consumer (`totem install` + pack-config resolution) around
19
+ * this primitive. Until then the logic is fully unit-tested in memory so
20
+ * the enforcement contract is ready the day pack distribution lands.
21
+ */
22
+ // ─── Merge ──────────────────────────────────────────
23
+ /**
24
+ * Merge local and pack rule arrays according to ADR-085 + ADR-089 semantics.
25
+ *
26
+ * Precedence:
27
+ * - When a `lessonHash` appears in both arrays, local wins (ADR-085
28
+ * Local Supreme Authority)
29
+ * - EXCEPT when the pack rule carries `immutable: true` AND
30
+ * `severity: 'error'`: the pack's severity is preserved and any local
31
+ * `status: 'archived'` is cleared back to active. The rest of the
32
+ * local rule's shape (pattern, message, fileGlobs, badExample) is
33
+ * still honored — immutable protects the enforcement knob, not the
34
+ * rule body. A pack author that needs to freeze the pattern as well
35
+ * should simply ship the rule without a matching local entry.
36
+ *
37
+ * Non-immutable pack rules follow pure local precedence: the local entry
38
+ * replaces the pack entry byte-for-byte.
39
+ *
40
+ * Rules that appear only in `packRules` are appended as-is. Rules that
41
+ * appear only in `localRules` are emitted as-is. Pure function — does
42
+ * not mutate its inputs.
43
+ */
44
+ export function mergeRules(localRules, packRules) {
45
+ const localByHash = new Map();
46
+ for (const rule of localRules) {
47
+ localByHash.set(rule.lessonHash, rule);
48
+ }
49
+ const merged = [];
50
+ const blocks = [];
51
+ const consumedLocalHashes = new Set();
52
+ for (const packRule of packRules) {
53
+ const localRule = localByHash.get(packRule.lessonHash);
54
+ if (!localRule) {
55
+ // No local override — pack rule lands as-is.
56
+ merged.push(packRule);
57
+ continue;
58
+ }
59
+ consumedLocalHashes.add(packRule.lessonHash);
60
+ const isEnforcedImmutable = packRule.immutable === true && (packRule.severity ?? 'warning') === 'error';
61
+ if (!isEnforcedImmutable) {
62
+ // ADR-085 default: local overrides pack byte-for-byte.
63
+ merged.push(localRule);
64
+ continue;
65
+ }
66
+ // Immutable carve-out (ADR-089). Start from the local rule, then
67
+ // force severity and clear archive status if the local attempted
68
+ // either of those. An omitted `localRule.severity` is NOT treated as
69
+ // a downgrade attempt — the local override is opting out of
70
+ // opinionating on severity, not declaring a lower one. Only an
71
+ // explicit `'warning'` counts. (Runtime severity defaults vary
72
+ // across consumers; finding.ts defaults to 'error' while
73
+ // compile-lesson.ts defaults to 'warning', so inferring a downgrade
74
+ // from absence would produce bogus blocks.)
75
+ const attemptedSeverityDowngrade = localRule.severity === 'warning';
76
+ const attemptedArchive = localRule.status === 'archived';
77
+ if (attemptedSeverityDowngrade || attemptedArchive) {
78
+ const attemptedChange = attemptedSeverityDowngrade && attemptedArchive
79
+ ? 'both'
80
+ : attemptedSeverityDowngrade
81
+ ? 'severity-downgrade'
82
+ : 'archive';
83
+ const block = {
84
+ lessonHash: packRule.lessonHash,
85
+ lessonHeading: packRule.lessonHeading,
86
+ attemptedChange,
87
+ enforcedSeverity: 'error',
88
+ };
89
+ if (attemptedSeverityDowngrade) {
90
+ block.attemptedSeverity = 'warning';
91
+ }
92
+ blocks.push(block);
93
+ }
94
+ // Build the enforced rule. Preserve the local rule's pattern / body
95
+ // (immutable protects severity, not code content), but force the
96
+ // pack's severity and clear any archive flag. Preserve local
97
+ // `archivedReason` removal by not copying the field forward.
98
+ const enforced = {
99
+ ...localRule,
100
+ severity: 'error',
101
+ immutable: true,
102
+ };
103
+ if (enforced.status === 'archived') {
104
+ enforced.status = 'active';
105
+ delete enforced.archivedReason;
106
+ }
107
+ merged.push(enforced);
108
+ }
109
+ // Emit local-only rules that no pack rule claimed.
110
+ for (const rule of localRules) {
111
+ if (!consumedLocalHashes.has(rule.lessonHash)) {
112
+ merged.push(rule);
113
+ }
114
+ }
115
+ return { rules: merged, blocks };
116
+ }
117
+ //# sourceMappingURL=pack-merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-merge.js","sourceRoot":"","sources":["../src/pack-merge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pack-merge.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-merge.test.d.ts","sourceRoot":"","sources":["../src/pack-merge.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,238 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { mergeRules } from './pack-merge.js';
3
+ // ─── Helpers ────────────────────────────────────────
4
+ const baseRule = (overrides) => ({
5
+ lessonHeading: 'test-rule',
6
+ message: 'test message',
7
+ pattern: 'pattern-x',
8
+ engine: 'regex',
9
+ compiledAt: '2026-04-17T00:00:00Z',
10
+ ...overrides,
11
+ });
12
+ // ─── Tests ──────────────────────────────────────────
13
+ describe('mergeRules', () => {
14
+ it('emits pack-only rules unchanged', () => {
15
+ const packRule = baseRule({ lessonHash: 'pack-only' });
16
+ const { rules, blocks } = mergeRules([], [packRule]);
17
+ expect(rules).toEqual([packRule]);
18
+ expect(blocks).toEqual([]);
19
+ });
20
+ it('emits local-only rules unchanged', () => {
21
+ const localRule = baseRule({ lessonHash: 'local-only' });
22
+ const { rules, blocks } = mergeRules([localRule], []);
23
+ expect(rules).toEqual([localRule]);
24
+ expect(blocks).toEqual([]);
25
+ });
26
+ it('returns empty result on empty inputs', () => {
27
+ const { rules, blocks } = mergeRules([], []);
28
+ expect(rules).toEqual([]);
29
+ expect(blocks).toEqual([]);
30
+ });
31
+ it('local rule overrides pack rule when pack is not immutable (ADR-085 default)', () => {
32
+ const packRule = baseRule({
33
+ lessonHash: 'shared',
34
+ severity: 'error',
35
+ message: 'pack message',
36
+ });
37
+ const localRule = baseRule({
38
+ lessonHash: 'shared',
39
+ severity: 'warning',
40
+ message: 'local message',
41
+ });
42
+ const { rules, blocks } = mergeRules([localRule], [packRule]);
43
+ expect(rules).toEqual([localRule]);
44
+ expect(blocks).toEqual([]);
45
+ });
46
+ it('forces pack severity when local downgrades an immutable+error pack rule', () => {
47
+ const packRule = baseRule({
48
+ lessonHash: 'immut',
49
+ immutable: true,
50
+ severity: 'error',
51
+ message: 'pack enforcement',
52
+ });
53
+ const localRule = baseRule({
54
+ lessonHash: 'immut',
55
+ severity: 'warning',
56
+ message: 'local tries to downgrade',
57
+ });
58
+ const { rules, blocks } = mergeRules([localRule], [packRule]);
59
+ expect(rules).toHaveLength(1);
60
+ expect(rules[0].severity).toBe('error');
61
+ expect(rules[0].immutable).toBe(true);
62
+ // Pattern / message bodies come from the local rule — immutable
63
+ // protects the enforcement knob, not the rule content.
64
+ expect(rules[0].message).toBe('local tries to downgrade');
65
+ expect(blocks).toEqual([
66
+ {
67
+ lessonHash: 'immut',
68
+ lessonHeading: 'test-rule',
69
+ attemptedChange: 'severity-downgrade',
70
+ attemptedSeverity: 'warning',
71
+ enforcedSeverity: 'error',
72
+ },
73
+ ]);
74
+ });
75
+ it('blocks archive attempt on an immutable+error pack rule and restores active status', () => {
76
+ const packRule = baseRule({
77
+ lessonHash: 'immut-archive',
78
+ immutable: true,
79
+ severity: 'error',
80
+ });
81
+ const localRule = baseRule({
82
+ lessonHash: 'immut-archive',
83
+ severity: 'error',
84
+ status: 'archived',
85
+ archivedReason: 'local tried to archive a security rule',
86
+ });
87
+ const { rules, blocks } = mergeRules([localRule], [packRule]);
88
+ expect(rules).toHaveLength(1);
89
+ expect(rules[0].severity).toBe('error');
90
+ expect(rules[0].status).toBe('active');
91
+ expect(rules[0].archivedReason).toBeUndefined();
92
+ expect(blocks).toEqual([
93
+ {
94
+ lessonHash: 'immut-archive',
95
+ lessonHeading: 'test-rule',
96
+ attemptedChange: 'archive',
97
+ enforcedSeverity: 'error',
98
+ },
99
+ ]);
100
+ });
101
+ it('blocks combined downgrade + archive attempt with attemptedChange: both', () => {
102
+ const packRule = baseRule({
103
+ lessonHash: 'immut-both',
104
+ immutable: true,
105
+ severity: 'error',
106
+ });
107
+ const localRule = baseRule({
108
+ lessonHash: 'immut-both',
109
+ severity: 'warning',
110
+ status: 'archived',
111
+ archivedReason: 'double override attempt',
112
+ });
113
+ const { rules, blocks } = mergeRules([localRule], [packRule]);
114
+ expect(rules).toHaveLength(1);
115
+ expect(rules[0].severity).toBe('error');
116
+ expect(rules[0].status).toBe('active');
117
+ expect(rules[0].archivedReason).toBeUndefined();
118
+ expect(blocks).toHaveLength(1);
119
+ expect(blocks[0].attemptedChange).toBe('both');
120
+ expect(blocks[0].attemptedSeverity).toBe('warning');
121
+ });
122
+ it('does not force severity when pack is immutable but severity is not error', () => {
123
+ // Immutable currently protects error-level rules only. A pack that
124
+ // declares immutable: true + severity: 'warning' communicates intent
125
+ // but the merge falls back to local precedence — no block reported.
126
+ const packRule = baseRule({
127
+ lessonHash: 'immut-warn',
128
+ immutable: true,
129
+ severity: 'warning',
130
+ });
131
+ const localRule = baseRule({
132
+ lessonHash: 'immut-warn',
133
+ severity: 'warning',
134
+ status: 'archived',
135
+ });
136
+ const { rules, blocks } = mergeRules([localRule], [packRule]);
137
+ expect(rules).toEqual([localRule]);
138
+ expect(blocks).toEqual([]);
139
+ });
140
+ it('does not treat an omitted local severity as a downgrade attempt', () => {
141
+ // CR finding on #1515: defaulting omitted localRule.severity to
142
+ // 'warning' records bogus blocks for local overrides that simply
143
+ // don't opine on severity. Runtime consumers disagree on the default
144
+ // (finding.ts uses 'error', compile-lesson.ts uses 'warning'), so
145
+ // absence is ambiguous — only an explicit 'warning' counts as a
146
+ // downgrade. The merged rule still gets the pack's 'error' forced.
147
+ const packRule = baseRule({
148
+ lessonHash: 'immut-implicit',
149
+ immutable: true,
150
+ severity: 'error',
151
+ });
152
+ const localRule = baseRule({
153
+ lessonHash: 'immut-implicit',
154
+ // severity intentionally omitted — local has no opinion
155
+ message: 'local refines message only',
156
+ });
157
+ const { rules, blocks } = mergeRules([localRule], [packRule]);
158
+ expect(rules).toHaveLength(1);
159
+ expect(rules[0].severity).toBe('error');
160
+ expect(rules[0].immutable).toBe(true);
161
+ expect(rules[0].message).toBe('local refines message only');
162
+ expect(blocks).toEqual([]);
163
+ });
164
+ it('emits no block when the local rule does not attempt to downgrade or archive', () => {
165
+ const packRule = baseRule({
166
+ lessonHash: 'immut-noop',
167
+ immutable: true,
168
+ severity: 'error',
169
+ });
170
+ const localRule = baseRule({
171
+ lessonHash: 'immut-noop',
172
+ severity: 'error',
173
+ message: 'local refines message but keeps severity',
174
+ });
175
+ const { rules, blocks } = mergeRules([localRule], [packRule]);
176
+ expect(rules).toHaveLength(1);
177
+ expect(rules[0].severity).toBe('error');
178
+ expect(rules[0].message).toBe('local refines message but keeps severity');
179
+ expect(rules[0].immutable).toBe(true);
180
+ expect(blocks).toEqual([]);
181
+ });
182
+ it('preserves deterministic ordering: pack rules first, then local-only rules', () => {
183
+ const pack1 = baseRule({ lessonHash: 'p1' });
184
+ const pack2 = baseRule({ lessonHash: 'p2' });
185
+ const localOverlap = baseRule({ lessonHash: 'p1', message: 'overrides pack1' });
186
+ const localOnly1 = baseRule({ lessonHash: 'l1' });
187
+ const localOnly2 = baseRule({ lessonHash: 'l2' });
188
+ const { rules } = mergeRules([localOverlap, localOnly1, localOnly2], [pack1, pack2]);
189
+ const hashes = rules.map((r) => r.lessonHash);
190
+ expect(hashes).toEqual(['p1', 'p2', 'l1', 'l2']);
191
+ expect(rules[0].message).toBe('overrides pack1');
192
+ });
193
+ it('is a pure function — inputs are not mutated', () => {
194
+ const packRule = baseRule({
195
+ lessonHash: 'immut',
196
+ immutable: true,
197
+ severity: 'error',
198
+ });
199
+ const localRule = baseRule({
200
+ lessonHash: 'immut',
201
+ severity: 'warning',
202
+ status: 'archived',
203
+ archivedReason: 'audit',
204
+ });
205
+ const packSnapshot = JSON.stringify(packRule);
206
+ const localSnapshot = JSON.stringify(localRule);
207
+ mergeRules([localRule], [packRule]);
208
+ expect(JSON.stringify(packRule)).toBe(packSnapshot);
209
+ expect(JSON.stringify(localRule)).toBe(localSnapshot);
210
+ });
211
+ it('handles multiple immutable pack rules with mixed override attempts', () => {
212
+ const p1 = baseRule({
213
+ lessonHash: 'p1',
214
+ immutable: true,
215
+ severity: 'error',
216
+ });
217
+ const p2 = baseRule({
218
+ lessonHash: 'p2',
219
+ immutable: true,
220
+ severity: 'error',
221
+ });
222
+ const p3 = baseRule({
223
+ lessonHash: 'p3',
224
+ immutable: true,
225
+ severity: 'error',
226
+ });
227
+ const l1 = baseRule({ lessonHash: 'p1', severity: 'warning' });
228
+ const l2 = baseRule({ lessonHash: 'p2', status: 'archived' });
229
+ // p3 has no local override — no block, emits pack rule as-is.
230
+ const { rules, blocks } = mergeRules([l1, l2], [p1, p2, p3]);
231
+ expect(rules).toHaveLength(3);
232
+ expect(rules.every((r) => r.severity === 'error')).toBe(true);
233
+ expect(rules.every((r) => r.status !== 'archived')).toBe(true);
234
+ expect(blocks).toHaveLength(2);
235
+ expect(blocks.map((b) => b.lessonHash).sort()).toEqual(['p1', 'p2']);
236
+ });
237
+ });
238
+ //# sourceMappingURL=pack-merge.test.js.map