You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-`capabilities.ts` — `detectCapabilities` maps the live tool surface to abstract capabilities (`ticket-tracker`, `code-host`, `doc-search`) by name pattern; `resolveStep` decides whether a step runs. A capability override set forces integrations off per run. Adding a capability is a data edit, not a logic change.
151
-
-`runtime.ts` — `WorkflowRuntime` drives execution on a call stack: it skips capability-unsatisfied steps, descends into sub-workflow references, emits step lifecycle events, and snapshots `WorkflowState`. `state.ts` persists that snapshot atomically to `.agent-state/workflow.json` for resume.
152
+
-`runtime.ts` — `WorkflowRuntime` drives execution on a call stack: it skips capability-unsatisfied steps, descends into sub-workflow references, emits step lifecycle events, and snapshots `WorkflowState`. `state.ts` persists that snapshot atomically to `workflow.json` under the session state root for resume.
153
+
152
154
-`coordinator.ts` — bridges runtime and director: produces the `[WORKFLOW STEP i/total: label]` directive injected into each turn's system prompt, and advances the runtime when `advance_workflow` (or a `submit_output` tagged `{ step }`) completes. Shared by both directors.
153
155
- The built-in recipes: the atomics `update-ticket`, `improve-docs`, `write-tests`, `triage-bug`, `code-review`, `scope-project`, and the `build-feature` composite that chains them.
154
156
@@ -196,8 +198,8 @@ The agent's identity is **Corbits Code**, framed as a senior coding assistant ru
- Atomic JSON save/load to `.agent-state/run.json`, with schema validation on load
200
-
- Conversation context is persisted separately by the git-backed store under `.agent-state/context`
201
+
- Atomic JSON save/load to `run.json` under the session state root (`~/.corbits/projects/<project-key>/<session-id>/`), with schema validation on load
202
+
- Conversation context is persisted separately by the git-backed store under that session's `context/` directory
201
203
202
204
### Lifecycle Hooks (`src/session/hooks.ts`)
203
205
@@ -249,7 +251,8 @@ tool call
249
251
-**classify** — Read-only tools (`read_file`, `search_files`, `grep`, `list_dir`) are tier `allow`; everything else is tier `ask`. Builds approval requests: shell yields one request for the full command the model asked to run (security still splits under the gate); file tools keyed on the target path; other tools keyed on tool name.
250
252
-**command** — Splits chained commands for security classification and derives command-shape approval scopes. Multi-segment chains only offer an exact-command persist pattern (a prefix like `npm *` must not cover `npm i && rm -rf /` later).
251
253
- **auto-shell-policy** — Constrains `run_shell` even when auto mode would otherwise rubber-stamp it. Before matching, `expandShellSubjects` peels `bash`/`sh`/`zsh -c`, `xargs` utility tails, and transparent prefixes (`env`, `nice`, `timeout`, …) so rules see the real payload; an unparseable wrapper (variable expansion or command substitution) sets an opaque flag that forces `ask`. Effects: `deny` blocks outright (file mutations through ad-hoc tooling — output redirection, `tee`, `sed -i`/`perl -i`, interpreter inline programs or heredocs — which must instead go through `write_file`/`edit_file`); `ask` declines to auto-allow and falls through to the operator prompt (recursive `rm`, dependency installs and remote runners: npm/yarn/pnpm/bun, pip, cargo, go, brew, npx/bunx, …, git worktree add/remove/prune, shell that references a sensitive path such as `.env` or a private key, and opaque wrappers). Deny beats ask when multiple subjects match. Quoted spans are stripped before pattern matching so a quoted `>` or install word in an argument is not flagged, and program names are matched only in command position. Adding a table category is a one-line rule append in `AUTO_SHELL_RULES`.
252
-
- **gate** — Evaluates a call: `skipPermissions` allows everything; `allow`-tier passes; for `ask`-tier, checks persisted approvals, otherwise requests operator approval. Shell security classifies each chain segment (`||` / `&&` / `|` / `;` / newlines), but the operator is prompted once for the full command block — any unapproved segment fails the whole block, and execution always runs the unsplit original. Safe pipeline tails and pure shell no-ops (`true` / `false` / `:` and bare control-flow keywords stranded by chain-splitting) skip without a prompt. In a non-interactive run an unresolved `ask` becomes a denial. In auto mode: non-shell built-ins in `AUTO_ALLOWED_TOOLS` (writes/edits/deletes, `manage_tasks`, `task`, …) auto-allow when not path-restricted; for `run_shell` the gate consults the auto-shell policy — a `deny` rule fails the call, an `ask` rule skips the auto-allow shortcut and proceeds to the normal approval flow, and anything unmatched is auto-allowed. Paths outside the workspace and writes under `.agent-state` still ask. Mutating MCP and unknown built-ins are not blanket-allowed. Newly granted scopes are appended in memory and persisted.
254
+
- **gate** — Evaluates a call: `skipPermissions` allows everything; `allow`-tier passes; for `ask`-tier, checks persisted approvals, otherwise requests operator approval. Shell security classifies each chain segment (`||` / `&&` / `|` / `;` / newlines), but the operator is prompted once for the full command block — any unapproved segment fails the whole block, and execution always runs the unsplit original. Safe pipeline tails and pure shell no-ops (`true` / `false` / `:` and bare control-flow keywords stranded by chain-splitting) skip without a prompt. In a non-interactive run an unresolved `ask` becomes a denial. In auto mode: non-shell built-ins in `AUTO_ALLOWED_TOOLS` (writes/edits/deletes, `manage_tasks`, `task`, …) auto-allow when not path-restricted; for `run_shell` the gate consults the auto-shell policy — a `deny` rule fails the call, an `ask` rule skips the auto-allow shortcut and proceeds to the normal approval flow, and anything unmatched is auto-allowed. Paths outside the workspace and writes under the session state root (`~/.corbits/projects/...` and legacy `.agent-state`) still ask. Mutating MCP and unknown built-ins are not blanket-allowed. Newly granted scopes are appended in memory and persisted.
255
+
253
256
-**matcher** — Approval pattern matching via `@intx/authz``matchPattern` (`*` wildcards). Exact-command grants store a backslash before each metacharacter; those patterns match by equality after unescape (the package has no escape syntax).
254
257
-**authz-grants** — Maps stored approvals into `@intx/authz``GrantRule`s and evaluates them with `evaluateGrants` (allow-only; Corbits cwd/provider-model filters applied first). Exact-escaped grants bypass the package path and use equality.
255
258
-**store** — Loads/persists approvals scoped to the working directory (Corbits JSON layout; not the package GrantStore).
@@ -367,7 +370,8 @@ CLI argv
367
370
↓ gates / errors
368
371
[blocked] → operator resolves → [running]
369
372
↓ fatal inference/reactor error
370
-
[failed] (TUI may surface and allow retry; context persists under .agent-state/)
373
+
[failed] (TUI may surface and allow retry; context persists under the session state root)
374
+
371
375
```
372
376
373
377
There is no post-submit `build`/`typecheck`/`test` critique step in the current tree; validation is operator- and hook-driven (`postTurn`/`postRun`) plus explicit `run_shell` during agent work.
|**ask**| Dependency installs / remote runners, recursive `rm`, git worktree add/remove/prune, sensitive-path references, paths outside the workspace (including through a symlink), opaque unparseable wrappers |
157
157
158
-
Unmatched shell auto-allows. Writes under `.agent-state`, mutating MCP, and unknown built-ins still prompt. Authorization hard-denies (catastrophic commands, open-ended shell search) remain independent of auto mode.
158
+
Unmatched shell auto-allows. Writes under the session state root (`~/.corbits/projects/<project-key>/…`, and legacy in-repo `.agent-state` during dual-read), mutating MCP, and unknown built-ins still prompt. Authorization hard-denies (catastrophic commands, open-ended shell search) remain independent of auto mode.
159
+
159
160
160
161
Plan approval is handled separately by `use-gates` (`pendingPlan`), independent of auto mode.
161
162
@@ -292,7 +293,8 @@ Positional arguments are joined into the optional initial task delivered when th
292
293
293
294
### Agent Source
294
295
295
-
`createAgent` is configured with a single OpenAI-compatible source built from the resolved config, `defaults.maxTokens = 16384`, and a git-backed `contextDir` at `.agent-state/context`.
296
+
`createAgent` is configured with a single OpenAI-compatible source built from the resolved config, `defaults.maxTokens = 16384`, and a git-backed `contextDir` at `~/.corbits/projects/<project-key>/<session-id>/context`.
297
+
296
298
297
299
## Protocols and Formats
298
300
@@ -303,8 +305,13 @@ Positional arguments are joined into the optional initial task delivered when th
- Project key: slug + short hash of the shared git root (from `--git-common-dir`, so main + linked worktrees share one key; workspace realpath when not a git tree)
313
+
314
+
- Migration: if a session exists only under in-repo `.agent-state/<session-id>/`, it is moved into the global tree on open/list
308
315
- Atomic JSON writes with schema validation on load
309
316
310
317
`createOptimizedContextStore` (`src/session/optimized-context-store.ts`) wraps the
Copy file name to clipboardExpand all lines: docs/PRODUCT.md
+4-2Lines changed: 4 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -65,7 +65,8 @@ Continues from the last saved state in the working directory.
65
65
-**Denied** (must use `write_file` / `edit_file`): shell file mutations via output redirection, `tee`, `sed -i` / `perl -i`, interpreter inline programs or heredocs.
66
66
-**Still asks**: dependency installs and remote runners (npm/yarn/pnpm/bun, pip, cargo, go, brew, `npx`/`bunx`, …), recursive `rm`, git worktree add/remove/prune (list is fine), shell that references sensitive paths, and opaque unparseable wrappers (variable expansion or command substitution).
67
67
-**Wrapper peel**: `bash`/`sh`/`zsh -c`, `xargs`, and transparent prefixes (`env`, `nice`, `timeout`, …) are expanded so the same deny/ask rules see the inner payload.
68
-
- Paths outside the workspace and writes under `.agent-state` still ask; mutating MCP and unknown tools still prompt.
68
+
- Paths outside the workspace and writes under the session state root still ask; mutating MCP and unknown tools still prompt.
69
+
69
70
-**Path sandboxing** — Tool path arguments are resolved against the working directory; paths that escape it are blocked.
70
71
-**Write verification** — After every write/edit the file is re-read and compared to confirm the change actually landed.
71
72
@@ -90,7 +91,8 @@ Config-driven `postTurn` and `postRun` hooks (TypeScript or shell) run automatic
90
91
91
92
**What the user sees:** The agent stops producing tool calls. After 3 idle turns the run aborts with `Agent stalled: no tool calls for 3 turns.`
92
93
93
-
**Recovery:** State is saved; inspect `.agent-state/run.json`, adjust the task or prompt, and start a new run.
94
+
**Recovery:** State is saved; inspect `~/.corbits/projects/<project-key>/<session-id>/run.json` (or a legacy in-repo `.agent-state/` tree if not yet migrated), adjust the task or prompt, and start a new run.
0 commit comments