diff --git a/README.md b/README.md index 17dd50a..6c4833a 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ comma-separated allow list and defaults to `push,release`. ```bash bun install bun run check +bun run workspace:doctor bun run dev ``` @@ -74,6 +75,15 @@ configured workspace backend or local adapter, and record dispatch outcomes in patch.moi-owned `DATA_DIR/maintenance-attempts.jsonl` entry that links the upstream update to workspace run ids, final flow outcome, and candidate refs. +The harness can also be run through the repo-native workspace task: + +```bash +CODEX_FLOW_FETCH=0 CODEX_FLOW_PUSH=0 bun run workspace:run:harness +``` + +That task writes local operator run state under `.codex/workspace/local/`, +which is ignored by Git. Patch service state remains under `DATA_DIR`. + ## Documentation The publishable docs site is a Tome project in `docs/`: diff --git a/docs/pages/concepts/architecture.md b/docs/pages/concepts/architecture.md index 2c9f3cc..78499b3 100644 --- a/docs/pages/concepts/architecture.md +++ b/docs/pages/concepts/architecture.md @@ -1,100 +1,105 @@ --- title: Architecture -description: How upstream intake, Git state, forge service mode, workspaces, and release channels fit together. +description: How intake, Git state, workspaces, service mode, and release channels fit together. --- # Architecture +patch.moi is a maintenance control plane, not a replacement for the maintained +repository. Its architecture follows one rule: Git and the forge hold patch +truth; patch.moi holds operational truth. + +## Product Loop + patch.moi has three product responsibilities: 1. Notice upstream movement. 2. Start or resume the right maintenance workflow. -3. Keep enough durable state to inspect, retry, and review what happened. - -The Git repository remains the source of truth for the maintained project. -patch.moi does not replace remotes, branches, tags, commits, or release refs -with a separate project file. It reads those facts and records operational state -around them. - -## Runtime Pieces - -The current service has these runtime pieces: - -- The HTTP server exposes health and admin flow endpoints. -- The feed poller reads configured upstream feeds on an interval. -- The JSONL store keeps feed signals, flow events, maintenance attempts, and - 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 -runner. - -The first concrete repo to model against is `../codex`. Its maintained branch is -`code-mode-exec-hooks` in the Peezy fork, and the branch carries Code Mode and -Peezy npm release patches ahead of `origin/main`. - -## Maintenance Loop +3. Keep durable state for inspection, retry, replay, and review. ```mermaid flowchart TD - A["upstream release, tag, or branch update"] --> B["Patch FeedSignal"] - B --> C["durable update event"] - C --> D{"mode"} - D -- local --> E["local Codex workspace"] - D -- service --> R["remote forge workflow"] - R --> S["runner checkout"] - E --> F["rebase or replay patch commits"] - S --> F - F --> G{"conflicts or failing checks?"} - G -- yes --> H["PR, issue, or paused intervention"] - G -- no --> I["candidate branch or tag"] - I --> J["internal build channel"] - I --> K["public release channel"] + A["upstream release, tag, branch update, or advisory"] --> B["Patch FeedSignal"] + B --> C["durable FlowEvent"] + C --> D["maintenance attempt"] + D --> E{"execution surface"} + E -- local --> F["local workspace"] + E -- service --> G["forge runner"] + F --> H["rebase, merge, or replay patches"] + G --> H + H --> I{"blocked?"} + I -- yes --> J["intervention, PR, issue, or failed run"] + I -- no --> K["candidate branch, tag, check, or artifact"] + K --> L["internal build channel"] + K --> M["public release channel"] ``` +## Runtime Pieces + +The current service has these pieces: + +| Piece | Role | +| --- | --- | +| HTTP server | health, admin listing, retry, replay, sync, and workspace inspection endpoints | +| feed poller | reads configured upstream feeds and emits normalized signals | +| JSONL store | writes feed events, flow events, workspace dispatches, and maintenance attempts under `DATA_DIR` | +| workspace backend adapter | dispatches locally when no backend URL is set, or calls a configured Codex workspace backend | +| harness flow | exercises real fork maintenance through `flows/patch-moi-harness` | +| repo workspace config | exposes manual operator tasks through `codex-flows workspace doctor|tick|run` | + +Those pieces are intentionally narrow. The service coordinates and records; the +workspace or runner performs the patch application work. + +## State Boundaries + +patch.moi-owned state lives under `DATA_DIR`: + +- feed cursors and feed events +- deterministic flow events +- workspace dispatch, retry, and replay records +- maintenance attempts, outcomes, candidate refs, and intervention state + +Codex workspace state lives under `.codex/workspace/` and describes the +operator automation surface. Local workspace state is ignored. Actions state is +reserved for future CI or service use where committing selected state may be +intentional. + +Neither store contains the patch stack. Patch commits, branches, tags, and +candidate refs remain in Git and the forge. + ## Local Mode -In local mode, patch.moi can run inside or next to the maintained repository. -The repository itself describes the project: +Local mode is checkout-oriented. The operator has a real repository nearby, +with remotes and branches that describe the project: -- `upstream` or another configured remote points at the source project. -- `origin` or another fork remote points at the maintained fork. -- branch names identify the maintained patch stack and candidate refs. -- tags identify upstream release points and downstream release candidates. +- `upstream` or another configured remote points at the source project +- `origin` or another fork remote points at the maintained fork +- branch names identify the patch stack and candidate refs +- tags identify upstream release points and downstream release candidates -No `.patchmoi` file is required for that topology. +No `.patchmoi` project file is required. Repo-native files such as +`package.json`, `flow.toml`, CI workflows, and `.codex/workspace.toml` can +describe automation, but Git still describes the patch stack. ## Service Mode -In service mode, the forge is the coordination surface. For Codex maintenance, -patch.moi should interact with the remote fork host: +Service mode is forge-oriented. patch.moi should interact with the remote fork +host: -- create or update remote maintenance branches +- create or update maintenance branches - trigger forge workflows or runners -- open or update pull requests, issues, comments, checks, and artifacts -- record workflow run ids, branch names, and review links +- open or update pull requests, issues, checks, comments, and artifacts +- record workflow run ids, branch names, outcomes, and review links -The runner checkout is disposable. The durable project state is the remote fork, -its refs, and the forge records around the maintenance attempt. +Runner checkouts are disposable. Durable project state is the remote fork, its +refs, and forge records around the maintenance attempt. -For the Codex fork, service mode should be able to target a remote fork, fetch -OpenAI upstream refs in a runner, rebase `code-mode-exec-hooks`, and push a -candidate branch or `rust-v*` tag when policy allows. +See [Forge service mode](forge-service-mode) for the service shape. -See [Forge service mode](forge-service-mode). +## Boundary Rule -## Boundaries +Use flow events for portable automation triggers. Use patch.moi state for the +product lifecycle around those triggers: feed history, dispatch attempts, +workspace run ids, candidate refs, review status, and intervention state. -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. +See [Flow boundary](flow-boundary) for the layer-by-layer contract. diff --git a/docs/pages/concepts/codex-use-case.md b/docs/pages/concepts/codex-use-case.md index 542996f..d0ae76c 100644 --- a/docs/pages/concepts/codex-use-case.md +++ b/docs/pages/concepts/codex-use-case.md @@ -5,9 +5,9 @@ description: How patch.moi applies to Codex fork maintenance. # Codex Use Case -patch.moi watches GitHub OpenAI Codex branch and release feeds. Branch activity -can notify operators. Release activity can emit a generic `upstream.release` -flow event for codex-flow automation. +patch.moi watches OpenAI Codex branch and release feeds. Branch activity can +notify operators. Release activity can emit a deterministic `upstream.release` +flow event that starts Codex fork maintenance. The concrete local model is the neighboring `../codex` checkout: @@ -23,8 +23,8 @@ should add or confirm `https://github.com/openai/codex.git` before a release rebase. The Codex maintenance flow rebases the Peezy Codex fork patch stack onto a -canonical upstream release tag. That is a patch application workspace, not a -public release by itself. +canonical upstream release tag. That is a patch application workspace job, not +a public release by itself. Internal Codex use can track a fast-moving branch for local work. Public npm release can follow upstream release tags and trusted publishing. Those channels @@ -35,4 +35,6 @@ In service mode, the same Codex maintenance work can run through a forge runner: patch.moi creates or updates the remote maintenance branch, triggers the runner, and records the resulting branch, artifact, check, or PR. -See [Codex fork model](codex-fork-model) for the exact repo-derived model. +See [Codex fork model](codex-fork-model) for the exact repo-derived model and +[Workspaces and channels](workspaces-and-channels) for why maintenance, +internal use, and public release stay separate. diff --git a/docs/pages/concepts/flow-boundary.md b/docs/pages/concepts/flow-boundary.md index ca1bc19..4d8162d 100644 --- a/docs/pages/concepts/flow-boundary.md +++ b/docs/pages/concepts/flow-boundary.md @@ -1,63 +1,74 @@ --- title: Flow boundary -description: What patch.moi owns, what codex-flow owns, and where workspace backend orchestration belongs. +description: What patch.moi, codex-flows, workspace backends, runners, and release channels own. --- -# Flow boundary +# Flow Boundary -patch.moi owns upstream observation and patch-stack orchestration. It knows -about feed sources, update signals, maintained repositories, remote branches, -workflow runs, dispatch attempts, and operator-visible state. +patch.moi uses flow events to start portable work, but a flow event is not the +whole product model. The event says "this upstream thing happened." patch.moi +must still know which attempt handled it, which workspace runs were created, +which candidate refs appeared, and whether review or intervention is required. -codex-flow owns portable event execution. Flow packages match `FlowEvent.type` -and payload schema, run Bun or Code Mode steps, and emit `FLOW_RESULT`. - -The Codex workspace backend owns workspace control surfaces: app-server -pass-through, delegation, flow execution transport, workbench state, and the -HTTP/WebSocket protocol around those capabilities. patch.moi should use that -surface instead of redefining it. - -The boundary should stay narrow: +## Layer Contract | Layer | Owns | | --- | --- | -| patch.moi intake | feeds, source ids, feed state, update records | -| patch.moi orchestration | maintained repo selection, remote branch policy, workflow triggers, retry and review state | -| codex-flow | generic event matching, step execution, run state, `FLOW_RESULT` | -| codex workspace backend | workspace transport, app-server bridge, delegation, flow HTTP routes | -| local workspace or forge runner | git operations, conflict resolution, checks, candidate refs | -| release channel | deploy, publish, trusted publishing, rollback policy | +| patch.moi intake | feed sources, feed cursors, normalized update signals | +| patch.moi orchestration | deterministic events, dispatch/retry/replay records, maintenance attempts, candidate refs, review state | +| codex-flows and flow-runtime | event matching, payload schema checks, step execution, `FLOW_RESULT` | +| Codex workspace backend | app-server bridge, delegation, flow transport, backend run inspection | +| local workspace or forge runner | Git operations, conflict resolution, verification, candidate ref creation | +| release channel | internal artifacts, public publishing, rollout, rollback, trusted publishing policy | -## Flow Events Are Triggers +Keeping these layers separate lets patch.moi retry or replay a trigger without +pretending that the trigger itself contains the maintained fork lifecycle. -A generic `upstream.release` event is a good trigger. It should not become the -whole product model. +## Event Contract -patch.moi should be able to say: this upstream release produced this workflow -run, which produced this candidate branch, which was used by this internal build -or public release. A single flow event cannot hold that lifecycle cleanly. +For patch.moi-dispatched maintenance, `event.id` is the idempotency key. Feed +targets create deterministic ids such as: -## Service State +```text +patch::: +``` -A patch.moi service backend is useful when patch.moi needs to coordinate a -remote forge, human intervention, and operator surfaces. That backend can own -patch.moi-specific service state while still dispatching generic flow events to -the Codex workspace backend where it fits. +The event should include enough payload for a flow package or backend workspace +to identify the upstream update. The receiving workspace still reads Git and +forge state to discover the maintained branch, patch commits, candidate refs, +and current checks. -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. +## Workspace Backends + +When `PATCH_WORKSPACE_BACKEND_URL` is unset, patch.moi uses local flow +execution from the process working directory. When it is set to an HTTP or +WebSocket URL, patch.moi dispatches to that Codex workspace backend. In both +cases patch.moi writes its own dispatch and maintenance-attempt records under +`DATA_DIR`. + +Workspace backend run state is useful for inspection and sync. It is not the +authoritative patch.moi product state. ## 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. +the first task is a manual command task that runs the existing harness fixture: -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. +```bash +bun run workspace:run:harness +``` + +That task is deliberately `kind = "command"`, not an implicit workspace +`kind = "flow"` task. Released workspace flow fallback behavior must not be +treated as a source of patch.moi's deterministic `id`, `occurredAt`, or +`receivedAt`; a future flow task must supply a complete explicit event. + +The sibling `../codex-flows` workspace currently has an unreleased fix that +synthesizes those event fields for workspace-owned flow tasks. patch.moi should +not rely on that behavior until it is available in a published +`@peezy.tech/codex-flows` release, and it should not use workspace-generated +event ids for feed-owned maintenance attempts. + +The generated local state under `.codex/workspace/local/` is run history for +the operator automation surface. It does not replace `DATA_DIR` feed events, +workspace dispatches, or maintenance attempts. diff --git a/docs/pages/concepts/git-source-of-truth.md b/docs/pages/concepts/git-source-of-truth.md index 265d4f9..023e058 100644 --- a/docs/pages/concepts/git-source-of-truth.md +++ b/docs/pages/concepts/git-source-of-truth.md @@ -6,13 +6,15 @@ description: Why patch.moi uses remotes, branches, tags, and commits as the proj # Git Source Of Truth patch.moi should not invent a second project format for patch stacks. The -maintained repository is already the best source of truth: +maintained repository and its forge records are already the best source of +truth: - remotes say where upstream and the maintained fork live - branches say which patch stack is being maintained - tags say which upstream or downstream release point is being targeted - commits are the patch inventory -- worktrees, checkouts, and runner workspaces are disposable execution surfaces +- worktrees, local workspaces, and runner checkouts are disposable execution + surfaces This matters because patch.moi is meant to maintain open source forks, not hide them behind an application database. @@ -44,13 +46,15 @@ patch.moi stores operational state: - retry and replay history - operator-facing notes or intervention state -That state explains what happened. It is not the patch stack itself. +That state explains what happened. It is not the patch stack itself, and it +does not replace workspace backend run state or forge records. ## Local Mode When patch.moi runs locally, the current checkout can be the project model. The -CLI or service process should inspect remotes and branches, then add missing -remotes only when the operator confirms or supplied enough information. +service, harness flow, or repo-native workspace command should inspect remotes +and branches, then add missing remotes only when the operator confirms or +supplied enough information. The default happy path is: @@ -103,5 +107,6 @@ Some policy cannot be inferred from refs alone: - whether public release uses GitHub trusted publishing That policy can live in service configuration, environment, codex-flow config, -or existing repo-native files such as `package.json`, CI workflows, `Makefile`, -or release docs. It should not obscure where the patch stack actually lives. +or existing repo-native files such as `package.json`, `.codex/workspace.toml`, +CI workflows, `Makefile`, or release docs. It should not obscure where the +patch stack actually lives. diff --git a/docs/pages/concepts/workspaces-and-channels.md b/docs/pages/concepts/workspaces-and-channels.md index e0489d0..5194d13 100644 --- a/docs/pages/concepts/workspaces-and-channels.md +++ b/docs/pages/concepts/workspaces-and-channels.md @@ -22,8 +22,8 @@ does not decide how to deploy or publish the maintained fork. A patch application workspace is the disposable place where a specific upstream point is carried forward into the maintained patch stack. In local mode, that -can be a Codex workspace near the checkout. In service mode, it should usually -be a forge runner checkout. +can be a checkout run directly or through Codex workspace tooling. In service +mode, it should usually be a forge runner checkout. Typical work: @@ -35,7 +35,8 @@ Typical work: - produce a candidate branch or tag The workspace may be local or runner-managed. The patch stack itself still lives -in Git. +in Git. Repo-native `codex-flows workspace` tasks are operator automation for +running known commands; they are not a separate patch-stack database. In the current Codex fork, this means carrying the commits on `code-mode-exec-hooks` ahead of `origin/main` onto a canonical upstream release @@ -108,3 +109,6 @@ flowchart LR patch.moi should record the relationship between those outcomes without forcing one channel to depend on another. + +See [Flow boundary](flow-boundary) for how feed events, workspace runs, and +maintenance attempts stay separate. diff --git a/docs/pages/guides/configure-feed-sources.md b/docs/pages/guides/configure-feed-sources.md index 676ac96..ac8b0bd 100644 --- a/docs/pages/guides/configure-feed-sources.md +++ b/docs/pages/guides/configure-feed-sources.md @@ -9,7 +9,8 @@ Feed sources live in a JSON file referenced by `FEED_SOURCES_PATH`. The bundled file is `apps/patch/feed-sources.json`. Feed sources describe intake. They should not duplicate the maintained patch -stack. The patch stack lives in Git as remotes, branches, tags, and commits. +stack. The patch stack lives in Git as remotes, branches, tags, and commits; +patch.moi records the operational state around feed events and dispatches. ## Choose an event @@ -48,5 +49,9 @@ For patch-stack maintenance, prefer `workspace_flow` to create an `upstream.release` or `upstream.update` trigger. Let the receiving workspace read Git to discover the maintained patch branch and candidate refs. +Use explicit payload fields for patch.moi-dispatched events. Do not rely on +implicit workspace flow defaults for maintenance events, because patch.moi uses +deterministic ids and timestamps for dispatch and replay. + Set `primeOnly: false` only when old feed entries should be emitted on the first poll. diff --git a/docs/pages/guides/run-patch-locally.md b/docs/pages/guides/run-patch-locally.md index 32b9692..ddacbd0 100644 --- a/docs/pages/guides/run-patch-locally.md +++ b/docs/pages/guides/run-patch-locally.md @@ -46,6 +46,7 @@ Root scripts delegate into the workspace: bun run check bun run test bun run docs:dev +bun run workspace:doctor ``` Use explicit paths when you run the app package directly: @@ -62,6 +63,16 @@ workspace backend URL is set. That makes local mode useful for testing a patch application workspace before sending the same event to a configured workspace backend or service runner. +The repo-native workspace task runs the harness fixture through the same direct +flow command: + +```bash +CODEX_FLOW_FETCH=0 CODEX_FLOW_PUSH=0 bun run workspace:run:harness +``` + +That task writes local run state under `.codex/workspace/local/`, which is +ignored by Git. + Local mode is checkout-oriented. Service mode is forge-oriented: patch.moi should talk to the remote forge, trigger a runner, and let that runner perform the disposable checkout and patch application work. diff --git a/docs/pages/index.md b/docs/pages/index.md index 119b730..8d942a3 100644 --- a/docs/pages/index.md +++ b/docs/pages/index.md @@ -1,60 +1,100 @@ --- title: patch.moi -description: Hands-off maintenance for custom patches on top of upstream open source software. +description: Git-first maintenance for custom patches on top of upstream open source software. --- # patch.moi -patch.moi keeps custom features alive on top of upstream open source projects. -It watches upstream movement, records durable update signals, and hands the -actual patch work to local workspaces or remote forge runners that operate on -normal Git repositories. +patch.moi watches upstream projects and keeps the operational record for +maintained forks. It does not replace Git, CI, or release tooling. It records +what upstream did, starts or resumes the right maintenance work, and preserves +enough state to inspect, retry, replay, and review the result. -The product boundary is Git-first: +The patch stack remains ordinary Git: -- Upstream projects stay upstream remotes, tags, branches, and release feeds. -- Maintained forks stay fork remotes and patch branches. -- Patch stacks are commits, branches, and tags, not a second Patch-specific - project file. -- patch.moi records observations, maintenance attempts, workspace run ids, and - review state around those Git facts. -- Local Codex workspaces or forge runners do the maintenance work: rebase patch - commits, resolve conflicts, build candidates, and leave human intervention - points when needed. +- upstream movement comes from feeds, remotes, tags, branches, and commits +- maintained forks live in fork repositories and patch branches +- patch commits stay in the maintained repository +- candidate outputs are branches, tags, pull requests, checks, or artifacts +- internal build and public release channels consume candidate refs separately ```mermaid flowchart LR - Upstream["upstream repo"] --> Feed["release and branch feeds"] - Upstream --> Git["upstream remote"] - Fork["maintained fork"] --> Git - Feed --> Patch["patch.moi intake"] - Patch --> Event["durable update signal"] - Event --> Workspace["local workspace or forge runner"] - Git --> Workspace - Workspace --> Candidate["remote candidate branch, tag, or artifact"] - Candidate --> Internal["internal build channel"] - Candidate --> Public["public release channel"] + Upstream["upstream feed or ref"] --> Patch["patch.moi intake"] + Patch --> Event["durable update event"] + Event --> Attempt["maintenance attempt"] + Attempt --> Workspace["local workspace or forge runner"] + Git["upstream and fork Git refs"] --> Workspace + Workspace --> Candidate["candidate ref or artifact"] + Candidate --> Internal["internal channel"] + Candidate --> Public["public release"] ``` -## Start here +## Ownership -- New service setup: [Watch an upstream release](tutorials/watch-upstream-release). -- Codex patch-stack automation: [Dispatch a Codex release flow](tutorials/dispatch-codex-release-flow). -- Running the service: [Run Patch locally](guides/run-patch-locally). -- Git model: [Git source of truth](concepts/git-source-of-truth). -- Concrete Codex model: [Codex fork model](concepts/codex-fork-model). -- Service mode: [Forge service mode](concepts/forge-service-mode). -- Release channels: [Workspaces and channels](concepts/workspaces-and-channels). -- Exact feed shape: [Feed sources](reference/feed-sources). -- Admin operations: [HTTP API](reference/http-api). +patch.moi owns product state around the patch stack: -## What is in this repo +- feed cursors and normalized update signals +- deterministic flow events +- workspace dispatch, retry, and replay records +- maintenance attempts, candidate refs, outcomes, and intervention state +- admin inspection APIs for that state -- `apps/patch`: the Patch Bun service, feed poller, JSONL store, and workspace - backend adapter. -- `docs`: this Tome documentation site, organized with the Diataxis framework. -- `Dockerfile`: container image for the Patch service app. +Execution surfaces own the work itself: -The current service implements upstream intake and dispatch. Patch-stack -maintenance is performed by the local workspace, forge runner, or codex-flow -package that receives the event. +- codex-flow packages match events and run portable Bun or Code Mode steps +- Codex workspace backends provide app-server, delegation, and flow transport +- local workspaces and forge runners fetch, rebase, verify, and push candidates +- release channels publish or deploy after review and policy gates + +`.codex/workspace.toml` is repo-native operator automation. In this repo it +exposes the harness fixture through `codex-flows workspace doctor|tick|run`. +That state lives under `.codex/workspace/` and does not replace +patch.moi-owned `DATA_DIR` records. + +## Fastest Path + +Install and run the checks: + +```bash +bun install +bun run check +``` + +Run the harness directly: + +```bash +CODEX_FLOW_FETCH=0 CODEX_FLOW_PUSH=0 bun run harness:flow +``` + +Run the same harness through repo-native workspace autonomy: + +```bash +bun run workspace:doctor +CODEX_FLOW_FETCH=0 CODEX_FLOW_PUSH=0 bun run workspace:run:harness +``` + +Start the Patch service when you want feed intake and admin state: + +```bash +DATA_DIR=./data FEED_SOURCES_PATH=./feed-sources.json bun run --filter @peezy.tech/patch dev +``` + +## Read Next + +- First harness run: [Run the harness maintenance flow](tutorials/run-harness-maintenance-flow). +- Feed intake: [Watch an upstream release](tutorials/watch-upstream-release). +- System model: [Architecture](concepts/architecture). +- Durable state: [JSONL state](reference/jsonl-state). +- Retry and replay: [Flow event retry and replay](reference/dispatch-and-replay-flow-events). +- Codex-specific model: [Codex fork model](concepts/codex-fork-model). +- Service runner shape: [Forge service mode](concepts/forge-service-mode). + +## Repository Layout + +- `apps/patch`: Patch service, feed poller, JSONL store, admin API, Discord + output, and workspace backend adapter. +- `flows/patch-moi-harness`: executable maintenance flow for the harness repos. +- `harness`: upstream and maintained fork repositories used for rehearsal. +- `.codex/workspace.toml`: optional repo-native workspace automation config. +- `docs`: this Tome documentation site. diff --git a/docs/pages/reference/packages.md b/docs/pages/reference/packages.md index 0bd2f3b..8f23c7d 100644 --- a/docs/pages/reference/packages.md +++ b/docs/pages/reference/packages.md @@ -29,3 +29,32 @@ The Tome documentation package in `docs`. Build it with: ```bash bun run docs:build ``` + +## Root Workspace + +The repository root owns shared scripts and dev dependencies. It installs +`@peezy.tech/codex-flows` so repo-native workspace commands are available: + +```bash +bun run workspace:doctor +bun run workspace:tick +bun run workspace:run:harness +``` + +Those commands are operator automation around the repo. They do not replace the +Patch service package or its `DATA_DIR` state. + +## Related Runtime Packages + +These published packages define the current patch.moi integration baseline: + +| Package | Published version | patch.moi use | +| --- | --- | --- | +| `@peezy.tech/codex-flows` | `0.3.3` | repo-native workspace commands and CLI automation | +| `@peezy.tech/flow-runtime` | `0.4.0` | local flow discovery, matching, execution, and Bun flow helpers | +| `@peezy.tech/flow-backend-convex` | `0.4.0` | optional generic durable flow backend for future service experiments | + +patch.moi product state still belongs in the Patch service JSONL store by +default. `flow-backend-convex` should be considered only when patch.moi needs a +generic durable flow event/run backend; it is not the default home for feed +signals, workspace dispatch records, or maintenance attempts. diff --git a/docs/pages/tutorials/dispatch-codex-release-flow.md b/docs/pages/tutorials/dispatch-codex-release-flow.md index 1efc4fb..c1b8090 100644 --- a/docs/pages/tutorials/dispatch-codex-release-flow.md +++ b/docs/pages/tutorials/dispatch-codex-release-flow.md @@ -5,9 +5,10 @@ description: Connect the OpenAI Codex release feed to a Codex patch-stack mainte # Dispatch a Codex release flow -This tutorial connects upstream OpenAI Codex releases to the Codex fork -maintenance flow. The flow rebases a maintained patch stack onto an upstream -release tag and verifies the candidate. +This tutorial connects upstream OpenAI Codex releases to Codex fork +maintenance. Patch records the upstream release and dispatches a deterministic +event. The receiving workspace or runner rebases the maintained patch stack +onto the upstream release tag and verifies the candidate. ## 1. Use the release source @@ -48,6 +49,9 @@ or its `/events` endpoint. Patch normalizes either HTTP form before calling the workspace flow capability. `PATCH_FLOW_BACKEND_URL` and `PATCH_FLOW_DISPATCH_URL` remain accepted for older feed targets. +Leave `PATCH_WORKSPACE_BACKEND_URL` unset only when you intentionally want local +flow execution from the Patch process working directory. + ## 3. Inspect the stored event ```bash @@ -57,7 +61,7 @@ curl http://127.0.0.1:3000/flow-events When `PATCH_ADMIN_TOKEN` is set, include either `Authorization: Bearer ` or `X-Patch-Admin-Token: `. -## 4. Keep completion app-owned +## 4. Keep completion workspace-owned, state app-owned Patch dispatches the generic event. The installed Codex release flow or workspace owns the work that happens next: @@ -69,6 +73,10 @@ workspace owns the work that happens next: - run the configured checks - optionally push a candidate ref +Patch remains responsible for maintenance-attempt state: it stores the dispatch, +can retry or replay the event, and can sync workspace run results back into the +attempt record. + That candidate can be used for an internal build/link workflow before a public release exists: build the local native binary, place it in the npm wrapper's vendor layout, and link the package with Bun. Public npm publishing should stay diff --git a/docs/pages/tutorials/run-harness-maintenance-flow.md b/docs/pages/tutorials/run-harness-maintenance-flow.md index a7294b0..5e4a004 100644 --- a/docs/pages/tutorials/run-harness-maintenance-flow.md +++ b/docs/pages/tutorials/run-harness-maintenance-flow.md @@ -7,9 +7,16 @@ description: Use the patch.moi harness repos to rehearse an upstream release and This tutorial runs the smallest real patch.moi maintenance loop. The upstream repo is `harness/upstream`. The maintained fork is `harness/fork`. The flow -package is `flows/patch-moi-harness`. It is the local version of the same work -a configured workspace backend would run after Patch accepts an upstream update -event. +package is `flows/patch-moi-harness`. + +There are two local operator paths: + +- run the flow directly with `bun run harness:flow` +- run the same flow through the repo-native `codex-flows workspace` task + +Both paths exercise the harness. The Patch service path still starts with feed +intake, writes `DATA_DIR` records, creates a maintenance attempt, and dispatches +the same kind of event through the workspace backend adapter. ## 1. Check out the harness repos @@ -52,7 +59,7 @@ 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. +generated local run state. The generated local state is ignored by Git. ## 4. Rehearse a real upstream release @@ -76,9 +83,10 @@ Run the harness flow again without disabling fetch: bun run harness:flow ``` -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. +Use an event file whose `id`, `occurredAt`, `receivedAt`, and `payload.tag` +identify 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. ## 5. Push only after review diff --git a/docs/pages/tutorials/watch-upstream-release.md b/docs/pages/tutorials/watch-upstream-release.md index 5fee124..eae4d78 100644 --- a/docs/pages/tutorials/watch-upstream-release.md +++ b/docs/pages/tutorials/watch-upstream-release.md @@ -5,9 +5,10 @@ description: Configure a release feed and turn an upstream release into patch ma # Watch an upstream release -This tutorial creates the smallest useful patch.moi intake: one upstream release -feed that becomes a stored update signal. That signal can later start a Codex -workspace that rebases a patch stack. +This tutorial creates the smallest useful patch.moi service path: one upstream +release feed becomes a stored update signal, a deterministic flow event, a +workspace dispatch, and a maintenance attempt record. The patch application work +still happens in a local workspace, workspace backend, or forge runner. Before configuring the feed, make sure the maintained repository has a Git source of truth: @@ -52,8 +53,9 @@ Create or edit `apps/patch/feed-sources.json`: } ``` -The target emits a generic `upstream.release` event. The event is a trigger for -patch work; the patch commits still live in the maintained Git repository. +The target emits a generic `upstream.release` event with a patch.moi-generated +id. The event is a trigger for patch work; the patch commits still live in the +maintained Git repository. ## 2. Start patch.moi @@ -94,3 +96,7 @@ A matching codex-flow package or backend workspace can consume the Internal builds and public release jobs can then consume the candidate ref independently. + +For a local rehearsal before wiring feed intake, use the harness tutorial. It +shows both the direct `bun run harness:flow` path and the repo-native +`bun run workspace:run:harness` path.