@design-intelligence/ghost 0.20.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 (269) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +75 -0
  3. package/dist/bin.d.ts +3 -0
  4. package/dist/bin.d.ts.map +1 -0
  5. package/dist/bin.js +19 -0
  6. package/dist/bin.js.map +1 -0
  7. package/dist/cli.d.ts +4 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +29 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/commands/checks-command.d.ts +9 -0
  12. package/dist/commands/checks-command.d.ts.map +1 -0
  13. package/dist/commands/checks-command.js +45 -0
  14. package/dist/commands/checks-command.js.map +1 -0
  15. package/dist/commands/command-discovery.d.ts +57 -0
  16. package/dist/commands/command-discovery.d.ts.map +1 -0
  17. package/dist/commands/command-discovery.js +220 -0
  18. package/dist/commands/command-discovery.js.map +1 -0
  19. package/dist/commands/errors.d.ts +7 -0
  20. package/dist/commands/errors.d.ts.map +1 -0
  21. package/dist/commands/errors.js +19 -0
  22. package/dist/commands/errors.js.map +1 -0
  23. package/dist/commands/export-command.d.ts +3 -0
  24. package/dist/commands/export-command.d.ts.map +1 -0
  25. package/dist/commands/export-command.js +157 -0
  26. package/dist/commands/export-command.js.map +1 -0
  27. package/dist/commands/fingerprint-commands.d.ts +10 -0
  28. package/dist/commands/fingerprint-commands.d.ts.map +1 -0
  29. package/dist/commands/fingerprint-commands.js +74 -0
  30. package/dist/commands/fingerprint-commands.js.map +1 -0
  31. package/dist/commands/gather-command.d.ts +3 -0
  32. package/dist/commands/gather-command.d.ts.map +1 -0
  33. package/dist/commands/gather-command.js +152 -0
  34. package/dist/commands/gather-command.js.map +1 -0
  35. package/dist/commands/init-command.d.ts +3 -0
  36. package/dist/commands/init-command.d.ts.map +1 -0
  37. package/dist/commands/init-command.js +79 -0
  38. package/dist/commands/init-command.js.map +1 -0
  39. package/dist/commands/manifest-command.d.ts +9 -0
  40. package/dist/commands/manifest-command.d.ts.map +1 -0
  41. package/dist/commands/manifest-command.js +33 -0
  42. package/dist/commands/manifest-command.js.map +1 -0
  43. package/dist/commands/pull-command.d.ts +3 -0
  44. package/dist/commands/pull-command.d.ts.map +1 -0
  45. package/dist/commands/pull-command.js +224 -0
  46. package/dist/commands/pull-command.js.map +1 -0
  47. package/dist/commands/pulse-command.d.ts +3 -0
  48. package/dist/commands/pulse-command.d.ts.map +1 -0
  49. package/dist/commands/pulse-command.js +257 -0
  50. package/dist/commands/pulse-command.js.map +1 -0
  51. package/dist/commands/review-command.d.ts +3 -0
  52. package/dist/commands/review-command.d.ts.map +1 -0
  53. package/dist/commands/review-command.js +77 -0
  54. package/dist/commands/review-command.js.map +1 -0
  55. package/dist/commands/skill-command.d.ts +3 -0
  56. package/dist/commands/skill-command.d.ts.map +1 -0
  57. package/dist/commands/skill-command.js +96 -0
  58. package/dist/commands/skill-command.js.map +1 -0
  59. package/dist/fingerprint.d.ts +5 -0
  60. package/dist/fingerprint.d.ts.map +1 -0
  61. package/dist/fingerprint.js +3 -0
  62. package/dist/fingerprint.js.map +1 -0
  63. package/dist/ghost-core/catalog/assemble.d.ts +30 -0
  64. package/dist/ghost-core/catalog/assemble.d.ts.map +1 -0
  65. package/dist/ghost-core/catalog/assemble.js +38 -0
  66. package/dist/ghost-core/catalog/assemble.js.map +1 -0
  67. package/dist/ghost-core/catalog/closest.d.ts +16 -0
  68. package/dist/ghost-core/catalog/closest.d.ts.map +1 -0
  69. package/dist/ghost-core/catalog/closest.js +63 -0
  70. package/dist/ghost-core/catalog/closest.js.map +1 -0
  71. package/dist/ghost-core/catalog/index.d.ts +10 -0
  72. package/dist/ghost-core/catalog/index.d.ts.map +1 -0
  73. package/dist/ghost-core/catalog/index.js +9 -0
  74. package/dist/ghost-core/catalog/index.js.map +1 -0
  75. package/dist/ghost-core/catalog/menu.d.ts +36 -0
  76. package/dist/ghost-core/catalog/menu.d.ts.map +1 -0
  77. package/dist/ghost-core/catalog/menu.js +27 -0
  78. package/dist/ghost-core/catalog/menu.js.map +1 -0
  79. package/dist/ghost-core/catalog/types.d.ts +37 -0
  80. package/dist/ghost-core/catalog/types.d.ts.map +1 -0
  81. package/dist/ghost-core/catalog/types.js +2 -0
  82. package/dist/ghost-core/catalog/types.js.map +1 -0
  83. package/dist/ghost-core/check/index.d.ts +12 -0
  84. package/dist/ghost-core/check/index.d.ts.map +1 -0
  85. package/dist/ghost-core/check/index.js +12 -0
  86. package/dist/ghost-core/check/index.js.map +1 -0
  87. package/dist/ghost-core/check/lint.d.ts +9 -0
  88. package/dist/ghost-core/check/lint.d.ts.map +1 -0
  89. package/dist/ghost-core/check/lint.js +119 -0
  90. package/dist/ghost-core/check/lint.js.map +1 -0
  91. package/dist/ghost-core/check/load.d.ts +7 -0
  92. package/dist/ghost-core/check/load.d.ts.map +1 -0
  93. package/dist/ghost-core/check/load.js +44 -0
  94. package/dist/ghost-core/check/load.js.map +1 -0
  95. package/dist/ghost-core/check/parse.d.ts +12 -0
  96. package/dist/ghost-core/check/parse.d.ts.map +1 -0
  97. package/dist/ghost-core/check/parse.js +13 -0
  98. package/dist/ghost-core/check/parse.js.map +1 -0
  99. package/dist/ghost-core/check/source-ref.d.ts +27 -0
  100. package/dist/ghost-core/check/source-ref.d.ts.map +1 -0
  101. package/dist/ghost-core/check/source-ref.js +58 -0
  102. package/dist/ghost-core/check/source-ref.js.map +1 -0
  103. package/dist/ghost-core/check/types.d.ts +48 -0
  104. package/dist/ghost-core/check/types.d.ts.map +1 -0
  105. package/dist/ghost-core/check/types.js +4 -0
  106. package/dist/ghost-core/check/types.js.map +1 -0
  107. package/dist/ghost-core/errors.d.ts +30 -0
  108. package/dist/ghost-core/errors.d.ts.map +1 -0
  109. package/dist/ghost-core/errors.js +33 -0
  110. package/dist/ghost-core/errors.js.map +1 -0
  111. package/dist/ghost-core/glob.d.ts +5 -0
  112. package/dist/ghost-core/glob.d.ts.map +1 -0
  113. package/dist/ghost-core/glob.js +68 -0
  114. package/dist/ghost-core/glob.js.map +1 -0
  115. package/dist/ghost-core/glossary.d.ts +38 -0
  116. package/dist/ghost-core/glossary.d.ts.map +1 -0
  117. package/dist/ghost-core/glossary.js +76 -0
  118. package/dist/ghost-core/glossary.js.map +1 -0
  119. package/dist/ghost-core/index.d.ts +13 -0
  120. package/dist/ghost-core/index.d.ts.map +1 -0
  121. package/dist/ghost-core/index.js +19 -0
  122. package/dist/ghost-core/index.js.map +1 -0
  123. package/dist/ghost-core/markdown.d.ts +15 -0
  124. package/dist/ghost-core/markdown.d.ts.map +1 -0
  125. package/dist/ghost-core/markdown.js +30 -0
  126. package/dist/ghost-core/markdown.js.map +1 -0
  127. package/dist/ghost-core/material-transport.d.ts +43 -0
  128. package/dist/ghost-core/material-transport.d.ts.map +1 -0
  129. package/dist/ghost-core/material-transport.js +231 -0
  130. package/dist/ghost-core/material-transport.js.map +1 -0
  131. package/dist/ghost-core/materials.d.ts +14 -0
  132. package/dist/ghost-core/materials.d.ts.map +1 -0
  133. package/dist/ghost-core/materials.js +52 -0
  134. package/dist/ghost-core/materials.js.map +1 -0
  135. package/dist/ghost-core/node/index.d.ts +11 -0
  136. package/dist/ghost-core/node/index.d.ts.map +1 -0
  137. package/dist/ghost-core/node/index.js +11 -0
  138. package/dist/ghost-core/node/index.js.map +1 -0
  139. package/dist/ghost-core/node/parse.d.ts +16 -0
  140. package/dist/ghost-core/node/parse.d.ts.map +1 -0
  141. package/dist/ghost-core/node/parse.js +55 -0
  142. package/dist/ghost-core/node/parse.js.map +1 -0
  143. package/dist/ghost-core/node/schema.d.ts +17 -0
  144. package/dist/ghost-core/node/schema.d.ts.map +1 -0
  145. package/dist/ghost-core/node/schema.js +49 -0
  146. package/dist/ghost-core/node/schema.js.map +1 -0
  147. package/dist/ghost-core/node/serialize.d.ts +11 -0
  148. package/dist/ghost-core/node/serialize.d.ts.map +1 -0
  149. package/dist/ghost-core/node/serialize.js +21 -0
  150. package/dist/ghost-core/node/serialize.js.map +1 -0
  151. package/dist/ghost-core/node/steering.d.ts +18 -0
  152. package/dist/ghost-core/node/steering.d.ts.map +1 -0
  153. package/dist/ghost-core/node/steering.js +65 -0
  154. package/dist/ghost-core/node/steering.js.map +1 -0
  155. package/dist/ghost-core/node/types.d.ts +42 -0
  156. package/dist/ghost-core/node/types.d.ts.map +1 -0
  157. package/dist/ghost-core/node/types.js +2 -0
  158. package/dist/ghost-core/node/types.js.map +1 -0
  159. package/dist/ghost-core/package-manifest.d.ts +12 -0
  160. package/dist/ghost-core/package-manifest.d.ts.map +1 -0
  161. package/dist/ghost-core/package-manifest.js +14 -0
  162. package/dist/ghost-core/package-manifest.js.map +1 -0
  163. package/dist/ghost-core/skill-bundle-loader.d.ts +28 -0
  164. package/dist/ghost-core/skill-bundle-loader.d.ts.map +1 -0
  165. package/dist/ghost-core/skill-bundle-loader.js +51 -0
  166. package/dist/ghost-core/skill-bundle-loader.js.map +1 -0
  167. package/dist/index.d.ts +5 -0
  168. package/dist/index.d.ts.map +1 -0
  169. package/dist/index.js +5 -0
  170. package/dist/index.js.map +1 -0
  171. package/dist/internal/fs.d.ts +4 -0
  172. package/dist/internal/fs.d.ts.map +1 -0
  173. package/dist/internal/fs.js +24 -0
  174. package/dist/internal/fs.js.map +1 -0
  175. package/dist/observability-events.d.ts +27 -0
  176. package/dist/observability-events.d.ts.map +1 -0
  177. package/dist/observability-events.js +56 -0
  178. package/dist/observability-events.js.map +1 -0
  179. package/dist/package-version.d.ts +3 -0
  180. package/dist/package-version.d.ts.map +1 -0
  181. package/dist/package-version.js +10 -0
  182. package/dist/package-version.js.map +1 -0
  183. package/dist/review/baseline.d.ts +11 -0
  184. package/dist/review/baseline.d.ts.map +1 -0
  185. package/dist/review/baseline.js +35 -0
  186. package/dist/review/baseline.js.map +1 -0
  187. package/dist/review/diff.d.ts +7 -0
  188. package/dist/review/diff.d.ts.map +1 -0
  189. package/dist/review/diff.js +41 -0
  190. package/dist/review/diff.js.map +1 -0
  191. package/dist/review/glob.d.ts +2 -0
  192. package/dist/review/glob.d.ts.map +1 -0
  193. package/dist/review/glob.js +2 -0
  194. package/dist/review/glob.js.map +1 -0
  195. package/dist/review/probes.d.ts +13 -0
  196. package/dist/review/probes.d.ts.map +1 -0
  197. package/dist/review/probes.js +45 -0
  198. package/dist/review/probes.js.map +1 -0
  199. package/dist/review/resolve.d.ts +29 -0
  200. package/dist/review/resolve.d.ts.map +1 -0
  201. package/dist/review/resolve.js +87 -0
  202. package/dist/review/resolve.js.map +1 -0
  203. package/dist/review/review-packet.d.ts +40 -0
  204. package/dist/review/review-packet.d.ts.map +1 -0
  205. package/dist/review/review-packet.js +139 -0
  206. package/dist/review/review-packet.js.map +1 -0
  207. package/dist/scan/check-files.d.ts +23 -0
  208. package/dist/scan/check-files.d.ts.map +1 -0
  209. package/dist/scan/check-files.js +90 -0
  210. package/dist/scan/check-files.js.map +1 -0
  211. package/dist/scan/check-scaffold.d.ts +7 -0
  212. package/dist/scan/check-scaffold.d.ts.map +1 -0
  213. package/dist/scan/check-scaffold.js +37 -0
  214. package/dist/scan/check-scaffold.js.map +1 -0
  215. package/dist/scan/constants.d.ts +21 -0
  216. package/dist/scan/constants.d.ts.map +1 -0
  217. package/dist/scan/constants.js +21 -0
  218. package/dist/scan/constants.js.map +1 -0
  219. package/dist/scan/file-kind.d.ts +12 -0
  220. package/dist/scan/file-kind.d.ts.map +1 -0
  221. package/dist/scan/file-kind.js +114 -0
  222. package/dist/scan/file-kind.js.map +1 -0
  223. package/dist/scan/fingerprint-package-loader.d.ts +5 -0
  224. package/dist/scan/fingerprint-package-loader.d.ts.map +1 -0
  225. package/dist/scan/fingerprint-package-loader.js +105 -0
  226. package/dist/scan/fingerprint-package-loader.js.map +1 -0
  227. package/dist/scan/fingerprint-package.d.ts +58 -0
  228. package/dist/scan/fingerprint-package.d.ts.map +1 -0
  229. package/dist/scan/fingerprint-package.js +301 -0
  230. package/dist/scan/fingerprint-package.js.map +1 -0
  231. package/dist/scan/index.d.ts +3 -0
  232. package/dist/scan/index.d.ts.map +1 -0
  233. package/dist/scan/index.js +3 -0
  234. package/dist/scan/index.js.map +1 -0
  235. package/dist/scan/lint.d.ts +15 -0
  236. package/dist/scan/lint.d.ts.map +1 -0
  237. package/dist/scan/lint.js +2 -0
  238. package/dist/scan/lint.js.map +1 -0
  239. package/dist/scan/node-files.d.ts +25 -0
  240. package/dist/scan/node-files.d.ts.map +1 -0
  241. package/dist/scan/node-files.js +114 -0
  242. package/dist/scan/node-files.js.map +1 -0
  243. package/dist/scan/package-paths.d.ts +10 -0
  244. package/dist/scan/package-paths.d.ts.map +1 -0
  245. package/dist/scan/package-paths.js +49 -0
  246. package/dist/scan/package-paths.js.map +1 -0
  247. package/dist/scan/steering-template.d.ts +8 -0
  248. package/dist/scan/steering-template.d.ts.map +1 -0
  249. package/dist/scan/steering-template.js +266 -0
  250. package/dist/scan/steering-template.js.map +1 -0
  251. package/dist/scan/tarball.d.ts +23 -0
  252. package/dist/scan/tarball.d.ts.map +1 -0
  253. package/dist/scan/tarball.js +145 -0
  254. package/dist/scan/tarball.js.map +1 -0
  255. package/dist/scan/templates.d.ts +24 -0
  256. package/dist/scan/templates.d.ts.map +1 -0
  257. package/dist/scan/templates.js +295 -0
  258. package/dist/scan/templates.js.map +1 -0
  259. package/dist/skill-bundle/SKILL.md +140 -0
  260. package/dist/skill-bundle/references/authoring-scenarios.md +147 -0
  261. package/dist/skill-bundle/references/blocks.md +180 -0
  262. package/dist/skill-bundle/references/brief.md +49 -0
  263. package/dist/skill-bundle/references/capture.md +377 -0
  264. package/dist/skill-bundle/references/recall.md +38 -0
  265. package/dist/skill-bundle/references/schema.md +119 -0
  266. package/dist/skill-bundle/references/self-check.md +65 -0
  267. package/dist/skill-bundle/references/steering-audit.md +61 -0
  268. package/dist/skill-bundle/references/wild.md +30 -0
  269. package/package.json +79 -0
@@ -0,0 +1,145 @@
1
+ import { readdir, readFile, stat, writeFile } from "node:fs/promises";
2
+ import { join, relative } from "node:path";
3
+ import { gzipSync } from "node:zlib";
4
+ const BLOCK_SIZE = 512;
5
+ /**
6
+ * Write a dependency-free `.tgz` archive for a Ghost package directory.
7
+ *
8
+ * This intentionally implements only the portable subset Ghost needs: ustar
9
+ * regular-file entries, deterministic path ordering, no symlink traversal.
10
+ */
11
+ export async function writeDirectoryTarball(options) {
12
+ const files = await listRegularFiles(options.rootDir, options.exclude);
13
+ const fileEntries = await Promise.all(files.map(async (file) => ({
14
+ path: file.path,
15
+ data: await readFile(file.absolutePath),
16
+ mtime: file.mtime,
17
+ mode: file.mode,
18
+ })));
19
+ const archive = createTarArchive([
20
+ ...(options.extraEntries ?? []),
21
+ ...fileEntries,
22
+ ]);
23
+ await writeFile(options.outFile, gzipSync(archive));
24
+ }
25
+ export function createTarArchive(entries) {
26
+ const sorted = entries
27
+ .map(normalizeEntry)
28
+ .sort((a, b) => a.path.localeCompare(b.path));
29
+ const chunks = [];
30
+ for (const entry of sorted) {
31
+ const data = Buffer.isBuffer(entry.data)
32
+ ? entry.data
33
+ : Buffer.from(entry.data, "utf-8");
34
+ chunks.push(createHeader({
35
+ path: entry.path,
36
+ size: data.byteLength,
37
+ mode: entry.mode ?? 0o644,
38
+ mtime: entry.mtime ?? new Date(0),
39
+ }));
40
+ chunks.push(data);
41
+ const remainder = data.byteLength % BLOCK_SIZE;
42
+ if (remainder !== 0)
43
+ chunks.push(Buffer.alloc(BLOCK_SIZE - remainder));
44
+ }
45
+ chunks.push(Buffer.alloc(BLOCK_SIZE * 2));
46
+ return Buffer.concat(chunks);
47
+ }
48
+ async function listRegularFiles(rootDir, exclude) {
49
+ const files = [];
50
+ await walk(rootDir, rootDir, exclude, files);
51
+ files.sort((a, b) => a.path.localeCompare(b.path));
52
+ return files;
53
+ }
54
+ async function walk(rootDir, dir, exclude, files) {
55
+ const entries = await readdir(dir, { withFileTypes: true });
56
+ for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
57
+ const absolutePath = join(dir, entry.name);
58
+ const relPath = normalizeTarPath(relative(rootDir, absolutePath));
59
+ if (exclude?.(relPath))
60
+ continue;
61
+ if (entry.isDirectory()) {
62
+ await walk(rootDir, absolutePath, exclude, files);
63
+ continue;
64
+ }
65
+ if (!entry.isFile())
66
+ continue;
67
+ const s = await stat(absolutePath);
68
+ if (!s.isFile())
69
+ continue;
70
+ files.push({
71
+ path: relPath,
72
+ absolutePath,
73
+ size: s.size,
74
+ mode: s.mode & 0o777,
75
+ mtime: s.mtime,
76
+ });
77
+ }
78
+ }
79
+ function normalizeEntry(entry) {
80
+ const path = normalizeTarPath(entry.path);
81
+ if (path === "" || path.startsWith("../") || path.includes("/../")) {
82
+ throw new Error(`Invalid tar entry path: ${entry.path}`);
83
+ }
84
+ return { ...entry, path };
85
+ }
86
+ function createHeader(entry) {
87
+ const header = Buffer.alloc(BLOCK_SIZE, 0);
88
+ const path = splitUstarPath(entry.path);
89
+ writeString(header, path.name, 0, 100);
90
+ writeOctal(header, entry.mode, 100, 8);
91
+ writeOctal(header, 0, 108, 8);
92
+ writeOctal(header, 0, 116, 8);
93
+ writeOctal(header, entry.size, 124, 12);
94
+ writeOctal(header, Math.floor(entry.mtime.getTime() / 1000), 136, 12);
95
+ header.fill(0x20, 148, 156);
96
+ writeString(header, "0", 156, 1);
97
+ writeString(header, "ustar", 257, 6);
98
+ writeString(header, "00", 263, 2);
99
+ if (path.prefix !== undefined)
100
+ writeString(header, path.prefix, 345, 155);
101
+ const checksum = header.reduce((sum, byte) => sum + byte, 0);
102
+ writeChecksum(header, checksum);
103
+ return header;
104
+ }
105
+ function splitUstarPath(path) {
106
+ const byteLength = Buffer.byteLength(path);
107
+ if (byteLength <= 100)
108
+ return { name: path };
109
+ const parts = path.split("/");
110
+ for (let index = 1; index < parts.length; index++) {
111
+ const prefix = parts.slice(0, index).join("/");
112
+ const name = parts.slice(index).join("/");
113
+ if (Buffer.byteLength(prefix) <= 155 && Buffer.byteLength(name) <= 100) {
114
+ return { prefix, name };
115
+ }
116
+ }
117
+ throw new Error(`Tar entry path is too long for ustar: ${path}`);
118
+ }
119
+ function writeString(buffer, value, offset, length) {
120
+ const bytes = Buffer.from(value, "utf-8");
121
+ if (bytes.byteLength > length) {
122
+ throw new Error(`Tar header value is too long: ${value}`);
123
+ }
124
+ bytes.copy(buffer, offset);
125
+ }
126
+ function writeOctal(buffer, value, offset, length) {
127
+ const text = value.toString(8).padStart(length - 1, "0");
128
+ if (text.length > length - 1) {
129
+ throw new Error(`Tar numeric value is too large: ${value}`);
130
+ }
131
+ buffer.write(text, offset, length - 1, "ascii");
132
+ }
133
+ function writeChecksum(buffer, checksum) {
134
+ const text = checksum.toString(8).padStart(6, "0");
135
+ buffer.write(text, 148, 6, "ascii");
136
+ buffer[154] = 0;
137
+ buffer[155] = 0x20;
138
+ }
139
+ function normalizeTarPath(path) {
140
+ return path.replace(/\\/g, "/").replace(/^\.\//, "").replace(/^\/+/, "");
141
+ }
142
+ export function defaultArchiveName(id) {
143
+ return `${id}-fingerprint.tgz`;
144
+ }
145
+ //# sourceMappingURL=tarball.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tarball.js","sourceRoot":"","sources":["../../src/scan/tarball.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * A single seed file an `init` template writes, relative to the package dir.
3
+ */
4
+ export interface TemplateFile {
5
+ /** Path relative to the package directory (e.g. "principle.voice.md"). */
6
+ relativePath: string;
7
+ content: string;
8
+ }
9
+ /**
10
+ * An `init` template: a pure description of the seed files a fresh node package
11
+ * starts with. Templates are the extension seam — adding a `marketing` / `voice`
12
+ * / `dashboard` starter later is just registering another entry here; `init`
13
+ * needs no change.
14
+ */
15
+ export interface GhostInitTemplate {
16
+ name: string;
17
+ description: string;
18
+ files(): TemplateFile[];
19
+ }
20
+ export declare const DEFAULT_TEMPLATE_NAME: string;
21
+ /** Look up a registered init template by name. */
22
+ export declare function getInitTemplate(name: string): GhostInitTemplate | undefined;
23
+ export declare function listInitTemplates(): string[];
24
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/scan/templates.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AACD;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,IAAI,YAAY,EAAE,CAAC;CACzB;AAkSD,eAAO,MAAM,qBAAqB,QAAyB,CAAC;AAE5D,kDAAkD;AAClD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAG3E;AAED,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAE5C"}
@@ -0,0 +1,295 @@
1
+ import { GHOST_FINGERPRINT_PACKAGE_SCHEMA } from "#ghost-core";
2
+ import { GHOST_EVENTS_FILENAME, LEGACY_PULL_HISTORY_FILENAME, } from "./constants.js";
3
+ import { createSteeringTemplate } from "./steering-template.js";
4
+ function manifestFile() {
5
+ return {
6
+ relativePath: "manifest.yml",
7
+ content: `schema: ${GHOST_FINGERPRINT_PACKAGE_SCHEMA}\nid: local\n`,
8
+ };
9
+ }
10
+ /**
11
+ * Keep events tapes out of version control: they are disposable
12
+ * per-machine signals for authors iterating on the fingerprint, never canonical
13
+ * state.
14
+ */
15
+ function gitignoreFile() {
16
+ return {
17
+ relativePath: ".gitignore",
18
+ content: `${GHOST_EVENTS_FILENAME}\n${LEGACY_PULL_HISTORY_FILENAME}\n`,
19
+ };
20
+ }
21
+ /**
22
+ * The minimal starter: a manifest, a package-level glossary declaring the
23
+ * starter kind vocabulary, and a package-root `index.md` node. Additional
24
+ * truths are plain markdown nodes; optional material locators live on the node
25
+ * that explains them. Checks are opt-in via `ghost checks init`.
26
+ */
27
+ const MINIMAL_TEMPLATE = {
28
+ name: "minimal",
29
+ description: "Minimal node package: manifest + glossary + a starter index node.",
30
+ files() {
31
+ return [
32
+ manifestFile(),
33
+ gitignoreFile(),
34
+ {
35
+ relativePath: "glossary.md",
36
+ content: `---
37
+ kinds:
38
+ - name: principle
39
+ - name: condition
40
+ - name: exemplar
41
+ - name: anti-goal
42
+ - name: asset
43
+ - name: pattern
44
+ # - { name: provocation, posture: wild, purpose: a deliberate provocation past the fingerprint — surfaced only on request }
45
+ ---
46
+
47
+ # principle
48
+
49
+ Durable stance: true across media unless a narrower condition explicitly limits it.
50
+
51
+ # condition
52
+
53
+ Situational truth: fires only when the stated situation holds.
54
+
55
+ # exemplar
56
+
57
+ Illustrative reference. Match its form and quality; treat its specifics as
58
+ evidence unless the node says the sample itself is normative.
59
+
60
+ # anti-goal
61
+
62
+ What this brand must never look, sound, or feel like — named generic patterns
63
+ and rejected neighbors. Always-on, like a principle, but stated as the thing
64
+ to steer away from.
65
+
66
+ # asset
67
+
68
+ Material truth about concrete brand assets such as logos, illustrations, motion, imagery, or files.
69
+
70
+ # pattern
71
+
72
+ Reusable composition or product pattern whose purpose is distinguishable from neighboring patterns.
73
+ `,
74
+ },
75
+ {
76
+ relativePath: "index.md",
77
+ content: `---
78
+ description: Always read first — the non-negotiables and how to read this fingerprint.
79
+ ---
80
+
81
+ Replace this placeholder prose with two things:
82
+
83
+ **The non-negotiables.** The handful of truths that apply to every task, every
84
+ medium, no matter what else is gathered — hard invariants, the anti-goals, the
85
+ one-sentence stance. This node is the only one an agent is told to always pull,
86
+ so anything that must never be missed belongs here (stated briefly; link out to
87
+ the full node by id for depth).
88
+
89
+ **How to read the rest.** What this fingerprint covers, how its kinds organize
90
+ the corpus, and where the fingerprint deliberately stays silent — including, if
91
+ you want one, a stricter silence posture ("when this fingerprint is silent on X,
92
+ ask a human") that overrides the default proceed-provisionally behavior.
93
+
94
+ \`index\` is an ordinary node in every mechanical sense — everything below the
95
+ \`---\` is its body; the frontmatter above is the retrieval description. Its
96
+ privilege is pure convention: the recipes tell agents to pull it first.
97
+
98
+ The glossary declares the kind vocabulary. A node's kind comes from its
99
+ filename prefix: \`principle.density.md\` has kind \`principle\` and slug
100
+ \`density\`. A bare filename like \`voice.md\` has no kind, which is fine.
101
+ When a truth is narrower, state the condition in the prose — the situation where
102
+ it applies — never a filing destination.
103
+ `,
104
+ },
105
+ ];
106
+ },
107
+ };
108
+ /**
109
+ * The composition starter: everything in `minimal`, plus a worked composition
110
+ * ladder — an invariants floor (`principle.composition`), one bound/open
111
+ * pattern, and an index that teaches the convention. For teams whose
112
+ * fingerprint must steer *what agents build*, not only what they say.
113
+ *
114
+ * The ladder is an authoring convention, not a schema: patterns state what is
115
+ * bound (do not redecide) and what is open (the generator's call), and every
116
+ * pattern names the principles it refines. Nothing here adds frontmatter,
117
+ * edges, or routing — the corpus stays flat.
118
+ */
119
+ const COMPOSITION_TEMPLATE = {
120
+ name: "composition",
121
+ description: "Composition starter: minimal files + an invariants floor and a worked bound/open pattern.",
122
+ files() {
123
+ return [
124
+ manifestFile(),
125
+ gitignoreFile(),
126
+ {
127
+ relativePath: "glossary.md",
128
+ content: `---
129
+ kinds:
130
+ - name: principle
131
+ - name: condition
132
+ - name: exemplar
133
+ - name: anti-goal
134
+ - name: asset
135
+ - name: pattern
136
+ # - { name: provocation, posture: wild, purpose: a deliberate provocation past the fingerprint — surfaced only on request }
137
+ ---
138
+
139
+ # principle
140
+
141
+ Durable stance: true across media unless a narrower condition explicitly limits it.
142
+ Composition principles are the floor — when no pattern matches an ask, they are
143
+ what the agent composes against.
144
+
145
+ # condition
146
+
147
+ Situational truth: fires only when the stated situation holds.
148
+
149
+ # exemplar
150
+
151
+ Illustrative reference. Match its form and quality; treat its specifics as
152
+ evidence unless the node says the sample itself is normative. Pair an
153
+ exemplar with a screenshot or implementation path in \`materials\` so the blessed
154
+ render travels with the prose.
155
+
156
+ # anti-goal
157
+
158
+ What this brand must never look, sound, or feel like — named generic patterns
159
+ and rejected neighbors. Always-on, like a principle, but stated as the thing
160
+ to steer away from.
161
+
162
+ # asset
163
+
164
+ Material truth about concrete brand assets such as logos, illustrations, motion,
165
+ imagery, or files. For components, state the slot contract in prose: what the
166
+ asset admits, how many, and where.
167
+
168
+ # pattern
169
+
170
+ Reusable composition whose purpose is distinguishable from neighboring patterns.
171
+ A pattern states what is **bound** (decided — do not redecide) and what is
172
+ **open** (the generator's call, within named limits), and names the principles
173
+ it refines. A pattern may only narrow what its principles allow — never loosen
174
+ them.
175
+ `,
176
+ },
177
+ {
178
+ relativePath: "index.md",
179
+ content: `---
180
+ description: Start here — how this fingerprint steers composition, from patterns down to principles.
181
+ ---
182
+
183
+ This fingerprint steers what gets built, not only what gets said. It is
184
+ organized as a ladder of binding depth:
185
+
186
+ 1. **Patterns** (\`pattern.*\`) are mostly-decided compositions. When an ask
187
+ matches a pattern's stated purpose, use it: apply what it binds, decide only
188
+ what it leaves open.
189
+ 2. **Principles** (\`principle.*\`) are the floor. When no pattern matches, do
190
+ not fall back to your own taste — compose freely *inside* the invariants in
191
+ \`principle.composition\` and its siblings.
192
+ 3. **Exemplars and assets** carry the concrete vocabulary: blessed renders,
193
+ real components, real tokens, located via \`materials\`.
194
+
195
+ Two laws keep the ladder honest:
196
+
197
+ - **Narrowing only.** A pattern may bind or narrow what a principle leaves
198
+ open; it may never contradict one. If a pattern conflicts with a principle,
199
+ the principle wins and the pattern file is wrong.
200
+ - **Every "never" casts a shadow.** Each refusal-grade line in a principle
201
+ should be mirrored by a review check (\`ghost checks init\`) that
202
+ references the node it enforces, so the same opinion steers before building
203
+ and grades after.
204
+
205
+ Replace this prose with your own front door once the corpus has shape. The
206
+ starter nodes below are teaching placeholders — edit them into your real
207
+ opinions before trusting them.
208
+ `,
209
+ },
210
+ {
211
+ relativePath: "principle.composition.md",
212
+ content: `---
213
+ description: The composition floor — hard layout invariants that hold for every screen, whether or not a pattern matches the ask.
214
+ ---
215
+
216
+ These invariants apply to everything built against this fingerprint. Patterns
217
+ narrow them; nothing loosens them. Each is written as a refusal or a limit with
218
+ a number, because a stance an agent can check is a stance that steers.
219
+
220
+ **The starter opinions below are placeholders. Keep the voice — refusals and
221
+ numbers, not vibes — and replace the values with yours.**
222
+
223
+ - **One focal point.** Every screen has exactly one element at the largest
224
+ scale. If two elements compete for primacy, the second one is wrong — demote
225
+ or delete it. Never resolve the tie by making both big.
226
+ - **Hierarchy descends.** Type scale strictly decreases with nesting depth.
227
+ Never give a child element a larger scale than its parent context.
228
+ - **Density has a budget.** State the budget per surface (for example: at most
229
+ N data points per viewport on consumer surfaces; a higher N on operational
230
+ ones). When content exceeds the budget, cut or collapse — never shrink type
231
+ below the ramp to make room.
232
+ - **Actions land last.** Calls to action render at the end of reading order.
233
+ At most one primary action per screen; never two.
234
+ - **Separation escalates.** To separate content, reach for whitespace first,
235
+ then a divider, then a container — in that order, never skipping a step.
236
+
237
+ Mirror each refusal here with a check under \`checks/\` that lists this
238
+ node in its \`references\`, so review enforces the same floor this prose sets.
239
+ `,
240
+ },
241
+ {
242
+ relativePath: "pattern.status-with-next-step.md",
243
+ content: `---
244
+ description: Status of an ongoing thing plus the single next step — reach for this when the ask is "where is X / how is X going."
245
+ ---
246
+
247
+ **This is a worked example of the pattern convention — bound, open, refines.
248
+ Replace its content with a real pattern from your product, keep the structure.**
249
+
250
+ **When this applies:** the ask is about the state of something in flight — an
251
+ order, a transfer, a build, a goal.
252
+
253
+ **Bound (decided — do not redecide):**
254
+
255
+ - The current status renders first and largest; it is the focal point.
256
+ - A short line of meaning follows the status: why it matters or what changed,
257
+ never a restatement of it.
258
+ - Exactly one primary action, rendered last: the single next step.
259
+
260
+ **Open (your call, within these limits):**
261
+
262
+ - Supporting evidence may be a timeline or a compact stat list — whichever
263
+ fits the data. Never a full chart in this pattern.
264
+ - Density may flex one step tighter on operational surfaces.
265
+
266
+ **Refines:** \`principle.composition\`. If anything above conflicts with the
267
+ floor, the floor wins and this file is wrong.
268
+
269
+ When a blessed render of this pattern exists, add an \`exemplar.*\` node with
270
+ \`materials\` pointing at the screenshot and the implementation path.
271
+ `,
272
+ },
273
+ ];
274
+ },
275
+ };
276
+ const STEERING_TEMPLATE = createSteeringTemplate({
277
+ manifestFile,
278
+ gitignoreFile,
279
+ });
280
+ const TEMPLATES = new Map([
281
+ [MINIMAL_TEMPLATE.name, MINIMAL_TEMPLATE],
282
+ [COMPOSITION_TEMPLATE.name, COMPOSITION_TEMPLATE],
283
+ [STEERING_TEMPLATE.name, STEERING_TEMPLATE],
284
+ ]);
285
+ export const DEFAULT_TEMPLATE_NAME = STEERING_TEMPLATE.name;
286
+ /** Look up a registered init template by name. */
287
+ export function getInitTemplate(name) {
288
+ if (name === "default")
289
+ return STEERING_TEMPLATE;
290
+ return TEMPLATES.get(name);
291
+ }
292
+ export function listInitTemplates() {
293
+ return [...TEMPLATES.keys()];
294
+ }
295
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/scan/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gCAAgC,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EACL,qBAAqB,EACrB,4BAA4B,GAC7B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAoBhE,SAAS,YAAY;IACnB,OAAO;QACL,YAAY,EAAE,cAAc;QAC5B,OAAO,EAAE,WAAW,gCAAgC,eAAe;KACpE,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa;IACpB,OAAO;QACL,YAAY,EAAE,YAAY;QAC1B,OAAO,EAAE,GAAG,qBAAqB,KAAK,4BAA4B,IAAI;KACvE,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,gBAAgB,GAAsB;IAC1C,IAAI,EAAE,SAAS;IACf,WAAW,EACT,mEAAmE;IACrE,KAAK;QACH,OAAO;YACL,YAAY,EAAE;YACd,aAAa,EAAE;YACf;gBACE,YAAY,EAAE,aAAa;gBAC3B,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqChB;aACM;YACD;gBACE,YAAY,EAAE,UAAU;gBACxB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BhB;aACM;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,oBAAoB,GAAsB;IAC9C,IAAI,EAAE,aAAa;IACnB,WAAW,EACT,2FAA2F;IAC7F,KAAK;QACH,OAAO;YACL,YAAY,EAAE;YACd,aAAa,EAAE;YACf;gBACE,YAAY,EAAE,aAAa;gBAC3B,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+ChB;aACM;YACD;gBACE,YAAY,EAAE,UAAU;gBACxB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BhB;aACM;YACD;gBACE,YAAY,EAAE,0BAA0B;gBACxC,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BhB;aACM;YACD;gBACE,YAAY,EAAE,kCAAkC;gBAChD,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BhB;aACM;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,MAAM,iBAAiB,GAAG,sBAAsB,CAAC;IAC/C,YAAY;IACZ,aAAa;CACd,CAAC,CAAC;AAEH,MAAM,SAAS,GAAG,IAAI,GAAG,CAA4B;IACnD,CAAC,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,CAAC;IACzC,CAAC,oBAAoB,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACjD,CAAC,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,CAAC;CAC5C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAG,iBAAiB,CAAC,IAAI,CAAC;AAE5D,kDAAkD;AAClD,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,iBAAiB,CAAC;IACjD,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,CAAC,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,140 @@
1
+ ---
2
+ name: ghost
3
+ description: Author, validate, consume, and review against a repo-local Ghost fingerprint — the medium-agnostic articulation of a product's brand. Use when the user wants to set up a .ghost fingerprint, write or update brand-truth nodes, gather brand context before generation, or assemble a review packet from Ghost checks.
4
+ license: Apache-2.0
5
+ metadata:
6
+ homepage: https://github.com/block/ghost
7
+ cli: ghost
8
+ ---
9
+
10
+ # Ghost — Brand Fingerprints
11
+
12
+ A Ghost fingerprint is the medium-agnostic articulation of a brand: its truths,
13
+ its stance, its conditions, and optional pointers to the concrete materials those
14
+ truths govern. One brand truth is stated once, at the altitude it is actually
15
+ true, and an agent reads the relevant truths before building.
16
+
17
+ ```text
18
+ .ghost/
19
+ manifest.yml # schema + id (the package anchor)
20
+ glossary.md # the author's kind vocabulary
21
+ materials/ # bundled materials; reserved, never nodes
22
+ <kind>.<slug>.md # a brand truth of a declared kind
23
+ <slug>.md # a brand truth without a kind
24
+ checks/ # optional review assertions; never nodes
25
+ ```
26
+
27
+ ## The model in one breath
28
+
29
+ - A **node** is a markdown file: `description`, optional `materials`, and a prose
30
+ brand truth.
31
+ - `materials` is one list of locators for the concrete stuff the truth is about:
32
+ repo-relative paths/globs or absolute HTTPS URLs. `materials/` is reserved for
33
+ bundled materials; reference living implementations where they already live.
34
+ Guidance stays in prose.
35
+ - A node's **kind** comes from its filename prefix (`principle.density.md` →
36
+ kind `principle`). A bare name (`voice.md`) has no kind.
37
+ - The **glossary** declares the kind vocabulary, what each kind means, and optional consumption posture: `steady` by default, `posture: wild` for truths that require explicit request, or `posture: guard` for review-critical anti-goals with positive replacement.
38
+ - The starter `index.md` node (id `index`) is the human-curated front door:
39
+ by convention it carries the non-negotiables and reading posture, and agents
40
+ pull it first.
41
+ - There is **no hierarchy, no inheritance, no edges**. Directories are for browsing
42
+ only; the model reads a flat menu.
43
+ - **Checks** are optional review assertions in a flat `.ghost/checks/*.md`
44
+ directory. Checks are feed-back only; they never leak into generation
45
+ context. Each check declares `references` to node ids and is used by
46
+ `ghost review`. A check may
47
+ include `probe: <command>`; review runs it as evidence unless `--no-probes` is
48
+ set. Checks are never emitted by `ghost gather` or `ghost pull`.
49
+
50
+ ## The loop
51
+
52
+ ```bash
53
+ ghost init # scaffold .ghost/ with the steering starter
54
+ ghost checks init # opt in to review assertions
55
+ ghost validate # artifact shape + node/material/check validation
56
+ ghost gather <ask> # emit the fingerprint menu for this task
57
+ ghost pull <ids> # read selected node bodies and materials
58
+ ghost review # assemble diff + matched material-backed nodes + checks
59
+ ghost export # package .ghost/ as a portable brand artifact
60
+ ghost pulse # summarize local gather/pull events while tuning
61
+ ```
62
+
63
+ `gather` does no selection. It emits the menu and you read the ask against it,
64
+ then pull the truths you judge relevant. Its header includes a coverage line —
65
+ total nodes, nodes carrying concrete material, and guards — so an all-prose or
66
+ unrouted fingerprint is visible before generation.
67
+
68
+ Prefer `ghost pull` over reading files directly: it emits the same prose,
69
+ inlines small local materials by default, turns binary materials into
70
+ inspect-pointers, orders the packet for steering (`index`, concrete nodes,
71
+ prose rules, guards), extracts Skeletons dead last, and appends structured
72
+ events to `.ghost/.events` for local tuning.
73
+
74
+ `review` does no grading. It assembles an advisory packet: touched files,
75
+ matched material-backed nodes, matched guard nodes, offered checks, probe
76
+ evidence, coverage gaps, and the diff. The host agent renders findings.
77
+
78
+ ## CLI verbs
79
+
80
+ | Verb | Purpose |
81
+ |---|---|
82
+ | `ghost init` | Scaffold `.ghost/` with the steering starter: manifest, glossary, `index.md`, and demo nodes for stance, composition, anti-goals, patterns, exemplars, materials, and decisions. `--template minimal` writes only the small manifest/glossary/index starter. `--with checks` also adds the checks directory. |
83
+ | `ghost checks init` | Scaffold `.ghost/checks/` with an example review assertion. |
84
+ | `ghost validate [file-or-dir]` | Validate manifest, nodes, material locators, check references, and glossary kind prefixes. |
85
+ | `ghost gather [ask…] [--wild] [--format json]` | Emit the node menu for selection plus coverage line; log exposed ids. Default gather excludes wild kinds unless `--wild` is explicit. |
86
+ | `ghost pull <id> [<id>…]` | Emit selected nodes' full bodies and materials in steering order; log selected/missed ids. |
87
+ | `ghost review [--diff <path|->] [--base <ref>] [--format json] [--no-probes]` | Emit an advisory review packet for a diff (requires `.ghost/checks/`). |
88
+ | `ghost export [--out <path>] [--no-checks] [--strict] [--format json]` | Package `.ghost/` as a portable brand artifact and report which material locators will not travel. |
89
+ | `ghost pulse [--format json]` | Summarize local `.ghost/.events`. |
90
+ | `ghost skill install` | Install this skill bundle. |
91
+ | `ghost manifest [--format json]` | Emit a self-describing JSON manifest of every command and flag. |
92
+
93
+ ## Skeleton convention
94
+
95
+ A `## Skeleton` section in a node contains the literal opening structure for a
96
+ surface, usually on a `pattern.*` node. `ghost validate` warns unless each
97
+ Skeleton section has exactly one fenced block. `ghost pull` removes Skeletons
98
+ from the node body and emits the fences at the end under a begin-from-this banner.
99
+ If a pulled Skeleton matches the task, start the artifact from it verbatim, then
100
+ fill with task facts.
101
+
102
+ ## Receiving a fingerprint
103
+
104
+ Unpack the exported archive, run `ghost validate --package <dir>`, then run
105
+ `ghost skill install` in the receiving workspace. From there, gather and pull
106
+ against the unpacked package with `--package <dir>`.
107
+
108
+ ## Workflows
109
+
110
+ - Author or update the fingerprint: follow [references/capture.md](references/capture.md).
111
+ - Author material-backed nodes: follow [references/blocks.md](references/blocks.md).
112
+ - Choose the right human-agent authoring workflow: follow [references/authoring-scenarios.md](references/authoring-scenarios.md).
113
+ - Gather applicable truths for a task: follow [references/recall.md](references/recall.md).
114
+ - Shape a pre-generation brief: follow [references/brief.md](references/brief.md).
115
+ - Explore deliberate provocations with wild nodes: follow [references/wild.md](references/wild.md).
116
+ - Probe readiness before generating: follow [references/self-check.md](references/self-check.md).
117
+ - Audit steering coverage: follow [references/steering-audit.md](references/steering-audit.md).
118
+ - Understand the package shape: see [references/schema.md](references/schema.md).
119
+
120
+ Fingerprint authoring is **elicitation, not scanning**. The raw material is what
121
+ the human brings and points at: words, images, links, exemplar products, brand
122
+ docs, copy they love or hate. Repo code can supply material locators and local
123
+ conventions, but durable brand truth should be curated by the human.
124
+
125
+ ## When the fingerprint is silent
126
+
127
+ A silent fingerprint does not require stopping. Proceed from nearby product
128
+ surfaces, local conventions, and ordinary reasoning when safe, and label that
129
+ reasoning as provisional and non-Ghost-backed — unless the fingerprint itself
130
+ declares a stricter silence posture (check the `index` node), which overrides
131
+ this default. Ask a human before high-risk, irreversible, privacy, security,
132
+ legal, or brand-defining choices.
133
+
134
+ ## Never
135
+
136
+ - Never invent hierarchy, inheritance, or cross-node edges.
137
+ - Never file a truth by destination (`for-emails.md`); state its condition in prose.
138
+ - Never put guidance in `materials`; it belongs in the node body.
139
+ - Never gather checks as generation context.
140
+ - Never claim provisional or local-convention reasoning as Ghost-backed.