diff --git a/LICENSE b/LICENSE index 7922a02..470f9ee 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -MIT License +The MIT License Copyright (c) 2026 John Dewey @@ -9,13 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/openspec/changes/specify-agent-tool-invocation/tasks.md b/openspec/changes/specify-agent-tool-invocation/tasks.md index 2c922b0..775f150 100644 --- a/openspec/changes/specify-agent-tool-invocation/tasks.md +++ b/openspec/changes/specify-agent-tool-invocation/tasks.md @@ -5,8 +5,8 @@ ## 2. Apply to each repository -- [ ] 2.1 `osapi` — blocked: it has no `AGENTS.md`, pending its CONTRIBUTING - conversion (`standardize-repository-layout` task 4.5) +- [x] 2.1 `osapi` — `AGENTS.md` written as part of its layout conversion + (osapi-io/osapi#450) - [x] 2.2 `gohai` - [x] 2.3 `nats-client` - [x] 2.4 `nats-server` @@ -16,5 +16,16 @@ ## 3. Verification -- [ ] 3.1 Confirm every `AGENTS.md` states how tools are invoked -- [ ] 3.2 Confirm every repository declares the tools its recipes invoke +- [x] 3.1 Confirm every `AGENTS.md` states how tools are invoked. All seven + carry the `mise exec -- just test` form and the explanation of why a bare + `just` resolves differently for an agent +- [ ] 3.2 Confirm every repository declares the tools its recipes invoke. Six of + seven do. `osapi` was missing `uv`, which `just md-fmt` invokes through `uvx`; + it is now declared (osapi-io/osapi#450). One gap remains: `osapi`'s `generate` + recipe invokes `redocly`, which no repository file declares — it resolves from + whatever the developer installed globally. Declaring it is not a one-line fix: + the version mise supplies (2.46.1) quotes YAML scalars differently from the + version currently on the developer's path (2.19.1), so the committed combined + spec and both generated SDKs change the first time anyone runs `just generate` + against it. That regeneration is its own change, and nothing in continuous + integration runs `generate`, so the drift is invisible until someone does diff --git a/openspec/changes/specify-documentation-homes/tasks.md b/openspec/changes/specify-documentation-homes/tasks.md index f73595e..bfaebfd 100644 --- a/openspec/changes/specify-documentation-homes/tasks.md +++ b/openspec/changes/specify-documentation-homes/tasks.md @@ -47,10 +47,10 @@ - [x] 3.5 `osapi` — propose a capability from `docs/sidebar/sdk/guidelines.md`; "never expose generated types" and "JSON tags required" bind every consumer of `pkg/sdk`, including `osapi-orchestrator` -- [ ] 3.6 `osapi` — resolve the three-way duplication of branching, commit - messages, linting, and test conventions across `CLAUDE.md`, `development.md`, - and `testing.md` before the root `CONTRIBUTING.md` is written, so the - conversion has one source to draw from +- [x] 3.6 `osapi` — the three-way duplication of branching, commit messages, + linting, and test conventions across `CLAUDE.md`, `development.md`, and + `testing.md` is resolved into the root `CONTRIBUTING.md`; the two site pages + are now pointers to it (osapi-io/osapi#450) - [ ] 3.9 `osapi` — capture "job creation goes through domain endpoints" as a requirement. Removing `docs/plans/` deletes its only written record: the rule still binds (the sole `post:` on the job API is `/api/job/{id}/retry`, an @@ -67,9 +67,12 @@ change before removal - [x] 4.2 `osapi` — remove `docs/plans/` (70 documents) - [x] 4.3 `osapi-orchestrator` — remove `docs/plans/` (6 documents) -- [ ] 4.4 Both — note in `CONTRIBUTING.md` that design records are changes in - the corpus. Done for `osapi-orchestrator`; `osapi` has no root - `CONTRIBUTING.md` until `standardize-repository-layout` task 4.5 writes one +- [x] 4.4 Both — `CONTRIBUTING.md` notes that design records are changes in the + corpus. `osapi-orchestrator` already did; `osapi`'s root `CONTRIBUTING.md` now + does (osapi-io/osapi#450). Applying this surfaced a stale pointer: + `osapi-orchestrator`'s `AGENTS.md` still sent readers to the `docs/plans/` + removed by task 4.3, contradicting its own `CONTRIBUTING.md` + (osapi-io/osapi-orchestrator#74) ## 4a. Make the corpus navigable diff --git a/openspec/changes/specify-go-code-standards/tasks.md b/openspec/changes/specify-go-code-standards/tasks.md index 2b2f237..7ce89b1 100644 --- a/openspec/changes/specify-go-code-standards/tasks.md +++ b/openspec/changes/specify-go-code-standards/tasks.md @@ -10,15 +10,36 @@ - [x] 2.2 `nats-client` — `CONTRIBUTING.md` - [x] 2.3 `nats-server` — `CONTRIBUTING.md` - [x] 2.4 `osapi-orchestrator` — `CONTRIBUTING.md` -- [ ] 2.5 `osapi` — `CLAUDE.md` drops `Code Standards`, and the conventions - duplicated into `development.md` and `testing.md` resolve to one source +- [x] 2.5 `osapi` — `CLAUDE.md` dropped `Code Standards`, and the conventions + duplicated into `development.md` and `testing.md` now resolve to the root + `CONTRIBUTING.md`, which points at this capability rather than restating it + (osapi-io/osapi#450) ## 3. Verification - [x] 3.1 Confirm no `types.go` contains a function - [x] 3.2 Confirm no repository holds a generically named file - [x] 3.3 Confirm every test package uses a table-driven suite -- [ ] 3.4 Confirm no mock is hand-written where an interface is mocked +- [ ] 3.4 Confirm no mock is hand-written where an interface is mocked. Three + remain, each a struct written to satisfy a project-owned interface: + `fakeCollector` in `gohai` (`internal/collector/registry_public_test.go`), + `mockRenderer` in `osapi-orchestrator` + (`pkg/orchestrator/orchestrator_test.go`), and `mockPKISigner` in `osapi` + (`internal/job/client/signing_public_test.go`). `mockPKISigner` signs with a + real ed25519 key, so it reads as a real implementation rather than a mock and + may fall under the carve-out; the other two do not. `gohai` and + `osapi-orchestrator` declare no mocking library, so satisfying this needs a + decision on introducing one, not just a regeneration - [ ] 3.5 Confirm no test uses an exported alias to re-cover behavior the - caller's own test already reaches -- [ ] 3.6 Confirm no shared convention is stated in two places + caller's own test already reaches. Not yet established: 65 `export_test.go` + files exist (32 in `gohai`, 32 in `osapi`, 1 in `osapi-orchestrator`), and the + requirement turns on what each exposure is *for*, which no search can decide. + This needs a file-by-file audit +- [ ] 3.6 Confirm no shared convention is stated in two places. `nats-client` + and `nats-server` point at the capability without restating it, and `osapi` + now does the same. `gohai` and `osapi-orchestrator` point at it *and* restate + it — `osapi-orchestrator` under `Function Signatures`, `Testing`, + `Go Patterns`, and `Linting`; `gohai` under `Function Signatures`. Both say + the specification wins where they disagree, which acknowledges the duplication + rather than removing it. Resolving this means deleting the restatements, which + reverses a deliberate choice recorded when those repositories were converted diff --git a/openspec/changes/standardize-repository-layout/tasks.md b/openspec/changes/standardize-repository-layout/tasks.md index 9f6e80b..5e7a3cf 100644 --- a/openspec/changes/standardize-repository-layout/tasks.md +++ b/openspec/changes/standardize-repository-layout/tasks.md @@ -44,12 +44,16 @@ structure for its type. - [x] 4.3 `nats-server` (Go library) - [x] 4.4 `osapi-orchestrator` (Go library, pending the open question on its type) -- [ ] 4.5 `osapi` (main product; file layout only, README exempt) — the only - repository with neither a root `CONTRIBUTING.md` nor `AGENTS.md`, a 917-line - `CLAUDE.md`, and three competing contributing documents: - `docs/CONTRIBUTING.md` (60 lines), - `docs/docs/sidebar/development/contributing.md` (109), and - `ui/docs/contributing.md` +- [x] 4.5 `osapi` (main product; file layout only, README exempt) — converted in + osapi-io/osapi#450. The 917-line `CLAUDE.md` split by audience: contributor + conventions to a root `CONTRIBUTING.md`, agent-specific guidance to + `AGENTS.md`, and the nine-step domain walkthrough to its own site page. + `CLAUDE.md` is now a pointer. Of the three competing contributing documents, + `docs/CONTRIBUTING.md` and `ui/docs/contributing.md` were removed and + `docs/docs/sidebar/development/contributing.md` reduced to a pointer. + `ui/docs/architecture.md` was kept: it holds a UI-primitives table, a `Text` + variant reference, and a hooks table the site's `ui.md` does not, so removing + it would lose content. Folding it in belongs to `specify-documentation-homes` - [x] 4.6 `osapi-ui` — not converted; recorded as deprecated instead - [x] 4.7 `specs` (documentation) — its `CODE_OF_CONDUCT.md` named no enforcement contact, leaving no way to report a violation, and its `LICENSE` @@ -59,48 +63,90 @@ structure for its type. No workflow in any repository uses mise; all seven provision tools twice. -- [ ] 5.1 `osapi`, `gohai`, `osapi-orchestrator`, `nats-client`, `nats-server` — - declare `just` in `.mise.toml`. None does, so it comes from the developer's - system: Homebrew's 1.45.0 formats a boolean setting as `:= true` while the - version CI installs writes the bare form, and each rejects the other -- [ ] 5.1a Record which version `extractions/setup-just` installs, and declare - that version, so `mise install` and CI agree +- [x] 5.1 `osapi`, `gohai`, `osapi-orchestrator`, `nats-client`, `nats-server` — + all five now declare `just` in `.mise.toml`, so it no longer comes from the + developer's system. `osapi` was also invoking `uv` through `uvx` without + declaring it (osapi-io/osapi#450) +- [x] 5.1a Record which version `extractions/setup-just` installs. No workflow + in any repository passes `just-version`, so the action installs the latest + release, and every `.mise.toml` declares `just = "latest"`. Both paths already + float together, which is what the requirement asks for where nothing automates + the version — so the pin this task called for would violate it. Recorded + rather than applied - [ ] 5.2 Confirm `.mise.toml` and the workflow resolve to the same version for - every tool, floating or pinned -- [ ] 5.3 Confirm no tool is pinned in one path and floating in the other + every tool, floating or pinned. `just`, `bun`, and `uv` float on both sides; + `node` is `22` in both. `go` does not agree: `.mise.toml` declares `1.25` + while every workflow sets `go-version: stable`. They resolve alike today and + diverge the day 1.26 ships +- [ ] 5.3 Confirm no tool is pinned in one path and floating in the other. `go` + fails it, in all five Go repositories. Fixing it is a choice the requirement + narrows but does not make: nothing bumps `.mise.toml`, so the requirement's + own answer is that both paths float, which means `go = "latest"` locally + rather than pinning CI to `1.25`. That changes which toolchain every developer + builds with, so it wants a decision rather than a sweep - [x] 5.5 `osapi-orchestrator` — `actions/setup-go@v6` while every other repository uses `@v7` -- [ ] 5.6 Confirm Dependabot raises each new pin, in both locations +- [x] 5.6 Confirm Dependabot raises each new pin, in both locations. It watches + `github-actions` in all seven repositories and `gomod` in the five Go ones. It + does not watch `.mise.toml`, and no ecosystem exists that would — which is why + the tools declared there float rather than pin ## 6. Resolve the deprecated repositories -- [ ] 6.1 `osapi-io-taskfiles` — record deprecation at the top of its README, - naming `osapi-justfiles` as the replacement. Blocked: the repository is now - archived and cannot be pushed to. Either unarchive briefly to add the notice, - or accept the archived state as the signal and drop this task +- [x] 6.1 `osapi-io-taskfiles` — dropped. The task was to record deprecation at + the top of its README, but the repository is archived and cannot be pushed to. + Of the two ways out the task offered, the archived state is accepted as the + signal: GitHub already marks it read-only and labels it archived, which is the + half of the requirement that changes what a reader sees. Unarchiving a + repository nothing consumes, to add a sentence, and re-archiving it buys a + line of prose at the cost of disturbing the signal that is already correct - [x] 6.2 Archive `osapi-sdk` on GitHub - [x] 6.3 Archive `osapi-ui` on GitHub - [x] 6.4 Archive `osapi-io-taskfiles` on GitHub ## 6a. Correct the react module override -- [ ] 6a.1 `osapi-justfiles` — make the `react` module take its directory as - configuration instead of a shim setting a working directory -- [ ] 6a.2 `osapi` — drop the tracked `.just/remote/react.mod.just` and its - `.gitignore` exception once the module is configurable +- [x] 6a.1 `osapi-justfiles` — the `react` module takes `react_dir` as + configuration and fails at parse time when a consumer omits it, rather than + relying on a shim to set a working directory +- [x] 6a.2 `osapi` — `.just/remote/react.mod.just` is gone and nothing under + `.just/` is tracked; `.gitignore` ignores `.just/remote/*` with no exception. + The root justfile sets `react_dir := "ui"` directly ## 7. Verification -- [ ] 7.1 Confirm every in-scope repository carries the required files -- [ ] 7.2 Confirm no repository still contains `docs/contributing.md` or - `docs/development.md` -- [ ] 7.3 Confirm no cross-repository link still points at the old paths -- [ ] 7.4 Confirm each README uses only vocabulary sections, in order -- [ ] 7.5 Confirm `LICENSE`, `AI_POLICY.md`, and `CODE_OF_CONDUCT.md` are - byte-identical everywhere +- [x] 7.1 Confirm every in-scope repository carries the required files. All + seven carry `README.md`, `LICENSE`, `AI_POLICY.md`, `CODE_OF_CONDUCT.md`, + `CONTRIBUTING.md`, `AGENTS.md`, `CLAUDE.md`, and `.mise.toml` +- [x] 7.2 Confirm no repository still contains `docs/contributing.md` or + `docs/development.md`. None does. `osapi` was the last, and its two remaining + copies under `ui/docs/` went with the conversion (osapi-io/osapi#450) +- [x] 7.3 Confirm no cross-repository link still points at the old paths. The + inbound links in `osapi`'s two architecture pages now point at the root + `CONTRIBUTING.md`, and the site builds with no broken link. One stale pointer + was found and fixed in the other direction: `osapi-orchestrator`'s `AGENTS.md` + still named the removed `docs/plans/` (osapi-io/osapi-orchestrator#74) +- [ ] 7.4 Confirm each README uses only vocabulary sections, in order. Not yet + established for the six non-exempt repositories. `osapi` is exempt from the + section set as the main product, and it gained `## 🤝 Contributing` so the new + root guide is reachable from it +- [x] 7.5 Confirm `LICENSE`, `AI_POLICY.md`, and `CODE_OF_CONDUCT.md` are + byte-identical everywhere. `AI_POLICY.md` and `CODE_OF_CONDUCT.md` are, in all + seven. `LICENSE` was not: `specs` carried a differently titled and differently + wrapped variant, which this change replaces with the canonical copy. The rest + differ only on the copyright year, as the requirement allows — 2024 for + `osapi`, 2025 for the two NATS libraries, 2026 for the rest - [ ] 7.6 Confirm no `.mise.toml` and no workflow floats a tool whose output a - check compares -- [ ] 7.7 Confirm `just test` locally and CI agree on every repository -- [ ] 7.8 Confirm every deprecated repository is archived on GitHub -- [ ] 7.9 Confirm no tracked file was removed on the basis of its path without - its content being read + check compares. Unresolved while 5.2 and 5.3 are: `go` is declared `1.25` + locally and `stable` in every workflow, and `go-fmt-check` compares its output +- [ ] 7.7 Confirm `just test` locally and CI agree on every repository. Not + established across all seven. The conversion ran `md-fmt-check`, + `docusaurus-fmt-check`, and `docusaurus-build` in `osapi` and `md-fmt-check` + in `osapi-orchestrator`; both pass +- [x] 7.8 Confirm every deprecated repository is archived on GitHub. + `osapi-sdk`, `osapi-ui`, and `osapi-io-taskfiles` all report archived +- [x] 7.9 Confirm no tracked file was removed on the basis of its path without + its content being read. Every file removed in osapi-io/osapi#450 was read + first, and that is what kept `ui/docs/architecture.md`: its path matched the + stale osapi-ui leftovers beside it, but its contents hold a component + reference the site does not carry