renma 0.16.0 → 0.18.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 (182) hide show
  1. package/CHANGELOG.md +157 -1
  2. package/README.md +219 -748
  3. package/architecture.md +533 -0
  4. package/design.md +469 -0
  5. package/dist/agent-skills.d.ts +1 -1
  6. package/dist/agent-skills.d.ts.map +1 -1
  7. package/dist/agent-skills.js +28 -8
  8. package/dist/agent-skills.js.map +1 -1
  9. package/dist/catalog.d.ts +1 -1
  10. package/dist/catalog.d.ts.map +1 -1
  11. package/dist/catalog.js +120 -12
  12. package/dist/catalog.js.map +1 -1
  13. package/dist/cli-help.d.ts +15 -9
  14. package/dist/cli-help.d.ts.map +1 -1
  15. package/dist/cli-help.js +32 -9
  16. package/dist/cli-help.js.map +1 -1
  17. package/dist/cli.d.ts.map +1 -1
  18. package/dist/cli.js +162 -40
  19. package/dist/cli.js.map +1 -1
  20. package/dist/commands/bom.d.ts +6 -3
  21. package/dist/commands/bom.d.ts.map +1 -1
  22. package/dist/commands/bom.js +27 -7
  23. package/dist/commands/bom.js.map +1 -1
  24. package/dist/commands/catalog.d.ts +1 -1
  25. package/dist/commands/catalog.d.ts.map +1 -1
  26. package/dist/commands/catalog.js +11 -4
  27. package/dist/commands/catalog.js.map +1 -1
  28. package/dist/commands/ci-report.d.ts.map +1 -1
  29. package/dist/commands/ci-report.js +18 -5
  30. package/dist/commands/ci-report.js.map +1 -1
  31. package/dist/commands/diff.js +8 -2
  32. package/dist/commands/diff.js.map +1 -1
  33. package/dist/commands/graph.d.ts +6 -2
  34. package/dist/commands/graph.d.ts.map +1 -1
  35. package/dist/commands/graph.js +30 -14
  36. package/dist/commands/graph.js.map +1 -1
  37. package/dist/commands/inspect.d.ts.map +1 -1
  38. package/dist/commands/inspect.js +2 -0
  39. package/dist/commands/inspect.js.map +1 -1
  40. package/dist/commands/ownership.d.ts +4 -3
  41. package/dist/commands/ownership.d.ts.map +1 -1
  42. package/dist/commands/ownership.js +27 -23
  43. package/dist/commands/ownership.js.map +1 -1
  44. package/dist/commands/readiness.d.ts +2 -1
  45. package/dist/commands/readiness.d.ts.map +1 -1
  46. package/dist/commands/readiness.js +105 -36
  47. package/dist/commands/readiness.js.map +1 -1
  48. package/dist/commands/scaffold.d.ts +3 -0
  49. package/dist/commands/scaffold.d.ts.map +1 -1
  50. package/dist/commands/scaffold.js +28 -2
  51. package/dist/commands/scaffold.js.map +1 -1
  52. package/dist/commands/suggest-metadata.d.ts.map +1 -1
  53. package/dist/commands/suggest-metadata.js +56 -8
  54. package/dist/commands/suggest-metadata.js.map +1 -1
  55. package/dist/commands/suggest-semantic-split.js +3 -3
  56. package/dist/commands/suggest-semantic-split.js.map +1 -1
  57. package/dist/commands/trust-graph.d.ts.map +1 -1
  58. package/dist/commands/trust-graph.js +12 -0
  59. package/dist/commands/trust-graph.js.map +1 -1
  60. package/dist/config.d.ts.map +1 -1
  61. package/dist/config.js +10 -3
  62. package/dist/config.js.map +1 -1
  63. package/dist/dependency-resolution.d.ts +6 -0
  64. package/dist/dependency-resolution.d.ts.map +1 -0
  65. package/dist/dependency-resolution.js +11 -0
  66. package/dist/dependency-resolution.js.map +1 -0
  67. package/dist/diagnostic-ids.d.ts +8 -0
  68. package/dist/diagnostic-ids.d.ts.map +1 -1
  69. package/dist/diagnostic-ids.js +8 -0
  70. package/dist/diagnostic-ids.js.map +1 -1
  71. package/dist/discovery.d.ts +33 -0
  72. package/dist/discovery.d.ts.map +1 -1
  73. package/dist/discovery.js +178 -80
  74. package/dist/discovery.js.map +1 -1
  75. package/dist/markdown.d.ts.map +1 -1
  76. package/dist/markdown.js +15 -0
  77. package/dist/markdown.js.map +1 -1
  78. package/dist/model.d.ts +17 -1
  79. package/dist/model.d.ts.map +1 -1
  80. package/dist/model.js +4 -1
  81. package/dist/model.js.map +1 -1
  82. package/dist/quality-profile.d.ts +91 -0
  83. package/dist/quality-profile.d.ts.map +1 -0
  84. package/dist/quality-profile.js +91 -0
  85. package/dist/quality-profile.js.map +1 -0
  86. package/dist/repeated-context.d.ts.map +1 -1
  87. package/dist/repeated-context.js +38 -83
  88. package/dist/repeated-context.js.map +1 -1
  89. package/dist/repository-boundary.d.ts +30 -0
  90. package/dist/repository-boundary.d.ts.map +1 -0
  91. package/dist/repository-boundary.js +116 -0
  92. package/dist/repository-boundary.js.map +1 -0
  93. package/dist/repository-evidence.d.ts +2 -0
  94. package/dist/repository-evidence.d.ts.map +1 -1
  95. package/dist/repository-evidence.js +6 -4
  96. package/dist/repository-evidence.js.map +1 -1
  97. package/dist/repository-paths.d.ts +19 -2
  98. package/dist/repository-paths.d.ts.map +1 -1
  99. package/dist/repository-paths.js +123 -14
  100. package/dist/repository-paths.js.map +1 -1
  101. package/dist/rules.d.ts +2 -0
  102. package/dist/rules.d.ts.map +1 -1
  103. package/dist/rules.js +322 -256
  104. package/dist/rules.js.map +1 -1
  105. package/dist/scanner.d.ts.map +1 -1
  106. package/dist/scanner.js +5 -1
  107. package/dist/scanner.js.map +1 -1
  108. package/dist/security-diagnostics.d.ts.map +1 -1
  109. package/dist/security-diagnostics.js +95 -30
  110. package/dist/security-diagnostics.js.map +1 -1
  111. package/dist/security-diff.d.ts +5 -2
  112. package/dist/security-diff.d.ts.map +1 -1
  113. package/dist/security-diff.js +20 -4
  114. package/dist/security-diff.js.map +1 -1
  115. package/dist/security-policy-inventory.d.ts +15 -3
  116. package/dist/security-policy-inventory.d.ts.map +1 -1
  117. package/dist/security-policy-inventory.js +123 -26
  118. package/dist/security-policy-inventory.js.map +1 -1
  119. package/dist/security-policy.d.ts +7 -0
  120. package/dist/security-policy.d.ts.map +1 -1
  121. package/dist/security-policy.js +70 -7
  122. package/dist/security-policy.js.map +1 -1
  123. package/dist/security-posture.d.ts.map +1 -1
  124. package/dist/security-posture.js +2 -1
  125. package/dist/security-posture.js.map +1 -1
  126. package/dist/skill-migration.js +2 -0
  127. package/dist/skill-migration.js.map +1 -1
  128. package/dist/static-support.d.ts +13 -0
  129. package/dist/static-support.d.ts.map +1 -0
  130. package/dist/static-support.js +284 -0
  131. package/dist/static-support.js.map +1 -0
  132. package/dist/token-estimator.d.ts +21 -0
  133. package/dist/token-estimator.d.ts.map +1 -0
  134. package/dist/token-estimator.js +84 -0
  135. package/dist/token-estimator.js.map +1 -0
  136. package/dist/trust-graph.d.ts +3 -3
  137. package/dist/trust-graph.d.ts.map +1 -1
  138. package/dist/trust-graph.js +76 -21
  139. package/dist/trust-graph.js.map +1 -1
  140. package/dist/types.d.ts +7 -2
  141. package/dist/types.d.ts.map +1 -1
  142. package/docs/README.md +61 -0
  143. package/docs/advanced-skill-authoring.md +147 -0
  144. package/docs/agent-skills-compatibility.md +508 -0
  145. package/docs/authoring-guide.md +382 -0
  146. package/docs/context-conflict-diagnostics.md +32 -0
  147. package/docs/context-language-diagnostics.md +99 -0
  148. package/docs/context-lens.md +253 -0
  149. package/docs/context-lifecycle-diagnostics.md +55 -0
  150. package/docs/diagnostics.md +406 -0
  151. package/docs/metadata-budget.md +14 -0
  152. package/docs/quality-profile.md +123 -0
  153. package/docs/repository-context-bom.md +172 -0
  154. package/docs/schemas/repository-context-bom-v2.schema.json +648 -0
  155. package/docs/schemas/trust-graph-v2.schema.json +301 -0
  156. package/docs/security-policy.md +354 -0
  157. package/docs/trust-graph.md +47 -0
  158. package/docs/user-manual.md +842 -0
  159. package/examples/context-lens/README.md +101 -0
  160. package/examples/context-lens/contexts/testing/boundary-value-analysis.md +23 -0
  161. package/examples/context-lens/lenses/testing/spec-review-boundary-values.md +29 -0
  162. package/examples/context-lens/lenses/testing/test-design-boundary-values.md +29 -0
  163. package/examples/context-lens/skills/testing/spec-review/SKILL.md +49 -0
  164. package/examples/context-repo/README.md +148 -0
  165. package/examples/context-repo/contexts/domain/payment/idempotency.md +27 -0
  166. package/examples/context-repo/contexts/testing/boundary-value-analysis.md +26 -0
  167. package/examples/context-repo/contexts/testing/negative-testing.md +26 -0
  168. package/examples/context-repo/lenses/testing/spec-review-boundary-values.md +35 -0
  169. package/examples/context-repo/renma.config.json +12 -0
  170. package/examples/context-repo/skills/testing/spec-review/SKILL.md +71 -0
  171. package/examples/context-repo/tools/appium/README.md +14 -0
  172. package/examples/github-actions/renma-ci-report.yml +36 -0
  173. package/examples/interactive-placeholder/README.md +104 -0
  174. package/examples/interactive-placeholder/assets/template.txt +1 -0
  175. package/examples/interactive-placeholder/renma.config.json +6 -0
  176. package/examples/interactive-placeholder/skills/replace-placeholder/SKILL.md +54 -0
  177. package/examples/interactive-placeholder/tools/README.md +48 -0
  178. package/examples/interactive-placeholder/tools/placeholder-demo.mjs +99 -0
  179. package/package.json +10 -1
  180. package/plan-discovery.md +749 -0
  181. package/plan.md +90 -0
  182. package/scripts/verify-package.mjs +104 -0
@@ -0,0 +1,284 @@
1
+ import path from "node:path";
2
+ import { classifyRepositorySkillPath, logicalSkillDirectory, } from "./discovery.js";
3
+ const SUPPORT_ROOTS = [
4
+ "references",
5
+ "scripts",
6
+ "assets",
7
+ "profiles",
8
+ "examples",
9
+ ];
10
+ /** Parse exact, repository-local support references once for rules and graphs. */
11
+ export function staticSupportReferences(document, skillDirectory, localCandidatePaths) {
12
+ const candidatesByBasename = new Map();
13
+ for (const candidate of localCandidatePaths) {
14
+ const basename = path.posix.basename(candidate);
15
+ const values = candidatesByBasename.get(basename) ?? [];
16
+ values.push(candidate);
17
+ candidatesByBasename.set(basename, values);
18
+ }
19
+ const references = [];
20
+ const seen = new Set();
21
+ for (let index = 0; index < document.lines.length; index += 1) {
22
+ const line = document.lines[index] ?? "";
23
+ const values = [];
24
+ const markdownLinks = markdownLinkDestinations(line);
25
+ values.push(...markdownLinks);
26
+ let unquotedLine = maskRawMatches(line, markdownLinks.map((link) => link.raw));
27
+ const quotedMatches = [];
28
+ for (const match of unquotedLine.matchAll(/([`'"])((?:\.\/)?(?:references|scripts|assets|profiles|examples)\/.*?)\1/g)) {
29
+ if (match[2]) {
30
+ values.push({ raw: match[0], value: match[2] });
31
+ quotedMatches.push(match[0]);
32
+ }
33
+ }
34
+ unquotedLine = maskRawMatches(unquotedLine, quotedMatches);
35
+ for (const match of unquotedLine.matchAll(/(?:^|[\s([])((?:\.\/)?(?:references|scripts|assets|profiles|examples)\/[^\s)`'"\],;]+)/g)) {
36
+ if (match[1])
37
+ values.push({ raw: match[0].trim(), value: match[1] });
38
+ }
39
+ for (const [basename, paths] of candidatesByBasename) {
40
+ if (paths.length !== 1 || !containsExactBasename(line, basename))
41
+ continue;
42
+ values.push({ raw: basename, value: paths[0] });
43
+ }
44
+ for (const value of values) {
45
+ const normalized = normalizeStaticSupportReference(value.value, skillDirectory);
46
+ if (!normalized)
47
+ continue;
48
+ const key = `${index + 1}:${normalized.targetPath}`;
49
+ if (seen.has(key))
50
+ continue;
51
+ seen.add(key);
52
+ references.push({
53
+ sourcePath: document.artifact.path,
54
+ targetPath: normalized.targetPath,
55
+ relativePath: normalized.relativePath,
56
+ line: index + 1,
57
+ raw: value.raw,
58
+ });
59
+ }
60
+ }
61
+ return references.sort((left, right) => left.line - right.line ||
62
+ left.targetPath.localeCompare(right.targetPath) ||
63
+ left.raw.localeCompare(right.raw));
64
+ }
65
+ function maskRawMatches(line, matches) {
66
+ let masked = line;
67
+ for (const match of matches) {
68
+ masked = masked.replace(match, " ".repeat(match.length));
69
+ }
70
+ return masked;
71
+ }
72
+ export function buildStaticSupportDependencies(documents, entries, repositoryPaths) {
73
+ const documentsByPath = new Map(documents.map((document) => [document.artifact.path, document]));
74
+ const entriesByPath = new Map(entries.map((entry) => [entry.sourcePath, entry]));
75
+ const skillEntries = entries.filter((entry) => entry.kind === "skill");
76
+ const skillCounts = new Map();
77
+ for (const skill of skillEntries) {
78
+ const directory = logicalSkillDirectory(skill.sourcePath);
79
+ if (!directory)
80
+ continue;
81
+ skillCounts.set(directory, (skillCounts.get(directory) ?? 0) + 1);
82
+ }
83
+ const result = [];
84
+ for (const skill of skillEntries) {
85
+ const skillDirectory = logicalSkillDirectory(skill.sourcePath);
86
+ if (!skillDirectory)
87
+ continue;
88
+ if (skillCounts.get(skillDirectory) !== 1)
89
+ continue;
90
+ const localEntries = entries.filter((entry) => {
91
+ const classified = classifyRepositorySkillPath(entry.sourcePath);
92
+ return (classified?.kind === "support" &&
93
+ classified.skillDirectory === skillDirectory);
94
+ });
95
+ for (const local of localEntries) {
96
+ result.push({
97
+ from: skill.id,
98
+ to: local.id,
99
+ kind: "owns_local_resource",
100
+ sourcePath: skill.sourcePath,
101
+ });
102
+ if (local.ownership.source === "inherited") {
103
+ result.push({
104
+ from: local.id,
105
+ to: skill.id,
106
+ kind: "inherits_owner",
107
+ sourcePath: local.sourcePath,
108
+ });
109
+ }
110
+ if (local.kind === "script" || local.kind === "asset") {
111
+ result.push({
112
+ from: local.id,
113
+ to: skill.id,
114
+ kind: "inherits_policy",
115
+ sourcePath: local.sourcePath,
116
+ });
117
+ }
118
+ }
119
+ const candidatePaths = [...repositoryPaths].filter((candidate) => {
120
+ const classified = classifyRepositorySkillPath(candidate);
121
+ return (classified?.kind === "support" &&
122
+ classified.skillDirectory === skillDirectory);
123
+ });
124
+ const sources = [skill, ...localEntries]
125
+ .map((entry) => documentsByPath.get(entry.sourcePath))
126
+ .filter((document) => document !== undefined);
127
+ for (const source of sources) {
128
+ for (const reference of staticSupportReferences(source, skillDirectory, candidatePaths)) {
129
+ const target = entriesByPath.get(reference.targetPath);
130
+ if (!target ||
131
+ target.id === entriesByPath.get(source.artifact.path)?.id)
132
+ continue;
133
+ result.push({
134
+ from: entriesByPath.get(source.artifact.path)?.id ?? skill.id,
135
+ to: target.id,
136
+ kind: "statically_references",
137
+ sourcePath: source.artifact.path,
138
+ evidence: {
139
+ path: source.artifact.path,
140
+ startLine: reference.line,
141
+ endLine: reference.line,
142
+ snippet: reference.raw,
143
+ },
144
+ });
145
+ }
146
+ }
147
+ }
148
+ return dedupeDependencies(result);
149
+ }
150
+ function normalizeStaticSupportReference(value, skillDirectory) {
151
+ const cleaned = decodePath(stripUriSuffix(value.trim()))
152
+ .replace(/^<|>$/g, "")
153
+ .replace(/[),.;:]+$/, "")
154
+ .replace(/^\.\//, "");
155
+ if (!cleaned || path.posix.isAbsolute(cleaned))
156
+ return undefined;
157
+ if (cleaned.split("/").includes(".."))
158
+ return undefined;
159
+ const repositoryRelative = cleaned.startsWith(`${skillDirectory}/`)
160
+ ? cleaned
161
+ : path.posix.join(skillDirectory, cleaned);
162
+ const normalized = path.posix.normalize(repositoryRelative);
163
+ const relativePath = path.posix.relative(skillDirectory, normalized);
164
+ if (relativePath.startsWith("../") ||
165
+ relativePath === ".." ||
166
+ !SUPPORT_ROOTS.includes(relativePath.split("/")[0]) ||
167
+ relativePath.endsWith("/")) {
168
+ return undefined;
169
+ }
170
+ return { targetPath: normalized, relativePath };
171
+ }
172
+ function markdownLinkDestinations(line) {
173
+ const destinations = [];
174
+ let searchFrom = 0;
175
+ while (searchFrom < line.length) {
176
+ const opener = line.indexOf("](", searchFrom);
177
+ if (opener < 0)
178
+ break;
179
+ const rawStart = line.lastIndexOf("[", opener);
180
+ let cursor = opener + 2;
181
+ while (/\s/.test(line[cursor] ?? ""))
182
+ cursor += 1;
183
+ const destinationStart = cursor;
184
+ let destination = "";
185
+ if (line[cursor] === "<") {
186
+ cursor += 1;
187
+ const valueStart = cursor;
188
+ while (cursor < line.length && line[cursor] !== ">")
189
+ cursor += 1;
190
+ if (line[cursor] === ">") {
191
+ destination = line.slice(valueStart, cursor);
192
+ cursor += 1;
193
+ }
194
+ }
195
+ else {
196
+ let nestedParentheses = 0;
197
+ while (cursor < line.length) {
198
+ const character = line[cursor] ?? "";
199
+ if (character === "\\" && cursor + 1 < line.length) {
200
+ cursor += 2;
201
+ continue;
202
+ }
203
+ if (character === "(") {
204
+ nestedParentheses += 1;
205
+ }
206
+ else if (character === ")") {
207
+ if (nestedParentheses === 0)
208
+ break;
209
+ nestedParentheses -= 1;
210
+ }
211
+ else if (/\s/.test(character) && nestedParentheses === 0) {
212
+ break;
213
+ }
214
+ cursor += 1;
215
+ }
216
+ destination = line.slice(destinationStart, cursor);
217
+ }
218
+ let outerClose = cursor;
219
+ let titleParentheses = 0;
220
+ let quote;
221
+ while (outerClose < line.length) {
222
+ const character = line[outerClose] ?? "";
223
+ if (character === "\\") {
224
+ outerClose += 2;
225
+ continue;
226
+ }
227
+ if (quote) {
228
+ if (character === quote)
229
+ quote = undefined;
230
+ }
231
+ else if (character === '"' || character === "'") {
232
+ quote = character;
233
+ }
234
+ else if (character === "(") {
235
+ titleParentheses += 1;
236
+ }
237
+ else if (character === ")") {
238
+ if (titleParentheses === 0)
239
+ break;
240
+ titleParentheses -= 1;
241
+ }
242
+ outerClose += 1;
243
+ }
244
+ if (destination && outerClose < line.length) {
245
+ destinations.push({
246
+ raw: line.slice(rawStart >= 0 ? rawStart : opener, outerClose + 1),
247
+ value: destination,
248
+ });
249
+ }
250
+ searchFrom = Math.max(outerClose + 1, opener + 2);
251
+ }
252
+ return destinations;
253
+ }
254
+ function stripUriSuffix(value) {
255
+ const query = value.indexOf("?");
256
+ const fragment = value.indexOf("#");
257
+ const boundary = [query, fragment]
258
+ .filter((index) => index >= 0)
259
+ .sort((left, right) => left - right)[0];
260
+ return boundary === undefined ? value : value.slice(0, boundary);
261
+ }
262
+ function containsExactBasename(content, basename) {
263
+ const escaped = basename.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
264
+ return new RegExp(`(?:^|[\\s\`'"()\\[\\]{},;:])${escaped}(?=$|[\\s\`'"()\\[\\]{},;:?!]|\\.(?=\\s|$))`, "m").test(content);
265
+ }
266
+ function decodePath(value) {
267
+ try {
268
+ return decodeURIComponent(value);
269
+ }
270
+ catch {
271
+ return value;
272
+ }
273
+ }
274
+ function dedupeDependencies(dependencies) {
275
+ const seen = new Set();
276
+ return dependencies.filter((dependency) => {
277
+ const key = `${dependency.from}\0${dependency.kind}\0${dependency.to}\0${dependency.sourcePath}`;
278
+ if (seen.has(key))
279
+ return false;
280
+ seen.add(key);
281
+ return true;
282
+ });
283
+ }
284
+ //# sourceMappingURL=static-support.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static-support.js","sourceRoot":"","sources":["../src/static-support.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /** A deterministic, model-neutral token estimate unit. */
2
+ export interface EstimatedTokenUnit {
3
+ value: string;
4
+ offset: number;
5
+ }
6
+ /**
7
+ * Estimate tokens without claiming compatibility with a model tokenizer.
8
+ *
9
+ * Latin-like words, code identifiers, URLs, and repository paths are lexical
10
+ * units. Consecutive Han, Hiragana, Katakana, and Hangul text is divided into
11
+ * two-code-point units so unspaced Japanese is neither one token nor one token
12
+ * per character. Other punctuation is grouped in runs of up to three code
13
+ * points. The algorithm is Unicode-aware, dependency-free, and deterministic,
14
+ * but is only suitable for stable repository thresholds and comparisons.
15
+ */
16
+ export declare function estimateTokens(value: string): number;
17
+ /** Return the deterministic units used by estimateTokens. */
18
+ export declare function estimatedTokenUnits(value: string): EstimatedTokenUnit[];
19
+ /** Return Markdown after a complete leading YAML frontmatter block. */
20
+ export declare function markdownBody(value: string): string;
21
+ //# sourceMappingURL=token-estimator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-estimator.d.ts","sourceRoot":"","sources":["../src/token-estimator.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAOD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,6DAA6D;AAC7D,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAiEvE;AAED,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOlD"}
@@ -0,0 +1,84 @@
1
+ const CJK_RUN = /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}]/u;
2
+ const WORD_RUN = /[\p{L}\p{N}_]/u;
3
+ const WORD_CONTINUATION = /[\p{L}\p{N}_./:+\-=]/u;
4
+ /**
5
+ * Estimate tokens without claiming compatibility with a model tokenizer.
6
+ *
7
+ * Latin-like words, code identifiers, URLs, and repository paths are lexical
8
+ * units. Consecutive Han, Hiragana, Katakana, and Hangul text is divided into
9
+ * two-code-point units so unspaced Japanese is neither one token nor one token
10
+ * per character. Other punctuation is grouped in runs of up to three code
11
+ * points. The algorithm is Unicode-aware, dependency-free, and deterministic,
12
+ * but is only suitable for stable repository thresholds and comparisons.
13
+ */
14
+ export function estimateTokens(value) {
15
+ return estimatedTokenUnits(value).length;
16
+ }
17
+ /** Return the deterministic units used by estimateTokens. */
18
+ export function estimatedTokenUnits(value) {
19
+ const codePoints = [...value];
20
+ const offsets = [];
21
+ let utf16Offset = 0;
22
+ for (const codePoint of codePoints) {
23
+ offsets.push(utf16Offset);
24
+ utf16Offset += codePoint.length;
25
+ }
26
+ const units = [];
27
+ let index = 0;
28
+ while (index < codePoints.length) {
29
+ const current = codePoints[index] ?? "";
30
+ if (/\s/u.test(current)) {
31
+ index += 1;
32
+ continue;
33
+ }
34
+ if (CJK_RUN.test(current)) {
35
+ const start = index;
36
+ index += 1;
37
+ if (index < codePoints.length && CJK_RUN.test(codePoints[index] ?? "")) {
38
+ index += 1;
39
+ }
40
+ units.push({
41
+ value: codePoints.slice(start, index).join("").toLowerCase(),
42
+ offset: offsets[start] ?? 0,
43
+ });
44
+ continue;
45
+ }
46
+ if (WORD_RUN.test(current)) {
47
+ const start = index;
48
+ index += 1;
49
+ while (index < codePoints.length &&
50
+ WORD_CONTINUATION.test(codePoints[index] ?? "") &&
51
+ !CJK_RUN.test(codePoints[index] ?? "")) {
52
+ index += 1;
53
+ }
54
+ units.push({
55
+ value: codePoints.slice(start, index).join("").toLowerCase(),
56
+ offset: offsets[start] ?? 0,
57
+ });
58
+ continue;
59
+ }
60
+ const start = index;
61
+ index += 1;
62
+ while (index < codePoints.length &&
63
+ index - start < 3 &&
64
+ !/\s/u.test(codePoints[index] ?? "") &&
65
+ !WORD_RUN.test(codePoints[index] ?? "") &&
66
+ !CJK_RUN.test(codePoints[index] ?? "")) {
67
+ index += 1;
68
+ }
69
+ units.push({
70
+ value: codePoints.slice(start, index).join(""),
71
+ offset: offsets[start] ?? 0,
72
+ });
73
+ }
74
+ return units;
75
+ }
76
+ /** Return Markdown after a complete leading YAML frontmatter block. */
77
+ export function markdownBody(value) {
78
+ const lines = value.split(/\r?\n/);
79
+ if (lines[0]?.trim() !== "---")
80
+ return value;
81
+ const end = lines.findIndex((line, index) => index > 0 && line.trim() === "---");
82
+ return end < 0 ? value : lines.slice(end + 1).join("\n");
83
+ }
84
+ //# sourceMappingURL=token-estimator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-estimator.js","sourceRoot":"","sources":["../src/token-estimator.ts"],"names":[],"mappings":"AAMA,MAAM,OAAO,GACX,0EAA0E,CAAC;AAC7E,MAAM,QAAQ,GAAG,gBAAgB,CAAC;AAClC,MAAM,iBAAiB,GAAG,uBAAuB,CAAC;AAElD;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;AAC3C,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IAC9B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1B,WAAW,IAAI,SAAS,CAAC,MAAM,CAAC;IAClC,CAAC;IAED,MAAM,KAAK,GAAyB,EAAE,CAAC;IACvC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACxC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,KAAK,IAAI,CAAC,CAAC;YACX,SAAS;QACX,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,KAAK,CAAC;YACpB,KAAK,IAAI,CAAC,CAAC;YACX,IAAI,KAAK,GAAG,UAAU,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;gBACvE,KAAK,IAAI,CAAC,CAAC;YACb,CAAC;YACD,KAAK,CAAC,IAAI,CAAC;gBACT,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE;gBAC5D,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;aAC5B,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,KAAK,CAAC;YACpB,KAAK,IAAI,CAAC,CAAC;YACX,OACE,KAAK,GAAG,UAAU,CAAC,MAAM;gBACzB,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBAC/C,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EACtC,CAAC;gBACD,KAAK,IAAI,CAAC,CAAC;YACb,CAAC;YACD,KAAK,CAAC,IAAI,CAAC;gBACT,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE;gBAC5D,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;aAC5B,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,MAAM,KAAK,GAAG,KAAK,CAAC;QACpB,KAAK,IAAI,CAAC,CAAC;QACX,OACE,KAAK,GAAG,UAAU,CAAC,MAAM;YACzB,KAAK,GAAG,KAAK,GAAG,CAAC;YACjB,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACpC,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACvC,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EACtC,CAAC;YACD,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;QACD,KAAK,CAAC,IAAI,CAAC;YACT,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9C,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;SAC5B,CAAC,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAC7C,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,CACzB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,KAAK,CACpD,CAAC;IACF,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3D,CAAC"}
@@ -1,9 +1,9 @@
1
- import type { Catalog } from "./model.js";
1
+ import { type Catalog } from "./model.js";
2
2
  import type { SecurityPolicyAssetEvidence } from "./security-policy-inventory.js";
3
3
  import type { Diagnostic, Evidence, Finding, RiskClass } from "./types.js";
4
- export type TrustGraphSchemaVersion = "renma.trustGraph.v1";
4
+ export type TrustGraphSchemaVersion = "renma.trustGraph.v2";
5
5
  export type TrustGraphNodeType = "asset" | "owner" | "lifecycle_status" | "security_profile" | "effective_policy" | "diagnostic";
6
- export type TrustGraphEdgeType = "owned_by" | "has_lifecycle_status" | "declares_dependency" | "references" | "selects_security_profile" | "inherits_policy" | "has_effective_policy" | "has_diagnostic";
6
+ export type TrustGraphEdgeType = "owned_by" | "has_lifecycle_status" | "declares_dependency" | "references" | "owns_local_resource" | "statically_references" | "inherits_owner" | "selects_security_profile" | "inherits_policy" | "has_effective_policy" | "has_diagnostic";
7
7
  export type TrustGraphFindingSource = "finding" | "diagnostic";
8
8
  export type TrustGraphFindingSeverity = Finding["severity"] | Diagnostic["severity"];
9
9
  export interface TrustGraphSummary {
@@ -1 +1 @@
1
- {"version":3,"file":"trust-graph.d.ts","sourceRoot":"","sources":["../src/trust-graph.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"trust-graph.d.ts","sourceRoot":"","sources":["../src/trust-graph.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
+ import { normalizeDependencyReference, resolveDependencyTarget, } from "./dependency-resolution.js";
3
+ import { effectiveAssetOwner, } from "./model.js";
2
4
  const NODE_TYPES = [
3
5
  "asset",
4
6
  "owner",
@@ -12,6 +14,9 @@ const EDGE_TYPES = [
12
14
  "has_lifecycle_status",
13
15
  "declares_dependency",
14
16
  "references",
17
+ "owns_local_resource",
18
+ "statically_references",
19
+ "inherits_owner",
15
20
  "selects_security_profile",
16
21
  "inherits_policy",
17
22
  "has_effective_policy",
@@ -37,17 +42,33 @@ export function buildTrustGraph(input) {
37
42
  const edges = new Map();
38
43
  const assets = stableAssets(input.catalog.assets);
39
44
  const assetsById = new Map(assets.map((asset) => [asset.id, asset]));
40
- const assetsByPath = new Map(assets.map((asset) => [normalizeReference(asset.sourcePath), asset]));
45
+ const assetsByPath = new Map(assets.map((asset) => [
46
+ normalizeDependencyReference(asset.sourcePath),
47
+ asset,
48
+ ]));
41
49
  for (const asset of assets) {
42
50
  addNode(nodes, assetNode(asset));
43
- if (asset.metadata.owner) {
44
- const ownerNodeId = ownerNode(asset.metadata.owner).id;
45
- addNode(nodes, ownerNode(asset.metadata.owner));
51
+ const owner = effectiveAssetOwner(asset);
52
+ if (owner) {
53
+ const ownerNodeId = ownerNode(owner).id;
54
+ addNode(nodes, ownerNode(owner));
55
+ const inheritedOwnerAsset = asset.ownership.source === "inherited" && asset.ownership.inheritedFrom
56
+ ? assetsByPath.get(normalizeDependencyReference(asset.ownership.inheritedFrom.sourcePath))
57
+ : undefined;
46
58
  addEdge(edges, {
47
59
  from: assetNodeId(asset),
48
60
  to: ownerNodeId,
49
61
  type: "owned_by",
50
- evidence: metadataEvidence(asset, "owner"),
62
+ properties: {
63
+ ownershipSource: asset.ownership.source,
64
+ ...(asset.ownership.source === "inherited" &&
65
+ asset.ownership.inheritedFrom
66
+ ? { inheritedFrom: asset.ownership.inheritedFrom }
67
+ : {}),
68
+ },
69
+ evidence: inheritedOwnerAsset
70
+ ? metadataEvidence(inheritedOwnerAsset, "owner")
71
+ : metadataEvidence(asset, "owner"),
51
72
  });
52
73
  }
53
74
  if (asset.metadata.status) {
@@ -69,26 +90,46 @@ export function buildTrustGraph(input) {
69
90
  addEdge(edges, {
70
91
  from: assetNodeId(source),
71
92
  to: assetNodeId(target),
72
- type: dependency.kind === "references" ? "references" : "declares_dependency",
93
+ type: trustEdgeTypeForDependency(dependency),
73
94
  properties: {
74
95
  dependencyKind: dependency.kind,
75
96
  declaredTarget: dependency.to,
97
+ ...(dependency.kind === "inherits_owner" ||
98
+ dependency.kind === "inherits_policy"
99
+ ? {
100
+ inheritedFrom: {
101
+ id: target.id,
102
+ sourcePath: target.sourcePath,
103
+ },
104
+ }
105
+ : {}),
76
106
  },
77
107
  evidence: dependency.evidence ? [dependency.evidence] : [],
78
108
  });
79
109
  }
80
110
  for (const policy of input.securityPolicies ?? []) {
81
- const asset = assetsByPath.get(normalizeReference(policy.path));
111
+ const asset = assetsByPath.get(normalizeDependencyReference(policy.path));
82
112
  if (!asset)
83
113
  continue;
84
- addPolicyEvidence(nodes, edges, asset, policy);
114
+ const inheritedAsset = policy.inheritedFrom
115
+ ? assetsByPath.get(normalizeDependencyReference(policy.inheritedFrom.sourcePath))
116
+ : undefined;
117
+ addPolicyEvidence(nodes, edges, asset, inheritedAsset
118
+ ? {
119
+ ...policy,
120
+ inheritedFrom: {
121
+ id: inheritedAsset.id,
122
+ sourcePath: inheritedAsset.sourcePath,
123
+ },
124
+ }
125
+ : policy);
85
126
  }
86
127
  const findings = stableTrustGraphFindings((input.findings ?? []).map(findingToTrustGraphFinding), (input.diagnostics ?? []).map(diagnosticToTrustGraphFinding));
87
128
  for (const finding of findings) {
88
129
  const diagnostic = diagnosticNode(finding);
89
130
  addNode(nodes, diagnostic);
90
131
  const asset = finding.path
91
- ? assetsByPath.get(normalizeReference(finding.path))
132
+ ? assetsByPath.get(normalizeDependencyReference(finding.path))
92
133
  : undefined;
93
134
  if (asset) {
94
135
  addEdge(edges, {
@@ -101,13 +142,25 @@ export function buildTrustGraph(input) {
101
142
  }
102
143
  const sortedNodes = [...nodes.values()].sort(compareNodes);
103
144
  const sortedEdges = [...edges.values()].sort(compareEdges);
104
- return {
105
- schemaVersion: "renma.trustGraph.v1",
145
+ const graph = {
146
+ schemaVersion: "renma.trustGraph.v2",
106
147
  summary: summarizeTrustGraph(assets.length, sortedNodes, sortedEdges, findings),
107
148
  nodes: sortedNodes,
108
149
  edges: sortedEdges,
109
150
  findings,
110
151
  };
152
+ return graph;
153
+ }
154
+ function trustEdgeTypeForDependency(dependency) {
155
+ if (dependency.kind === "references")
156
+ return "references";
157
+ if (dependency.kind === "owns_local_resource" ||
158
+ dependency.kind === "statically_references" ||
159
+ dependency.kind === "inherits_owner" ||
160
+ dependency.kind === "inherits_policy") {
161
+ return dependency.kind;
162
+ }
163
+ return "declares_dependency";
111
164
  }
112
165
  function addPolicyEvidence(nodes, edges, asset, policy) {
113
166
  if (policy.selectedSecurityProfile) {
@@ -126,6 +179,11 @@ function addPolicyEvidence(nodes, edges, asset, policy) {
126
179
  : [],
127
180
  });
128
181
  }
182
+ if (!policy.hasEffectivePolicy)
183
+ return;
184
+ if (policy.policySources.length === 0) {
185
+ throw new Error(`Effective security policy for ${policy.path} has no provenance source.`);
186
+ }
129
187
  for (let index = 1; index < policy.profileChain.length; index += 1) {
130
188
  const childProfile = policy.profileChain[index];
131
189
  const parentProfile = policy.profileChain[index - 1];
@@ -149,6 +207,8 @@ function addPolicyEvidence(nodes, edges, asset, policy) {
149
207
  type: "has_effective_policy",
150
208
  properties: {
151
209
  hasLocalPolicyMetadata: policy.hasLocalPolicyMetadata,
210
+ policySources: policy.policySources,
211
+ ...(policy.inheritedFrom ? { inheritedFrom: policy.inheritedFrom } : {}),
152
212
  },
153
213
  evidence: policy.evidence.policyFields,
154
214
  });
@@ -163,8 +223,11 @@ function assetNode(asset) {
163
223
  kind: asset.kind,
164
224
  sourcePath: asset.sourcePath,
165
225
  contentHash: asset.contentHash,
226
+ sizeBytes: asset.sizeBytes,
227
+ contentClassification: asset.contentClassification,
228
+ markdownParserEligible: asset.markdownParserEligible,
166
229
  tags: asset.metadata.tags,
167
- ...(asset.metadata.owner ? { owner: asset.metadata.owner } : {}),
230
+ ownership: asset.ownership,
168
231
  ...(asset.metadata.status ? { status: asset.metadata.status } : {}),
169
232
  },
170
233
  evidence: [
@@ -237,7 +300,7 @@ function diagnosticNode(finding) {
237
300
  };
238
301
  }
239
302
  function assetNodeId(asset) {
240
- // Trust Graph v1 keeps asset IDs logical. Duplicate-id diagnostics preserve
303
+ // Trust Graph keeps asset IDs logical. Duplicate-id diagnostics preserve
241
304
  // per-source evidence when multiple catalog assets share the same id.
242
305
  return `asset:${asset.id}`;
243
306
  }
@@ -383,14 +446,6 @@ function summarizeTrustGraph(assetCount, nodes, edges, findings) {
383
446
  function zeroCounts(values) {
384
447
  return Object.fromEntries(values.map((value) => [value, 0]));
385
448
  }
386
- function resolveDependencyTarget(dependency, assets) {
387
- const target = normalizeReference(dependency.to);
388
- return assets.find((asset) => asset.id === dependency.to ||
389
- normalizeReference(asset.sourcePath) === target);
390
- }
391
- function normalizeReference(reference) {
392
- return reference.replace(/\\/g, "/").replace(/^\.\//, "");
393
- }
394
449
  function stableAssets(assets) {
395
450
  return [...assets].sort((left, right) => {
396
451
  const byKind = left.kind.localeCompare(right.kind);