@mmnto/totem 1.40.2 → 1.42.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.
Files changed (40) hide show
  1. package/dist/badge-verifier.d.ts +60 -0
  2. package/dist/badge-verifier.d.ts.map +1 -0
  3. package/dist/badge-verifier.js +228 -0
  4. package/dist/badge-verifier.js.map +1 -0
  5. package/dist/badge-verifier.test.d.ts +2 -0
  6. package/dist/badge-verifier.test.d.ts.map +1 -0
  7. package/dist/badge-verifier.test.js +264 -0
  8. package/dist/badge-verifier.test.js.map +1 -0
  9. package/dist/compile-manifest.d.ts +3 -0
  10. package/dist/compile-manifest.d.ts.map +1 -1
  11. package/dist/compile-manifest.js +4 -0
  12. package/dist/compile-manifest.js.map +1 -1
  13. package/dist/compile-manifest.test.js +32 -0
  14. package/dist/compile-manifest.test.js.map +1 -1
  15. package/dist/compile-worker-fingerprint.d.ts +66 -0
  16. package/dist/compile-worker-fingerprint.d.ts.map +1 -0
  17. package/dist/compile-worker-fingerprint.js +59 -0
  18. package/dist/compile-worker-fingerprint.js.map +1 -0
  19. package/dist/compile-worker-fingerprint.test.d.ts +2 -0
  20. package/dist/compile-worker-fingerprint.test.d.ts.map +1 -0
  21. package/dist/compile-worker-fingerprint.test.js +128 -0
  22. package/dist/compile-worker-fingerprint.test.js.map +1 -0
  23. package/dist/errors.d.ts +1 -1
  24. package/dist/errors.d.ts.map +1 -1
  25. package/dist/errors.js.map +1 -1
  26. package/dist/index.d.ts +5 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +3 -1
  29. package/dist/index.js.map +1 -1
  30. package/dist/ledger.d.ts +7 -3
  31. package/dist/ledger.d.ts.map +1 -1
  32. package/dist/ledger.js +5 -0
  33. package/dist/ledger.js.map +1 -1
  34. package/dist/sys/git.d.ts +14 -0
  35. package/dist/sys/git.d.ts.map +1 -1
  36. package/dist/sys/git.js +29 -0
  37. package/dist/sys/git.js.map +1 -1
  38. package/dist/sys/git.test.js +66 -2
  39. package/dist/sys/git.test.js.map +1 -1
  40. package/package.json +1 -1
@@ -0,0 +1,60 @@
1
+ import { z } from 'zod';
2
+ export declare const ToolIntegrationConfigSchema: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "atleastone">>;
3
+ export declare const BadgeVerificationResultSchema: z.ZodObject<{
4
+ valid: z.ZodBoolean;
5
+ errors: z.ZodArray<z.ZodString, "many">;
6
+ warnings: z.ZodArray<z.ZodString, "many">;
7
+ }, "strip", z.ZodTypeAny, {
8
+ valid: boolean;
9
+ warnings: string[];
10
+ errors: string[];
11
+ }, {
12
+ valid: boolean;
13
+ warnings: string[];
14
+ errors: string[];
15
+ }>;
16
+ export type ToolIntegrationConfig = z.infer<typeof ToolIntegrationConfigSchema>;
17
+ export type BadgeVerificationResult = z.infer<typeof BadgeVerificationResultSchema>;
18
+ export declare const DEFAULT_TOOL_INTEGRATIONS: ToolIntegrationConfig;
19
+ export interface ExtractedBadge {
20
+ rawUrl: string;
21
+ altText: string;
22
+ label: string;
23
+ message: string;
24
+ linkTarget?: string;
25
+ file: string;
26
+ lineNumber: number;
27
+ }
28
+ /**
29
+ * Extract shields.io badges from added (`+`) lines of a unified diff,
30
+ * filtered to `README.md` only. Stateless — recomputes from diff each
31
+ * invocation (ADR-083: no SHA-stamped flag files).
32
+ */
33
+ export declare function extractBadgesFromDiff(diff: string): ExtractedBadge[];
34
+ /**
35
+ * Predicate used by `verifyToolClaims` to determine whether a tool-integration
36
+ * file/directory exists at the given absolute path. Injectable for tests;
37
+ * production callers pass `fs.existsSync` (the default).
38
+ */
39
+ export type PathExistsPredicate = (absolutePath: string) => boolean;
40
+ /**
41
+ * For each badge, check whether any tool name from `config` appears in the
42
+ * decoded label or message (case-insensitive, word-boundary match). For every
43
+ * matched tool, require that at least one of its configured paths exists in
44
+ * `repoRoot`. Missing tools become errors.
45
+ *
46
+ * Falsifying metric: existence of at least one config-listed path satisfies
47
+ * the badge's tool-integration claim.
48
+ */
49
+ export declare function verifyToolClaims(badges: ExtractedBadge[], config: ToolIntegrationConfig, repoRoot: string, exists?: PathExistsPredicate): string[];
50
+ /**
51
+ * Flag standard-claim badges (AGENTS.md, MIT, Apache 2.0, etc.) whose link
52
+ * target points at internal repo paths instead of the canonical upstream
53
+ * standard. This is the failure class from mmnto-ai/totem#1925 R2.
54
+ *
55
+ * Standard claims are recognized in EITHER the label or the message position
56
+ * to catch both `[![AGENTS.md](.../AGENTS.md-compliant-...)](./AGENTS.md)` and
57
+ * `[![Tool-agnostic](.../Tool--agnostic-AGENTS.md-...)](./AGENTS.md)`.
58
+ */
59
+ export declare function verifySelfReferenceLinks(badges: ExtractedBadge[]): string[];
60
+ //# sourceMappingURL=badge-verifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge-verifier.d.ts","sourceRoot":"","sources":["../src/badge-verifier.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,2BAA2B,iEAAuD,CAAC;AAEhG,eAAO,MAAM,6BAA6B;;;;;;;;;;;;EAIxC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAChF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAIpF,eAAO,MAAM,yBAAyB,EAAE,qBAMvC,CAAC;AAIF,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAKD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CAsCpE;AAID;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC;AAEpE;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,cAAc,EAAE,EACxB,MAAM,EAAE,qBAAqB,EAC7B,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,mBAAmC,GAC1C,MAAM,EAAE,CAuCV;AA+CD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CAY3E"}
@@ -0,0 +1,228 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { z } from 'zod';
4
+ import { extractAddedLines } from './diff-parser.js';
5
+ // ─── Schemas ────────────────────────────────────────
6
+ export const ToolIntegrationConfigSchema = z.record(z.string(), z.array(z.string()).nonempty());
7
+ export const BadgeVerificationResultSchema = z.object({
8
+ valid: z.boolean(),
9
+ errors: z.array(z.string()),
10
+ warnings: z.array(z.string()),
11
+ });
12
+ // ─── Default integration matrix (mmnto-ai/totem#1924) ───
13
+ export const DEFAULT_TOOL_INTEGRATIONS = {
14
+ claude: ['.claude/', 'CLAUDE.md'],
15
+ gemini: ['.gemini/', 'GEMINI.md'],
16
+ cursor: ['.cursor/', '.cursorrules'],
17
+ windsurf: ['.windsurfrules', '.windsurf/'],
18
+ copilot: ['.github/copilot-instructions.md'],
19
+ };
20
+ const BADGE_IMAGE_RE = /!\[([^\]]*)\]\((https:\/\/img\.shields\.io\/badge\/[^)\s"]+)\)/g;
21
+ const WRAP_TAIL_RE = /^\]\(([^)\s"]+)\)/;
22
+ /**
23
+ * Extract shields.io badges from added (`+`) lines of a unified diff,
24
+ * filtered to `README.md` only. Stateless — recomputes from diff each
25
+ * invocation (ADR-083: no SHA-stamped flag files).
26
+ */
27
+ export function extractBadgesFromDiff(diff) {
28
+ if (!diff)
29
+ return [];
30
+ const additions = extractAddedLines(diff);
31
+ const badges = [];
32
+ for (const addition of additions) {
33
+ if (addition.file !== 'README.md')
34
+ continue;
35
+ const line = addition.line;
36
+ for (const match of line.matchAll(BADGE_IMAGE_RE)) {
37
+ const altText = match[1] ?? '';
38
+ const url = match[2] ?? '';
39
+ const start = match.index ?? 0;
40
+ const end = start + match[0].length;
41
+ let linkTarget;
42
+ // Wrapped form `[![alt](url)](target)`: precede by `[`, follow with `](target)`
43
+ if (line[start - 1] === '[') {
44
+ const after = line.slice(end);
45
+ const wrap = WRAP_TAIL_RE.exec(after);
46
+ if (wrap) {
47
+ linkTarget = wrap[1];
48
+ }
49
+ }
50
+ const { label, message } = decodeBadgeUrl(url);
51
+ badges.push({
52
+ rawUrl: url,
53
+ altText,
54
+ label,
55
+ message,
56
+ linkTarget,
57
+ file: addition.file,
58
+ lineNumber: addition.lineNumber,
59
+ });
60
+ }
61
+ }
62
+ return badges;
63
+ }
64
+ /**
65
+ * For each badge, check whether any tool name from `config` appears in the
66
+ * decoded label or message (case-insensitive, word-boundary match). For every
67
+ * matched tool, require that at least one of its configured paths exists in
68
+ * `repoRoot`. Missing tools become errors.
69
+ *
70
+ * Falsifying metric: existence of at least one config-listed path satisfies
71
+ * the badge's tool-integration claim.
72
+ */
73
+ export function verifyToolClaims(badges, config, repoRoot, exists = fs.existsSync) {
74
+ const errors = [];
75
+ const reported = new Set();
76
+ const toolKeys = Object.keys(config);
77
+ for (const badge of badges) {
78
+ const haystack = `${badge.label} ${badge.message}`.toLowerCase();
79
+ for (const tool of toolKeys) {
80
+ const key = tool.toLowerCase();
81
+ const wordBoundary = new RegExp(`\\b${escapeRegExp(key)}\\b`);
82
+ if (!wordBoundary.test(haystack))
83
+ continue;
84
+ const candidatePaths = config[tool] ?? [];
85
+ // Resolve and constrain to repoRoot — a path like '../CLAUDE.md' would
86
+ // satisfy the claim with a file OUTSIDE the repo, defeating the falsifying
87
+ // metric. Drop paths that escape the repo before existence-checking.
88
+ const anyExists = candidatePaths.some((rel) => {
89
+ const resolved = path.resolve(repoRoot, rel);
90
+ const repoRootResolved = path.resolve(repoRoot);
91
+ const sep = path.sep;
92
+ if (resolved !== repoRootResolved && !resolved.startsWith(repoRootResolved + sep)) {
93
+ return false;
94
+ }
95
+ return exists(resolved);
96
+ });
97
+ if (anyExists)
98
+ continue;
99
+ const dedupKey = `${badge.rawUrl}|${key}`;
100
+ if (reported.has(dedupKey))
101
+ continue;
102
+ reported.add(dedupKey);
103
+ const expected = candidatePaths.join(', ');
104
+ errors.push(`Badge at README.md:${badge.lineNumber} claims integration with "${tool}" but none of the expected paths exist in the repo: ${expected}`);
105
+ }
106
+ }
107
+ return errors;
108
+ }
109
+ function escapeRegExp(s) {
110
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
111
+ }
112
+ // ─── Self-reference link verification ───────────────
113
+ /**
114
+ * Standard-claim labels — badges that assert compliance with an external
115
+ * spec/license. When these claims appear, the badge's link target must point
116
+ * at the canonical upstream, not at internal repo paths (the "circular claim"
117
+ * trap from mmnto-ai/totem#1925 R2).
118
+ */
119
+ const STANDARD_CLAIM_LABELS = new Set([
120
+ 'agents.md',
121
+ 'mit',
122
+ 'apache 2.0',
123
+ 'apache-2.0',
124
+ 'apache2.0',
125
+ 'bsd',
126
+ 'bsd-2-clause',
127
+ 'bsd-3-clause',
128
+ 'gpl',
129
+ 'gpl-3.0',
130
+ 'mpl',
131
+ 'mpl-2.0',
132
+ ]);
133
+ /**
134
+ * A link target is "internal" if either:
135
+ * - it has no HTTP(S) scheme (bare/relative path: `AGENTS.md`, `./AGENTS.md`,
136
+ * `../docs/foo.md`, `LICENSE`, `docs/ADR-038.md`), OR
137
+ * - it's a fully-qualified URL into a `mmnto-ai/...` GitHub path (self-reference
138
+ * for this org — the catalyst class from mmnto-ai/totem#1925 R2).
139
+ *
140
+ * The `mmnto-ai/` pattern is intentionally hardcoded for this PR's scope and
141
+ * tracked as a follow-up: GCA's review on #1934 flagged this as core-pack coupling
142
+ * to a single user. Resolution path is configuration via `totem.config.ts`
143
+ * (e.g., a `selfLinkOrgs: string[]` field) — see the PR description.
144
+ */
145
+ function isInternalLinkTarget(target) {
146
+ if (!/^https?:\/\//i.test(target))
147
+ return true;
148
+ if (/\bmmnto-ai\//i.test(target))
149
+ return true;
150
+ return false;
151
+ }
152
+ /**
153
+ * Flag standard-claim badges (AGENTS.md, MIT, Apache 2.0, etc.) whose link
154
+ * target points at internal repo paths instead of the canonical upstream
155
+ * standard. This is the failure class from mmnto-ai/totem#1925 R2.
156
+ *
157
+ * Standard claims are recognized in EITHER the label or the message position
158
+ * to catch both `[![AGENTS.md](.../AGENTS.md-compliant-...)](./AGENTS.md)` and
159
+ * `[![Tool-agnostic](.../Tool--agnostic-AGENTS.md-...)](./AGENTS.md)`.
160
+ */
161
+ export function verifySelfReferenceLinks(badges) {
162
+ const errors = [];
163
+ for (const badge of badges) {
164
+ if (!badge.linkTarget)
165
+ continue;
166
+ const claim = findStandardClaim(badge);
167
+ if (!claim)
168
+ continue;
169
+ if (!isInternalLinkTarget(badge.linkTarget))
170
+ continue;
171
+ errors.push(`Badge at README.md:${badge.lineNumber} claims "${claim}" but links to internal path "${badge.linkTarget}". Standard-claim badges must link to the canonical upstream (e.g., https://agents.md/, https://opensource.org/licenses/MIT).`);
172
+ }
173
+ return errors;
174
+ }
175
+ function findStandardClaim(badge) {
176
+ for (const field of [badge.label, badge.message]) {
177
+ const key = field.toLowerCase().trim();
178
+ if (STANDARD_CLAIM_LABELS.has(key))
179
+ return field;
180
+ }
181
+ return null;
182
+ }
183
+ // ─── shields.io URL decoding ────────────────────────
184
+ function decodeBadgeUrl(url) {
185
+ const m = url.match(/\/badge\/(.+)$/);
186
+ if (!m)
187
+ return { label: '', message: '' };
188
+ let path = m[1] ?? '';
189
+ const queryIdx = path.indexOf('?');
190
+ if (queryIdx >= 0)
191
+ path = path.slice(0, queryIdx);
192
+ path = path.replace(/\.svg$/, '');
193
+ // Split on unescaped single dashes; `--` is the shields.io escape for literal `-`.
194
+ const parts = path.split(/(?<!-)-(?!-)/);
195
+ // shields.io treats /badge/<LABEL>-<MESSAGE>-<COLOR> as 3-part and /badge/<MESSAGE>-<COLOR>
196
+ // as 2-part (empty label). Without this branch, a badge like `/badge/Claude-blue` would
197
+ // misassign `Claude` to label and never get checked for tool-claim membership.
198
+ const hasLabel = parts.length >= 3;
199
+ return {
200
+ label: decodeShieldsText(hasLabel ? (parts[0] ?? '') : ''),
201
+ message: decodeShieldsText(hasLabel ? (parts[1] ?? '') : (parts[0] ?? '')),
202
+ };
203
+ }
204
+ /**
205
+ * Decode shields.io path-segment encoding per the static-badge spec:
206
+ * `--` → `-`, `__` → `_`, `_` → ` `, plus standard percent-encoding.
207
+ *
208
+ * Single-pass replace with alternation order (`--` and `__` listed before `_`)
209
+ * matches longer sequences first at each position, so `key__value` decodes to
210
+ * `key_value` rather than `key value`.
211
+ */
212
+ function decodeShieldsText(s) {
213
+ let out;
214
+ try {
215
+ out = decodeURIComponent(s); // totem-context: intentional cleanup — next-line catch swallows malformed % escapes (e.g., a stray `%` in a badge URL) so verifyToolClaims can still match the raw segment instead of crashing the whole hook.
216
+ }
217
+ catch {
218
+ out = s;
219
+ }
220
+ return out.replace(/--|__|_/g, (m) => {
221
+ if (m === '--')
222
+ return '-';
223
+ if (m === '__')
224
+ return '_';
225
+ return ' ';
226
+ });
227
+ }
228
+ //# sourceMappingURL=badge-verifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge-verifier.js","sourceRoot":"","sources":["../src/badge-verifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,uDAAuD;AAEvD,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;AAEhG,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC;IACpD,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE;IAClB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC3B,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CAC9B,CAAC,CAAC;AAKH,2DAA2D;AAE3D,MAAM,CAAC,MAAM,yBAAyB,GAA0B;IAC9D,MAAM,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,MAAM,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,MAAM,EAAE,CAAC,UAAU,EAAE,cAAc,CAAC;IACpC,QAAQ,EAAE,CAAC,gBAAgB,EAAE,YAAY,CAAC;IAC1C,OAAO,EAAE,CAAC,iCAAiC,CAAC;CAC7C,CAAC;AAcF,MAAM,cAAc,GAAG,iEAAiE,CAAC;AACzF,MAAM,YAAY,GAAG,mBAAmB,CAAC;AAEzC;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAqB,EAAE,CAAC;IAEpC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,QAAQ,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QAC5C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;QAC3B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YAClD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;YAC/B,MAAM,GAAG,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAEpC,IAAI,UAA8B,CAAC;YACnC,gFAAgF;YAChF,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC9B,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACtC,IAAI,IAAI,EAAE,CAAC;oBACT,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;gBACvB,CAAC;YACH,CAAC;YAED,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;YAC/C,MAAM,CAAC,IAAI,CAAC;gBACV,MAAM,EAAE,GAAG;gBACX,OAAO;gBACP,KAAK;gBACL,OAAO;gBACP,UAAU;gBACV,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,UAAU,EAAE,QAAQ,CAAC,UAAU;aAChC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAWD;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAwB,EACxB,MAA6B,EAC7B,QAAgB,EAChB,SAA8B,EAAE,CAAC,UAAU;IAE3C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAErC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,WAAW,EAAE,CAAC;QACjE,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YAC/B,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC9D,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAE3C,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1C,uEAAuE;YACvE,2EAA2E;YAC3E,qEAAqE;YACrE,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAC7C,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAChD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;gBACrB,IAAI,QAAQ,KAAK,gBAAgB,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,gBAAgB,GAAG,GAAG,CAAC,EAAE,CAAC;oBAClF,OAAO,KAAK,CAAC;gBACf,CAAC;gBACD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC1B,CAAC,CAAC,CAAC;YACH,IAAI,SAAS;gBAAE,SAAS;YAExB,MAAM,QAAQ,GAAG,GAAG,KAAK,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;YAC1C,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;gBAAE,SAAS;YACrC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAEvB,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3C,MAAM,CAAC,IAAI,CACT,sBAAsB,KAAK,CAAC,UAAU,6BAA6B,IAAI,uDAAuD,QAAQ,EAAE,CACzI,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,YAAY,CAAC,CAAS;IAC7B,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AAED,uDAAuD;AAEvD;;;;;GAKG;AACH,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IACpC,WAAW;IACX,KAAK;IACL,YAAY;IACZ,YAAY;IACZ,WAAW;IACX,KAAK;IACL,cAAc;IACd,cAAc;IACd,KAAK;IACL,SAAS;IACT,KAAK;IACL,SAAS;CACV,CAAC,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,SAAS,oBAAoB,CAAC,MAAc;IAC1C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,IAAI,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAwB;IAC/D,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,UAAU;YAAE,SAAS;QAChC,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,UAAU,CAAC;YAAE,SAAS;QACtD,MAAM,CAAC,IAAI,CACT,sBAAsB,KAAK,CAAC,UAAU,YAAY,KAAK,iCAAiC,KAAK,CAAC,UAAU,+HAA+H,CACxO,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAqB;IAC9C,KAAK,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACjD,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;QACvC,IAAI,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;IACnD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,uDAAuD;AAEvD,SAAS,cAAc,CAAC,GAAW;IACjC,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACtC,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC1C,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,QAAQ,IAAI,CAAC;QAAE,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAClD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAElC,mFAAmF;IACnF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACzC,4FAA4F;IAC5F,wFAAwF;IACxF,+EAA+E;IAC/E,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IACnC,OAAO;QACL,KAAK,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,OAAO,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;KAC3E,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,iBAAiB,CAAC,CAAS;IAClC,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,+MAA+M;IAC9O,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,GAAG,CAAC,CAAC;IACV,CAAC;IACD,OAAO,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE;QACnC,IAAI,CAAC,KAAK,IAAI;YAAE,OAAO,GAAG,CAAC;QAC3B,IAAI,CAAC,KAAK,IAAI;YAAE,OAAO,GAAG,CAAC;QAC3B,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=badge-verifier.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge-verifier.test.d.ts","sourceRoot":"","sources":["../src/badge-verifier.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,264 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { BadgeVerificationResultSchema, DEFAULT_TOOL_INTEGRATIONS, extractBadgesFromDiff, ToolIntegrationConfigSchema, verifySelfReferenceLinks, verifyToolClaims, } from './badge-verifier.js';
3
+ function makeBadge(overrides = {}) {
4
+ return {
5
+ rawUrl: 'https://img.shields.io/badge/x-y-blue',
6
+ altText: '',
7
+ label: 'x',
8
+ message: 'y',
9
+ file: 'README.md',
10
+ lineNumber: 1,
11
+ ...overrides,
12
+ };
13
+ }
14
+ const README_DIFF_HEADER = `diff --git a/README.md b/README.md
15
+ index aaaaaa..bbbbbb 100644
16
+ --- a/README.md
17
+ +++ b/README.md
18
+ @@ -1,5 +1,5 @@\n`;
19
+ const DIFF_NOT_README_HEADER = `diff --git a/docs/other.md b/docs/other.md
20
+ index aaaaaa..bbbbbb 100644
21
+ --- a/docs/other.md
22
+ +++ b/docs/other.md
23
+ @@ -1,5 +1,5 @@\n`;
24
+ describe('badge-verifier — schemas', () => {
25
+ it('ToolIntegrationConfigSchema accepts a mapping of tool name to path list', () => {
26
+ const parsed = ToolIntegrationConfigSchema.parse({
27
+ claude: ['.claude/', 'CLAUDE.md'],
28
+ gemini: ['.gemini/'],
29
+ });
30
+ expect(parsed.claude).toEqual(['.claude/', 'CLAUDE.md']);
31
+ });
32
+ it('ToolIntegrationConfigSchema rejects empty path arrays', () => {
33
+ expect(() => ToolIntegrationConfigSchema.parse({ claude: [] })).toThrow();
34
+ });
35
+ it('BadgeVerificationResultSchema valid===true iff errors empty', () => {
36
+ const ok = BadgeVerificationResultSchema.parse({
37
+ valid: true,
38
+ errors: [],
39
+ warnings: ['something'],
40
+ });
41
+ expect(ok.valid).toBe(true);
42
+ expect(ok.warnings).toHaveLength(1);
43
+ });
44
+ it('DEFAULT_TOOL_INTEGRATIONS includes the 5 tools named in mmnto-ai/totem#1924', () => {
45
+ expect(Object.keys(DEFAULT_TOOL_INTEGRATIONS).sort()).toEqual([
46
+ 'claude',
47
+ 'copilot',
48
+ 'cursor',
49
+ 'gemini',
50
+ 'windsurf',
51
+ ]);
52
+ // Every tool has at least one falsifying path
53
+ for (const [, paths] of Object.entries(DEFAULT_TOOL_INTEGRATIONS)) {
54
+ expect(paths.length).toBeGreaterThan(0);
55
+ }
56
+ });
57
+ });
58
+ describe('badge-verifier — extractBadgesFromDiff', () => {
59
+ it('extracts url, decoded text, and link target from complex multiline diffs', () => {
60
+ // The TEST DIRECTIVE from spec — proves shields.io URL encoding (_, --) decodes correctly.
61
+ const diff = README_DIFF_HEADER +
62
+ ` # Totem\n` +
63
+ `+[![Tool-agnostic](https://img.shields.io/badge/Tool--agnostic-AGENTS.md-blue)](./AGENTS.md)\n` +
64
+ `+[![Build Status](https://img.shields.io/badge/build-passing-green)](https://example.com/ci)\n` +
65
+ `+Some text with [![Hello World](https://img.shields.io/badge/Hello_World-yes-blue)](https://example.com)\n` +
66
+ ` ## Other\n`;
67
+ const badges = extractBadgesFromDiff(diff);
68
+ expect(badges).toHaveLength(3);
69
+ expect(badges[0]).toMatchObject({
70
+ rawUrl: 'https://img.shields.io/badge/Tool--agnostic-AGENTS.md-blue',
71
+ label: 'Tool-agnostic',
72
+ message: 'AGENTS.md',
73
+ linkTarget: './AGENTS.md',
74
+ file: 'README.md',
75
+ });
76
+ expect(badges[1]).toMatchObject({
77
+ rawUrl: 'https://img.shields.io/badge/build-passing-green',
78
+ label: 'build',
79
+ message: 'passing',
80
+ linkTarget: 'https://example.com/ci',
81
+ });
82
+ expect(badges[2]).toMatchObject({
83
+ label: 'Hello World',
84
+ message: 'yes',
85
+ });
86
+ });
87
+ it('ignores - (removed) lines', () => {
88
+ const diff = README_DIFF_HEADER +
89
+ ` # Totem\n` +
90
+ `-[![Old](https://img.shields.io/badge/Old-badge-red)](./old.md)\n` +
91
+ `+[![New](https://img.shields.io/badge/New-badge-green)](./new.md)\n`;
92
+ const badges = extractBadgesFromDiff(diff);
93
+ expect(badges).toHaveLength(1);
94
+ expect(badges[0]?.label).toBe('New');
95
+ });
96
+ it('ignores badges in files other than README.md', () => {
97
+ const diff = DIFF_NOT_README_HEADER +
98
+ ` text\n` +
99
+ `+[![Tool](https://img.shields.io/badge/Tool-agnostic-blue)](./foo.md)\n`;
100
+ expect(extractBadgesFromDiff(diff)).toHaveLength(0);
101
+ });
102
+ it('handles badge without surrounding markdown link', () => {
103
+ const diff = README_DIFF_HEADER + `+![alt](https://img.shields.io/badge/MIT-License-green)\n`;
104
+ const badges = extractBadgesFromDiff(diff);
105
+ expect(badges).toHaveLength(1);
106
+ expect(badges[0]?.linkTarget).toBeUndefined();
107
+ expect(badges[0]?.label).toBe('MIT');
108
+ expect(badges[0]?.message).toBe('License');
109
+ });
110
+ it('decodes percent-encoded characters in label/message', () => {
111
+ const diff = README_DIFF_HEADER +
112
+ `+[![X](https://img.shields.io/badge/Apache%202.0-license-blue)](./LICENSE)\n`;
113
+ const badges = extractBadgesFromDiff(diff);
114
+ expect(badges[0]?.label).toBe('Apache 2.0');
115
+ });
116
+ it('treats 2-part shields URLs (/<MESSAGE>-<COLOR>) as empty-label per shields.io spec', () => {
117
+ // GCA review on mmnto-ai/totem#1934: `/badge/Claude-blue` means MESSAGE=Claude,
118
+ // COLOR=blue, LABEL=''. Without the 2-part branch, "Claude" lands in label,
119
+ // and downstream consumers that key on label vs message misidentify.
120
+ const diff = README_DIFF_HEADER + `+[![X](https://img.shields.io/badge/Claude-blue)](https://claude.ai)\n`;
121
+ const badges = extractBadgesFromDiff(diff);
122
+ expect(badges[0]?.label).toBe('');
123
+ expect(badges[0]?.message).toBe('Claude');
124
+ });
125
+ it('returns empty array when diff has no README.md changes', () => {
126
+ expect(extractBadgesFromDiff('')).toEqual([]);
127
+ expect(extractBadgesFromDiff(DIFF_NOT_README_HEADER + ` text\n+more text\n`)).toEqual([]);
128
+ });
129
+ });
130
+ describe('badge-verifier — verifyToolClaims', () => {
131
+ const config = DEFAULT_TOOL_INTEGRATIONS;
132
+ const noPathsExist = (_p) => false;
133
+ const allPathsExist = (_p) => true;
134
+ it('returns 2 errors when badge claims Claude and Cursor but neither integration file exists', () => {
135
+ const badge = makeBadge({ label: 'Tool', message: 'Claude · Cursor' });
136
+ const errors = verifyToolClaims([badge], config, '/repo', noPathsExist);
137
+ expect(errors).toHaveLength(2);
138
+ expect(errors.some((e) => e.toLowerCase().includes('claude'))).toBe(true);
139
+ expect(errors.some((e) => e.toLowerCase().includes('cursor'))).toBe(true);
140
+ });
141
+ it('returns 0 errors when at least one config path exists for the claimed tool', () => {
142
+ const badge = makeBadge({ label: 'Integration', message: 'Claude' });
143
+ const errors = verifyToolClaims([badge], config, '/repo', (p) => p.endsWith('CLAUDE.md'));
144
+ expect(errors).toHaveLength(0);
145
+ });
146
+ it('returns 0 errors when no tool name appears in badge text', () => {
147
+ const badge = makeBadge({ label: 'build', message: 'passing' });
148
+ const errors = verifyToolClaims([badge], config, '/repo', noPathsExist);
149
+ expect(errors).toHaveLength(0);
150
+ });
151
+ it('matches tool names case-insensitively with word boundaries', () => {
152
+ // "claudette" should NOT match "claude" — word-boundary required.
153
+ const badge1 = makeBadge({ message: 'claudette' });
154
+ expect(verifyToolClaims([badge1], config, '/repo', noPathsExist)).toHaveLength(0);
155
+ // "CLAUDE" uppercase should match.
156
+ const badge2 = makeBadge({ message: 'CLAUDE' });
157
+ expect(verifyToolClaims([badge2], config, '/repo', noPathsExist)).toHaveLength(1);
158
+ });
159
+ it('does not double-count tools that appear in both label and message', () => {
160
+ const badge = makeBadge({ label: 'Claude', message: 'Claude integration' });
161
+ const errors = verifyToolClaims([badge], config, '/repo', noPathsExist);
162
+ expect(errors).toHaveLength(1);
163
+ });
164
+ it('error message names the tool and at least one expected path', () => {
165
+ const badge = makeBadge({ message: 'gemini' });
166
+ const errors = verifyToolClaims([badge], config, '/repo', noPathsExist);
167
+ expect(errors[0]).toContain('gemini');
168
+ expect(errors[0]).toMatch(/\.gemini\/|GEMINI\.md/);
169
+ });
170
+ it('passes through cleanly when all paths exist', () => {
171
+ const badge = makeBadge({ message: 'Claude Gemini Cursor' });
172
+ expect(verifyToolClaims([badge], config, '/repo', allPathsExist)).toHaveLength(0);
173
+ });
174
+ it('rejects configured paths that escape repoRoot via .. traversal', () => {
175
+ // CR review on mmnto-ai/totem#1934: a configured path like '../CLAUDE.md' would
176
+ // satisfy the claim with a file outside the repo, defeating the falsifying metric.
177
+ const escapeConfig = {
178
+ claude: ['../CLAUDE.md', '../../CLAUDE.md'],
179
+ };
180
+ const badge = makeBadge({ message: 'Claude' });
181
+ // Predicate returns true for everything — but the path-escape guard must filter
182
+ // before existence-checking, so we still get an error.
183
+ const errors = verifyToolClaims([badge], escapeConfig, '/repo/root', () => true);
184
+ expect(errors).toHaveLength(1);
185
+ expect(errors[0]).toMatch(/claude/i);
186
+ });
187
+ });
188
+ describe('badge-verifier — verifySelfReferenceLinks', () => {
189
+ it('rejects AGENTS.md badge pointing to internal ADR instead of canonical standard', () => {
190
+ // The TEST DIRECTIVE from spec — circular claim: badge claims AGENTS.md compliance
191
+ // but links to an internal ADR (not the upstream standard).
192
+ const badge = makeBadge({
193
+ label: 'AGENTS.md',
194
+ message: 'compliant',
195
+ linkTarget: 'https://github.com/mmnto-ai/totem/blob/main/docs/ADR-038.md',
196
+ });
197
+ const errors = verifySelfReferenceLinks([badge]);
198
+ expect(errors).toHaveLength(1);
199
+ expect(errors[0]).toMatch(/AGENTS\.md|self-reference|internal/i);
200
+ });
201
+ it('rejects standard-claim badge linked to a relative internal path', () => {
202
+ const badge = makeBadge({
203
+ label: 'MIT',
204
+ message: 'license',
205
+ linkTarget: './docs/licensing.md',
206
+ });
207
+ expect(verifySelfReferenceLinks([badge])).toHaveLength(1);
208
+ });
209
+ it('rejects standard-claim badge linked to mmnto-ai/<anything>', () => {
210
+ const badge = makeBadge({
211
+ label: 'Apache 2.0',
212
+ message: 'license',
213
+ linkTarget: 'https://github.com/mmnto-ai/totem-strategy',
214
+ });
215
+ expect(verifySelfReferenceLinks([badge])).toHaveLength(1);
216
+ });
217
+ it('accepts AGENTS.md badge linked to canonical upstream', () => {
218
+ const badge = makeBadge({
219
+ label: 'AGENTS.md',
220
+ message: 'compliant',
221
+ linkTarget: 'https://agents.md/',
222
+ });
223
+ expect(verifySelfReferenceLinks([badge])).toHaveLength(0);
224
+ });
225
+ it('accepts MIT badge linked to opensource.org', () => {
226
+ const badge = makeBadge({
227
+ label: 'MIT',
228
+ message: 'license',
229
+ linkTarget: 'https://opensource.org/licenses/MIT',
230
+ });
231
+ expect(verifySelfReferenceLinks([badge])).toHaveLength(0);
232
+ });
233
+ it('ignores non-standard-claim badges entirely (no self-reference check)', () => {
234
+ const badge = makeBadge({
235
+ label: 'build',
236
+ message: 'passing',
237
+ linkTarget: './docs/ci.md',
238
+ });
239
+ expect(verifySelfReferenceLinks([badge])).toHaveLength(0);
240
+ });
241
+ it('ignores standard-claim badges with no link target', () => {
242
+ const badge = makeBadge({ label: 'AGENTS.md', message: 'compliant' });
243
+ expect(verifySelfReferenceLinks([badge])).toHaveLength(0);
244
+ });
245
+ it('flags bare relative paths like LICENSE or docs/ADR-038.md as internal', () => {
246
+ // CR review on mmnto-ai/totem#1934: hardcoded `./` / `../` regex missed bare
247
+ // README-relative targets. Inversion: anything without http(s):// is internal.
248
+ const cases = [
249
+ { linkTarget: 'LICENSE', expectFlag: true },
250
+ { linkTarget: 'docs/ADR-038.md', expectFlag: true },
251
+ { linkTarget: 'AGENTS.md', expectFlag: true },
252
+ { linkTarget: './AGENTS.md', expectFlag: true },
253
+ { linkTarget: '../AGENTS.md', expectFlag: true },
254
+ { linkTarget: 'https://agents.md/', expectFlag: false },
255
+ { linkTarget: 'http://opensource.org/licenses/MIT', expectFlag: false },
256
+ ];
257
+ for (const { linkTarget, expectFlag } of cases) {
258
+ const badge = makeBadge({ label: 'AGENTS.md', message: 'compliant', linkTarget });
259
+ const errors = verifySelfReferenceLinks([badge]);
260
+ expect(errors).toHaveLength(expectFlag ? 1 : 0);
261
+ }
262
+ });
263
+ });
264
+ //# sourceMappingURL=badge-verifier.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge-verifier.test.js","sourceRoot":"","sources":["../src/badge-verifier.test.ts"],"names":[],"mappings":"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"}
@@ -5,18 +5,21 @@ export declare const CompileManifestSchema: z.ZodObject<{
5
5
  input_hash: z.ZodString;
6
6
  output_hash: z.ZodString;
7
7
  rule_count: z.ZodNumber;
8
+ compile_worker_fingerprint: z.ZodOptional<z.ZodString>;
8
9
  }, "strip", z.ZodTypeAny, {
9
10
  model: string;
10
11
  compiled_at: string;
11
12
  input_hash: string;
12
13
  output_hash: string;
13
14
  rule_count: number;
15
+ compile_worker_fingerprint?: string | undefined;
14
16
  }, {
15
17
  model: string;
16
18
  compiled_at: string;
17
19
  input_hash: string;
18
20
  output_hash: string;
19
21
  rule_count: number;
22
+ compile_worker_fingerprint?: string | undefined;
20
23
  }>;
21
24
  export type CompileManifest = z.infer<typeof CompileManifestSchema>;
22
25
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"compile-manifest.d.ts","sourceRoot":"","sources":["../src/compile-manifest.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;EAMhC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AA8BpE;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAoB5D;AAmDD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAUxD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAyB1E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAuC5D;AAMD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI,CAW1F;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,CA6BzE"}
1
+ {"version":3,"file":"compile-manifest.d.ts","sourceRoot":"","sources":["../src/compile-manifest.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;EAUhC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AA8BpE;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAoB5D;AAmDD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAUxD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAyB1E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAuC5D;AAMD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI,CAW1F;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,CA6BzE"}
@@ -11,6 +11,10 @@ export const CompileManifestSchema = z.object({
11
11
  input_hash: z.string(),
12
12
  output_hash: z.string(),
13
13
  rule_count: z.number().int().nonnegative(),
14
+ // Producer attestation orthogonal to output_hash (recompute trigger).
15
+ // Optional for backward-compat with pre-#1937 manifests; only the anthropic
16
+ // provider populates it in Phase 1. Per Proposal 278 § Action 3.
17
+ compile_worker_fingerprint: z.string().optional(),
14
18
  });
15
19
  // ─── Hashing ─────────────────────────────────────────
16
20
  /**