guardian-framework 0.1.126 → 0.1.128

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
@@ -3202,7 +3202,7 @@ __export(exports_package, {
3202
3202
  bin: () => bin,
3203
3203
  author: () => author
3204
3204
  });
3205
- var name = "guardian-framework", version = "0.1.126", 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;
3205
+ var name = "guardian-framework", version = "0.1.128", 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;
3206
3206
  var init_package = __esm(() => {
3207
3207
  exports = {
3208
3208
  ".": {
@@ -12376,7 +12376,12 @@ function scaffoldFromExploration(sessionId, options) {
12376
12376
  const depthHeaderNote = bc.subdomainType === undefined || bc.subdomainType === null ? " (unclassified \u2014 defaulted to tactical; re-run exploration with ADR-008 depth)" : "";
12377
12377
  const contextEdges = (result.contextMap || []).filter((e) => e.from === bc.name || e.to === bc.name);
12378
12378
  const invariants = bc.invariants || [];
12379
+ const force = options?.overwrite === true;
12379
12380
  if (!dryRun && fs.existsSync(filePath)) {
12381
+ if (!force) {
12382
+ warnings.push(`Module already exists, preserved (use overwrite:true to replace): ${fileName}`);
12383
+ continue;
12384
+ }
12380
12385
  warnings.push(`Module already exists, will be overwritten: ${fileName}`);
12381
12386
  }
12382
12387
  const aggregateRoots = contextEntities.filter((e) => e.type === "aggregate-root");
package/dist/exports.js CHANGED
@@ -1987,7 +1987,7 @@ __export(exports_package, {
1987
1987
  bin: () => bin,
1988
1988
  author: () => author
1989
1989
  });
1990
- var name = "guardian-framework", version = "0.1.126", 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;
1990
+ var name = "guardian-framework", version = "0.1.128", 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;
1991
1991
  var init_package = __esm(() => {
1992
1992
  exports = {
1993
1993
  ".": {
@@ -12700,7 +12700,12 @@ function scaffoldFromExploration(sessionId, options) {
12700
12700
  const depthHeaderNote = bc.subdomainType === undefined || bc.subdomainType === null ? " (unclassified — defaulted to tactical; re-run exploration with ADR-008 depth)" : "";
12701
12701
  const contextEdges = (result.contextMap || []).filter((e) => e.from === bc.name || e.to === bc.name);
12702
12702
  const invariants = bc.invariants || [];
12703
+ const force = options?.overwrite === true;
12703
12704
  if (!dryRun && fs12.existsSync(filePath)) {
12705
+ if (!force) {
12706
+ warnings.push(`Module already exists, preserved (use overwrite:true to replace): ${fileName}`);
12707
+ continue;
12708
+ }
12704
12709
  warnings.push(`Module already exists, will be overwritten: ${fileName}`);
12705
12710
  }
12706
12711
  const aggregateRoots = contextEntities.filter((e) => e.type === "aggregate-root");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "guardian-framework",
3
- "version": "0.1.126",
3
+ "version": "0.1.128",
4
4
  "description": "Token-optimized agentic framework scaffolder with pi-first architecture",
5
5
  "type": "module",
6
6
  "main": "dist/exports.js",
@@ -978,10 +978,12 @@ export default function (pi: ExtensionAPI) {
978
978
  // /domain --architect-scaffold <session-id>
979
979
  // /domain --architect-scaffold <session-id>
980
980
  if (trimmed.startsWith("--architect-scaffold")) {
981
- const sessionId = trimmed.slice("--architect-scaffold".length).trim();
981
+ const rest = trimmed.slice("--architect-scaffold".length).trim();
982
+ const forceScaffold = rest.includes("--force");
983
+ const sessionId = rest.split(/\s+/)[0] || "";
982
984
  if (!sessionId) {
983
985
  ctx.ui.notify(
984
- "Usage: /domain --architect-scaffold <session-id>",
986
+ "Usage: /domain --architect-scaffold <session-id> [--force]",
985
987
  "error",
986
988
  );
987
989
  return "(domain command handled)";
@@ -1079,8 +1081,13 @@ export default function (pi: ExtensionAPI) {
1079
1081
  ctx.ui.notify("Module scaffold unavailable - agent can create docs directly", "info");
1080
1082
  }
1081
1083
 
1082
- // Step 2: Always regenerate ADR-001 to reflect current session
1084
+ // Step 2: Refresh ADR-001 only when it does not exist yet (or --force).
1085
+ // Never clobber an existing ADR that documents implemented architecture.
1083
1086
  const adrPath = path.join(decisionsDir, "ADR-001-architecture-pattern.md");
1087
+ if (fs.existsSync(adrPath) && !forceScaffold) {
1088
+ ctx.ui.notify("Existing ADR-001 preserved — module docs scaffolded (use --force to refresh ADR)", "info");
1089
+ return "(domain command handled)";
1090
+ }
1084
1091
  const bcList = bcNames.length > 0
1085
1092
  ? bcNames.map(n => " - " + n).join("\n")
1086
1093
  : " - (to be defined during architecture planning)";
@@ -1229,9 +1236,11 @@ export default function (pi: ExtensionAPI) {
1229
1236
  return resultLines.join("\n");
1230
1237
  }
1231
1238
  if (trimmed.startsWith("--enrich")) {
1232
- const sessionId = trimmed.slice("--enrich".length).trim();
1239
+ const restE = trimmed.slice("--enrich".length).trim();
1240
+ const forceEnrich = restE.includes("--force");
1241
+ const sessionId = restE.split(/\s+/)[0] || "";
1233
1242
  if (!sessionId) {
1234
- ctx.ui.notify("Usage: /domain --enrich <session-id>", "error");
1243
+ ctx.ui.notify("Usage: /domain --enrich <session-id> [--force]", "error");
1235
1244
  return "(domain command handled)";
1236
1245
  }
1237
1246
 
@@ -1244,9 +1253,45 @@ export default function (pi: ExtensionAPI) {
1244
1253
  return "(domain command handled)";
1245
1254
  }
1246
1255
 
1247
- const moduleFiles = fs.readdirSync(modulesDir).filter(f => f.endsWith(".md") && f !== "module-template.md");
1256
+ // Enrichment is SESSION-SCOPED: only module docs that belong to THIS
1257
+ // session's bounded contexts may be touched, and existing module docs
1258
+ // are preserved unless --force. Prevents clobbering other streams.
1259
+ const allModules = fs.readdirSync(modulesDir).filter(f => f.endsWith(".md") && f !== "module-template.md");
1260
+ const kebab = (n: string) => n.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
1261
+ let sessionModules: string[] = [];
1262
+ const sRawPath = path.join(explorationDir, sessionId + ".raw.json");
1263
+ if (fs.existsSync(sRawPath)) {
1264
+ try {
1265
+ const rawS = JSON.parse(fs.readFileSync(sRawPath, "utf-8")) as Record<string, unknown>;
1266
+ const bcs = Array.isArray(rawS.boundedContexts) ? (rawS.boundedContexts as Record<string, unknown>[]) : [];
1267
+ sessionModules = bcs.map((bc) => kebab(String(bc.name ?? "")) + ".md").filter((n) => allModules.includes(n));
1268
+ } catch { /* ignore */ }
1269
+ }
1270
+ if (sessionModules.length === 0) {
1271
+ // fallback: session md bounded-contexts table
1272
+ const md = fs.existsSync(sessionPath) ? fs.readFileSync(sessionPath, "utf-8") : "";
1273
+ const m = md.match(/## Bounded Contexts[\s\S]*?\n((?:\|.*\n)+?)(?=\n##|$)/);
1274
+ if (m) {
1275
+ sessionModules = m[1].split("\n")
1276
+ .map((l) => l.split("|").map((c) => c.trim()).filter(Boolean)[0])
1277
+ .filter(Boolean)
1278
+ .map((n) => kebab(n) + ".md")
1279
+ .filter((n) => allModules.includes(n));
1280
+ }
1281
+ }
1282
+ const preserved: string[] = [];
1283
+ const moduleFiles = sessionModules.filter((f) => {
1284
+ if (fs.existsSync(path.join(modulesDir, f)) && !forceEnrich) {
1285
+ preserved.push(f);
1286
+ return false;
1287
+ }
1288
+ return true;
1289
+ });
1290
+ if (preserved.length > 0) {
1291
+ ctx.ui.notify("Preserving existing module docs (use --force to enrich): " + preserved.join(", "), "info");
1292
+ }
1248
1293
  if (moduleFiles.length === 0) {
1249
- ctx.ui.notify("No module docs found. Run /domain --architect-scaffold " + sessionId + " first.", "error");
1294
+ ctx.ui.notify("No new module docs for this session. Existing docs preserved — no enrich needed (or pass --force).", "error");
1250
1295
  return "(domain command handled)";
1251
1296
  }
1252
1297
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2026-09-06T11:30:37Z",
2
+ "timestamp": "2026-09-06T13:11:45Z",
3
3
  "mode": "all",
4
4
  "stages_run": [],
5
5
  "summary": {
@@ -109,7 +109,7 @@ if [ -d ".pi/architecture/modules" ]; then
109
109
  # concrete impl markers (Jdbc*/Jpa*/Local*/InMemory*/Hibernate*/...);
110
110
  # in tactical modules ANY .infrastructure. import from web layer is a leak
111
111
  case "$cls" in
112
- Jdbc*|Jpa*|Local*|InMemory*|Hibernate*|Sql*|FileStore*|OutboxStore*)
112
+ Jdbc*|Jpa*|Local*|InMemory*|Hibernate*|Sql*)
113
113
  report "$f" "$ln" "web-layer-leak" "web layer imports CONCRETE infrastructure impl $cls — depend on a port/interface via the application layer"
114
114
  ;;
115
115
  esac
@@ -149,6 +149,12 @@ if [ -d ".pi/architecture/modules" ]; then
149
149
  [ -n "$n" ] || continue
150
150
  case " $names " in *" $n "*) ;; *) names="$names $n" ;; esac
151
151
  done
152
+ # infix markers: MoneyOutIntentJdbcRepository -> MoneyOutIntentRepository
153
+ for marker in Jpa Jdbc Hibernate Spring; do
154
+ n="${stem//$marker/}"
155
+ [ -n "$n" ] || continue
156
+ case " $names " in *" $n "*) ;; *) names="$names $n" ;; esac
157
+ done
152
158
  found=""
153
159
  for n in $names; do
154
160
  if grep -rqiE "interface ${n}\\b|class ${n}\\b" "$match_dir/domain" --include="*.java" 2>/dev/null; then