Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9cfd084
docs(harness): plan harness-adapter-table change
replygirl Sep 25, 2026
e64e30b
docs(harness): pin HARNESS_NAMES, T3 order, tool-matrix handoff
replygirl Sep 25, 2026
70b32f9
test(harness): add render + wiring characterization goldens
replygirl Sep 25, 2026
e1d357f
refactor(harness): declare tool layout in a typed HARNESS_TABLE
replygirl Sep 25, 2026
3131c03
refactor(harness): render from HARNESS_TABLE and drop the yaml block
replygirl Sep 25, 2026
3872617
refactor(harness): add toml serializer and per-row command extension
replygirl Sep 25, 2026
ca7ea6e
chore(harness): record init --harness all sha256 baseline (task 1.3)
replygirl Sep 25, 2026
d337f0b
refactor(harness): record the T4 no-behavior-change checkpoint (4.1)
replygirl Sep 25, 2026
ea9f97b
docs(harness): describe HARNESS_TABLE as the one layout declaration
replygirl Sep 25, 2026
431144c
test(harness): pin the flat `/` prefix row to the OpenCode golden
replygirl Sep 26, 2026
af2b700
refactor(harness): record the three gating changes as archived (5.1)
replygirl Sep 29, 2026
2f5a9de
test(harness): re-take the wiring baseline on the rebased tree (5.2)
replygirl Sep 29, 2026
ba4c045
refactor(harness): read init's harness wiring from HARNESS_TABLE (5.3)
replygirl Sep 29, 2026
357fc7f
refactor(harness): derive update's roots and marker from HARNESS_TABL…
replygirl Sep 29, 2026
11122ee
refactor(harness): derive doctor's roots from HARNESS_TABLE (5.5)
replygirl Sep 29, 2026
0a56cce
docs(harness): point agent docs at HARNESS_TABLE as the layout source
replygirl Sep 29, 2026
4431d39
refactor(harness): record the group 5 no-behavior-change check (5.6)
replygirl Sep 29, 2026
24a78d5
refactor(harness): note section 2 rows re-observed after T3 (5.6)
replygirl Sep 29, 2026
6b6d74b
fix(harness): sweep orphan commands by each row's extension
replygirl Oct 4, 2026
977f129
fix(harness): attribute doctor refs by every root and prefix
replygirl Oct 4, 2026
6ab6f89
docs(harness): name what a new tool needs beyond its table row
replygirl Oct 4, 2026
8c9c9c5
refactor(harness): record the post-review-fix check run (5.3)
replygirl Oct 4, 2026
bc51c1c
refactor(harness): scan doctor's harness files by each row's extension
replygirl Oct 4, 2026
f2e9fab
refactor(harness): derive the receipt's shared-root line from rows
replygirl Oct 4, 2026
680fc7d
refactor(harness): read init's opsx scan and skill file from the table
replygirl Oct 4, 2026
ab25c95
docs(harness): record what stays outside the harness table on purpose
replygirl Oct 4, 2026
9c2b702
refactor(harness): record the round-2 check run (5.3)
replygirl Oct 4, 2026
d99b412
fix(harness): attribute doctor files by their longest row surface
replygirl Oct 4, 2026
5b2e317
docs(harness): say what doctor's scan reads and what stays codex-only
replygirl Oct 4, 2026
43e79f5
refactor(harness): record the round-3 check run (5.3)
replygirl Oct 4, 2026
5d9a842
docs(harness): remove the self-written Non-Goal mislabeling
replygirl Oct 5, 2026
9ce9a8e
docs(harness): record post-rebase byte-identity evidence
replygirl Oct 5, 2026
aad0bf9
docs(harness): record the final pre-archive check run (5.3)
replygirl Oct 5, 2026
6ddec87
refactor(harness): archive harness-adapter-table
replygirl Oct 5, 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
23 changes: 20 additions & 3 deletions .agents/shared.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ self-hosts: this repo's own `openspec/` tree is managed by cospec.
cospec/
├── apps/cli/ @aligned-team/cospec — the cospec CLI
│ ├── src/canon/ single source of truth: schemas + workflows + gate
│ ├── src/harness/ HARNESS_TABLE (per-tool layout) + the harness renderer
│ ├── src/core/ openspec wrapper, parsers, validation, managed files
│ ├── src/commands/ one file per cospec subcommand
│ └── test/ unit / contract / integration / fixtures
Expand Down Expand Up @@ -249,9 +250,25 @@ fails, fix the root cause; never use `--no-verify`, `pre-commit`, or raw

**Managed files are generated** — `openspec/schemas/**` and the harness dirs
(`.claude/`, `.agents/skills/cospec-*/`, `.codex/`, `.opencode/`) are composed
from `apps/cli/src/canon/`. Edit the canon, run `mise run generate`; never
hand-edit generated output. The `generate:check` drift gate blocks the commit
otherwise.
from `apps/cli/src/canon/` (schemas, workflow bodies and workflow identity) and
`HARNESS_TABLE` in `apps/cli/src/harness/adapters.ts` — the one declaration of
each tool's layout: skills and commands dirs, filenames, serializer,
frontmatter, body dialect, rules file, detection paths and receipt note.
`render.ts`, `init`, `update` and `doctor` all read the table; none keeps its
own copy of a layout fact. A new tool is mostly a new row, not only one: a
home-scoped skills root renders but is not yet written; the legacy-skills
migration (`harness/legacy-skills.ts`, its receipt and `update --check` lines,
doctor's `legacy-layout` warning) covers only Codex's `.codex/skills`, so a new
row's `legacySkillsDirs` is detected but never migrated; and deliberate
Claude-only behaviour sits outside the table — `init`'s `.claude/settings.json`
merge and its `claude` default (docs/harness-integration.md names them). The
receipt's `/cospec:propose` hint, always in Claude's spelling regardless of
selected row, and doctor's scan reading every `.md` file under a skills root
rather than just `SKILL.md` and the table's command paths, are known defects on
`main`, not part of that deliberate set; the follow-on change
`harness-receipt-and-doctor-scope` fixes both. Edit the canon or the table, run
`mise run generate`; never hand-edit generated output. The `generate:check`
drift gate blocks the commit otherwise.

**Error handling** — never silently swallow errors. Catch only specific expected
cases; let unexpected exceptions propagate. Fixes must change observable
Expand Down
8 changes: 8 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,11 @@ openspec/schemas/
# checked-in fixture itself must never be reformatted, or the scenario would
# start pre-completed.
packages/bench/scenarios/fixtures/style/src/format.ts

# harness-adapter-table (R8): committed raw golden files proving
# renderHarnessFiles/init/update/doctor output is byte-identical across the
# refactor (Buffer-compared, regenerated only under COSPEC_GOLDEN_WRITE=1).
# `renderHarnessFiles`'s own output is their formatting authority; reflowing
# them here would make a committed golden diverge from what the code actually
# emits, defeating the byte-identity proof.
__golden__/
23 changes: 20 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ self-hosts: this repo's own `openspec/` tree is managed by cospec.
cospec/
├── apps/cli/ @aligned-team/cospec — the cospec CLI
│ ├── src/canon/ single source of truth: schemas + workflows + gate
│ ├── src/harness/ HARNESS_TABLE (per-tool layout) + the harness renderer
│ ├── src/core/ openspec wrapper, parsers, validation, managed files
│ ├── src/commands/ one file per cospec subcommand
│ └── test/ unit / contract / integration / fixtures
Expand Down Expand Up @@ -253,9 +254,25 @@ fails, fix the root cause; never use `--no-verify`, `pre-commit`, or raw

**Managed files are generated** — `openspec/schemas/**` and the harness dirs
(`.claude/`, `.agents/skills/cospec-*/`, `.codex/`, `.opencode/`) are composed
from `apps/cli/src/canon/`. Edit the canon, run `mise run generate`; never
hand-edit generated output. The `generate:check` drift gate blocks the commit
otherwise.
from `apps/cli/src/canon/` (schemas, workflow bodies and workflow identity) and
`HARNESS_TABLE` in `apps/cli/src/harness/adapters.ts` — the one declaration of
each tool's layout: skills and commands dirs, filenames, serializer,
frontmatter, body dialect, rules file, detection paths and receipt note.
`render.ts`, `init`, `update` and `doctor` all read the table; none keeps its
own copy of a layout fact. A new tool is mostly a new row, not only one: a
home-scoped skills root renders but is not yet written; the legacy-skills
migration (`harness/legacy-skills.ts`, its receipt and `update --check` lines,
doctor's `legacy-layout` warning) covers only Codex's `.codex/skills`, so a new
row's `legacySkillsDirs` is detected but never migrated; and deliberate
Claude-only behaviour sits outside the table — `init`'s `.claude/settings.json`
merge and its `claude` default (docs/harness-integration.md names them). The
receipt's `/cospec:propose` hint, always in Claude's spelling regardless of
selected row, and doctor's scan reading every `.md` file under a skills root
rather than just `SKILL.md` and the table's command paths, are known defects on
`main`, not part of that deliberate set; the follow-on change
`harness-receipt-and-doctor-scope` fixes both. Edit the canon or the table, run
`mise run generate`; never hand-edit generated output. The `generate:check`
drift gate blocks the commit otherwise.

**Error handling** — never silently swallow errors. Catch only specific expected
cases; let unexpected exceptions propagate. Fixes must change observable
Expand Down
23 changes: 20 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ self-hosts: this repo's own `openspec/` tree is managed by cospec.
cospec/
├── apps/cli/ @aligned-team/cospec — the cospec CLI
│ ├── src/canon/ single source of truth: schemas + workflows + gate
│ ├── src/harness/ HARNESS_TABLE (per-tool layout) + the harness renderer
│ ├── src/core/ openspec wrapper, parsers, validation, managed files
│ ├── src/commands/ one file per cospec subcommand
│ └── test/ unit / contract / integration / fixtures
Expand Down Expand Up @@ -249,9 +250,25 @@ fails, fix the root cause; never use `--no-verify`, `pre-commit`, or raw

**Managed files are generated** — `openspec/schemas/**` and the harness dirs
(`.claude/`, `.agents/skills/cospec-*/`, `.codex/`, `.opencode/`) are composed
from `apps/cli/src/canon/`. Edit the canon, run `mise run generate`; never
hand-edit generated output. The `generate:check` drift gate blocks the commit
otherwise.
from `apps/cli/src/canon/` (schemas, workflow bodies and workflow identity) and
`HARNESS_TABLE` in `apps/cli/src/harness/adapters.ts` — the one declaration of
each tool's layout: skills and commands dirs, filenames, serializer,
frontmatter, body dialect, rules file, detection paths and receipt note.
`render.ts`, `init`, `update` and `doctor` all read the table; none keeps its
own copy of a layout fact. A new tool is mostly a new row, not only one: a
home-scoped skills root renders but is not yet written; the legacy-skills
migration (`harness/legacy-skills.ts`, its receipt and `update --check` lines,
doctor's `legacy-layout` warning) covers only Codex's `.codex/skills`, so a new
row's `legacySkillsDirs` is detected but never migrated; and deliberate
Claude-only behaviour sits outside the table — `init`'s `.claude/settings.json`
merge and its `claude` default (docs/harness-integration.md names them). The
receipt's `/cospec:propose` hint, always in Claude's spelling regardless of
selected row, and doctor's scan reading every `.md` file under a skills root
rather than just `SKILL.md` and the table's command paths, are known defects on
`main`, not part of that deliberate set; the follow-on change
`harness-receipt-and-doctor-scope` fixes both. Edit the canon or the table, run
`mise run generate`; never hand-edit generated output. The `generate:check`
drift gate blocks the commit otherwise.

**Error handling** — never silently swallow errors. Catch only specific expected
cases; let unexpected exceptions propagate. Fixes must change observable
Expand Down
41 changes: 5 additions & 36 deletions apps/cli/src/canon/workflows/harness.yaml
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
# Per-harness rendering manifest (DESIGN 6.1). Consumed by src/harness/render.ts.
# Workflow identity manifest (DESIGN 6.1). Consumed by src/harness/render.ts.
# Workflow bodies are single-sourced in the sibling <id>.md files; render.ts pairs each
# workflow with each selected harness surface and stamps generatedBy/contentHash frontmatter.
# workflow with each selected tool row and stamps generatedBy/contentHash frontmatter.
#
# Skill directories exist for every harness. Command (slash) surfaces exist for claude and
# opencode only; codex gets skills plus a prefix-rule allowlist (rulesPath) and no slash
# commands. Path templates use {command} and {skill} placeholders.
#
# `codex` and `agents` both render into the vendor-neutral `.agents/skills` root that
# Codex, Zed, Antigravity and other AGENTS.md-aware assistants read. They share one
# bodyDialect, so selecting both emits one byte-identical set of files plus codex's
# rules file. `legacySkillDirs` records the pre-1.11 location cospec migrates away from.
#
# `bodyDialect` picks how in-body `/cospec:<id>` references are respelled:
# canonical - left as `/cospec:<id>` (Claude registers those slash commands)
# opencode - `/cospec-<id>`, matching the slash commands OpenCode registers
# shared - `$cospec-<skill> (Codex) or /cospec-<skill> (other agents)`, because the
# shared root emits no command files and only skill names resolve there
# This file declares workflow identity only. Every tool's layout — skills and commands
# roots, filename templates, body dialect, rules file, legacy dirs, detection paths — is
# declared once, in HARNESS_TABLE in src/harness/adapters.ts.
#
# `takesArguments` is audited per workflow: true when the body reads a positional
# argument (a `<type>: <text>` or a change slug). It drives the OpenCode $ARGUMENTS
Expand Down Expand Up @@ -124,23 +113,3 @@ workflows:
description: >-
Walk a first-time user through one real cospec change end to end, narrating each step.
Also use when the user says "cospec onboard" or "openspec onboard".

harnesses:
claude:
commandDir: .claude/commands/cospec
commandFile: '{command}.md'
skillDir: .claude/skills/{skill}
bodyDialect: canonical
codex:
skillDir: .agents/skills/{skill}
legacySkillDirs: ['.codex/skills/{skill}']
rulesPath: .codex/rules/cospec.rules
bodyDialect: shared
agents:
skillDir: .agents/skills/{skill}
bodyDialect: shared
opencode:
commandDir: .opencode/commands
commandFile: 'cospec-{command}.md'
skillDir: .opencode/skills/{skill}
bodyDialect: opencode
Loading
Loading