Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
6fb80cb
Delphi 1.3.0: add portable Codex harness and default Argos workspace
bracyw Oct 19, 2026
0bbbe52
Merge main into codex/default-codex
bracyw Oct 19, 2026
fd503fa
Simplify harness authoring and cover project defaults
bracyw Oct 19, 2026
4d663f7
Remove unnecessary Codex launcher
bracyw Oct 19, 2026
95ebe3d
Render native workspace context on main
bracyw Oct 20, 2026
26818f5
Preserve existing Claude skill permissions and behavior
bracyw Oct 21, 2026
f215074
Keep Claude inheritance sources and translate Codex output
bracyw Oct 21, 2026
e15034d
Simplify harness adapters and protect workspace-owned files
bracyw Oct 23, 2026
6379d97
Handle native metadata variants and protect adapter instruction paths
bracyw Oct 23, 2026
89d45d0
Clarify preservation of edited managed files during retirement
bracyw Oct 23, 2026
5c2d5f9
Protect managed ownership through path topology changes and retirement
bracyw Oct 23, 2026
7891f6d
Keep topology regression fixtures separate from parking scratch notes
bracyw Oct 23, 2026
646a452
Generate inherited workspace context only on workspace branches
bracyw Oct 24, 2026
dd202a1
Merge main and release the workspace bootstrap as Delphi 2.1.0
bracyw Oct 27, 2026
3126309
Address Codex workspace review feedback
bracyw Oct 27, 2026
86e5481
Translate skills per harness and keep sync history clean
bracyw Oct 27, 2026
3a39aad
Clarify when workspace context is translated
bracyw Oct 28, 2026
b2c53a5
Merge workspace changes before preparing native inheritance
bracyw Oct 28, 2026
d28f42f
Preserve literal references and scope harness skill translation
bracyw Oct 28, 2026
08ea327
Remove prose heuristics from instruction reference translation
bracyw Oct 28, 2026
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
7 changes: 7 additions & 0 deletions .delphi/exec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
# Run a command with this clone's layout, even in hosts whose fresh shells discard session exports.
set -euo pipefail
# shellcheck source=.delphi/paths.sh
source "$(dirname "$0")/paths.sh"
[ "$#" -gt 0 ] || { echo "usage: bash .delphi/exec.sh <command> [<arg>...]" >&2; exit 2; }
exec "$@"
3 changes: 2 additions & 1 deletion .delphi/manifest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
# MINOR something new that existing clones need nothing for
# MAJOR clones need cleanup (MINOR while 0.x): add .delphi/migrations/<version>-<slug>.sh, which
# setup.sh runs once per workspace in each clone (rules in Delphi's CLAUDE.md)
version: 2.0.0
version: 2.1.0
files: # repo-relative paths; a trailing / means everything under it
- .delphi/manifest.yml
- .delphi/.gitattributes
- .delphi/.gitignore
- .delphi/version.sh
- .delphi/setup.sh
- .delphi/new-worktree.sh
- .delphi/exec.sh
- .delphi/paths.sh
- .delphi/plugins.sh
- .delphi/switch.sh
Expand Down
1 change: 1 addition & 0 deletions .delphi/versions
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@
1.1.0 a3446f7f763c setup.sh clones each repos: entry at repos/<name> (a normal clone on its default branch, was a bare store) and adds no worktree; new-worktree.sh makes worktrees from that clone; older bare stores are left as they are
1.2.0 d139aaf9f4a5 worktrees come from their own bare store, worktrees/<name>/.bare, separate from the plain clone at repos/<name>; setup.sh makes the store and the default-branch worktree again; an older bare store at repos/<name> is left as it is
2.0.0 750acf945979 a bare repos/<name> from before 1.1.0 becomes the worktree store, worktrees/<name>/.bare, with its worktrees, and repos/<name> is cloned normally (migration; skipped with a message if it has no origin or work not on origin)
2.1.0 84b00128fc22 add a harness-independent per-command workspace bootstrap for Codex
37 changes: 28 additions & 9 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ source of truth; `docs/goals.md` lists what any change must keep.
labelled `by: ai` (new-workspace: `--by ai-assisted|human` when the user says so).
- `ci/plugins.sh`: writes `.claude-plugin/marketplace.json` from the plugin sets
(`software/**/plugins/<harness>/<set>/`, named `<scope>[.<set>]`; a folder's scope is its
`plugins/scope`, else its `short-name`, else its name), each workspace's `workspace.yml` `plugins:` defaults (the
`plugins/scope`, else its `short-name`, else its name), each Claude Code workspace's `workspace.yml` `plugins:` defaults (the
`default` set of every folder above), and its `.claude/settings.json` (enabled sets, and the SessionStart hook that sets `$DELPHI_ROOT`; never edit
it by hand). Run it after changing a set or a `workspace.yml`'s `plugins:`.
it by hand). `ci/render.sh` calls it for main-side plugin output; sync keeps branch-selected
plugin sets active while their proposal to main is pending.
- `.delphi/{setup,new-worktree,switch,park,plugins}.sh`: the scripts every workspace runs (setup.sh
runs `plugins.sh`, which makes this clone's local `@delphi` installs what the workspace enables and
uninstalls ones the marketplace dropped, so plugin changes need no migration); `.delphi/paths.sh`
Expand All @@ -31,18 +32,29 @@ source of truth; `docs/goals.md` lists what any change must keep.
version, with its hash from `.delphi/version.sh`), `.delphi/migrations/<version>-<slug>.sh` (clone
cleanup, run by `setup.sh`).
- `templates/workspace/`: `workspace.yml`, `CLAUDE.md` (`{{name}}`, `{{folder}}`), the managed
`.github/workflows/delphi.yml` every workspace carries unchanged. The general `new-worktree`,
`switch-workspace`, `setup-workspace`, and `journal` skills are in `software/workspace-inherit/`.
`.github/workflows/delphi.yml` every workspace carries unchanged. The general skills are in
`software/workspace-inherit/.claude/skills/`; Codex adds its bootstrap from `templates/harnesses/`
to the common instruction base once at creation.
- `software/plugins/claude/default/`: the `delphi` plugin set, a mod whose `/ws-delphi` pane switches
workspaces (`hooks/register.tsx`, tests in `tests/ws.test.ts`, run by `claude plugin test`);
`/ws-delphi --web` serves the same cards in a browser tab (`web/server.py`, `web/index.html`).
- `software/…/workspaces/<leaf>/`: the workspaces. Org structure is plain directories. A project
folder (the one holding `workspaces/`) may add `README.md`, `AUTHORING.md`, and `workspace-defaults/`
(copied once into a new workspace there). Any folder may add `workspace-inherit/` (written onto the
`ws/*` root of every workspace below on each refresh, never proposed; `opt-out:` in a
`workspace.yml` skips a path).
(translated once into a new workspace there). Existing source layouts stay intact; optional
`source.yml` declares a different authoring format. Any org/project folder may add `workspace-inherit/`;
CI prepares inheritance in temporary staging and refresh copies it only to ws branches.
Their `workspace.generated` records ownership; `opt-out:` transfers a native path to the workspace.
Main keeps owned native files and canonical sources, never inherited copies or ledgers.
- `.github/workflows/delphi.yml` (identical to the template's copy), `.github/CODEOWNERS`; issue templates (idea, spike, epic, dev work) and the PR template in `.github/`, filed with the `create-ticket` skill (`.claude/skills/`).
- `tests/e2e.sh`: end-to-end test in a throwaway sandbox (bare origin, stub `gh` logging to `gh.log`).
- `ci/render.sh [--check] [--workspace <folder>] [<main-checkout> [<staging-output>]]`: update plugin
output, or prepare inherited native files and ledgers in optional temporary staging. Main-side
checks reject managed copies, ledgers and ownership collisions; inherited output is never committed there.
`ci/harnesses.sh` reads `ci/harnesses/<name>.sh` through pure `harness_field` queries;
`ci/sources.sh` reads independently selected formats; `ci/inherit.sh` resolves sources.
`ci/managed.sh` shares ownership logic with sync, whose refresh
copies staged output. Every workspace must explicitly declare its harness. Codex uses
`.delphi/exec.sh` to initialize helper commands in independent shells.

## Rules

Expand All @@ -52,11 +64,18 @@ source of truth; `docs/goals.md` lists what any change must keep.
headers): name the file or key that holds them ("the folders in `.delphi/park.list`", "each repo
under `repos:`"), never its entries. A copied list goes stale. Runtime tools: bash, git, and `gh` (only to open or update PRs).
- Every script: `#!/usr/bin/env bash`, `set -euo pipefail`, `shellcheck`-clean.
- Skills name nothing harness-specific (SKILL.md is the shared Agent Skills format): call scripts by
- Keep Claude skill sources under workspace-inherit/.claude/skills with their metadata intact.
Each descriptor owns `translate_skill`; native metadata conversion, identifier mappings and
helper bootstrap affect only generated output. Write skills once in Claude format; translate
identifiers and feature bullets, never exact source sentences or per-skill copies. Validation
rejects unmapped Claude identifiers in other harnesses; qualified code-repository paths stay literal.
Shared-source paths and opt-out keys follow `docs/design.md`'s portable-path rule; existing owned
workspace filenames are unaffected.
Skill scripts stay harness-independent (SKILL.md uses the Agent Skills format): call scripts by
their path in the skill's folder, `bash scripts/<script>.sh <names>…`, and reference files the same
way. Skill scripts (inherited, plugin or workspace) take only names (repo, branch) and read the workspace
from `$DELPHI_ROOT`, sourcing `$DELPHI_ROOT/.delphi/paths.sh` for every folder; each harness's
generated settings set it (Claude Code: a SessionStart hook in `.claude/settings.json`, from
bootstrap sets it (Claude Code: a SessionStart hook in `.claude/settings.json`, from
`ci/plugins.sh`). Never search for the root or default to the cwd's branch.
- `.delphi/*.sh` run on people's machines: bash 3.2 (macOS) and Git Bash safe. No bash-4
features (associative arrays, `mapfile`, `${x,,}`, `|&`), POSIX awk only.
Expand Down
56 changes: 46 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ named by the **short name** of each folder above it, from `software/` down, then
name, joined by dots: `software/application-software/argos/workspaces/argos-dev` is
`s.app.argos.argos-dev` (a folder's short name is its `short-name` file, else its name;
`.delphi/names.sh` prints them all). For each one, CI keeps a branch **`ws/<name>`**
whose repo root *is* that folder, so people and agents work on it with plain git. Design: `docs/design.md`. Goals: `docs/goals.md`.
whose repo root *is* that folder. Each workspace explicitly declares its harness and keeps its owned
files at native paths on `main`. Shared skills stay in their canonical sources on main; CI adds
inherited native copies only to `ws/*`. People and agents work with plain git. Design:
`docs/design.md`. Goals: `docs/goals.md`.

## How it works

Expand Down Expand Up @@ -83,11 +86,30 @@ references are there too (a workspace inside another's `workspaces/` skips its o
edited from the workspace that links them; to change one, work in its own clone or switch to it.

The workspace's dotted name is repeated in `name:` so a checkout knows which workspace it is; names
are unique (give a folder a `short-name` that no sibling's name or short name clashes with). Every other file in the folder is the workspace's own, at its normal harness
path, except `.github/workflows/delphi.yml` (a copy of the template's). The scripts, `.delphi/*.sh`
are unique (give a folder a `short-name` that no sibling's name or short name clashes with). Files
live at normal harness paths. On `ws/*`, `workspace.generated` records managed copies; it never
returns to main. Instructions, docs and opted-out copies remain workspace-owned. The workflow comes from
the template. The scripts, `.delphi/*.sh`
(listed in `.delphi/manifest.yml`), live once at main's root: sync puts
`.delphi/` on every `ws/*` branch, so change them only through PRs to main.

## Codex

Argos's `default-codex` workspace targets the Codex harness across hosts:

```sh
git clone -b ws/s.app.argos.default-codex https://github.com/Northeastern-Electric-Racing/Delphi.git delphi
cd delphi
bash .delphi/setup.sh
```

Open the workspace in Codex and follow `AGENTS.md`. It discovers native skills under `.agents/skills/`.
Use `.delphi/exec.sh` for helper commands so each shell receives the workspace layout. Start a fresh
session after switching workspaces. The host supplies dependencies, credentials and integrations;
Codex workspaces do not enable Delphi's Claude plugin sets.
Generated Codex skills include the complete helper invocation in each script command, so fresh
shells and sub-agents initialize the same layout.

## Versions

`.delphi/manifest.yml` lists Delphi's own files under a `version:` (MAJOR.MINOR.PATCH), and
Expand All @@ -98,7 +120,7 @@ a version needs cleanup in people's clones, it ships `.delphi/migrations/<versio

## New workspace

`tools/new-workspace.sh <org-path under software/> <leaf>` copies `templates/workspace/` into
`tools/new-workspace.sh [--harness <adapter>] <org-path under software/> <leaf>` copies `templates/workspace/` into
`software/<org-path>/workspaces/<leaf>/`, adds the project's `workspace-defaults/` if it has one, and
opens a PR to `main`, labelled `by: ai` (put `--by ai-assisted` or `--by human` first to change it).
Once it merges, CI creates `ws/<name>` (its dotted name).
Expand All @@ -107,12 +129,26 @@ Once it merges, CI creates `ws/<name>` (its dotted name).
can hold shared context (`README.md`), a guide to its workspaces (`AUTHORING.md`), and
`workspace-defaults/` (what a new workspace there starts with).

**Inherited files.** Any folder under `software/`, `software/` itself included, can hold
`workspace-inherit/`: files (usually skills, never `CLAUDE.md`) that CI writes onto the `ws/*` branch
of every workspace below it on each sync. Edit them on `main`; a workspace's own edit is undone. To
keep its own copy, a workspace lists the path under `opt-out:` in its `workspace.yml`.
A workspace that lists `main` under `workspaces:` reads them at `workspaces/main/` (recommended for every
new workspace); to change them, switch to `main`.
**Shared sources.** Keep Claude skills and their metadata in
`workspace-inherit/.claude/skills/<name>/`. The optional `source.yml` selects an authoring format
from the harness registry; each workspace's `harness:` independently selects its target.
`workspace-defaults/` seeds owned files once; `workspace-inherit/` stays managed.
Each harness descriptor owns its translation function. Skills are authored once in Claude format;
CI rejects Claude identifiers that a non-Claude translator leaves unmapped.
Register a target or source format in `ci/harnesses/<name>.sh`; its entry owns the native contract.

**Preparation and sync.** CI translates inheritance from main into temporary staging, then refresh
copies it onto workspace branches. Main contains no inherited copies or ownership ledgers.
After source or configuration changes, run `bash ci/render.sh` to update plugin settings and
`bash ci/check.sh` to validate the repo. Commit sources and owned files; CI prepares inheritance.

**Ownership.** Edit shared sources instead of their managed branch copies. To keep an editable
workspace copy, list its native path under `opt-out:`. Proposals retain owned files and opted-out
skills while stripping managed copies, `workspace.generated` and the branch's `.delphi/`.
Collisions are reported. See `docs/design.md` for the adapter contract and ownership rules.
Source-native opt-outs also exclude unsupported inputs before mapping. Shared paths and opt-out
keys use portable ASCII names without spaces or control characters; this naming rule does not
restrict workspace-owned files.

## CI (`.github/workflows/delphi.yml`)

Expand Down
Loading
Loading