@unrdf/diataxis-kit 26.4.2

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 (49) hide show
  1. package/README.md +425 -0
  2. package/bin/report.mjs +529 -0
  3. package/bin/run.mjs +114 -0
  4. package/bin/verify.mjs +356 -0
  5. package/capability-map.md +92 -0
  6. package/package.json +42 -0
  7. package/src/classify.mjs +584 -0
  8. package/src/diataxis-schema.mjs +425 -0
  9. package/src/evidence.mjs +268 -0
  10. package/src/hash.mjs +37 -0
  11. package/src/inventory.mjs +280 -0
  12. package/src/reference-extractor.mjs +324 -0
  13. package/src/scaffold.mjs +458 -0
  14. package/src/stable-json.mjs +113 -0
  15. package/src/verify-implementation.mjs +131 -0
  16. package/test/determinism.test.mjs +321 -0
  17. package/test/evidence.test.mjs +145 -0
  18. package/test/fixtures/scaffold-det1/explanation/explanation.md +35 -0
  19. package/test/fixtures/scaffold-det1/index.md +29 -0
  20. package/test/fixtures/scaffold-det1/reference/reference.md +34 -0
  21. package/test/fixtures/scaffold-det1/tutorials/tutorial-test-tutorial.md +37 -0
  22. package/test/fixtures/scaffold-det2/explanation/explanation.md +35 -0
  23. package/test/fixtures/scaffold-det2/index.md +29 -0
  24. package/test/fixtures/scaffold-det2/reference/reference.md +34 -0
  25. package/test/fixtures/scaffold-det2/tutorials/tutorial-test-tutorial.md +37 -0
  26. package/test/fixtures/scaffold-empty/explanation/explanation.md +35 -0
  27. package/test/fixtures/scaffold-empty/index.md +25 -0
  28. package/test/fixtures/scaffold-empty/reference/reference.md +34 -0
  29. package/test/fixtures/scaffold-escape/explanation/explanation.md +35 -0
  30. package/test/fixtures/scaffold-escape/index.md +29 -0
  31. package/test/fixtures/scaffold-escape/reference/reference.md +36 -0
  32. package/test/fixtures/scaffold-output/explanation/explanation.md +39 -0
  33. package/test/fixtures/scaffold-output/how-to/howto-configure-options.md +39 -0
  34. package/test/fixtures/scaffold-output/index.md +41 -0
  35. package/test/fixtures/scaffold-output/reference/reference.md +36 -0
  36. package/test/fixtures/scaffold-output/tutorials/tutorial-getting-started.md +41 -0
  37. package/test/fixtures/test-artifacts/ARTIFACTS/diataxis/test-pkg-1.inventory.json +115 -0
  38. package/test/fixtures/test-artifacts/ARTIFACTS/diataxis/test-pkg-2.inventory.json +93 -0
  39. package/test/fixtures/test-artifacts/ARTIFACTS/diataxis/test-pkg-3.inventory.json +97 -0
  40. package/test/fixtures/test-package/LICENSE +1 -0
  41. package/test/fixtures/test-package/README.md +15 -0
  42. package/test/fixtures/test-package/docs/guide.md +3 -0
  43. package/test/fixtures/test-package/examples/basic.mjs +3 -0
  44. package/test/fixtures/test-package/src/index.mjs +3 -0
  45. package/test/inventory.test.mjs +199 -0
  46. package/test/reference-extractor.test.mjs +187 -0
  47. package/test/report.test.mjs +503 -0
  48. package/test/scaffold.test.mjs +242 -0
  49. package/test/verify-gate.test.mjs +634 -0
@@ -0,0 +1,321 @@
1
+ /**
2
+ * @file Determinism tests for Diátaxis Kit
3
+ * @description Validates that DETERMINISTIC=1 produces identical output across runs
4
+ */
5
+
6
+ import { execFile } from 'node:child_process';
7
+ import { promisify } from 'node:util';
8
+ import { readFile, readdir, rm } from 'node:fs/promises';
9
+ import { join, resolve, dirname } from 'node:path';
10
+ import { createHash } from 'node:crypto';
11
+ import { existsSync } from 'node:fs';
12
+ import { fileURLToPath } from 'node:url';
13
+
14
+ const execFileAsync = promisify(execFile);
15
+ const __filename = fileURLToPath(import.meta.url);
16
+ const __dirname = dirname(__filename);
17
+ const packageRoot = resolve(__dirname, '..');
18
+
19
+ let passCount = 0;
20
+ let failCount = 0;
21
+
22
+ /**
23
+ * Test runner with timeout support
24
+ * @param {string} name - Test name
25
+ * @param {Function} fn - Async test function
26
+ * @param {number} [timeout=30000] - Timeout in milliseconds
27
+ */
28
+ async function test(name, fn, timeout = 30000) {
29
+ const timeoutPromise = new Promise((_, reject) => {
30
+ setTimeout(() => reject(new Error(`Test timeout after ${timeout}ms`)), timeout);
31
+ });
32
+
33
+ try {
34
+ await Promise.race([fn(), timeoutPromise]);
35
+ console.log(`✅ ${name}`);
36
+ passCount++;
37
+ } catch (err) {
38
+ console.log(`❌ ${name}: ${err.message}`);
39
+ if (err.stack && process.env.VERBOSE) {
40
+ console.log(err.stack);
41
+ }
42
+ failCount++;
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Hash a file's contents
48
+ * @param {string} filePath - Path to file
49
+ * @returns {Promise<string>} SHA256 hash
50
+ */
51
+ async function hashFile(filePath) {
52
+ const content = await readFile(filePath, 'utf8');
53
+ return createHash('sha256').update(content, 'utf8').digest('hex');
54
+ }
55
+
56
+ /**
57
+ * Recursively find all files in a directory
58
+ * @param {string} dir - Directory to search
59
+ * @param {string[]} results - Accumulator for results
60
+ * @returns {Promise<string[]>} Array of file paths
61
+ */
62
+ async function findAllFiles(dir, results = []) {
63
+ if (!existsSync(dir)) {
64
+ return results;
65
+ }
66
+
67
+ const entries = await readdir(dir, { withFileTypes: true });
68
+
69
+ for (const entry of entries) {
70
+ const fullPath = join(dir, entry.name);
71
+ if (entry.isDirectory()) {
72
+ await findAllFiles(fullPath, results);
73
+ } else if (entry.isFile()) {
74
+ results.push(fullPath);
75
+ }
76
+ }
77
+
78
+ return results;
79
+ }
80
+
81
+ /**
82
+ * Clean output directories
83
+ * @returns {Promise<void>}
84
+ */
85
+ async function cleanOutputs() {
86
+ const artifactsDir = join(packageRoot, 'ARTIFACTS');
87
+ const outDir = join(packageRoot, 'OUT');
88
+
89
+ if (existsSync(artifactsDir)) {
90
+ await rm(artifactsDir, { recursive: true, force: true });
91
+ }
92
+ if (existsSync(outDir)) {
93
+ await rm(outDir, { recursive: true, force: true });
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Run bin/run.mjs with DETERMINISTIC=1
99
+ * @returns {Promise<void>}
100
+ */
101
+ async function runPipeline() {
102
+ const binPath = join(packageRoot, 'bin', 'run.mjs');
103
+
104
+ await execFileAsync('node', [binPath], {
105
+ cwd: packageRoot,
106
+ env: {
107
+ ...process.env,
108
+ DETERMINISTIC: '1'
109
+ }
110
+ });
111
+ }
112
+
113
+ /**
114
+ * Test: Determinism - running twice produces identical hashes
115
+ */
116
+ async function testDeterminism() {
117
+ // Run 1
118
+ await cleanOutputs();
119
+ await runPipeline();
120
+
121
+ const artifactsDir = join(packageRoot, 'ARTIFACTS');
122
+ const outDir = join(packageRoot, 'OUT');
123
+
124
+ const files1 = await findAllFiles(artifactsDir);
125
+ const hashes1 = new Map();
126
+
127
+ for (const file of files1) {
128
+ const hash = await hashFile(file);
129
+ const relativePath = file.replace(artifactsDir + '/', '');
130
+ hashes1.set(relativePath, hash);
131
+ }
132
+
133
+ // Sleep 100ms
134
+ await new Promise(resolve => setTimeout(resolve, 100));
135
+
136
+ // Run 2
137
+ await cleanOutputs();
138
+ await runPipeline();
139
+
140
+ const files2 = await findAllFiles(artifactsDir);
141
+ const hashes2 = new Map();
142
+
143
+ for (const file of files2) {
144
+ const hash = await hashFile(file);
145
+ const relativePath = file.replace(artifactsDir + '/', '');
146
+ hashes2.set(relativePath, hash);
147
+ }
148
+
149
+ // Compare file counts
150
+ if (files1.length !== files2.length) {
151
+ throw new Error(`File count mismatch: ${files1.length} vs ${files2.length}`);
152
+ }
153
+
154
+ // Compare hashes
155
+ const mismatches = [];
156
+ for (const [path, hash1] of hashes1) {
157
+ const hash2 = hashes2.get(path);
158
+ if (!hash2) {
159
+ mismatches.push(`Missing in run 2: ${path}`);
160
+ } else if (hash1 !== hash2) {
161
+ mismatches.push(`Hash mismatch: ${path}\n Run 1: ${hash1}\n Run 2: ${hash2}`);
162
+ }
163
+ }
164
+
165
+ if (mismatches.length > 0) {
166
+ throw new Error(`Determinism failed:\n${mismatches.join('\n')}`);
167
+ }
168
+
169
+ console.log(` Verified ${hashes1.size} files identical across runs`);
170
+ }
171
+
172
+ /**
173
+ * Test: Consistent timestamps when DETERMINISTIC=1
174
+ */
175
+ async function testConsistentTimestamps() {
176
+ await cleanOutputs();
177
+ await runPipeline();
178
+
179
+ const artifactsDir = join(packageRoot, 'ARTIFACTS', 'diataxis');
180
+
181
+ // Check inventory.json
182
+ const inventoryPath = join(artifactsDir, 'inventory.json');
183
+ const inventory = JSON.parse(await readFile(inventoryPath, 'utf8'));
184
+
185
+ if (inventory.generatedAt !== '2000-01-01T00:00:00.000Z') {
186
+ throw new Error(`Inventory timestamp not fixed: ${inventory.generatedAt}`);
187
+ }
188
+
189
+ // Check 5 random diataxis.json files
190
+ const packageDirs = await readdir(artifactsDir, { withFileTypes: true });
191
+ const validDirs = packageDirs.filter(d => d.isDirectory()).slice(0, 5);
192
+
193
+ for (const dir of validDirs) {
194
+ const diataxisPath = join(artifactsDir, dir.name, 'diataxis.json');
195
+ if (existsSync(diataxisPath)) {
196
+ const diataxis = JSON.parse(await readFile(diataxisPath, 'utf8'));
197
+ if (diataxis.generatedAt !== '2000-01-01T00:00:00.000Z') {
198
+ throw new Error(`${dir.name} timestamp not fixed: ${diataxis.generatedAt}`);
199
+ }
200
+ }
201
+ }
202
+
203
+ console.log(` Verified timestamps fixed at 2000-01-01T00:00:00.000Z`);
204
+ }
205
+
206
+ /**
207
+ * Test: Stable ordering in output files
208
+ */
209
+ async function testStableOrdering() {
210
+ await cleanOutputs();
211
+ await runPipeline();
212
+
213
+ const artifactsDir = join(packageRoot, 'ARTIFACTS', 'diataxis');
214
+ const inventoryPath = join(artifactsDir, 'inventory.json');
215
+ const inventory = JSON.parse(await readFile(inventoryPath, 'utf8'));
216
+
217
+ // Verify packages are sorted by name
218
+ const packageNames = inventory.packages.map(p => p.name);
219
+ const sortedNames = [...packageNames].sort((a, b) => a.localeCompare(b));
220
+
221
+ for (let i = 0; i < packageNames.length; i++) {
222
+ if (packageNames[i] !== sortedNames[i]) {
223
+ throw new Error(`Packages not sorted: ${packageNames[i]} at index ${i}, expected ${sortedNames[i]}`);
224
+ }
225
+ }
226
+
227
+ // Check one diataxis.json for sorted tutorials/howtos
228
+ const firstPackageDir = inventory.packages[0].name;
229
+ const diataxisPath = join(artifactsDir, firstPackageDir, 'diataxis.json');
230
+
231
+ if (existsSync(diataxisPath)) {
232
+ const diataxis = JSON.parse(await readFile(diataxisPath, 'utf8'));
233
+
234
+ // Verify tutorials sorted by id
235
+ if (diataxis.tutorials && diataxis.tutorials.length > 1) {
236
+ const tutorialIds = diataxis.tutorials.map(t => t.id);
237
+ const sortedIds = [...tutorialIds].sort((a, b) => a.localeCompare(b));
238
+ for (let i = 0; i < tutorialIds.length; i++) {
239
+ if (tutorialIds[i] !== sortedIds[i]) {
240
+ throw new Error(`Tutorials not sorted in ${firstPackageDir}`);
241
+ }
242
+ }
243
+ }
244
+
245
+ // Verify howtos sorted by id
246
+ if (diataxis.howtos && diataxis.howtos.length > 1) {
247
+ const howtoIds = diataxis.howtos.map(h => h.id);
248
+ const sortedIds = [...howtoIds].sort((a, b) => a.localeCompare(b));
249
+ for (let i = 0; i < howtoIds.length; i++) {
250
+ if (howtoIds[i] !== sortedIds[i]) {
251
+ throw new Error(`How-tos not sorted in ${firstPackageDir}: ${howtoIds[i]} at index ${i}, expected ${sortedIds[i]}`);
252
+ }
253
+ }
254
+ }
255
+ }
256
+
257
+ console.log(` Verified stable ordering for ${packageNames.length} packages`);
258
+ }
259
+
260
+ /**
261
+ * Test: Proof hashes in generated markdown files
262
+ */
263
+ async function testProofHashes() {
264
+ await cleanOutputs();
265
+ await runPipeline();
266
+
267
+ const outDir = join(packageRoot, 'OUT');
268
+ const allMarkdownFiles = await findAllFiles(outDir);
269
+ const markdownFiles = allMarkdownFiles.filter(f => f.endsWith('.md'));
270
+
271
+ if (markdownFiles.length === 0) {
272
+ throw new Error('No markdown files generated');
273
+ }
274
+
275
+ let proofCount = 0;
276
+ const invalidProofs = [];
277
+
278
+ for (const mdFile of markdownFiles) {
279
+ const content = await readFile(mdFile, 'utf8');
280
+
281
+ // Parse frontmatter for proof field
282
+ const frontmatterMatch = content.match(/^---\n([\s\S]+?)\n---/);
283
+ if (!frontmatterMatch) {
284
+ continue; // Skip files without frontmatter
285
+ }
286
+
287
+ const frontmatter = frontmatterMatch[1];
288
+ const proofMatch = frontmatter.match(/^proof:\s*([a-f0-9]{64})$/m);
289
+
290
+ if (proofMatch) {
291
+ const proof = proofMatch[1];
292
+ proofCount++;
293
+
294
+ // Verify it's a valid 64-character hex string (SHA256)
295
+ if (!/^[a-f0-9]{64}$/.test(proof)) {
296
+ invalidProofs.push(`${mdFile}: invalid proof format "${proof}"`);
297
+ }
298
+ }
299
+ }
300
+
301
+ if (invalidProofs.length > 0) {
302
+ throw new Error(`Invalid proofs:\n${invalidProofs.join('\n')}`);
303
+ }
304
+
305
+ console.log(` Verified ${proofCount} proof hashes in ${markdownFiles.length} markdown files`);
306
+ }
307
+
308
+ // Run all tests
309
+ async function runTests() {
310
+ console.log('Running determinism tests...\n');
311
+
312
+ await test('determinism: inventory and artifacts hashes match', testDeterminism, 60000);
313
+ await test('determinism: timestamps fixed at 2000-01-01', testConsistentTimestamps, 30000);
314
+ await test('determinism: stable ordering', testStableOrdering, 30000);
315
+ await test('determinism: proof hashes', testProofHashes, 30000);
316
+
317
+ console.log(`\n${passCount}/${passCount + failCount} tests passed`);
318
+ process.exit(failCount > 0 ? 1 : 0);
319
+ }
320
+
321
+ runTests();
@@ -0,0 +1,145 @@
1
+ /**
2
+ * @file evidence.test.mjs
3
+ * @description Tests for evidence collection module
4
+ */
5
+
6
+ import { describe, it } from 'node:test';
7
+ import assert from 'node:assert/strict';
8
+ import { collectEvidence, hashEvidence } from '../src/evidence.mjs';
9
+ import { fileURLToPath } from 'node:url';
10
+ import { dirname, join } from 'node:path';
11
+
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = dirname(__filename);
14
+ const fixturesDir = join(__dirname, 'fixtures', 'test-package');
15
+
16
+ describe('evidence.mjs', () => {
17
+ describe('collectEvidence', () => {
18
+ it('should return valid EvidenceSnapshot structure', async () => {
19
+ const packageJson = {
20
+ name: 'test-package',
21
+ version: '1.0.0',
22
+ keywords: ['test', 'example'],
23
+ bin: { 'test-cli': './bin/cli.js' },
24
+ exports: { '.': './src/index.mjs' }
25
+ };
26
+
27
+ const evidence = await collectEvidence(fixturesDir, packageJson);
28
+
29
+ // Verify structure
30
+ assert.ok(evidence);
31
+ assert.ok(typeof evidence.readmeContent === 'string' || evidence.readmeContent === null);
32
+ assert.ok(Array.isArray(evidence.readmeHeadings));
33
+ assert.ok(Array.isArray(evidence.examplesFiles));
34
+ assert.ok(typeof evidence.examplesSnippets === 'object');
35
+ assert.ok(Array.isArray(evidence.docsFiles));
36
+ assert.ok(typeof evidence.docsSnippets === 'object');
37
+ assert.ok(Array.isArray(evidence.srcFiles));
38
+ assert.ok(typeof evidence.testFileCount === 'number');
39
+ assert.ok(typeof evidence.binEntries === 'object');
40
+ assert.ok(typeof evidence.exportSurface === 'object');
41
+ assert.ok(Array.isArray(evidence.keywords));
42
+ assert.ok(typeof evidence.hasLicense === 'boolean');
43
+ assert.ok(typeof evidence.hasTsConfig === 'boolean');
44
+ assert.ok(typeof evidence.fingerprint === 'string');
45
+ assert.equal(evidence.fingerprint.length, 64); // SHA256 hex = 64 chars
46
+ });
47
+
48
+ it('should extract package.json fields correctly', async () => {
49
+ const packageJson = {
50
+ keywords: ['rdf', 'semantic'],
51
+ bin: { 'my-cli': './bin/cli.js' },
52
+ exports: { '.': './index.js' }
53
+ };
54
+
55
+ const evidence = await collectEvidence(fixturesDir, packageJson);
56
+
57
+ assert.deepEqual(evidence.keywords, ['rdf', 'semantic']);
58
+ assert.deepEqual(evidence.binEntries, { 'my-cli': './bin/cli.js' });
59
+ assert.deepEqual(evidence.exportSurface, { '.': './index.js' });
60
+ });
61
+
62
+ it('should handle missing directories gracefully', async () => {
63
+ const packageJson = { name: 'test' };
64
+ const evidence = await collectEvidence('/tmp/nonexistent-package-dir', packageJson);
65
+
66
+ assert.equal(evidence.readmeContent, null);
67
+ assert.deepEqual(evidence.readmeHeadings, []);
68
+ assert.deepEqual(evidence.examplesFiles, []);
69
+ assert.deepEqual(evidence.docsFiles, []);
70
+ assert.deepEqual(evidence.srcFiles, []);
71
+ assert.equal(evidence.testFileCount, 0);
72
+ });
73
+
74
+ it('should throw on invalid package.json', async () => {
75
+ await assert.rejects(
76
+ async () => await collectEvidence('/tmp', null),
77
+ { message: /Invalid package.json/ }
78
+ );
79
+ });
80
+
81
+ it('should compute deterministic fingerprint', async () => {
82
+ const packageJson = { name: 'test', keywords: ['a', 'b'] };
83
+ const evidence1 = await collectEvidence(fixturesDir, packageJson);
84
+ const evidence2 = await collectEvidence(fixturesDir, packageJson);
85
+
86
+ assert.equal(evidence1.fingerprint, evidence2.fingerprint);
87
+ });
88
+ });
89
+
90
+ describe('hashEvidence', () => {
91
+ it('should produce deterministic hash', () => {
92
+ const evidence = {
93
+ readmeContent: 'test',
94
+ readmeHeadings: ['Heading 1'],
95
+ examplesFiles: ['example.js'],
96
+ examplesSnippets: { 'example.js': 'code' },
97
+ docsFiles: ['doc.md'],
98
+ docsSnippets: { 'doc.md': 'docs' },
99
+ srcFiles: ['index.js'],
100
+ testFileCount: 5,
101
+ binEntries: {},
102
+ exportSurface: {},
103
+ keywords: ['test'],
104
+ hasLicense: true,
105
+ hasTsConfig: false,
106
+ fingerprint: 'abc123'
107
+ };
108
+
109
+ const hash1 = hashEvidence(evidence);
110
+ const hash2 = hashEvidence(evidence);
111
+
112
+ assert.equal(hash1, hash2);
113
+ assert.equal(hash1.length, 64); // SHA256 hex
114
+ });
115
+
116
+ it('should produce different hashes for different evidence', () => {
117
+ const evidence1 = {
118
+ readmeContent: 'test1',
119
+ readmeHeadings: [],
120
+ examplesFiles: [],
121
+ examplesSnippets: {},
122
+ docsFiles: [],
123
+ docsSnippets: {},
124
+ srcFiles: [],
125
+ testFileCount: 0,
126
+ binEntries: {},
127
+ exportSurface: {},
128
+ keywords: [],
129
+ hasLicense: false,
130
+ hasTsConfig: false,
131
+ fingerprint: 'abc'
132
+ };
133
+
134
+ const evidence2 = {
135
+ ...evidence1,
136
+ readmeContent: 'test2'
137
+ };
138
+
139
+ const hash1 = hashEvidence(evidence1);
140
+ const hash2 = hashEvidence(evidence2);
141
+
142
+ assert.notEqual(hash1, hash2);
143
+ });
144
+ });
145
+ });
@@ -0,0 +1,35 @@
1
+ ---
2
+ title: "test-deterministic Explanation"
3
+ type: "explanation"
4
+ packageName: "test-deterministic"
5
+ version: "1.0.0"
6
+ generatedAt: "2000-01-01T00:00:00.000Z"
7
+ confidenceScore: 0
8
+ proof: "3f8072cee79349fae3971f82f5c1d412e5a32fbe09ed9860a00bdc84d583b953"
9
+ ---
10
+
11
+ ## Concepts
12
+
13
+ - (No concepts documented)
14
+
15
+ ## Architecture
16
+
17
+ (No architecture documented)
18
+
19
+ ## Tradeoffs
20
+
21
+ - (No tradeoffs documented)
22
+
23
+ ## Proof
24
+
25
+ This file was generated from the following evidence sources:
26
+
27
+ - (No sources recorded)
28
+
29
+ ```json
30
+ {
31
+ "fingerprintInput": "|test-deterministic Explanation|0",
32
+ "hash": "3f8072cee79349fae3971f82f5c1d412e5a32fbe09ed9860a00bdc84d583b953",
33
+ "sources": []
34
+ }
35
+ ```
@@ -0,0 +1,29 @@
1
+ ---
2
+ title: "test-deterministic Documentation"
3
+ packageName: "test-deterministic"
4
+ version: "1.0.0"
5
+ generatedAt: "2000-01-01T00:00:00.000Z"
6
+ ---
7
+
8
+ # test-deterministic Documentation
9
+
10
+ Generated documentation using the Diátaxis framework.
11
+
12
+ ## Quick Stats
13
+
14
+ - **Tutorials**: 1
15
+ - **How-To Guides**: 0
16
+ - **Reference**: Not available
17
+ - **Explanation**: Not available
18
+
19
+ ## Documentation Sections
20
+
21
+ ### Tutorials
22
+
23
+ - [Test Tutorial](tutorials/tutorial-test-tutorial.md)
24
+
25
+
26
+
27
+ ---
28
+
29
+ *Generated at 2000-01-01T00:00:00.000Z*
@@ -0,0 +1,34 @@
1
+ ---
2
+ title: "test-deterministic Reference"
3
+ type: "reference"
4
+ packageName: "test-deterministic"
5
+ version: "1.0.0"
6
+ generatedAt: "2000-01-01T00:00:00.000Z"
7
+ confidenceScore: 0
8
+ proof: "1db83d70e898a847f11d662317d65d4a5326b670fe1cc181774ba086078fd6a7"
9
+ ---
10
+
11
+ ## Overview
12
+
13
+ This reference documentation provides technical details for test-deterministic.
14
+
15
+ ## API Reference
16
+
17
+ | Name | Type | Description |
18
+ |------|------|-------------|
19
+ | - | - | (No items documented) |
20
+
21
+
22
+ ## Proof
23
+
24
+ This file was generated from the following evidence sources:
25
+
26
+ - (No sources recorded)
27
+
28
+ ```json
29
+ {
30
+ "fingerprintInput": "|test-deterministic Reference|0",
31
+ "hash": "1db83d70e898a847f11d662317d65d4a5326b670fe1cc181774ba086078fd6a7",
32
+ "sources": []
33
+ }
34
+ ```
@@ -0,0 +1,37 @@
1
+ ---
2
+ title: "Test Tutorial"
3
+ type: "tutorial"
4
+ packageName: "test-deterministic"
5
+ version: "1.0.0"
6
+ generatedAt: "2000-01-01T00:00:00.000Z"
7
+ confidenceScore: 0.9
8
+ proof: "fa5ec3edd8fd24ada2fbe509ea3369703fea30ef1c5d0707430893d876099862"
9
+ ---
10
+
11
+ ## Overview
12
+
13
+ Test
14
+
15
+ ## Prerequisites
16
+
17
+ - None
18
+
19
+ ## Steps
20
+
21
+ 1. Step 1
22
+
23
+ ## Proof
24
+
25
+ This file was generated from the following evidence sources:
26
+
27
+ - test.md
28
+
29
+ ```json
30
+ {
31
+ "fingerprintInput": "test.md|Test Tutorial|0.9",
32
+ "hash": "fa5ec3edd8fd24ada2fbe509ea3369703fea30ef1c5d0707430893d876099862",
33
+ "sources": [
34
+ "test.md"
35
+ ]
36
+ }
37
+ ```
@@ -0,0 +1,35 @@
1
+ ---
2
+ title: "test-deterministic Explanation"
3
+ type: "explanation"
4
+ packageName: "test-deterministic"
5
+ version: "1.0.0"
6
+ generatedAt: "2000-01-01T00:00:00.000Z"
7
+ confidenceScore: 0
8
+ proof: "3f8072cee79349fae3971f82f5c1d412e5a32fbe09ed9860a00bdc84d583b953"
9
+ ---
10
+
11
+ ## Concepts
12
+
13
+ - (No concepts documented)
14
+
15
+ ## Architecture
16
+
17
+ (No architecture documented)
18
+
19
+ ## Tradeoffs
20
+
21
+ - (No tradeoffs documented)
22
+
23
+ ## Proof
24
+
25
+ This file was generated from the following evidence sources:
26
+
27
+ - (No sources recorded)
28
+
29
+ ```json
30
+ {
31
+ "fingerprintInput": "|test-deterministic Explanation|0",
32
+ "hash": "3f8072cee79349fae3971f82f5c1d412e5a32fbe09ed9860a00bdc84d583b953",
33
+ "sources": []
34
+ }
35
+ ```
@@ -0,0 +1,29 @@
1
+ ---
2
+ title: "test-deterministic Documentation"
3
+ packageName: "test-deterministic"
4
+ version: "1.0.0"
5
+ generatedAt: "2000-01-01T00:00:00.000Z"
6
+ ---
7
+
8
+ # test-deterministic Documentation
9
+
10
+ Generated documentation using the Diátaxis framework.
11
+
12
+ ## Quick Stats
13
+
14
+ - **Tutorials**: 1
15
+ - **How-To Guides**: 0
16
+ - **Reference**: Not available
17
+ - **Explanation**: Not available
18
+
19
+ ## Documentation Sections
20
+
21
+ ### Tutorials
22
+
23
+ - [Test Tutorial](tutorials/tutorial-test-tutorial.md)
24
+
25
+
26
+
27
+ ---
28
+
29
+ *Generated at 2000-01-01T00:00:00.000Z*
@@ -0,0 +1,34 @@
1
+ ---
2
+ title: "test-deterministic Reference"
3
+ type: "reference"
4
+ packageName: "test-deterministic"
5
+ version: "1.0.0"
6
+ generatedAt: "2000-01-01T00:00:00.000Z"
7
+ confidenceScore: 0
8
+ proof: "1db83d70e898a847f11d662317d65d4a5326b670fe1cc181774ba086078fd6a7"
9
+ ---
10
+
11
+ ## Overview
12
+
13
+ This reference documentation provides technical details for test-deterministic.
14
+
15
+ ## API Reference
16
+
17
+ | Name | Type | Description |
18
+ |------|------|-------------|
19
+ | - | - | (No items documented) |
20
+
21
+
22
+ ## Proof
23
+
24
+ This file was generated from the following evidence sources:
25
+
26
+ - (No sources recorded)
27
+
28
+ ```json
29
+ {
30
+ "fingerprintInput": "|test-deterministic Reference|0",
31
+ "hash": "1db83d70e898a847f11d662317d65d4a5326b670fe1cc181774ba086078fd6a7",
32
+ "sources": []
33
+ }
34
+ ```