From a879474a7ab1062f3ae6220847db40c72439edab Mon Sep 17 00:00:00 2001 From: M Waleed Kadous Date: Sun, 18 Oct 2026 16:05:07 -0700 Subject: [PATCH 1/8] chore(porch): 1826 init air --- .../status.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 codev/projects/1826-skeleton-ship-the-owner-decisi/status.yaml diff --git a/codev/projects/1826-skeleton-ship-the-owner-decisi/status.yaml b/codev/projects/1826-skeleton-ship-the-owner-decisi/status.yaml new file mode 100644 index 000000000..af58bb4e2 --- /dev/null +++ b/codev/projects/1826-skeleton-ship-the-owner-decisi/status.yaml @@ -0,0 +1,14 @@ +id: '1826' +title: skeleton-ship-the-owner-decisi +protocol: air +phase: implement +plan_phases: [] +current_plan_phase: null +gates: + pr: + status: pending +iteration: 1 +build_complete: false +history: [] +started_at: '2026-10-18T23:05:06.935Z' +updated_at: '2026-10-18T23:05:06.936Z' From f4c854e420a0f0fd80b8991eededdf06d094c9e2 Mon Sep 17 00:00:00 2001 From: M Waleed Kadous Date: Sun, 18 Oct 2026 16:12:07 -0700 Subject: [PATCH 2/8] [Air #1826] feat: Ship the owner decisions process with the Decisions tab Add resources/decision-protocol.md to both trees: the intake message, the item format the Decisions tab parses (bare words described from **Options:**, stamps that carry their own zone), what the hub does, and the file skeleton. Link it from the Decisions tab section of agent-farm.md and from the architect role. A test runs the doc's own examples through the tab's parser, splice and notice. Co-Authored-By: Claude Opus 5.5 --- .../resources/commands/agent-farm.md | 2 + codev-skeleton/resources/decision-protocol.md | 178 ++++++++++++++++++ codev-skeleton/roles/architect.md | 9 + codev/resources/commands/agent-farm.md | 2 + codev/resources/decision-protocol.md | 178 ++++++++++++++++++ codev/roles/architect.md | 9 + codev/state/air-1826_thread.md | 27 +++ .../__tests__/decision-protocol-doc.test.ts | 155 +++++++++++++++ 8 files changed, 560 insertions(+) create mode 100644 codev-skeleton/resources/decision-protocol.md create mode 100644 codev/resources/decision-protocol.md create mode 100644 codev/state/air-1826_thread.md create mode 100644 packages/codev/src/agent-farm/__tests__/decision-protocol-doc.test.ts diff --git a/codev-skeleton/resources/commands/agent-farm.md b/codev-skeleton/resources/commands/agent-farm.md index 553200f4a..f42808ba9 100644 --- a/codev-skeleton/resources/commands/agent-farm.md +++ b/codev-skeleton/resources/commands/agent-farm.md @@ -936,6 +936,8 @@ Both are Tower-global (they apply to the whole Tower, not per-project) and optio When a workspace has a pending-decisions file, the dashboard shows a **Decisions** tab (Spec 1819). The tab is a view of that file. Each item under `## Open` becomes a card with a click box per option (the first option, the recommended one, is marked) and a comment box. Submitting writes the chosen word, then the comment, on the lines right after the item's `**Your word:**` line, exactly as the owner would type them, and changes nothing else. `## Ruled` is shown below as a collapsed, read-only list. The file is the only state. While the tab is open it re-reads the file every 2 seconds, so edits made elsewhere appear without a reload, and an unsent draft survives them. +The file's format and the process around it are in [`decision-protocol.md`](../decision-protocol.md): one hub architect, `main`, is the only agent that edits the file, other architects send it their items, and the hub relays each ruling. The tab reads exactly the item format that document describes. + The file is `codev/state/pending-decisions.md` unless `dashboard.decisionsFile` names another: ```json diff --git a/codev-skeleton/resources/decision-protocol.md b/codev-skeleton/resources/decision-protocol.md new file mode 100644 index 000000000..01b21840d --- /dev/null +++ b/codev-skeleton/resources/decision-protocol.md @@ -0,0 +1,178 @@ +# Owner decisions: one file, one hub + +How a workspace's owner and its architects make decisions through one markdown file, +`codev/state/pending-decisions.md`. The dashboard's **Decisions** tab is a view of that file: +see the Decisions tab section of [`commands/agent-farm.md`](commands/agent-farm.md). This is a +working agreement between people and agents, not a porch protocol; nothing is spawned from it. + +- **The owner** is the human whose word clears a gate, a merge, a spend or a product choice. +- **The hub** is one architect, named `main`. It is the only agent that edits the file. +- **Every other architect** sends its asks to the hub and acts on the ruling the hub relays. + +Anything that needs the owner's word goes through the file, one item per question. Status +reports and FYIs do not. + +## 1. The intake message (architect → hub) + +An architect sends the item as one message: + +```bash +afx send architect:main 'DECISION -: +' +``` + +The first line is `DECISION -: `; append ` [urgent]` only when a live user +or running work is blocked. Single-quote the message, because inside double quotes the shell +runs the item's backticks; write an apostrophe inside it as `'\''`. Ids are +`-` (`web-4`, `main-12`): each architect keeps its own counter +and never reuses a number. + +## 2. The item + +```markdown +### - · · + +- **Problem:** (or **Context:**) what is wrong or undecided, as the owner would see it. One to three sentences. +- **Root cause:** why, for a fix. +- **Options:** for a choice, (a) `` = what it does (b) `` = what it does. +- **Fix:** what the change does, in product terms. +- **Testing:** the receipt: tests before and after, a live check, checks green on the exact head. +- **Cost:** money or time, only when a budget is involved. +- **Recommendation ():** one line, owned by the architect. +- **Links:** pull request and issue URLs; spec, plan and receipt paths. + +**Your word:** `` / `` / `hold` +``` + +Delete labels that do not apply; never rename them. The hub bounces a malformed item back, +naming what is missing, and does not post it. + +### What the tab reads + +The Decisions tab parses the file by these rules. An item that follows them gets a click box +per option and a comment box. + +- **Items are the `###` headings under `## Open`.** An item runs to the next `#`, `##` or `###` + heading, so inside an item use `####` or bold labels, never a higher heading. The file has + exactly one `## Open`. +- **The heading is id · stamp · question.** The first word is the id; ` · ` (space, middle dot, + space) separates the id, the stamp and the question. Open items that share an id are + read-only until the ids differ. +- **The stamp carries its zone; nothing assumes one.** `YYYY-MM-DD h:mm am` (or `pm`), or 24-hour + `YYYY-MM-DD HH:mm`, then the zone the time was read in. The tab converts the stamp using only + that zone and shows it in the viewer's local time. It reads the North-American generic zones + `PT`, `MT`, `CT`, `ET`, `AKT` and `HT` (daylight saving follows the stamp's date), fixed + abbreviations such as `UTC`, `GMT`, `EST`/`EDT`, `CET`/`CEST`, `JST` and `AEST`/`AEDT` (`CST` + is North-American Central), offsets such as `+05:30`, `UTC+5:30` or `GMT-3`, and IANA names + such as `Europe/Berlin`. Any other zone, including ambiguous abbreviations such as `IST`, + `BST` and `AST`, is shown as written and marked not converted, as is a time the clocks + skipped or repeated that day. +- **Exactly one `**Your word:**` line**, starting a line, outside a code block. The options are + the backticked words on it, separated by ` / `. The first is the recommended one, and the tab + marks it. A description follows a word after ` = ` and runs to the next ` / ` before a + backtick: `` `retry` = keep the page / `signout` = sign out / `hold` ``. Other text on the + line is ignored. +- **A bare word takes its description from `**Options:**`.** A word written without ` = …` on + the word line is described by the body's `**Options:**` entry for the same word: ``(a) `word` = …`` + or ``(a) `word`: …`` after the label, or ``- `word` = …`` list items under it. A + description on the word line wins; a word with neither (`hold`) shows bare. +- **Questions and answers** are body lines above the word line, `- **You asked (