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
12 changes: 9 additions & 3 deletions uts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,16 +162,22 @@ See [docs/writing-test-specs.md](docs/writing-test-specs.md) for the full pseudo

### Installing the skill creator

Install it once, at user level, by symlinking (if an earlier copy is there, remove it first: `ln -sfn` would create the link inside it) the skill directory from your local clone of this repo into both tools' skill directories. Both Claude Code and Codex follow directory symlinks, and a `git pull` of the clone updates both:
Keep one shared clone of this repo, `~/.ably/specification` (`%USERPROFILE%\.ably\specification` on Windows), or wherever `ABLY_SPEC_CLONE` points, and install the skill once, at user level, by symlinking its directory from that clone into both tools' skill directories. Both Claude Code and Codex follow directory symlinks. The clone's checkout must contain `uts/skills/uts-to-lang-skill-creator`; if its `main` doesn't yet, see the last bullet below.

```sh
SPEC=~/src/specification # your local clone of ably/specification
SPEC="${ABLY_SPEC_CLONE:-$HOME/.ably/specification}" # the shared clone
[ -d "$SPEC/.git" ] || git clone -c core.autocrlf=false --no-recurse-submodules https://github.com/ably/specification.git "$SPEC"
mkdir -p ~/.claude/skills ~/.agents/skills
ln -sfn "$SPEC/uts/skills/uts-to-lang-skill-creator" ~/.claude/skills/uts-to-lang-skill-creator # Claude Code
ln -sfn "$SPEC/uts/skills/uts-to-lang-skill-creator" ~/.agents/skills/uts-to-lang-skill-creator # Codex
```

Then, in the SDK repo, run `/uts-to-lang-skill-creator <spec-clone-path>` (Claude Code) or `$uts-to-lang-skill-creator <spec-clone-path>` (Codex), or ask for a `uts-to-<lang>` skill in your own words. Run it on the most capable model tier available (Opus-class). If symlinks aren't available (for example on Windows without Developer Mode), copy the directory instead and re-copy after each pull; the skill detects a stale copy and asks you to refresh it. Without installing, any agent can be told: "Read `<spec-clone>/uts/skills/uts-to-lang-skill-creator/SKILL.md` and follow it."
- **Keeping it current.** Each run offers to fetch and fast-forward the shared clone's `main`, which also updates the skill; it does so only when `main` is checked out, clean and strictly behind `origin/main`, and otherwise reports the clone's state and asks. It never pulls, resets, stashes or switches branches. Set `ABLY_SPEC_SYNC=auto` to stop being asked, or `off` to stay offline (with no clone at all, the skill still offers to clone one, and asks first). The skill never sets it for you.
- **An earlier install.** If a copy of the skill directory is already at either install path, remove it first: `ln -sfn` would create the link inside it.
- **Windows.** Without symlinks (Developer Mode), copy the directory instead, and copy it again after each update; the skill detects a stale copy and asks you to refresh it.
- **Testing an unmerged spec or skill change.** Add a worktree of the shared clone (`git -C "$SPEC" worktree add <dir> <branch>`) and install the skill from it, or pass `--spec-clone <dir>`; keep the shared clone itself on `main`. The sync runs only when the clone in use is the shared clone, however it was found: a worktree, or any other clone you name, is never synced, and the skill warns you to keep it up to date yourself. Unless you name another clone, the skill reads the one it is installed from, so the guide it reads matches it. If the shared clone's `main` doesn't contain `uts/skills/uts-to-lang-skill-creator` yet, install from a clone or worktree of a branch that does; given only a clone that predates the skill, it stops with `SPEC_CLONE_INCOMPLETE` and says what to do.

Then, in the SDK repo, run `/uts-to-lang-skill-creator` (Claude Code) or `$uts-to-lang-skill-creator` (Codex), or ask for a `uts-to-<lang>` skill in your own words; no path is needed (`--spec-clone <path>`, or a path in your words, still names another clone, which isn't synced). Run it on the most capable model tier available (Opus-class). Without installing, any agent can be told: "Read `<spec-clone>/uts/skills/uts-to-lang-skill-creator/SKILL.md` and follow it." The `uts-to-<lang>` skills it generates use the same shared clone by default, with the same rule: a module path into any other clone is used as it is, with a warning.

## Go Test Proxy

Expand Down
45 changes: 28 additions & 17 deletions uts/docs/writing-uts-spec-translator-skills.md

Large diffs are not rendered by default.

40 changes: 19 additions & 21 deletions uts/skills/uts-to-lang-skill-creator/SKILL.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
| Module notes for every diverging module; `objects` decided from evidence of the LiveObjects public API (full notes if exposed, even if incomplete; a placeholder or an entry with every tier marked not ready otherwise) | 7.5; D-23; 12.1–12.3; D-28 (decided at STOP-14) | 7.5 acceptance; 8.5 paths 3–4 | |
| Scripts run on every developer platform (path handling, UTF-8, LF) | 7.1–7.3; D-02 | 8.1 (path parts, `~`), 8.6 (platforms) | |
| **Workflow** | | | |
| Required reading incl. features specs, from the same clone | 7.6 (step 0) | 8.3 pilot | |
| Required reading incl. features specs, from the same clone, synced first (SHOULD; D-32) | 7.6 (step 0) | 8.3 pilot; 8.5 path 11 | |
| Steps 0 and A–F: the four questions and the harness preflight (stop on red) | 7.6 | 8.3 pilot (green preflight first); 8.5 paths 8–9 | |
| Steps 1–7 with batching; a reference test per tier; review in both modes | 7.6; 8.8 | 8.3 pilot; 8.8 | |
| Unmapped constructs stop and ask; corpus scanner in `scripts/` (SHOULD) | 7.4; 7.6; D-19 | 8.3 pilot; 8.5 (re-sync) | |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Design record: uts-to-<lang>

## Inputs at generation time
- Spec clone: <sha> (clean | dirty: <files>); guide/skill: <sha of last change>; uts-to-lang-skill-creator version <metadata.version>
- Spec clone: <shared|env|explicit|skill-clone> <path>; <sha> on <branch|detached> (clean | dirty: <files>); on origin/main: <yes|no>; sync: <fast-forwarded <old8>..<new8> | up to date | not updated: <reason>, behind <n> as of last fetch | not synced (not the shared clone)>; guide/skill: <sha of last change>; uts-to-lang-skill-creator version <metadata.version>
- Repo: <sha>
- Repo profile confirmed: <date>; harness option at STOP-3: (a | b | c); harness confirmed: <date>
- Harness README: <full repo path>
Expand Down Expand Up @@ -47,6 +47,7 @@
| D-29 | Gap-audit choices: add / skip / defer per GA- or CH- item; preserve list (STOP-15; n/a in create mode) | | | | |
| D-30 | Provenance stamp (metadata.generated-by, metadata.records) and Run status | | | | |
| D-31 | Capability profile and skill scope (STOP-13 or STOP-17) | | | | |
| D-32 | Spec-clone sync in the generated skill (ensure_spec_clone.py copied; ABLY_SPEC_SYNC) | | | | |

### D-03 mapping
| Module | unit | integration | proxy | notes | hand-maintained? |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Final report: uts-to-<lang> for <repo>

- Spec clone <sha> (clean | dirty: <files>); repo <sha>; date
- Spec clone: <shared|env|explicit|skill-clone> <path>; <sha> on <branch|detached> (clean | dirty: <files>); on origin/main: <yes|no>; sync: <fast-forwarded <old8>..<new8> | up to date | not updated: <reason>, behind <n> as of last fetch | not synced (not the shared clone)>; repo <sha>; date
- Spec SHA not on origin/main (a branch run): <none | sha: the stamp and any test headers that carry it may stop resolving once that branch is deleted>
- Model: <name and ID> (Opus-class: yes | no, and why); sub-agents: <role → model>, or none
- Scope: <modules × tiers covered>; out of scope and why
- Conforms to the guide: yes | no (MUST rows ✗: …)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
(paste orient.py's stateSummaryText, completed with the model, the capability profile confirmed at STOP-13 or STOP-17 (D-31), and the option chosen at STOP-13)

- Repo: <path>, HEAD <sha> (clean | dirty: <files>)
- Spec clone: <path>, HEAD <sha> (clean | dirty: <files>); guide/skill last changed in <sha>; skill version <metadata.version>
- Spec clone: <shared|env|explicit|skill-clone> <path>; <sha> on <branch|detached> (clean | dirty: <files>); on origin/main: <yes|no>; sync: <fast-forwarded <old8>..<new8> | up to date | not updated: <reason>, behind <n> as of last fetch | not synced (not the shared clone)>; guide/skill last changed in <sha>; skill version <metadata.version>
- Date: <yyyy-mm-dd>; confirmed by the user on <date> (STOP-2)
- User goals: <modules and tiers, in priority order>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Gap audit: uts-to-<lang> in <repo name>

- Existing skill: <path> (installs: <.claude/skills/…, .agents/skills/… (symlink | copy)>); frontmatter version <metadata.version or none>
- Repo <sha> (clean | dirty: <files>); spec clone <sha> (clean | dirty: <files>)
- Repo <sha> (clean | dirty: <files>)
- Spec clone: <shared|env|explicit|skill-clone> <path>; <sha> on <branch|detached> (clean | dirty: <files>); on origin/main: <yes|no>; sync: <fast-forwarded <old8>..<new8> | up to date | not updated: <reason>, behind <n> as of last fetch | not synced (not the shared clone)>
- State class (Orient): S2 | S3 | S4; mode at STOP-13: upgrade: diff-driven | upgrade: full audit | upgrade: regenerate — chosen by <user> on <date>
- inspect_existing_skill.py run: <date>; its checks are regex hints, every row below is confirmed by reading
- Capabilities: recorded D-31 <line or none> vs Orient now <profile; side>; delta: <none | capability added | side changed>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ All from the guide and the UTS docs; follow the link for the detail.
| Orient offers to resume a run that finished | The Design record's Run status wasn't set to finished at Phase 7 | Restart, or set the Run status after checking the Final report | [13.6](orient.md#136-re-entry-resume-or-restart) |
| A REST-only SDK reported with realtime, or a full SDK reported REST-only | Realtime names only in comments, tests or docs; renamed clients the detector doesn't know; a client only reachable through a factory in an excluded directory or submodule | Read the evidence; correct the profile at STOP-17 with evidence; add a new client name to `aliases` in `assets/capability-names.json` (not the code) | [13.8](orient.md#138-capabilities-and-scope-stop-17-d-31) |
| Orient's Spec names line says FALLBACK, or a renamed spec type isn't found | The spec clone's IDL couldn't be parsed (a missing heading, a moved file, an old clone), so the detectors used the data file's minimal, possibly stale names | Fix or update the spec clone at STOP-1 and rerun; if the IDL's format changed, report the parser gap. Don't rely on the LiveObjects or capability verdicts until it says `spec` | [13.4](orient.md#134-the-state-summary-and-stop-13), [13.8](orient.md#138-capabilities-and-scope-stop-17-d-31) |
| The spec-clone sync says `FETCH_FAILED` although the machine is online | A sandbox denies writes under the clone's `.git` or network access; or a credential or SSH prompt was suppressed | Use the clone as it is for this run; the user allows the directory and network (Claude Code `/add-dir` or `permissions.additionalDirectories`; Codex a writable root and network), or fixes the remote's auth, then reruns | [13.9](orient.md#139-sync-the-spec-clone) |
| The sync says `NOT_SYNCED_NAMED_CLONE`, or Orient shows SPEC CLONE NOT SYNCED | The clone in use isn't the shared clone (a path the user named, or a skill installed from another clone): only the shared clone is synced | Expected. The user keeps that clone up to date; to have it synced, use the shared clone instead (no path, a path into it, or `ABLY_SPEC_CLONE` pointing at it) | [13.9](orient.md#139-sync-the-spec-clone) |
| The sync says `LOCKED` | Another run is syncing the same clone, or a crashed run left its lock | Use the clone as it is; if no other run is syncing, the user removes the reported lock file | [13.9](orient.md#139-sync-the-spec-clone) |
| The sync says `NOT_ON_MAIN`, and nobody meant to leave the shared clone on a branch | The clone was switched to test a spec change and left there | Use it as it is, or stop while the user switches it back; the sync never switches. To test branches, use a worktree of the shared clone instead | [13.9](orient.md#139-sync-the-spec-clone) |
| The spec clone's HEAD moved mid-run | This run's sync, or another run's fast-forward of the shared clone | Stop and ask whether to restart from the new SHA; never stamp the old SHA on files read after the move | [13.9](orient.md#139-sync-the-spec-clone), [2.6](../SKILL.md#26-pin-the-spec-clone) |
| Orient says the recorded spec SHA isn't in this clone | The records came from another clone, or from a branch whose commits were since deleted | In the shared clone, fetch the SHA after STOP-6 and rerun Orient; if it is still missing, run the full gap audit. In any other clone, never fetch: the user fetches it, or run the full gap audit | [13.9](orient.md#139-sync-the-spec-clone) |
| `SPEC_CLONE_INCOMPLETE` | The clone's checkout predates the guide or this skill (for example a `main` from before they were merged) | Follow the message: for the shared clone, sync it if `origin/main` has them; otherwise name a clone or worktree of a branch that has them | [13.9](orient.md#139-sync-the-spec-clone) |
| Sides reported for an SDK without doors, or a door's side wrong | A factory or door type whose name or path the data file doesn't know, or a door type under an unexpected path | Read the Side lines' evidence; correct the side at STOP-17; add the door type or path to `doorFactories.sides` in `assets/capability-names.json` | [13.8](orient.md#138-capabilities-and-scope-stop-17-d-31) |
| A harness defect reported as SDK-blocked | The objects smoke test fails, and it is blamed on the SDK without checking | SDK-blocked needs every self-test green and evidence naming an SDK not-implemented symbol; otherwise it is a harness stop | [12.5](liveobjects-support.md#125-an-sdk-blocked-objects-tier) |
| `objects` translated with no notes in a later run | No mapping entry, so the skill's step B offered `--create` | Give `objects` an entry even when out of scope: every tier unready, with the reason | [12.2](liveobjects-support.md#122-stop-14-recommend-then-ask) |
Expand Down
2 changes: 2 additions & 0 deletions uts/skills/uts-to-lang-skill-creator/references/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ Part of the `uts-to-lang-skill-creator` skill: read [SKILL.md](../SKILL.md) firs
| **Delegating spec/test** | One that says to run another module's tests against this client |
| **Re-sync** | Re-auditing a module against a newer spec SHA and regenerating what changed |
| **Spec SHA** | The commit of the local spec clone that a test, or the skill, was derived from |
| **Shared spec clone** | The one local clone of `ably/specification` that every run and every SDK repo reads by default: `ABLY_SPEC_CLONE`, else `~/.ably/specification`; a path the user names, or the clone this skill is installed from, comes first, and is the shared clone only if it is that same directory ([13.9](orient.md#139-sync-the-spec-clone)) |
| **Spec-clone sync** | Step 0's only network use (including fetching a recorded spec SHA missing from the clone), for the shared clone only (any other clone gets a static warning and is never fetched): with approval (or the user's `ABLY_SPEC_SYNC=auto`), fetch `origin main` and fast-forward a clean, checked-out `main` that is strictly behind; anything else is reported and left alone. `ensure_spec_clone.py` does it ([13.9](orient.md#139-sync-the-spec-clone)) |
| **Phase N / generated-skill Phase 1–2** | "Phase N" (0–7) is a phase of this procedure; Phase 0 is Orient, also called Step 0 (the generated skill's own step 0 is named with its context: "guide 4 step 0" or "generated-skill step 0"). "Generated-skill Phase 1" (selection, steps 0 and A–F) and "generated-skill Phase 2" (per spec, steps 1–7) are the generated `uts-to-<lang>` skill's workflow (guide [4](../../../docs/writing-uts-spec-translator-skills.md#4-the-workflow-the-skill-must-implement)). `writing-derived-tests.md` Phase 1/2 is always named with that document |
| **Working records** | Repo profile, Harness design (with the gap table), Design record, Final report; in Upgrade/Fix, also the gap audit |
| **Stop point** | A STOP-n point where you present what you found and the options, wait for the user's answer and record it ([2.3](../SKILL.md#23-stop-points)) |
Expand Down
Loading
Loading