diff --git a/.codex/workspace.toml b/.codex/workspace.toml new file mode 100644 index 0000000..43b5e84 --- /dev/null +++ b/.codex/workspace.toml @@ -0,0 +1,7 @@ +[workspace] +name = "patch.moi" + +[[workspace.tasks]] +id = "harness-maintenance-fixture" +kind = "command" +command = ["bun", "run", "harness:flow"] diff --git a/.gitignore b/.gitignore index 9e47bf6..d03953e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ dist coverage *.log .env +/.codex/workspace/local/ data/ apps/*/data/ docs/out/ diff --git a/bun.lock b/bun.lock index 75ff09b..d9a868f 100644 --- a/bun.lock +++ b/bun.lock @@ -4,6 +4,9 @@ "workspaces": { "": { "name": "@peezy.tech/patch", + "devDependencies": { + "@peezy.tech/codex-flows": "^0.3.2", + }, }, "apps/patch": { "name": "@peezy.tech/patch", @@ -87,7 +90,7 @@ "@oxc-project/types": ["@oxc-project/types@0.130.0", "", {}, "sha512-ibD2usx9JRu7f5pu2tMKMI4cpA4NgXJQoYRP4pQ7Pxmn1l6k/53qWtQWZayhYy3X4QZkt90Ot+mJEaeXouio6Q=="], - "@peezy.tech/codex-flows": ["@peezy.tech/codex-flows@0.3.1", "", {}, "sha512-kUvNSkoVAhG8TLdRriK0FdW5h8xQOm4z/SpbY4Mjt21x6fyUzuLQNLvIKwPn5HKozfBOrkME0nEFLy9aAz8LIA=="], + "@peezy.tech/codex-flows": ["@peezy.tech/codex-flows@0.3.2", "", { "bin": { "codex-flows": "dist/cli/index.js" } }, "sha512-M98nt2+d0H4OEknAAQRnm/11Bxw49EP1oa+hoqVKcilQAdXwfQRPcDe4tVRoWVqiEOtwu22e8HGY2uH9vkx/0Q=="], "@peezy.tech/flow-runtime": ["@peezy.tech/flow-runtime@0.3.1", "", { "dependencies": { "@peezy.tech/codex-flows": "^0.3.1" } }, "sha512-uhctsitbz1AgDRTS8TcAVxVuTs7shuQ8dD7MH+pAAgY0KHv2A3A1h2KFA4ysoD7hBD/kA6ivLV6haVK4crh6Jw=="], @@ -869,6 +872,8 @@ "@apidevtools/json-schema-ref-parser/js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + "@peezy.tech/flow-runtime/@peezy.tech/codex-flows": ["@peezy.tech/codex-flows@0.3.1", "", {}, "sha512-kUvNSkoVAhG8TLdRriK0FdW5h8xQOm4z/SpbY4Mjt21x6fyUzuLQNLvIKwPn5HKozfBOrkME0nEFLy9aAz8LIA=="], + "@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], "hast-util-raw/parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], diff --git a/docs/pages/concepts/architecture.md b/docs/pages/concepts/architecture.md index 476dfdf..2c9f3cc 100644 --- a/docs/pages/concepts/architecture.md +++ b/docs/pages/concepts/architecture.md @@ -26,6 +26,8 @@ The current service has these runtime pieces: workspace dispatch records under `DATA_DIR`. - The workspace backend adapter can execute locally or call a configured Codex workspace backend, such as `codex-workspace-backend-local`. +- The optional repo-native `.codex/workspace.toml` exposes operator automation + tasks through `codex-flows workspace doctor|tick|run`. Those pieces are the intake layer. The patch-stack layer can run in local mode against a checkout, or in service mode through a remote forge workflow and @@ -90,3 +92,9 @@ See [Forge service mode](forge-service-mode). patch.moi owns update intake and maintenance orchestration. Local workspaces or forge runners own the actual patch application work. Release channels own deployment and publishing decisions. + +The repo-native Codex workspace config is an operator convenience for running +known maintenance commands from the repository. Its generated state under +`.codex/workspace/` is run history for that automation surface; it does +not replace `DATA_DIR` feed events, workspace dispatches, or maintenance +attempt records. diff --git a/docs/pages/concepts/flow-boundary.md b/docs/pages/concepts/flow-boundary.md index 5c86c79..ca1bc19 100644 --- a/docs/pages/concepts/flow-boundary.md +++ b/docs/pages/concepts/flow-boundary.md @@ -47,3 +47,17 @@ the Codex workspace backend where it fits. The rule is simple: use flow events for portable automation triggers, and use a patch.moi service for patch-stack product state: remote refs, workflow runs, pull requests, issues, checks, artifacts, and review status. + +## Repo-Native Workspace Automation + +`.codex/workspace.toml` is optional repo automation for operators. In this repo, +the first task is a manual command task that runs the existing harness fixture. +It does not change the patch.moi service path: feed intake still creates +deterministic `FlowEvent` records, dispatch and replay still go through the +patch.moi workspace backend adapter, and maintenance outcomes still sync into +patch.moi-owned attempt records. + +Avoid implicit workspace `kind = "flow"` tasks for patch.moi maintenance unless +the task supplies a complete explicit event. The default workspace flow fallback +does not carry patch.moi's deterministic `id` and `receivedAt`, which are part +of the dispatch and audit contract. diff --git a/docs/pages/reference/jsonl-state.md b/docs/pages/reference/jsonl-state.md index b250c9c..9bd8819 100644 --- a/docs/pages/reference/jsonl-state.md +++ b/docs/pages/reference/jsonl-state.md @@ -27,3 +27,11 @@ If a runner checkout is lost, patch.moi should be able to recreate the maintenance context from remote Git refs and forge records. JSONL state explains feed, attempt, and dispatch history; Git and the forge remain the source of truth for patch contents and review state. + +## Codex Workspace State + +`codex-flows workspace` commands write operator run state under +`.codex/workspace/`. Local state under `.codex/workspace/local/` is +ignored by Git. Actions state under `.codex/workspace/actions/` is reserved for +future CI or service use, where committing selected workspace state may be +intentional. diff --git a/docs/pages/tutorials/run-harness-maintenance-flow.md b/docs/pages/tutorials/run-harness-maintenance-flow.md index 948c9d6..a7294b0 100644 --- a/docs/pages/tutorials/run-harness-maintenance-flow.md +++ b/docs/pages/tutorials/run-harness-maintenance-flow.md @@ -23,7 +23,7 @@ The fork should have `origin`, `upstream`, and `jojo` remotes. The flow can add the configured upstream remote when it is missing, but it will not invent the fork or service remotes. -## 2. Run the fixture event +## 2. Run the fixture event directly ```bash CODEX_FLOW_FETCH=0 \ @@ -36,7 +36,25 @@ flow should skip rebase work, run `npm test` and `npm run pack:dry-run` in the fork, report `candidateRefs` for the maintained fork branch, and leave the fork checkout unchanged. -## 3. Rehearse a real upstream release +## 3. Run the fixture through workspace autonomy + +The repo also exposes the same fixture as a manual codex-flows workspace task: + +```bash +CODEX_FLOW_FETCH=0 \ +CODEX_FLOW_PUSH=0 \ +bun run workspace:run:harness +``` + +That task is defined in `.codex/workspace.toml` as a command task that runs +`bun run harness:flow`. It is intentionally unscheduled, so `bun run +workspace:tick` is safe by default and explicit `workspace run` remains the +operator action. + +Use `bun run workspace:doctor` to inspect the repo-native workspace config and +generated local run state. + +## 4. Rehearse a real upstream release Create a new upstream release in `harness/upstream`, then point the fixture or a feed event at the new tag: @@ -62,7 +80,7 @@ Use an event file whose `payload.tag` is the new upstream tag. The flow rebases `harness/fork` onto that tag, verifies the fork package, reports the local candidate branch, and keeps pushes off. -## 4. Push only after review +## 5. Push only after review When the local result is the maintained fork state you want: diff --git a/harness/README.md b/harness/README.md index bb9631a..f2894a7 100644 --- a/harness/README.md +++ b/harness/README.md @@ -110,9 +110,17 @@ flow: CODEX_FLOW_FETCH=0 CODEX_FLOW_PUSH=0 bun run harness:flow ``` -That direct command is local-mode execution. In the service shape, Patch writes -the upstream update event, creates a maintenance attempt record, and hands the -same flow event to the configured workspace backend. +That direct command is local-mode execution. The repo-native workspace autonomy +surface runs the same harness through a manual command task: + +```bash +CODEX_FLOW_FETCH=0 CODEX_FLOW_PUSH=0 bun run workspace:run:harness +``` + +The workspace task is unscheduled, so `bun run workspace:tick` should not run +the harness until a schedule is added. In the service shape, Patch writes the +upstream update event, creates a maintenance attempt record, and hands the same +flow event to the configured workspace backend. The default fixture targets `v0.1.3`, which should verify the current fork without changing it and report `candidateRefs` for the maintained fork branch. diff --git a/package.json b/package.json index 4e59972..15ad90a 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,12 @@ "docs:dev": "bun run --filter @peezy.tech/patch-docs dev", "harness:flow": "bun run --filter @peezy.tech/patch harness:flow", "start": "bun run --filter @peezy.tech/patch start", - "test": "bun run --filter @peezy.tech/patch test" + "test": "bun run --filter @peezy.tech/patch test", + "workspace:doctor": "codex-flows workspace doctor --workspace-root .", + "workspace:run:harness": "codex-flows workspace run harness-maintenance-fixture --workspace-root . --mode local", + "workspace:tick": "codex-flows workspace tick --workspace-root . --mode local" + }, + "devDependencies": { + "@peezy.tech/codex-flows": "^0.3.2" } }