@neuroverseos/governance 0.4.0 → 0.4.1

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 (105) hide show
  1. package/dist/adapters/autoresearch.d.cts +2 -1
  2. package/dist/adapters/autoresearch.d.ts +2 -1
  3. package/dist/adapters/autoresearch.js +2 -2
  4. package/dist/adapters/deep-agents.d.cts +3 -2
  5. package/dist/adapters/deep-agents.d.ts +3 -2
  6. package/dist/adapters/deep-agents.js +2 -2
  7. package/dist/adapters/express.d.cts +2 -1
  8. package/dist/adapters/express.d.ts +2 -1
  9. package/dist/adapters/express.js +2 -2
  10. package/dist/adapters/index.cjs +66 -1
  11. package/dist/adapters/index.d.cts +4 -278
  12. package/dist/adapters/index.d.ts +4 -278
  13. package/dist/adapters/index.js +33 -33
  14. package/dist/adapters/langchain.d.cts +3 -2
  15. package/dist/adapters/langchain.d.ts +3 -2
  16. package/dist/adapters/langchain.js +2 -2
  17. package/dist/adapters/mentraos.cjs +2181 -0
  18. package/dist/adapters/mentraos.d.cts +319 -0
  19. package/dist/adapters/mentraos.d.ts +319 -0
  20. package/dist/{mentraos-YFS7FMJH.js → adapters/mentraos.js} +6 -6
  21. package/dist/adapters/openai.d.cts +3 -2
  22. package/dist/adapters/openai.d.ts +3 -2
  23. package/dist/adapters/openai.js +2 -2
  24. package/dist/adapters/openclaw.d.cts +3 -2
  25. package/dist/adapters/openclaw.d.ts +3 -2
  26. package/dist/adapters/openclaw.js +2 -2
  27. package/dist/{add-LYHDZ5RL.js → add-XSANI3FK.js} +1 -1
  28. package/dist/bootstrap-contract-DcV6t-8M.d.cts +216 -0
  29. package/dist/bootstrap-contract-DcV6t-8M.d.ts +216 -0
  30. package/dist/{build-THUEYMVT.js → build-EGBGZFIJ.js} +5 -5
  31. package/dist/{chunk-MFKHTE5R.js → chunk-3AYKQHYI.js} +1 -1
  32. package/dist/chunk-3S5AD4AB.js +421 -0
  33. package/dist/{chunk-V4FZHJQX.js → chunk-A7SHG75T.js} +1 -1
  34. package/dist/{chunk-JKGPSFGH.js → chunk-AV7XJJWK.js} +1 -1
  35. package/dist/{chunk-Y6WXAPKY.js → chunk-DA5MHFRR.js} +1 -1
  36. package/dist/{chunk-7D7PZLB7.js → chunk-FS2UUJJO.js} +3 -3
  37. package/dist/{chunk-TD5GKIHP.js → chunk-FVOGUCB6.js} +1 -1
  38. package/dist/{chunk-APU4OZIP.js → chunk-GTPV2XGO.js} +67 -2
  39. package/dist/{chunk-BXLTEUS4.js → chunk-I4RTIMLX.js} +2 -2
  40. package/dist/{chunk-5JUZ4HL7.js → chunk-J2IZBHXJ.js} +3 -3
  41. package/dist/{chunk-YNYCQECH.js → chunk-QMVQ6KPL.js} +1 -1
  42. package/dist/{chunk-25XHSTPT.js → chunk-RDA7ISWC.js} +1 -1
  43. package/dist/{chunk-DWHUZUEY.js → chunk-YJ34R5NB.js} +1 -1
  44. package/dist/{chunk-UTH7OXTM.js → chunk-ZEIT2QLM.js} +3 -3
  45. package/dist/cli/neuroverse.cjs +580 -28
  46. package/dist/cli/neuroverse.js +21 -21
  47. package/dist/cli/plan.js +2 -2
  48. package/dist/cli/run.js +2 -2
  49. package/dist/{demo-66MMJTEH.js → demo-6OQYWRR6.js} +3 -3
  50. package/dist/{derive-5LOMN7GO.js → derive-7Y7YWVLU.js} +4 -4
  51. package/dist/{doctor-WIO4FLA3.js → doctor-NHXI7OQW.js} +3 -2
  52. package/dist/engine/bootstrap-emitter.cjs +241 -0
  53. package/dist/engine/bootstrap-emitter.d.cts +27 -0
  54. package/dist/engine/bootstrap-emitter.d.ts +27 -0
  55. package/dist/{bootstrap-emitter-GIMOJFOC.js → engine/bootstrap-emitter.js} +2 -2
  56. package/dist/engine/bootstrap-parser.cjs +560 -0
  57. package/dist/engine/bootstrap-parser.d.cts +96 -0
  58. package/dist/engine/bootstrap-parser.d.ts +96 -0
  59. package/dist/{bootstrap-parser-LBLGVEMU.js → engine/bootstrap-parser.js} +2 -2
  60. package/dist/engine/guard-engine.cjs +1116 -0
  61. package/dist/engine/guard-engine.d.cts +60 -0
  62. package/dist/engine/guard-engine.d.ts +60 -0
  63. package/dist/{guard-engine-N7TUIUU7.js → engine/guard-engine.js} +3 -3
  64. package/dist/engine/simulate-engine.cjs +390 -0
  65. package/dist/engine/simulate-engine.d.cts +105 -0
  66. package/dist/engine/simulate-engine.d.ts +105 -0
  67. package/dist/engine/simulate-engine.js +9 -0
  68. package/dist/{equity-penalties-WWC7UDQD.js → equity-penalties-NVBAB5WL.js} +2 -2
  69. package/dist/{explain-MUSGDT67.js → explain-HDFN4ION.js} +1 -1
  70. package/dist/github-TIKTWOGU.js +27 -0
  71. package/dist/{guard-W3BMQPBJ.js → guard-6KSCWT2W.js} +2 -2
  72. package/dist/{guard-contract-CLBbTGK_.d.cts → guard-contract-C991HDZp.d.cts} +2 -369
  73. package/dist/{guard-contract-CLBbTGK_.d.ts → guard-contract-hHjTTjtR.d.ts} +2 -369
  74. package/dist/{improve-PJDAWW4Q.js → improve-2PWGGO5B.js} +3 -3
  75. package/dist/index.cjs +452 -0
  76. package/dist/index.d.cts +231 -492
  77. package/dist/index.d.ts +231 -492
  78. package/dist/index.js +76 -55
  79. package/dist/{lens-IP6GIZ2Q.js → lens-MHMUDCMQ.js} +92 -25
  80. package/dist/{mcp-server-OG3PPVD2.js → mcp-server-TNIWZ7B5.js} +2 -2
  81. package/dist/{playground-4BK2XQ47.js → playground-3FLDGBET.js} +2 -2
  82. package/dist/{redteam-BRZALBPP.js → redteam-HV6LMKEH.js} +2 -2
  83. package/dist/{session-SGRUT2UH.js → session-XZP2754M.js} +2 -2
  84. package/dist/{shared-BGzmYP5g.d.cts → shared-DGnn1jiS.d.cts} +1 -1
  85. package/dist/{shared-CwGpPheR.d.ts → shared-U405h52W.d.ts} +1 -1
  86. package/dist/{simulate-FGXKIH7V.js → simulate-VT437EEL.js} +2 -2
  87. package/dist/spatial/index.cjs +682 -0
  88. package/dist/spatial/index.d.cts +517 -0
  89. package/dist/spatial/index.d.ts +517 -0
  90. package/dist/spatial/index.js +633 -0
  91. package/dist/{test-PT44BSYG.js → test-4WTX6RKQ.js} +2 -2
  92. package/dist/types.cjs +18 -0
  93. package/dist/types.d.cts +370 -0
  94. package/dist/types.d.ts +370 -0
  95. package/dist/types.js +0 -0
  96. package/dist/{validate-Q5O5TGLT.js → validate-M52DX22Y.js} +1 -1
  97. package/dist/{world-V52ZMH26.js → world-O4HTQPDP.js} +1 -1
  98. package/dist/{world-loader-C4D3VPP3.js → world-loader-YTYFOP7D.js} +1 -1
  99. package/dist/worlds/mentraos-spatial.nv-world.md +68 -0
  100. package/package.json +46 -3
  101. package/dist/{behavioral-SPWPGYXL.js → behavioral-SLW7ALEK.js} +3 -3
  102. package/dist/{bootstrap-IP5QMC3Q.js → bootstrap-2OW5ZLBL.js} +3 -3
  103. package/dist/{chunk-7QIAF377.js → chunk-CYDMUJVZ.js} +0 -0
  104. package/dist/{chunk-QZ666FCV.js → chunk-FHXXD2TI.js} +6 -6
  105. package/dist/{configure-ai-5MP5DWTT.js → configure-ai-LL3VAPQW.js} +3 -3
@@ -9544,6 +9544,425 @@ var init_express = __esm({
9544
9544
  }
9545
9545
  });
9546
9546
 
9547
+ // src/adapters/github.ts
9548
+ var github_exports = {};
9549
+ __export(github_exports, {
9550
+ GitHubGovernanceBlockedError: () => GitHubGovernanceBlockedError,
9551
+ GitHubGovernor: () => GitHubGovernor,
9552
+ GitHubWebhookHandler: () => GitHubWebhookHandler,
9553
+ createGitHubGovernor: () => createGitHubGovernor,
9554
+ createGitHubGovernorFromWorld: () => createGitHubGovernorFromWorld,
9555
+ createGitHubWebhookHandler: () => createGitHubWebhookHandler,
9556
+ createGitHubWebhookHandlerFromWorld: () => createGitHubWebhookHandlerFromWorld,
9557
+ formatForActions: () => formatForActions,
9558
+ formatPRComment: () => formatPRComment
9559
+ });
9560
+ function extractBranch(ref) {
9561
+ if (!ref) return void 0;
9562
+ if (ref.startsWith("refs/heads/")) return ref.slice("refs/heads/".length);
9563
+ if (ref.startsWith("refs/tags/")) return ref.slice("refs/tags/".length);
9564
+ return ref;
9565
+ }
9566
+ function isProtectedBranch(branch, protectedBranches) {
9567
+ if (!branch) return false;
9568
+ return protectedBranches.some(
9569
+ (pb) => branch === pb || branch.startsWith(`${pb}/`)
9570
+ );
9571
+ }
9572
+ function defaultMapAction(action, protectedBranches, restrictedActors) {
9573
+ const branch = action.branch ?? extractBranch(action.ref);
9574
+ const isProtected = isProtectedBranch(branch, protectedBranches);
9575
+ const isRestricted = action.actor ? restrictedActors.some((ra) => action.actor === ra || action.actor?.endsWith("[bot]")) : false;
9576
+ let actionCategory = "other";
9577
+ const act = action.action.toLowerCase();
9578
+ if (act.includes("read") || act.includes("get") || act.includes("list") || act.includes("view")) {
9579
+ actionCategory = "read";
9580
+ } else if (act.includes("delete") || act.includes("remove") || act.includes("close")) {
9581
+ actionCategory = "delete";
9582
+ } else if (act.includes("deploy") || act.includes("run") || act.includes("execute") || act.includes("merge")) {
9583
+ actionCategory = "network";
9584
+ } else if (act.includes("create") || act.includes("push") || act.includes("write") || act.includes("update") || act.includes("edit")) {
9585
+ actionCategory = "write";
9586
+ } else if (act.includes("comment") || act.includes("review") || act.includes("notify")) {
9587
+ actionCategory = "other";
9588
+ }
9589
+ return {
9590
+ intent: action.action,
9591
+ tool: "github",
9592
+ scope: `${action.repository}${branch ? `@${branch}` : ""}`,
9593
+ actionCategory,
9594
+ direction: "input",
9595
+ args: {
9596
+ repository: action.repository,
9597
+ ref: action.ref,
9598
+ branch,
9599
+ actor: action.actor,
9600
+ protected_branch: isProtected,
9601
+ restricted_actor: isRestricted,
9602
+ ...action.metadata
9603
+ }
9604
+ };
9605
+ }
9606
+ function defaultMapWebhook(eventType, payload) {
9607
+ const repo = payload.repository;
9608
+ const repoFullName = repo?.full_name ?? "unknown/unknown";
9609
+ const sender = payload.sender;
9610
+ const actor = sender?.login ?? void 0;
9611
+ const webhookAction = payload.action;
9612
+ switch (eventType) {
9613
+ case "push": {
9614
+ const ref = payload.ref;
9615
+ const branch = extractBranch(ref);
9616
+ const forced = payload.forced;
9617
+ return {
9618
+ action: forced ? "force_push" : `push_to_${branch ?? "branch"}`,
9619
+ repository: repoFullName,
9620
+ ref,
9621
+ branch,
9622
+ actor,
9623
+ metadata: {
9624
+ forced: forced ?? false,
9625
+ commits_count: payload.commits?.length ?? 0,
9626
+ head_commit: payload.head_commit?.id
9627
+ }
9628
+ };
9629
+ }
9630
+ case "pull_request": {
9631
+ const pr = payload.pull_request;
9632
+ const base = pr?.base;
9633
+ const baseBranch = base?.ref;
9634
+ const prNumber = pr?.number;
9635
+ const merged = pr?.merged;
9636
+ const labels = pr?.labels?.map((l) => l.name) ?? [];
9637
+ let action = `pull_request_${webhookAction ?? "unknown"}`;
9638
+ if (webhookAction === "closed" && merged) {
9639
+ action = "merge_pull_request";
9640
+ }
9641
+ return {
9642
+ action,
9643
+ repository: repoFullName,
9644
+ branch: baseBranch,
9645
+ actor,
9646
+ metadata: {
9647
+ pr_number: prNumber,
9648
+ labels,
9649
+ merged: merged ?? false,
9650
+ draft: pr?.draft ?? false,
9651
+ webhook_action: webhookAction
9652
+ }
9653
+ };
9654
+ }
9655
+ case "release": {
9656
+ const release = payload.release;
9657
+ return {
9658
+ action: `release_${webhookAction ?? "published"}`,
9659
+ repository: repoFullName,
9660
+ ref: release?.tag_name ? `refs/tags/${release.tag_name}` : void 0,
9661
+ actor,
9662
+ metadata: {
9663
+ tag: release?.tag_name,
9664
+ prerelease: release?.prerelease ?? false,
9665
+ draft: release?.draft ?? false,
9666
+ webhook_action: webhookAction
9667
+ }
9668
+ };
9669
+ }
9670
+ case "deployment":
9671
+ case "deployment_status": {
9672
+ const deployment = payload.deployment ?? payload;
9673
+ return {
9674
+ action: eventType === "deployment" ? "create_deployment" : "deployment_status_update",
9675
+ repository: repoFullName,
9676
+ ref: deployment.ref,
9677
+ actor,
9678
+ metadata: {
9679
+ environment: deployment.environment,
9680
+ status: payload.deployment_status?.state,
9681
+ webhook_action: webhookAction
9682
+ }
9683
+ };
9684
+ }
9685
+ case "workflow_run": {
9686
+ const run = payload.workflow_run;
9687
+ return {
9688
+ action: `workflow_${webhookAction ?? "completed"}`,
9689
+ repository: repoFullName,
9690
+ branch: run?.head_branch,
9691
+ actor,
9692
+ metadata: {
9693
+ workflow_name: run?.name,
9694
+ conclusion: run?.conclusion,
9695
+ status: run?.status,
9696
+ webhook_action: webhookAction
9697
+ }
9698
+ };
9699
+ }
9700
+ case "issues": {
9701
+ const issue = payload.issue;
9702
+ return {
9703
+ action: `issue_${webhookAction ?? "opened"}`,
9704
+ repository: repoFullName,
9705
+ actor,
9706
+ metadata: {
9707
+ issue_number: issue?.number,
9708
+ labels: issue?.labels?.map((l) => l.name) ?? [],
9709
+ webhook_action: webhookAction
9710
+ }
9711
+ };
9712
+ }
9713
+ case "issue_comment": {
9714
+ return {
9715
+ action: `issue_comment_${webhookAction ?? "created"}`,
9716
+ repository: repoFullName,
9717
+ actor,
9718
+ metadata: {
9719
+ issue_number: payload.issue?.number,
9720
+ webhook_action: webhookAction
9721
+ }
9722
+ };
9723
+ }
9724
+ case "delete": {
9725
+ return {
9726
+ action: `delete_${payload.ref_type ?? "ref"}`,
9727
+ repository: repoFullName,
9728
+ ref: payload.ref,
9729
+ actor,
9730
+ metadata: {
9731
+ ref_type: payload.ref_type
9732
+ }
9733
+ };
9734
+ }
9735
+ default: {
9736
+ return {
9737
+ action: webhookAction ? `${eventType}_${webhookAction}` : eventType,
9738
+ repository: repoFullName,
9739
+ actor,
9740
+ metadata: { webhook_action: webhookAction }
9741
+ };
9742
+ }
9743
+ }
9744
+ }
9745
+ function formatForActions(verdict) {
9746
+ const status = verdict.status === "ALLOW" ? "allowed" : verdict.status === "BLOCK" ? "blocked" : "paused";
9747
+ const reason = verdict.reason ?? "";
9748
+ const ruleId = verdict.ruleId ?? "";
9749
+ const lines = [
9750
+ `governance_status=${status}`,
9751
+ `verdict_status=${verdict.status}`,
9752
+ `reason=${reason}`,
9753
+ `rule_id=${ruleId}`
9754
+ ].join("\n");
9755
+ return {
9756
+ governance_status: status,
9757
+ verdict_status: verdict.status,
9758
+ reason,
9759
+ rule_id: ruleId,
9760
+ outputLines: lines
9761
+ };
9762
+ }
9763
+ function formatPRComment(verdict, action) {
9764
+ const icon = verdict.status === "ALLOW" ? "\u2705" : verdict.status === "BLOCK" ? "\u{1F6AB}" : "\u23F8\uFE0F";
9765
+ const status = verdict.status;
9766
+ let body = `## ${icon} Governance: ${status}
9767
+
9768
+ `;
9769
+ body += `**Action:** \`${action.action}\`
9770
+ `;
9771
+ body += `**Repository:** \`${action.repository}\`
9772
+ `;
9773
+ if (action.branch) {
9774
+ body += `**Branch:** \`${action.branch}\`
9775
+ `;
9776
+ }
9777
+ if (action.actor) {
9778
+ body += `**Actor:** \`${action.actor}\`
9779
+ `;
9780
+ }
9781
+ body += "\n";
9782
+ if (verdict.reason) {
9783
+ body += `**Reason:** ${verdict.reason}
9784
+ `;
9785
+ }
9786
+ if (verdict.ruleId) {
9787
+ body += `**Rule:** \`${verdict.ruleId}\`
9788
+ `;
9789
+ }
9790
+ if (verdict.evidence?.invariantsSatisfied < verdict.evidence?.invariantsTotal) {
9791
+ body += `**Invariants:** ${verdict.evidence.invariantsSatisfied}/${verdict.evidence.invariantsTotal} satisfied
9792
+ `;
9793
+ }
9794
+ body += "\n---\n*Evaluated by [NeuroVerse Governance](https://github.com/NeuroverseOS/neuroverseos-governance)*";
9795
+ return body;
9796
+ }
9797
+ async function createGitHubGovernor(worldPath, options) {
9798
+ const world = await loadWorld(worldPath);
9799
+ return new GitHubGovernor(world, options);
9800
+ }
9801
+ function createGitHubGovernorFromWorld(world, options) {
9802
+ return new GitHubGovernor(world, options);
9803
+ }
9804
+ async function createGitHubWebhookHandler(worldPath, options) {
9805
+ const world = await loadWorld(worldPath);
9806
+ return new GitHubWebhookHandler(world, options);
9807
+ }
9808
+ function createGitHubWebhookHandlerFromWorld(world, options) {
9809
+ return new GitHubWebhookHandler(world, options);
9810
+ }
9811
+ var GitHubGovernanceBlockedError, GitHubGovernor, GitHubWebhookHandler;
9812
+ var init_github = __esm({
9813
+ "src/adapters/github.ts"() {
9814
+ "use strict";
9815
+ init_guard_engine();
9816
+ init_world_loader();
9817
+ init_shared();
9818
+ GitHubGovernanceBlockedError = class extends GovernanceBlockedError {
9819
+ action;
9820
+ constructor(verdict, action) {
9821
+ super(verdict, `[NeuroVerse] GitHub action blocked: ${action.action} on ${action.repository}`);
9822
+ this.name = "GitHubGovernanceBlockedError";
9823
+ this.action = action;
9824
+ }
9825
+ };
9826
+ GitHubGovernor = class {
9827
+ world;
9828
+ options;
9829
+ engineOptions;
9830
+ activePlan;
9831
+ protectedBranches;
9832
+ restrictedActors;
9833
+ mapFn;
9834
+ constructor(world, options = {}) {
9835
+ this.world = world;
9836
+ this.options = options;
9837
+ this.activePlan = options.plan;
9838
+ this.engineOptions = buildEngineOptions(options, this.activePlan);
9839
+ this.protectedBranches = options.protectedBranches ?? ["main", "master", "production"];
9840
+ this.restrictedActors = options.restrictedActors ?? [];
9841
+ this.mapFn = options.mapAction ?? ((action) => defaultMapAction(action, this.protectedBranches, this.restrictedActors));
9842
+ }
9843
+ /**
9844
+ * Evaluate a GitHub action against governance rules.
9845
+ * Returns a full result with verdict, event, and the original action.
9846
+ */
9847
+ evaluate(action) {
9848
+ const event = this.mapFn(action);
9849
+ this.engineOptions.plan = this.activePlan;
9850
+ const verdict = evaluateGuard(event, this.world, this.engineOptions);
9851
+ this.options.onEvaluate?.(verdict, event, action);
9852
+ if (verdict.status === "ALLOW") {
9853
+ trackPlanProgress(event, this, this.options);
9854
+ }
9855
+ return { verdict, event, action };
9856
+ }
9857
+ /**
9858
+ * Evaluate and enforce — throws GitHubGovernanceBlockedError on BLOCK/PAUSE.
9859
+ * Use this as a gate before executing GitHub API calls.
9860
+ */
9861
+ enforce(action) {
9862
+ const result = this.evaluate(action);
9863
+ if (result.verdict.status === "BLOCK" || result.verdict.status === "PAUSE") {
9864
+ throw new GitHubGovernanceBlockedError(result.verdict, action);
9865
+ }
9866
+ return result;
9867
+ }
9868
+ /**
9869
+ * Check if pushing to a branch is allowed.
9870
+ * Convenience method for the most common governance check.
9871
+ */
9872
+ canPush(repository, branch, actor) {
9873
+ return this.evaluate({
9874
+ action: `push_to_${branch}`,
9875
+ repository,
9876
+ ref: `refs/heads/${branch}`,
9877
+ branch,
9878
+ actor
9879
+ }).verdict;
9880
+ }
9881
+ /**
9882
+ * Check if merging a PR is allowed.
9883
+ */
9884
+ canMerge(repository, targetBranch, prNumber, actor, labels) {
9885
+ return this.evaluate({
9886
+ action: "merge_pull_request",
9887
+ repository,
9888
+ branch: targetBranch,
9889
+ actor,
9890
+ metadata: { pr_number: prNumber, labels: labels ?? [] }
9891
+ }).verdict;
9892
+ }
9893
+ /**
9894
+ * Check if creating a release is allowed.
9895
+ */
9896
+ canRelease(repository, tag, actor, prerelease) {
9897
+ return this.evaluate({
9898
+ action: "release_published",
9899
+ repository,
9900
+ ref: `refs/tags/${tag}`,
9901
+ actor,
9902
+ metadata: { tag, prerelease: prerelease ?? false }
9903
+ }).verdict;
9904
+ }
9905
+ /**
9906
+ * Check if deploying to an environment is allowed.
9907
+ */
9908
+ canDeploy(repository, environment, ref, actor) {
9909
+ return this.evaluate({
9910
+ action: "create_deployment",
9911
+ repository,
9912
+ ref,
9913
+ actor,
9914
+ metadata: { environment }
9915
+ }).verdict;
9916
+ }
9917
+ };
9918
+ GitHubWebhookHandler = class {
9919
+ governor;
9920
+ mapWebhookFn;
9921
+ webhookSecret;
9922
+ constructor(world, options = {}) {
9923
+ this.governor = new GitHubGovernor(world, options);
9924
+ this.mapWebhookFn = options.mapWebhook ?? defaultMapWebhook;
9925
+ this.webhookSecret = options.webhookSecret;
9926
+ }
9927
+ /**
9928
+ * Evaluate a webhook payload.
9929
+ *
9930
+ * @param eventType - The X-GitHub-Event header value
9931
+ * @param payload - The parsed webhook body
9932
+ */
9933
+ evaluate(eventType, payload) {
9934
+ const action = this.mapWebhookFn(eventType, payload);
9935
+ const result = this.governor.evaluate(action);
9936
+ return {
9937
+ verdict: result.verdict,
9938
+ event: result.event,
9939
+ webhookEvent: eventType,
9940
+ webhookAction: payload.action
9941
+ };
9942
+ }
9943
+ /**
9944
+ * Evaluate and enforce — throws on BLOCK/PAUSE.
9945
+ */
9946
+ enforce(eventType, payload) {
9947
+ const result = this.evaluate(eventType, payload);
9948
+ if (result.verdict.status === "BLOCK" || result.verdict.status === "PAUSE") {
9949
+ const action = this.mapWebhookFn(eventType, payload);
9950
+ throw new GitHubGovernanceBlockedError(result.verdict, action);
9951
+ }
9952
+ return result;
9953
+ }
9954
+ /** Access the underlying governor for direct action evaluation. */
9955
+ getGovernor() {
9956
+ return this.governor;
9957
+ }
9958
+ /** Get the configured webhook secret (for signature verification in your server). */
9959
+ getWebhookSecret() {
9960
+ return this.webhookSecret;
9961
+ }
9962
+ };
9963
+ }
9964
+ });
9965
+
9547
9966
  // src/adapters/langchain.ts
9548
9967
  var langchain_exports = {};
9549
9968
  __export(langchain_exports, {
@@ -9755,7 +10174,7 @@ __export(openclaw_exports, {
9755
10174
  createNeuroVersePlugin: () => createNeuroVersePlugin,
9756
10175
  createNeuroVersePluginFromWorld: () => createNeuroVersePluginFromWorld
9757
10176
  });
9758
- function defaultMapAction(action, direction) {
10177
+ function defaultMapAction2(action, direction) {
9759
10178
  return {
9760
10179
  intent: action.type,
9761
10180
  tool: action.tool ?? action.type,
@@ -9797,7 +10216,7 @@ var init_openclaw = __esm({
9797
10216
  this.options = options;
9798
10217
  this.activePlan = options.plan;
9799
10218
  this.engineOptions = buildEngineOptions(options, this.activePlan);
9800
- this.mapAction = options.mapAction ?? defaultMapAction;
10219
+ this.mapAction = options.mapAction ?? defaultMapAction2;
9801
10220
  }
9802
10221
  /**
9803
10222
  * Evaluate an action before execution.
@@ -10525,6 +10944,7 @@ var init_mentraos = __esm({
10525
10944
  _userRules;
10526
10945
  _emergencyOverride = false;
10527
10946
  _emergencyActivatedAt = null;
10947
+ _spatialSession = null;
10528
10948
  constructor(world, options = {}, userRules = DEFAULT_USER_RULES) {
10529
10949
  this.world = world;
10530
10950
  this.options = options;
@@ -10581,13 +11001,36 @@ var init_mentraos = __esm({
10581
11001
  get emergencyActivatedAt() {
10582
11002
  return this._emergencyActivatedAt;
10583
11003
  }
11004
+ // ── Spatial Governance (optional) ────────────────────────────────────────
11005
+ /**
11006
+ * Attach a spatial session to this executor.
11007
+ *
11008
+ * When attached, intents are evaluated against the spatial context
11009
+ * (zone rules + handshake rules) AFTER user rules but BEFORE
11010
+ * hardware and platform checks. This is Layer 1.5.
11011
+ *
11012
+ * Pass null to detach (e.g., when leaving a zone).
11013
+ */
11014
+ setSpatialSession(session) {
11015
+ this._spatialSession = session;
11016
+ }
11017
+ /** Whether a spatial session is currently active */
11018
+ get hasSpatialSession() {
11019
+ return this._spatialSession !== null;
11020
+ }
11021
+ /** Get the current spatial session description */
11022
+ get spatialDescription() {
11023
+ return this._spatialSession?.description ?? null;
11024
+ }
10584
11025
  /**
10585
11026
  * Evaluate an intent against user rules + platform world.
10586
11027
  *
10587
11028
  * Three-layer evaluation:
10588
- * 0. Emergency override — if active, skip governance (layers 1 + 3),
11029
+ * 0. Emergency override — if active, skip governance (layers 1 + 1.5 + 3),
10589
11030
  * but STILL enforce platform constraints (layer 2)
10590
11031
  * 1. User rules check — personal governance override, can BLOCK or PAUSE
11032
+ * 1.5. Spatial governance — zone + handshake rules (optional, temporary)
11033
+ * ↑ ONLY ACTIVE when a spatial session is attached
10591
11034
  * 2. Hardware capability check — validates glasses support
10592
11035
  * ↑ THIS IS A PLATFORM CONSTRAINT — never overridden
10593
11036
  * 3. Platform guard engine — full world rule evaluation
@@ -10618,6 +11061,47 @@ var init_mentraos = __esm({
10618
11061
  return result2;
10619
11062
  }
10620
11063
  }
11064
+ if (!this._emergencyOverride && this._spatialSession) {
11065
+ const spatialResult = this._spatialSession.evaluate(intent);
11066
+ if (!spatialResult.allowed && !spatialResult.requiresConfirmation) {
11067
+ const verdict2 = {
11068
+ status: "BLOCK",
11069
+ ruleId: "spatial-zone-rule",
11070
+ reason: spatialResult.reason,
11071
+ evidence: makeEvidence("spatial-zone-rule")
11072
+ };
11073
+ const result2 = {
11074
+ allowed: false,
11075
+ requiresConfirmation: false,
11076
+ verdict: verdict2,
11077
+ intentDef,
11078
+ appContext,
11079
+ decidingLayer: "spatial"
11080
+ };
11081
+ this.options.onBlock?.(result2);
11082
+ this.options.onEvaluate?.(result2);
11083
+ return result2;
11084
+ }
11085
+ if (spatialResult.requiresConfirmation) {
11086
+ const verdict2 = {
11087
+ status: "PAUSE",
11088
+ ruleId: "spatial-zone-rule",
11089
+ reason: spatialResult.reason,
11090
+ evidence: makeEvidence("spatial-zone-rule")
11091
+ };
11092
+ const result2 = {
11093
+ allowed: false,
11094
+ requiresConfirmation: true,
11095
+ verdict: verdict2,
11096
+ intentDef,
11097
+ appContext,
11098
+ decidingLayer: "spatial"
11099
+ };
11100
+ this.options.onPause?.(result2);
11101
+ this.options.onEvaluate?.(result2);
11102
+ return result2;
11103
+ }
11104
+ }
10621
11105
  if (intentDef && glassesModel && !intentDef.supported_glasses.includes(glassesModel)) {
10622
11106
  const verdict2 = {
10623
11107
  status: "BLOCK",
@@ -10762,6 +11246,7 @@ var init_ = __esm({
10762
11246
  "../adapters/autoresearch.ts": () => Promise.resolve().then(() => (init_autoresearch(), autoresearch_exports)),
10763
11247
  "../adapters/deep-agents.ts": () => Promise.resolve().then(() => (init_deep_agents(), deep_agents_exports)),
10764
11248
  "../adapters/express.ts": () => Promise.resolve().then(() => (init_express(), express_exports)),
11249
+ "../adapters/github.ts": () => Promise.resolve().then(() => (init_github(), github_exports)),
10765
11250
  "../adapters/index.ts": () => Promise.resolve().then(() => (init_adapters(), adapters_exports)),
10766
11251
  "../adapters/langchain.ts": () => Promise.resolve().then(() => (init_langchain(), langchain_exports)),
10767
11252
  "../adapters/mentraos.ts": () => Promise.resolve().then(() => (init_mentraos(), mentraos_exports)),
@@ -16074,7 +16559,7 @@ function lensForRole(world, roleId, roleLensOverride) {
16074
16559
  if (byRole) return byRole;
16075
16560
  return lenses[0];
16076
16561
  }
16077
- var STOIC_LENS, CLOSER_LENS, SAMURAI_LENS, HYPE_MAN_LENS, MONK_LENS, SOCRATIC_LENS, MINIMALIST_LENS, COACH_LENS, CALM_LENS, BUILTIN_LENSES;
16562
+ var STOIC_LENS, CLOSER_LENS, SAMURAI_LENS, HYPE_MAN_LENS, MONK_LENS, SOCRATIC_LENS, MINIMALIST_LENS, LIFE_COACH_LENS, NFL_COACH_LENS, CALM_LENS, BUILTIN_LENSES;
16078
16563
  var init_lens = __esm({
16079
16564
  "src/builder/lens.ts"() {
16080
16565
  "use strict";
@@ -16447,14 +16932,14 @@ var init_lens = __esm({
16447
16932
  }
16448
16933
  ]
16449
16934
  };
16450
- COACH_LENS = {
16451
- id: "coach",
16452
- name: "Coach",
16453
- tagline: "You said this mattered. What's the next step?",
16935
+ LIFE_COACH_LENS = {
16936
+ id: "life-coach",
16937
+ name: "Life Coach",
16938
+ tagline: "What's really going on for you right now?",
16454
16939
  author: "NeuroverseOS",
16455
- version: "1.0.0",
16456
- description: "For when you need accountability, not sympathy. The AI holds you to your own standards. It doesn't let you off the hook, but it doesn't shame you either. It reminds you what you committed to and asks for the smallest next step.",
16457
- tags: ["motivation", "accountability", "discipline", "growth"],
16940
+ version: "2.0.0",
16941
+ description: "ICF-aligned professional coaching. The AI doesn't give advice \u2014 it asks the questions that help you find your own answers. Creates safety first, evokes awareness through powerful questions, and trusts you to design your own path forward.",
16942
+ tags: ["coaching", "icf", "awareness", "growth", "autonomy", "presence"],
16458
16943
  stackable: true,
16459
16944
  priority: 50,
16460
16945
  appliesTo: "all",
@@ -16462,45 +16947,111 @@ var init_lens = __esm({
16462
16947
  formality: "casual",
16463
16948
  verbosity: "concise",
16464
16949
  emotion: "warm",
16465
- confidence: "authoritative"
16950
+ confidence: "balanced"
16466
16951
  },
16467
16952
  directives: [
16468
16953
  {
16469
- id: "hold_the_standard",
16954
+ id: "evoke_dont_advise",
16470
16955
  scope: "behavior_shaping",
16471
- instruction: `When the user expresses reluctance, avoidance, or excuse-making about something they previously identified as important, do not sympathize with the avoidance. Acknowledge the difficulty briefly, then redirect to action. "I know it's hard" is fine once. Dwelling on why it's hard is not.`,
16956
+ instruction: 'Never give advice, solutions, or tell the user what to do. Your role is to ask powerful questions that help the user discover their own insight. If you feel the urge to suggest an action, convert it into a question. "Have you considered X?" is still advising. "What options do you see?" is coaching. The user is resourceful and capable \u2014 trust that. (ICF Competency 7: Evokes Awareness)',
16472
16957
  example: {
16473
- without: "I totally get it, sometimes we just don't feel like working out. It's okay to take a break. Listen to your body!",
16474
- with: "Tough day. You committed to 3x a week. What's the smallest version you'd still respect yourself for doing?"
16958
+ without: "You should try waking up earlier. Set an alarm for 6am and put your phone across the room.",
16959
+ with: "What would your morning look like if it actually worked for you?"
16475
16960
  }
16476
16961
  },
16477
16962
  {
16478
- id: "smallest_next_step",
16963
+ id: "listen_for_whats_unsaid",
16479
16964
  scope: "response_framing",
16480
- instruction: 'Always reduce big tasks to the immediate next action. Not the whole plan. Not the end goal. Just the next step. "What can you do in the next 10 minutes?" is the core question.',
16965
+ instruction: `Pay attention to what the user is NOT saying as much as what they are saying. Notice gaps, contradictions, energy shifts, and recurring themes. Reflect these back as observations, not judgments. "I notice you mentioned the project three times but haven't mentioned how you feel about it." Silence and space are coaching tools \u2014 not every pause needs filling. (ICF Competency 6: Listens Actively)`,
16481
16966
  example: {
16482
- without: "To write your book, you should first create an outline, then develop character profiles, then write a first draft of chapter 1, then...",
16483
- with: "Open a blank doc and write one sentence. Any sentence. That's today."
16967
+ without: "Okay so you want to change jobs. Let's figure out your next steps.",
16968
+ with: "You've told me a lot about what you'd leave behind. What is it you'd be moving toward?"
16484
16969
  }
16485
16970
  },
16486
16971
  {
16487
- id: "no_empty_praise",
16972
+ id: "safety_before_challenge",
16488
16973
  scope: "behavior_shaping",
16489
- instruction: `Do not give praise unless the user actually did something. "Great job thinking about it!" is empty. "You finished the draft \u2014 that's done" is real. Praise effort and completion, not intention.`
16974
+ instruction: "Create a safe, supportive space before exploring difficult territory. Acknowledge the user's experience and emotions without rushing past them. Trust is built before insight is possible. Never shame, guilt, or pressure. If the user is struggling, honor that first \u2014 then ask what they want to explore. (ICF Competency 4: Cultivates Trust and Safety)",
16975
+ example: {
16976
+ without: "You keep saying you're stressed but you're not doing anything about it. What's one thing you can change today?",
16977
+ with: "That sounds like a lot to carry. What feels most important to you to explore right now?"
16978
+ }
16490
16979
  },
16491
16980
  {
16492
- id: "reflect_their_words_back",
16981
+ id: "client_designs_the_action",
16493
16982
  scope: "response_framing",
16494
- instruction: 'When the user is wavering, reference their own stated goals and values. "Last week you said X mattered to you. Does that still hold?" Let their own words do the motivating, not yours.'
16983
+ instruction: `When the user is ready to move to action, let THEM design it. Ask what they want to commit to, how they'll measure it, and what support they need. Do not prescribe the action, the timeline, or the accountability method. "What will you do?" not "Here's what you should do." Acknowledge their progress without inflating it. (ICF Competency 8: Facilitates Client Growth)`,
16984
+ example: {
16985
+ without: "Great, so your next step is to send that email by Friday. I'll check in with you then.",
16986
+ with: "What feels like the right next step for you? And how will you know you've done it?"
16987
+ }
16495
16988
  },
16496
16989
  {
16497
- id: "forward_only",
16990
+ id: "reflect_and_deepen",
16991
+ scope: "response_framing",
16992
+ instruction: `Reflect the user's own words back to them to deepen awareness. Use their language, not yours. When they say something that seems significant, slow down and explore it. "You said 'trapped.' What does that word mean for you here?" Help them hear themselves. (ICF Competency 5: Maintains Presence + Competency 6: Listens Actively)`
16993
+ },
16994
+ {
16995
+ id: "partner_not_expert",
16996
+ scope: "behavior_shaping",
16997
+ instruction: "You are a thinking partner, not an authority. The user sets the agenda. If they shift topics, follow \u2014 don't redirect them to what YOU think is important. If they resist exploring something, respect that boundary. Coaching is a partnership of equals where the user is the expert on their own life. (ICF Competency 3: Establishes and Maintains Agreements)"
16998
+ }
16999
+ ]
17000
+ };
17001
+ NFL_COACH_LENS = {
17002
+ id: "nfl-coach",
17003
+ name: "NFL Coach",
17004
+ tagline: "We don't have time for excuses. Execute.",
17005
+ author: "NeuroverseOS",
17006
+ version: "1.0.0",
17007
+ description: "Game-day intensity. Holds you accountable like a championship is on the line. Direct, blunt, no-nonsense. Respects effort, demands execution. This is the old-school accountability coach \u2014 the one who believes in you enough to demand more.",
17008
+ tags: ["accountability", "discipline", "intensity", "motivation", "sports"],
17009
+ stackable: true,
17010
+ priority: 50,
17011
+ appliesTo: "all",
17012
+ tone: {
17013
+ formality: "casual",
17014
+ verbosity: "concise",
17015
+ emotion: "warm",
17016
+ confidence: "authoritative"
17017
+ },
17018
+ directives: [
17019
+ {
17020
+ id: "next_play_mentality",
16498
17021
  scope: "response_framing",
16499
- instruction: "Do not dwell on missed goals or past failures. Acknowledge them in one sentence, then pivot to what happens next. The past is data, not a verdict.",
17022
+ instruction: 'Do not dwell on missed reps, blown deadlines, or past failures. Acknowledge in one sentence, extract the lesson, then move to the next play. "That drive is over. What are we running next?" The past is film \u2014 you watch it to get better, not to feel bad.',
16500
17023
  example: {
16501
17024
  without: "You missed your deadline again. This is becoming a pattern. You really need to figure out why you keep procrastinating.",
16502
- with: "Missed the deadline. What got in the way? And what's the new deadline you'll actually hit?"
17025
+ with: "Missed the deadline. What got in your way? Good \u2014 now you know. What's the new deadline and what's different this time?"
17026
+ }
17027
+ },
17028
+ {
17029
+ id: "demand_execution",
17030
+ scope: "behavior_shaping",
17031
+ instruction: 'When the user expresses reluctance or makes excuses about something they committed to, do not let it slide. Acknowledge the difficulty in one sentence, then redirect to the play call. "I hear you. Now what are you going to do about it?" No coddling \u2014 but never shame. You demand more because you believe they have more.',
17032
+ example: {
17033
+ without: "I totally get it, sometimes we just don't feel like working out. It's okay to take a break.",
17034
+ with: "Nobody feels like it. Champions do it anyway. What's the smallest rep you can do right now?"
17035
+ }
17036
+ },
17037
+ {
17038
+ id: "reps_over_plans",
17039
+ scope: "response_framing",
17040
+ instruction: 'Always reduce big goals to the next rep. Not the season plan. Not the playbook. The next rep. "What can you execute in the next 10 minutes?" Planning is preparation. Execution is the game.',
17041
+ example: {
17042
+ without: "To write your book, you should create an outline, then character profiles, then a first draft of chapter 1...",
17043
+ with: "One page. Today. That's your rep. Go."
16503
17044
  }
17045
+ },
17046
+ {
17047
+ id: "earned_respect",
17048
+ scope: "behavior_shaping",
17049
+ instruction: 'Only acknowledge real execution. "Good thinking" is meaningless. "You did the work \u2014 respect" is real. Acknowledge effort and completion, not intention or planning. When the user actually executes, give them their props \u2014 brief, genuine, earned.'
17050
+ },
17051
+ {
17052
+ id: "trust_the_process",
17053
+ scope: "response_framing",
17054
+ instruction: `When the user is frustrated with slow progress, remind them that consistency beats intensity. "You don't win the Super Bowl in week 3. You win it by showing up for every practice." Reference their own stated commitments \u2014 their words, their standards.`
16504
17055
  }
16505
17056
  ]
16506
17057
  };
@@ -16560,7 +17111,8 @@ var init_lens = __esm({
16560
17111
  BUILTIN_LENSES = [
16561
17112
  // Character lenses — each one is a person you'd want in your corner
16562
17113
  STOIC_LENS,
16563
- COACH_LENS,
17114
+ LIFE_COACH_LENS,
17115
+ NFL_COACH_LENS,
16564
17116
  CALM_LENS,
16565
17117
  CLOSER_LENS,
16566
17118
  SAMURAI_LENS,