@ai-dossier/core 1.0.1 → 1.0.3

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 (52) hide show
  1. package/README.md +232 -0
  2. package/dist/formatter/formatter.d.ts.map +1 -1
  3. package/dist/formatter/formatter.js +2 -0
  4. package/dist/formatter/formatter.js.map +1 -1
  5. package/dist/index.d.ts +5 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +17 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/linter/rules/external-references-declared.d.ts +3 -0
  10. package/dist/linter/rules/external-references-declared.d.ts.map +1 -0
  11. package/dist/linter/rules/external-references-declared.js +48 -0
  12. package/dist/linter/rules/external-references-declared.js.map +1 -0
  13. package/dist/linter/rules/index.d.ts +2 -1
  14. package/dist/linter/rules/index.d.ts.map +1 -1
  15. package/dist/linter/rules/index.js +4 -1
  16. package/dist/linter/rules/index.js.map +1 -1
  17. package/dist/linter/rules/risk-level-consistency.d.ts.map +1 -1
  18. package/dist/linter/rules/risk-level-consistency.js +12 -2
  19. package/dist/linter/rules/risk-level-consistency.js.map +1 -1
  20. package/dist/linter/rules/tools-check-command.d.ts.map +1 -1
  21. package/dist/linter/rules/tools-check-command.js.map +1 -1
  22. package/dist/parser.d.ts +20 -4
  23. package/dist/parser.d.ts.map +1 -1
  24. package/dist/parser.js +64 -32
  25. package/dist/parser.js.map +1 -1
  26. package/dist/risk-assessment.d.ts +29 -0
  27. package/dist/risk-assessment.d.ts.map +1 -0
  28. package/dist/risk-assessment.js +83 -0
  29. package/dist/risk-assessment.js.map +1 -0
  30. package/dist/schema/dossier-schema.json +47 -0
  31. package/dist/signature.d.ts +4 -4
  32. package/dist/signature.d.ts.map +1 -1
  33. package/dist/signature.js +9 -8
  34. package/dist/signature.js.map +1 -1
  35. package/dist/signers/ed25519.d.ts +2 -2
  36. package/dist/signers/ed25519.d.ts.map +1 -1
  37. package/dist/signers/ed25519.js +4 -3
  38. package/dist/signers/ed25519.js.map +1 -1
  39. package/dist/signers/index.d.ts +9 -2
  40. package/dist/signers/index.d.ts.map +1 -1
  41. package/dist/signers/index.js.map +1 -1
  42. package/dist/signers/kms.d.ts +2 -2
  43. package/dist/signers/kms.d.ts.map +1 -1
  44. package/dist/signers/kms.js +4 -4
  45. package/dist/signers/kms.js.map +1 -1
  46. package/dist/types.d.ts +44 -15
  47. package/dist/types.d.ts.map +1 -1
  48. package/dist/utils/url-scanner.d.ts +8 -0
  49. package/dist/utils/url-scanner.d.ts.map +1 -0
  50. package/dist/utils/url-scanner.js +73 -0
  51. package/dist/utils/url-scanner.js.map +1 -0
  52. package/package.json +9 -4
package/README.md ADDED
@@ -0,0 +1,232 @@
1
+ # @ai-dossier/core
2
+
3
+ Core parsing, verification, and linting logic for the [Dossier](https://github.com/imboard-ai/ai-dossier) automation standard.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @ai-dossier/core
9
+ ```
10
+
11
+ Requires Node.js >= 18.0.0.
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import {
17
+ parseDossierContent,
18
+ verifyIntegrity,
19
+ lintDossier,
20
+ } from '@ai-dossier/core';
21
+
22
+ // 1. Parse a dossier
23
+ const dossier = parseDossierContent(rawContent);
24
+ console.log(dossier.frontmatter.title); // => "My Dossier"
25
+
26
+ // 2. Verify integrity
27
+ const integrity = verifyIntegrity(
28
+ dossier.body,
29
+ dossier.frontmatter.checksum?.hash
30
+ );
31
+ console.log(integrity.status); // => "valid" | "invalid" | "missing"
32
+
33
+ // 3. Lint for issues
34
+ const result = lintDossier(rawContent);
35
+ console.log(result.errorCount, result.warningCount);
36
+ ```
37
+
38
+ ## API
39
+
40
+ ### Parsing
41
+
42
+ ```typescript
43
+ import {
44
+ parseDossierContent,
45
+ parseDossierFile,
46
+ validateFrontmatter,
47
+ } from '@ai-dossier/core';
48
+ ```
49
+
50
+ #### `parseDossierContent(content: string): ParsedDossier`
51
+
52
+ Parse a dossier content string into frontmatter and body. Accepts both `---dossier` (JSON/YAML) and standard `---` (YAML) delimiters.
53
+
54
+ ```typescript
55
+ const { frontmatter, body, raw } = parseDossierContent(content);
56
+ ```
57
+
58
+ #### `parseDossierFile(filePath: string): ParsedDossier`
59
+
60
+ Read and parse a dossier file from disk.
61
+
62
+ ```typescript
63
+ const parsed = parseDossierFile('./path/to/dossier.ds.md');
64
+ ```
65
+
66
+ #### `validateFrontmatter(frontmatter: DossierFrontmatter): string[]`
67
+
68
+ Validate required fields and enum values. Returns an array of error messages (empty if valid).
69
+
70
+ ```typescript
71
+ const errors = validateFrontmatter(parsed.frontmatter);
72
+ if (errors.length > 0) {
73
+ console.error('Validation errors:', errors);
74
+ }
75
+ ```
76
+
77
+ ### Checksum Verification
78
+
79
+ ```typescript
80
+ import { calculateChecksum, verifyIntegrity } from '@ai-dossier/core';
81
+ ```
82
+
83
+ #### `calculateChecksum(body: string): string`
84
+
85
+ Calculate the SHA-256 hash of dossier body content (excluding frontmatter).
86
+
87
+ #### `verifyIntegrity(body: string, expectedHash: string | undefined): IntegrityResult`
88
+
89
+ Compare the computed hash against the expected hash from frontmatter.
90
+
91
+ ```typescript
92
+ const result = verifyIntegrity(body, frontmatter.checksum?.hash);
93
+ // result.status: "valid" | "invalid" | "missing"
94
+ ```
95
+
96
+ ### Signature Verification
97
+
98
+ ```typescript
99
+ import {
100
+ verifySignature,
101
+ verifyWithEd25519,
102
+ verifyWithKms,
103
+ loadTrustedKeys,
104
+ } from '@ai-dossier/core';
105
+ ```
106
+
107
+ #### `verifySignature(content: string, signature: SignatureResult): Promise<VerifyResult>`
108
+
109
+ Verify a signature using the verifier registry. Automatically selects the correct verifier based on `signature.algorithm`.
110
+
111
+ ```typescript
112
+ const result = await verifySignature(body, frontmatter.signature);
113
+ console.log(result.valid); // true | false
114
+ ```
115
+
116
+ #### `verifyWithEd25519(content: string, signature: string, publicKey: string): VerifyResult`
117
+
118
+ Verify an Ed25519 signature directly.
119
+
120
+ #### `verifyWithKms(content: string, signature: string, keyId: string, region?: string): Promise<VerifyResult>`
121
+
122
+ Verify an ECDSA-SHA-256 signature using AWS KMS.
123
+
124
+ #### `loadTrustedKeys(filePath?: string): Map<string, string>`
125
+
126
+ Load trusted public keys from a file (default: `~/.dossier/trusted-keys.txt`). Returns a map of public key to key ID.
127
+
128
+ ### Linting
129
+
130
+ ```typescript
131
+ import { lintDossier, lintDossierFile } from '@ai-dossier/core';
132
+ ```
133
+
134
+ #### `lintDossier(content: string, config?: LintConfig): LintResult`
135
+
136
+ Lint dossier content against built-in rules (checksum validity, schema validation, required sections, semver version, etc.).
137
+
138
+ ```typescript
139
+ const result = lintDossier(content);
140
+ for (const d of result.diagnostics) {
141
+ console.log(`[${d.severity}] ${d.ruleId}: ${d.message}`);
142
+ }
143
+ ```
144
+
145
+ #### `lintDossierFile(filePath: string, config?: LintConfig): LintResult`
146
+
147
+ Lint a dossier file from disk.
148
+
149
+ ### Formatting
150
+
151
+ ```typescript
152
+ import { formatDossierContent, formatDossierFile } from '@ai-dossier/core';
153
+ ```
154
+
155
+ #### `formatDossierContent(content: string, options?: Partial<FormatOptions>): FormatResult`
156
+
157
+ Format dossier content (sort keys, update checksum). Returns `{ formatted, changed }`.
158
+
159
+ ```typescript
160
+ const { formatted, changed } = formatDossierContent(rawContent, {
161
+ sortKeys: true,
162
+ updateChecksum: true,
163
+ });
164
+ ```
165
+
166
+ #### `formatDossierFile(filePath: string, options?: Partial<FormatOptions>): FormatResult`
167
+
168
+ Format a dossier file in place. Only writes if changes were made.
169
+
170
+ ### Signer/Verifier Interfaces
171
+
172
+ The package exports extensible interfaces for signing and verification:
173
+
174
+ ```typescript
175
+ import type { Signer, Verifier, SignatureResult, VerifyResult } from '@ai-dossier/core';
176
+ ```
177
+
178
+ Built-in implementations:
179
+ - `Ed25519Signer` / `Ed25519Verifier` — Ed25519 key pair signing
180
+ - `KmsSigner` / `KmsVerifier` — AWS KMS ECDSA-SHA-256 signing
181
+
182
+ Registry for algorithm dispatch:
183
+ ```typescript
184
+ import { getVerifierRegistry, VerifierRegistry } from '@ai-dossier/core';
185
+
186
+ const registry = getVerifierRegistry();
187
+ const verifier = registry.get('ed25519');
188
+ const result = await verifier.verify(content, signature);
189
+ ```
190
+
191
+ ## Types
192
+
193
+ All TypeScript types are exported from the package root:
194
+
195
+ ```typescript
196
+ import type {
197
+ // Core types
198
+ DossierFrontmatter, // Frontmatter fields (title, version, checksum, signature, ...)
199
+ ParsedDossier, // { frontmatter, body, raw }
200
+ DossierStatus, // "Draft" | "Stable" | "Deprecated" | "Experimental"
201
+ DossierListItem, // Summary for listing dossiers
202
+
203
+ // Verification
204
+ IntegrityResult, // Checksum verification result
205
+ AuthenticityResult, // Signature verification result
206
+ RiskAssessment, // Risk level, factors, destructive ops
207
+ VerificationResult, // Combined verification report
208
+ TrustedKey, // { publicKey, keyId }
209
+
210
+ // Signing
211
+ Signer, // Sign interface
212
+ Verifier, // Verify interface
213
+ SignatureResult, // Signature metadata
214
+ VerifyResult, // { valid, error? }
215
+ VerifierRegistry, // Algorithm → verifier dispatch
216
+
217
+ // Linting
218
+ LintResult, // { diagnostics, errorCount, warningCount, infoCount }
219
+ LintDiagnostic, // { ruleId, severity, message, field? }
220
+ LintRule, // Custom rule interface
221
+ LintConfig, // { rules: Record<string, severity> }
222
+ LintSeverity, // "error" | "warning" | "info"
223
+
224
+ // Formatting
225
+ FormatOptions, // { indent, sortKeys, updateChecksum }
226
+ FormatResult, // { formatted, changed }
227
+ } from '@ai-dossier/core';
228
+ ```
229
+
230
+ ## License
231
+
232
+ [AGPL-3.0](https://github.com/imboard-ai/ai-dossier/blob/main/LICENSE)
@@ -1 +1 @@
1
- {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../src/formatter/formatter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAiG3D,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC/B,YAAY,CAmCd"}
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../src/formatter/formatter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAmG3D,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC/B,YAAY,CAmCd"}
@@ -25,6 +25,8 @@ const KEY_ORDER = [
25
25
  'risk_factors',
26
26
  'requires_approval',
27
27
  'destructive_operations',
28
+ 'content_scope',
29
+ 'external_references',
28
30
  'prerequisites',
29
31
  'inputs',
30
32
  'outputs',
@@ -1 +1 @@
1
- {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../src/formatter/formatter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../src/formatter/formatter.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -12,12 +12,15 @@ export type { FormatOptions, FormatResult } from './formatter';
12
12
  export { formatDossierContent, formatDossierFile } from './formatter';
13
13
  export type { LintConfig, LintDiagnostic, LintResult, LintRule, LintRuleContext, LintSeverity, RuleSeverityOverride, } from './linter';
14
14
  export { defaultRules, LintRuleRegistry, lintDossier, lintDossierFile, loadLintConfig, } from './linter';
15
- export { parseDossierContent, parseDossierFile, validateFrontmatter } from './parser';
15
+ export { parseDossierContent, parseDossierFile, RECOMMENDED_FIELDS, REQUIRED_FIELDS, VALID_RISK_LEVELS, VALID_STATUSES, validateFrontmatter, } from './parser';
16
+ export type { ChecksumStatus, ContentRiskResult, SignatureStatus, VerificationRiskLevel, VerificationRiskResult, } from './risk-assessment';
17
+ export { assessContentRisk, assessVerificationRisk } from './risk-assessment';
16
18
  export { loadTrustedKeys, verifySignature, verifyWithEd25519, verifyWithKms } from './signature';
17
- export { Ed25519Signer, Ed25519Verifier, getVerifierRegistry, KmsSigner, KmsVerifier, SignatureResult, Signer, Verifier, VerifierRegistry, } from './signers';
19
+ export { Ed25519Signer, Ed25519Verifier, getVerifierRegistry, KmsSigner, KmsVerifier, SignatureResult, Signer, Verifier, VerifierRegistry, VerifyResult, } from './signers';
18
20
  export * from './types';
19
21
  export { sha256Hash, sha256Hex } from './utils/crypto';
20
22
  export { getErrorMessage, getErrorStack } from './utils/errors';
21
23
  export { readFileIfExists } from './utils/fs';
24
+ export { collectDeclaredUrls, findStaleReferences, findUndeclaredUrls, isPlaceholderUrl, isUrlCoveredByDeclared, scanBodyForUrls, } from './utils/url-scanner';
22
25
  export { createDefaultVerificationResult } from './utils/verification';
23
26
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAChE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACtE,YAAY,EACV,UAAU,EACV,cAAc,EACd,UAAU,EACV,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,oBAAoB,GACrB,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAEtF,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjG,OAAO,EACL,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,SAAS,EACT,WAAW,EACX,eAAe,EACf,MAAM,EACN,QAAQ,EACR,gBAAgB,GACjB,MAAM,WAAW,CAAC;AAEnB,cAAc,SAAS,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,+BAA+B,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAChE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACtE,YAAY,EACV,UAAU,EACV,cAAc,EACd,UAAU,EACV,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,oBAAoB,GACrB,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,mBAAmB,GACpB,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE9E,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjG,OAAO,EACL,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,SAAS,EACT,WAAW,EACX,eAAe,EACf,MAAM,EACN,QAAQ,EACR,gBAAgB,EAChB,YAAY,GACb,MAAM,WAAW,CAAC;AAEnB,cAAc,SAAS,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,+BAA+B,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
23
23
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.createDefaultVerificationResult = exports.readFileIfExists = exports.getErrorStack = exports.getErrorMessage = exports.sha256Hex = exports.sha256Hash = exports.VerifierRegistry = exports.KmsVerifier = exports.KmsSigner = exports.getVerifierRegistry = exports.Ed25519Verifier = exports.Ed25519Signer = exports.verifyWithKms = exports.verifyWithEd25519 = exports.verifySignature = exports.loadTrustedKeys = exports.validateFrontmatter = exports.parseDossierFile = exports.parseDossierContent = exports.loadLintConfig = exports.lintDossierFile = exports.lintDossier = exports.LintRuleRegistry = exports.defaultRules = exports.formatDossierFile = exports.formatDossierContent = exports.verifyIntegrity = exports.calculateChecksum = void 0;
26
+ exports.createDefaultVerificationResult = exports.scanBodyForUrls = exports.isUrlCoveredByDeclared = exports.isPlaceholderUrl = exports.findUndeclaredUrls = exports.findStaleReferences = exports.collectDeclaredUrls = exports.readFileIfExists = exports.getErrorStack = exports.getErrorMessage = exports.sha256Hex = exports.sha256Hash = exports.VerifierRegistry = exports.KmsVerifier = exports.KmsSigner = exports.getVerifierRegistry = exports.Ed25519Verifier = exports.Ed25519Signer = exports.verifyWithKms = exports.verifyWithEd25519 = exports.verifySignature = exports.loadTrustedKeys = exports.assessVerificationRisk = exports.assessContentRisk = exports.validateFrontmatter = exports.VALID_STATUSES = exports.VALID_RISK_LEVELS = exports.REQUIRED_FIELDS = exports.RECOMMENDED_FIELDS = exports.parseDossierFile = exports.parseDossierContent = exports.loadLintConfig = exports.lintDossierFile = exports.lintDossier = exports.LintRuleRegistry = exports.defaultRules = exports.formatDossierFile = exports.formatDossierContent = exports.verifyIntegrity = exports.calculateChecksum = void 0;
27
27
  // Checksum exports
28
28
  var checksum_1 = require("./checksum");
29
29
  Object.defineProperty(exports, "calculateChecksum", { enumerable: true, get: function () { return checksum_1.calculateChecksum; } });
@@ -43,7 +43,15 @@ Object.defineProperty(exports, "loadLintConfig", { enumerable: true, get: functi
43
43
  var parser_1 = require("./parser");
44
44
  Object.defineProperty(exports, "parseDossierContent", { enumerable: true, get: function () { return parser_1.parseDossierContent; } });
45
45
  Object.defineProperty(exports, "parseDossierFile", { enumerable: true, get: function () { return parser_1.parseDossierFile; } });
46
+ Object.defineProperty(exports, "RECOMMENDED_FIELDS", { enumerable: true, get: function () { return parser_1.RECOMMENDED_FIELDS; } });
47
+ Object.defineProperty(exports, "REQUIRED_FIELDS", { enumerable: true, get: function () { return parser_1.REQUIRED_FIELDS; } });
48
+ Object.defineProperty(exports, "VALID_RISK_LEVELS", { enumerable: true, get: function () { return parser_1.VALID_RISK_LEVELS; } });
49
+ Object.defineProperty(exports, "VALID_STATUSES", { enumerable: true, get: function () { return parser_1.VALID_STATUSES; } });
46
50
  Object.defineProperty(exports, "validateFrontmatter", { enumerable: true, get: function () { return parser_1.validateFrontmatter; } });
51
+ // Risk assessment exports
52
+ var risk_assessment_1 = require("./risk-assessment");
53
+ Object.defineProperty(exports, "assessContentRisk", { enumerable: true, get: function () { return risk_assessment_1.assessContentRisk; } });
54
+ Object.defineProperty(exports, "assessVerificationRisk", { enumerable: true, get: function () { return risk_assessment_1.assessVerificationRisk; } });
47
55
  // Signature exports
48
56
  var signature_1 = require("./signature");
49
57
  Object.defineProperty(exports, "loadTrustedKeys", { enumerable: true, get: function () { return signature_1.loadTrustedKeys; } });
@@ -71,6 +79,14 @@ Object.defineProperty(exports, "getErrorStack", { enumerable: true, get: functio
71
79
  // File system utilities
72
80
  var fs_1 = require("./utils/fs");
73
81
  Object.defineProperty(exports, "readFileIfExists", { enumerable: true, get: function () { return fs_1.readFileIfExists; } });
82
+ // URL scanning utilities
83
+ var url_scanner_1 = require("./utils/url-scanner");
84
+ Object.defineProperty(exports, "collectDeclaredUrls", { enumerable: true, get: function () { return url_scanner_1.collectDeclaredUrls; } });
85
+ Object.defineProperty(exports, "findStaleReferences", { enumerable: true, get: function () { return url_scanner_1.findStaleReferences; } });
86
+ Object.defineProperty(exports, "findUndeclaredUrls", { enumerable: true, get: function () { return url_scanner_1.findUndeclaredUrls; } });
87
+ Object.defineProperty(exports, "isPlaceholderUrl", { enumerable: true, get: function () { return url_scanner_1.isPlaceholderUrl; } });
88
+ Object.defineProperty(exports, "isUrlCoveredByDeclared", { enumerable: true, get: function () { return url_scanner_1.isUrlCoveredByDeclared; } });
89
+ Object.defineProperty(exports, "scanBodyForUrls", { enumerable: true, get: function () { return url_scanner_1.scanBodyForUrls; } });
74
90
  // Verification utilities
75
91
  var verification_1 = require("./utils/verification");
76
92
  Object.defineProperty(exports, "createDefaultVerificationResult", { enumerable: true, get: function () { return verification_1.createDefaultVerificationResult; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;;;;;;;;;;;;;;;AAEH,mBAAmB;AACnB,uCAAgE;AAAvD,6GAAA,iBAAiB,OAAA;AAAE,2GAAA,eAAe,OAAA;AAE3C,oBAAoB;AACpB,yCAAsE;AAA7D,iHAAA,oBAAoB,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAUhD,iBAAiB;AACjB,mCAMkB;AALhB,sGAAA,YAAY,OAAA;AACZ,0GAAA,gBAAgB,OAAA;AAChB,qGAAA,WAAW,OAAA;AACX,yGAAA,eAAe,OAAA;AACf,wGAAA,cAAc,OAAA;AAEhB,iBAAiB;AACjB,mCAAsF;AAA7E,6GAAA,mBAAmB,OAAA;AAAE,0GAAA,gBAAgB,OAAA;AAAE,6GAAA,mBAAmB,OAAA;AACnE,oBAAoB;AACpB,yCAAiG;AAAxF,4GAAA,eAAe,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAAE,0GAAA,aAAa,OAAA;AAC3E,iDAAiD;AACjD,qCAUmB;AATjB,wGAAA,aAAa,OAAA;AACb,0GAAA,eAAe,OAAA;AACf,8GAAA,mBAAmB,OAAA;AACnB,oGAAA,SAAS,OAAA;AACT,sGAAA,WAAW,OAAA;AAIX,2GAAA,gBAAgB,OAAA;AAElB,eAAe;AACf,0CAAwB;AACxB,mBAAmB;AACnB,yCAAuD;AAA9C,oGAAA,UAAU,OAAA;AAAE,mGAAA,SAAS,OAAA;AAC9B,kBAAkB;AAClB,yCAAgE;AAAvD,yGAAA,eAAe,OAAA;AAAE,uGAAA,aAAa,OAAA;AACvC,wBAAwB;AACxB,iCAA8C;AAArC,sGAAA,gBAAgB,OAAA;AACzB,yBAAyB;AACzB,qDAAuE;AAA9D,+HAAA,+BAA+B,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;;;;;;;;;;;;;;;AAEH,mBAAmB;AACnB,uCAAgE;AAAvD,6GAAA,iBAAiB,OAAA;AAAE,2GAAA,eAAe,OAAA;AAE3C,oBAAoB;AACpB,yCAAsE;AAA7D,iHAAA,oBAAoB,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAUhD,iBAAiB;AACjB,mCAMkB;AALhB,sGAAA,YAAY,OAAA;AACZ,0GAAA,gBAAgB,OAAA;AAChB,qGAAA,WAAW,OAAA;AACX,yGAAA,eAAe,OAAA;AACf,wGAAA,cAAc,OAAA;AAEhB,iBAAiB;AACjB,mCAQkB;AAPhB,6GAAA,mBAAmB,OAAA;AACnB,0GAAA,gBAAgB,OAAA;AAChB,4GAAA,kBAAkB,OAAA;AAClB,yGAAA,eAAe,OAAA;AACf,2GAAA,iBAAiB,OAAA;AACjB,wGAAA,cAAc,OAAA;AACd,6GAAA,mBAAmB,OAAA;AASrB,0BAA0B;AAC1B,qDAA8E;AAArE,oHAAA,iBAAiB,OAAA;AAAE,yHAAA,sBAAsB,OAAA;AAClD,oBAAoB;AACpB,yCAAiG;AAAxF,4GAAA,eAAe,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAAE,0GAAA,aAAa,OAAA;AAC3E,iDAAiD;AACjD,qCAWmB;AAVjB,wGAAA,aAAa,OAAA;AACb,0GAAA,eAAe,OAAA;AACf,8GAAA,mBAAmB,OAAA;AACnB,oGAAA,SAAS,OAAA;AACT,sGAAA,WAAW,OAAA;AAIX,2GAAA,gBAAgB,OAAA;AAGlB,eAAe;AACf,0CAAwB;AACxB,mBAAmB;AACnB,yCAAuD;AAA9C,oGAAA,UAAU,OAAA;AAAE,mGAAA,SAAS,OAAA;AAC9B,kBAAkB;AAClB,yCAAgE;AAAvD,yGAAA,eAAe,OAAA;AAAE,uGAAA,aAAa,OAAA;AACvC,wBAAwB;AACxB,iCAA8C;AAArC,sGAAA,gBAAgB,OAAA;AACzB,yBAAyB;AACzB,mDAO6B;AAN3B,kHAAA,mBAAmB,OAAA;AACnB,kHAAA,mBAAmB,OAAA;AACnB,iHAAA,kBAAkB,OAAA;AAClB,+GAAA,gBAAgB,OAAA;AAChB,qHAAA,sBAAsB,OAAA;AACtB,8GAAA,eAAe,OAAA;AAEjB,yBAAyB;AACzB,qDAAuE;AAA9D,+HAAA,+BAA+B,OAAA"}
@@ -0,0 +1,3 @@
1
+ import type { LintRule } from '../types';
2
+ export declare const externalReferencesDeclaredRule: LintRule;
3
+ //# sourceMappingURL=external-references-declared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-references-declared.d.ts","sourceRoot":"","sources":["../../../src/linter/rules/external-references-declared.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAkB,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzD,eAAO,MAAM,8BAA8B,EAAE,QAgD5C,CAAC"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.externalReferencesDeclaredRule = void 0;
4
+ const url_scanner_1 = require("../../utils/url-scanner");
5
+ exports.externalReferencesDeclaredRule = {
6
+ id: 'external-references-declared',
7
+ description: 'External URLs in body must be declared in external_references',
8
+ defaultSeverity: 'error',
9
+ run(context) {
10
+ const { frontmatter, body } = context;
11
+ const diagnostics = [];
12
+ const bodyUrls = (0, url_scanner_1.scanBodyForUrls)(body);
13
+ if (bodyUrls.length === 0) {
14
+ return diagnostics;
15
+ }
16
+ const declaredUrls = (0, url_scanner_1.collectDeclaredUrls)(frontmatter);
17
+ const undeclaredUrls = (0, url_scanner_1.findUndeclaredUrls)(bodyUrls, declaredUrls);
18
+ for (const url of undeclaredUrls) {
19
+ diagnostics.push({
20
+ ruleId: 'external-references-declared',
21
+ severity: 'error',
22
+ message: `Undeclared external URL in body: ${url} — add it to external_references`,
23
+ field: 'external_references',
24
+ });
25
+ }
26
+ if (bodyUrls.length > 0 && frontmatter.content_scope !== 'references-external') {
27
+ diagnostics.push({
28
+ ruleId: 'external-references-declared',
29
+ severity: 'error',
30
+ message: `Body contains ${bodyUrls.length} external URL(s) but content_scope is not "references-external"`,
31
+ field: 'content_scope',
32
+ });
33
+ }
34
+ if (Array.isArray(frontmatter.external_references)) {
35
+ const stale = (0, url_scanner_1.findStaleReferences)(frontmatter.external_references, bodyUrls);
36
+ for (const ref of stale) {
37
+ diagnostics.push({
38
+ ruleId: 'external-references-declared',
39
+ severity: 'info',
40
+ message: `Declared external reference not found in body (possibly stale): ${ref.url}`,
41
+ field: 'external_references',
42
+ });
43
+ }
44
+ }
45
+ return diagnostics;
46
+ },
47
+ };
48
+ //# sourceMappingURL=external-references-declared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-references-declared.js","sourceRoot":"","sources":["../../../src/linter/rules/external-references-declared.ts"],"names":[],"mappings":";;;AAAA,yDAKiC;AAGpB,QAAA,8BAA8B,GAAa;IACtD,EAAE,EAAE,8BAA8B;IAClC,WAAW,EAAE,+DAA+D;IAC5E,eAAe,EAAE,OAAO;IACxB,GAAG,CAAC,OAAO;QACT,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;QACtC,MAAM,WAAW,GAAqB,EAAE,CAAC;QAEzC,MAAM,QAAQ,GAAG,IAAA,6BAAe,EAAC,IAAI,CAAC,CAAC;QACvC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,MAAM,YAAY,GAAG,IAAA,iCAAmB,EAAC,WAAW,CAAC,CAAC;QACtD,MAAM,cAAc,GAAG,IAAA,gCAAkB,EAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAElE,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;YACjC,WAAW,CAAC,IAAI,CAAC;gBACf,MAAM,EAAE,8BAA8B;gBACtC,QAAQ,EAAE,OAAgB;gBAC1B,OAAO,EAAE,oCAAoC,GAAG,kCAAkC;gBAClF,KAAK,EAAE,qBAAqB;aAC7B,CAAC,CAAC;QACL,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,WAAW,CAAC,aAAa,KAAK,qBAAqB,EAAE,CAAC;YAC/E,WAAW,CAAC,IAAI,CAAC;gBACf,MAAM,EAAE,8BAA8B;gBACtC,QAAQ,EAAE,OAAgB;gBAC1B,OAAO,EAAE,iBAAiB,QAAQ,CAAC,MAAM,iEAAiE;gBAC1G,KAAK,EAAE,eAAe;aACvB,CAAC,CAAC;QACL,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,mBAAmB,CAAC,EAAE,CAAC;YACnD,MAAM,KAAK,GAAG,IAAA,iCAAmB,EAAC,WAAW,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC;YAC7E,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;gBACxB,WAAW,CAAC,IAAI,CAAC;oBACf,MAAM,EAAE,8BAA8B;oBACtC,QAAQ,EAAE,MAAe;oBACzB,OAAO,EAAE,mEAAmE,GAAG,CAAC,GAAG,EAAE;oBACrF,KAAK,EAAE,qBAAqB;iBAC7B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;CACF,CAAC"}
@@ -1,11 +1,12 @@
1
1
  import type { LintRule } from '../types';
2
2
  import { checksumValidRule } from './checksum-valid';
3
+ import { externalReferencesDeclaredRule } from './external-references-declared';
3
4
  import { objectiveQualityRule } from './objective-quality';
4
5
  import { requiredSectionsRule } from './required-sections';
5
6
  import { riskLevelConsistencyRule } from './risk-level-consistency';
6
7
  import { schemaValidRule } from './schema-valid';
7
8
  import { semverVersionRule } from './semver-version';
8
9
  import { toolsCheckCommandRule } from './tools-check-command';
9
- export { checksumValidRule, objectiveQualityRule, requiredSectionsRule, riskLevelConsistencyRule, schemaValidRule, semverVersionRule, toolsCheckCommandRule, };
10
+ export { checksumValidRule, externalReferencesDeclaredRule, objectiveQualityRule, requiredSectionsRule, riskLevelConsistencyRule, schemaValidRule, semverVersionRule, toolsCheckCommandRule, };
10
11
  export declare const defaultRules: LintRule[];
11
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/linter/rules/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,GACtB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,QAAQ,EAQlC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/linter/rules/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EACL,iBAAiB,EACjB,8BAA8B,EAC9B,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,GACtB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,QAAQ,EASlC,CAAC"}
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defaultRules = exports.toolsCheckCommandRule = exports.semverVersionRule = exports.schemaValidRule = exports.riskLevelConsistencyRule = exports.requiredSectionsRule = exports.objectiveQualityRule = exports.checksumValidRule = void 0;
3
+ exports.defaultRules = exports.toolsCheckCommandRule = exports.semverVersionRule = exports.schemaValidRule = exports.riskLevelConsistencyRule = exports.requiredSectionsRule = exports.objectiveQualityRule = exports.externalReferencesDeclaredRule = exports.checksumValidRule = void 0;
4
4
  const checksum_valid_1 = require("./checksum-valid");
5
5
  Object.defineProperty(exports, "checksumValidRule", { enumerable: true, get: function () { return checksum_valid_1.checksumValidRule; } });
6
+ const external_references_declared_1 = require("./external-references-declared");
7
+ Object.defineProperty(exports, "externalReferencesDeclaredRule", { enumerable: true, get: function () { return external_references_declared_1.externalReferencesDeclaredRule; } });
6
8
  const objective_quality_1 = require("./objective-quality");
7
9
  Object.defineProperty(exports, "objectiveQualityRule", { enumerable: true, get: function () { return objective_quality_1.objectiveQualityRule; } });
8
10
  const required_sections_1 = require("./required-sections");
@@ -23,5 +25,6 @@ exports.defaultRules = [
23
25
  tools_check_command_1.toolsCheckCommandRule,
24
26
  objective_quality_1.objectiveQualityRule,
25
27
  required_sections_1.requiredSectionsRule,
28
+ external_references_declared_1.externalReferencesDeclaredRule,
26
29
  ];
27
30
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/linter/rules/index.ts"],"names":[],"mappings":";;;AACA,qDAAqD;AASnD,kGATO,kCAAiB,OASP;AARnB,2DAA2D;AASzD,qGATO,wCAAoB,OASP;AARtB,2DAA2D;AASzD,qGATO,wCAAoB,OASP;AARtB,qEAAoE;AASlE,yGATO,iDAAwB,OASP;AAR1B,iDAAiD;AAS/C,gGATO,8BAAe,OASP;AARjB,qDAAqD;AASnD,kGATO,kCAAiB,OASP;AARnB,+DAA8D;AAS5D,sGATO,2CAAqB,OASP;AAGV,QAAA,YAAY,GAAe;IACtC,8BAAe;IACf,kCAAiB;IACjB,kCAAiB;IACjB,iDAAwB;IACxB,2CAAqB;IACrB,wCAAoB;IACpB,wCAAoB;CACrB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/linter/rules/index.ts"],"names":[],"mappings":";;;AACA,qDAAqD;AAUnD,kGAVO,kCAAiB,OAUP;AATnB,iFAAgF;AAU9E,+GAVO,6DAA8B,OAUP;AAThC,2DAA2D;AAUzD,qGAVO,wCAAoB,OAUP;AATtB,2DAA2D;AAUzD,qGAVO,wCAAoB,OAUP;AATtB,qEAAoE;AAUlE,yGAVO,iDAAwB,OAUP;AAT1B,iDAAiD;AAU/C,gGAVO,8BAAe,OAUP;AATjB,qDAAqD;AAUnD,kGAVO,kCAAiB,OAUP;AATnB,+DAA8D;AAU5D,sGAVO,2CAAqB,OAUP;AAGV,QAAA,YAAY,GAAe;IACtC,8BAAe;IACf,kCAAiB;IACjB,kCAAiB;IACjB,iDAAwB;IACxB,2CAAqB;IACrB,wCAAoB;IACpB,wCAAoB;IACpB,6DAA8B;CAC/B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"risk-level-consistency.d.ts","sourceRoot":"","sources":["../../../src/linter/rules/risk-level-consistency.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,wBAAwB,EAAE,QAuBtC,CAAC"}
1
+ {"version":3,"file":"risk-level-consistency.d.ts","sourceRoot":"","sources":["../../../src/linter/rules/risk-level-consistency.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzD,eAAO,MAAM,wBAAwB,EAAE,QAqCtC,CAAC"}
@@ -3,10 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.riskLevelConsistencyRule = void 0;
4
4
  exports.riskLevelConsistencyRule = {
5
5
  id: 'risk-level-consistency',
6
- description: 'Risk level should be consistent with destructive operations',
6
+ description: 'Risk level should be consistent with destructive operations and external references',
7
7
  defaultSeverity: 'warning',
8
8
  run(context) {
9
- const { risk_level, destructive_operations } = context.frontmatter;
9
+ const { risk_level, destructive_operations, external_references, risk_factors } = context.frontmatter;
10
10
  const diagnostics = [];
11
11
  if (risk_level === 'low' &&
12
12
  Array.isArray(destructive_operations) &&
@@ -18,6 +18,16 @@ exports.riskLevelConsistencyRule = {
18
18
  field: 'risk_level',
19
19
  });
20
20
  }
21
+ if (Array.isArray(external_references) && external_references.length > 0) {
22
+ if (!Array.isArray(risk_factors) || !risk_factors.includes('network_access')) {
23
+ diagnostics.push({
24
+ ruleId: 'risk-level-consistency',
25
+ severity: 'warning',
26
+ message: 'external_references declared but risk_factors does not include "network_access"',
27
+ field: 'risk_factors',
28
+ });
29
+ }
30
+ }
21
31
  return diagnostics;
22
32
  },
23
33
  };
@@ -1 +1 @@
1
- {"version":3,"file":"risk-level-consistency.js","sourceRoot":"","sources":["../../../src/linter/rules/risk-level-consistency.ts"],"names":[],"mappings":";;;AAEa,QAAA,wBAAwB,GAAa;IAChD,EAAE,EAAE,wBAAwB;IAC5B,WAAW,EAAE,6DAA6D;IAC1E,eAAe,EAAE,SAAS;IAC1B,GAAG,CAAC,OAAO;QACT,MAAM,EAAE,UAAU,EAAE,sBAAsB,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;QACnE,MAAM,WAAW,GAAG,EAAE,CAAC;QAEvB,IACE,UAAU,KAAK,KAAK;YACpB,KAAK,CAAC,OAAO,CAAC,sBAAsB,CAAC;YACrC,sBAAsB,CAAC,MAAM,GAAG,CAAC,EACjC,CAAC;YACD,WAAW,CAAC,IAAI,CAAC;gBACf,MAAM,EAAE,wBAAwB;gBAChC,QAAQ,EAAE,SAAkB;gBAC5B,OAAO,EAAE,2BAA2B,sBAAsB,CAAC,MAAM,kEAAkE;gBACnI,KAAK,EAAE,YAAY;aACpB,CAAC,CAAC;QACL,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"risk-level-consistency.js","sourceRoot":"","sources":["../../../src/linter/rules/risk-level-consistency.ts"],"names":[],"mappings":";;;AAEa,QAAA,wBAAwB,GAAa;IAChD,EAAE,EAAE,wBAAwB;IAC5B,WAAW,EACT,qFAAqF;IACvF,eAAe,EAAE,SAAS;IAC1B,GAAG,CAAC,OAAO;QACT,MAAM,EAAE,UAAU,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,YAAY,EAAE,GAC7E,OAAO,CAAC,WAAW,CAAC;QACtB,MAAM,WAAW,GAAqB,EAAE,CAAC;QAEzC,IACE,UAAU,KAAK,KAAK;YACpB,KAAK,CAAC,OAAO,CAAC,sBAAsB,CAAC;YACrC,sBAAsB,CAAC,MAAM,GAAG,CAAC,EACjC,CAAC;YACD,WAAW,CAAC,IAAI,CAAC;gBACf,MAAM,EAAE,wBAAwB;gBAChC,QAAQ,EAAE,SAAS;gBACnB,OAAO,EAAE,2BAA2B,sBAAsB,CAAC,MAAM,kEAAkE;gBACnI,KAAK,EAAE,YAAY;aACpB,CAAC,CAAC;QACL,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAC,IAAI,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBAC7E,WAAW,CAAC,IAAI,CAAC;oBACf,MAAM,EAAE,wBAAwB;oBAChC,QAAQ,EAAE,SAAS;oBACnB,OAAO,EACL,iFAAiF;oBACnF,KAAK,EAAE,cAAc;iBACtB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tools-check-command.d.ts","sourceRoot":"","sources":["../../../src/linter/rules/tools-check-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAOzC,eAAO,MAAM,qBAAqB,EAAE,QA0BnC,CAAC"}
1
+ {"version":3,"file":"tools-check-command.d.ts","sourceRoot":"","sources":["../../../src/linter/rules/tools-check-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,qBAAqB,EAAE,QA0BnC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tools-check-command.js","sourceRoot":"","sources":["../../../src/linter/rules/tools-check-command.ts"],"names":[],"mappings":";;;AAOa,QAAA,qBAAqB,GAAa;IAC7C,EAAE,EAAE,qBAAqB;IACzB,WAAW,EAAE,oDAAoD;IACjE,eAAe,EAAE,SAAS;IAC1B,GAAG,CAAC,OAAO;QACT,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,cAA4C,CAAC;QAE/E,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChD,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,WAAW,GAAG,EAAE,CAAC;QAEvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;gBACxB,WAAW,CAAC,IAAI,CAAC;oBACf,MAAM,EAAE,qBAAqB;oBAC7B,QAAQ,EAAE,SAAkB;oBAC5B,OAAO,EAAE,SAAS,IAAI,CAAC,IAAI,+DAA+D;oBAC1F,KAAK,EAAE,gBAAgB;iBACxB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"tools-check-command.js","sourceRoot":"","sources":["../../../src/linter/rules/tools-check-command.ts"],"names":[],"mappings":";;;AAEa,QAAA,qBAAqB,GAAa;IAC7C,EAAE,EAAE,qBAAqB;IACzB,WAAW,EAAE,oDAAoD;IACjE,eAAe,EAAE,SAAS;IAC1B,GAAG,CAAC,OAAO;QACT,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,cAAc,CAAC;QAEjD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChD,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,WAAW,GAAG,EAAE,CAAC;QAEvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;gBACxB,WAAW,CAAC,IAAI,CAAC;oBACf,MAAM,EAAE,qBAAqB;oBAC7B,QAAQ,EAAE,SAAkB;oBAC5B,OAAO,EAAE,SAAS,IAAI,CAAC,IAAI,+DAA+D;oBAC1F,KAAK,EAAE,gBAAgB;iBACxB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;CACF,CAAC"}
package/dist/parser.d.ts CHANGED
@@ -1,10 +1,23 @@
1
1
  /**
2
- * Dossier parser - extracts frontmatter and body from dossier files
2
+ * Dossier parser - extracts frontmatter and body from dossier files.
3
+ *
4
+ * Supports two frontmatter formats:
5
+ * 1. ---dossier\n{JSON or YAML}\n--- (dossier-specific delimiter)
6
+ * 2. ---\n{YAML}\n--- (standard markdown frontmatter)
3
7
  */
4
8
  import type { DossierFrontmatter, ParsedDossier } from './types';
9
+ /** Required fields for a valid dossier frontmatter. */
10
+ export declare const REQUIRED_FIELDS: readonly ["dossier_schema_version", "title", "version"];
11
+ /** Recommended (but optional) fields. */
12
+ export declare const RECOMMENDED_FIELDS: readonly ["objective", "risk_level", "status"];
13
+ /** Valid values for the status field (Title Case, matching DossierStatus type and schema). */
14
+ export declare const VALID_STATUSES: readonly ["Draft", "Stable", "Deprecated", "Experimental"];
15
+ /** Valid values for the risk_level field. */
16
+ export declare const VALID_RISK_LEVELS: readonly ["low", "medium", "high", "critical"];
5
17
  /**
6
- * Parse dossier content into frontmatter and body
7
- * Format: ---dossier\n{JSON}\n---\n[body]
18
+ * Parse dossier content into frontmatter and body.
19
+ *
20
+ * Accepts both `---dossier` (JSON/YAML) and standard `---` (YAML) frontmatter.
8
21
  */
9
22
  export declare function parseDossierContent(content: string): ParsedDossier;
10
23
  /**
@@ -12,7 +25,10 @@ export declare function parseDossierContent(content: string): ParsedDossier;
12
25
  */
13
26
  export declare function parseDossierFile(filePath: string): ParsedDossier;
14
27
  /**
15
- * Validate required frontmatter fields
28
+ * Validate required frontmatter fields.
29
+ *
30
+ * Checks for required fields (dossier_schema_version, title, version),
31
+ * and validates enum values for status and risk_level.
16
32
  */
17
33
  export declare function validateFrontmatter(frontmatter: DossierFrontmatter): string[];
18
34
  //# sourceMappingURL=parser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAIjE;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAuBlE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAGhE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,kBAAkB,GAAG,MAAM,EAAE,CAmC7E"}
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAIjE,uDAAuD;AACvD,eAAO,MAAM,eAAe,yDAA0D,CAAC;AAEvF,yCAAyC;AACzC,eAAO,MAAM,kBAAkB,gDAAiD,CAAC;AAEjF,8FAA8F;AAC9F,eAAO,MAAM,cAAc,4DAA6D,CAAC;AAEzF,6CAA6C;AAC7C,eAAO,MAAM,iBAAiB,gDAAiD,CAAC;AAEhF;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CA2ClE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAGhE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,kBAAkB,GAAG,MAAM,EAAE,CAgC7E"}