opensymphony 1.4.0

A Rust implementation of the OpenAI Symphony orchestration design
Documentation
# Project Memory

OpenSymphony project memory preserves completed-issue knowledge before Linear
issues are archived. The normal workflow captures evidence from Linear and
GitHub, writes private issue capsules under `.opensymphony/memory/`, indexes
them in DuckDB, and can sync selected knowledge into public topic docs.

Project memory has two separate surfaces:

- **CLI commands** such as `opensymphony memory capture` and
  `opensymphony linear archive` create, query, sync, and guard memory.
- **Agent skills** under `.agents/skills/` tell implementation agents when to
  consult memory. Those skills are target-repo template assets, not files
  embedded or injected by the OpenSymphony binary.

## Normal live capture

Live capture requires Linear access from `WORKFLOW.md` and uses GitHub PR
discovery by default through `gh`:

```bash
opensymphony memory capture COE-123 --dry-run
opensymphony memory capture COE-123
opensymphony memory capture --issues COE-123,COE-124
opensymphony memory capture --issue-range COE-120..COE-130 --dry-run
```

For each selected issue, OpenSymphony:

1. reads the Linear issue, state, labels, URL, description, and active workpad
   comment;
2. discovers matching GitHub PRs with `gh pr list --search ISSUE-KEY`;
3. enriches matched PRs with changed files, commits, reviews, checks, and merge
   SHA using `gh pr view`;
4. renders a capture plan or writes the issue capsule and index entry.

Linear is always attempted for live capture. A missing `WORKFLOW.md`, invalid
Linear configuration, missing issue, or Linear API failure is a command failure.
GitHub is also part of the default live flow. A missing or failing `gh` command
is a command failure unless `--no-github` is supplied:

```bash
opensymphony memory capture COE-123 --no-github --dry-run
```

`--no-github` is intended for unusual non-PR work. If GitHub is available but no
matching PR is found, capture records a warning. Warnings keep the issue visible
for review and block archival unless `--force` is used.

## Import and backfill

`memory import` is for deterministic backfills, migrations, tests, or external
exports. Failed Linear or GitHub access should be fixed before live capture is
retried.

```bash
opensymphony memory import --source-file completed.yaml --dry-run
opensymphony memory import --source-file completed.yaml
opensymphony memory import COE-123 --source-file completed.yaml
opensymphony memory import --issue-range COE-120..COE-130 --source-file completed.yaml --dry-run
```

The source file is produced by a user or external export tool. OpenSymphony does
not currently generate this file during the normal live capture flow.

Import selection flags filter records already present in the YAML:

- issue selectors: positional issue, `--issues`, `--issues-file`,
  `--issue-range`
- source filters: `--milestone`, `--state`, `--before-date`, `--before-issue`

If selected records are not present, import fails instead of inventing
placeholder issue evidence.

### Source YAML schema

Top-level fields:

```yaml
issues: []
prs: []
overrides: {}
```

Issue fields:

```yaml
issues:
  - id: issue-id
    identifier: COE-123
    title: Issue title
    url: https://linear.app/example/issue/COE-123
    description: Optional issue description
    state: Done
    milestone: M3
    labels:
      - runtime
    comments:
      - author: username
        body: "Decision or summary text"
        updated_at: 2026-03-25T22:05:00Z
        source: linear:workpad
    linked_prs:
      - 456
    task_files:
      - docs/tasks/COE-123.md
    updated_at: 2026-03-25T22:05:00Z
    completed_at: 2026-03-26T10:00:00Z
```

PR fields:

```yaml
prs:
  - number: 456
    title: COE-123 implement reconnect recovery
    url: https://github.com/example/repo/pull/456
    branch: coe-123-reconnect
    body: Pull request summary
    merge_sha: abcdef1234567890
    merged_at: 2026-03-26T10:30:00Z
    commits:
      - sha: abcdef1234567890
        author: username
        timestamp: 2026-03-26T10:00:00Z
        summary: Implement reconnect recovery
    changed_files:
      - path: crates/opensymphony-openhands/src/client.rs
        change_kind: modified
    checks:
      - name: cargo test
        conclusion: success
        completed_at: 2026-03-26T10:20:00Z
    reviews:
      - reviewer: reviewer
        state: APPROVED
        submitted_at: 2026-03-26T10:25:00Z
        disposition: Looks correct.
```

Overrides are keyed by issue identifier:

```yaml
overrides:
  COE-123:
    prs:
      - 456
    areas:
      - openhands-runtime
```

All fields except `issues[].identifier` and `prs[].number` are optional.
`linked_prs` and `overrides.*.prs` associate issue records with PR records in
the same source file.

## Query and docs sync

Useful read commands:

```bash
opensymphony memory status
opensymphony memory brief COE-123
opensymphony memory related --area openhands-runtime
opensymphony memory related --paths crates/opensymphony-openhands
opensymphony memory search "reconnect recovery"
opensymphony memory docs --area openhands-runtime
```

Docs sync is review-first. It shows the managed-section diff before writing:

```bash
opensymphony memory sync-docs --issues COE-123 --dry-run
opensymphony memory sync-docs --issues COE-123
opensymphony memory lint --public-docs
```

`opensymphony-memory.yaml` configures memory roots, visibility, area detection,
docs targets, and redaction. See [Configuration](configuration.md#project-memory)
for the config shape.

## Archive guard

Archival is guarded by memory capture. For explicit issues,
`opensymphony linear archive` first performs live Linear and GitHub capture, then
archives only eligible issues:

```bash
opensymphony linear archive --issues COE-123 --dry-run
opensymphony linear archive --issues COE-123
opensymphony linear archive --issue-range COE-120..COE-130 --dry-run
```

An issue is eligible when fresh captured memory exists and has no unresolved
capture warnings. `--force` bypasses the guard when an operator has reviewed the
risk:

```bash
opensymphony linear archive --issues COE-123 --force
```

To archive from already captured memory without recapturing, use
`--from-memory`:

```bash
opensymphony linear archive --from-memory --state captured --dry-run
opensymphony linear archive --from-memory --state pending
```

`--state` only applies to `--from-memory`. Explicit issue archive selectors use
the normal live capture path.

## Troubleshooting

- Use `opensymphony memory capture ... --dry-run` before running the writing command.
- Use `opensymphony memory capture --help`,
  `opensymphony memory import --help`, and
  `opensymphony linear archive --help` for the current command surface.
- If Linear fails, fix `WORKFLOW.md`, tracker credentials, or issue selection.
  Live capture does not fall back to placeholder records.
- If GitHub discovery fails, install/authenticate `gh` or intentionally rerun
  with `--no-github`.
- If archive is blocked by warnings, inspect the capture dry-run or capsule,
  refresh capture, or use `--force` only after review.