@open-agent-toolkit/cli 0.3.21 → 0.3.23

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 (130) hide show
  1. package/assets/bundle-metadata.json +1 -1
  2. package/assets/docs/docs-tooling/add-docs-to-a-repo.md +3 -9
  3. package/assets/docs/reference/cli-reference.md +8 -3
  4. package/assets/docs/reference/configuration.md +3 -0
  5. package/assets/docs/reference/oat-directory-structure.md +1 -1
  6. package/assets/docs/reference/project-artifacts.md +141 -2
  7. package/assets/docs/reference/project-state-machine.md +2 -2
  8. package/assets/docs/workflows/advanced/autonomy.md +29 -12
  9. package/assets/docs/workflows/advanced/cursor-cloud.md +20 -6
  10. package/assets/docs/workflows/advanced/workflow-gates.md +9 -0
  11. package/assets/docs/workflows/projects/closeout/closeout-skills.md +24 -5
  12. package/assets/docs/workflows/projects/closeout/retro.md +6 -2
  13. package/assets/docs/workflows/projects/execution/implementation-execution.md +18 -4
  14. package/assets/docs/workflows/projects/execution/index.md +1 -1
  15. package/assets/docs/workflows/projects/execution/picking-up-projects.md +3 -2
  16. package/assets/docs/workflows/projects/execution/project-log.md +100 -11
  17. package/assets/docs/workflows/projects/lifecycle.md +3 -3
  18. package/assets/docs/workflows/projects/reviews/index.md +18 -0
  19. package/assets/public-package-versions.json +4 -4
  20. package/assets/skills/oat-cursor-cloud-projects/SKILL.md +12 -8
  21. package/assets/skills/oat-cursor-cloud-projects/references/cursor-cloud-mechanics.md +63 -2
  22. package/assets/skills/oat-docs/SKILL.md +14 -28
  23. package/assets/skills/oat-docs-analyze/SKILL.md +4 -2
  24. package/assets/skills/oat-docs-analyze/references/legacy-scaffold-checks.md +16 -0
  25. package/assets/skills/oat-docs-apply/SKILL.md +2 -2
  26. package/assets/skills/oat-docs-authoring/SKILL.md +2 -2
  27. package/assets/skills/oat-docs-authoring/references/lifecycle-boundaries.md +1 -2
  28. package/assets/skills/oat-docs-authoring/references/mkdocs-to-oat-fumadocs-refactor-guide.md +73 -0
  29. package/assets/skills/oat-docs-bootstrap/SKILL.md +44 -310
  30. package/assets/skills/oat-project-autonomous/SKILL.md +88 -26
  31. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +1 -1
  32. package/assets/skills/oat-project-brief/SKILL.md +1 -1
  33. package/assets/skills/oat-project-brief/references/brief-contract.md +33 -27
  34. package/assets/skills/oat-project-brief/references/docs/autonomy-contract.md +1 -1
  35. package/assets/skills/oat-project-complete/SKILL.md +142 -25
  36. package/assets/skills/oat-project-complete-auto/SKILL.md +4 -4
  37. package/assets/skills/oat-project-dispatch-subagents/SKILL.md +10 -5
  38. package/assets/skills/oat-project-document/SKILL.md +1 -1
  39. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +1 -1
  40. package/assets/skills/oat-project-goal/SKILL.md +63 -15
  41. package/assets/skills/oat-project-goal/references/docs/autonomy-contract.md +1 -1
  42. package/assets/skills/oat-project-implement/SKILL.md +6 -6
  43. package/assets/skills/oat-project-implement/references/completion-and-closeout.md +28 -7
  44. package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +10 -5
  45. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +1 -1
  46. package/assets/skills/oat-project-implement/references/phase-execution.md +23 -9
  47. package/assets/skills/oat-project-implement/references/plan-and-resume.md +4 -4
  48. package/assets/skills/oat-project-lite/SKILL.md +1 -1
  49. package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +1 -1
  50. package/assets/skills/oat-project-pr-final/SKILL.md +6 -1
  51. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +1 -1
  52. package/assets/skills/oat-project-pr-progress/SKILL.md +6 -1
  53. package/assets/skills/oat-project-quick-start/SKILL.md +1 -1
  54. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +1 -1
  55. package/assets/skills/oat-project-reconcile/SKILL.md +13 -19
  56. package/assets/skills/oat-project-retro/SKILL.md +5 -2
  57. package/assets/skills/oat-project-retro/references/evidence-and-lanes.md +9 -3
  58. package/assets/skills/oat-project-review-provide/SKILL.md +28 -3
  59. package/assets/skills/oat-project-review-receive/SKILL.md +32 -18
  60. package/assets/skills/oat-project-review-receive-remote/SKILL.md +10 -6
  61. package/assets/skills/oat-project-revise/SKILL.md +9 -2
  62. package/assets/skills/oat-project-summary/SKILL.md +166 -37
  63. package/assets/skills/oat-worktree-bootstrap-auto/SKILL.md +3 -3
  64. package/assets/templates/docs-app-fuma/docs/contributing.md +6 -0
  65. package/assets/templates/docs-app-fuma/docs/getting-started.md +1 -1
  66. package/assets/templates/docs-app-fuma/next.config.js +5 -1
  67. package/assets/templates/implementation-brief.md +5 -36
  68. package/assets/templates/implementation.md +11 -81
  69. package/assets/templates/project-log.md +2 -31
  70. package/assets/templates/project-retro.md +4 -1
  71. package/assets/templates/summary.md +13 -5
  72. package/dist/commands/config/index.d.ts.map +1 -1
  73. package/dist/commands/config/index.js +44 -1
  74. package/dist/commands/docs/analyze.js +1 -1
  75. package/dist/commands/docs/apply.js +1 -1
  76. package/dist/commands/docs/init/scaffold.d.ts.map +1 -1
  77. package/dist/commands/docs/init/scaffold.js +35 -2
  78. package/dist/commands/project/archive/archive-utils.d.ts +205 -8
  79. package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
  80. package/dist/commands/project/archive/archive-utils.js +708 -44
  81. package/dist/commands/project/archive/index.d.ts.map +1 -1
  82. package/dist/commands/project/archive/index.js +1 -0
  83. package/dist/commands/project/archive/push-runner.d.ts +9 -1
  84. package/dist/commands/project/archive/push-runner.d.ts.map +1 -1
  85. package/dist/commands/project/archive/push-runner.js +56 -18
  86. package/dist/commands/project/archive/sync-runner.d.ts +28 -0
  87. package/dist/commands/project/archive/sync-runner.d.ts.map +1 -1
  88. package/dist/commands/project/archive/sync-runner.js +44 -22
  89. package/dist/commands/project/complete-state/index.d.ts.map +1 -1
  90. package/dist/commands/project/complete-state/index.js +45 -0
  91. package/dist/commands/project/dispatch/index.d.ts.map +1 -1
  92. package/dist/commands/project/dispatch/index.js +24 -2
  93. package/dist/commands/project/dispatch/record.d.ts +54 -1
  94. package/dist/commands/project/dispatch/record.d.ts.map +1 -1
  95. package/dist/commands/project/dispatch/record.js +229 -1
  96. package/dist/commands/project/index.d.ts.map +1 -1
  97. package/dist/commands/project/index.js +2 -0
  98. package/dist/commands/project/journal-check/evaluator.d.ts +17 -0
  99. package/dist/commands/project/journal-check/evaluator.d.ts.map +1 -0
  100. package/dist/commands/project/journal-check/evaluator.js +140 -0
  101. package/dist/commands/project/journal-check/index.d.ts +34 -0
  102. package/dist/commands/project/journal-check/index.d.ts.map +1 -0
  103. package/dist/commands/project/journal-check/index.js +163 -0
  104. package/dist/commands/project/journal-check/rules.d.ts +68 -0
  105. package/dist/commands/project/journal-check/rules.d.ts.map +1 -0
  106. package/dist/commands/project/journal-check/rules.js +994 -0
  107. package/dist/commands/project/journal-check/types.d.ts +63 -0
  108. package/dist/commands/project/journal-check/types.d.ts.map +1 -0
  109. package/dist/commands/project/journal-check/types.js +26 -0
  110. package/dist/commands/project/log/append.d.ts +6 -0
  111. package/dist/commands/project/log/append.d.ts.map +1 -1
  112. package/dist/commands/project/log/append.js +114 -6
  113. package/dist/commands/project/log/check.d.ts +23 -1
  114. package/dist/commands/project/log/check.d.ts.map +1 -1
  115. package/dist/commands/project/log/check.js +20 -3
  116. package/dist/commands/project/log/grammar.d.ts +37 -0
  117. package/dist/commands/project/log/grammar.d.ts.map +1 -1
  118. package/dist/commands/project/log/grammar.js +72 -0
  119. package/dist/commands/project/log/rollup.d.ts +87 -1
  120. package/dist/commands/project/log/rollup.d.ts.map +1 -1
  121. package/dist/commands/project/log/rollup.js +257 -5
  122. package/dist/config/oat-config.d.ts +14 -0
  123. package/dist/config/oat-config.d.ts.map +1 -1
  124. package/dist/config/oat-config.js +17 -0
  125. package/dist/config/resolve.d.ts.map +1 -1
  126. package/dist/config/resolve.js +5 -1
  127. package/dist/providers/identity/generic-dispatch-record.d.ts +33 -0
  128. package/dist/providers/identity/generic-dispatch-record.d.ts.map +1 -1
  129. package/dist/providers/identity/generic-dispatch-record.js +60 -1
  130. package/package.json +2 -2
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Journal evaluator contract (`oat project journal check`).
3
+ *
4
+ * The evaluator is pure: it reads the bytes of `plan.md`, `implementation.md`
5
+ * and `state.md` and returns `{ status, reasons }`. It never writes. Callers
6
+ * pick the boundary: `implement-preflight` (implement, before Step 16, while
7
+ * Step 16's terminal headers and pointers may still be unwritten), `review`
8
+ * (with an explicit phase scope), or `completion` (complete, after the
9
+ * owner-controlled refresh and before roll-up, seal or lifecycle mutation).
10
+ */
11
+ export declare const JOURNAL_CHECK_BOUNDARIES: readonly ['implement-preflight', 'review', 'completion'];
12
+ export type JournalCheckBoundary = (typeof JOURNAL_CHECK_BOUNDARIES)[number];
13
+ export type JournalArtifactPath = 'implementation.md' | 'plan.md' | 'state.md';
14
+ export type JournalReasonCode = 'journal-frontmatter-malformed' | 'journal-frontmatter-missing' | 'journal-missing' | 'state-frontmatter-malformed' | 'journal-status-not-terminal' | 'journal-pointer-not-cleared' | 'state-status-disagrees' | 'state-pointer-not-cleared' | 'task-block-missing' | 'task-duplicate-block' | 'task-unplanned' | 'task-status-missing' | 'task-status-ambiguous' | 'task-status-invalid' | 'task-not-completed' | 'task-commit-missing' | 'task-misplaced' | 'plan-task-duplicate' | 'plan-task-misplaced' | 'execution-record-open' | 'phase-status-disagrees' | 'phase-status-ambiguous' | 'phase-duplicate-section' | 'phase-head-missing' | 'phase-not-accepted' | 'overview-total-mismatch' | 'references-not-last' | 'receipt-misplaced' | 'deferral-misplaced' | 'dispatch-payload' | 'run-line-malformed' | 'run-line-misplaced' | 'run-line-duplicate' | 'run-line-unresolved' | 'template-residue' | 'override-malformed' | 'override-misplaced' | 'override-unused';
15
+ export interface JournalCheckReason {
16
+ code: JournalReasonCode;
17
+ path: JournalArtifactPath;
18
+ /** 1-based source line, or `null` when the finding has no single line. */
19
+ line: number | null;
20
+ /** The skill that owns the correction. */
21
+ owner: string;
22
+ message: string;
23
+ }
24
+ /**
25
+ * Journal-only override reason codes. An override is one line under
26
+ * `## Deviations from Plan / Design`:
27
+ *
28
+ * `**Override:** <code> · **Authorized by:** <decision id> · **Scope:** <pNN-tNN|pNN> · <reason>`
29
+ */
30
+ export declare const JOURNAL_OVERRIDE_CODES: readonly ['scope-disposition-approved', 'evidence-lost', 'operator-accepted-gap'];
31
+ export type JournalOverrideCode = (typeof JOURNAL_OVERRIDE_CODES)[number];
32
+ export interface JournalOverride {
33
+ code: JournalOverrideCode;
34
+ authorizedBy: string;
35
+ /** Normalized scope: a task id (`pNN-tNN`, `prevN-tNN`) or a phase id. */
36
+ scope: string;
37
+ reason: string;
38
+ line: number;
39
+ /** Whether the override suppressed at least one eligible finding. */
40
+ applied: boolean;
41
+ }
42
+ export interface JournalCheckInput {
43
+ boundary: JournalCheckBoundary;
44
+ /**
45
+ * Review boundary only: the validated phase scope (normalized phase ids).
46
+ * Ignored at the other boundaries.
47
+ */
48
+ scope?: readonly string[] | null;
49
+ planContent: string;
50
+ journalContent: string;
51
+ stateContent: string;
52
+ }
53
+ export interface JournalCheckResult {
54
+ status: 'ok' | 'refused';
55
+ boundary: JournalCheckBoundary;
56
+ workflowMode: string;
57
+ scope: string[] | null;
58
+ reasons: JournalCheckReason[];
59
+ /** Non-refusing findings (live runs at review, unused overrides). */
60
+ warnings: JournalCheckReason[];
61
+ overrides: JournalOverride[];
62
+ }
63
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/journal-check/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,eAAO,MAAM,wBAAwB,YACnC,qBAAqB,EACrB,QAAQ,EACR,YAAY,CACJ,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7E,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,GAAG,SAAS,GAAG,UAAU,CAAC;AAE/E,MAAM,MAAM,iBAAiB,GAEzB,+BAA+B,GAC/B,6BAA6B,GAC7B,iBAAiB,GACjB,6BAA6B,GAC7B,6BAA6B,GAC7B,6BAA6B,GAC7B,wBAAwB,GACxB,2BAA2B,GAE3B,oBAAoB,GACpB,sBAAsB,GACtB,gBAAgB,GAChB,qBAAqB,GACrB,uBAAuB,GACvB,qBAAqB,GACrB,oBAAoB,GACpB,qBAAqB,GACrB,gBAAgB,GAChB,qBAAqB,GACrB,qBAAqB,GACrB,uBAAuB,GAEvB,wBAAwB,GACxB,wBAAwB,GACxB,yBAAyB,GACzB,oBAAoB,GACpB,oBAAoB,GACpB,yBAAyB,GAEzB,qBAAqB,GACrB,mBAAmB,GACnB,oBAAoB,GACpB,kBAAkB,GAClB,oBAAoB,GACpB,oBAAoB,GACpB,oBAAoB,GACpB,qBAAqB,GACrB,kBAAkB,GAElB,oBAAoB,GACpB,oBAAoB,GACpB,iBAAiB,CAAC;AAEtB,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,YACjC,4BAA4B,EAC5B,eAAe,EACf,uBAAuB,CACf,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,IAAI,GAAG,SAAS,CAAC;IACzB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,qEAAqE;IACrE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,SAAS,EAAE,eAAe,EAAE,CAAC;CAC9B"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Journal evaluator contract (`oat project journal check`).
3
+ *
4
+ * The evaluator is pure: it reads the bytes of `plan.md`, `implementation.md`
5
+ * and `state.md` and returns `{ status, reasons }`. It never writes. Callers
6
+ * pick the boundary: `implement-preflight` (implement, before Step 16, while
7
+ * Step 16's terminal headers and pointers may still be unwritten), `review`
8
+ * (with an explicit phase scope), or `completion` (complete, after the
9
+ * owner-controlled refresh and before roll-up, seal or lifecycle mutation).
10
+ */
11
+ export const JOURNAL_CHECK_BOUNDARIES = [
12
+ 'implement-preflight',
13
+ 'review',
14
+ 'completion',
15
+ ];
16
+ /**
17
+ * Journal-only override reason codes. An override is one line under
18
+ * `## Deviations from Plan / Design`:
19
+ *
20
+ * `**Override:** <code> · **Authorized by:** <decision id> · **Scope:** <pNN-tNN|pNN> · <reason>`
21
+ */
22
+ export const JOURNAL_OVERRIDE_CODES = [
23
+ 'scope-disposition-approved',
24
+ 'evidence-lost',
25
+ 'operator-accepted-gap',
26
+ ];
@@ -210,6 +210,12 @@ export interface AppendProjectLogInput {
210
210
  body?: string;
211
211
  versionNote?: string;
212
212
  idempotencyKey?: string;
213
+ /** Learning category for a judgment entry; one of `PROJECT_LOG_CATEGORIES`. */
214
+ category?: string;
215
+ /** Stable per-observation source id; required with `category`. */
216
+ source?: string;
217
+ /** The producer that recorded the learning. */
218
+ origin?: string;
213
219
  }
214
220
  /**
215
221
  * Raised when an append that is not the completion seal targets a sealed log.
@@ -1 +1 @@
1
- {"version":3,"file":"append.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/log/append.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"append.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/log/append.ts"],"names":[],"mappings":"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"}
@@ -14,7 +14,7 @@ import { dirExists, fileExists } from '../../../fs/io.js';
14
14
  import { resolveProjectRoot } from '../../../fs/paths.js';
15
15
  import { Command } from 'commander';
16
16
  import { findProjectLogAmbiguity, findProjectLogSeal, unreachableProjectLogSealError, } from './check.js';
17
- import { composeJudgmentHeading, composeStructuralHeading, containsAmbiguousProjectLogMarker, isProjectLogEntryMarker, findProjectLogSealHeadingLine, isProjectLogSealHeading, isProjectLogSectionMarker, PROJECT_LOG_AREA_MAX_LENGTH, PROJECT_LOG_HEADING_DELIMITER, PROJECT_LOG_LINE_TERMINATOR_RE, PROJECT_LOG_LONE_TERMINATOR_RE, PROJECT_LOG_SCOPES, PROJECT_LOG_TYPES, normalizeProjectLogLineEndings, splitProjectLogLines, } from './grammar.js';
17
+ import { composeJudgmentBodyHead, composeJudgmentHeading, composeStructuralHeading, containsAmbiguousProjectLogMarker, isProjectLogCategory, isProjectLogEntryMarker, findProjectLogSealHeadingLine, isProjectLogSealHeading, isProjectLogSectionMarker, PROJECT_LOG_AREA_MAX_LENGTH, PROJECT_LOG_CATEGORIES, PROJECT_LOG_HEADING_DELIMITER, PROJECT_LOG_LINE_TERMINATOR_RE, PROJECT_LOG_LONE_TERMINATOR_RE, PROJECT_LOG_SCOPES, PROJECT_LOG_TYPES, normalizeProjectLogLineEndings, splitProjectLogLines, } from './grammar.js';
18
18
  export const PROJECT_LOG_FILENAME = 'project-log.md';
19
19
  /**
20
20
  * Where `appendEntry` inserts: entries go before the end-of-run synthesis
@@ -838,6 +838,68 @@ function validateVersionNote(value) {
838
838
  }
839
839
  return validateSingleLine(value, '--version-note', Number.MAX_SAFE_INTEGER);
840
840
  }
841
+ /**
842
+ * Validates `--category`. The named guard `learning-category-validation`: a
843
+ * category outside the six is refused, so a typo can never become a seventh
844
+ * category that summary, retro and the digest silently fail to recognize.
845
+ */
846
+ function validateCategory(value) {
847
+ const category = validateSingleLine(value, '--category');
848
+ if (!isProjectLogCategory(category)) {
849
+ throw new Error(`Invalid --category '${category}'; accepted values: ${PROJECT_LOG_CATEGORIES.join(' | ')}.`);
850
+ }
851
+ return category;
852
+ }
853
+ /**
854
+ * Validates `--source`, the stable per-observation id. It is one
855
+ * whitespace-free word so a producer can pass the same id as
856
+ * `--idempotency-key` and the existing whole-word replay check recognizes it in
857
+ * the `**Source:**` head line.
858
+ */
859
+ function validateSource(value) {
860
+ const source = validateSingleLine(value, '--source');
861
+ if (/\s/.test(source)) {
862
+ throw new Error('--source must be one word without whitespace.');
863
+ }
864
+ return source;
865
+ }
866
+ /**
867
+ * The judgment body head requested by `--category`, `--source` and `--origin`,
868
+ * or undefined when none was passed. `recorded` is filled by the caller.
869
+ */
870
+ function validateBodyHead(input) {
871
+ if (input.category === undefined &&
872
+ input.source === undefined &&
873
+ input.origin === undefined) {
874
+ return undefined;
875
+ }
876
+ if (input.category !== undefined && input.source === undefined) {
877
+ throw new Error('--category requires --source: a categorized learning carries a stable per-observation source id.');
878
+ }
879
+ return {
880
+ ...(input.category !== undefined
881
+ ? {
882
+ category: validateCategory(input.category),
883
+ }
884
+ : {}),
885
+ ...(input.source !== undefined
886
+ ? { source: validateSource(input.source) }
887
+ : {}),
888
+ ...(input.origin !== undefined
889
+ ? { origin: validateHeadingField(input.origin, '--origin') }
890
+ : {}),
891
+ };
892
+ }
893
+ /**
894
+ * The body a judgment entry is stored with: the head lines, a blank line, then
895
+ * the caller's body. Without a head the body is returned unchanged, so an entry
896
+ * written without the new flags keeps exactly the bytes it always had.
897
+ */
898
+ function composeJudgmentBody(head, body) {
899
+ if (head === undefined)
900
+ return body;
901
+ return `${composeJudgmentBodyHead(head).join('\n')}\n\n${body}`;
902
+ }
841
903
  /**
842
904
  * Whether any line of `body` is a `## ` or `### ` marker the command owns.
843
905
  *
@@ -851,7 +913,7 @@ function validateVersionNote(value) {
851
913
  function containsCommandOwnedMarker(body) {
852
914
  return splitProjectLogLines(body).some((line) => isProjectLogSectionMarker(line) || isProjectLogEntryMarker(line));
853
915
  }
854
- function validateEntry(input, date) {
916
+ function validateEntry(input, now) {
855
917
  // The lone-terminator rule is tested against the *raw* body, before trimming.
856
918
  // `String.prototype.trim` strips CR, LF, U+2028 and U+2029 as whitespace, so a
857
919
  // body edge-terminated by one of them — `'ab\r'`, `'\rabc'` — never reached
@@ -876,12 +938,18 @@ function validateEntry(input, date) {
876
938
  const normalized = supplied.includes('\r\n');
877
939
  const body = normalizeProjectLogLineEndings(supplied);
878
940
  const versionNote = validateVersionNote(input.versionNote);
941
+ const date = now.toISOString().slice(0, 10);
879
942
  if (input.structural) {
880
943
  if (input.type !== undefined ||
881
944
  input.scope !== undefined ||
882
945
  input.area !== undefined) {
883
946
  throw new Error('--structural cannot be combined with judgment flags --type, --scope, or --area.');
884
947
  }
948
+ if (input.category !== undefined ||
949
+ input.source !== undefined ||
950
+ input.origin !== undefined) {
951
+ throw new Error('--structural cannot be combined with judgment flags --category, --source, or --origin.');
952
+ }
885
953
  if (PROJECT_LOG_LINE_TERMINATOR_RE.test(body)) {
886
954
  throw new Error('--body for structural entries must be one line without newline characters.');
887
955
  }
@@ -922,6 +990,7 @@ function validateEntry(input, date) {
922
990
  throw new Error('--body for judgment entries must not contain command-owned level-two or level-three Markdown headings.');
923
991
  }
924
992
  const area = validateHeadingField(input.area, '--area');
993
+ const head = validateBodyHead(input);
925
994
  return {
926
995
  heading: composeJudgmentHeading({
927
996
  date,
@@ -929,7 +998,9 @@ function validateEntry(input, date) {
929
998
  scope: input.scope,
930
999
  area,
931
1000
  }),
932
- body,
1001
+ body: composeJudgmentBody(head === undefined
1002
+ ? undefined
1003
+ : { ...head, recorded: now.toISOString().replace(/\.\d{3}Z$/, 'Z') }, body),
933
1004
  versionNote,
934
1005
  normalized,
935
1006
  };
@@ -1076,8 +1147,9 @@ async function prepareProjectLogAppend(input, dependencies, logPath) {
1076
1147
  return { status: 'skipped', reason: 'projectLog=false' };
1077
1148
  }
1078
1149
  }
1079
- const date = dependencies.now().toISOString().slice(0, 10);
1080
- const { heading, body, versionNote, normalized } = validateEntry(input, date);
1150
+ const now = dependencies.now();
1151
+ const date = now.toISOString().slice(0, 10);
1152
+ const { heading, body, versionNote, normalized } = validateEntry(input, now);
1081
1153
  const idempotencyKey = validateIdempotencyKey(input.idempotencyKey, body);
1082
1154
  let instantiated;
1083
1155
  if (logExists) {
@@ -1303,6 +1375,33 @@ function reportReceiptMismatch(context, receiptPath, reason) {
1303
1375
  }
1304
1376
  context.logger.error(`gate-project-log-receipt-mismatch: ${reason} (${receiptPath}). Nothing was appended or committed.`);
1305
1377
  }
1378
+ /**
1379
+ * The body the commit's identity check derives its token from. A judgment head
1380
+ * puts `--source` above the caller's body, and a producer passes that same id
1381
+ * as `--idempotency-key`, so the identity must see the head the stored entry
1382
+ * carries (without the varying `**Recorded:**` line) to find the same token.
1383
+ */
1384
+ function identityBody(options, body) {
1385
+ if (options.structural ||
1386
+ (options.category === undefined &&
1387
+ options.source === undefined &&
1388
+ options.origin === undefined)) {
1389
+ return body;
1390
+ }
1391
+ return composeJudgmentBody({
1392
+ ...(options.category !== undefined
1393
+ ? {
1394
+ category: options.category.trim(),
1395
+ }
1396
+ : {}),
1397
+ ...(options.source !== undefined
1398
+ ? { source: options.source.trim() }
1399
+ : {}),
1400
+ ...(options.origin !== undefined
1401
+ ? { origin: options.origin.trim() }
1402
+ : {}),
1403
+ }, body);
1404
+ }
1306
1405
  async function runAppendCommand(options, context, dependencies) {
1307
1406
  try {
1308
1407
  const repoRoot = await dependencies.resolveProjectRoot(context.cwd);
@@ -1367,7 +1466,12 @@ async function runAppendCommand(options, context, dependencies) {
1367
1466
  repoRoot,
1368
1467
  logPath: result.logPath,
1369
1468
  ...(options.idempotencyKey !== undefined && body !== undefined
1370
- ? { identity: { key: options.idempotencyKey, body } }
1469
+ ? {
1470
+ identity: {
1471
+ key: options.idempotencyKey,
1472
+ body: identityBody(options, body),
1473
+ },
1474
+ }
1371
1475
  : {}),
1372
1476
  });
1373
1477
  if (receiptPath !== undefined &&
@@ -1435,6 +1539,9 @@ export function createProjectLogAppendCommand(overrides = {}) {
1435
1539
  .option('--version-note <text>', 'Append an observed-on version clause')
1436
1540
  .option('--project <path>', 'Explicit project path; defaults to the active project')
1437
1541
  .option('--idempotency-key <key>', 'Globally unique key (a run id, not a common word) that must appear in --body; an entry already carrying it is reported as already-appended instead of duplicated')
1542
+ .option('--category <category>', `Learning category for a judgment entry: ${PROJECT_LOG_CATEGORIES.join(', ')}; requires --source`)
1543
+ .option('--source <id>', 'Stable per-observation source id for a judgment entry (one word); pass the same id as --idempotency-key so a retry appends nothing')
1544
+ .option('--origin <producer>', 'Producer that recorded a judgment entry, for example oat-project-autonomous')
1438
1545
  .option('--commit', 'Stage and commit the project log after appending, retrying across a transient index lock')
1439
1546
  .addHelpText('after', `
1440
1547
  Entry contract:
@@ -1443,6 +1550,7 @@ Entry contract:
1443
1550
  High-value judgments may use Observation:, Impact:, and Recommendation: fields.
1444
1551
  Structural bodies are one line and reference artifacts by path instead of inlining them.
1445
1552
  Add --version-note for tool-related observations.
1553
+ Learnings: --category, --source, and --origin write a body head (**Category:**, **Source:**, **Origin:**, **Recorded:**) above a judgment body; --category requires --source, and the category must be one of the six.
1446
1554
  Pass --idempotency-key so a replay reports already-appended instead of duplicating the entry; the key must appear in --body as its own word. Adding --commit also finalizes a gate partial-finalization receipt.
1447
1555
  The completion seal (--structural --producer oat-project-complete --ref seal) dedupes on its own, and every append carrying new content onto a sealed log is refused.
1448
1556
  A replay recognized by its own --idempotency-key still reports already-appended on a sealed log and writes nothing.
@@ -1,10 +1,16 @@
1
1
  import { type CommandContext, type GlobalOptions } from '../../../app/command-context.js';
2
2
  import { type ActiveProjectResolution } from '../../../config/oat-config.js';
3
3
  import { Command } from 'commander';
4
- import { type ProjectLogSection, type ProjectLogScope, type ProjectLogType } from './grammar.js';
4
+ import { type ProjectLogCategory, type ProjectLogSection, type ProjectLogScope, type ProjectLogType } from './grammar.js';
5
5
  export declare const PROJECT_LOG_FILENAME = "project-log.md";
6
6
  export declare const SYNTHESIS_PENDING_HEADING = "## End-of-run synthesis (pending \u2014 do not skip at project completion)";
7
7
  export declare const SYNTHESIS_COMPLETE_HEADING = "## End-of-run synthesis";
8
+ /**
9
+ * The separate learnings file the autonomous, cloud and goal producers wrote
10
+ * before judgment entries carried a category. It is read, never migrated;
11
+ * `check` reports its presence so summary and retro know to read it second.
12
+ */
13
+ export declare const LEGACY_LEARNINGS_FILENAME = "oat-execution-learnings.md";
8
14
  /**
9
15
  * The completion seal a project log already carries.
10
16
  *
@@ -47,6 +53,13 @@ export interface ProjectLogCheckResult {
47
53
  lastEntryDate: string | null;
48
54
  synthesisPending: boolean;
49
55
  grammarViolations: string[];
56
+ /**
57
+ * `legacy` when the project still carries `oat-execution-learnings.md`, which
58
+ * summary and retro read after the unified log; `none` otherwise. Reported in
59
+ * every status, including `absent` and `ambiguous`, because the file's
60
+ * presence does not depend on the log's.
61
+ */
62
+ learnings: 'legacy' | 'none';
50
63
  }
51
64
  export type ParsedProjectLogEntry = {
52
65
  class: 'judgment';
@@ -56,6 +69,15 @@ export type ParsedProjectLogEntry = {
56
69
  type: ProjectLogType;
57
70
  area: string;
58
71
  body: string;
72
+ /**
73
+ * Body-head fields, present only when the entry's body opens with them
74
+ * (`append --category/--source/--origin`). Absent rather than null so a
75
+ * log written before the head existed parses to exactly the same entries.
76
+ */
77
+ category?: ProjectLogCategory;
78
+ source?: string;
79
+ origin?: string;
80
+ recorded?: string;
59
81
  } | {
60
82
  class: 'structural';
61
83
  heading: string;
@@ -1 +1 @@
1
- {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/log/check.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/log/check.ts"],"names":[],"mappings":"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"}
@@ -6,10 +6,16 @@ import { resolveActiveProject, } from '../../../config/oat-config.js';
6
6
  import { dirExists, fileExists } from '../../../fs/io.js';
7
7
  import { resolveProjectRoot } from '../../../fs/paths.js';
8
8
  import { Command } from 'commander';
9
- import { carriesProjectLogSealKey, containsAmbiguousProjectLogMarker, findProjectLogSealHeadingLine, findProjectLogSections, isProjectLogEntryMarker, isProjectLogSealEntry, JUDGMENT_HEADING_RE, PROJECT_LOG_TYPES, STRUCTURAL_HEADING_RE, } from './grammar.js';
9
+ import { carriesProjectLogSealKey, containsAmbiguousProjectLogMarker, findProjectLogSealHeadingLine, findProjectLogSections, isProjectLogEntryMarker, isProjectLogSealEntry, JUDGMENT_HEADING_RE, parseProjectLogBodyHead, PROJECT_LOG_TYPES, STRUCTURAL_HEADING_RE, } from './grammar.js';
10
10
  export const PROJECT_LOG_FILENAME = 'project-log.md';
11
11
  export const SYNTHESIS_PENDING_HEADING = '## End-of-run synthesis (pending — do not skip at project completion)';
12
12
  export const SYNTHESIS_COMPLETE_HEADING = '## End-of-run synthesis';
13
+ /**
14
+ * The separate learnings file the autonomous, cloud and goal producers wrote
15
+ * before judgment entries carried a category. It is read, never migrated;
16
+ * `check` reports its presence so summary and retro know to read it second.
17
+ */
18
+ export const LEGACY_LEARNINGS_FILENAME = 'oat-execution-learnings.md';
13
19
  const DEFAULT_CHECK_DEPENDENCIES = {
14
20
  resolveActiveProject,
15
21
  };
@@ -86,6 +92,7 @@ export function parseProjectLogEntries(content) {
86
92
  index = cursor - 1;
87
93
  const judgment = JUDGMENT_HEADING_RE.exec(heading);
88
94
  if (judgment) {
95
+ const { head } = parseProjectLogBodyHead(body);
89
96
  entries.push({
90
97
  class: 'judgment',
91
98
  heading,
@@ -94,6 +101,10 @@ export function parseProjectLogEntries(content) {
94
101
  type: judgment[3],
95
102
  area: judgment[4].trim(),
96
103
  body,
104
+ ...(head.category !== undefined ? { category: head.category } : {}),
105
+ ...(head.source !== undefined ? { source: head.source } : {}),
106
+ ...(head.origin !== undefined ? { origin: head.origin } : {}),
107
+ ...(head.recorded !== undefined ? { recorded: head.recorded } : {}),
97
108
  });
98
109
  continue;
99
110
  }
@@ -218,6 +229,9 @@ export async function checkProjectLog(input, overrides = {}) {
218
229
  const dependencies = { ...DEFAULT_CHECK_DEPENDENCIES, ...overrides };
219
230
  const projectPath = await resolveTargetProject(input, dependencies);
220
231
  const logPath = join(projectPath, PROJECT_LOG_FILENAME);
232
+ const learnings = (await fileExists(join(projectPath, LEGACY_LEARNINGS_FILENAME)))
233
+ ? 'legacy'
234
+ : 'none';
221
235
  if (!(await fileExists(logPath))) {
222
236
  return {
223
237
  status: 'absent',
@@ -229,6 +243,7 @@ export async function checkProjectLog(input, overrides = {}) {
229
243
  lastEntryDate: null,
230
244
  synthesisPending: false,
231
245
  grammarViolations: [],
246
+ learnings,
232
247
  };
233
248
  }
234
249
  const content = await readFile(logPath, 'utf8');
@@ -248,6 +263,7 @@ export async function checkProjectLog(input, overrides = {}) {
248
263
  lastEntryDate: null,
249
264
  synthesisPending: false,
250
265
  grammarViolations: [],
266
+ learnings,
251
267
  };
252
268
  }
253
269
  const parsed = parseProjectLogEntries(content);
@@ -273,6 +289,7 @@ export async function checkProjectLog(input, overrides = {}) {
273
289
  lastEntryDate: parsed.entries.at(-1)?.date ?? null,
274
290
  synthesisPending,
275
291
  grammarViolations: parsed.grammarViolations,
292
+ learnings,
276
293
  };
277
294
  }
278
295
  async function runCheckCommand(options, context, dependencies) {
@@ -286,14 +303,14 @@ async function runCheckCommand(options, context, dependencies) {
286
303
  context.logger.error(result.ambiguity ?? 'Project log has two readings.');
287
304
  }
288
305
  else {
289
- context.logger.info(result.status === 'absent'
306
+ context.logger.info(`${result.status === 'absent'
290
307
  ? 'Project log: absent'
291
308
  : `Project log: ${result.status}; entries: ${result.entryCounts.structural +
292
309
  PROJECT_LOG_TYPES.reduce((total, type) => total + result.entryCounts.judgment[type], 0)}${result.seal
293
310
  ? `; sealed${result.seal.count > 1
294
311
  ? ` (${result.seal.count} seal entries)`
295
312
  : ''}`
296
- : ''}`);
313
+ : ''}`}${result.learnings === 'legacy' ? '; learnings: legacy' : ''}`);
297
314
  }
298
315
  // An ambiguous log exits non-zero whether or not synthesis was required: a
299
316
  // caller that only checks the exit status must not read this as a clean log,
@@ -2,6 +2,43 @@ export declare const PROJECT_LOG_TYPES: readonly ['bug', 'friction', 'worked-wel
2
2
  export declare const PROJECT_LOG_SCOPES: readonly ['project', 'general'];
3
3
  export type ProjectLogType = (typeof PROJECT_LOG_TYPES)[number];
4
4
  export type ProjectLogScope = (typeof PROJECT_LOG_SCOPES)[number];
5
+ /**
6
+ * The learning taxonomy a judgment entry may carry verbatim in its body head.
7
+ *
8
+ * These are the six categories the autonomous, cloud and goal producers used
9
+ * in `oat-execution-learnings.md`. They ride beside the four judgment types
10
+ * rather than replacing them: the heading grammar and `JUDGMENT_HEADING_RE`
11
+ * are unchanged, so every existing reader keeps parsing every existing log.
12
+ */
13
+ export declare const PROJECT_LOG_CATEGORIES: readonly ['gotcha', 'efficiency', 'documentation-gap', 'candidate-skill-content', 'decision', 'environment-limited'];
14
+ export type ProjectLogCategory = (typeof PROJECT_LOG_CATEGORIES)[number];
15
+ export declare function isProjectLogCategory(value: string): value is ProjectLogCategory;
16
+ /**
17
+ * The structured head a judgment body may open with, in the order the command
18
+ * writes it. Every field is optional; an entry written without `--category`,
19
+ * `--source` or `--origin` has no head at all and its bytes are unchanged.
20
+ */
21
+ export interface ProjectLogBodyHead {
22
+ category?: ProjectLogCategory;
23
+ source?: string;
24
+ origin?: string;
25
+ recorded?: string;
26
+ }
27
+ /** Renders the head lines `append` writes above a judgment body. */
28
+ export declare function composeJudgmentBodyHead(head: ProjectLogBodyHead): string[];
29
+ /**
30
+ * Reads the structured head off the top of a judgment body.
31
+ *
32
+ * Only the leading run of head lines counts; a `**Source:**` line further down
33
+ * is body prose. The first occurrence of a field wins, and a category outside
34
+ * the six is not reported as a category (a hand-written head cannot smuggle a
35
+ * value `append` would refuse). `rest` is the body below the head, or the whole
36
+ * body when there is no head.
37
+ */
38
+ export declare function parseProjectLogBodyHead(body: string): {
39
+ head: ProjectLogBodyHead;
40
+ rest: string;
41
+ };
5
42
  export declare const PROJECT_LOG_AREA_MAX_LENGTH = 120;
6
43
  export declare const PROJECT_LOG_HEADING_DELIMITER = "\u00B7";
7
44
  export declare const JUDGMENT_HEADING_RE: RegExp;
@@ -1 +1 @@
1
- {"version":3,"file":"grammar.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/log/grammar.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,YAC5B,KAAK,EACL,UAAU,EACV,aAAa,EACb,UAAU,CACF,CAAC;AACX,eAAO,MAAM,kBAAkB,YAAI,SAAS,EAAE,SAAS,CAAU,CAAC;AAElE,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAChE,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAElE,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAC/C,eAAO,MAAM,6BAA6B,WAAM,CAAC;AAEjD,eAAO,MAAM,mBAAmB,QACqE,CAAC;AACtG,eAAO,MAAM,qBAAqB,QACoC,CAAC;AAEvE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,8BAA8B,QAAuB,CAAC;AAEnE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,8BAA8B,QAA4B,CAAC;AAExE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAE9D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAO3E;AAqBD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,iCAAiC,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAc1E;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,eAAe,CAAC;IACvB,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,MAAM,CAET;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb,GAAG,MAAM,CAET;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,yBAAyB,CAAC;AAChE,eAAO,MAAM,oBAAoB,SAAS,CAAC;AAE3C;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,cAAc,CAAC;AAEvD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb,GAAG,OAAO,CAKV;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAShE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,MAAM,GACd;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAY7C;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQ9D"}
1
+ {"version":3,"file":"grammar.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/log/grammar.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,78 @@ export const PROJECT_LOG_TYPES = [
5
5
  'feedback',
6
6
  ];
7
7
  export const PROJECT_LOG_SCOPES = ['project', 'general'];
8
+ /**
9
+ * The learning taxonomy a judgment entry may carry verbatim in its body head.
10
+ *
11
+ * These are the six categories the autonomous, cloud and goal producers used
12
+ * in `oat-execution-learnings.md`. They ride beside the four judgment types
13
+ * rather than replacing them: the heading grammar and `JUDGMENT_HEADING_RE`
14
+ * are unchanged, so every existing reader keeps parsing every existing log.
15
+ */
16
+ export const PROJECT_LOG_CATEGORIES = [
17
+ 'gotcha',
18
+ 'efficiency',
19
+ 'documentation-gap',
20
+ 'candidate-skill-content',
21
+ 'decision',
22
+ 'environment-limited',
23
+ ];
24
+ export function isProjectLogCategory(value) {
25
+ return PROJECT_LOG_CATEGORIES.includes(value);
26
+ }
27
+ const BODY_HEAD_LINE_RE = /^\*\*(Category|Source|Origin|Recorded):\*\* (\S.*)$/;
28
+ /** Renders the head lines `append` writes above a judgment body. */
29
+ export function composeJudgmentBodyHead(head) {
30
+ const lines = [];
31
+ if (head.category !== undefined)
32
+ lines.push(`**Category:** ${head.category}`);
33
+ if (head.source !== undefined)
34
+ lines.push(`**Source:** ${head.source}`);
35
+ if (head.origin !== undefined)
36
+ lines.push(`**Origin:** ${head.origin}`);
37
+ if (head.recorded !== undefined)
38
+ lines.push(`**Recorded:** ${head.recorded}`);
39
+ return lines;
40
+ }
41
+ /**
42
+ * Reads the structured head off the top of a judgment body.
43
+ *
44
+ * Only the leading run of head lines counts; a `**Source:**` line further down
45
+ * is body prose. The first occurrence of a field wins, and a category outside
46
+ * the six is not reported as a category (a hand-written head cannot smuggle a
47
+ * value `append` would refuse). `rest` is the body below the head, or the whole
48
+ * body when there is no head.
49
+ */
50
+ export function parseProjectLogBodyHead(body) {
51
+ const lines = body.split(/\r?\n/);
52
+ const head = {};
53
+ let index = 0;
54
+ for (; index < lines.length; index += 1) {
55
+ const match = BODY_HEAD_LINE_RE.exec(lines[index] ?? '');
56
+ if (!match)
57
+ break;
58
+ const value = match[2].trim();
59
+ switch (match[1]) {
60
+ case 'Category':
61
+ if (head.category === undefined && isProjectLogCategory(value)) {
62
+ head.category = value;
63
+ }
64
+ break;
65
+ case 'Source':
66
+ head.source ??= value;
67
+ break;
68
+ case 'Origin':
69
+ head.origin ??= value;
70
+ break;
71
+ case 'Recorded':
72
+ head.recorded ??= value;
73
+ break;
74
+ }
75
+ }
76
+ if (index === 0)
77
+ return { head, rest: body };
78
+ return { head, rest: lines.slice(index).join('\n').trim() };
79
+ }
8
80
  export const PROJECT_LOG_AREA_MAX_LENGTH = 120;
9
81
  export const PROJECT_LOG_HEADING_DELIMITER = '·';
10
82
  export const JUDGMENT_HEADING_RE = /^### (\d{4}-\d{2}-\d{2}) · (project|general) · (bug|friction|worked-well|feedback) · ([^·\r\n]+)$/;