Skip to content

[Air #1826] feat: Ship the owner decisions process with the Decisions tab - #1832

Merged
waleedkadous merged 8 commits into
mainfrom
builder/air-1826
Oct 19, 2026
Merged

waleedkadous merged 8 commits into
mainfrom
builder/air-1826

Conversation

@waleedkadous

@waleedkadous waleedkadous commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adopters get the Decisions tab (Spec 1819, PR #1820) in the next release but not the process or the file format it parses. This adds resources/decision-protocol.md, a scrubbed version of Shannon's owner decisions process, as the canonical description of codev/state/pending-decisions.md. The tab doc and the architect role now point to it.

Closes #1826

What Changed

  • codev-skeleton/resources/decision-protocol.md (new; byte-identical copy at codev/resources/decision-protocol.md). Shannon's sections 3, 4 (with 4b and 4c) and 5, renumbered 1–4 so the doc stands alone:
    1. Intake message: what an architect sends to the hub, afx send architect:main 'DECISION <id>: …', with the shell-quoting note.
    2. The item: the template, plus a "What the tab reads" list taken from servers/decisions/parse.ts, grammar.ts and stamp.ts, and a worked example.
    3. What the hub does: post, learn of rulings (now including Tower's RULED/QUESTION notice from tower: tell the hub architect when the owner submits a ruling from the Decisions tab #1828), relay, record, done. Then 3b (a ruling that carries a question comes back as a new item) and 3c (the owner's question gets the architect's answer pasted into the item as a You asked / <Name>'s answer pair).
    4. The file skeleton.
  • resources/commands/agent-farm.md, Decisions tab section, both trees: one paragraph linking ../decision-protocol.md.
  • roles/architect.md, both trees (still byte-identical): a three-line "The owner decisions file" section. It says what the file is and that main is the hub, and points to the doc.
  • Test: packages/codev/src/agent-farm/__tests__/decision-protocol-doc.test.ts.

Key Decisions

  • The format follows the parser, line by line (baked). The "What the tab reads" list states only what the code accepts:
    • ### items under exactly one ## Open; an item ends at the next #, ## or ### heading.
    • The heading is id · stamp · question.
    • Exactly one **Your word:** line.
    • Bare-word options take their description from the body's **Options:** entry, in the (a) \word` = …, (a) `word`: …and- `word` = …` forms; a description on the word line wins.
    • Q&A lines, with continuation indent.
    • Any text after the word line is the ruling, and the card then takes no submit.
  • Time zones (baked). Every heading stamp carries its zone, and the doc lists exactly what stamp.ts resolves: generic North-American zones, fixed abbreviations (CST = North-American Central), numeric offsets and IANA names. Ambiguous abbreviations, and times the clocks skipped or repeated, are shown as written and marked not converted. Nothing in the doc assumes PT. Every example time carries a zone, and a test enforces that.
  • Placement is resources/, not protocols/. The source itself says this is not a porch protocol, and a protocols/<name>/ directory would read as something you can spawn. It sits beside risk-triage.md.
  • Scrubbed from the source: all Shannon product names and incidents, its jargon table, its "what needs a word" list (sections 0/0b/0c/1/2 are out of the issue's scope), the PT clock rule, HTML-comment and <!-- REVIEW --> markers (left over from the annotation viewer), and the file-watch implementation details.
  • One inconsistency in the source, resolved toward later practice. §4 step 2 adds a **Ruling:** line under the word line and moves the item only on DONE. §6 and the Tower: a Decisions tab — a UI view of codev/state/pending-decisions.md with click boxes per option (recommended marked) and a comment box per decision, writing the owner's word back into the file #1819 issue body say a ruled item leaves ## Open at once. The doc follows the latter: on a ruling the hub relays it and moves the item to ## Ruled as one line. Both the relay and that line carry the owner's comment along with the word, and DONE appends → DONE <time> <zone>: <what happened> to the line later.
  • Kept from §6 only the rule about how the hub writes the file: as little as possible, re-read before each write, every time written with its zone.

Test Plan

  • Unit tests added. decision-protocol-doc.test.ts (15 tests) pulls the doc's own markdown blocks and runs them through the tab's code:
    • The file skeleton parses with no problems.
    • The template yields its options.
    • The worked example is one writable item. Its bare words get their descriptions from **Options:**, and its ET stamp converts to the right UTC instant.
    • A submit goes through spliceRuling, rulingNotice gives RULED web-4: retry with the comment, and the card is ruled afterwards. The doc's relay and ## Ruled forms both keep the comment.
    • A comment-only question blocks the card. Once the hub pastes the doc's 3c pair above the word line, the card is writable again and shows an answered thread.
    • A word typed on the line under **Your word:**, as the file's header says, rules the item; a word typed on the word line itself does not.
    • No time in the doc is PT-only or zoneless, every zone the doc names converts through stamp.ts, and the ambiguous abbreviations it names (IST, BST, AST) do not.
    • The two copies of the doc are identical, both agent-farm.md links resolve, and both architect roles name the doc.
  • Mutation check: dropping the example's zone and turning = into - in an **Options:** entry fails 5 tests. The doc was restored from its twin afterwards.
  • Build passes (pnpm build).
  • All tests pass: 318 files, 6,494 tests, 48 skipped.

Flaky Tests

Porch's first tests check failed, and its output was cut off before naming a test. The same suite then passed three times on the same commit: npx vitest run, npm test, and porch's re-run. Nothing in this PR touches runtime code, so the failure is unrelated; I couldn't identify the test.

CMAP

Codex and Claude reviewed via consult --type pr. Gemini was not run: the agy lane is known-broken for typed reviews, and .codev/config.json configures codex and claude only.

  • codex: REQUEST_CHANGES
    • Fixed: the file header said to rule "on" the **Your word:** line, but the tab reads only the lines under it, so a word typed on that line leaves the card open. The header now says "on the line under"; §3 says the hub scans "the lines under". A test pins both cases.
    • Fixed: the ## Ruled one-liner showed <what happened> before DONE supplied it. The relay line now ends at the word, and DONE is appended later.
    • Rebutted (size): the PR is over AIR's ~300 LOC, but it has 0 lines of runtime code. The length is the doc the issue asks for (~180 lines), its byte-identical mirror (two-trees rule) and its test (~170 lines). The issue fixes the scope, and trimming would mean dropping either required sections or the drift guard. Raised with the architect rather than cut silently.
  • claude: APPROVE, with four non-blocking notes:
    • Applied: a test pins every zone the doc names to stamp.ts.
    • Applied: §4 says creating the file is what makes the tab appear.
    • Applied: §3 says the Tower notice reaches only an architect named main, and that a hub without that name must scan the file.
    • Folded into the follow-up below: add resources/decision-protocol.md to UPDATABLE_PREFIXES.

Integration review (architect)

  • Applied: the owner's comment is now carried in the hub's RULING relay (verbatim, on the lines after it) and in the ## Ruled line (quoted after the word), so a conditional ruling keeps its condition.
  • Applied: the roles/architect.md section is trimmed to three lines that point to the doc.
  • Filed: scaffold: skeleton resources/*.md reference docs never reach adopter repos #1834, copying skeleton resources/*.md reference docs into adopter repos.

Review Notes

  • Size: about 175 lines of doc, mirrored once in the instance tree as the two-trees rule requires; about 150 lines of test; 22 lines of cross-references.
  • Gap left open (out of scope): skeleton resources/*.md files are not copied into adopter repos. They resolve only inside the installed package. The architect role names codev/resources/decision-protocol.md by path the same way it already names risk-triage.md, so in a fresh install an architect cannot open either at that path. The role section includes the essentials so it is usable without the file. Copying these into codev/resources/ on init/update, as is done for the hot tier, and adding them to UPDATABLE_PREFIXES, is now scaffold: skeleton resources/*.md reference docs never reach adopter repos #1834.

🤖 Generated with Claude Code

waleedkadous and others added 6 commits October 18, 2026 16:05
… 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 <noreply@anthropic.com>
- The file header now says to rule on the line under **Your word:**, which is
  what the tab reads; a word typed on the line itself leaves the card open.
- The ## Ruled line no longer names an outcome before DONE; DONE is appended.
- Say that creating the file makes the tab appear, and that Tower's notice
  reaches only an architect named main.
- Tests pin the hand-ruling instruction and every zone the doc names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@waleedkadous

Copy link
Copy Markdown
Contributor Author

Thank you — this is exactly the doc the tab needed, and the executable-doc test (the doc's own fenced examples run through parseDecisions, spliceRuling, rulingNotice and resolveStamp) is a pattern worth copying elsewhere. I verified the format claims against parse.ts/stamp.ts/notice.ts myself and they hold; twins are byte-identical; no adopter specifics leaked.

Two changes before merge, both small:

  1. The owner's comment is dropped on relay and in ## Ruled. rulingNotice delivers RULED <id>: <word> with the comment, but §3 step 3 relays only RULING <id>: <word> (owner, <time> <zone>) and the ## Ruled one-liner keeps only the word. A conditional ruling ("retry, but not until after the release") would lose its condition. Please carry the comment in both: append it to the relay message, and to the ## Ruled line (e.g. → `retry` — "not until after the release"). One clause each.

  2. Trim the roles/architect.md section. It's 9 lines on a ~98-line always-loaded role and restates the intake command and RULED format the doc already carries (Spec 1280 is pulling the other way). Three lines is enough: what the file is, that main is the hub, and a pointer to the doc.

Not for this PR, please file as a follow-up: resources/*.md (risk-triage.md, this doc) are not materialized into adopter repos on init/update and aren't in UPDATABLE_PREFIXES, so the role's codev/resources/decision-protocol.md path only resolves at tier 4. Generic fix, not per-file.

waleedkadous and others added 2 commits October 18, 2026 16:29
…hitect role section

- The hub's RULING relay carries the owner's comment verbatim, and the
  ## Ruled line quotes it after the word, so a conditional ruling keeps its
  condition. The doc test asserts both forms.
- roles/architect.md: three lines pointing at the doc instead of restating it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@waleedkadous
waleedkadous merged commit e7c4128 into main Oct 19, 2026
7 checks passed
waleedkadous added a commit that referenced this pull request Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

skeleton: ship the owner decisions process (decision-protocol.md) with the Decisions tab

1 participant