Skip to content

Commit b537a1a

Browse files
authored
Merge pull request #43 from initializ/security/phase2-high-fixes
docs: sync documentation for Phase 2 fixes and UI improvements
2 parents 3b779f6 + f0d06fc commit b537a1a

5 files changed

Lines changed: 24 additions & 5 deletions

File tree

docs/dashboard.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ The main view discovers all agents in the workspace directory and shows their st
3030
| Daemon processes | Agents run as background daemons via `forge serve` — they survive UI shutdown |
3131
| Live status | Real-time state updates (stopped, starting, running, errored) |
3232
| Passphrase unlock | Prompts for `FORGE_PASSPHRASE` when agents have encrypted secrets |
33+
| Startup error display | Shows actual error messages (e.g., missing env vars) in the agent card when startup fails, extracted from `.forge/serve.log` |
3334
| Auto-rescan | Detects new agents after creation |
3435
| Unified management | All agents (UI-started or CLI-started) get identical Start/Stop controls |
3536

@@ -39,6 +40,7 @@ The UI manages agents as daemon processes using `forge serve start` / `forge ser
3940

4041
- **Agents survive UI shutdown** — closing the dashboard does not kill running agents.
4142
- **Restart detection** — restarting the UI auto-discovers running agents via `.forge/serve.json` and TCP probing.
43+
- **PID liveness verification** — after `forge serve start` returns, the UI verifies the child process is still alive via PID probing and TCP port check. If the child crashed (e.g., missing env vars), the error is extracted from `.forge/serve.log` and displayed in the agent card.
4244
- **Unified view** — agents started from the CLI (`forge serve start`) and agents started from the UI appear identically. There is no distinction between "UI-managed" and "CLI-managed" agents.
4345

4446
## Interactive Chat
@@ -102,7 +104,7 @@ An AI-powered conversational tool for creating custom skills. Access it via the
102104

103105
### How It Works
104106

105-
The Skill Builder uses the agent's own LLM provider to power a chat conversation that generates valid SKILL.md files and optional helper scripts. It automatically selects a stronger code-generation model when available (e.g. `gpt-4.1` for OpenAI, `claude-opus-4-6` for Anthropic).
107+
The Skill Builder uses the agent's own LLM provider to power a chat conversation that generates valid SKILL.md files and optional helper scripts. It automatically selects a stronger code-generation model when available (e.g. `gpt-4.1` for OpenAI, `claude-opus-4-6` for Anthropic). API key detection loads the agent's `.env` file and encrypted secrets (if unlocked) in addition to system environment variables.
106108

107109
### Features
108110

docs/runtime.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ User message → Memory → LLM → tool_calls? → Execute tools → LLM → ..
2121

2222
The loop terminates when `FinishReason == "stop"` or `len(ToolCalls) == 0`.
2323

24+
### Q&A Nudge Suppression
25+
26+
When the agent finishes with `stop` and no workflow phases are configured, the loop checks whether edit or git tools were used. If only explore-phase tools were invoked (e.g., `web_search`, `file_read`), the conversation is classified as informational/Q&A — the agent's text response is the final answer and no continuation nudge ("You stopped…") is sent. This prevents the agent from re-summarizing answers to simple questions.
27+
2428
## LLM Providers
2529

2630
Forge supports multiple LLM providers with automatic fallback:
@@ -222,7 +226,7 @@ The runner registers five hook groups: logging, audit, progress, global guardrai
222226

223227
## Streaming
224228

225-
The current implementation (v1) runs the full tool-calling loop non-streaming. `ExecuteStream` calls `Execute` internally and emits the final response as a single message on a channel. True word-by-word streaming during tool loops is planned for v2.
229+
The LLM tool-calling loop runs non-streaming internally. `ExecuteStream` calls `Execute` and emits the final response on a channel. However, the **UI chat proxy** (`forge-ui/chat.go`) streams A2A SSE events to the browser in real-time — `status` events carry incremental text, `progress` events carry tool execution updates, and `result` events carry the final response. The frontend renders text and tool progress as each event arrives.
226230

227231
---
228232
[Tools](tools.md) | [Back to README](../README.md) | [Memory](memory.md)

docs/security/guardrails.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ Some tools legitimately return PII as part of their function (e.g., `github_get_
108108
"file_create",
109109
"code_agent_write",
110110
"code_agent_edit",
111-
"cli_execute"
111+
"cli_execute",
112+
"web_search"
112113
]
113114
}
114115
}
@@ -122,6 +123,7 @@ Some tools legitimately return PII as part of their function (e.g., `github_get_
122123
|----------|--------|
123124
| Per-guardrail scope | `allow_tools` on `no_pii` does **not** bypass `no_secrets` — each guardrail has its own allowlist |
124125
| Write tools included | `file_create`, `code_agent_write`, `code_agent_edit`, and `cli_execute` are included because they echo back content the LLM already has or return operational output that may contain incidental PII (e.g., git log author emails) |
126+
| Web search included | `web_search` is included because search results routinely contain names, emails, and other PII that is public web content — blocking these results would make Q&A conversations unusable |
125127
| Default config | The default policy scaffold pre-configures `allow_tools` for GitHub profile tools and write tools |
126128
| Custom overrides | Override via `policy-scaffold.json` to add or remove tools from the allowlist |
127129

docs/security/overview.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ The `cli_execute` tool (`forge-cli/tools/cli_execute.go`) provides 13 security l
143143
| 7 | **Timeout** | Configurable per-command timeout (default: 120s) |
144144
| 8 | **No shell** | Uses `exec.CommandContext` directly — no shell expansion |
145145
| 9 | **Working directory** | `cmd.Dir` set to `workDir` for relative path resolution |
146-
| 10 | **Environment isolation** | Only `PATH`, `HOME`, `LANG`, explicit passthrough vars, proxy vars, and `GH_CONFIG_DIR` (auto-set **only for `gh` binary** when HOME is overridden) |
146+
| 10 | **Environment isolation** | Only `PATH`, `HOME`, `LANG`, explicit passthrough vars, proxy vars, `GH_CONFIG_DIR` (auto-set **only for `gh`**), and `KUBECONFIG`/`NO_PROXY` (**only for `kubectl`/`helm`** — restores kubeconfig access and bypasses egress proxy for the K8s API server when HOME is overridden) |
147147
| 11 | **Output limits** | Configurable max output size (default: 1MB) to prevent memory exhaustion |
148148
| 12 | **Skill guardrails** | Skill-declared `deny_commands` and `deny_output` patterns via hooks |
149149
| 13 | **Custom tool entrypoint validation** | Custom tool entrypoints are validated against path traversal, symlink escape, absolute paths, and non-regular files |

docs/tools.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,22 @@ tools:
117117
| 7 | **Timeout** | Configurable per-command timeout (default: 120s) |
118118
| 8 | **No shell** | Uses `exec.CommandContext` directly — no shell expansion |
119119
| 9 | **Working directory** | `cmd.Dir` set to `workDir` so relative paths resolve within the agent directory |
120-
| 10 | **Environment isolation** | Only `PATH`, `HOME`, `LANG`, explicit passthrough vars, proxy vars, `OPENAI_ORG_ID` (when set), and `GH_CONFIG_DIR` (auto-set to real `~/.config/gh` **only for the `gh` binary** when HOME is overridden). `HOME` is overridden to `workDir` to prevent `~` expansion from reaching the real home directory |
120+
| 10 | **Environment isolation** | Only `PATH`, `HOME`, `LANG`, explicit passthrough vars, proxy vars, `OPENAI_ORG_ID` (when set), `GH_CONFIG_DIR` (auto-set to real `~/.config/gh` **only for `gh`**), and `KUBECONFIG`/`NO_PROXY` (**only for `kubectl`/`helm`** — see below). `HOME` is overridden to `workDir` to prevent `~` expansion from reaching the real home directory |
121121
| 11 | **Output limits** | Configurable max output size (default: 1MB) to prevent memory exhaustion |
122122
| 12 | **Skill guardrails** | Skill-declared `deny_commands` and `deny_output` patterns block/redact command inputs and outputs (see [Skill Guardrails](security/guardrails.md#skill-guardrails)) |
123123
| 13 | **Custom tool entrypoint validation** | Custom tool entrypoints are validated: rejects empty, absolute, or `..`-containing paths; resolves symlinks and verifies the target stays within the project directory and is a regular file |
124124

125+
### KUBECONFIG and NO_PROXY Scoping
126+
127+
When `HOME` is overridden to `workDir`, `kubectl` and `helm` lose access to `~/.kube/config`. For these two binaries only, `cli_execute` auto-sets:
128+
129+
| Env Var | Value | Purpose |
130+
|---------|-------|---------|
131+
| `KUBECONFIG` | `<real-home>/.kube/config` | Restores access to the real kubeconfig |
132+
| `NO_PROXY` | K8s API server hostname(s) | Bypasses the egress proxy for cluster connections |
133+
134+
`NO_PROXY` is extracted from the kubeconfig's `clusters[].cluster.server` field. Other binaries do not receive these variables.
135+
125136
## File Create
126137

127138
The `file_create` tool generates downloadable files that are both written to disk and uploaded to the user's channel (Slack/Telegram).

0 commit comments

Comments
 (0)