archgraph-argo 0.26.2 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,144 @@
1
+ 'use strict';
2
+
3
+ // Cross-project workspace WRITE guard.
4
+ //
5
+ // The per-call `workspaceRoot` override is a wanted capability: it lets a caller
6
+ // READ another local project's intent graph. It must NOT let the caller WRITE an
7
+ // arbitrary other project's graph. This guard bounds writes to the server's HOME
8
+ // workspace PLUS a host-designated session workspace that only a trusted broker
9
+ // may name.
10
+ //
11
+ // Two channels, deliberately distinct:
12
+ // - `workspaceRoot` : the generic per-call override. A model may set it.
13
+ // Reads honor it; a WRITE to a foreign path is denied.
14
+ // - `sessionWorkspaceRoot`: the host broker's (e.g. the DSH workspace bridge)
15
+ // designation of the current session's workspace. It
16
+ // is trusted for writes ONLY when the process was
17
+ // launched with ARGO_WORKSPACE_ROOT_TRUSTED=1 (set by
18
+ // the broker at spawn, which the model cannot forge).
19
+ // A model-supplied sessionWorkspaceRoot on a plain
20
+ // (unflagged) server is ignored.
21
+ //
22
+ // So: cross-project reading keeps working everywhere; cross-project WRITING is
23
+ // blocked unless the trusted host broker explicitly designates that workspace.
24
+ // The whole guard is OFF (all-or-nothing) with ARGO_WORKSPACE_WRITE_GUARD=0.
25
+
26
+ const path = require('node:path');
27
+
28
+ // Host-designated trusted session workspace (broker channel, not advertised to
29
+ // the model).
30
+ const TRUSTED_SESSION_FIELD = 'sessionWorkspaceRoot';
31
+ // Spawn-time flag the broker sets to assert it controls TRUSTED_SESSION_FIELD.
32
+ const TRUSTED_ENV = 'ARGO_WORKSPACE_ROOT_TRUSTED';
33
+
34
+ // Tools whose invocation mutates the target workspace. `preview*` and the read
35
+ // tools are intentionally absent.
36
+ const WRITE_TOOLS = Object.freeze(new Set([
37
+ 'initializeWorkspace',
38
+ 'runArchitectureTests',
39
+ 'applySystemArchitectureMutation',
40
+ 'addArchitectureElement',
41
+ 'updateArchitectureElement',
42
+ 'removeArchitectureElement',
43
+ 'addArchitectureRelationship',
44
+ 'updateArchitectureRelationship',
45
+ 'removeArchitectureRelationship',
46
+ 'addArchitectureView',
47
+ 'updateArchitectureView',
48
+ 'removeArchitectureView',
49
+ ]));
50
+
51
+ function guardDisabled(env = process.env) {
52
+ const value = env && env.ARGO_WORKSPACE_WRITE_GUARD;
53
+ return value !== undefined && String(value).trim() === '0';
54
+ }
55
+
56
+ // A focused mutation with dryRun:true validates only and never writes, so it is
57
+ // not a write for this guard. initializeWorkspace has no dry-run.
58
+ function isWriteTool(name, args = {}) {
59
+ if (!WRITE_TOOLS.has(name)) {
60
+ return false;
61
+ }
62
+ if (name !== 'initializeWorkspace' && args && args.dryRun === true) {
63
+ return false;
64
+ }
65
+ return true;
66
+ }
67
+
68
+ function sameWorkspace(a, b) {
69
+ const na = path.resolve(String(a));
70
+ const nb = path.resolve(String(b));
71
+ return process.platform === 'win32' ? na.toLowerCase() === nb.toLowerCase() : na === nb;
72
+ }
73
+
74
+ // The host-broker-designated session workspace, honored only behind the
75
+ // spawn-time trust flag. Returns an absolute path or null.
76
+ function trustedSessionWorkspace(args, env = process.env) {
77
+ if (!env || String(env[TRUSTED_ENV]).trim() !== '1') {
78
+ return null;
79
+ }
80
+ const raw = args && typeof args[TRUSTED_SESSION_FIELD] === 'string'
81
+ ? args[TRUSTED_SESSION_FIELD].trim()
82
+ : '';
83
+ return raw !== '' ? path.resolve(raw) : null;
84
+ }
85
+
86
+ /**
87
+ * Authorize one write against the home workspace and the trusted session workspace.
88
+ *
89
+ * @param {object} options
90
+ * @param {string} options.tool
91
+ * @param {object} [options.args]
92
+ * @param {string} options.homeRoot - the server's own workspace root.
93
+ * @param {object} [options.env] - injectable environment (tests).
94
+ * @returns {{allowed:boolean, category?:string, message?:string, tool:string, homeWorkspaceRoot:string, requestedWorkspaceRoot:string, trustedSessionWorkspaceRoot:(string|null)}}
95
+ */
96
+ function authorizeWorkspaceWrite({ tool, args = {}, homeRoot, env = process.env }) {
97
+ const requestedRaw = args && typeof args.workspaceRoot === 'string' ? args.workspaceRoot.trim() : '';
98
+ const requested = requestedRaw !== '' ? path.resolve(requestedRaw) : path.resolve(homeRoot);
99
+ const trusted = trustedSessionWorkspace(args, env);
100
+ const base = {
101
+ tool,
102
+ homeWorkspaceRoot: path.resolve(homeRoot),
103
+ requestedWorkspaceRoot: requested,
104
+ trustedSessionWorkspaceRoot: trusted,
105
+ };
106
+ if (guardDisabled(env) || sameWorkspace(requested, homeRoot)) {
107
+ return { ...base, allowed: true };
108
+ }
109
+ if (trusted && sameWorkspace(requested, trusted)) {
110
+ return { ...base, allowed: true };
111
+ }
112
+ return {
113
+ ...base,
114
+ allowed: false,
115
+ category: 'WORKSPACE_WRITE_DENIED',
116
+ message:
117
+ `Write tool '${tool}' targets workspace '${requested}' but this server is only allowed to write its home workspace ` +
118
+ `'${base.homeWorkspaceRoot}' (plus a trusted host-designated session workspace). Cross-project access is read-only: ` +
119
+ 'pass workspaceRoot only to read tools (getSystemArchitecture, getIntentElementContext, getArchitectureViewContext, ' +
120
+ 'queryNeo4jGraph, memory_search).',
121
+ };
122
+ }
123
+
124
+ // Remove the broker-only field so it never reaches tool schema validation.
125
+ function stripTrustedSessionField(args) {
126
+ if (!args || !Object.prototype.hasOwnProperty.call(args, TRUSTED_SESSION_FIELD)) {
127
+ return args;
128
+ }
129
+ const next = { ...args };
130
+ delete next[TRUSTED_SESSION_FIELD];
131
+ return next;
132
+ }
133
+
134
+ module.exports = {
135
+ WRITE_TOOLS,
136
+ TRUSTED_SESSION_FIELD,
137
+ TRUSTED_ENV,
138
+ guardDisabled,
139
+ isWriteTool,
140
+ sameWorkspace,
141
+ trustedSessionWorkspace,
142
+ authorizeWorkspaceWrite,
143
+ stripTrustedSessionField,
144
+ };
@@ -17,10 +17,12 @@ disable-model-invocation: true
17
17
  ## Rules
18
18
 
19
19
  - **MUST** 调用 ARGO MCP 工具 `initializeWorkspace`(传当前工作区根)执行确定性初始化,并以其返回报告为最终判断依据。
20
+ - **MUST** 报告当前 schema:`initializeWorkspace` 返回的 `schema`(或 harness 的 `schemaBundle`)中的 `kind`(default=内置 ArchiMate 3.2 / workspace=仓内自定义 / override)、`language`(名称)、`actorElementType`、`dir`、`guide`;输出形如 `schema: default / ArchiMate 3.2`。
20
21
  - **MUST** 报告 `mcp` / `systemArchitecture` / `neo4j` / `qeaFullProjection` / `semanticLifecycle` / `subdiagramViews` 与整体 `status`。
21
22
  - **MUST** 核验并报告:① `.qea` 投影是否成功(`qeaFullProjection.status`),且投影目标 `qeaFullProjection.qea` 是否为**本仓库自己的 .qea 文件**(解析自 `ARGO_EA_QEA` 或仓库根唯一 `*.qea`);目标不是本仓库文件或投影失败 → 报告为告警/失败,不得视为 init 成功。
22
23
  - **MUST** 核验并报告:Neo4j 投影目标数据库名(`neo4j.database`)是否**与本仓库名一致**(仓库 basename == 数据库名);不一致 → 报告为告警/失败。
23
- - **MUST NOT** 读取、打印或复述 `.env` 中的 secret 值;排查时只允许报告 key 是否存在、ACL 主体。
24
+ - **MUST NOT** 因 schema 是自定义的而跳过 `.qea` 投影:投影对任何 schema 都执行;只有确实没有 `.qea` 目标时才允许 `noop`。
25
+ - **MUST NOT** 读取、打印或复述 `.env` 中的 secret 值;排查时只允许报告 key 是否存在。
24
26
  - **MUST NOT** 通过 shell 手工执行 WORKSPACE 外的初始化脚本或一组无关命令来替代 `initializeWorkspace`(除非报告显示底层脚本自身失败需要排查)。
25
27
 
26
28
  ## Workflow
@@ -47,18 +49,13 @@ disable-model-invocation: true
47
49
 
48
50
  ### 3. Handle Secret File Blockers(仅当报告含 secret 相关失败)
49
51
 
50
- `semanticLifecycle` 或 `systemArchitecture` 失败可能源于 `.env` 安全预检。诊断(不打印 secret 值):
52
+ `semanticLifecycle` 或 `systemArchitecture` 失败可能源于 `.env` 预检。诊断(不打印 secret 值):
51
53
 
52
- ```powershell
53
- icacls "$env:USERPROFILE\.argo\.env"
54
- ```
54
+ 处理规则(env 文件不做 OS ACL / 权限加固;只保证不被提交):
55
55
 
56
- 处理规则:
57
-
58
- - `SECRET_FILE_ACL_UNSAFE`:收紧 Windows ACL,只保留当前用户、Administrators、SYSTEM。
59
56
  - `SECRET_FILE_REPARSE_PROHIBITED`:将 `.env` 替换为普通文件(去掉符号链接/重解析点)。
60
57
  - `SECRET_FILE_PATH_PROHIBITED`:修正 `ARGO_ENV_FILE` 与安装根 `.env` 不一致的路径。
61
- - git 跟踪/忽略类错误(`SECRET_FILE_TRACKED` / `SECRET_FILE_NOT_IGNORED`)只在 `.env` 位于 git 仓库内时出现;全局 `.env` 位于仓库外时天然不适用。
58
+ - git 跟踪/忽略类错误(`SECRET_FILE_TRACKED` / `SECRET_FILE_NOT_IGNORED`):把 `.env` 加入 `.gitignore` 并 `git rm --cached`;全局 `.env` 位于仓库外时天然不适用。
62
59
 
63
60
  修复后重跑 `initializeWorkspace`。
64
61
 
@@ -72,6 +69,7 @@ icacls "$env:USERPROFILE\.argo\.env"
72
69
 
73
70
  ### 1. Environment Status
74
71
  - overall status: ok / failed
72
+ - **解析到的 schema:kind(default/workspace/override)+ language(名称)+ actorElementType + dir/guide**(默认 ArchiMate 3.2 还是仓内自定义 schema)
75
73
  - whether mcp health passed
76
74
  - whether neo4j health passed
77
75
  - whether .qea full projection passed
@@ -1,39 +1,40 @@
1
- ---
2
- name: ea-human-reconcile
3
- description: "把人类从 EA 提取的 draft 提议(results/human-draft.md,内嵌 JSON 提议集)交给 Agent 后,Agent 结合当前全局(canonical 意图图 design/KG/SystemArchitecture.json + Neo4j 语义检索)逐条/整体分析并给出建议,最终由人类裁决是否写入。它是『人类 EA 草稿 → 语义 diff 提取 → 人类裁决写回』的最后一步:Agent 只做分析+建议,绝不自作主张 apply。Use when the user hands over an EA human-draft proposal set (human-draft.md) and wants the agent to analyze it against the whole architecture and propose, leaving the final decision to the human. Keywords: EA human draft, reconcile, EA 人类草稿裁决, draft review, 语义diff建议, ARGO preview/apply, 人类裁决."
4
- argument-hint: human-draft
5
- disable-model-invocation: true
6
- ---
7
-
8
- # EA HUMAN DRAFT RECONCILE(EA 人类草稿 → Agent 分析建议 → 人类裁决)
9
-
10
- Agent 的职责:结合全局分析 draft 中的每条提议、给出建议与理由、识别风险,把结论呈现给人类,由人类裁决。Agent 不自动执行写入。
11
-
12
- ## 前置
13
-
14
- - [ ] 存在 `results/human-draft.md`(人类从 EA 提取的草稿提议集)。
15
- - [ ] 工作区有 `design/KG/SystemArchitecture.json`(canonical 意图图)——分析全局的依据。
16
- - [ ] ARGO MCP 可用。关键查询手段:
17
- - 语义/上下文:`getSystemArchitecture`(带 query.purpose + query.intent)、`getIntentElementContext`(看单个元素/关系/视图的依赖与受影响对象)。
18
- - 结构/类型:`queryNeo4jGraph`(只读 Cypher,如 `MATCH (e:Element {graphKey: $graphKey, type:'Business Actor'}) ...`;先 `{schema:true}` 查投影 schema)。
19
- - 校验:`validateSystemArchitecture`;写图:`previewSystemArchitectureMutation` / `applySystemArchitectureMutation`。
20
-
21
- ## 原则
22
-
23
- - **人类裁决**:Agent 只分析、给建议、识别风险;**MUST NOT 未经人类裁决就 `applySystemArchitectureMutation`(或任何写图)**。人类拍板(采纳/拒绝/修改)后才写。
24
- - **全局优先**:不只对着 draft 字段,要用查询手段读 canonical 中相关对象及其依赖(被谁引用、级联影响谁、子视图是否悬空、命名/类型是否与全局一致、是否与既有元素重复冲突),再下判断。
25
- - **删除/破坏性提议单独把关**:对 `removeElement` / `removeRelationship` / `removeView`,必须指出 canonical 里谁引用它、删除会级联影响谁,并给出「保留 / 改挂 / 确认删除」的建议,交由人类确认。
26
- - **新增/更新提议**:核对 type / name / description / attributes 是否与全局命名与类型一致、是否与既有元素/关系重复冲突、应挂在哪个 parent / 视图下。
27
- - **视图提议**:核对成员是否落在正确层级(parent_element_id 是否合理)、删视图会否使相关 subdiagram_views 悬空。
28
- - **只读取、不泄露**:MUST NOT 读取/复述 `.env` 里的 secret 或推断敏感配置值。
29
-
30
- ## 目标
31
-
32
- 读 draft → 结合全局逐条分析 → 给出「逐条建议 + 整体结论 + 待人类裁决项」。具体产出:
33
-
34
- 1. **操作统计**:add/update/remove × element/relationship/view。
35
- 2. **逐条建议**:每条含 `提议`(op + id/名称)、`分析`(全局依赖/冲突/层级)、`建议`(采纳/拒绝/修改后采纳,附理由)、`风险`(若有)。
36
- 3. **整体结论**:这批草稿的整体风险等级、必人工确认的高风险项。
37
- 4. **待裁决**:明确列出需人类拍板的条目,并询问哪些采纳、哪些修改、哪些拒绝。
38
-
39
- **等待人类答复之后**才进入写回;若人类同意,才经 `previewSystemArchitectureMutation` →(确认后)`applySystemArchitectureMutation`;拒绝/搁置的不写。
1
+ ---
2
+ name: ea-human-reconcile
3
+ description: "把人类从 EA 提取的 draft 提议(results/human-draft.md,内嵌 JSON 提议集)交给 Agent 后,Agent 结合当前全局(canonical 意图图 design/KG/SystemArchitecture.json + Neo4j 语义检索)逐条/整体分析并给出建议,最终由人类裁决是否写入。它是『人类 EA 草稿 → 语义 diff 提取 → 人类裁决写回』的最后一步:Agent 只做分析+建议,绝不自作主张 apply。Use when the user hands over an EA human-draft proposal set (human-draft.md) and wants the agent to analyze it against the whole architecture and propose, leaving the final decision to the human. Keywords: EA human draft, reconcile, EA 人类草稿裁决, draft review, 语义diff建议, ARGO preview/apply, 人类裁决."
4
+ argument-hint: human-draft
5
+ disable-model-invocation: true
6
+ ---
7
+
8
+ # EA HUMAN DRAFT RECONCILE(EA 人类草稿 → Agent 分析建议 → 人类裁决)
9
+
10
+ Agent 的职责:结合全局分析 draft 中的每条提议、给出建议与理由、识别风险,把结论呈现给人类,由人类裁决。Agent 不自动执行写入。
11
+
12
+ ## 前置
13
+
14
+ - [ ] 存在 `results/human-draft.md`(人类从 EA 提取的草稿提议集)。
15
+ - [ ] 工作区有 `design/KG/SystemArchitecture.json`(canonical 意图图)——分析全局的依据。
16
+ - [ ] ARGO MCP 可用。关键查询手段:
17
+ - 语义/上下文:`getSystemArchitecture`(带 query.purpose + query.intent)、`getIntentElementContext`(看单个元素/关系/视图的依赖与受影响对象)。
18
+ - 结构/类型:`queryNeo4jGraph`(只读 Cypher,如 `MATCH (e:Element {graphKey: $graphKey, type:'<element type>'}) ...`)。先 `{schema:true}` 取当前工作区的语言与类型枚举,类型名一律取自该结果,勿硬编码。
19
+ - 校验:`validateSystemArchitecture`;写图:`previewSystemArchitectureMutation` / `applySystemArchitectureMutation`。
20
+
21
+ ## 原则
22
+
23
+ - **人类裁决**:Agent 只分析、给建议、识别风险;**MUST NOT 未经人类裁决就 `applySystemArchitectureMutation`(或任何写图)**。人类拍板(采纳/拒绝/修改)后才写。
24
+ - **全局优先**:不只对着 draft 字段,要用查询手段读 canonical 中相关对象及其依赖(被谁引用、级联影响谁、子视图是否悬空、命名/类型是否与全局一致、是否与既有元素重复冲突),再下判断。
25
+ - **删除/破坏性提议单独把关**:对 `removeElement` / `removeRelationship` / `removeView`,必须指出 canonical 里谁引用它、删除会级联影响谁,并给出「保留 / 改挂 / 确认删除」的建议,交由人类确认。
26
+ - **新增/更新提议**:核对 type / name / description / attributes 是否与全局命名与类型一致、是否与既有元素/关系重复冲突、应挂在哪个 parent / 视图下。
27
+ - **视图提议**:核对成员是否落在正确层级(parent_element_id 是否合理)、删视图会否使相关 subdiagram_views 悬空。
28
+ - **类型以工作区 schema 为准**:分析前先 `queryNeo4jGraph {schema:true}` 取 `schemaLanguage` 与元素/关系类型枚举;按该枚举判定类型,**勿硬编码 ArchiMate 类型**。
29
+ - **只读取、不泄露**:MUST NOT 读取/复述 `.env` 里的 secret 或推断敏感配置值。
30
+
31
+ ## 目标
32
+
33
+ 读 draft → 结合全局逐条分析 → 给出「逐条建议 + 整体结论 + 待人类裁决项」。具体产出:
34
+
35
+ 1. **操作统计**:add/update/remove × element/relationship/view。
36
+ 2. **逐条建议**:每条含 `提议`(op + id/名称)、`分析`(全局依赖/冲突/层级)、`建议`(采纳/拒绝/修改后采纳,附理由)、`风险`(若有)。
37
+ 3. **整体结论**:这批草稿的整体风险等级、必人工确认的高风险项。
38
+ 4. **待裁决**:明确列出需人类拍板的条目,并询问哪些采纳、哪些修改、哪些拒绝。
39
+
40
+ **等待人类答复之后**才进入写回;若人类同意,才经 `previewSystemArchitectureMutation` →(确认后)`applySystemArchitectureMutation`;拒绝/搁置的不写。
package/cordis.patch.yml CHANGED
@@ -1,6 +1,15 @@
1
- # ArchGraph ARGO bundle patch:随 bundle 安装,按包名引用包内插件(非 file://)。
2
- - insert:
3
- - id: argo-workspace
4
- name: archgraph-argo/dsh-argo-workspace
5
- - id: argo-wakeup
6
- name: archgraph-argo/dsh-argo-wakeup
1
+ # ArchGraph ARGO bundle patch:随 bundle 安装,按包名引用包内插件(非 file://)。
2
+ - insert:
3
+ - id: argo-workspace
4
+ name: archgraph-argo/dsh-argo-workspace
5
+ config:
6
+ servers:
7
+ - id: argo
8
+ injectWorkspaceRoot: true
9
+ - id: graph-mcp
10
+ serverPath: '../argo/mcp-bridges/graph-mcp-stdio.js'
11
+ env:
12
+ GRAPH_MCP_URL: https://argo.derekworkspacev5.com/mcp
13
+ injectWorkspaceRoot: false
14
+ - id: argo-wakeup
15
+ name: archgraph-argo/dsh-argo-wakeup
@@ -1,17 +1,17 @@
1
- // dsh-argo-wakeup - generated by install-argo.ps1 from
2
- // argo/rules/archgraph.instructions.md (single source of truth: the rule file;
3
- // this file is a deployment artifact, do not edit by hand).
4
- // DeepSeek Harness equivalent of the OpenCode hook argo/plugins/argo-wakeup.js:
5
- // registers the unconditional wakeup gate as the first system-prompt section
6
- // after the harness identity, so every session identifies its Business Actor
7
- // through the argo MCP server before responding.
8
- export const name = 'dsh-argo-wakeup'
9
- export const inject = ['systemPrompt']
10
- const WAKEUP_GATE = "STEP 0 — UNCONDITIONAL STARTUP GATE. This applies to the very first message of every session, including greetings, casual chat, and questions; it may never be skipped, deferred, or treated as optional.\r\n1. Your very FIRST tool call in the session MUST be an ARGO MCP query that lists all `Business Actor`s (getSystemArchitecture with purpose \"audit\" and subject \"Business Actor\"). Identify which `Business Actor` you are. If you are not sure, consult your human partner to confirm your role before doing anything else.\r\n2. Restore your long-term memory: the SUBVIEW hierarchy mounted under that `Business Actor` element — the Views whose `parent_element_id` points to this Actor, plus the elements, relationships, and further nested sub-views inside them (NOT the View that merely includes the Actor in its `included_elements`) — and load it into session memory.\r\n3. If the `agent` attribute of the confirmed Actor differs from your current Agent type, switch to that Agent type, or delegate to an Agent of that type per `\u003cCoperationGuideline\u003e` item 2.\r\n4. If the ARGO MCP is unavailable or errors, state that explicitly to the user before doing anything else. Only after completing this gate may you respond to the user or take any other action."
11
- export function apply(ctx) {
12
- ctx.effect(() => ctx.systemPrompt.section({
13
- name: 'argo:wakeup',
14
- order: -90,
15
- text: WAKEUP_GATE,
16
- }), 'argo:wakeup.section()')
17
- }
1
+ // dsh-argo-wakeup - generated by scripts/gen-dsh-plugins.js from
2
+ // argo/rules/archgraph.instructions.md (single source of truth: the rule file;
3
+ // this file is a deployment artifact, do not edit by hand).
4
+ // DeepSeek Harness equivalent of the OpenCode hook argo/plugins/argo-wakeup.js:
5
+ // registers the unconditional wakeup gate as the first system-prompt section
6
+ // after the harness identity, so every session identifies its Business Actor
7
+ // through the argo MCP server before responding.
8
+ export const name = 'dsh-argo-wakeup'
9
+ export const inject = ['systemPrompt']
10
+ const WAKEUP_GATE = "STEP 0 — UNCONDITIONAL STARTUP GATE. Applies to the very first message of every session, greetings and chat included; never skip, defer, or treat it as optional.\n1. Your first tool call MUST resolve the workspace schema and list its Actors: `queryNeo4jGraph` with `{schema:true}` → read `actorElementType` (`null` = no Actor concept, skip Actor identification), then query that element type. Confirm which Actor you are; if unsure, ask your human partner before anything else.\n2. Restore memory: load ONLY the T1 working-memory digest — your T1 summary, the most recent/active memory cards, and any session hooks (unfinished items from the last session). Do NOT bulk-load the T2 long-term memory or T3 archive; recall them on demand via `memory_search`, then read full content with `getIntentElementContext`. T2 is a recall target, not as a bulk context load.\n3. If the Actor's `agent` attribute differs from your type, switch to it or delegate per `<CoperationGuideline>` item 2.\n4. If the ARGO MCP is unavailable or errors, say so before doing anything else."
11
+ export function apply(ctx) {
12
+ ctx.effect(() => ctx.systemPrompt.section({
13
+ name: 'argo:wakeup',
14
+ order: -90,
15
+ text: WAKEUP_GATE,
16
+ }), 'argo:wakeup.section()')
17
+ }