guardian-framework 0.1.79 → 0.1.81

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.
package/dist/cli.js CHANGED
@@ -3197,7 +3197,7 @@ __export(exports_package, {
3197
3197
  bin: () => bin,
3198
3198
  author: () => author
3199
3199
  });
3200
- var name = "guardian-framework", version = "0.1.79", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
3200
+ var name = "guardian-framework", version = "0.1.81", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
3201
3201
  var init_package = __esm(() => {
3202
3202
  exports = {
3203
3203
  ".": {
@@ -12438,6 +12438,23 @@ ${bc.description}
12438
12438
 
12439
12439
  `;
12440
12440
  content += `${depsSection}
12441
+ `;
12442
+ content += `## Acceptance Criteria
12443
+
12444
+ `;
12445
+ content += `Each component in this module must satisfy its specific acceptance criteria.
12446
+ `;
12447
+ content += `Fill these out for each component before implementation begins.
12448
+ `;
12449
+ content += `
12450
+ `;
12451
+ content += `| # | Component | Criterion | Verify In |
12452
+ `;
12453
+ content += `|---|-----------|-----------|-----------|
12454
+ `;
12455
+ content += `| 1 | [Component] | [Specific, testable criterion] | [unit / integration / manual] |
12456
+ `;
12457
+ content += `
12441
12458
  `;
12442
12459
  content += `## Key Files
12443
12460
 
@@ -12641,6 +12658,24 @@ ${bc.description}
12641
12658
  content += `Each layer MUST NOT leak into adjacent layers.
12642
12659
  `;
12643
12660
  content += `
12661
+ `;
12662
+ content += `## Acceptance Criteria
12663
+ `;
12664
+ content += `
12665
+ `;
12666
+ content += `Each component in this module must satisfy its specific acceptance criteria.
12667
+ `;
12668
+ content += `Fill these out for each component before implementation begins.
12669
+ `;
12670
+ content += `
12671
+ `;
12672
+ content += `| # | Component | Criterion | Verify In |
12673
+ `;
12674
+ content += `|---|-----------|-----------|-----------|
12675
+ `;
12676
+ content += `| 1 | [Component] | [Specific, testable criterion] | [unit / integration / manual] |
12677
+ `;
12678
+ content += `
12644
12679
  `;
12645
12680
  content += `## ADRs
12646
12681
  `;
package/dist/exports.js CHANGED
@@ -1982,7 +1982,7 @@ __export(exports_package, {
1982
1982
  bin: () => bin,
1983
1983
  author: () => author
1984
1984
  });
1985
- var name = "guardian-framework", version = "0.1.79", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
1985
+ var name = "guardian-framework", version = "0.1.81", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
1986
1986
  var init_package = __esm(() => {
1987
1987
  exports = {
1988
1988
  ".": {
@@ -12762,6 +12762,23 @@ ${bc.description}
12762
12762
 
12763
12763
  `;
12764
12764
  content += `${depsSection}
12765
+ `;
12766
+ content += `## Acceptance Criteria
12767
+
12768
+ `;
12769
+ content += `Each component in this module must satisfy its specific acceptance criteria.
12770
+ `;
12771
+ content += `Fill these out for each component before implementation begins.
12772
+ `;
12773
+ content += `
12774
+ `;
12775
+ content += `| # | Component | Criterion | Verify In |
12776
+ `;
12777
+ content += `|---|-----------|-----------|-----------|
12778
+ `;
12779
+ content += `| 1 | [Component] | [Specific, testable criterion] | [unit / integration / manual] |
12780
+ `;
12781
+ content += `
12765
12782
  `;
12766
12783
  content += `## Key Files
12767
12784
 
@@ -12965,6 +12982,24 @@ ${bc.description}
12965
12982
  content += `Each layer MUST NOT leak into adjacent layers.
12966
12983
  `;
12967
12984
  content += `
12985
+ `;
12986
+ content += `## Acceptance Criteria
12987
+ `;
12988
+ content += `
12989
+ `;
12990
+ content += `Each component in this module must satisfy its specific acceptance criteria.
12991
+ `;
12992
+ content += `Fill these out for each component before implementation begins.
12993
+ `;
12994
+ content += `
12995
+ `;
12996
+ content += `| # | Component | Criterion | Verify In |
12997
+ `;
12998
+ content += `|---|-----------|-----------|-----------|
12999
+ `;
13000
+ content += `| 1 | [Component] | [Specific, testable criterion] | [unit / integration / manual] |
13001
+ `;
13002
+ content += `
12968
13003
  `;
12969
13004
  content += `## ADRs
12970
13005
  `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "guardian-framework",
3
- "version": "0.1.79",
3
+ "version": "0.1.81",
4
4
  "description": "Token-optimized agentic framework scaffolder with pi-first architecture",
5
5
  "type": "module",
6
6
  "main": "dist/exports.js",
@@ -9,10 +9,59 @@
9
9
  * reach the agent. The agent makes them green via Red→Green→Refactor.
10
10
  */
11
11
 
12
- import { existsSync, mkdirSync, writeFileSync } from "node:fs";
12
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
13
13
  import { join } from "node:path";
14
14
  import type { ModuleComponent } from "./types.ts";
15
15
 
16
+ // ── Java package derivation (from project manifest) ──
17
+
18
+ /** Read groupId from guardian-manifest.json (never from pom.xml). */
19
+ function readGroupId(cwd: string): string {
20
+ try {
21
+ const raw = readFileSync(join(cwd, "guardian-manifest.json"), "utf-8");
22
+ const manifest = JSON.parse(raw);
23
+ if (manifest.groupId && typeof manifest.groupId === "string") {
24
+ return manifest.groupId;
25
+ }
26
+ } catch {}
27
+ return "com.example";
28
+ }
29
+
30
+ /**
31
+ * Read the module→Java-package mapping from guardian-manifest.json.
32
+ * The manifest should have a `javaModulePackages` field:
33
+ * \`\`\`json
34
+ * {
35
+ * "javaModulePackages": {
36
+ * "integration-acl": "acl",
37
+ * "order-intake": "orderintake"
38
+ * }
39
+ * }
40
+ * \`\`\`
41
+ * Missing modules throw — no silent fallback to bad paths.
42
+ */
43
+ function readJavaModulePackages(cwd: string): Record<string, string> {
44
+ try {
45
+ const raw = readFileSync(join(cwd, "guardian-manifest.json"), "utf-8");
46
+ const manifest = JSON.parse(raw);
47
+ if (manifest.javaModulePackages && typeof manifest.javaModulePackages === "object") {
48
+ return manifest.javaModulePackages;
49
+ }
50
+ } catch {}
51
+ return {};
52
+ }
53
+
54
+ /** Resolve a module ID to its Java sub-package suffix. Throws if unknown. */
55
+ function javaModulePackage(cwd: string, moduleId: string): string {
56
+ const mapping = readJavaModulePackages(cwd);
57
+ const pkg = mapping[moduleId];
58
+ if (pkg) return pkg;
59
+ throw new Error(
60
+ `Unknown Java package for module "${moduleId}". ` +
61
+ `Add it to the "javaModulePackages" field in guardian-manifest.json.`
62
+ );
63
+ }
64
+
16
65
  // ── Supported Languages ──
17
66
 
18
67
  const TDD_LANGUAGES = new Set(["typescript", "rust", "python", "go", "java"]);
@@ -60,8 +109,14 @@ export function generateEpicTestFiles(options: TddGenerateOptions): string[] {
60
109
  let modulePath: string;
61
110
 
62
111
  if (language === "java") {
63
- testBaseDir = testBaseDir ?? "src/test/java";
64
- modulePath = (moduleName || moduleId).replace(/[^a-zA-Z0-9\/]/g, "-");
112
+ // Java: src/test/java/<groupId-path>/<module-package>/
113
+ // All components in the same module share the same package dir.
114
+ const groupId = readGroupId(cwd);
115
+ const groupPath = groupId.replace(/\./g, "/");
116
+ const modPkg = javaModulePackage(cwd, moduleName || moduleId);
117
+ const modPath = modPkg.replace(/\./g, "/");
118
+ testBaseDir = testBaseDir ?? join("src", "test", "java");
119
+ modulePath = join(groupPath, modPath);
65
120
  } else {
66
121
  testBaseDir = testBaseDir ?? "tests/unit";
67
122
  modulePath = moduleName || moduleId;
@@ -72,7 +127,19 @@ export function generateEpicTestFiles(options: TddGenerateOptions): string[] {
72
127
  for (const comp of components) {
73
128
  const componentId = comp.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
74
129
 
75
- const testDir = join(cwd, testBaseDir, modulePath, componentId);
130
+ let testDir: string;
131
+ let javaPackage: string | undefined;
132
+
133
+ if (language === "java") {
134
+ // No componentId subdir — all components in same package dir
135
+ testDir = join(cwd, testBaseDir, modulePath);
136
+ const groupId = readGroupId(cwd);
137
+ const modPkg = javaModulePackage(cwd, moduleName || moduleId);
138
+ javaPackage = `${groupId}.${modPkg}`;
139
+ } else {
140
+ testDir = join(cwd, testBaseDir, modulePath, componentId);
141
+ }
142
+
76
143
  mkdirSync(testDir, { recursive: true });
77
144
 
78
145
  const fileName = getTestFileName(componentId, language);
@@ -81,7 +148,7 @@ export function generateEpicTestFiles(options: TddGenerateOptions): string[] {
81
148
  // Skip if file already exists (don't overwrite user edits)
82
149
  if (existsSync(filePath)) continue;
83
150
 
84
- const content = generateTestContent(comp, language, moduleId, componentId);
151
+ const content = generateTestContent(comp, language, moduleId, componentId, javaPackage);
85
152
  writeFileSync(filePath, content, "utf-8");
86
153
  generated.push(filePath);
87
154
  }
@@ -115,6 +182,7 @@ function generateTestContent(
115
182
  language: string,
116
183
  moduleId: string,
117
184
  componentId: string,
185
+ javaPackage?: string,
118
186
  ): string {
119
187
  switch (language) {
120
188
  case "rust":
@@ -124,7 +192,7 @@ function generateTestContent(
124
192
  case "go":
125
193
  return generateGo(component, moduleId, componentId);
126
194
  case "java":
127
- return generateJava(component, moduleId, componentId);
195
+ return generateJava(component, moduleId, componentId, javaPackage);
128
196
  case "typescript":
129
197
  default:
130
198
  return generateTypeScript(component, moduleId, componentId);
@@ -136,7 +204,7 @@ function generateTestContent(
136
204
  function generateTypeScript(
137
205
  component: ModuleComponent,
138
206
  moduleId: string,
139
- _componentId: string,
207
+ componentId: string,
140
208
  ): string {
141
209
  const lines: string[] = [
142
210
  `// Generated by Guardian TDD`,
@@ -310,6 +378,7 @@ function generateJava(
310
378
  component: ModuleComponent,
311
379
  moduleId: string,
312
380
  componentId: string,
381
+ javaPackage?: string,
313
382
  ): string {
314
383
  const clsName = toPascalCase(componentId);
315
384
  const lines: string[] = [
@@ -317,6 +386,14 @@ function generateJava(
317
386
  `// From: ${component.name} (${moduleId} module)`,
318
387
  `// These tests will FAIL until ${component.name} is implemented.`,
319
388
  ``,
389
+ ];
390
+
391
+ // Always include package declaration for Java
392
+ if (javaPackage) {
393
+ lines.push(`package ${javaPackage};`, ``);
394
+ }
395
+
396
+ lines.push(
320
397
  `import org.junit.jupiter.api.Test;`,
321
398
  `import static org.junit.jupiter.api.Assertions.*;`,
322
399
  ``,
@@ -329,10 +406,10 @@ function generateJava(
329
406
  ` // assertNotNull(instance);`,
330
407
  ` fail("Test not yet implemented");`,
331
408
  ` }`,
332
- ];
409
+ );
333
410
 
334
411
  for (const dep of component.dependencies) {
335
- lines.push(...[
412
+ lines.push(
336
413
  ``,
337
414
  ` @Test`,
338
415
  ` void test${clsName}_InteractsWith_${capitalize(dep.replace(/[^a-zA-Z0-9]/g, ""))}() {`,
@@ -341,11 +418,10 @@ function generateJava(
341
418
  ` // ${clsName} instance = new ${clsName}(mock);`,
342
419
  ` fail("Dependency test not yet implemented");`,
343
420
  ` }`,
344
- ]);
421
+ );
345
422
  }
346
423
 
347
- lines.push(`}`);
348
- lines.push(``);
424
+ lines.push(`}`, ``);
349
425
  return lines.join("\n");
350
426
  }
351
427
 
@@ -1034,12 +1034,13 @@ export default function (pi: ExtensionAPI) {
1034
1034
  "",
1035
1035
  "1. **## Related ADRs** — Links to ADR files with descriptions of relevance",
1036
1036
  "2. **## Diagrams** — Embed the 4 mermaid diagrams from Step 2",
1037
- "3. **## Components** — Expand each aggregate with " + lang + " stubs, methods, invariants keep `status:` and `depends:` markers",
1038
- "4. **Domain Events** — Table: Event, Description, Trigger, Payload, Published By",
1039
- "5. **API Endpoints** — Table: Method, Path, Handler, Input, Output, Auth",
1040
- "6. **Ubiquitous Language** — Terms for this context from `.pi/domain/ubiquitous-language.md`",
1041
- "7. **Dependencies** — Depends On + Used By",
1042
- "8. **Implementation Sequence** — Ordered build list",
1037
+ "3. **## Acceptance Criteria** — Add a table row for each component: | # | Component | Criterion | Verify In | with specific, testable acceptance criteria",
1038
+ "5. **## Components** — Expand each aggregate with " + lang + " stubs, methods, invariants keep `status:` and `depends:` markers",
1039
+ "6. **Domain Events** — Table: Event, Description, Trigger, Payload, Published By",
1040
+ "7. **API Endpoints** — Table: Method, Path, Handler, Input, Output, Auth",
1041
+ "8. **Ubiquitous Language** — Terms for this context from `.pi/domain/ubiquitous-language.md`",
1042
+ "9. **Dependencies** — Depends On + Used By",
1043
+ "10. **Implementation Sequence** — Ordered build list",
1043
1044
  "",
1044
1045
  "### STEP 4: Generate Implementation Roadmap",
1045
1046
  "",
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2026-07-16T09:34:57Z",
2
+ "timestamp": "2026-07-16T13:01:09Z",
3
3
  "mode": "all",
4
4
  "stages_run": [],
5
5
  "summary": {
@@ -8,7 +8,7 @@
8
8
  "failed": 1,
9
9
  "skipped": 12
10
10
  },
11
- "duration_seconds": 0,
11
+ "duration_seconds": 1,
12
12
  "results": [
13
13
  {
14
14
  "name": "check_mr_traceability.sh",
@@ -56,7 +56,7 @@
56
56
  "name": "cargo test --lib",
57
57
  "status": "fail",
58
58
  "message": "unit test failures",
59
- "duration": 0
59
+ "duration": 1
60
60
  },
61
61
  {
62
62
  "name": "integration",