@cleocode/core 2026.4.5 → 2026.4.6

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 (144) hide show
  1. package/dist/discovery.d.ts +69 -0
  2. package/dist/discovery.d.ts.map +1 -0
  3. package/dist/index.d.ts +3 -2
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +1643 -2349
  6. package/dist/index.js.map +4 -4
  7. package/dist/init.d.ts +51 -0
  8. package/dist/init.d.ts.map +1 -1
  9. package/dist/internal.d.ts +9 -1
  10. package/dist/internal.d.ts.map +1 -1
  11. package/dist/lifecycle/default-chain.d.ts +8 -2
  12. package/dist/lifecycle/default-chain.d.ts.map +1 -1
  13. package/dist/lifecycle/index.d.ts +1 -0
  14. package/dist/lifecycle/index.d.ts.map +1 -1
  15. package/dist/lifecycle/stage-guidance.d.ts +140 -0
  16. package/dist/lifecycle/stage-guidance.d.ts.map +1 -0
  17. package/dist/orchestration/protocol-validators.d.ts +122 -3
  18. package/dist/orchestration/protocol-validators.d.ts.map +1 -1
  19. package/dist/paths.d.ts +91 -0
  20. package/dist/paths.d.ts.map +1 -1
  21. package/dist/scaffold.d.ts +31 -1
  22. package/dist/scaffold.d.ts.map +1 -1
  23. package/dist/skills/dispatch.d.ts +1 -1
  24. package/dist/skills/skill-paths.d.ts +9 -6
  25. package/dist/skills/skill-paths.d.ts.map +1 -1
  26. package/dist/validation/protocols/_shared.d.ts +40 -0
  27. package/dist/validation/protocols/_shared.d.ts.map +1 -0
  28. package/dist/validation/protocols/architecture-decision.d.ts +23 -0
  29. package/dist/validation/protocols/architecture-decision.d.ts.map +1 -0
  30. package/dist/validation/protocols/artifact-publish.d.ts +22 -0
  31. package/dist/validation/protocols/artifact-publish.d.ts.map +1 -0
  32. package/dist/validation/protocols/consensus.d.ts +11 -17
  33. package/dist/validation/protocols/consensus.d.ts.map +1 -1
  34. package/dist/validation/protocols/contribution.d.ts +12 -17
  35. package/dist/validation/protocols/contribution.d.ts.map +1 -1
  36. package/dist/validation/protocols/decomposition.d.ts +18 -21
  37. package/dist/validation/protocols/decomposition.d.ts.map +1 -1
  38. package/dist/validation/protocols/implementation.d.ts +9 -17
  39. package/dist/validation/protocols/implementation.d.ts.map +1 -1
  40. package/dist/validation/protocols/provenance.d.ts +23 -0
  41. package/dist/validation/protocols/provenance.d.ts.map +1 -0
  42. package/dist/validation/protocols/release.d.ts +25 -0
  43. package/dist/validation/protocols/release.d.ts.map +1 -0
  44. package/dist/validation/protocols/research.d.ts +9 -17
  45. package/dist/validation/protocols/research.d.ts.map +1 -1
  46. package/dist/validation/protocols/specification.d.ts +7 -17
  47. package/dist/validation/protocols/specification.d.ts.map +1 -1
  48. package/dist/validation/protocols/testing.d.ts +22 -0
  49. package/dist/validation/protocols/testing.d.ts.map +1 -0
  50. package/dist/validation/protocols/validation.d.ts +22 -0
  51. package/dist/validation/protocols/validation.d.ts.map +1 -0
  52. package/package.json +7 -7
  53. package/src/__tests__/injection-mvi-tiers.test.js +54 -90
  54. package/src/__tests__/injection-mvi-tiers.test.js.map +1 -1
  55. package/src/discovery.ts +235 -0
  56. package/src/hooks/handlers/__tests__/hook-automation-e2e.test.js +3 -1
  57. package/src/hooks/handlers/__tests__/hook-automation-e2e.test.js.map +1 -1
  58. package/src/index.ts +16 -0
  59. package/src/init.ts +196 -0
  60. package/src/internal.ts +31 -1
  61. package/src/lifecycle/default-chain.ts +11 -2
  62. package/src/lifecycle/index.ts +10 -0
  63. package/src/lifecycle/stage-guidance.ts +282 -0
  64. package/src/metrics/__tests__/provider-detection.test.js +19 -7
  65. package/src/metrics/__tests__/provider-detection.test.js.map +1 -1
  66. package/src/orchestration/__tests__/protocol-validators.test.js +228 -8
  67. package/src/orchestration/__tests__/protocol-validators.test.js.map +1 -1
  68. package/src/orchestration/__tests__/protocol-validators.test.ts +259 -7
  69. package/src/orchestration/protocol-validators.ts +419 -4
  70. package/src/paths.ts +110 -0
  71. package/src/scaffold.ts +240 -4
  72. package/src/skills/dispatch.ts +6 -6
  73. package/src/skills/skill-paths.ts +27 -23
  74. package/src/validation/protocols/_shared.ts +88 -0
  75. package/src/validation/protocols/architecture-decision.ts +52 -0
  76. package/src/validation/protocols/artifact-publish.ts +49 -0
  77. package/src/validation/protocols/consensus.ts +44 -74
  78. package/src/validation/protocols/contribution.ts +28 -65
  79. package/src/validation/protocols/decomposition.ts +37 -64
  80. package/src/validation/protocols/implementation.ts +25 -65
  81. package/src/validation/protocols/protocols-markdown/architecture-decision.md +303 -0
  82. package/src/validation/protocols/protocols-markdown/artifact-publish.md +600 -0
  83. package/src/validation/protocols/protocols-markdown/consensus.md +322 -0
  84. package/src/validation/protocols/protocols-markdown/contribution.md +388 -0
  85. package/src/validation/protocols/protocols-markdown/decomposition.md +421 -0
  86. package/src/validation/protocols/protocols-markdown/implementation.md +357 -0
  87. package/src/validation/protocols/protocols-markdown/provenance.md +613 -0
  88. package/src/validation/protocols/protocols-markdown/release.md +783 -0
  89. package/src/validation/protocols/protocols-markdown/research.md +261 -0
  90. package/src/validation/protocols/protocols-markdown/specification.md +300 -0
  91. package/src/validation/protocols/protocols-markdown/testing.md +287 -0
  92. package/src/validation/protocols/protocols-markdown/validation.md +242 -0
  93. package/src/validation/protocols/provenance.ts +50 -0
  94. package/src/validation/protocols/release.ts +44 -0
  95. package/src/validation/protocols/research.ts +25 -87
  96. package/src/validation/protocols/specification.ts +27 -89
  97. package/src/validation/protocols/testing.ts +46 -0
  98. package/src/validation/protocols/validation.ts +46 -0
  99. package/dist/validation/protocols/release-protocol.d.ts +0 -27
  100. package/dist/validation/protocols/release-protocol.d.ts.map +0 -1
  101. package/dist/validation/protocols/testing-protocol.d.ts +0 -27
  102. package/dist/validation/protocols/testing-protocol.d.ts.map +0 -1
  103. package/dist/validation/protocols/validation-protocol.d.ts +0 -27
  104. package/dist/validation/protocols/validation-protocol.d.ts.map +0 -1
  105. package/schemas/agent-configs.schema.json +0 -120
  106. package/schemas/agent-registry.schema.json +0 -132
  107. package/schemas/archive.schema.json +0 -450
  108. package/schemas/brain-decision.schema.json +0 -69
  109. package/schemas/brain-learning.schema.json +0 -57
  110. package/schemas/brain-pattern.schema.json +0 -72
  111. package/schemas/critical-path.schema.json +0 -246
  112. package/schemas/deps-cache.schema.json +0 -97
  113. package/schemas/doctor-output.schema.json +0 -283
  114. package/schemas/error.schema.json +0 -161
  115. package/schemas/global-config.schema.json +0 -219
  116. package/schemas/grade.schema.json +0 -49
  117. package/schemas/log.schema.json +0 -250
  118. package/schemas/metrics.schema.json +0 -328
  119. package/schemas/migrations.schema.json +0 -150
  120. package/schemas/nexus-registry.schema.json +0 -90
  121. package/schemas/operation-constitution.schema.json +0 -438
  122. package/schemas/output.schema.json +0 -164
  123. package/schemas/projects-registry.schema.json +0 -107
  124. package/schemas/protocol-frontmatter.schema.json +0 -72
  125. package/schemas/rcasd-consensus-report.schema.json +0 -10
  126. package/schemas/rcasd-evidence.schema.json +0 -42
  127. package/schemas/rcasd-gate-result.schema.json +0 -46
  128. package/schemas/rcasd-hitl-resolution.schema.json +0 -10
  129. package/schemas/rcasd-index.schema.json +0 -10
  130. package/schemas/rcasd-manifest.schema.json +0 -10
  131. package/schemas/rcasd-research-output.schema.json +0 -10
  132. package/schemas/rcasd-spec-frontmatter.schema.json +0 -10
  133. package/schemas/rcasd-stage-transition.schema.json +0 -38
  134. package/schemas/releases.schema.json +0 -267
  135. package/schemas/skills-manifest.schema.json +0 -91
  136. package/schemas/spec-index.schema.json +0 -196
  137. package/schemas/system-flow-atlas.schema.json +0 -125
  138. package/src/conduit/__tests__/dual-api-e2e.test.d.ts.map +0 -1
  139. package/src/conduit/__tests__/dual-api-e2e.test.js +0 -178
  140. package/src/conduit/__tests__/dual-api-e2e.test.js.map +0 -1
  141. package/src/conduit/__tests__/dual-api-e2e.test.ts +0 -212
  142. package/src/validation/protocols/release-protocol.ts +0 -80
  143. package/src/validation/protocols/testing-protocol.ts +0 -93
  144. package/src/validation/protocols/validation-protocol.ts +0 -93
@@ -1,28 +1,18 @@
1
1
  /**
2
- * Specification protocol validation.
2
+ * Specification protocol — thin wrapper delegating to the canonical pure validator.
3
+ *
3
4
  * @task T4537
4
- * @epic T4454
5
+ * @task T260
5
6
  */
6
- interface ValidationResult {
7
- valid: boolean;
8
- violations: Array<{
9
- code: string;
10
- severity: string;
11
- message: string;
12
- }>;
13
- score: number;
14
- protocol: string;
15
- taskId: string;
16
- }
7
+ import { type ProtocolValidationResult } from '../../orchestration/protocol-validators.js';
17
8
  /** Validate specification protocol for a task. */
18
9
  export declare function validateSpecificationTask(taskId: string, opts: {
19
10
  strict?: boolean;
20
11
  specFile?: string;
21
- }): Promise<ValidationResult>;
22
- /** Validate specification protocol from manifest file. */
12
+ }): Promise<ProtocolValidationResult>;
13
+ /** Validate specification protocol from a manifest file. */
23
14
  export declare function checkSpecificationManifest(manifestFile: string, opts: {
24
15
  strict?: boolean;
25
16
  specFile?: string;
26
- }): Promise<ValidationResult>;
27
- export {};
17
+ }): Promise<ProtocolValidationResult>;
28
18
  //# sourceMappingURL=specification.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"specification.d.ts","sourceRoot":"","sources":["../../../src/validation/protocols/specification.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,UAAU,gBAAgB;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAWD,kDAAkD;AAClD,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5C,OAAO,CAAC,gBAAgB,CAAC,CA4D3B;AAED,0DAA0D;AAC1D,wBAAsB,0BAA0B,CAC9C,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5C,OAAO,CAAC,gBAAgB,CAAC,CAO3B"}
1
+ {"version":3,"file":"specification.d.ts","sourceRoot":"","sources":["../../../src/validation/protocols/specification.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,KAAK,wBAAwB,EAE9B,MAAM,4CAA4C,CAAC;AAOpD,kDAAkD;AAClD,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5C,OAAO,CAAC,wBAAwB,CAAC,CAOnC;AAED,4DAA4D;AAC5D,wBAAsB,0BAA0B,CAC9C,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5C,OAAO,CAAC,wBAAwB,CAAC,CAQnC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Testing protocol — thin wrapper delegating to the canonical pure validator.
3
+ *
4
+ * Renamed from testing-protocol.ts in T260. The testing protocol is the
5
+ * project-agnostic IVT loop closure stage: it checks that a detected test
6
+ * framework ran, achieved 100% pass rate, and the Implement→Validate→Test
7
+ * loop converged on the specification. Framework detection and loop logic
8
+ * live in the `ct-ivt-looper` skill; this validator only certifies results.
9
+ *
10
+ * @task T4804
11
+ * @task T260 — drop -protocol suffix, delegate, project-agnostic IVT
12
+ */
13
+ import { type ProtocolValidationResult, type TestingOptions } from '../../orchestration/protocol-validators.js';
14
+ /** Validate testing protocol for a task. */
15
+ export declare function validateTestingTask(taskId: string, opts: {
16
+ strict?: boolean;
17
+ } & TestingOptions): Promise<ProtocolValidationResult>;
18
+ /** Validate testing protocol from a manifest file. */
19
+ export declare function checkTestingManifest(manifestFile: string, opts: {
20
+ strict?: boolean;
21
+ } & TestingOptions): Promise<ProtocolValidationResult>;
22
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../../src/validation/protocols/testing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,cAAc,EAEpB,MAAM,4CAA4C,CAAC;AAOpD,4CAA4C;AAC5C,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,cAAc,GAC1C,OAAO,CAAC,wBAAwB,CAAC,CAKnC;AAED,sDAAsD;AACtD,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,cAAc,GAC1C,OAAO,CAAC,wBAAwB,CAAC,CAMnC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Validation protocol — thin wrapper delegating to the canonical pure validator.
3
+ *
4
+ * Renamed from validation-protocol.ts in T260. The validation stage runs
5
+ * static analysis, type checking, and pre-test quality gates. It is the
6
+ * first half of the IVT loop (Implement → Validate → Test); the validator
7
+ * here only verifies that a validation run produced a proper manifest
8
+ * entry — runtime gate enforcement is in the lifecycle state machine.
9
+ *
10
+ * @task T4804
11
+ * @task T260 — drop -protocol suffix, delegate to orchestration validator
12
+ */
13
+ import { type ProtocolValidationResult, type ValidationStageOptions } from '../../orchestration/protocol-validators.js';
14
+ /** Validate validation-stage protocol for a task. */
15
+ export declare function validateValidationTask(taskId: string, opts: {
16
+ strict?: boolean;
17
+ } & ValidationStageOptions): Promise<ProtocolValidationResult>;
18
+ /** Validate validation-stage protocol from a manifest file. */
19
+ export declare function checkValidationManifest(manifestFile: string, opts: {
20
+ strict?: boolean;
21
+ } & ValidationStageOptions): Promise<ProtocolValidationResult>;
22
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/validation/protocols/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAE5B,MAAM,4CAA4C,CAAC;AAOpD,qDAAqD;AACrD,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,sBAAsB,GAClD,OAAO,CAAC,wBAAwB,CAAC,CAKnC;AAED,+DAA+D;AAC/D,wBAAsB,uBAAuB,CAC3C,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,sBAAsB,GAClD,OAAO,CAAC,wBAAwB,CAAC,CAMnC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cleocode/core",
3
- "version": "2026.4.5",
3
+ "version": "2026.4.6",
4
4
  "description": "CLEO core business logic kernel — tasks, sessions, memory, orchestration, lifecycle, with bundled SQLite store",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -35,12 +35,12 @@
35
35
  "write-file-atomic": "^6.0.0",
36
36
  "yaml": "^2.8.2",
37
37
  "zod": "^3.25.76",
38
- "@cleocode/adapters": "2026.4.5",
39
- "@cleocode/caamp": "2026.4.5",
40
- "@cleocode/contracts": "2026.4.5",
41
- "@cleocode/agents": "2026.4.5",
42
- "@cleocode/lafs": "2026.4.5",
43
- "@cleocode/skills": "2026.4.5"
38
+ "@cleocode/adapters": "2026.4.6",
39
+ "@cleocode/caamp": "2026.4.6",
40
+ "@cleocode/contracts": "2026.4.6",
41
+ "@cleocode/lafs": "2026.4.6",
42
+ "@cleocode/agents": "2026.4.6",
43
+ "@cleocode/skills": "2026.4.6"
44
44
  },
45
45
  "optionalDependencies": {
46
46
  "tree-sitter-c": "^0.24.1",
@@ -1,12 +1,12 @@
1
1
  /**
2
- * Test CLEO-INJECTION.md v2.3.0 minimal-only template.
2
+ * Test CLEO-INJECTION.md v2.4.0 optimized CLI-only template.
3
3
  *
4
4
  * Validates the trimmed template:
5
- * 1. Has version 2.3.0
6
- * 2. Contains all minimal sections
7
- * 3. Does NOT contain standard/orchestrator content
5
+ * 1. Has version 2.4.0 with CLI-only dispatch
6
+ * 2. Contains all essential sections (session start, work loop, discovery, memory, errors)
7
+ * 3. Uses `cleo` prefix exclusively (no `ct` prefix, no MCP syntax)
8
8
  * 4. Contains escalation section with skill pointers
9
- * 5. Does NOT contain TIER markers
9
+ * 5. Is under 100 lines (optimized for token efficiency)
10
10
  *
11
11
  * @task T5096
12
12
  */
@@ -15,106 +15,84 @@ import { dirname, join, resolve } from 'node:path';
15
15
  import { fileURLToPath } from 'node:url';
16
16
  import { describe, expect, it } from 'vitest';
17
17
  const thisFile = fileURLToPath(import.meta.url);
18
- // Template moved to packages/core/templates/ (was at monorepo root templates/)
19
- // thisFile is at packages/core/src/__tests__/, go up two levels to reach packages/core/
20
18
  const corePackageRoot = resolve(dirname(thisFile), '..', '..');
21
19
  const injectionPath = join(corePackageRoot, 'templates', 'CLEO-INJECTION.md');
22
20
  const templateExists = existsSync(injectionPath);
23
- describe('CLEO-INJECTION v2.3.0 minimal-only template', () => {
21
+ describe('CLEO-INJECTION v2.4.0 CLI-only template', () => {
24
22
  const content = templateExists ? readFileSync(injectionPath, 'utf-8') : '';
25
23
  it('template file exists at templates/CLEO-INJECTION.md', () => {
26
24
  expect(templateExists).toBe(true);
27
25
  });
28
- describe('Version and metadata', () => {
29
- it('has version 2.3.0', () => {
30
- expect(content).toContain('Version: 2.3.0');
26
+ describe('Version and identity', () => {
27
+ it('has version 2.4.0', () => {
28
+ expect(content).toContain('Version: 2.4.0');
31
29
  });
32
- it('has status ACTIVE', () => {
33
- expect(content).toContain('Status: ACTIVE');
34
- });
35
- });
36
- describe('Contains all minimal sections', () => {
37
- it('includes CLEO Identity section', () => {
38
- expect(content).toContain('## CLEO Identity');
39
- expect(content).toContain('CLEO protocol agent');
30
+ it('declares CLI-only dispatch', () => {
31
+ expect(content).toContain('CLI-only dispatch');
40
32
  expect(content).toContain('cleo <command>');
41
33
  });
42
- it('includes Mandatory Efficiency Sequence', () => {
43
- expect(content).toContain('## Mandatory Efficiency Sequence');
34
+ });
35
+ describe('Contains essential sections', () => {
36
+ it('includes Session Start sequence', () => {
37
+ expect(content).toContain('## Session Start');
44
38
  expect(content).toContain('cleo session status');
45
39
  expect(content).toContain('cleo dash');
46
40
  expect(content).toContain('cleo current');
47
41
  expect(content).toContain('cleo next');
48
42
  expect(content).toContain('cleo show');
49
43
  });
50
- it('includes Agent Work Loop', () => {
51
- expect(content).toContain('## Agent Work Loop');
52
- expect(content).toContain('cleo current');
44
+ it('includes Work Loop', () => {
45
+ expect(content).toContain('## Work Loop');
53
46
  expect(content).toContain('cleo complete');
54
- expect(content).toContain('cleo next');
55
47
  });
56
- it('includes Context Ethics', () => {
57
- expect(content).toContain('## Context Ethics');
58
- expect(content).toContain('Anti-patterns');
48
+ it('includes Task Discovery', () => {
49
+ expect(content).toContain('## Task Discovery');
50
+ expect(content).toContain('cleo find');
51
+ expect(content).toContain('cleo list');
52
+ });
53
+ it('includes Session Commands', () => {
54
+ expect(content).toContain('## Session Commands');
55
+ expect(content).toContain('cleo briefing');
56
+ });
57
+ it('includes Memory (BRAIN)', () => {
58
+ expect(content).toContain('## Memory (BRAIN)');
59
+ expect(content).toContain('cleo memory find');
60
+ expect(content).toContain('cleo memory timeline');
61
+ expect(content).toContain('cleo memory fetch');
62
+ expect(content).toContain('cleo observe');
59
63
  });
60
64
  it('includes Error Handling', () => {
61
65
  expect(content).toContain('## Error Handling');
62
66
  expect(content).toContain('exit code');
67
+ expect(content).toContain('E_NOT_FOUND');
63
68
  });
64
- it('includes Task Discovery', () => {
65
- expect(content).toContain('## Task Discovery');
66
- expect(content).toContain('tasks find');
67
- });
68
- it('includes Time Estimates Prohibited', () => {
69
- expect(content).toContain('## Time Estimates Prohibited');
70
- expect(content).toContain('MUST NOT');
69
+ it('includes Rules', () => {
70
+ expect(content).toContain('## Rules');
71
+ expect(content).toContain('small');
72
+ expect(content).toContain('medium');
73
+ expect(content).toContain('large');
71
74
  });
72
75
  });
73
- describe('Does NOT contain standard/orchestrator content', () => {
74
- it('does not contain Session Protocol section', () => {
75
- expect(content).not.toContain('## Session Protocol');
76
+ describe('CLI-only no legacy MCP or ct syntax', () => {
77
+ it('does not use ct prefix for commands', () => {
78
+ expect(content).not.toMatch(/`ct /);
76
79
  });
77
- it('does not contain CLI Fallback section', () => {
78
- expect(content).not.toContain('## CLI Fallback');
80
+ it('does not contain MCP query/mutate syntax', () => {
81
+ expect(content).not.toContain('query({');
82
+ expect(content).not.toContain('mutate({');
83
+ expect(content).not.toContain('orchestrate.bootstrap');
79
84
  });
80
- it('does not contain RCASD lifecycle', () => {
81
- expect(content).not.toContain('## RCASD-IVTR+C');
82
- expect(content).not.toContain('RCASD-IVTR+C Lifecycle');
85
+ it('does not contain TIER markers', () => {
86
+ expect(content).not.toMatch(/<!-- TIER:\w+ -->/);
83
87
  });
84
- it('does not contain ORC constraints', () => {
88
+ it('does not contain removed standard/orchestrator content', () => {
89
+ expect(content).not.toContain('## RCASD-IVTR+C');
85
90
  expect(content).not.toContain('ORC-001');
86
- expect(content).not.toContain('## ORC Constraints');
87
- });
88
- it('does not contain BASE constraints', () => {
89
- expect(content).not.toContain('BASE-001');
90
- expect(content).not.toContain('## BASE Constraints');
91
- });
92
- it('does not contain Spawn Pipeline section', () => {
93
91
  expect(content).not.toContain('## Spawn Pipeline');
94
92
  });
95
- it('does not contain Architecture Overview section', () => {
96
- expect(content).not.toContain('## Architecture Overview');
97
- });
98
- it('does not contain Token Pre-Resolution section', () => {
99
- expect(content).not.toContain('## Token Pre-Resolution');
100
- });
101
- it('does not contain Subagent Lifecycle section', () => {
102
- expect(content).not.toContain('## Subagent Lifecycle');
103
- });
104
- });
105
- describe('Does NOT contain TIER markers', () => {
106
- it('has no TIER opening markers', () => {
107
- expect(content).not.toMatch(/<!-- TIER:\w+ -->/);
108
- });
109
- it('has no TIER closing markers', () => {
110
- expect(content).not.toMatch(/<!-- \/TIER:\w+ -->/);
111
- });
112
- it('does not contain MVI Progressive Disclosure comment', () => {
113
- expect(content).not.toContain('MVI Progressive Disclosure');
114
- });
115
93
  });
116
94
  describe('Contains escalation section', () => {
117
- it('has Escalation section header', () => {
95
+ it('has Escalation section', () => {
118
96
  expect(content).toContain('## Escalation');
119
97
  });
120
98
  it('points to ct-cleo skill', () => {
@@ -123,29 +101,15 @@ describe('CLEO-INJECTION v2.3.0 minimal-only template', () => {
123
101
  it('points to ct-orchestrator skill', () => {
124
102
  expect(content).toContain('ct-orchestrator');
125
103
  });
126
- it('points to admin help', () => {
127
- expect(content).toContain('admin help');
128
- });
129
- it('points to operations reference', () => {
130
- expect(content).toContain('CLEO-OPERATIONS-REFERENCE.md');
131
- });
132
- });
133
- describe('References section', () => {
134
- it('has References section', () => {
135
- expect(content).toContain('## References');
136
- });
137
- it('references VERB-STANDARDS.md', () => {
138
- expect(content).toContain('VERB-STANDARDS.md');
139
- });
140
104
  });
141
105
  describe('Template size', () => {
142
- it('is under 160 lines', () => {
106
+ it('is under 100 lines (token-optimized)', () => {
143
107
  const lines = content.split('\n').length;
144
- expect(lines).toBeLessThan(160);
108
+ expect(lines).toBeLessThanOrEqual(100);
145
109
  });
146
- it('is at least 60 lines (not accidentally empty)', () => {
110
+ it('is at least 50 lines (not accidentally empty)', () => {
147
111
  const lines = content.split('\n').length;
148
- expect(lines).toBeGreaterThan(60);
112
+ expect(lines).toBeGreaterThan(50);
149
113
  });
150
114
  });
151
115
  });
@@ -1 +1 @@
1
- {"version":3,"file":"injection-mvi-tiers.test.js","sourceRoot":"","sources":["injection-mvi-tiers.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"injection-mvi-tiers.test.js","sourceRoot":"","sources":["injection-mvi-tiers.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Greenfield/Brownfield project discovery & classification (Phase 5).
3
+ *
4
+ * Classifies a project directory as either:
5
+ * - **greenfield**: empty or nearly-empty, no code, no git history
6
+ * - **brownfield**: existing codebase with files, possibly git history
7
+ *
8
+ * Used by `cleo init` (Phase 5 bootstrap) to choose the correct seed
9
+ * pipeline:
10
+ * - Greenfield → seed a Vision/PRD "research" epic so the agent starts
11
+ * from a blank-slate planning posture
12
+ * - Brownfield → invoke codebase mapping and anchor findings in BRAIN as
13
+ * baseline context (per ULTRAPLAN §1 "Context Anchoring")
14
+ *
15
+ * Classification is intentionally simple and transparent — no heuristics,
16
+ * no ML, just file/directory presence checks. A project qualifies as
17
+ * brownfield if ANY of these are true:
18
+ * - `.git/` directory exists (under a size threshold we still treat as
19
+ * brownfield since history matters)
20
+ * - source files exist under common source dirs (src, lib, app, packages)
21
+ * - any manifest file exists (package.json, Cargo.toml, go.mod, pyproject.toml)
22
+ * - markdown docs already exist (README.md, docs/)
23
+ *
24
+ * @task Phase 5 — Greenfield/brownfield bootstrap + context anchoring
25
+ */
26
+
27
+ import { existsSync, readdirSync, statSync } from 'node:fs';
28
+ import { join, resolve } from 'node:path';
29
+
30
+ /**
31
+ * Classification result for a project directory.
32
+ */
33
+ export interface ProjectClassification {
34
+ /** Project type: 'greenfield' (empty/new) or 'brownfield' (existing). */
35
+ kind: 'greenfield' | 'brownfield';
36
+ /** Absolute path that was classified. */
37
+ directory: string;
38
+ /** Signal list — which indicators led to the classification. */
39
+ signals: ClassificationSignal[];
40
+ /** Total non-hidden files found at the top level (for reporting). */
41
+ topLevelFileCount: number;
42
+ /** Whether a `.git/` directory is present. */
43
+ hasGit: boolean;
44
+ }
45
+
46
+ /** A single classification signal detected on the filesystem. */
47
+ export interface ClassificationSignal {
48
+ /** Canonical signal id for programmatic handling. */
49
+ id:
50
+ | 'git-dir'
51
+ | 'source-dir'
52
+ | 'package-manifest'
53
+ | 'docs'
54
+ | 'rust-manifest'
55
+ | 'go-manifest'
56
+ | 'python-manifest'
57
+ | 'readme'
58
+ | 'empty';
59
+ /** Human-readable description of what was detected. */
60
+ description: string;
61
+ /** File or directory that triggered this signal. */
62
+ path: string;
63
+ }
64
+
65
+ // ============================================================================
66
+ // Detection helpers
67
+ // ============================================================================
68
+
69
+ /** Common source directory names that indicate an existing codebase. */
70
+ const SOURCE_DIRS = ['src', 'lib', 'app', 'packages', 'crates', 'cmd', 'internal'];
71
+
72
+ /** Manifest files that indicate a managed project. */
73
+ const MANIFESTS: Array<{
74
+ file: string;
75
+ signal: ClassificationSignal['id'];
76
+ description: string;
77
+ }> = [
78
+ { file: 'package.json', signal: 'package-manifest', description: 'Node.js manifest' },
79
+ { file: 'Cargo.toml', signal: 'rust-manifest', description: 'Rust manifest' },
80
+ { file: 'go.mod', signal: 'go-manifest', description: 'Go manifest' },
81
+ { file: 'pyproject.toml', signal: 'python-manifest', description: 'Python manifest (PEP 621)' },
82
+ { file: 'requirements.txt', signal: 'python-manifest', description: 'Python requirements.txt' },
83
+ { file: 'setup.py', signal: 'python-manifest', description: 'Python setup.py' },
84
+ ];
85
+
86
+ /** Docs files/directories that indicate prior work. */
87
+ const DOCS_MARKERS: Array<{ path: string; signal: ClassificationSignal['id'] }> = [
88
+ { path: 'README.md', signal: 'readme' },
89
+ { path: 'README.rst', signal: 'readme' },
90
+ { path: 'docs', signal: 'docs' },
91
+ ];
92
+
93
+ /**
94
+ * Check if a directory (at the top level only) contains any files that are
95
+ * NOT part of the CLEO scaffolding itself. Used to decide whether the caller
96
+ * is about to `cleo init` into an already-populated directory.
97
+ */
98
+ function countMeaningfulTopLevelFiles(directory: string): number {
99
+ if (!existsSync(directory)) return 0;
100
+ try {
101
+ const entries = readdirSync(directory);
102
+ let count = 0;
103
+ for (const entry of entries) {
104
+ // Ignore hidden files, the CLEO dir itself, and common CI/git debris
105
+ if (
106
+ entry.startsWith('.') ||
107
+ entry === '.cleo' ||
108
+ entry === 'node_modules' ||
109
+ entry === 'target' ||
110
+ entry === 'dist' ||
111
+ entry === 'build'
112
+ ) {
113
+ continue;
114
+ }
115
+ count += 1;
116
+ }
117
+ return count;
118
+ } catch {
119
+ return 0;
120
+ }
121
+ }
122
+
123
+ // ============================================================================
124
+ // Public API
125
+ // ============================================================================
126
+
127
+ /**
128
+ * Classify a project directory as greenfield or brownfield.
129
+ *
130
+ * Read-only — never mutates the filesystem. Safe to call at any time.
131
+ *
132
+ * @param directory - Absolute or relative path; defaults to process.cwd()
133
+ * @returns Classification result with signals and metadata
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * const classification = classifyProject('/my/project');
138
+ * if (classification.kind === 'greenfield') {
139
+ * // Seed initial Vision epic
140
+ * } else {
141
+ * // Run codebase mapping
142
+ * }
143
+ * ```
144
+ */
145
+ export function classifyProject(directory?: string): ProjectClassification {
146
+ const root = resolve(directory ?? process.cwd());
147
+ const signals: ClassificationSignal[] = [];
148
+
149
+ // Signal 1: .git directory
150
+ const gitPath = join(root, '.git');
151
+ const hasGit = existsSync(gitPath);
152
+ if (hasGit) {
153
+ signals.push({
154
+ id: 'git-dir',
155
+ description: '.git/ directory present — project has version history',
156
+ path: gitPath,
157
+ });
158
+ }
159
+
160
+ // Signal 2: manifest files
161
+ for (const manifest of MANIFESTS) {
162
+ const manifestPath = join(root, manifest.file);
163
+ if (existsSync(manifestPath)) {
164
+ signals.push({
165
+ id: manifest.signal,
166
+ description: manifest.description,
167
+ path: manifestPath,
168
+ });
169
+ }
170
+ }
171
+
172
+ // Signal 3: common source directories
173
+ for (const dir of SOURCE_DIRS) {
174
+ const srcPath = join(root, dir);
175
+ if (existsSync(srcPath) && isNonEmptyDir(srcPath)) {
176
+ signals.push({
177
+ id: 'source-dir',
178
+ description: `Source directory ${dir}/ contains files`,
179
+ path: srcPath,
180
+ });
181
+ break; // One source-dir signal is enough
182
+ }
183
+ }
184
+
185
+ // Signal 4: docs / README
186
+ for (const marker of DOCS_MARKERS) {
187
+ const markerPath = join(root, marker.path);
188
+ if (existsSync(markerPath)) {
189
+ signals.push({
190
+ id: marker.signal,
191
+ description: `${marker.path} present`,
192
+ path: markerPath,
193
+ });
194
+ break;
195
+ }
196
+ }
197
+
198
+ const topLevelFileCount = countMeaningfulTopLevelFiles(root);
199
+
200
+ // Empty signal if we have nothing
201
+ if (signals.length === 0 && topLevelFileCount === 0) {
202
+ signals.push({
203
+ id: 'empty',
204
+ description: 'No source files, manifests, git history, or docs detected',
205
+ path: root,
206
+ });
207
+ }
208
+
209
+ // Classification rule: brownfield if ANY non-'empty' signal present
210
+ const kind: ProjectClassification['kind'] = signals.some((s) => s.id !== 'empty')
211
+ ? 'brownfield'
212
+ : 'greenfield';
213
+
214
+ return {
215
+ kind,
216
+ directory: root,
217
+ signals,
218
+ topLevelFileCount,
219
+ hasGit,
220
+ };
221
+ }
222
+
223
+ /**
224
+ * True if a directory exists AND contains at least one non-hidden entry.
225
+ */
226
+ function isNonEmptyDir(dirPath: string): boolean {
227
+ try {
228
+ const stat = statSync(dirPath);
229
+ if (!stat.isDirectory()) return false;
230
+ const entries = readdirSync(dirPath).filter((e) => !e.startsWith('.'));
231
+ return entries.length > 0;
232
+ } catch {
233
+ return false;
234
+ }
235
+ }
@@ -64,7 +64,9 @@ const TIMESTAMP = '2026-03-24T00:00:00.000Z';
64
64
  // ---------------------------------------------------------------------------
65
65
  describe('hook automation E2E', () => {
66
66
  beforeEach(() => {
67
- observeBrainMock.mockReset().mockResolvedValue({ id: 'O-test', type: 'observation', createdAt: '2026-01-01 00:00:00' });
67
+ observeBrainMock
68
+ .mockReset()
69
+ .mockResolvedValue({ id: 'O-test', type: 'observation', createdAt: '2026-01-01 00:00:00' });
68
70
  loadConfigMock.mockReset().mockResolvedValue(makeConfig());
69
71
  maybeRefreshMemoryBridgeMock.mockReset().mockResolvedValue(undefined);
70
72
  // Clear work-capture env var