-
Notifications
You must be signed in to change notification settings - Fork 0
docs(adr): an embedded agent that reads freely and writes through the gate #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5345f68
011b8ac
f84b9e1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,182 @@ | ||||||||||
| --- | ||||||||||
| status: accepted | ||||||||||
| --- | ||||||||||
|
|
||||||||||
| # 0019 · An embedded agent that reads freely and writes through the gate | ||||||||||
|
|
||||||||||
| ## Context | ||||||||||
|
|
||||||||||
| `adr:0003-mcp-as-the-only-bridge-to-the-llm` decided that **the application does not | ||||||||||
| call an LLM**. `adr:0013-the-project-directory-is-the-unit` superseded that record but | ||||||||||
| kept three of its clauses, calling them the substance of it: the application does not | ||||||||||
| call an LLM, the agent writes the pages, and write-time validation is what replaces the | ||||||||||
| writer. | ||||||||||
|
|
||||||||||
| The argument for the first clause was competition, and it was a good argument: the user | ||||||||||
| already pays for an agent, already configured it, already trusts it. A second writing | ||||||||||
| engine inside the application is duplicated work that delivers less. | ||||||||||
|
|
||||||||||
| **What changed is who installs the application.** 0003 was written for a user who | ||||||||||
| already had a harness open — for them the argument still holds completely, and this | ||||||||||
| record does not touch it. But the product now ships a signed installer, and somebody who | ||||||||||
| downloads it and has no harness has nothing: a window that scaffolds a project, validates | ||||||||||
| what is written into it, records every write, and cannot write a single page. The desktop | ||||||||||
| application says so on screen in as many words — *there is no model behind this window* — | ||||||||||
| which is honest and is also a description of a dead end. | ||||||||||
|
|
||||||||||
| The user with a harness is served, and `plans/harness-portability.md` is about serving | ||||||||||
| them better — `ow init` taking harnesses plural, so a project reaches whoever clones it | ||||||||||
| whichever one they use. That plan is written and not yet built; either way it is about | ||||||||||
| somebody who already has an agent. The user with none is the whole of what is left, and | ||||||||||
| nothing in this repository is addressed to them. | ||||||||||
|
|
||||||||||
| **And the reason the methodology works turns out to be a constraint on the answer.** The | ||||||||||
| LLM-Wiki convention works in Claude Code because the agent can explore: grep for a term | ||||||||||
| before coining a second name for it, glob the tree to see how pages are organised, read a | ||||||||||
| neighbouring page before writing one beside it. | ||||||||||
|
|
||||||||||
| The project already answers part of that. `ow search` is a lexical scan over every page's | ||||||||||
| title and body, and `ow graph` walks the structure. But `runSearch` returns | ||||||||||
| `{ slug, title, matches }` — **which pages mention a term and how many times, not the | ||||||||||
| passage**. `adr:0010-a-derived-index-engine-behind-a-cli` described "lexical hits with | ||||||||||
| page or source, passage, anchor"; what was built is narrower, and the difference decides | ||||||||||
| this. An agent told "three pages mention *cutover*" must read all three in full to learn | ||||||||||
| how the term is used there; `grep` hands it the line. For the cheap models this door | ||||||||||
| exists for, that is the context window. | ||||||||||
|
|
||||||||||
| So the gap is not that content search is missing. It is that one query returning counts | ||||||||||
| is not a discovery loop, and discovering that a concept already has a name is the exact | ||||||||||
| failure `docs/glossary.md` exists to prevent. | ||||||||||
|
|
||||||||||
| ## Decision | ||||||||||
|
|
||||||||||
| **The application may run an embedded agent. It reads the project the way a harness | ||||||||||
| does, and it writes only through the path the editor writes through.** | ||||||||||
|
|
||||||||||
| Three parts, and the split between the first two is the whole record. | ||||||||||
|
|
||||||||||
| **Reading is unrestricted within the project.** The agent gets the harness set — list, | ||||||||||
| glob, grep, read — over the project directory, every path confined with `assertWithin` | ||||||||||
| the way `packages/mcp` already confines its own. This is a reversal of nothing: reads | ||||||||||
| were never what the guarantees rested on. | ||||||||||
|
|
||||||||||
| **MCP's read-only rule does not transfer, and is not the reason for the next paragraph.** | ||||||||||
| That rule exists because one resident process serves *many* projects to a caller it does | ||||||||||
| not know, so the blast radius is every wiki on the machine and read-only has to be what | ||||||||||
| the process *can* do. The embedded agent is scoped to the project this window opened, in | ||||||||||
| this process, started by the person who clicked. Neither half of that reasoning applies. | ||||||||||
|
|
||||||||||
| **What does apply is the store's own invariant: nothing enters `wiki/` unvalidated.** | ||||||||||
| That is not distrust of the agent — the human typing in the editor goes through the same | ||||||||||
| door, and so does every hook. Frontmatter against the schema, wikilinks that resolve, | ||||||||||
| citations that point at a source and an instant that exist, the write atomic, the | ||||||||||
| operation logged with its origin and undoable. So the agent creates, edits, renames and | ||||||||||
| deletes pages through tools that do those things, and **no tool writes into `wiki/` | ||||||||||
| without passing through them**. Nothing is taken from the agent by this: `write_file` and | ||||||||||
| `writePage` are the same act, and only one of them is recoverable. | ||||||||||
|
|
||||||||||
| Outside `wiki/` the rule does not apply. A scratchpad — in memory, or under the | ||||||||||
| application's own temp — is where a proposal lives before anyone has approved it, and | ||||||||||
| that is a place the agent may write freely. | ||||||||||
|
Comment on lines
+69
to
+80
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
rg -n -C 5 --glob '!docs/**' \
'assertWithin|writePage|write_file|edit_file|execute|wiki/' .Repository: protonspy/open-wiki Length of output: 50376 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- relevant source files ---'
fd -t f . packages/access/src packages/cli/src packages/cli/tests | sort | \
rg '(paths|atomic-write|write|gate|hooks|commands/(edit|page|init)|main)\.(ts|tsx)$'
printf '%s\n' '--- hook implementation ---'
cat -n packages/cli/src/hooks.ts | sed -n '100,360p'
printf '%s\n' '--- gate command and dispatch references ---'
rg -n -C 8 'runPreToolUse|preWrite|writePage|atomicWrite|recordWrite|write_file|edit_file|execute|Bash|MultiEdit|Write|Edit' \
packages/cli/src packages/cli/tests plugins apps/desktop/src
printf '%s\n' '--- path and write implementations ---'
cat -n packages/access/src/paths.ts
cat -n packages/access/src/write/atomic-write.ts
cat -n packages/access/src/write/record.ts 2>/dev/null || true
cat -n packages/access/src/write/log.tsRepository: protonspy/open-wiki Length of output: 50376 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- ADR contexts ---'
cat -n docs/adr/0019-an-embedded-agent-that-reads-freely-and-writes-through-the-gate.md | sed -n '55,95p'
cat -n docs/adr/0019-an-embedded-agent-that-reads-freely-and-writes-through-the-gate.md | sed -n '124,145p'
printf '%s\n' '--- direct filesystem write calls outside tests ---'
rg -n --glob '*.ts' --glob '*.tsx' --glob '!**/*.spec.ts' --glob '!**/*.test.ts' \
'\b(writeFileSync|appendFileSync|renameSync|copyFileSync|rmSync|mkdirSync|createWriteStream|writeFile|appendFile|rename|copyFile|rm|mkdir)\s*\(' \
packages/access/src packages/cli/src apps/desktop/src plugins
printf '%s\n' '--- configured agent tools and hook matchers ---'
cat -n plugins/open-wiki/hooks/hooks.json
rg -n -C 10 'HOOK_MATCHERS|PreToolUse|PostToolUse|write_file|edit_file|execute|conformance|directly' \
packages/cli/src packages/cli/tests plugins docs/adrRepository: protonspy/open-wiki Length of output: 50377 🏁 Script executed: #!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
import re
# Read-only structural inventory of filesystem writes and hook decisions.
roots = [Path("packages/access/src"), Path("packages/cli/src"), Path("apps/desktop/src")]
write_re = re.compile(r'\b(?:writeFileSync|appendFileSync|renameSync|copyFileSync|rmSync|mkdirSync|createWriteStream)\s*\(')
for root in roots:
for p in sorted(root.rglob("*.ts")):
text = p.read_text()
hits = [(i, line.strip()) for i, line in enumerate(text.splitlines(), 1) if write_re.search(line)]
if hits:
print(f"{p}:")
for i, line in hits:
print(f" {i}: {line}")
PYRepository: protonspy/open-wiki Length of output: 3872 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- narrowed hook and gate files ---'
wc -l packages/cli/src/hooks.ts packages/cli/src/commands/gate.ts packages/cli/src/main.ts packages/access/src/paths.ts packages/access/src/write/atomic-write.ts
cat -n packages/cli/src/hooks.ts | sed -n '1,280p'
cat -n packages/cli/src/commands/gate.ts | sed -n '1,240p'
cat -n packages/access/src/paths.ts | sed -n '1,220p'
cat -n packages/access/src/write/atomic-write.ts | sed -n '1,150p'
printf '%s\n' '--- relevant tests only ---'
rg -n -C 6 'outside|project|\.claude|CLAUDE|README|notes|raw/|wiki/|Bash|Write|Edit|MultiEdit|execute|deny|allow' \
packages/cli/tests/hooks.spec.ts packages/cli/tests/gate.spec.ts packages/access/tests apps/desktop/tests 2>/dev/null || true
printf '%s\n' '--- ADR references and conformance wording ---'
rg -n -C 6 'conformance|writes directly|write_file|edit_file|execute|scratchpad|outside `wiki/`|application.*temp|project path|filesystem' docs/adr/0019-an-embedded-agent-that-reads-freely-and-writes-through-the-gate.md docs/adrRepository: protonspy/open-wiki Length of output: 50378 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- exact boundary logic ---'
sed -n '1,260p' packages/cli/src/hooks.ts
sed -n '1,220p' packages/cli/src/commands/gate.ts
sed -n '1,180p' packages/access/src/paths.ts
printf '%s\n' '--- configured hook tools ---'
cat plugins/open-wiki/hooks/hooks.json
rg -n -C 8 'does not flag a write outside|outside the wiki|\.claude/settings|preWrite\(|detectShellWrite\(|Write|Edit|MultiEdit|Bash' packages/cli/tests/hooks.spec.ts packages/cli/tests/release.spec.ts
printf '%s\n' '--- ADR target passages ---'
sed -n '64,92p' docs/adr/0019-an-embedded-agent-that-reads-freely-and-writes-through-the-gate.md
sed -n '128,140p' docs/adr/0019-an-embedded-agent-that-reads-freely-and-writes-through-the-gate.mdRepository: protonspy/open-wiki Length of output: 35516 🏁 Script executed: #!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
for p in [
Path("packages/cli/src/hooks.ts"),
Path("packages/cli/tests/hooks.spec.ts"),
Path("plugins/open-wiki/hooks/hooks.json"),
]:
print(f"--- {p} ---")
lines = p.read_text().splitlines()
for n, line in enumerate(lines, 1):
if any(term in line for term in (
"function preWrite", "function runPreToolUse", "detectShellWrite",
"isProtected", "wiki/", "notes/", "README.md", "permissionDecision",
"Write", "Edit", "MultiEdit", "Bash", "matcher", "hook",
)):
lo, hi = max(1, n-2), min(len(lines), n+3)
for i in range(lo, hi+1):
print(f"{i}: {lines[i-1]}")
print()
PYRepository: protonspy/open-wiki Length of output: 29933 Enforce a deny-by-default write boundary for agent tools.
🤖 Prompt for AI Agents |
||||||||||
|
|
||||||||||
| `adr:0003` closed by naming the shape that would preserve its decision if this day came: | ||||||||||
| "an embedded agent speaking the same MCP tools — **not a second writer with direct disk | ||||||||||
| access**". MCP is no longer the bridge, so the first half is now "the same tools the | ||||||||||
| external agent gets"; the second half is untouched and is the load-bearing half of this | ||||||||||
| record. An agent toolkit's filesystem surface — `write_file`, `edit_file`, `execute` — | ||||||||||
| is exactly what it excludes. | ||||||||||
|
|
||||||||||
| That is a restriction the toolkits support rather than resist, and saying otherwise | ||||||||||
| would be the easy overstatement here: `deepagents@1.12.1` defaults its filesystem to an | ||||||||||
| in-memory backend, hides `execute` unless the backend can execute at all, and takes an | ||||||||||
| allowlist whose own worked example is `["read_file", "ls", "glob", "grep"]`. **What is | ||||||||||
| not the default is the guarding.** Its path permissions are permissive when no rule | ||||||||||
| matches, and confinement to a root directory is opt-in. So the constraint costs a | ||||||||||
| configuration, and holding it means proving the refusal rather than reading the option | ||||||||||
| back. | ||||||||||
|
Comment on lines
+89
to
+96
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
rg -n -C 6 \
'deepagents|assertWithin|read_file|write_file|edit_file|execute|writePage|atomic|undo|allowlist|permission' .Repository: protonspy/open-wiki Length of output: 50376 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- ADR 0019 ---'
sed -n '1,190p' docs/adr/0019-an-embedded-agent-that-reads-freely-and-writes-through-the-gate.md
printf '%s\n' '--- candidate agent/config files ---'
git ls-files | rg -i 'deepagents|agent|mcp|claude|access|write|gate|package\.json|lock' | head -200
printf '%s\n' '--- focused access symbols ---'
rg -n -C 5 \
'export .*assertWithin|function assertWithin|gateWrite|writePage|atomicWrite|read_file|write_file|edit_file|execute|allowlist|permission|deepagents' \
packages/access packages/cli apps docs/adr/0019-an-embedded-agent-that-reads-freely-and-writes-through-the-gate.md \
--glob '!**/node_modules/**' --glob '!**/dist/**' | head -500Repository: protonspy/open-wiki Length of output: 50375 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- deepagents references and dependency declarations ---'
rg -n -i 'deepagents|langchain|filesystem|backend|allowlist|assertWithin|embedded agent|embedded-agent' \
--glob '!**/node_modules/**' --glob '!**/dist/**' . | head -400
printf '%s\n' '--- package manifests ---'
for f in package.json packages/access/package.json packages/cli/package.json packages/mcp/package.json apps/desktop/package.json; do
if test -f "$f"; then
echo "### $f"
cat "$f"
fi
done
printf '%s\n' '--- relevant gate and path implementation ---'
sed -n '1,180p' packages/access/src/gate/gate.ts
sed -n '1,130p' packages/access/src/paths.ts
sed -n '1,240p' packages/access/tests/gate-guard.spec.ts
printf '%s\n' '--- relevant application-tool tests ---'
sed -n '1,230p' packages/cli/tests/e2e.spec.ts
sed -n '1,180p' packages/cli/tests/gate.spec.tsRepository: protonspy/open-wiki Length of output: 49117 🌐 Web query:
💡 Result: In deepagents 1.12.1, the FilesystemMiddleware supports a tools allowlist to explicitly control which built-in filesystem tools are exposed to an agent [1][2]. Filesystem Tool Allowlist You can restrict an agent's filesystem capabilities by passing a tools set to the FilesystemMiddleware constructor [1][2]. The allowlist governs the eight built-in tool names: ls, read_file, write_file, edit_file, delete, glob, grep, and execute [1][2]. Note that read_file is mandatory and must be included in any provided allowlist; omitting it will raise a ValueError [3][2]. Any tool name not in this list, or any custom tool added via the agent's primary tools argument, remains unaffected [1][3]. If you use a backend that does not support the execute tool, including execute in the allowlist is a no-op [2]. Filesystem Permissions and assertWithin Filesystem permissions provide path-based access control (e.g., allow/deny operations on specific paths) for the built-in filesystem tools [4][3]. These are defined using a list of FilesystemPermission rules passed to the agent during creation [4][3]. While there is no direct public method named assertWithin in the filesystem API, the system enforces path restrictions primarily through virtual mode [5][6] and FilesystemPermission middleware [4][7]. Key Security Considerations: 1. Permissions vs. Execution: Filesystem permissions do not apply to sandbox backends that support arbitrary shell command execution via the execute tool [4][3]. Attempting to use path-based permissions with a backend that supports execution will raise a NotImplementedError, unless all paths are scoped under known route prefixes [7]. 2. Virtual Mode: Using virtual_mode=True in your FilesystemBackend is recommended to anchor operations to a specific root directory and prevent path traversal attacks (e.g.,../, ~) [5][6]. 3. Middleware Override: If you replace the default FilesystemMiddleware, you must manually pass the backend and permissions to your custom instance, as they will not be automatically inherited from the parent create_deep_agent configuration [8][9]. Citations:
Define and test the embedded-agent boundary before implementation.
🤖 Prompt for AI Agents |
||||||||||
|
|
||||||||||
| **The convention is carried in, never re-authored.** The agent's instructions are the | ||||||||||
| generated `CLAUDE.md` — or the entry file whichever harness the project was scaffolded | ||||||||||
| for reads — and the scaffolded skills, unchanged. One convention, two consumers. A system | ||||||||||
| prompt written by hand beside them would recreate 0003's two-authors problem inside one | ||||||||||
| product, where it would be harder to see: two agents writing the same folder by two | ||||||||||
| conventions, both passing every check. | ||||||||||
|
|
||||||||||
| `scaffoldSkills` already writes `.claude/skills/<name>/SKILL.md` with `name` and | ||||||||||
| `description` in the frontmatter, which is the layout the agent toolkits converged on, so | ||||||||||
| this is a path to point at rather than a format to convert. That is luck rather than | ||||||||||
| foresight — `adr:0015-the-convention-ships-as-skills` chose it to be read by Claude Code — | ||||||||||
| and it is worth naming as luck, because the day the two shapes diverge nothing will fail | ||||||||||
| loudly. | ||||||||||
|
|
||||||||||
| **Neither the skills nor `CLAUDE.md` name a search tool, and both assume one.** They | ||||||||||
| instruct the agent to use the project's own term, one page per concept, aliases for the | ||||||||||
| names to avoid. Obeying that requires finding out which terms are already in use. The | ||||||||||
| methodology assumed a harness that could look before it wrote, without ever saying so — | ||||||||||
| which is why this record has to say so. | ||||||||||
|
|
||||||||||
| **This narrows `adr:0013` rather than superseding it.** One of its three surviving | ||||||||||
| clauses falls — the application may now call an LLM. The other two stand, and the second | ||||||||||
| stands harder than before: write-time validation was the thing that replaced the writer, | ||||||||||
| and it is now the only thing standing between a cheap model and the wiki. | ||||||||||
|
|
||||||||||
| **The embedded agent is the lesser door and the product says so.** It exists for the | ||||||||||
| user who has no harness. It is not positioned as equivalent to Claude Code or Codex, and | ||||||||||
| where the two disagree the external agent is the one the product was designed around. | ||||||||||
|
|
||||||||||
| Rejected: **a second writer with direct disk access**, which would delete the guarantee | ||||||||||
| the product sells for an ergonomic saving of nothing. Rejected: **giving the agent only | ||||||||||
| the derived index**, which is safe, cheap, and produces an agent that cannot tell whether | ||||||||||
| a concept already has a name. | ||||||||||
|
|
||||||||||
| ## Consequences | ||||||||||
|
|
||||||||||
| **A well-formed and wrong page passes.** 0003 wrote this about the external agent and it | ||||||||||
| is sharper here, because the models this door is for are the cheap ones. The gate holds | ||||||||||
| form and cannot hold meaning: a page with three concepts in it, or the non-canonical | ||||||||||
| term, or a superseded decision quietly overwritten, passes every check the product has. | ||||||||||
| A wiki can now be filled with plausible material that validates, and the trust that | ||||||||||
| material destroys is the only thing the product sells. This is the cost of the record and | ||||||||||
| it is not mitigated by anything in it. | ||||||||||
|
|
||||||||||
| The mitigation is elsewhere and belongs in the plan, not here: distillation proposes and | ||||||||||
| the user approves, conformance work writes directly, and every write carries its origin | ||||||||||
| so a bad run is one undo rather than an archaeology. | ||||||||||
|
|
||||||||||
| **The line has to be proved, not configured.** The read/write split is enforceable with | ||||||||||
| what exists — the toolkit checked while writing this restricts its filesystem tools to an | ||||||||||
| allowlist, and a tool the application supplies is untouched by that restriction, so the | ||||||||||
| gate stays the only way in. But two of the guards fail open: a permission model that | ||||||||||
| allows when no rule matches, and path confinement that is opt-in per backend. A | ||||||||||
| configuration that looks right and a configuration that refuses are different claims, and | ||||||||||
| only the second one is testable. Every constraint this record makes needs a test that | ||||||||||
| attempts the write and watches it fail, in the same spirit as the gate's own tests. | ||||||||||
|
|
||||||||||
| **A second credential purpose.** `adr:0007-plaintext-credentials-in-the-config` was | ||||||||||
| walked back to one secret and `adr:0013` made a point of it. The Groq credential now has | ||||||||||
| two uses, transcription and the agent, which means revoking it breaks two things and the | ||||||||||
| settings screen has to say so. A project on whisper.cpp has no credential and therefore | ||||||||||
| no embedded agent — which the settings screen also has to say, before the user finds out | ||||||||||
| by opening a chat that cannot answer. | ||||||||||
|
|
||||||||||
| **Model choice becomes a product decision.** The provider's model list is not a menu the | ||||||||||
| user has the information to choose from: most entries are bad at tool calling and none of | ||||||||||
| them says so. Offering the raw list is handing over a decision and then inheriting the | ||||||||||
| blame for the wiki it produces. | ||||||||||
|
|
||||||||||
| **Two writers of the wiki now exist, and they are not symmetric.** The external agent has | ||||||||||
| the better model and the user's trust; the embedded one has the project's index and the | ||||||||||
| validated write. They must not drift into two conventions, which is why the instructions | ||||||||||
| are generated rather than written — but nothing enforces it beyond that, and | ||||||||||
| `SKILLS_VERSION` reporting a stale scaffold is the only signal there is. | ||||||||||
|
|
||||||||||
| **Subagents are dangerous here for a reason already written down.** | ||||||||||
| `.claude/rules/delivery.md` refuses parallel dispatch because file-disjointness is not | ||||||||||
| independence: two tasks that touch no common file both need a type that does not exist | ||||||||||
| yet, each invents one, and the merge is clean. Two subagents distilling two parts of one | ||||||||||
| recording invent two pages for one concept, or two names for it, and every check passes. | ||||||||||
| Parallelism across *sources* is the safe split; across chunks of one source it needs a | ||||||||||
| consolidation step that is not optional. | ||||||||||
|
Comment on lines
+178
to
+179
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win Qualify the “safe split” for parallel work. Different sources do not guarantee disjoint concepts. Two source-specific agents can still create the same page or canonical term, as described in Lines 159-160. Limit parallelism to disjoint concept scopes and require consolidation before writes. Proposed wording-Parallelism across *sources* is the safe split; across chunks of one source it needs a
-consolidation step that is not optional.
+Parallelism across sources is safer only when the sources have disjoint concept scopes;
+every parallel batch still requires consolidation before it writes.📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
|
|
||||||||||
| **The empty state stops being true.** *There is no model behind this window* ships today | ||||||||||
| and has to change with the first release that carries this. | ||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
Document and enforce the LLM data-egress policy.
The embedded agent can read every path inside the project. The Groq credential also serves agent requests. When file content enters a prompt, that content leaves the project and reaches Groq.
Define consent, sensitive-file handling, redaction, retention, and provider failure behavior.
assertWithinlimits path traversal, but it does not limit disclosure to the LLM provider.Also applies to: 138-143
🤖 Prompt for AI Agents