@opengsd/gsd-pi 1.5.0-dev.4fb2d460 → 1.5.0-dev.c4c8885f

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 (234) hide show
  1. package/dist/resources/.managed-resources-content-hash +1 -1
  2. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +114 -36
  3. package/dist/resources/extensions/gsd/activity-log.js +1 -1
  4. package/dist/resources/extensions/gsd/auto/orchestrator.js +16 -10
  5. package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
  6. package/dist/resources/extensions/gsd/auto-dispatch.js +53 -15
  7. package/dist/resources/extensions/gsd/auto-model-selection.js +28 -1
  8. package/dist/resources/extensions/gsd/auto-post-unit.js +4 -3
  9. package/dist/resources/extensions/gsd/auto-prompts.js +29 -117
  10. package/dist/resources/extensions/gsd/auto-start.js +53 -30
  11. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +12 -2
  12. package/dist/resources/extensions/gsd/auto-timers.js +9 -2
  13. package/dist/resources/extensions/gsd/auto.js +97 -31
  14. package/dist/resources/extensions/gsd/compat/compat-marker.js +44 -0
  15. package/dist/resources/extensions/gsd/config-overlay.js +7 -2
  16. package/dist/resources/extensions/gsd/db/engine.js +33 -0
  17. package/dist/resources/extensions/gsd/db-adapter.js +30 -3
  18. package/dist/resources/extensions/gsd/docs/preferences-reference.md +3 -3
  19. package/dist/resources/extensions/gsd/journal.js +1 -1
  20. package/dist/resources/extensions/gsd/markdown-renderer.js +34 -91
  21. package/dist/resources/extensions/gsd/metrics.js +2 -2
  22. package/dist/resources/extensions/gsd/paths.js +70 -49
  23. package/dist/resources/extensions/gsd/post-unit-hooks.js +27 -0
  24. package/dist/resources/extensions/gsd/preferences-models.js +66 -15
  25. package/dist/resources/extensions/gsd/preferences-validation.js +66 -10
  26. package/dist/resources/extensions/gsd/rule-registry.js +106 -10
  27. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +1 -10
  28. package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +3 -24
  29. package/dist/resources/extensions/gsd/state-reconciliation/index.js +10 -0
  30. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -5
  31. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +16 -10
  32. package/dist/resources/extensions/gsd/tools/validate-milestone.js +3 -8
  33. package/dist/resources/extensions/gsd/uat-dispatch.js +94 -0
  34. package/dist/resources/extensions/gsd/uok/audit-toggle.js +31 -2
  35. package/dist/resources/extensions/gsd/uok/audit.js +3 -0
  36. package/dist/resources/extensions/gsd/uok/gate-runner.js +22 -30
  37. package/dist/resources/extensions/gsd/uok/gitops.js +18 -15
  38. package/dist/resources/extensions/gsd/uok/kernel.js +120 -46
  39. package/dist/resources/extensions/gsd/uok/model-policy.js +17 -14
  40. package/dist/resources/extensions/gsd/workflow-event-ledger.js +1 -1
  41. package/dist/resources/extensions/gsd/workflow-logger.js +1 -1
  42. package/dist/resources/extensions/gsd/workflow-projections.js +9 -26
  43. package/dist/resources/extensions/gsd/workspace.js +5 -14
  44. package/dist/resources/extensions/shared/gsd-browser-cli.js +29 -0
  45. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  46. package/dist/web/standalone/.next/BUILD_ID +1 -1
  47. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  48. package/dist/web/standalone/.next/build-manifest.json +2 -2
  49. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  50. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  51. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  56. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  57. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  58. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  59. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  66. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  67. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  68. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  69. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  70. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  71. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  72. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  73. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  74. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  75. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  76. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  77. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  78. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  79. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  80. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  81. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  82. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  83. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  84. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  85. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  86. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  87. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  88. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  89. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  90. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  91. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  92. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  93. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  94. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  95. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  96. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  97. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  98. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  99. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  100. package/dist/web/standalone/.next/server/app/index.html +1 -1
  101. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  108. package/dist/web/standalone/.next/server/chunks/{1128.js → 1991.js} +1 -1
  109. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  110. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  112. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  113. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  114. package/dist/worktree-cli-create.d.ts +10 -0
  115. package/dist/worktree-cli-create.js +11 -0
  116. package/dist/worktree-cli-format.d.ts +12 -0
  117. package/dist/worktree-cli-format.js +38 -0
  118. package/dist/worktree-cli-plan.d.ts +16 -0
  119. package/dist/worktree-cli-plan.js +19 -0
  120. package/dist/worktree-cli-session.d.ts +13 -0
  121. package/dist/worktree-cli-session.js +18 -0
  122. package/dist/worktree-cli-status.d.ts +35 -0
  123. package/dist/worktree-cli-status.js +54 -0
  124. package/dist/worktree-cli.d.ts +1 -16
  125. package/dist/worktree-cli.js +28 -122
  126. package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
  127. package/integrations/hermes/pyproject.toml +1 -1
  128. package/package.json +1 -1
  129. package/packages/cloud-mcp-gateway/package.json +2 -2
  130. package/packages/contracts/package.json +1 -1
  131. package/packages/daemon/dist/orchestrator-agent.d.ts +21 -0
  132. package/packages/daemon/dist/orchestrator-agent.d.ts.map +1 -0
  133. package/packages/daemon/dist/orchestrator-agent.js +113 -0
  134. package/packages/daemon/dist/orchestrator-agent.js.map +1 -0
  135. package/packages/daemon/dist/orchestrator-tools.d.ts +12 -0
  136. package/packages/daemon/dist/orchestrator-tools.d.ts.map +1 -0
  137. package/packages/daemon/dist/orchestrator-tools.js +137 -0
  138. package/packages/daemon/dist/orchestrator-tools.js.map +1 -0
  139. package/packages/daemon/dist/orchestrator.d.ts +4 -56
  140. package/packages/daemon/dist/orchestrator.d.ts.map +1 -1
  141. package/packages/daemon/dist/orchestrator.js +13 -303
  142. package/packages/daemon/dist/orchestrator.js.map +1 -1
  143. package/packages/daemon/dist/orchestrator.test.js +11 -1
  144. package/packages/daemon/dist/orchestrator.test.js.map +1 -1
  145. package/packages/daemon/package.json +4 -4
  146. package/packages/gsd-agent-core/package.json +5 -5
  147. package/packages/gsd-agent-modes/package.json +7 -7
  148. package/packages/mcp-server/package.json +4 -4
  149. package/packages/native/package.json +1 -1
  150. package/packages/pi-agent-core/package.json +1 -1
  151. package/packages/pi-ai/package.json +1 -1
  152. package/packages/pi-coding-agent/package.json +7 -7
  153. package/packages/pi-tui/package.json +2 -2
  154. package/packages/rpc-client/package.json +2 -2
  155. package/pkg/package.json +1 -1
  156. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +146 -33
  157. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +25 -0
  158. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +93 -0
  159. package/src/resources/extensions/gsd/activity-log.ts +1 -1
  160. package/src/resources/extensions/gsd/auto/orchestrator.ts +17 -11
  161. package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -1
  162. package/src/resources/extensions/gsd/auto-dispatch.ts +59 -14
  163. package/src/resources/extensions/gsd/auto-model-selection.ts +33 -1
  164. package/src/resources/extensions/gsd/auto-post-unit.ts +4 -2
  165. package/src/resources/extensions/gsd/auto-prompts.ts +53 -113
  166. package/src/resources/extensions/gsd/auto-start.ts +57 -28
  167. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -2
  168. package/src/resources/extensions/gsd/auto-timers.ts +9 -2
  169. package/src/resources/extensions/gsd/auto.ts +103 -30
  170. package/src/resources/extensions/gsd/compat/compat-marker.ts +47 -0
  171. package/src/resources/extensions/gsd/config-overlay.ts +7 -1
  172. package/src/resources/extensions/gsd/db/engine.ts +36 -0
  173. package/src/resources/extensions/gsd/db-adapter.ts +29 -3
  174. package/src/resources/extensions/gsd/docs/preferences-reference.md +3 -3
  175. package/src/resources/extensions/gsd/journal.ts +1 -1
  176. package/src/resources/extensions/gsd/markdown-renderer.ts +52 -103
  177. package/src/resources/extensions/gsd/metrics.ts +2 -2
  178. package/src/resources/extensions/gsd/paths.ts +87 -48
  179. package/src/resources/extensions/gsd/post-unit-hooks.ts +32 -0
  180. package/src/resources/extensions/gsd/preferences-models.ts +74 -20
  181. package/src/resources/extensions/gsd/preferences-types.ts +24 -1
  182. package/src/resources/extensions/gsd/preferences-validation.ts +77 -9
  183. package/src/resources/extensions/gsd/rule-registry.ts +111 -9
  184. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +1 -9
  185. package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +2 -22
  186. package/src/resources/extensions/gsd/state-reconciliation/index.ts +14 -0
  187. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +41 -2
  188. package/src/resources/extensions/gsd/tests/auto-post-unit-artifact-diagnostic.test.ts +48 -1
  189. package/src/resources/extensions/gsd/tests/auto-start-project-milestone-reconcile.test.ts +29 -1
  190. package/src/resources/extensions/gsd/tests/auto-timeout-recovery-supervisor-inflight-guard.test.ts +159 -0
  191. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +3 -1
  192. package/src/resources/extensions/gsd/tests/compat-marker.test.ts +85 -0
  193. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +45 -0
  194. package/src/resources/extensions/gsd/tests/db-adapter.test.ts +39 -0
  195. package/src/resources/extensions/gsd/tests/db-writable-probe.test.ts +66 -0
  196. package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +22 -1
  197. package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +72 -32
  198. package/src/resources/extensions/gsd/tests/integration/paths.test.ts +88 -1
  199. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +2 -1
  200. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +0 -1
  201. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +269 -0
  202. package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +8 -1
  203. package/src/resources/extensions/gsd/tests/read-uat-gate-verdict.test.ts +54 -0
  204. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +49 -1
  205. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +95 -1
  206. package/src/resources/extensions/gsd/tests/sibling-model-fallbacks.test.ts +189 -0
  207. package/src/resources/extensions/gsd/tests/single-field-model-thinking.test.ts +156 -0
  208. package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +6 -1
  209. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +32 -0
  210. package/src/resources/extensions/gsd/tests/supervisor-model-swap-inflight-guard.test.ts +181 -0
  211. package/src/resources/extensions/gsd/tests/supervisor-model-swap-thinking-clamp.test.ts +122 -0
  212. package/src/resources/extensions/gsd/tests/uat-dispatch.test.ts +211 -0
  213. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +39 -0
  214. package/src/resources/extensions/gsd/tests/uok-kernel-path.test.ts +226 -2
  215. package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +6 -0
  216. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +213 -2
  217. package/src/resources/extensions/gsd/tools/complete-milestone.ts +9 -5
  218. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +19 -8
  219. package/src/resources/extensions/gsd/tools/validate-milestone.ts +13 -9
  220. package/src/resources/extensions/gsd/types.ts +23 -4
  221. package/src/resources/extensions/gsd/uat-dispatch.ts +176 -0
  222. package/src/resources/extensions/gsd/uok/audit-toggle.ts +32 -2
  223. package/src/resources/extensions/gsd/uok/audit.ts +2 -0
  224. package/src/resources/extensions/gsd/uok/gate-runner.ts +26 -36
  225. package/src/resources/extensions/gsd/uok/gitops.ts +21 -18
  226. package/src/resources/extensions/gsd/uok/kernel.ts +169 -48
  227. package/src/resources/extensions/gsd/uok/model-policy.ts +20 -17
  228. package/src/resources/extensions/gsd/workflow-event-ledger.ts +1 -1
  229. package/src/resources/extensions/gsd/workflow-logger.ts +1 -1
  230. package/src/resources/extensions/gsd/workflow-projections.ts +9 -24
  231. package/src/resources/extensions/gsd/workspace.ts +5 -21
  232. package/src/resources/extensions/shared/gsd-browser-cli.ts +29 -0
  233. /package/dist/web/standalone/.next/static/{gXoWec4UNqcR0tkuHwYCr → NPMNi2HV8BuK3baQsEUhk}/_buildManifest.js +0 -0
  234. /package/dist/web/standalone/.next/static/{gXoWec4UNqcR0tkuHwYCr → NPMNi2HV8BuK3baQsEUhk}/_ssgManifest.js +0 -0
@@ -1,5 +1,6 @@
1
1
  import { insertGateRun } from "../gsd-db.js";
2
2
  import { buildAuditEnvelope, emitUokAuditEvent } from "./audit.js";
3
+ import { isUnifiedAuditEnabled } from "./audit-toggle.js";
3
4
  const RETRY_MATRIX = {
4
5
  none: 0,
5
6
  policy: 0,
@@ -13,6 +14,25 @@ const RETRY_MATRIX = {
13
14
  "manual-attention": 0,
14
15
  unknown: 0,
15
16
  };
17
+ function emitGateAuditIfEnabled(ctx, result) {
18
+ if (!isUnifiedAuditEnabled(ctx.basePath))
19
+ return;
20
+ emitUokAuditEvent(ctx.basePath, buildAuditEnvelope({
21
+ traceId: ctx.traceId,
22
+ turnId: ctx.turnId,
23
+ category: "gate",
24
+ type: "gate-run",
25
+ payload: {
26
+ gateId: result.gateId,
27
+ gateType: result.gateType,
28
+ outcome: result.outcome,
29
+ failureClass: result.failureClass,
30
+ attempt: result.attempt,
31
+ maxAttempts: result.maxAttempts,
32
+ retryable: result.retryable,
33
+ },
34
+ }));
35
+ }
16
36
  export class UokGateRunner {
17
37
  registry = new Map();
18
38
  register(gate) {
@@ -55,21 +75,7 @@ export class UokGateRunner {
55
75
  retryable: unknownResult.retryable,
56
76
  evaluatedAt: unknownResult.evaluatedAt,
57
77
  });
58
- emitUokAuditEvent(ctx.basePath, buildAuditEnvelope({
59
- traceId: ctx.traceId,
60
- turnId: ctx.turnId,
61
- category: "gate",
62
- type: "gate-run",
63
- payload: {
64
- gateId: unknownResult.gateId,
65
- gateType: unknownResult.gateType,
66
- outcome: unknownResult.outcome,
67
- failureClass: unknownResult.failureClass,
68
- attempt: unknownResult.attempt,
69
- maxAttempts: unknownResult.maxAttempts,
70
- retryable: unknownResult.retryable,
71
- },
72
- }));
78
+ emitGateAuditIfEnabled(ctx, unknownResult);
73
79
  return unknownResult;
74
80
  }
75
81
  let attempt = 0;
@@ -125,21 +131,7 @@ export class UokGateRunner {
125
131
  retryable: final.retryable,
126
132
  evaluatedAt: final.evaluatedAt,
127
133
  });
128
- emitUokAuditEvent(ctx.basePath, buildAuditEnvelope({
129
- traceId: ctx.traceId,
130
- turnId: ctx.turnId,
131
- category: "gate",
132
- type: "gate-run",
133
- payload: {
134
- gateId: final.gateId,
135
- gateType: final.gateType,
136
- outcome: final.outcome,
137
- failureClass: final.failureClass,
138
- attempt: final.attempt,
139
- maxAttempts: final.maxAttempts,
140
- retryable: final.retryable,
141
- },
142
- }));
134
+ emitGateAuditIfEnabled(ctx, final);
143
135
  if (!retryable)
144
136
  break;
145
137
  }
@@ -1,5 +1,6 @@
1
1
  import { isDbAvailable, upsertTurnGitTransaction } from "../gsd-db.js";
2
2
  import { buildAuditEnvelope, emitUokAuditEvent } from "./audit.js";
3
+ import { isUnifiedAuditEnabled } from "./audit-toggle.js";
3
4
  export function writeTurnGitTransaction(args) {
4
5
  if (!isDbAvailable())
5
6
  return;
@@ -16,21 +17,23 @@ export function writeTurnGitTransaction(args) {
16
17
  metadata: args.metadata,
17
18
  updatedAt: new Date().toISOString(),
18
19
  });
19
- emitUokAuditEvent(args.basePath, buildAuditEnvelope({
20
- traceId: args.traceId,
21
- turnId: args.turnId,
22
- category: "gitops",
23
- type: `turn-git-${args.stage}`,
24
- payload: {
25
- unitType: args.unitType,
26
- unitId: args.unitId,
27
- action: args.action,
28
- push: args.push,
29
- status: args.status,
30
- error: args.error,
31
- ...(args.metadata ?? {}),
32
- },
33
- }));
20
+ if (isUnifiedAuditEnabled(args.basePath)) {
21
+ emitUokAuditEvent(args.basePath, buildAuditEnvelope({
22
+ traceId: args.traceId,
23
+ turnId: args.turnId,
24
+ category: "gitops",
25
+ type: `turn-git-${args.stage}`,
26
+ payload: {
27
+ unitType: args.unitType,
28
+ unitId: args.unitId,
29
+ action: args.action,
30
+ push: args.push,
31
+ status: args.status,
32
+ error: args.error,
33
+ ...(args.metadata ?? {}),
34
+ },
35
+ }));
36
+ }
34
37
  }
35
38
  export function writeTurnCloseoutGitRecord(basePath, record, metadata) {
36
39
  writeTurnGitTransaction({
@@ -2,10 +2,11 @@ import { appendFileSync, mkdirSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { gsdRoot } from "../paths.js";
4
4
  import { buildAuditEnvelope, emitUokAuditEvent } from "./audit.js";
5
- import { setUnifiedAuditEnabled } from "./audit-toggle.js";
5
+ import { getUnifiedAuditOverride, restoreUnifiedAuditOverride, setUnifiedAuditEnabled, setUnifiedAuditSuppressedForBasePath, } from "./audit-toggle.js";
6
6
  import { resolveUokFlags } from "./flags.js";
7
7
  import { createTurnObserver } from "./loop-adapter.js";
8
8
  import { incrementLegacyTelemetry } from "../legacy-telemetry.js";
9
+ import { logWarning } from "../workflow-logger.js";
9
10
  function parityLogPath(basePath) {
10
11
  return join(gsdRoot(basePath), "runtime", "uok-parity.jsonl");
11
12
  }
@@ -23,68 +24,141 @@ function resolveKernelPathLabel(flags) {
23
24
  return "legacy-fallback";
24
25
  return flags.enabled ? "uok-kernel" : "legacy-wrapper";
25
26
  }
26
- export async function runAutoLoopWithUok(args) {
27
- const { ctx, pi, s, deps, runKernelLoop, runLegacyLoop } = args;
28
- const prefs = deps.loadEffectiveGSDPreferences()?.preferences;
29
- const flags = resolveUokFlags(prefs);
30
- setUnifiedAuditEnabled(flags.auditUnified);
27
+ function createUokKernelRunPlan(input) {
28
+ const flags = resolveUokFlags(input.preferences?.preferences);
31
29
  const pathLabel = resolveKernelPathLabel(flags);
32
- if (pathLabel !== "uok-kernel") {
33
- incrementLegacyTelemetry("legacy.uokFallbackUsed");
34
- }
35
- writeParityEvent(s.basePath, {
36
- ts: new Date().toISOString(),
37
- path: pathLabel,
30
+ return {
38
31
  flags,
39
- phase: "enter",
40
- });
41
- if (flags.auditUnified) {
42
- emitUokAuditEvent(s.basePath, buildAuditEnvelope({
43
- traceId: `session:${String(s.autoStartTime || Date.now())}`,
32
+ pathLabel,
33
+ traceId: `session:${String(input.autoStartTime || Date.now())}`,
34
+ useKernel: flags.enabled,
35
+ };
36
+ }
37
+ function createKernelAuditStateController(basePath) {
38
+ const previousAuditOverride = getUnifiedAuditOverride();
39
+ return {
40
+ apply(enabled) {
41
+ setUnifiedAuditSuppressedForBasePath(basePath, !enabled);
42
+ setUnifiedAuditEnabled(enabled);
43
+ },
44
+ restore() {
45
+ restoreUnifiedAuditOverride(previousAuditOverride);
46
+ },
47
+ };
48
+ }
49
+ function emitKernelEnterAudit(input) {
50
+ if (!input.plan.flags.auditUnified)
51
+ return true;
52
+ try {
53
+ emitUokAuditEvent(input.basePath, buildAuditEnvelope({
54
+ traceId: input.plan.traceId,
44
55
  category: "orchestration",
45
56
  type: "uok-kernel-enter",
46
57
  payload: {
47
- flags,
48
- sessionId: ctx.sessionManager?.getSessionId?.(),
58
+ flags: input.plan.flags,
59
+ sessionId: input.sessionId,
49
60
  },
50
61
  }));
62
+ return true;
51
63
  }
52
- const decoratedDeps = flags.enabled
53
- ? {
54
- ...deps,
55
- uokObserver: createTurnObserver({
56
- basePath: s.basePath,
57
- gitAction: flags.gitopsTurnAction,
58
- gitPush: flags.gitopsTurnPush,
59
- enableAudit: flags.auditUnified,
60
- enableGitops: flags.gitops,
61
- }),
62
- }
63
- : deps;
64
+ catch (err) {
65
+ const errorMessage = err instanceof Error ? err.message : String(err);
66
+ writeParityEvent(input.basePath, {
67
+ ts: new Date().toISOString(),
68
+ path: input.plan.pathLabel,
69
+ flags: input.plan.flags,
70
+ phase: "telemetry-error",
71
+ telemetry: "uok-kernel-enter",
72
+ error: errorMessage,
73
+ });
74
+ logWarning("db", `uok-kernel-enter audit emit failed (non-fatal): ${errorMessage}`);
75
+ return false;
76
+ }
77
+ }
78
+ function decorateLoopDepsForKernel(input) {
79
+ if (!input.plan.useKernel)
80
+ return input.deps;
81
+ return {
82
+ ...input.deps,
83
+ uokObserver: createTurnObserver({
84
+ basePath: input.basePath,
85
+ gitAction: input.plan.flags.gitopsTurnAction,
86
+ gitPush: input.plan.flags.gitopsTurnPush,
87
+ enableAudit: input.plan.flags.auditUnified && input.auditHealthy,
88
+ enableGitops: input.plan.flags.gitops,
89
+ }),
90
+ };
91
+ }
92
+ async function executeKernelRunPlan(input) {
93
+ if (input.plan.useKernel) {
94
+ await input.runKernelLoop(input.ctx, input.pi, input.s, input.kernelDeps);
95
+ return;
96
+ }
97
+ await input.runLegacyLoop(input.ctx, input.pi, input.s, input.deps);
98
+ }
99
+ export async function runAutoLoopWithUok(args) {
100
+ const { ctx, pi, s, deps, runKernelLoop, runLegacyLoop } = args;
101
+ const auditState = createKernelAuditStateController(s.basePath);
102
+ let plan = null;
64
103
  try {
65
- if (flags.enabled) {
66
- await runKernelLoop(ctx, pi, s, decoratedDeps);
67
- }
68
- else {
69
- await runLegacyLoop(ctx, pi, s, deps);
104
+ plan = createUokKernelRunPlan({
105
+ preferences: deps.loadEffectiveGSDPreferences(),
106
+ autoStartTime: s.autoStartTime,
107
+ });
108
+ auditState.apply(plan.flags.auditUnified);
109
+ if (plan.pathLabel !== "uok-kernel") {
110
+ incrementLegacyTelemetry("legacy.uokFallbackUsed");
70
111
  }
71
112
  writeParityEvent(s.basePath, {
72
113
  ts: new Date().toISOString(),
73
- path: pathLabel,
74
- flags,
75
- phase: "exit",
76
- status: "ok",
114
+ path: plan.pathLabel,
115
+ flags: plan.flags,
116
+ phase: "enter",
117
+ });
118
+ const auditHealthy = emitKernelEnterAudit({
119
+ basePath: s.basePath,
120
+ plan,
121
+ sessionId: ctx.sessionManager?.getSessionId?.(),
122
+ });
123
+ auditState.apply(plan.flags.auditUnified && auditHealthy);
124
+ const kernelDeps = decorateLoopDepsForKernel({
125
+ deps,
126
+ basePath: s.basePath,
127
+ plan,
128
+ auditHealthy,
129
+ });
130
+ await executeKernelRunPlan({
131
+ plan,
132
+ ctx,
133
+ pi,
134
+ s,
135
+ deps,
136
+ kernelDeps,
137
+ runKernelLoop,
138
+ runLegacyLoop,
77
139
  });
78
- }
79
- catch (err) {
80
140
  writeParityEvent(s.basePath, {
81
141
  ts: new Date().toISOString(),
82
- path: pathLabel,
83
- flags,
142
+ path: plan.pathLabel,
143
+ flags: plan.flags,
84
144
  phase: "exit",
85
- status: "error",
86
- error: err instanceof Error ? err.message : String(err),
145
+ status: "ok",
87
146
  });
147
+ }
148
+ catch (err) {
149
+ if (plan) {
150
+ writeParityEvent(s.basePath, {
151
+ ts: new Date().toISOString(),
152
+ path: plan.pathLabel,
153
+ flags: plan.flags,
154
+ phase: "exit",
155
+ status: "error",
156
+ error: err instanceof Error ? err.message : String(err),
157
+ });
158
+ }
88
159
  throw err;
89
160
  }
161
+ finally {
162
+ auditState.restore();
163
+ }
90
164
  }
@@ -1,5 +1,6 @@
1
1
  import { computeTaskRequirements, filterToolsForProvider } from "../model-router.js";
2
2
  import { buildAuditEnvelope, emitUokAuditEvent } from "./audit.js";
3
+ import { isUnifiedAuditEnabled } from "./audit-toggle.js";
3
4
  export function buildRequirementVector(unitType, taskMetadata) {
4
5
  if (!unitType)
5
6
  return {};
@@ -41,20 +42,22 @@ export function applyModelPolicyFilter(candidates, options) {
41
42
  reason,
42
43
  };
43
44
  decisions.push(decision);
44
- emitUokAuditEvent(options.basePath, buildAuditEnvelope({
45
- traceId: options.traceId,
46
- turnId: options.turnId,
47
- category: "model-policy",
48
- type: allowed ? "model-policy-allow" : "model-policy-deny",
49
- payload: {
50
- modelId: model.id,
51
- provider: model.provider,
52
- api: model.api,
53
- reason,
54
- unitType: options.unitType,
55
- requirements,
56
- },
57
- }));
45
+ if (isUnifiedAuditEnabled(options.basePath)) {
46
+ emitUokAuditEvent(options.basePath, buildAuditEnvelope({
47
+ traceId: options.traceId,
48
+ turnId: options.turnId,
49
+ category: "model-policy",
50
+ type: allowed ? "model-policy-allow" : "model-policy-deny",
51
+ payload: {
52
+ modelId: model.id,
53
+ provider: model.provider,
54
+ api: model.api,
55
+ reason,
56
+ unitType: options.unitType,
57
+ requirements,
58
+ },
59
+ }));
60
+ }
58
61
  if (allowed)
59
62
  eligible.push(model);
60
63
  }
@@ -66,7 +66,7 @@ export function writeWorktreeEventLog(worktreeBasePath, events) {
66
66
  atomicWriteSync(logPath, content);
67
67
  }
68
68
  function emitWorkflowEventAudit(basePath, event) {
69
- if (!isUnifiedAuditEnabled())
69
+ if (!isUnifiedAuditEnabled(basePath))
70
70
  return;
71
71
  try {
72
72
  const normalized = normalizeWorkflowEventCommand(event.cmd) ?? "unknown";
@@ -209,7 +209,7 @@ function _push(severity, component, message, context) {
209
209
  if (_buffer.length > MAX_BUFFER) {
210
210
  _buffer.shift();
211
211
  }
212
- if (_auditBasePath && isUnifiedAuditEnabled()) {
212
+ if (_auditBasePath && isUnifiedAuditEnabled(_auditBasePath)) {
213
213
  try {
214
214
  emitUokAuditEvent(_auditBasePath, buildAuditEnvelope({
215
215
  traceId: `workflow-log:${component}`,
@@ -5,7 +5,7 @@
5
5
  // Projections are read-only views of engine state (Layer 3 of the architecture).
6
6
  import { _getAdapter, isDbAvailable, getAllMilestones, getMilestone, getMilestoneSlices, getSliceTasks, getVerificationEvidence, } from "./gsd-db.js";
7
7
  import { atomicWriteSync } from "./atomic-write.js";
8
- import { join } from "node:path";
8
+ import { dirname, join } from "node:path";
9
9
  import { mkdirSync, existsSync } from "node:fs";
10
10
  import { readFile } from "node:fs/promises";
11
11
  import { logWarning } from "./workflow-logger.js";
@@ -13,7 +13,7 @@ import { isClosedStatus } from "./status-guards.js";
13
13
  import { deriveState } from "./state.js";
14
14
  import { renderPlanFromDb, renderRoadmapFromDb } from "./markdown-renderer.js";
15
15
  import { readManifest } from "./workflow-manifest.js";
16
- import { gsdRoot, resolveSliceFile, resolveMilestonePath, resolveSlicePath, gsdProjectionRoot } from "./paths.js";
16
+ import { gsdRoot, resolveMilestoneFile, resolveSliceFile, resolveTaskFile, relTaskFile } from "./paths.js";
17
17
  // ─── Helpers ─────────────────────────────────────────────────────────────
18
18
  /**
19
19
  * Strip a leading ID prefix (e.g. "M001: " or "S04: ") from a title
@@ -276,26 +276,10 @@ export function renderSummaryProjection(basePath, milestoneId, sliceId, taskId)
276
276
  return;
277
277
  const evidenceRows = getVerificationEvidence(milestoneId, sliceId, taskId);
278
278
  const content = renderSummaryContent(taskRow, sliceId, milestoneId, evidenceRows);
279
- // Layout-aware: avoid creating a milestones/ directory as a side effect for
280
- // flat-phase projects. If milestonesDir() sees a freshly-created milestones/
281
- // dir it treats the project as legacy, breaking all subsequent path resolution.
282
- const slicePath = resolveSlicePath(basePath, milestoneId, sliceId);
283
- const phaseDir = resolveMilestonePath(basePath, milestoneId);
284
- let dir;
285
- if (slicePath && phaseDir && slicePath !== phaseDir) {
286
- // Legacy layout: slice has its own slices/SID/ subdir → tasks/ subdir
287
- dir = join(slicePath, "tasks");
288
- }
289
- else if (phaseDir) {
290
- // Flat-phase: task summaries go in the phase dir (no tasks/ subdir needed)
291
- dir = phaseDir;
292
- }
293
- else {
294
- // Fallback: legacy hardcoded path (milestone dir not on disk yet)
295
- dir = join(gsdProjectionRoot(basePath), "milestones", milestoneId, "slices", sliceId, "tasks");
296
- }
297
- mkdirSync(dir, { recursive: true });
298
- atomicWriteSync(join(dir, `${taskId}-SUMMARY.md`), content);
279
+ const summaryPath = resolveTaskFile(basePath, milestoneId, sliceId, taskId, "SUMMARY")
280
+ ?? join(basePath, relTaskFile(basePath, milestoneId, sliceId, taskId, "SUMMARY", getMilestone(milestoneId)?.title));
281
+ mkdirSync(dirname(summaryPath), { recursive: true });
282
+ atomicWriteSync(summaryPath, content);
299
283
  }
300
284
  // ─── STATE.md Projection ────────────────────────────────────────────────
301
285
  /**
@@ -474,7 +458,7 @@ export async function regenerateIfMissing(basePath, milestoneId, sliceId, fileTy
474
458
  filePath = resolveSliceFile(basePath, milestoneId, sliceId, "PLAN") ?? "";
475
459
  break;
476
460
  case "ROADMAP":
477
- filePath = join(basePath, ".gsd", "milestones", milestoneId, `${milestoneId}-ROADMAP.md`);
461
+ filePath = resolveMilestoneFile(basePath, milestoneId, "ROADMAP") ?? "";
478
462
  break;
479
463
  case "SUMMARY":
480
464
  // For SUMMARY, we regenerate all task summaries in the slice
@@ -490,8 +474,7 @@ export async function regenerateIfMissing(basePath, milestoneId, sliceId, fileTy
490
474
  const doneTasks = taskRows.filter(t => t.status === "done" || t.status === "complete");
491
475
  let regenerated = 0;
492
476
  for (const task of doneTasks) {
493
- const summaryPath = join(basePath, ".gsd", "milestones", milestoneId, "slices", sliceId, "tasks", `${task.id}-SUMMARY.md`);
494
- if (!existsSync(summaryPath)) {
477
+ if (!resolveTaskFile(basePath, milestoneId, sliceId, task.id, "SUMMARY")) {
495
478
  try {
496
479
  renderSummaryProjection(basePath, milestoneId, sliceId, task.id);
497
480
  regenerated++;
@@ -526,7 +509,7 @@ export async function regenerateIfMissing(basePath, milestoneId, sliceId, fileTy
526
509
  return !!(resolveSliceFile(basePath, milestoneId, sliceId, "PLAN"));
527
510
  case "ROADMAP":
528
511
  await renderRoadmapFromDb(basePath, milestoneId);
529
- return existsSync(filePath);
512
+ return !!resolveMilestoneFile(basePath, milestoneId, "ROADMAP");
530
513
  case "STATE":
531
514
  await renderStateProjection(basePath);
532
515
  return existsSync(filePath);
@@ -1,26 +1,17 @@
1
1
  // gsd-pi + Workspace handle: single source of truth for path resolution per milestone
2
2
  import { dirname, join, resolve } from "node:path";
3
- import { buildMilestoneFileName, canonicalPhaseDirName, isLegacyMilestonesLayout, milestonesDir, resolveGsdPathContract, resolveMilestoneFile, resolveMilestonePath, normalizeRealPath, } from "./paths.js";
3
+ import { resolveGsdPathContract, resolveMilestoneFile, resolveMilestonePath, targetMilestoneFile, normalizeRealPath, } from "./paths.js";
4
4
  import { isGsdWorktreePath, resolveWorktreeProjectRoot } from "./worktree-root.js";
5
5
  function tryRealpath(p) {
6
6
  return normalizeRealPath(p);
7
7
  }
8
- function isLegacyMilestoneDirectory(dir) {
9
- const parent = dirname(dir);
10
- return parent.endsWith("/milestones") || parent.endsWith("\\milestones");
11
- }
12
8
  function scopeMilestoneDir(basePath, milestoneId) {
13
- return resolveMilestonePath(basePath, milestoneId) ?? join(milestonesDir(basePath), isLegacyMilestonesLayout(basePath) ? milestoneId : canonicalPhaseDirName(milestoneId));
9
+ return resolveMilestonePath(basePath, milestoneId)
10
+ ?? dirname(targetMilestoneFile(basePath, milestoneId, "ROADMAP"));
14
11
  }
15
12
  function scopeMilestoneFile(basePath, milestoneId, suffix) {
16
- const existing = resolveMilestoneFile(basePath, milestoneId, suffix);
17
- if (existing)
18
- return existing;
19
- const dir = scopeMilestoneDir(basePath, milestoneId);
20
- const filename = isLegacyMilestoneDirectory(dir)
21
- ? `${milestoneId}-${suffix}.md`
22
- : buildMilestoneFileName(milestoneId, suffix);
23
- return join(dir, filename);
13
+ return resolveMilestoneFile(basePath, milestoneId, suffix)
14
+ ?? targetMilestoneFile(basePath, milestoneId, suffix);
24
15
  }
25
16
  /**
26
17
  * Create an immutable GsdWorkspace handle from a raw base path.
@@ -48,6 +48,30 @@ function splitCommandLine(commandLine) {
48
48
  return part;
49
49
  });
50
50
  }
51
+ /**
52
+ * Extra gsd-browser CLI flags to forward verbatim to the launched daemon, from
53
+ * GSD_BROWSER_MCP_EXTRA_ARGS. Unlike GSD_BROWSER_MCP_ARGS (a full args override),
54
+ * these are *appended* to the default `mcp`/`daemon start` invocation so callers
55
+ * keep the managed session/identity flags. Accepts a JSON array (e.g.
56
+ * `["--stealth"]`) or a plain, optionally-quoted command-line string
57
+ * (e.g. `--stealth --browser-path /usr/bin/chromium`). This is the config-level
58
+ * knob for environments where Chrome needs extra launch flags — e.g. containers
59
+ * without unprivileged user namespaces, where `--stealth` supplies Chrome's
60
+ * `--no-sandbox`.
61
+ */
62
+ function resolveExtraGsdBrowserArgs(env) {
63
+ const raw = env.GSD_BROWSER_MCP_EXTRA_ARGS?.trim();
64
+ if (!raw)
65
+ return [];
66
+ if (raw.startsWith("[")) {
67
+ const parsed = parseJsonEnv(env, "GSD_BROWSER_MCP_EXTRA_ARGS");
68
+ if (!Array.isArray(parsed)) {
69
+ throw new Error("GSD_BROWSER_MCP_EXTRA_ARGS JSON must be an array of strings");
70
+ }
71
+ return parsed.map(String);
72
+ }
73
+ return splitCommandLine(raw);
74
+ }
51
75
  function buildPathGsdBrowserVersionInvocation(platform) {
52
76
  if (platform === "win32") {
53
77
  return { command: "cmd", args: ["/d", "/s", "/c", "gsd-browser", "--version"] };
@@ -251,6 +275,10 @@ export function resolveGsdBrowserMcpLaunchConfig(projectRoot, env = process.env,
251
275
  || (preferPathCli ? "gsd-browser" : undefined)
252
276
  || (bundledCliPath ? process.execPath : undefined)
253
277
  || "gsd-browser";
278
+ // Appended after the managed session/identity flags so they survive the
279
+ // daemon-start transformation (which forwards everything after `mcp`), letting
280
+ // callers add extra Chrome/gsd-browser launch flags via one config knob.
281
+ const extraArgs = resolveExtraGsdBrowserArgs(env);
254
282
  const args = Array.isArray(explicitArgs) && explicitArgs.length > 0
255
283
  ? explicitArgs.map(String)
256
284
  : [
@@ -265,6 +293,7 @@ export function resolveGsdBrowserMcpLaunchConfig(projectRoot, env = process.env,
265
293
  identityKey,
266
294
  "--identity-project",
267
295
  identityProject,
296
+ ...extraArgs,
268
297
  ];
269
298
  const cwd = env.GSD_BROWSER_MCP_CWD?.trim() || resolvedProjectRoot;
270
299
  return {