@llm4ts/shell 0.5.0 → 0.6.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 (146) hide show
  1. package/dist/Cli.d.ts.map +1 -1
  2. package/dist/Cli.js +5 -1
  3. package/dist/Cli.js.map +1 -1
  4. package/flows/fixtures/scaffolds/kafka-streams-service/README.md +12 -0
  5. package/flows/fixtures/scaffolds/kafka-streams-service/pom.xml +49 -0
  6. package/flows/fixtures/scaffolds/kafka-streams-service/scripts/replay.sh +10 -0
  7. package/flows/fixtures/scaffolds/kafka-streams-service/src/main/java/com/meridian/scaffold/Application.java +29 -0
  8. package/flows/fixtures/scaffolds/kafka-streams-service/src/test/java/com/meridian/scaffold/ApplicationTests.java +21 -0
  9. package/flows/fixtures/scaffolds/kafka-streams-service/src/test/resources/features/.gitkeep +0 -0
  10. package/flows/fixtures/scaffolds/nextjs-spa/README.md +6 -0
  11. package/flows/fixtures/scaffolds/nextjs-spa/app/layout.js +11 -0
  12. package/flows/fixtures/scaffolds/nextjs-spa/app/page.js +7 -0
  13. package/flows/fixtures/scaffolds/nextjs-spa/docs/specs/.gitkeep +0 -0
  14. package/flows/fixtures/scaffolds/nextjs-spa/features/.gitkeep +0 -0
  15. package/flows/fixtures/scaffolds/nextjs-spa/next.config.js +7 -0
  16. package/flows/fixtures/scaffolds/nextjs-spa/package.json +15 -0
  17. package/flows/fixtures/scaffolds/nextjs-spa/tests/smoke.test.js +6 -0
  18. package/flows/fixtures/scaffolds/spring-bff/README.md +9 -0
  19. package/flows/fixtures/scaffolds/spring-bff/frontend/app/layout.js +11 -0
  20. package/flows/fixtures/scaffolds/spring-bff/frontend/app/page.js +7 -0
  21. package/flows/fixtures/scaffolds/spring-bff/frontend/next.config.js +7 -0
  22. package/flows/fixtures/scaffolds/spring-bff/frontend/package.json +15 -0
  23. package/flows/fixtures/scaffolds/spring-bff/frontend/tests/smoke.test.js +6 -0
  24. package/flows/fixtures/scaffolds/spring-bff/pom.xml +57 -0
  25. package/flows/fixtures/scaffolds/spring-bff/scripts/test.sh +6 -0
  26. package/flows/fixtures/scaffolds/spring-bff/src/main/java/com/meridian/bff/Application.java +12 -0
  27. package/flows/fixtures/scaffolds/spring-bff/src/main/resources/application.yaml +12 -0
  28. package/flows/fixtures/scaffolds/spring-bff/src/test/java/com/meridian/bff/ApplicationTests.java +12 -0
  29. package/flows/fixtures/scaffolds/spring-bff/src/test/resources/features/.gitkeep +0 -0
  30. package/flows/fixtures/scaffolds/spring-boot-service/README.md +7 -0
  31. package/flows/fixtures/scaffolds/spring-boot-service/pom.xml +53 -0
  32. package/flows/fixtures/scaffolds/spring-boot-service/scripts/replay.sh +9 -0
  33. package/flows/fixtures/scaffolds/spring-boot-service/src/main/java/com/meridian/scaffold/Application.java +12 -0
  34. package/flows/fixtures/scaffolds/spring-boot-service/src/main/resources/application.yaml +12 -0
  35. package/flows/fixtures/scaffolds/spring-boot-service/src/test/java/com/meridian/scaffold/ApplicationTests.java +12 -0
  36. package/flows/fixtures/scaffolds/spring-boot-service/src/test/resources/features/.gitkeep +0 -0
  37. package/flows/modernize-bench.ts +10 -4
  38. package/flows/modernize-extract.ts +17 -8
  39. package/flows/modernize-implement.ts +13 -6
  40. package/flows/modernize-review.ts +14 -6
  41. package/flows/modernize-seed.ts +12 -5
  42. package/flows/modernize-survey.ts +0 -0
  43. package/flows/modernize-verify.ts +11 -4
  44. package/flows/packs/ace-integration/lessons.md +6 -0
  45. package/flows/packs/ace-integration/pack.md +29 -0
  46. package/flows/packs/ace-integration/prompts/analysis.md +21 -0
  47. package/flows/packs/ace-integration/prompts/bdd.md +13 -0
  48. package/flows/packs/ace-integration/prompts/implement.md +17 -0
  49. package/flows/packs/ace-integration/prompts/plan.md +12 -0
  50. package/flows/packs/ace-integration/prompts/review.md +17 -0
  51. package/flows/packs/ace-integration/prompts/spec.md +29 -0
  52. package/flows/packs/ace-integration/reviewers/routing-fidelity.md +19 -0
  53. package/flows/packs/ace-integration/reviewers/traceability.md +13 -0
  54. package/flows/packs/ace-kafka/lessons.md +6 -0
  55. package/flows/packs/ace-kafka/pack.md +36 -0
  56. package/flows/packs/ace-kafka/prompts/analysis.md +21 -0
  57. package/flows/packs/ace-kafka/prompts/bdd.md +13 -0
  58. package/flows/packs/ace-kafka/prompts/implement.md +34 -0
  59. package/flows/packs/ace-kafka/prompts/plan.md +12 -0
  60. package/flows/packs/ace-kafka/prompts/review.md +17 -0
  61. package/flows/packs/ace-kafka/prompts/spec.md +31 -0
  62. package/flows/packs/ace-kafka/prompts/vectors.md +21 -0
  63. package/flows/packs/ace-kafka/reviewers/event-contracts.md +9 -0
  64. package/flows/packs/ace-kafka/reviewers/routing-fidelity.md +19 -0
  65. package/flows/packs/ace-kafka/reviewers/traceability.md +13 -0
  66. package/flows/packs/cobol-kafka/lessons.md +3 -0
  67. package/flows/packs/cobol-kafka/pack.md +51 -0
  68. package/flows/packs/cobol-kafka/patterns/PAT-STREAM-001-record-to-event.md +7 -0
  69. package/flows/packs/cobol-kafka/patterns/PAT-STREAM-002-job-step-topology.md +6 -0
  70. package/flows/packs/cobol-kafka/patterns/PAT-STREAM-003-checkpoint-idempotence.md +7 -0
  71. package/flows/packs/cobol-kafka/patterns/PAT-STREAM-004-eod-totals-window.md +7 -0
  72. package/flows/packs/cobol-kafka/patterns/PAT-STREAM-005-reject-topic.md +6 -0
  73. package/flows/packs/cobol-kafka/patterns/PAT-STREAM-006-keyed-state-store.md +7 -0
  74. package/flows/packs/cobol-kafka/patterns/PAT-STREAM-007-outbox.md +7 -0
  75. package/flows/packs/cobol-kafka/patterns/PAT-STREAM-008-partition-key.md +7 -0
  76. package/flows/packs/cobol-kafka/patterns/PAT-STREAM-009-batch-window-cutoff.md +7 -0
  77. package/flows/packs/cobol-kafka/patterns/PAT-STREAM-010-replay-backfill.md +7 -0
  78. package/flows/packs/cobol-kafka/prompts/analysis.md +23 -0
  79. package/flows/packs/cobol-kafka/prompts/bdd.md +15 -0
  80. package/flows/packs/cobol-kafka/prompts/implement.md +47 -0
  81. package/flows/packs/cobol-kafka/prompts/plan.md +13 -0
  82. package/flows/packs/cobol-kafka/prompts/review.md +17 -0
  83. package/flows/packs/cobol-kafka/prompts/spec.md +28 -0
  84. package/flows/packs/cobol-kafka/prompts/vectors.md +21 -0
  85. package/flows/packs/cobol-kafka/reviewers/cobol-fidelity.md +16 -0
  86. package/flows/packs/cobol-kafka/reviewers/pattern-conformance.md +10 -0
  87. package/flows/packs/cobol-kafka/reviewers/traceability.md +13 -0
  88. package/flows/packs/cobol-springboot/lessons.md +3 -0
  89. package/flows/packs/cobol-springboot/pack.md +51 -0
  90. package/flows/packs/cobol-springboot/prompts/analysis.md +23 -0
  91. package/flows/packs/cobol-springboot/prompts/bdd.md +15 -0
  92. package/flows/packs/cobol-springboot/prompts/implement.md +31 -0
  93. package/flows/packs/cobol-springboot/prompts/plan.md +13 -0
  94. package/flows/packs/cobol-springboot/prompts/review.md +17 -0
  95. package/flows/packs/cobol-springboot/prompts/spec.md +28 -0
  96. package/flows/packs/cobol-springboot/prompts/vectors.md +22 -0
  97. package/flows/packs/cobol-springboot/reviewers/cobol-fidelity.md +16 -0
  98. package/flows/packs/cobol-springboot/reviewers/pattern-conformance.md +10 -0
  99. package/flows/packs/cobol-springboot/reviewers/traceability.md +13 -0
  100. package/flows/packs/jsp-bff-nextjs/lessons.md +6 -0
  101. package/flows/packs/jsp-bff-nextjs/pack.md +30 -0
  102. package/flows/packs/jsp-bff-nextjs/prompts/analysis.md +20 -0
  103. package/flows/packs/jsp-bff-nextjs/prompts/bdd.md +10 -0
  104. package/flows/packs/jsp-bff-nextjs/prompts/implement.md +17 -0
  105. package/flows/packs/jsp-bff-nextjs/prompts/plan.md +12 -0
  106. package/flows/packs/jsp-bff-nextjs/prompts/review.md +16 -0
  107. package/flows/packs/jsp-bff-nextjs/prompts/spec.md +27 -0
  108. package/flows/packs/jsp-bff-nextjs/reviewers/bff-boundary.md +18 -0
  109. package/flows/packs/jsp-bff-nextjs/reviewers/traceability.md +13 -0
  110. package/flows/packs/jsp-nextjs/lessons.md +6 -0
  111. package/flows/packs/jsp-nextjs/pack.md +29 -0
  112. package/flows/packs/jsp-nextjs/prompts/analysis.md +21 -0
  113. package/flows/packs/jsp-nextjs/prompts/bdd.md +12 -0
  114. package/flows/packs/jsp-nextjs/prompts/implement.md +17 -0
  115. package/flows/packs/jsp-nextjs/prompts/plan.md +14 -0
  116. package/flows/packs/jsp-nextjs/prompts/review.md +16 -0
  117. package/flows/packs/jsp-nextjs/prompts/spec.md +26 -0
  118. package/flows/packs/jsp-nextjs/reviewers/traceability.md +13 -0
  119. package/flows/packs/jsp-nextjs/reviewers/ux-fidelity.md +16 -0
  120. package/flows/patterns/PAT-COBOL-001-comp3-money.md +7 -0
  121. package/flows/patterns/PAT-COBOL-002-redefines.md +7 -0
  122. package/flows/patterns/PAT-COBOL-003-88-levels.md +7 -0
  123. package/flows/patterns/PAT-COBOL-004-perform-thru.md +7 -0
  124. package/flows/patterns/PAT-COBOL-005-file-status.md +6 -0
  125. package/flows/patterns/PAT-COBOL-006-sqlcode.md +7 -0
  126. package/flows/patterns/PAT-COBOL-007-validation-order.md +7 -0
  127. package/flows/patterns/PAT-COBOL-008-zoned-decimal.md +6 -0
  128. package/flows/patterns/PAT-COBOL-009-occurs-table.md +6 -0
  129. package/flows/patterns/PAT-COBOL-010-copybook-record.md +7 -0
  130. package/flows/patterns/PAT-COBOL-011-batch-counters.md +6 -0
  131. package/flows/patterns/PAT-COBOL-012-commit-frequency.md +7 -0
  132. package/flows/patterns/PAT-COBOL-013-abend.md +6 -0
  133. package/flows/patterns/PAT-COBOL-014-reject-file.md +6 -0
  134. package/flows/patterns/PAT-COBOL-015-accept-date.md +6 -0
  135. package/flows/patterns/PAT-COBOL-016-string-building.md +6 -0
  136. package/flows/patterns/PAT-COBOL-017-cursor-loop.md +6 -0
  137. package/flows/patterns/PAT-COBOL-018-yn-switches.md +6 -0
  138. package/flows/patterns/PAT-COBOL-019-shared-accumulators.md +6 -0
  139. package/flows/patterns/PAT-COBOL-020-tiered-fees.md +7 -0
  140. package/flows/patterns/PAT-COBOL-021-overdraft-floor.md +7 -0
  141. package/flows/patterns/PAT-COBOL-022-jcl-job-net.md +6 -0
  142. package/flows/patterns/PAT-COBOL-023-sort-step.md +6 -0
  143. package/flows/patterns/PAT-COBOL-024-fixed-width-records.md +6 -0
  144. package/flows/patterns/PAT-COBOL-025-audit-rows.md +6 -0
  145. package/package.json +5 -4
  146. package/src/Cli.ts +10 -1
@@ -19,8 +19,9 @@
19
19
  // `- [ ] Approved` marker in `docs/modernization/README.md`.
20
20
  //
21
21
  // Pack: LLM4TS_PACK=<dir> (default packs/cobol-springboot, resolved against the
22
- // launch dir). LLM4TS_WAVE=<name> scopes the run to one wave of the approved
23
- // plan. Judge context is bounded by LLM4TS_JUDGE_SOURCES_LIMIT (chars).
22
+ // launch dir, then against the flow's own directory the built-in packs).
23
+ // LLM4TS_WAVE=<name> scopes the run to one wave of the approved plan. Judge
24
+ // context is bounded by LLM4TS_JUDGE_SOURCES_LIMIT (chars).
24
25
  import { join } from "node:path"
25
26
  import * as Effect from "effect/Effect"
26
27
  import { Sample, type EvalResult } from "@llm4ts/core/eval/Eval"
@@ -29,7 +30,7 @@ import type { JsonSchema } from "@llm4ts/core/Models"
29
30
  import { FlowAborted, FlowLlmError } from "@llm4ts/flow/FlowError"
30
31
  import { Info } from "@llm4ts/flow/FlowEvents"
31
32
  import { makeChat } from "@llm4ts/flow/Chat"
32
- import { loadPack, type Pack } from "@llm4ts/flow/Pack"
33
+ import type { Pack } from "@llm4ts/flow/Pack"
33
34
  import { loadPatternCards, matchingPatternCards } from "@llm4ts/flow/Patterns"
34
35
  import { stage } from "@llm4ts/flow/PlanExecution"
35
36
  import { defaultPlanInstructions, planFrom } from "@llm4ts/flow/Planner"
@@ -48,6 +49,7 @@ import { runFlowMain, runNode } from "@llm4ts/runner/FlowRunner"
48
49
  import { reviewFingerprint } from "@llm4ts/runner/ReviewFingerprint"
49
50
  import { nodePlainFileStore } from "@llm4ts/runner/NodePlainFileStore"
50
51
  import { makeNodeWorkspace } from "@llm4ts/runner/NodeWorkspace"
52
+ import { loadUniversalPatternCards, openPack } from "@llm4ts/runner/Packs"
51
53
 
52
54
  const ModDir = "docs/modernization"
53
55
  const MaxRounds = 3
@@ -202,7 +204,6 @@ const program = Effect.gen(function* () {
202
204
  const input = yield* resolveFlowInput(
203
205
  "Extract the complete behavioural spec pack for this legacy estate"
204
206
  )
205
- const packDir = process.env.LLM4TS_PACK ?? "packs/cobol-springboot"
206
207
  const coder = coderFromEnv(process.env)
207
208
  const files = nodePlainFileStore
208
209
  const modDirAbs = join(input.workDir, ModDir)
@@ -218,9 +219,17 @@ const program = Effect.gen(function* () {
218
219
  },
219
220
  (context) =>
220
221
  Effect.gen(function* () {
221
- const launchWorkspace = yield* makeNodeWorkspace(input.workspace)
222
222
  const repo = yield* makeNodeWorkspace(input.workDir)
223
- const pack = yield* stage(context.events, "pack", loadPack(launchWorkspace, packDir))
223
+ const opened = yield* stage(
224
+ context.events,
225
+ "pack",
226
+ openPack({
227
+ environment: process.env,
228
+ launchDir: input.workspace,
229
+ flowDir: import.meta.dirname
230
+ })
231
+ )
232
+ const pack = opened.pack
224
233
  yield* stage(
225
234
  context.events,
226
235
  "branch",
@@ -273,8 +282,8 @@ const program = Effect.gen(function* () {
273
282
  // Pattern cards are selected deterministically from the SOURCE, never by
274
283
  // the model: implementation later injects exactly the cards cited here.
275
284
  const cards = [
276
- ...(yield* loadPatternCards(launchWorkspace, `${packDir}/patterns`)),
277
- ...(yield* loadPatternCards(launchWorkspace, "patterns"))
285
+ ...(yield* loadPatternCards(opened.workspace, `${opened.dir}/patterns`)),
286
+ ...(yield* loadUniversalPatternCards([input.workspace, import.meta.dirname]))
278
287
  ]
279
288
 
280
289
  // One structured analyst call per program, resumable per program: a rerun
@@ -25,7 +25,6 @@ import { judge } from "@llm4ts/core/eval/Judge"
25
25
  import { makeChat } from "@llm4ts/flow/Chat"
26
26
  import { FlowAborted, FlowLlmError, type FlowError } from "@llm4ts/flow/FlowError"
27
27
  import { Info } from "@llm4ts/flow/FlowEvents"
28
- import { loadPack } from "@llm4ts/flow/Pack"
29
28
  import { loadPatternCards, taggedPatternIds } from "@llm4ts/flow/Patterns"
30
29
  import { makePlanStore } from "@llm4ts/flow/Persistence"
31
30
  import { implementTaskLoop, stage } from "@llm4ts/flow/PlanExecution"
@@ -44,6 +43,7 @@ import { runFlowMain, runNode } from "@llm4ts/runner/FlowRunner"
44
43
  import { nodePlainFileStore } from "@llm4ts/runner/NodePlainFileStore"
45
44
  import { nodeProcessExecutor } from "@llm4ts/runner/NodeProcessExecutor"
46
45
  import { makeNodeWorkspace } from "@llm4ts/runner/NodeWorkspace"
46
+ import { loadUniversalPatternCards, openPack } from "@llm4ts/runner/Packs"
47
47
 
48
48
  const ModDir = "docs/modernization"
49
49
 
@@ -87,7 +87,6 @@ const issueText = (issues: ReadonlyArray<ReviewIssue>): string =>
87
87
 
88
88
  const program = Effect.gen(function* () {
89
89
  const input = yield* resolveFlowInput("Implement the seeded modernization plan")
90
- const packDir = process.env.LLM4TS_PACK ?? "packs/cobol-springboot"
91
90
  const coder = coderFromEnv(process.env)
92
91
  const files = nodePlainFileStore
93
92
  const planPath = join(input.workDir, ModDir, "plan.md")
@@ -104,9 +103,17 @@ const program = Effect.gen(function* () {
104
103
  },
105
104
  (context) =>
106
105
  Effect.gen(function* () {
107
- const launchWorkspace = yield* makeNodeWorkspace(input.workspace)
108
106
  const target = yield* makeNodeWorkspace(input.workDir)
109
- const pack = yield* stage(context.events, "pack", loadPack(launchWorkspace, packDir))
107
+ const opened = yield* stage(
108
+ context.events,
109
+ "pack",
110
+ openPack({
111
+ environment: process.env,
112
+ launchDir: input.workspace,
113
+ flowDir: import.meta.dirname
114
+ })
115
+ )
116
+ const pack = opened.pack
110
117
 
111
118
  yield* stage(
112
119
  context.events,
@@ -161,8 +168,8 @@ const program = Effect.gen(function* () {
161
168
  // ids, and only the cited cards reach the brief.
162
169
  const specText = yield* gatherSpecs(target, pack.specsDir)
163
170
  const cards = [
164
- ...(yield* loadPatternCards(launchWorkspace, `${packDir}/patterns`)),
165
- ...(yield* loadPatternCards(launchWorkspace, "patterns"))
171
+ ...(yield* loadPatternCards(opened.workspace, `${opened.dir}/patterns`)),
172
+ ...(yield* loadUniversalPatternCards([input.workspace, import.meta.dirname]))
166
173
  ]
167
174
  const cited = new Set(taggedPatternIds(specText))
168
175
  const playbook = cards.filter((card) => cited.has(card.id))
@@ -22,7 +22,7 @@ import { judge } from "@llm4ts/core/eval/Judge"
22
22
  import type { JsonSchema } from "@llm4ts/core/Models"
23
23
  import { FlowAborted, FlowLlmError } from "@llm4ts/flow/FlowError"
24
24
  import { Info } from "@llm4ts/flow/FlowEvents"
25
- import { appendPackLesson, loadPack, type Pack } from "@llm4ts/flow/Pack"
25
+ import { appendPackLesson, type Pack } from "@llm4ts/flow/Pack"
26
26
  import { makePlanStore } from "@llm4ts/flow/Persistence"
27
27
  import { Plan, Task } from "@llm4ts/flow/Plan"
28
28
  import { stage } from "@llm4ts/flow/PlanExecution"
@@ -40,6 +40,7 @@ import { resolveFlowInput } from "@llm4ts/runner/FlowArgs"
40
40
  import { runFlowMain, runNode } from "@llm4ts/runner/FlowRunner"
41
41
  import { nodePlainFileStore } from "@llm4ts/runner/NodePlainFileStore"
42
42
  import { makeNodeWorkspace } from "@llm4ts/runner/NodeWorkspace"
43
+ import { openPack } from "@llm4ts/runner/Packs"
43
44
 
44
45
  const ModDir = "docs/modernization"
45
46
 
@@ -146,7 +147,6 @@ const distillPrompt = (
146
147
 
147
148
  const program = Effect.gen(function* () {
148
149
  const input = yield* resolveFlowInput("Review the modernization increment against its spec pack")
149
- const packDir = process.env.LLM4TS_PACK ?? "packs/cobol-springboot"
150
150
  const coder = coderFromEnv(process.env)
151
151
  const files = nodePlainFileStore
152
152
  const planPath = join(input.workDir, ModDir, "plan.md")
@@ -163,9 +163,17 @@ const program = Effect.gen(function* () {
163
163
  },
164
164
  (context) =>
165
165
  Effect.gen(function* () {
166
- const launchWorkspace = yield* makeNodeWorkspace(input.workspace)
167
166
  const target = yield* makeNodeWorkspace(input.workDir)
168
- const pack = yield* stage(context.events, "pack", loadPack(launchWorkspace, packDir))
167
+ const opened = yield* stage(
168
+ context.events,
169
+ "pack",
170
+ openPack({
171
+ environment: process.env,
172
+ launchDir: input.workspace,
173
+ flowDir: import.meta.dirname
174
+ })
175
+ )
176
+ const pack = opened.pack
169
177
  const reviewService = context.reviewers[0] ?? context.reasoning
170
178
 
171
179
  yield* stage(
@@ -307,12 +315,12 @@ const program = Effect.gen(function* () {
307
315
  )
308
316
  }
309
317
  for (const lesson of outcome.lessons) {
310
- yield* appendPackLesson(launchWorkspace, packDir, lesson)
318
+ yield* appendPackLesson(opened.workspace, opened.dir, lesson)
311
319
  }
312
320
  yield* context.events.publish(
313
321
  Info.make({
314
322
  message:
315
- `${outcome.lessons.length} lesson(s) appended to ${packDir}/lessons.md — ` +
323
+ `${outcome.lessons.length} lesson(s) appended to ${opened.dir}/lessons.md — ` +
316
324
  "review and commit the pack change"
317
325
  })
318
326
  )
@@ -24,7 +24,6 @@ import * as Schema from "effect/Schema"
24
24
  import { FlowAborted, PersistenceError } from "@llm4ts/flow/FlowError"
25
25
  import { Info } from "@llm4ts/flow/FlowEvents"
26
26
  import { packageVersion } from "@llm4ts/flow/Package"
27
- import { loadPack } from "@llm4ts/flow/Pack"
28
27
  import { parsePlan } from "@llm4ts/flow/Plan"
29
28
  import { stage } from "@llm4ts/flow/PlanExecution"
30
29
  import { Provenance, makeProvenanceStore } from "@llm4ts/flow/Provenance"
@@ -36,6 +35,7 @@ import { resolveFlowInput } from "@llm4ts/runner/FlowArgs"
36
35
  import { runFlowMain, runNode } from "@llm4ts/runner/FlowRunner"
37
36
  import { nodePlainFileStore } from "@llm4ts/runner/NodePlainFileStore"
38
37
  import { makeNodeWorkspace } from "@llm4ts/runner/NodeWorkspace"
38
+ import { openPack } from "@llm4ts/runner/Packs"
39
39
 
40
40
  const ModDir = "docs/modernization"
41
41
  const skipped = new Set([".git", "target", "node_modules", "dist"])
@@ -84,7 +84,6 @@ const copyFile = Effect.fn("modernize-seed.copyFile")(function* (
84
84
 
85
85
  const program = Effect.gen(function* () {
86
86
  const input = yield* resolveFlowInput("Seed the target repository from the approved spec pack")
87
- const packDir = process.env.LLM4TS_PACK ?? "packs/cobol-springboot"
88
87
  const legacyRepo = process.env.LLM4TS_LEGACY_REPO?.trim()
89
88
  const files = nodePlainFileStore
90
89
 
@@ -106,10 +105,18 @@ const program = Effect.gen(function* () {
106
105
  "set LLM4TS_LEGACY_REPO to the legacy repository holding the approved spec pack"
107
106
  })
108
107
  }
109
- const launchWorkspace = yield* makeNodeWorkspace(input.workspace)
110
108
  const legacy = yield* makeNodeWorkspace(legacyRepo)
111
109
  const target = yield* makeNodeWorkspace(input.workDir)
112
- const pack = yield* stage(context.events, "pack", loadPack(launchWorkspace, packDir))
110
+ const opened = yield* stage(
111
+ context.events,
112
+ "pack",
113
+ openPack({
114
+ environment: process.env,
115
+ launchDir: input.workspace,
116
+ flowDir: import.meta.dirname
117
+ })
118
+ )
119
+ const pack = opened.pack
113
120
  const specPackRoot = join(legacyRepo, ModDir)
114
121
 
115
122
  yield* stage(
@@ -138,7 +145,7 @@ const program = Effect.gen(function* () {
138
145
  }
139
146
  // The scaffold path is relative to the pack directory.
140
147
  const scaffoldRoot = join(pack.dir, pack.scaffold)
141
- const scaffold = yield* makeNodeWorkspace(join(input.workspace, scaffoldRoot))
148
+ const scaffold = yield* makeNodeWorkspace(join(opened.workspace.root, scaffoldRoot))
142
149
  const paths = (yield* scaffold.discover()).filter((path) => !isLitter(path))
143
150
  for (const path of paths) {
144
151
  yield* target.write(path, yield* scaffold.read(path))
Binary file
@@ -34,7 +34,7 @@ import {
34
34
  import { renderEquivReport, VectorVerdict } from "@llm4ts/flow/EquivReport"
35
35
  import { FlowAborted, FlowLlmError, PlanParseError } from "@llm4ts/flow/FlowError"
36
36
  import { Info } from "@llm4ts/flow/FlowEvents"
37
- import { loadPack, type Pack } from "@llm4ts/flow/Pack"
37
+ import type { Pack } from "@llm4ts/flow/Pack"
38
38
  import { makePlanStore } from "@llm4ts/flow/Persistence"
39
39
  import { stage } from "@llm4ts/flow/PlanExecution"
40
40
  import { Plan, Task } from "@llm4ts/flow/Plan"
@@ -49,6 +49,7 @@ import { runFlowMain, runNode } from "@llm4ts/runner/FlowRunner"
49
49
  import { nodePlainFileStore } from "@llm4ts/runner/NodePlainFileStore"
50
50
  import { nodeProcessExecutor } from "@llm4ts/runner/NodeProcessExecutor"
51
51
  import { makeNodeWorkspace } from "@llm4ts/runner/NodeWorkspace"
52
+ import { openPack } from "@llm4ts/runner/Packs"
52
53
 
53
54
  const ModDir = "docs/modernization"
54
55
 
@@ -278,7 +279,6 @@ const specPrograms = Effect.fn("modernize-verify.specPrograms")(function* (
278
279
 
279
280
  const program = Effect.gen(function* () {
280
281
  const input = yield* resolveFlowInput("Prove the implementation equivalent to its spec pack")
281
- const packDir = process.env.LLM4TS_PACK ?? "packs/cobol-springboot"
282
282
  const coder = coderFromEnv(process.env)
283
283
  const files = nodePlainFileStore
284
284
  const planPath = join(input.workDir, ModDir, "plan.md")
@@ -295,9 +295,16 @@ const program = Effect.gen(function* () {
295
295
  },
296
296
  (context) =>
297
297
  Effect.gen(function* () {
298
- const launchWorkspace = yield* makeNodeWorkspace(input.workspace)
299
298
  const target = yield* makeNodeWorkspace(input.workDir)
300
- const pack = yield* stage(context.events, "pack", loadPack(launchWorkspace, packDir))
299
+ const { pack } = yield* stage(
300
+ context.events,
301
+ "pack",
302
+ openPack({
303
+ environment: process.env,
304
+ launchDir: input.workspace,
305
+ flowDir: import.meta.dirname
306
+ })
307
+ )
301
308
 
302
309
  yield* stage(
303
310
  context.events,
@@ -0,0 +1,6 @@
1
+ - ESQL routing ladders are business policy tables in disguise: extract them into the
2
+ spec AS TABLES and keep them as declarative data in the target service — once they
3
+ dissolve into nested ifs, nobody can verify them against the source again.
4
+ - MQ failure terminals and reject queues are part of the contract: every failure
5
+ path in the msgflow needs a spec rule and a scenario, or it silently disappears in
6
+ the port.
@@ -0,0 +1,29 @@
1
+ # Pack: ace-integration
2
+
3
+ source: ace
4
+ scaffold: ../../fixtures/scaffolds/spring-boot-service
5
+ sources: .*\.(msgflow|esql)
6
+ specs-dir: docs/specs
7
+ features-dir: src/test/resources/features
8
+
9
+ ## Gates
10
+
11
+ - build: mvn -q -B test-compile
12
+ - test: mvn -q -B test
13
+ - verify: mvn -q -B verify
14
+
15
+ ## Judge
16
+
17
+ - completeness (0..2): Every node in the message flow, every routing rule, validation, reject code, queue interface, message mapping, and threshold/flag in the msgflow/ESQL source is captured in the specs and BDD scenarios; the traceability matrix accounts for every flow node and ESQL module. Score 2 only if nothing material is missing.
18
+ - faithfulness (0..2): Every statement is grounded in the source: reject codes, routing predicates, currency lists, thresholds, flag values, queue names, and field mappings match the ESQL exactly, and nothing is invented. Score 2 only if fully source-grounded.
19
+ - testability (0..2): Scenarios are concrete message-in/outcome-out examples — specific payloads, amounts, currencies, and the exact destination or reject code expected; no vague language. Score 2 only if every scenario is directly encodable as a test.
20
+
21
+ ## Coverage: flow-node
22
+
23
+ files: .*\.msgflow
24
+ unit: <translation xmi:type="utility:ConstantString" string="([^"]+)"/>
25
+
26
+ ## Coverage: esql-module
27
+
28
+ files: .*\.esql
29
+ unit: ^CREATE (?:COMPUTE|FILTER|DATABASE) MODULE (\S+)
@@ -0,0 +1,21 @@
1
+ You are an ESB reverse-engineering analyst. Extract the COMPLETE observable
2
+ behaviour of the IBM ACE (IIB) message flows in this repository into a spec pack
3
+ precise enough that a team who never sees this source can rebuild them as Spring
4
+ Boot integration services.
5
+
6
+ How to read the estate:
7
+
8
+ - The .msgflow is the topology: nodes, their types (MQInput/MQOutput/Compute),
9
+ their labels, and the connections — including FAILURE terminals, which are error
10
+ handling and must be accounted for.
11
+ - Queue names on input/output nodes are the INTERFACES: who sends, who consumes,
12
+ and what each queue means downstream (a CICS request queue means the mainframe is
13
+ the system of record — say so).
14
+ - The ESQL carries the logic: validation rules with their reject codes, routing
15
+ predicates (read every CASE/IF — including account-prefix and currency
16
+ conditions), field-by-field message mappings, thresholds and the flags they set.
17
+ - Static routing tables (SHARED ROW, CASE ladders) are business policy — reproduce
18
+ them as tables in the spec, not prose.
19
+ - Reject envelopes are contract: code, reason, and what wraps the original payload.
20
+
21
+ Never invent behaviour. Ambiguity goes in "Open questions", not guesses.
@@ -0,0 +1,13 @@
1
+ Write Gherkin .feature files encoding the specs as executable message-in/outcome-out
2
+ scenarios — these become the acceptance tests of the new integration service.
3
+
4
+ - One feature per flow (or per coherent rule cluster within one).
5
+ - Scenario shape: Given a payment message with concrete field values, When the
6
+ service processes it, Then it is delivered to <destination> with <mapped fields /
7
+ flags> — or rejected with code <code>.
8
+ - Business vocabulary with the codes kept in the Then step (e.g. `Then the payment
9
+ is rejected with code V01 (unsupported currency)`).
10
+ - Concrete values everywhere: real amounts, currencies, account numbers, IBANs.
11
+ - Cover: every routing branch, EVERY reject code, every threshold boundary (a flag
12
+ at 10000.00 gets scenarios at 9999.99 and 10000.00 per its semantics), and the
13
+ field mappings of each destination message.
@@ -0,0 +1,17 @@
1
+ You implement one task at a time in a Spring Boot 3 / Java 21 integration service
2
+ that replaces an IBM ACE message flow. The committed specs under docs/specs/ and the
3
+ .feature files under src/test/resources/features/ are the contract; the acceptance
4
+ tests encode them — make them pass without weakening them.
5
+
6
+ Non-negotiables when porting ESQL semantics:
7
+
8
+ - Validation order and reject codes match the spec exactly — first-failure-wins,
9
+ codes verbatim.
10
+ - The routing table stays DATA (a declarative table/map the spec's table maps onto),
11
+ not a nest of ifs — reviewers must be able to diff it against the spec table.
12
+ - Amount thresholds keep their inclusive/exclusive semantics; money and amounts are
13
+ BigDecimal — never float/double.
14
+ - Destination messages are built by explicit field-by-field mapping per the spec —
15
+ no passthrough of unmapped fields.
16
+ - Destinations are ports (interfaces); tests capture what was sent where. Keep the
17
+ scaffold's structure and idioms.
@@ -0,0 +1,12 @@
1
+ Derive the implementation task list for the target Spring Boot integration service
2
+ from the spec pack. Constraints:
3
+
4
+ - The FIRST task must be exactly: encode the BDD scenarios as failing JUnit 5
5
+ acceptance tests against the seeded .feature files, driving the service's
6
+ processing entry point with in-memory inputs/outputs (no production code).
7
+ - Early tasks: the message model (typed payment/request/reject types mirroring the
8
+ spec's mappings — money as BigDecimal) and the ports for destinations (interfaces
9
+ the tests can capture; real MQ/HTTP adapters are out of scope for the slice).
10
+ - Then one task per rule cluster in spec order: validation chain with reject codes,
11
+ the routing table, destination mappings, thresholds/flags.
12
+ - Each task names the spec rules (R1, ...) and scenarios it covers.
@@ -0,0 +1,17 @@
1
+ You review a finished modernization increment: a Spring Boot integration service
2
+ built from specs reverse-engineered out of IBM ACE message flows. Judge against the
3
+ committed spec pack, not your own taste.
4
+
5
+ Look specifically for:
6
+
7
+ - Routing drift: predicates, currency lists, or account-prefix rules differing from
8
+ the spec's routing table in any value or in evaluation order.
9
+ - Reject-code drift: wrong codes, reordered validations, missing reject envelope
10
+ fields.
11
+ - Threshold/flag drift: boundaries moved, flags set at the wrong amounts.
12
+ - Mapping gaps: destination message fields missing, renamed, or silently passed
13
+ through unmapped.
14
+ - Weakened tests: scenarios deleted, captured-destination assertions loosened.
15
+
16
+ Classify each finding as FIX (violates the spec) or IMPROVEMENT (compliant but
17
+ worth a follow-up).
@@ -0,0 +1,29 @@
1
+ Write one behavioural spec per message flow as Markdown with exactly these sections:
2
+
3
+ # <Flow> — <one-line purpose>
4
+
5
+ ## Overview
6
+ What the flow does, its trigger (input queue), and where messages can end up.
7
+
8
+ ## Interfaces
9
+ Every queue (name, direction, who is on the other end) and the message format on
10
+ each.
11
+
12
+ ## Routing rules
13
+ Numbered (R1, R2, ...), in evaluation order: the predicate (exact values —
14
+ currencies, prefixes, thresholds with boundary semantics) and the destination.
15
+ Static routing tables reproduced AS TABLES.
16
+
17
+ ## Validation & rejects
18
+ Each validation in order, its reject code, and the reject envelope structure.
19
+
20
+ ## Message mappings
21
+ Field-by-field source→target mappings for each output (e.g. the CICS request built
22
+ from the inbound payment), naming the exact target fields.
23
+
24
+ ## Thresholds & flags
25
+ Every amount threshold and the flag/value it sets (priority, regulatory reporting),
26
+ with inclusive/exclusive semantics.
27
+
28
+ ## Open questions
29
+ Anything ambiguous in the source. Empty if none.
@@ -0,0 +1,19 @@
1
+ ---
2
+ files: .*\.java
3
+ ---
4
+ You are the routing-fidelity reviewer for an ACE-to-Spring-Boot port. Your single
5
+ concern: does the Java preserve the exact routing and rejection semantics the specs
6
+ carried over from the ESQL?
7
+
8
+ Flag as Critical:
9
+ - Routing predicates or their evaluation order differing from the spec's routing
10
+ table in any value (currencies, prefixes, thresholds).
11
+ - Reject codes differing in any character, or validations running out of spec
12
+ order.
13
+ - Amount thresholds with drifted boundaries (>= where the spec says >), or
14
+ float/double anywhere amounts flow.
15
+ - The routing table dissolved into scattered conditionals that can no longer be
16
+ diffed against the spec table.
17
+ - Destination message mappings missing fields the spec maps.
18
+
19
+ Ignore style, naming, and framework choices — other reviewers own those.
@@ -0,0 +1,13 @@
1
+ You are the traceability reviewer for a spec-driven modernization. Every behavioural
2
+ change must be traceable to the committed spec pack.
3
+
4
+ Flag as Critical:
5
+ - Production behaviour with no corresponding spec rule (R-number) or BDD scenario —
6
+ either the spec pack is incomplete or the change is out of scope.
7
+ - Changes to .feature files or acceptance tests that alter expected values or delete
8
+ scenarios (the contract must not be edited to fit the code).
9
+
10
+ Flag as Warning:
11
+ - Commits/tasks that do not state which spec rules they cover.
12
+
13
+ Ignore refactors with no behavioural surface.
@@ -0,0 +1,6 @@
1
+ - ESQL routing ladders are business policy tables in disguise: extract them into the
2
+ spec AS TABLES and keep them as declarative data in the target service — once they
3
+ dissolve into nested ifs, nobody can verify them against the source again.
4
+ - MQ failure terminals and reject queues are part of the contract: every failure
5
+ path in the msgflow needs a spec rule and a scenario, or it silently disappears in
6
+ the port.
@@ -0,0 +1,36 @@
1
+ # Pack: ace-kafka
2
+
3
+ source: ace
4
+ scaffold: ../../fixtures/scaffolds/kafka-streams-service
5
+ sources: .*\.(msgflow|esql)
6
+ programs: .*\.(msgflow|esql)
7
+ specs-dir: docs/specs
8
+ features-dir: src/test/resources/features
9
+ replay: scripts/replay.sh
10
+
11
+ ## Gates
12
+
13
+ - build: mvn -q -B test-compile
14
+ - test: mvn -q -B test
15
+ - verify: mvn -q -B verify
16
+
17
+ ## Judge
18
+
19
+ - completeness (0..2): Every node in the message flow, every routing rule, validation, reject code, interface, message mapping, and threshold/flag in the msgflow/ESQL source is captured in the specs and BDD scenarios — re-expressed as event contracts (topics, keys, event payloads); the traceability matrix accounts for every flow node and ESQL module. Score 2 only if nothing material is missing.
20
+ - faithfulness (0..2): Every statement is grounded in the source: reject codes, routing predicates, currency lists, thresholds, flag values, and field mappings match the ESQL exactly, and nothing is invented — renaming a queue to a topic is mapping, changing its meaning is invention. Score 2 only if fully source-grounded.
21
+ - testability (0..2): Scenarios are concrete event-in/events-out examples — specific payloads, amounts, currencies, correlation keys, and the exact output topic or reject code expected; no vague language. Score 2 only if every scenario is directly encodable as a TopologyTestDriver test.
22
+
23
+ ## Equivalence
24
+
25
+ - ordering: per-key
26
+ - ignore: TIMESTAMP, TS, PROCESSED_AT
27
+
28
+ ## Coverage: flow-node
29
+
30
+ files: .*\.msgflow
31
+ unit: <translation xmi:type="utility:ConstantString" string="([^"]+)"/>
32
+
33
+ ## Coverage: esql-module
34
+
35
+ files: .*\.esql
36
+ unit: ^CREATE (?:COMPUTE|FILTER|DATABASE) MODULE (\S+)
@@ -0,0 +1,21 @@
1
+ You are an ESB reverse-engineering analyst. Extract the COMPLETE observable
2
+ behaviour of the IBM ACE (IIB) message flows in this repository into a spec pack
3
+ precise enough that a team who never sees this source can rebuild them as Spring
4
+ Boot integration services.
5
+
6
+ How to read the estate:
7
+
8
+ - The .msgflow is the topology: nodes, their types (MQInput/MQOutput/Compute),
9
+ their labels, and the connections — including FAILURE terminals, which are error
10
+ handling and must be accounted for.
11
+ - Queue names on input/output nodes are the INTERFACES: who sends, who consumes,
12
+ and what each queue means downstream (a CICS request queue means the mainframe is
13
+ the system of record — say so).
14
+ - The ESQL carries the logic: validation rules with their reject codes, routing
15
+ predicates (read every CASE/IF — including account-prefix and currency
16
+ conditions), field-by-field message mappings, thresholds and the flags they set.
17
+ - Static routing tables (SHARED ROW, CASE ladders) are business policy — reproduce
18
+ them as tables in the spec, not prose.
19
+ - Reject envelopes are contract: code, reason, and what wraps the original payload.
20
+
21
+ Never invent behaviour. Ambiguity goes in "Open questions", not guesses.
@@ -0,0 +1,13 @@
1
+ Write Gherkin .feature files encoding the specs as executable message-in/outcome-out
2
+ scenarios — these become the acceptance tests of the new integration service.
3
+
4
+ - One feature per flow (or per coherent rule cluster within one).
5
+ - Scenario shape: Given a payment event with concrete field values and key, When
6
+ the topology processes it, Then an event is emitted on <output topic> with
7
+ <mapped fields / flags> — or a reject event with code <code>.
8
+ - Business vocabulary with the codes kept in the Then step (e.g. `Then the payment
9
+ is rejected with code V01 (unsupported currency)`).
10
+ - Concrete values everywhere: real amounts, currencies, account numbers, IBANs.
11
+ - Cover: every routing branch, EVERY reject code, every threshold boundary (a flag
12
+ at 10000.00 gets scenarios at 9999.99 and 10000.00 per its semantics), and the
13
+ field mappings of each destination message.
@@ -0,0 +1,34 @@
1
+ You implement one task at a time in a Kafka Streams / Java 21 service that replaces
2
+ an IBM ACE message flow with an event-streaming topology. The committed specs under
3
+ docs/specs/ and the .feature files under src/test/resources/features/ are the
4
+ contract; the acceptance tests encode them — make them pass without weakening them.
5
+
6
+ Non-negotiables when porting ESQL semantics to a topology:
7
+
8
+ - Queues become topics per the spec's interface mapping: one input topic for the
9
+ flow's trigger, one output topic per destination (CICS bridge, SEPA gateway,
10
+ rejects). The event KEY is the correlation identity the spec names (the payment's
11
+ debtor account unless the spec says otherwise) — per-key ordering is contract.
12
+ - Validation order and reject codes match the spec exactly — first-failure-wins,
13
+ codes verbatim; a rejected payment emits ONE reject event and nothing else.
14
+ - The routing table stays DATA (a declarative map the spec's table maps onto), not
15
+ a nest of ifs — reviewers must be able to diff it against the spec table.
16
+ - Amount thresholds keep their inclusive/exclusive semantics; money is BigDecimal —
17
+ never float/double, and never a double-backed Serde.
18
+ - Destination events are built by explicit field-by-field mapping per the spec — no
19
+ passthrough of unmapped fields.
20
+ - The topology is built by a pure `Topology buildTopology()` factory the tests and
21
+ the replay harness drive with TopologyTestDriver — no broker in the test path.
22
+ Keep the scaffold's structure and idioms.
23
+
24
+ Replay harness (equivalence verification — part of the contract, same rules as tests):
25
+
26
+ - The scaffold ships scripts/replay.sh; it runs com.meridian.replay.ReplayHarness,
27
+ which YOU implement: read one equivalence vector as JSON on stdin, print a JSON
28
+ array of observations on stdout — nothing else on stdout, ever.
29
+ - The vector's "inputs" is a flat string map: the inbound event's fields using the
30
+ specs' names, plus "topic:" for the input topic and "key:" for the event key.
31
+ Feed exactly one input event through TopologyTestDriver and emit every output
32
+ event, in per-key order, as:
33
+ {"type":"message","topic":"<output topic>","key":"<event key>","fields":{...}}
34
+ - Amounts as plain scale-2 decimal strings, codes verbatim from the specs.
@@ -0,0 +1,12 @@
1
+ Derive the implementation task list for the target Spring Boot integration service
2
+ from the spec pack. Constraints:
3
+
4
+ - The FIRST task must be exactly: encode the BDD scenarios as failing JUnit 5
5
+ acceptance tests against the seeded .feature files, driving the service's
6
+ processing entry point with in-memory inputs/outputs (no production code).
7
+ - Early tasks: the message model (typed payment/request/reject types mirroring the
8
+ spec's mappings — money as BigDecimal) and the ports for destinations (interfaces
9
+ the tests can capture; real MQ/HTTP adapters are out of scope for the slice).
10
+ - Then one task per rule cluster in spec order: validation chain with reject codes,
11
+ the routing table, destination mappings, thresholds/flags.
12
+ - Each task names the spec rules (R1, ...) and scenarios it covers.
@@ -0,0 +1,17 @@
1
+ You review a finished modernization increment: a Spring Boot integration service
2
+ built from specs reverse-engineered out of IBM ACE message flows. Judge against the
3
+ committed spec pack, not your own taste.
4
+
5
+ Look specifically for:
6
+
7
+ - Routing drift: predicates, currency lists, or account-prefix rules differing from
8
+ the spec's routing table in any value or in evaluation order.
9
+ - Reject-code drift: wrong codes, reordered validations, missing reject envelope
10
+ fields.
11
+ - Threshold/flag drift: boundaries moved, flags set at the wrong amounts.
12
+ - Mapping gaps: destination message fields missing, renamed, or silently passed
13
+ through unmapped.
14
+ - Weakened tests: scenarios deleted, captured-destination assertions loosened.
15
+
16
+ Classify each finding as FIX (violates the spec) or IMPROVEMENT (compliant but
17
+ worth a follow-up).