@forwardimpact/outpost 3.12.0 → 3.13.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 (129) hide show
  1. package/README.md +2 -2
  2. package/bin/fit-outpost.js +3 -2
  3. package/package.json +6 -5
  4. package/src/agent-path.js +10 -6
  5. package/src/agent-runner.js +28 -24
  6. package/src/index.js +2 -3
  7. package/src/kb-manager.js +75 -20
  8. package/src/kb-validator.js +762 -0
  9. package/src/outpost.js +108 -39
  10. package/src/posture.js +3 -3
  11. package/src/privilege.js +11 -11
  12. package/src/scheduler.js +14 -12
  13. package/src/socket-server.js +19 -18
  14. package/src/spawn-env.js +7 -6
  15. package/src/state-manager.js +2 -2
  16. package/templates/.claude/agents/chief-of-staff.md +32 -24
  17. package/templates/.claude/agents/concierge.md +26 -17
  18. package/templates/.claude/agents/head-hunter.md +34 -26
  19. package/templates/.claude/agents/librarian.md +26 -18
  20. package/templates/.claude/agents/postman.md +26 -18
  21. package/templates/.claude/agents/recruiter.md +38 -27
  22. package/templates/.claude/skills/anarlog-follow/SKILL.md +91 -66
  23. package/templates/.claude/skills/anarlog-follow/references/coaching.md +22 -21
  24. package/templates/.claude/skills/anarlog-follow/references/sessions.md +52 -0
  25. package/templates/.claude/skills/anarlog-process/SKILL.md +108 -62
  26. package/templates/.claude/skills/anarlog-process/references/extraction.md +41 -29
  27. package/templates/.claude/skills/anarlog-process/references/sessions.md +92 -58
  28. package/templates/.claude/skills/anarlog-process/scripts/scan.mjs +402 -160
  29. package/templates/.claude/skills/candidate-report/SKILL.md +41 -36
  30. package/templates/.claude/skills/candidate-report/references/report-template.html +10 -10
  31. package/templates/.claude/skills/candidate-report/references/report.css +4 -4
  32. package/templates/.claude/skills/candidate-report/references/rubric.md +15 -14
  33. package/templates/.claude/skills/candidate-report/scripts/render-pdf.mjs +2 -2
  34. package/templates/.claude/skills/changelog/SKILL.md +122 -67
  35. package/templates/.claude/skills/deck-create/SKILL.md +90 -32
  36. package/templates/.claude/skills/deck-create/references/slide.css +4 -4
  37. package/templates/.claude/skills/deck-create/scripts/convert-to-pdf.mjs +6 -6
  38. package/templates/.claude/skills/deck-review/SKILL.md +63 -58
  39. package/templates/.claude/skills/deck-review/assets/slide-annotator.js +58 -49
  40. package/templates/.claude/skills/deck-summarize/SKILL.md +55 -45
  41. package/templates/.claude/skills/deck-summarize/references/brief-template.md +5 -4
  42. package/templates/.claude/skills/deck-summarize/scripts/extract-pptx.mjs +8 -7
  43. package/templates/.claude/skills/doc-collab/SKILL.md +39 -34
  44. package/templates/.claude/skills/doc-create/SKILL.md +27 -23
  45. package/templates/.claude/skills/doc-create/scripts/convert-to-pdf.mjs +6 -6
  46. package/templates/.claude/skills/draft-emails/SKILL.md +63 -53
  47. package/templates/.claude/skills/draft-emails/references/template.md +2 -2
  48. package/templates/.claude/skills/draft-emails/scripts/scan-emails.mjs +15 -8
  49. package/templates/.claude/skills/draft-emails/scripts/send-email.mjs +19 -11
  50. package/templates/.claude/skills/extract-entities/SKILL.md +76 -75
  51. package/templates/.claude/skills/extract-entities/references/TEMPLATES.md +6 -5
  52. package/templates/.claude/skills/extract-entities/references/conditions.md +20 -18
  53. package/templates/.claude/skills/extract-entities/references/content.md +10 -9
  54. package/templates/.claude/skills/extract-entities/references/links.md +37 -13
  55. package/templates/.claude/skills/extract-entities/references/recruitment.md +30 -24
  56. package/templates/.claude/skills/extract-entities/references/resolution.md +14 -14
  57. package/templates/.claude/skills/extract-entities/references/sources.md +9 -9
  58. package/templates/.claude/skills/extract-entities/references/templates-conditions.md +12 -6
  59. package/templates/.claude/skills/extract-entities/references/templates-people-orgs.md +29 -10
  60. package/templates/.claude/skills/extract-entities/references/templates-priorities.md +10 -4
  61. package/templates/.claude/skills/extract-entities/references/templates-projects-topics.md +19 -7
  62. package/templates/.claude/skills/extract-entities/scripts/state.mjs +9 -8
  63. package/templates/.claude/skills/meeting-prep/SKILL.md +42 -36
  64. package/templates/.claude/skills/organize-files/SKILL.md +27 -22
  65. package/templates/.claude/skills/organize-files/scripts/organize-by-type.mjs +5 -4
  66. package/templates/.claude/skills/organize-files/scripts/summarize.mjs +4 -4
  67. package/templates/.claude/skills/person-identify/SKILL.md +77 -27
  68. package/templates/.claude/skills/person-identify/scripts/identify.sh +125 -26
  69. package/templates/.claude/skills/person-lookup/SKILL.md +34 -30
  70. package/templates/.claude/skills/person-lookup/scripts/lookup.sh +46 -17
  71. package/templates/.claude/skills/req-assess/SKILL.md +44 -36
  72. package/templates/.claude/skills/req-assess/references/interview-template.md +7 -2
  73. package/templates/.claude/skills/req-assess/references/panel-template.md +7 -2
  74. package/templates/.claude/skills/req-assess/references/rubric.md +13 -13
  75. package/templates/.claude/skills/req-bundle/SKILL.md +164 -0
  76. package/templates/.claude/skills/req-bundle/references/matching.md +70 -0
  77. package/templates/.claude/skills/req-bundle/references/pdf-structure.md +74 -0
  78. package/templates/.claude/skills/req-bundle/scripts/split-bundle.mjs +377 -0
  79. package/templates/.claude/skills/req-decide/SKILL.md +52 -41
  80. package/templates/.claude/skills/req-decide/references/rubric.md +11 -10
  81. package/templates/.claude/skills/req-decide/references/template.md +2 -2
  82. package/templates/.claude/skills/req-forget/SKILL.md +58 -39
  83. package/templates/.claude/skills/req-forget/references/classify.md +15 -13
  84. package/templates/.claude/skills/req-forget/references/locations.md +27 -22
  85. package/templates/.claude/skills/req-forget/references/report-template.md +24 -16
  86. package/templates/.claude/skills/req-scan/SKILL.md +27 -25
  87. package/templates/.claude/skills/req-scan/references/fallbacks.md +9 -9
  88. package/templates/.claude/skills/req-scan/references/filters.md +13 -13
  89. package/templates/.claude/skills/req-scan/references/sources.md +7 -7
  90. package/templates/.claude/skills/req-scan/references/state.md +1 -1
  91. package/templates/.claude/skills/req-scan/references/template.md +11 -1
  92. package/templates/.claude/skills/req-scan/scripts/state.mjs +3 -2
  93. package/templates/.claude/skills/req-screen/SKILL.md +96 -50
  94. package/templates/.claude/skills/req-screen/references/rubric.md +46 -50
  95. package/templates/.claude/skills/req-screen/references/scoring.md +79 -0
  96. package/templates/.claude/skills/req-screen/references/template.md +29 -17
  97. package/templates/.claude/skills/req-track/SKILL.md +76 -76
  98. package/templates/.claude/skills/req-track/references/fields.md +31 -27
  99. package/templates/.claude/skills/req-track/references/overlays.md +42 -0
  100. package/templates/.claude/skills/req-track/references/signals.md +12 -12
  101. package/templates/.claude/skills/req-track/references/statuses.md +3 -2
  102. package/templates/.claude/skills/req-track/references/templates.md +28 -27
  103. package/templates/.claude/skills/req-workday/SKILL.md +69 -40
  104. package/templates/.claude/skills/req-workday/references/brief.md +81 -0
  105. package/templates/.claude/skills/req-workday/references/status-mapping.md +5 -5
  106. package/templates/.claude/skills/req-workday/references/templates.md +11 -78
  107. package/templates/.claude/skills/req-workday/references/xlsx-format.md +26 -7
  108. package/templates/.claude/skills/req-workday/scripts/parse-workday.mjs +113 -35
  109. package/templates/.claude/skills/send-chat/SKILL.md +58 -54
  110. package/templates/.claude/skills/sync-apple-calendar/SKILL.md +23 -19
  111. package/templates/.claude/skills/sync-apple-calendar/references/SCHEMA.md +7 -7
  112. package/templates/.claude/skills/sync-apple-calendar/scripts/query.mjs +6 -6
  113. package/templates/.claude/skills/sync-apple-calendar/scripts/sync.mjs +9 -8
  114. package/templates/.claude/skills/sync-apple-mail/SKILL.md +20 -14
  115. package/templates/.claude/skills/sync-apple-mail/references/SCHEMA.md +10 -10
  116. package/templates/.claude/skills/sync-apple-mail/scripts/parse-emlx.mjs +9 -9
  117. package/templates/.claude/skills/sync-apple-mail/scripts/sync-helpers.mjs +16 -13
  118. package/templates/.claude/skills/sync-apple-mail/scripts/sync.mjs +3 -3
  119. package/templates/.claude/skills/sync-teams/SKILL.md +46 -43
  120. package/templates/.claude/skills/sync-teams/scripts/idb-reader.mjs +22 -21
  121. package/templates/.claude/skills/sync-teams/scripts/leveldb-reader.mjs +4 -4
  122. package/templates/.claude/skills/sync-teams/scripts/sync.mjs +4 -4
  123. package/templates/.claude/skills/upstream-instructions/SKILL.md +43 -41
  124. package/templates/.claude/skills/upstream-instructions/references/examples.md +5 -5
  125. package/templates/CLAUDE.md +97 -85
  126. package/templates/MIGRATION.md +359 -0
  127. package/templates/registry.yaml +25 -0
  128. package/templates/.claude/skills/anarlog-follow/scripts/follow.mjs +0 -243
  129. package/templates/.claude/skills/anarlog-trim/SKILL.md +0 -183
@@ -7,20 +7,21 @@
7
7
  * data-slide-selector=".slide"
8
8
  * data-label-selector=".slide-num"></script>
9
9
  *
10
- * Click the “✎ Review” button (bottom-left), select text on a slide, optionally
11
- * add a note, and Add. Annotations autosave to localStorage immediately. Click
12
- * “Connect folder” once to (a) write a real sidecar JSON next to the page and
13
- * (b) resolve each highlight to its SOURCE line/column + context lines by
14
- * reading the page’s own source file. No build step, no server, no deps.
10
+ * Click the “✎ Review” button (bottom-left). Select text on a slide. Add an
11
+ * optional note. Then click Add. Annotations autosave to localStorage
12
+ * immediately. Click “Connect folder” once. The tool then writes a real
13
+ * sidecar JSON next to the page. It also reads the page’s own source file, so
14
+ * it resolves each highlight to its SOURCE line/column + context lines. The
15
+ * tool needs no build step, no server, and no dependencies.
15
16
  *
16
- * The connected folder is remembered across reloads (the directory handle is
17
- * stored in IndexedDB). On reload it reconnects silently if the browser still
18
- * grants permission; otherwise the button reads “Reconnect folder” and one
19
- * click re-grants access without re-picking the folder.
17
+ * The tool remembers the connected folder across reloads. It stores the
18
+ * directory handle in IndexedDB. On reload it reconnects silently if the
19
+ * browser still grants permission. If not, the button reads “Reconnect
20
+ * folder”. One click then re-grants access without a new folder pick.
20
21
  *
21
- * Optional host hook: if the page defines `window.deckGoto(index)` the panel’s
22
- * “Go” buttons will navigate to the right slide. Without it, the tool still
23
- * works (it falls back to scrollIntoView).
22
+ * Optional host hook. If the page defines `window.deckGoto(index)`, the
23
+ * panel’s “Go” buttons navigate to the right slide. Without it, the tool
24
+ * still works (it falls back to scrollIntoView).
24
25
  *
25
26
  * SIDECAR JSON SCHEMA (what an agent reads to act on the feedback):
26
27
  * {
@@ -120,7 +121,8 @@
120
121
  ::highlight(sa-all){background:rgba(255,221,0,.45);text-decoration:underline;text-decoration-color:#caا}\
121
122
  ::highlight(sa-active){background:rgba(255,0,110,.35)}\
122
123
  @media print{.sa-ui{display:none!important}}";
123
- // (one stray glyph above is harmless inside a CSS comment-free value; replaced below)
124
+ // The stray glyph above is harmless in a comment-free CSS value.
125
+ // The next line replaces it.
124
126
  css = css.replace("#caا", "#b38f00");
125
127
  var styleEl = document.createElement("style");
126
128
  styleEl.textContent = css;
@@ -160,13 +162,14 @@
160
162
  ui.note = ui.pop.querySelector("textarea");
161
163
  var onlyThisSlide = false;
162
164
 
163
- // Keep the tool's own keystrokes from leaking to the host page (e.g. a deck's
164
- // Space / arrow-key slide navigation) while typing a note or using a panel
165
- // button. We stop propagation in the BUBBLE phase, so: (a) our capture-phase
166
- // Esc handler has already run, and (b) the default action — typing the
167
- // character, moving the caret — still happens. Scoped to the tool's own UI,
168
- // so arrow/Space navigation still works when focus is on the page itself.
169
- // Independent of any host: we never touch the host's handlers, just our own.
165
+ // Keep the tool's own keystrokes away from the host page. One example is a
166
+ // deck's Space and arrow-key slide navigation. This applies while the user
167
+ // types a note or uses a panel button. We stop propagation in the BUBBLE
168
+ // phase. So our capture-phase Esc handler already ran. The default action
169
+ // also still happens. The character appears and the caret moves. We scope
170
+ // this to the tool's own UI. Arrow and Space navigation still works when
171
+ // focus is on the page itself. This works with any host. We never touch
172
+ // the host's handlers, only our own.
170
173
  [ui.fab, ui.banner, ui.panel, ui.pop].forEach(function (node) {
171
174
  ["keydown", "keyup", "keypress"].forEach(function (type) {
172
175
  node.addEventListener(type, function (e) { e.stopPropagation(); });
@@ -210,10 +213,11 @@
210
213
  else if (review) { toggle(false); e.stopPropagation(); }
211
214
  }, true);
212
215
 
213
- // In review mode, swallow ONLY the click that ends a text-selection drag, so a
214
- // host with click-to-advance can't navigate out from under the highlight. Plain
215
- // clicks (with no active selection) pass through untouched — footer dots, links
216
- // and buttons keep working. Non-invasive and host-agnostic.
216
+ // In review mode, swallow ONLY the click that ends a text-selection drag.
217
+ // A host with click-to-advance then cannot navigate out from under the
218
+ // highlight. Plain clicks (with no active selection) pass through
219
+ // untouched. Footer dots, links and buttons keep working. The tool does
220
+ // not intrude, and it works with any host.
217
221
  function clickSuppressor(e) {
218
222
  if (e.target.closest(".sa-ui")) return;
219
223
  var sel = window.getSelection();
@@ -252,9 +256,10 @@
252
256
  var off = offsets(slide, range);
253
257
  var text = slide.textContent;
254
258
  var slides = allSlides();
255
- // Anchor on the underlying DOM text (text.slice), NOT Selection.toString():
256
- // the latter applies text-transform (e.g. uppercase headings) and would no
257
- // longer match the source or the slide's textContent.
259
+ // Anchor on the underlying DOM text (text.slice). Do NOT use
260
+ // Selection.toString(). It applies text-transform (e.g. uppercase
261
+ // headings). The result would no longer match the source or the slide's
262
+ // textContent.
258
263
  var storedQuote = text.slice(off.start, off.end) || quote;
259
264
 
260
265
  pending = {
@@ -394,7 +399,7 @@
394
399
  if (!list.length) {
395
400
  ui.list.innerHTML = '<div class="sa-empty">' +
396
401
  (onlyThisSlide ? "No annotations on this slide." :
397
- "No annotations yet.<br><br>Select text on a slide to highlight it. Highlights autosave locally; click <b>Connect folder</b> to write the sidecar JSON and capture source line numbers.") +
402
+ "No annotations yet.<br><br>Select text on a slide to highlight it. Highlights autosave locally. Click <b>Connect folder</b> to write the sidecar JSON and capture source line numbers.") +
398
403
  '</div>';
399
404
  return;
400
405
  }
@@ -417,7 +422,7 @@
417
422
  function currentSlideIndex() {
418
423
  var slides = allSlides();
419
424
  for (var i = 0; i < slides.length; i++) if (slides[i].classList.contains("active")) return i;
420
- // else the slide most centered in viewport
425
+ // else the slide most centered in the viewport
421
426
  var best = 0, bestD = Infinity, cx = window.innerWidth / 2, cy = window.innerHeight / 2;
422
427
  slides.forEach(function (s, i) {
423
428
  var r = s.getBoundingClientRect();
@@ -442,12 +447,13 @@
442
447
  if (ui.count) ui.count.textContent = state.annotations.length;
443
448
  }
444
449
 
445
- /* Persist the connected directory handle across reloads. FileSystemHandles are
446
- * structured-cloneable, so they live in IndexedDB (localStorage is strings
447
- * only). Re-granting read/write permission after a reload needs a user
448
- * gesture, so a remembered folder reconnects with one click via the same
449
- * "Connect folder" button rather than the full directory picker. Keyed by
450
- * cfg.target so distinct decks in a folder don't clobber each other. */
450
+ /* Persist the connected directory handle across reloads. FileSystemHandles
451
+ * are structured-cloneable, so they live in IndexedDB (localStorage holds
452
+ * strings only). A re-grant of read/write permission after a reload needs
453
+ * a user gesture. So a remembered folder reconnects with one click through
454
+ * the same "Connect folder" button. It does not open the full directory
455
+ * picker. The key is cfg.target, so distinct decks in a folder do not
456
+ * clobber each other. */
451
457
  var IDB_NAME = "slide-annotator", IDB_STORE = "handles";
452
458
  function idbOpen() {
453
459
  return new Promise(function (resolve, reject) {
@@ -484,16 +490,17 @@
484
490
  : rememberedHandle ? "Reconnect folder" : "Connect folder";
485
491
  }
486
492
 
487
- // Adopt a (freshly picked or re-granted) handle: link source, load any
488
- // sidecar, and remember it for next time. Shared by connect and restore.
493
+ // Adopt a freshly picked or re-granted handle. Link the source, load any
494
+ // sidecar, and remember the handle for next time. Both connect and restore
495
+ // call this.
489
496
  async function adoptFolder(handle) {
490
497
  dirHandle = handle;
491
- // read page source → enables source line/column resolution
498
+ // read the page source → the tool can then resolve source line/column
492
499
  try {
493
500
  var fh = await dirHandle.getFileHandle(cfg.target);
494
501
  sourceText = await (await fh.getFile()).text();
495
502
  state.annotations.forEach(function (a) { a.source = locateInSource(a); });
496
- } catch (e) { sourceText = null; setStatus("Connected, but '" + cfg.target + "' not found in folder — line numbers unavailable."); }
503
+ } catch (e) { sourceText = null; setStatus("Connected, but the folder has no '" + cfg.target + "'. Line numbers are unavailable."); }
497
504
  // load an existing sidecar if present
498
505
  try {
499
506
  var sh = await dirHandle.getFileHandle(SIDECAR);
@@ -503,12 +510,13 @@
503
510
  rememberedHandle = null;
504
511
  updateConnectLabel();
505
512
  persistLocal(); renderPanel(); renderHighlights();
506
- setStatus("Connected. Saving to " + SIDECAR + (sourceText ? " · source linked" : ""));
513
+ setStatus("Connected. Saves to " + SIDECAR + (sourceText ? " · source linked" : ""));
507
514
  }
508
515
 
509
516
  async function connectFolder() {
510
- // Prefer a folder remembered from a prior session: re-granting permission is
511
- // a single click (this click IS the required user gesture), no picker.
517
+ // Prefer a folder remembered from a prior session. A permission re-grant
518
+ // takes a single click (this click IS the required user gesture). The
519
+ // picker does not open.
512
520
  if (rememberedHandle) {
513
521
  try {
514
522
  var perm = await rememberedHandle.requestPermission({ mode: "readwrite" });
@@ -524,10 +532,11 @@
524
532
  }
525
533
  }
526
534
 
527
- // On load, try to restore a previously connected folder. queryPermission needs
528
- // no gesture; if it's still "granted" we reconnect silently. If it's "prompt",
529
- // we keep the handle so the next "Connect folder" click reconnects with one
530
- // grant dialog (no picker). Handles cleared/denied storage are ignored.
535
+ // On load, try to restore a previously connected folder. queryPermission
536
+ // needs no gesture. If it is still "granted", we reconnect silently. If it
537
+ // is "prompt", we keep the handle. The next "Connect folder" click then
538
+ // reconnects with one grant dialog (no picker). We ignore a handle from
539
+ // cleared or denied storage.
531
540
  function restoreFolder() {
532
541
  idbGet(cfg.target).then(function (handle) {
533
542
  if (!handle || typeof handle.queryPermission !== "function") return;
@@ -535,7 +544,7 @@
535
544
  if (perm === "granted") { adoptFolder(handle); }
536
545
  else {
537
546
  rememberedHandle = handle; updateConnectLabel();
538
- if (review) setStatus("Folder '" + cfg.target + "' remembered click Reconnect folder.");
547
+ if (review) setStatus("Folder '" + cfg.target + "' remembered. Click Reconnect folder.");
539
548
  }
540
549
  }).catch(function () {});
541
550
  });
@@ -553,7 +562,7 @@
553
562
  } catch (e) { setStatus("Disk write failed (" + e.name + "). Downloaded instead."); }
554
563
  }
555
564
  download(SIDECAR, json);
556
- setStatus("Downloaded " + SIDECAR + " move it next to the deck.");
565
+ setStatus("Downloaded " + SIDECAR + ". Move it next to the deck.");
557
566
  }
558
567
 
559
568
  async function loadDisk() {
@@ -669,7 +678,7 @@
669
678
  // Supply page source to resolve source line/column without the folder picker.
670
679
  setSource: function (text) { sourceText = text; state.annotations.forEach(function (a) { a.source = locateInSource(a); }); persistLocal(); renderPanel(); },
671
680
  get state() { return state; },
672
- // for automation/testing:
681
+ // for automation and tests:
673
682
  _capture: captureSelection,
674
683
  _confirm: function (note) { if (pending) { ui.note.value = note || ""; confirmPending(); } }
675
684
  };
@@ -1,21 +1,25 @@
1
1
  ---
2
2
  name: deck-summarize
3
- description: Synthesize PowerPoint decks into engineer-friendly markdown briefs covering Jobs-To-Be-Done, dependencies, and synthetic data needs. Use when the user asks to break down, summarize, or make sense of a slide deck (.pptx) for engineering work.
3
+ description: Synthesize PowerPoint decks into engineer-friendly markdown briefs. Each brief covers Jobs-To-Be-Done, dependencies, and synthetic data needs. Use when the user asks to break down, summarize, or make sense of a slide deck (.pptx) for engineering work.
4
4
  compatibility: Node.js only — no external dependencies.
5
5
  ---
6
6
 
7
7
  # Synthesize Deck
8
8
 
9
+ Write tier: `0-Draft` (promotion is a human act)
10
+ Frontmatter: none
11
+
9
12
  Turn messy PowerPoint specification decks into clear, actionable markdown briefs
10
- that forward deployed engineers can build from. Strip business jargon and focus
11
- on what matters: what needs to be built, what blocks progress, what data is
12
- needed to start prototyping.
13
+ that forward deployed engineers can build from. Strip business jargon. Focus on
14
+ what matters: what the team must build, what blocks progress, and what data you
15
+ need to start a prototype.
13
16
 
14
17
  ## Trigger
15
18
 
16
- The user asks to summarize, synthesize, or break down a `.pptx` deck; make sense
17
- of a specification or proposal deck for engineering; create an engineering brief
18
- from a slide deck; or understand what a project deck is actually asking for.
19
+ Run when the user asks to summarize, synthesize, or break down a `.pptx` deck.
20
+ Run when the user wants to make sense of a specification or proposal deck for
21
+ engineering. Run when the user asks for an engineering brief from a slide deck.
22
+ Run when the user wants to understand what a project deck really asks for.
19
23
 
20
24
  ## Prerequisites
21
25
 
@@ -30,21 +34,23 @@ from a slide deck; or understand what a project deck is actually asking for.
30
34
  ## Outputs
31
35
 
32
36
  - One markdown file per deck (or one combined file for related decks) written to
33
- `Knowledge/Projects/{Project Name} - Engineering Brief.md`.
37
+ `0-Draft/{Project Name} - Engineering Brief.md`. The human promotes a
38
+ finished brief into `3-Team/Projects/`.
34
39
 
35
40
  <do_confirm_checklist goal="Verify the brief is engineer-actionable before
36
41
  delivering">
37
42
 
38
- - [ ] No invented requirements every claim traces to the deck.
39
- - [ ] Plain language; no marketing jargon (no "synergize", "orchestrate",
43
+ - [ ] No invented requirements. Every claim traces to the deck.
44
+ - [ ] Plain language, with no marketing jargon (no "synergize", "orchestrate",
40
45
  "leverage", "intelligent \_\_\_ hub").
41
- - [ ] JTBDs describe the user's goal, not the proposed solution; one job per
42
- statement; each includes the "so that".
43
- - [ ] Data dependencies table flags blockers (missing, locked, compliance).
46
+ - [ ] JTBDs describe the user's goal. They do not describe the proposed
47
+ solution. One job per statement. Each job includes the "so that".
48
+ - [ ] The data-dependencies table flags blockers (missing, locked, compliance).
44
49
  - [ ] Synthetic data needs name fields, ranges, edge cases, and volume.
45
50
  - [ ] Gaps and open questions list what an engineer would notice missing.
46
- - [ ] Brief is under 2,000 lines a summary, not a transcription.
47
- - [ ] Knowledge base looked up for mentioned people, orgs, and projects.
51
+ - [ ] The brief is under 2,000 lines. It summarizes the deck. It does not
52
+ transcribe it.
53
+ - [ ] You looked up mentioned people, orgs, and projects in the knowledge base.
48
54
 
49
55
  </do_confirm_checklist>
50
56
 
@@ -65,20 +71,21 @@ For multiple decks, pass all files at once. To save the extracted text:
65
71
  node .claude/skills/deck-summarize/scripts/extract-pptx.mjs "$FILE_PATH" -o /tmp/deck_extract.txt
66
72
  ```
67
73
 
68
- Read all extracted text before continuing.
74
+ Read all extracted text before you continue.
69
75
 
70
76
  ### 2. Identify the core problem
71
77
 
72
- Plain-language answers to: what process exists today; what's broken, slow, or
73
- painful; who suffers. Don't restate the deck's framing.
78
+ Give plain-language answers. Name the process that exists today. Name what is
79
+ broken, slow, or painful. Name who suffers. Don't restate how the deck frames
80
+ the problem.
74
81
 
75
82
  ### 3. Extract Jobs-To-Be-Done
76
83
 
77
84
  Format: `When [situation], I need to [action], so that [outcome].`
78
85
 
79
- Group by user role/persona. One job per statement. Use the user's goal, not the
80
- proposed solution. A job should still make sense if you discard the deck's
81
- solution. Don't restate the deck's feature list as jobs and don't reuse its
86
+ Group by user role/persona. One job per statement. Use the user's goal. Do not
87
+ use the proposed solution. A job should still make sense if you discard the
88
+ deck's solution. Don't restate the deck's feature list as jobs. Don't reuse its
82
89
  jargon.
83
90
 
84
91
  ### 4. Map dependencies
@@ -87,53 +94,56 @@ jargon.
87
94
  [references/brief-template.md](references/brief-template.md#data-dependencies-table).
88
95
  Flag blockers (missing, locked, unstructured, compliance).
89
96
 
90
- **4b. Systems & integrations** — every external system/API/platform: what the
91
- integration does, read-only vs read-write, API vs manual/scraping, access
92
- confirmed?
97
+ **4b. Systems & integrations** — list every external system, API, and platform.
98
+ For each one, say what the integration does. Say whether it is read-only or
99
+ read-write. Say whether access runs through an API or through manual work or
100
+ scraping. Say whether someone confirmed access.
93
101
 
94
- **4c. People & approvals** — approvals, reviews, or co-creation needed before
95
- engineering can proceed. Flag long lead-time items (legal, compliance, vendor
96
- contracts).
102
+ **4c. People & approvals** — list the approvals, reviews, or co-creation that
103
+ must happen before engineering can proceed. Flag long lead-time items (legal,
104
+ compliance, vendor contracts).
97
105
 
98
106
  ### 5. Define synthetic-data needs
99
107
 
100
108
  For each core feature/use case:
101
109
 
102
110
  - **Generate:** entity, key fields and types, realistic value ranges and
103
- distributions, edge cases that matter, volume for meaningful testing.
111
+ distributions, edge cases that matter, volume for a meaningful test.
104
112
  - **Simulate:** workflows and state transitions, time-series patterns,
105
113
  multi-actor interactions, error/failure modes.
106
- - **Format:** prefer CSV/JSON; PII-shaped fake data only never real PII;
107
- include happy-path _and_ adversarial examples; consider ML training/eval data.
114
+ - **Format:** prefer CSV/JSON. Use PII-shaped fake data only. Never use real
115
+ PII. Include happy-path _and_ adversarial examples. Consider ML training and
116
+ eval data.
108
117
 
109
118
  ### 6. Translate the proposed solution
110
119
 
111
- Describe the build in engineering terms: components, what each does in plain
112
- terms, how they connect, end-to-end data flow, AI/ML capabilities and what
113
- they're actually doing. Translate branded names — e.g. "Intelligent Intake Hub"
114
- "OCR + NLP pipeline that extracts structured fields from scanned enrollment
115
- forms"; "Copay Guardian" "Anomaly detection on weekly claims data".
120
+ Describe the build in engineering terms. Cover the components and what each does
121
+ in plain terms. Cover how they connect and the end-to-end data flow. Cover the
122
+ AI/ML capabilities and what they actually do. Translate branded names. For
123
+ example, "Intelligent Intake Hub"
124
+ "OCR + NLP pipeline that extracts structured fields from scanned enrollment
125
+ forms". "Copay Guardian" → "Anomaly detection on weekly claims data".
116
126
 
117
127
  ### 7. Identify what's missing
118
128
 
119
- Call out: features without clear data sources; AI capabilities without a
120
- training-data strategy; assumed integrations; user workflows that skip edge
121
- cases; metrics promised without measurement infrastructure; timeline–scope
122
- mismatches.
129
+ Call out features without clear data sources. Call out AI capabilities without a
130
+ training-data strategy. Call out assumed integrations. Call out user workflows
131
+ that skip edge cases. Call out metrics promised without measurement
132
+ infrastructure. Call out timeline–scope mismatches.
123
133
 
124
134
  ### 8. Assemble the brief
125
135
 
126
136
  Use the structure in
127
137
  [references/brief-template.md](references/brief-template.md). Save to
128
- `Knowledge/Projects/{Project Name} - Engineering Brief.md`. For multiple related
138
+ `0-Draft/{Project Name} - Engineering Brief.md`. For multiple related
129
139
  decks, write one combined brief with shared dependencies.
130
140
 
131
141
  ### 9. Save and report
132
142
 
133
- Tell the user the file path and give a 3-sentence project summary.
143
+ Tell the user the file path. Give a 3-sentence project summary.
134
144
 
135
- ## Writing style
145
+ ## Style
136
146
 
137
- Plain language, concrete over abstract, honest about uncertainty, opinionated
138
- when helpful (flag dependency or timeline risks), short sentences. Engineers
139
- scan, they don't read essays.
147
+ Use plain language. Choose the concrete over the abstract. Be honest about
148
+ uncertainty. Be opinionated when it helps, and flag dependency or timeline
149
+ risks. Keep sentences short. Engineers scan. They don't read essays.
@@ -1,7 +1,7 @@
1
1
  # Engineering Brief Template
2
2
 
3
3
  Reference template for `deck-summarize` Step 8. Save the assembled brief to
4
- `Knowledge/Projects/{Project Name} - Engineering Brief.md`.
4
+ `0-Draft/{Project Name} - Engineering Brief.md`.
5
5
 
6
6
  ```markdown
7
7
  ---
@@ -76,9 +76,10 @@ what's realistic and what depends on what}
76
76
 
77
77
  ## Data dependencies table
78
78
 
79
- For Step 4a, fill in this table. Flag any data that doesn't seem to exist yet,
80
- is locked behind inaccessible systems, is unstructured and would need heavy
81
- preprocessing, or carries compliance/privacy constraints.
79
+ For Step 4a, fill in this table. Flag any data that doesn't seem to exist yet.
80
+ Flag data that is locked behind inaccessible systems. Flag unstructured data
81
+ that would need heavy preprocessing. Flag data that carries compliance or
82
+ privacy constraints.
82
83
 
83
84
  | Data | Where It Lives | Format | Access | Blocker? |
84
85
  | ----------- | -------------------------- | ---------------------------------- | ------------------------------- | -------------- |
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * Extract text from PowerPoint (.pptx) slides.
4
4
  *
5
- * PPTX files are ZIP archives containing XML. This script extracts all text
6
- * from each slide and outputs it as structured markdown with slide headings.
7
- * Handles multiple files and outputs to stdout or a file.
5
+ * A PPTX file is a ZIP archive that holds XML. This script extracts all text
6
+ * from each slide. It outputs the text as structured markdown with slide
7
+ * headings. It handles multiple files. It writes to stdout or to a file.
8
8
  *
9
9
  * Usage:
10
10
  * node scripts/extract-pptx.mjs <path-to-pptx>
@@ -12,7 +12,8 @@
12
12
  * node scripts/extract-pptx.mjs file1.pptx file2.pptx
13
13
  * node scripts/extract-pptx.mjs -h|--help
14
14
  *
15
- * No external dependencies uses Node.js built-in modules only.
15
+ * The script needs no external dependencies. It uses Node.js built-in
16
+ * modules only.
16
17
  */
17
18
 
18
19
  import { readFileSync, writeFileSync } from "node:fs";
@@ -26,7 +27,7 @@ Usage:
26
27
  node scripts/extract-pptx.mjs -h|--help
27
28
 
28
29
  Options:
29
- -o <path> Write output to file instead of stdout
30
+ -o <path> Write output to a file instead of stdout
30
31
  -h, --help Show this help
31
32
 
32
33
  Output: Markdown-formatted text with ## Slide N headings per slide.
@@ -136,8 +137,8 @@ function readEntry(buf, entry) {
136
137
  }
137
138
 
138
139
  /**
139
- * Extract all text content from slide XML using the DrawingML namespace.
140
- * Matches <a:t>text</a:t> elements used by PowerPoint.
140
+ * Extract all text content from slide XML with the DrawingML namespace.
141
+ * The pattern matches the <a:t>text</a:t> elements that PowerPoint uses.
141
142
  * @param {string} xml
142
143
  * @returns {string[]}
143
144
  */
@@ -1,13 +1,17 @@
1
1
  ---
2
2
  name: doc-collab
3
- description: Help the user create, edit, and refine documents in the knowledge base. Use when the user asks to create, edit, review, or collaborate on a document. Supports direct editing and approval-based workflows with knowledge base context for entity references.
3
+ description: Help the user create, edit, and refine documents in the knowledge base. Use when the user asks to create, edit, review, or collaborate on a document. Supports direct edits and approval-based workflows, with context from the knowledge base for entity references.
4
4
  ---
5
5
 
6
6
  # Document Collaboration
7
7
 
8
- Help the user create, edit, and refine documents in the knowledge base. Supports
9
- direct editing and approval-based workflows. Always uses knowledge base context
10
- for entity references.
8
+ Write tier: `0-Draft` (working copies; the human promotes)
9
+ Frontmatter: none
10
+
11
+ Help the user create, edit, and refine documents in the knowledge base. This
12
+ skill supports direct edits and approval-based workflows. It always uses context
13
+ from the knowledge base for entity references. New documents start in
14
+ `0-Draft/`. The human promotes a finished document into its tier.
11
15
 
12
16
  ## Trigger
13
17
 
@@ -15,62 +19,63 @@ Run when the user asks to create, edit, review, or collaborate on a document.
15
19
 
16
20
  ## Prerequisites
17
21
 
18
- - Knowledge base directory exists
22
+ - The KB root exists with its tier directories
19
23
 
20
24
  ## Inputs
21
25
 
22
- - User's editing instructions
23
- - `Knowledge/` — existing notes and documents
26
+ - The user's edit instructions
27
+ - The tier directories — existing notes and documents
24
28
  - Document to edit (user-specified or searched)
25
29
 
26
30
  ## Outputs
27
31
 
28
- - Created or modified documents in `Knowledge/` or user-specified location
32
+ - New documents in `0-Draft/` (or a user-specified location)
33
+ - Modified documents in the tier where the user points
29
34
 
30
35
  ---
31
36
 
32
37
  ## First: Ask About Edit Mode
33
38
 
34
- **Before doing anything, ask:** "Should I make edits directly, or show you
39
+ **Ask before you do anything:** "Should I make edits directly, or show you
35
40
  changes first for approval?"
36
41
 
37
- - **Direct mode:** Make edits immediately, confirm after
38
- - **Approval mode:** Show proposed changes, wait for approval
42
+ - **Direct mode:** Make edits immediately, then confirm
43
+ - **Approval mode:** Show proposed changes, then wait for approval
39
44
 
40
45
  Follow their choice for the entire session.
41
46
 
42
47
  ## Core Principles
43
48
 
44
- - **Re-read before every response** — the user may have edited the file manually
49
+ - **Re-read before every response** — the user may edit the file manually
45
50
  - **Be concise** — don't propose outlines unless asked
46
- - **Don't assume** — if unclear, ask ONE simple question
47
- - **Use knowledge context** — search knowledge base for mentioned entities, use
48
- `[[wiki-links]]`
51
+ - **Don't assume** — if something is unclear, ask ONE simple question
52
+ - **Use knowledge context** — search the knowledge base for mentioned entities,
53
+ then use `[[wiki-links]]`
49
54
 
50
- ## Processing Flow
55
+ ## Process Flow
51
56
 
52
57
  ### Step 1: Find the Document
53
58
 
54
- Search thoroughly before saying a document doesn't exist:
59
+ Search thoroughly before you say a document doesn't exist:
55
60
 
56
61
  ```bash
57
- rg -l -i "roadmap" Knowledge/
58
- find Knowledge/ -iname "*roadmap*" 2>/dev/null
62
+ rg -l -i "roadmap" [0-9]-*/
63
+ find [0-9]-*/ -iname "*roadmap*" 2>/dev/null
59
64
  ```
60
65
 
61
- **If found:** Read it and proceed. **If NOT found:** Ask "I couldn't find
66
+ **If found:** Read it. Then proceed. **If NOT found:** Ask "I couldn't find
62
67
  [name]. Shall I create it?"
63
68
 
64
- **Creating new documents:**
69
+ **Create a new document:**
65
70
 
66
- 1. Ask: "Shall I create Knowledge/[name].md?"
67
- 2. Create with just a title — don't pre-populate with structure
71
+ 1. Ask: "Shall I create 0-Draft/[name].md?"
72
+ 2. Create it with just a title. Don't pre-populate it with structure
68
73
  3. Ask: "What would you like in this?"
69
74
 
70
75
  ### Step 2: Understand the Request
71
76
 
72
- **NEVER make unsolicited edits.** If the user hasn't specified what to change,
73
- ask: "What would you like to change?"
77
+ **NEVER make unsolicited edits.** If the user did not say what to change, ask:
78
+ "What would you like to change?"
74
79
 
75
80
  Types of requests:
76
81
 
@@ -83,8 +88,8 @@ Types of requests:
83
88
 
84
89
  ### Step 3: Execute Changes
85
90
 
86
- Make targeted edits change only what's needed. Preserve the user's voice and
87
- don't reorganize unless asked.
91
+ Make targeted edits. Change only what's needed. Preserve the user's voice. Don't
92
+ reorganize unless the user asks.
88
93
 
89
94
  ### Step 4: Confirm and Continue
90
95
 
@@ -92,14 +97,14 @@ don't reorganize unless asked.
92
97
  - Ask: "What's next?"
93
98
  - Don't read back the entire document unless asked
94
99
 
95
- ## Searching Knowledge for Context
100
+ ## Search the Graph for Context
96
101
 
97
102
  When the user mentions people, companies, or projects:
98
103
 
99
104
  ```bash
100
- rg -l "Name" Knowledge/
101
- cat "Knowledge/People/Person.md"
102
- cat "Knowledge/Organizations/Company.md"
105
+ rg -l "Name" [0-9]-*/
106
+ cat "3-Team/People/Person.md"
107
+ cat "3-Team/Organizations/Company.md"
103
108
  ```
104
109
 
105
110
  Use `[[wiki-links]]` to connect to other notes. Only link to notes that exist.
@@ -107,6 +112,6 @@ Use `[[wiki-links]]` to connect to other notes. Only link to notes that exist.
107
112
  ## Constraints
108
113
 
109
114
  - Match the user's tone and style
110
- - Make surgical edits change only what's needed
111
- - Preserve the user's voice don't reorganize unless asked
112
- - Only link to notes that exist use `[[Person Name]]` for existing notes
115
+ - Make surgical edits that change only what's needed
116
+ - Preserve the user's voice, and don't reorganize unless the user asks
117
+ - Only link to notes that exist, and use `[[Person Name]]` for existing notes