@holmes-lab/holmes-kit 0.25.1 → 0.26.1

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 (50) hide show
  1. package/CHANGELOG.md +133 -0
  2. package/README.md +10 -3
  3. package/dist/.build-id +1 -1
  4. package/dist/holmes/cli/approve.js +7 -26
  5. package/dist/holmes/cli/doctor.js +53 -10
  6. package/dist/holmes/cli/index.js +8 -1
  7. package/dist/holmes/cli/release-docs.d.ts +27 -0
  8. package/dist/holmes/cli/release-docs.js +45 -0
  9. package/dist/holmes/config/config.d.ts +11 -0
  10. package/dist/holmes/config/config.js +11 -1
  11. package/dist/holmes/cpg/cycle-observation.d.ts +13 -0
  12. package/dist/holmes/cpg/cycle-observation.js +25 -2
  13. package/dist/holmes/cpg/cycle-report.d.ts +35 -0
  14. package/dist/holmes/cpg/cycle-report.js +74 -0
  15. package/dist/holmes/cpg/forbidden-edge-report.d.ts +20 -0
  16. package/dist/holmes/cpg/forbidden-edge-report.js +31 -0
  17. package/dist/holmes/cpg/forbidden-edges.d.ts +85 -2
  18. package/dist/holmes/cpg/forbidden-edges.js +135 -2
  19. package/dist/holmes/cpg/import-resolver.d.ts +12 -0
  20. package/dist/holmes/cpg/import-resolver.js +215 -0
  21. package/dist/holmes/cpg/language-capability.d.ts +14 -0
  22. package/dist/holmes/cpg/language-capability.js +37 -13
  23. package/dist/holmes/cpg/proposed-content.d.ts +7 -1
  24. package/dist/holmes/cpg/proposed-content.js +7 -0
  25. package/dist/holmes/governance/approval-queue.d.ts +33 -0
  26. package/dist/holmes/governance/approval-queue.js +85 -0
  27. package/dist/holmes/hooks/pre-tool-use.js +8 -1
  28. package/dist/holmes/hooks/session-start.js +39 -0
  29. package/dist/holmes/hooks/stop.d.ts +38 -2
  30. package/dist/holmes/hooks/stop.js +169 -50
  31. package/dist/holmes/mcp/handlers/entity-integration.js +5 -8
  32. package/dist/holmes/mcp/handlers/entity-renumber.js +4 -5
  33. package/dist/holmes/mcp/handlers/spec-authoring.js +9 -1
  34. package/dist/holmes/mcp/handlers/spec-lifecycle.d.ts +7 -5
  35. package/dist/holmes/mcp/handlers/spec-lifecycle.js +15 -2
  36. package/dist/holmes/mcp/handlers.d.ts +7 -5
  37. package/dist/holmes/project/report-briefing.d.ts +48 -0
  38. package/dist/holmes/project/report-briefing.js +70 -0
  39. package/dist/holmes/project/resolved-reports.d.ts +20 -0
  40. package/dist/holmes/project/resolved-reports.js +7 -0
  41. package/dist/holmes/project/root.js +11 -1
  42. package/dist/holmes/rtm/rtm-builder.js +6 -141
  43. package/dist/holmes/spec/id-collision.d.ts +98 -0
  44. package/dist/holmes/spec/id-collision.js +149 -1
  45. package/dist/holmes/spec/remote-spec-refs.d.ts +16 -0
  46. package/dist/holmes/spec/remote-spec-refs.js +148 -0
  47. package/dist/holmes/spec/renumber.d.ts +12 -2
  48. package/dist/holmes/spec/renumber.js +25 -6
  49. package/package.json +1 -1
  50. package/playbooks/publish/PLAYBOOK.md +18 -0
@@ -489,9 +489,17 @@ function readSourcesForRenumber(projectRoot) {
489
489
  }
490
490
  return out;
491
491
  }
492
- /** Spec documents as the planner needs them, with store-relative POSIX paths. */
492
+ /**
493
+ * Spec documents as the planner needs them, with store-relative POSIX paths.
494
+ *
495
+ * @implements A-SPEC-699 — `unreadable` exists because the absence of it cost a day. A `.md` whose
496
+ * frontmatter would not parse used to be skipped by a bare `continue`, so "this store holds no
497
+ * specs" and "I could not read any of these specs" reached the caller as the same answer. They are
498
+ * different facts and the caller has to be able to tell them apart.
499
+ */
493
500
  function readSpecsForRenumber(specsRoot) {
494
501
  const out = [];
502
+ const unreadable = [];
495
503
  for (const abs of walk(specsRoot).concat((function md(dir, acc = []) {
496
504
  let entries;
497
505
  try {
@@ -511,21 +519,32 @@ function readSpecsForRenumber(specsRoot) {
511
519
  })(specsRoot))) {
512
520
  if (!abs.endsWith('.md'))
513
521
  continue;
522
+ const rel = path.relative(specsRoot, abs).split(path.sep).join('/');
514
523
  let text;
515
524
  try {
516
525
  text = fs.readFileSync(abs, 'utf8');
517
526
  }
518
527
  catch {
528
+ unreadable.push(rel);
519
529
  continue;
520
530
  }
521
- const fm = /^---\n([\s\S]*?)\n---/.exec(text);
522
- if (!fm)
531
+ // @implements A-SPEC-699 — `\r?\n`, not `\n`. A checkout with core.autocrlf=true holds every
532
+ // spec as CRLF, and an LF-only fence matched none of them.
533
+ const fm = /^---\r?\n([\s\S]*?)\r?\n---/.exec(text);
534
+ if (!fm) {
535
+ unreadable.push(rel);
523
536
  continue;
537
+ }
524
538
  const field = (k) => (new RegExp(`^${k}:[ \\t]*(.+)$`, 'm').exec(fm[1])?.[1] ?? '').trim();
525
539
  const id = field('id');
526
- if (id === '')
540
+ if (id === '') {
541
+ unreadable.push(rel);
527
542
  continue;
528
- const deps = (/^depends_on:\n((?:[ \t]*-[ \t]*.+\n?)+)/m.exec(fm[1])?.[1] ?? '')
543
+ }
544
+ // @implements A-SPEC-699 — the fence is not the only LF-only site. Fixing it alone would leave
545
+ // this one matching nothing on CRLF, so every family would come back with no edges and both
546
+ // unsealOrder and approveOrder would arrive empty: the same silence, one layer down.
547
+ const deps = (/^depends_on:\r?\n((?:[ \t]*-[ \t]*.+\r?\n?)+)/m.exec(fm[1])?.[1] ?? '')
529
548
  .split('\n').map((l) => l.replace(/^[ \t]*-[ \t]*/, '').trim()).filter((x) => x !== '');
530
549
  const inline = /^depends_on:[ \t]*\[(.*)\]/m.exec(fm[1])?.[1];
531
550
  out.push({
@@ -536,5 +555,5 @@ function readSpecsForRenumber(specsRoot) {
536
555
  body: text,
537
556
  });
538
557
  }
539
- return out;
558
+ return { specs: out, unreadable };
540
559
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "//": "@implements A-SPEC-209",
3
3
  "name": "@holmes-lab/holmes-kit",
4
- "version": "0.25.1",
4
+ "version": "0.26.1",
5
5
  "description": "Holmes-Kit — deterministic Agentic Software Engineering (ASE) harness with causal traceability (spec chain + D-CPG + RTM + phase guardrail)",
6
6
  "main": "dist/holmes/mcp/server.js",
7
7
  "types": "dist/holmes/mcp/server.d.ts",
@@ -58,6 +58,24 @@ README 에 현재형으로 남은 사고, 그리고 **0.16.0 — 신기능 3건
58
58
 
59
59
  ---
60
60
 
61
+ ### 2.6단계: 해결된 현장 보고 기록 (Resolved Field Reports) — 소비자에게 닫히는 고리
62
+
63
+ 소비자가 `holmes-kit report` 로 보고한 결함을 이번 릴리스가 고쳤다면, 그 **fingerprint 를
64
+ `src/holmes/project/resolved-reports.ts` 에 기록**한다. 그래야 그 소비자의 다음 세션에서
65
+ "당신이 보고한 것이 고쳐졌다"가 한 번 발화된다(A-SPEC-687).
66
+
67
+ - fingerprint 는 GitHub 이슈 본문에 이미 실려 있다(`fingerprint: <16 hex>`).
68
+ - `{ fingerprint, version, note }` — version 은 지금 자르는 릴리스, note 는 사람이 읽을 한 문장.
69
+ - 해결한 보고가 없으면 아무것도 하지 않는다. 빈 목록은 정상이고, 브리핑은 침묵한다.
70
+
71
+ > [!NOTE]
72
+ > 이 단계가 **명령이 아니라 의식 안에 있는 이유**: 안 도는 명령은 목록을 비워두고 브리핑을
73
+ > 영구히 침묵시킨다. 이 저장소에는 만들어만 지고 소비되지 않은 계측기가 여섯 개 기록돼 있고,
74
+ > 지식이 있는 순간(유지보수자가 이슈를 닫는 때)과 이미 도는 절차에 붙이는 것이 그 일곱 번째를
75
+ > 막는 유일한 방법이다.
76
+
77
+ ---
78
+
61
79
  ### 3단계: 릴리스 자율 판정 (Release Autonomy) — auto 또는 HITL
62
80
  `releaseAutonomy(specsSinceTag, versionBump, process.env, root, now)` 로 이번 릴리스를 분류한다
63
81
  (`versionBumpKind(현재버전, 대상버전)` 으로 범프 종류 산출):