Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Heartwood reuses OpenHands for the agent loop and coding tools, then adds projec
## What Heartwood Provides

- A conversation-first coding workflow for the current project directory.
- Full-screen and plain terminal interfaces, a browser interface, and a notebook bridge.
- Full-screen and plain terminal interfaces, a browser interface, and a notebook bridge with shared read-only file and change inspection.
- Research-environment, ChatGPT sign-in, hosted API, compatible-service, and Heartwood-managed model connections through one setup flow.
- Recommended Heartwood-managed models plus best-effort support for arbitrary public Hugging Face repositories and reviewed offline imports.
- Clear review of complete OpenHands action sets before execution.
Expand Down
8 changes: 7 additions & 1 deletion documentation/architecture/sessions-audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ Heartwood displays every member as one action set and applies one decision to th
The gateway commits that complete-set decision before OpenHands can continue into model or tool execution.
The pending set is reconstructed from unmatched OpenHands actions after restart rather than from a separate Heartwood cache.

Each OpenHands proposal becomes one `heartwood.action-record.v1` projection correlated by stable action and tool-call identifiers.
The same record accumulates its group, decision, execution state, bounded result, and typed affected-path evidence across replay.
Terminal, file-editor, Task, and other actions use typed variants, while the exact OpenHands arguments remain available for review.
Unknown outcomes fail closed and are never converted into a successful result by an interface.

## Audit Integrity

Audit records are chained so replay and export can detect modification, reordering, or missing records within the available chain.
Expand All @@ -85,7 +90,8 @@ The recovery journal repairs a verified interrupted two-file append before repla
The chain alone cannot prove that an intact suffix was not deleted; deployments that require truncation detection must checkpoint the terminal hash or event count in independently retained storage.
The export path is itself recorded as an event.

The log minimizes content but cannot make every prompt, path, tool summary, or outcome non-sensitive.
Exact action arguments, commands, affected paths, file content, patches, tool output, and failure text stay out of the content-minimized audit payload.
The log still cannot make every operational identifier, decision, classification, count, or timestamp non-sensitive.
Deployments must define retention, access, export, and deletion policy.

## Long Conversations
Expand Down
14 changes: 13 additions & 1 deletion documentation/architecture/system.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,26 @@ Incremental token text is transient and is never appended to the session or audi
### Interface Projections

The gateway reduces durable events and current transient text into one session projection.
That projection contains the conversation, lifecycle, complete pending action set, task plan, total and per-purpose model usage, specialist lineage, activity, and available commands.
That projection contains the conversation, versioned correlated action records, lifecycle, complete pending action set, task plan, total and per-purpose model usage, specialist lineage, activity, and available commands.
The gateway enforces those available commands before dispatch, so terminal, browser, and notebook clients share the same lifecycle rules.
REST and streaming transports return events and that projection from one serialized snapshot; a transient revision orders token-only updates between durable events.
The terminal, browser, and notebook bridge render the projection without maintaining their own event reducers.

The gateway also owns researcher-facing setup choices, model-connection categories, readiness diagnostics, and action settings.
Interfaces may present these differently, but they do not infer separate labels, capabilities, or persistence behavior.

### Workspace Inspection

The gateway owns one bounded read-only workspace service for project trees, UTF-8 text files, changed paths, and per-file diffs.
It accepts normalized project-relative paths, excludes `.heartwood/` and `.git/` at every depth, does not follow symbolic links, and rejects special files.
Every operation applies fixed count, depth, line, and byte bounds.
Tree and changed-path responses publish the active limits, and all responses report unavailable, binary, truncated, non-Git, or unsupported state when applicable.

For Git projects, the service delegates changed-file and diff inspection to the pinned OpenHands `LocalWorkspace` API.
For non-Git projects, it projects only successful paths attributed to typed OpenHands file-editor actions in the selected session.
Terminal command text is never parsed into file evidence.
The terminal, REST API, browser, and notebook bridge adapt this service without maintaining separate workspace roots or change stores.

### Gateway Ingress

`IngressPolicy` is the transport boundary for HTTP and WebSocket requests.
Expand Down
5 changes: 3 additions & 2 deletions documentation/architecture/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ No single layer establishes every property of a deployment.
|---|---|
| Unit and schema tests | Validation, state boundaries, policy, diagnostics, model planning, and serialization |
| OpenHands conformance tests | Public typed events, explicit settings, background control, grouped approval, restart recovery, real Task Tracker execution, usage, and sequential specialists with deterministic `TestLLM` |
| Gateway contract tests | Shared command/event behavior, projection replay, coherent REST, WebSocket, and server-sent-events snapshots, transient ordering, credentials, sessions, and imports |
| Interface tests | Terminal, browser, and notebook rendering of the gateway-owned projection |
| Gateway contract tests | Shared command/event behavior, action correlation, projection replay, bounded workspace inspection, coherent REST, WebSocket, and server-sent-events snapshots, transient ordering, credentials, sessions, and imports |
| Interface tests | Terminal, browser, and notebook rendering of the gateway-owned projection, files, and changes |
| Container smoke tests | Entrypoint, filesystem, architecture, no-secret image layers, and deterministic OpenHands integration |
| No-network smoke tests | Gateway, OpenHands, grouped action, tool, replay, and audit operation without outbound network |
| Capable-model evaluation | Real Heartwood-managed inference, OpenHands-compatible tool proposal, bounded execution, and exact synthetic output |
Expand All @@ -35,6 +35,7 @@ The CPU capable-model job and GPU qualification wrapper use this same acceptance

OpenHands SDK conformance tests use the real conversation persistence layer and deterministic `TestLLM`.
They verify that pending actions and completed tool turns survive restart without repeated model or tool work, grouped approval executes each action once, grouped rejection executes none, active work can be steered and paused, a stale running state fails closed as an unknown outcome, persisted progress appears before completion, Task Tracker updates are translated, and one tool-free research-planning specialist returns to its parent conversation.
Workspace contract tests qualify the pinned OpenHands Git change and diff APIs, non-Git typed-action fallback, canonical path handling, nested private-state exclusion, traversal and symlink rejection, special and binary files, UTF-8 boundaries, limits, audit scrubbing, and cross-interface transport.
The browser reference analysis stops its gateway, replays and mutates the same session through the CLI, restarts the gateway, and verifies that the browser receives the CLI update on one contiguous authoritative sequence.

Native packaging CI uses deterministic dependency-tool substitutes to verify failure paths and reproducibility, then installs the release archive in an empty Ubuntu 24.04 AMD64 container and runs the real CPU inference and browser paths.
Expand Down
Binary file modified documentation/assets/screenshots/browser-action-review.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified documentation/assets/screenshots/browser-action-settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: 2026 Stanford University and the project authors (see CONTRIBUTORS.md)

SPDX-License-Identifier: MIT
Binary file modified documentation/assets/screenshots/browser-conversation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions documentation/assets/screenshots/browser-files.png.license
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: 2026 Stanford University and the project authors (see CONTRIBUTORS.md)

SPDX-License-Identifier: MIT
12 changes: 12 additions & 0 deletions documentation/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,18 @@ The selected non-secret model profile remains in the project until another conne
The aliases `approve` and `deny` remain command-line synonyms for automation.
Interactive users should use the visible controls or `/allow` and `/reject` without internal identifiers.

## Project Inspection

| Command | Purpose |
|---|---|
| `heartwood files list [DIRECTORY] [--depth N]` | List a bounded project tree |
| `heartwood files show FILE` | Print one bounded UTF-8 text file |
| `heartwood changes` | List Git changes or successful typed file actions for the selected non-Git session |
| `heartwood changes FILE` | Print one bounded read-only diff or non-Git current-file view |

These commands use the same gateway service as the full-screen terminal, browser, and notebook bridge.
They exclude private project state and return a nonzero status for unavailable, binary, or unsupported content.

## Operator Commands

| Command | Purpose |
Expand Down
32 changes: 32 additions & 0 deletions documentation/reference/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Codes use `HW-{AREA}-{NNN}`.
| `CREDENTIAL` | Provider API key, subscription credential, or managed-identity availability |
| `INGRESS` | Gateway binding, proxy trust, origins, forwarding metadata, and paths |
| `AGENT` | OpenHands agent runtime availability |
| `WORKSPACE` | Read-only project file and change inspection |
| `COMPUTE` | Scheduler allocation, GPU, memory, and scratch storage |
| `TERRA` | Terra-specific project and compute requirements |
| `ENV` | Conditions that cannot yet be classified more precisely |
Expand Down Expand Up @@ -158,6 +159,37 @@ Inspect the session replay and Activity & audit, then continue in a new session.
An execution backend returned an error without a more specific stable code.
Review Activity & audit, run `heartwood doctor`, and try the task again.

## Project Inspection

### `HW-WORKSPACE-001` — Project Path Is Invalid

Use a normalized path relative to the current project.
Do not use an absolute path, `..`, backslashes, repeated separators, control characters, or a trailing separator.

### `HW-WORKSPACE-002` — Private Project State Is Not Available

The Files and Changes interfaces never expose `.heartwood/` or `.git/`, including nested directories with either name.
Use the documented audit export or Git commands from a trusted terminal when you are authorized to inspect that state.

### `HW-WORKSPACE-003` — Symbolic Link Inspection Is Not Available

Heartwood does not follow symbolic links through its read-only project API.
Inspect the intended regular file through its project-relative path.

### `HW-WORKSPACE-004` — Expected a Directory

Use `heartwood files show FILE` for a file or choose a directory for `heartwood files list`.

### `HW-WORKSPACE-005` — Project Entry Is Unavailable

The path does not exist or its metadata cannot be read.
Confirm the spelling and project permissions, then retry from the same project directory.

### `HW-WORKSPACE-006` — Requested Tree Depth Is Unsupported

Choose a positive depth no greater than the limit reported by the workspace response.
Omit `--depth` to use the default bounded depth.

## Managed Compute

### `HW-COMPUTE-001` — A Compute Allocation May Be Required
Expand Down
6 changes: 6 additions & 0 deletions documentation/use/actions-audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ Session events include user requests, model-route decisions, final assistant res
The gateway turns that stream into one projection for terminal, browser, and notebook clients.
Incremental response tokens are visible while the model works but are not persisted.

Each proposed tool has one versioned action record.
It correlates the OpenHands action and tool-call identifiers, grouped decision, typed terminal, file-editor, Task, or other arguments, execution state, bounded outcome, and explicitly supported affected paths.
States distinguish proposed, awaiting review, approved, rejected, running, succeeded, failed, and outcome unknown.
Heartwood does not infer authoritative file changes from shell command text.

Use `/replay` in the terminal or the browser activity view to inspect it.
Replay verifies the audit chain and the one-to-one hash binding between each audit record and the complete session event before returning persisted history.

Expand All @@ -57,6 +62,7 @@ Replay verifies the audit chain and the one-to-one hash binding between each aud
Use `/audit-export` or the browser export control to create a JSON Lines file for review.
The export is scrubbed and content-minimized.
It records task counts and statuses instead of task titles or notes, usage totals instead of completion content, and stable error codes instead of provider details.
Exact action arguments, commands, affected paths, file content, diffs, tool output, and failure text remain in private session state and are not copied into the audit export.
Operational identifiers, decisions, classifications, counts, and timestamps may still be sensitive in context.

An audit record supports review and reproducibility; it is not proof that a scientific result is correct or that a deployment meets a regulatory requirement.
24 changes: 23 additions & 1 deletion documentation/use/browser.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ SPDX-License-Identifier: MIT

# Use the Browser

The browser interface presents conversations, action review, model setup, Skills, activity, and audit export without introducing a separate backend or project state.
The browser interface presents conversations, action review, read-only project files and changes, model setup, Skills, activity, and audit export without introducing a separate backend or project state.
It is available on workstations and in the generic container.
Terra and Stanford Carina do not expose a supported Heartwood browser route; use their terminal or notebook interfaces instead.

Expand Down Expand Up @@ -48,6 +48,8 @@ The first browser conversation is the same **Main session** used by the terminal
- Use **New analysis** to create another persistent session.
- Enter requests in the composer after model readiness is confirmed.
- Send additional guidance or pause while OpenHands is working.
- Use **Files** to inspect the bounded project tree with read-only syntax highlighting.
- Use **Changes** to inspect Git changes or session-attributed non-Git changes with read-only per-file diffs.
- Inspect task progress, model-call totals, and sequential specialist status below the conversation.
- Open **Activity & audit** to inspect route decisions, tool results, and errors.
- Open **Skills** to inspect repository-verified and installed Skills.
Expand All @@ -61,6 +63,26 @@ The first browser conversation is the same **Main session** used by the terminal

The review panel lists all proposed members together with tool names, risk labels, summaries, and relevant arguments.
One decision resolves the complete OpenHands action set: allowing runs every listed action once, while rejecting runs none of them.
Completed action records show the correlated state, exit status, bounded result, and affected paths when OpenHands supplied reliable typed evidence.

## Inspect the Project

The **Files** and **Changes** views are read-only.
They never provide a second editing path around action review.
Tree, file, changed-path, and diff responses have fixed depth, count, line, and byte limits; the interface labels truncated or unavailable content instead of silently omitting the condition.

![Heartwood Files view showing the bounded project tree and a syntax-highlighted result](../assets/screenshots/browser-files.png)

Select a file to inspect its contents without leaving the session.

![Heartwood Changes view showing a Git-backed per-file diff](../assets/screenshots/browser-changes.png)

Select a changed path to compare its current contents with the Git baseline.
When the project does not use Git, Heartwood instead shows changes that OpenHands reported through typed file-editor actions in the selected session.

Heartwood excludes `.heartwood/` and `.git/` at every depth and refuses path traversal, symbolic links, special files, and non-UTF-8 text.
In a non-Git project, **Changes** includes only successful typed file-editor actions from the selected session.
Terminal command text is not treated as authoritative file evidence.

## Keep the Interface Reachable

Expand Down
19 changes: 18 additions & 1 deletion documentation/use/notebooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Inspect every member before resolving the group:
```python
pending = view.pending_approval
assert pending is not None
[(action.tool_name, action.summary, action.arguments) for action in pending.actions]
[(action.tool_name, action.state, action.details, action.arguments) for action in pending.actions]
```

Allow or reject the complete set with its group identifier:
Expand All @@ -90,10 +90,27 @@ view = session.approve(group_id=pending.group_id)

The decision applies to every action displayed in that OpenHands action set.

All correlated action records remain available through `view.actions`.
Each record includes its OpenHands identifiers, grouped decision, typed details, state, bounded outcome, and explicit affected-path evidence.

Task progress is available through `view.task_plan`.
Combined model usage is available through `view.usage`, and agent and condenser usage are separated in `view.usage_by_purpose`.
Sequential specialist work and parent lineage are available through `view.subagents`.

## Inspect Files and Changes

The notebook bridge exposes the same bounded read-only service as the terminal and browser without building a separate notebook file browser:

```python
tree = session.files()
source = session.file("analysis/cohort.py")
changes = session.changes()
diff = session.diff("analysis/cohort.py")
```

The returned typed mappings label binary, truncated, unavailable, non-Git, and unsupported states.
They exclude `.heartwood/` and `.git/`, reject unsafe paths, and apply the same count, depth, line, and byte limits as the other interfaces.

## Export the Audit Record

```python
Expand Down
Loading
Loading