Conversation
Adds a nondominium-review skill under pai/, distributed by the existing nix pipeline to .claude/, .cursor/ and .agents/ so any collaborator's assistant runs the same procedure. It routes to REVIEW.md and CONTRIBUTING.md rather than restating them, matching the nondominium-domain skill's discipline. Adds an advisory lint workflow reporting rustfmt status, documents the two sources a skill can come from, and corrects the await_consistency call shape in REVIEW.md, which named a signature that does not compile.
continue-on-error keeps the workflow green but still marks the job failed, so every PR showed a red X and gh pr checks reported a failure. Our own review procedure treats a failing check as a merge blocker, so the advisory job was blocking reviews it was never meant to gate. The job now always exits 0 and the blocking form is one commented line away.
The governing question when resolving is which side carried semantic intent and which only restated it. Presentational changes yield to semantic ones, a conflict where both sides are semantic is a decision between two authors rather than a merge mechanic, and a resolution is backed by evidence instead of asserted. Names what counts as fundamental here (REQ meaning, enforced validation, VF field names, NDO layer boundaries) and the two hotspots the open branches actually conflict on. The integrity enum case is the rule at its sharpest: hdk_entry_types derives indices from declaration order, so tidying the enum while resolving invalidates every entry already on the DHT. The review skill now treats conflict resolution as its own check.
pai/shared/ now holds everything that describes the project: conventions, rules (was cursor-rules/, whose content was never Cursor-specific), and skills (was claude/skills/, though every skill already fanned out to .claude/, .cursor/ and .agents/). pai/harnesses/ holds only what one tool needs of its own, which today is Claude Code's settings.json. Cursor gets no directory because its adapter is a pure transform in nix/cursor-pai.nix. The test for where a file belongs: would its content change if we dropped support for a tool? If no, it is shared. Adds bun run pai:sync for the inner loop. Nix flakes only see git-tracked files, so a new skill silently does not materialize until it is committed; this copies pai/shared/skills/ from the working tree so an uncommitted edit is visible immediately. Nix stays the authority: it owns the pinned flake inputs and is what CI runs. Also removes the pai/README.md description of a LoadProjectDocs.hook.ts SessionStart hook. No such hook exists and settings.json wires none; the @ mentions in .rules are the whole mechanism. The docs described a second injection path that was never built.
A slash command any contributor gets from the repo itself, with nothing installed from anywhere else. It is deliberately thin: it points at the shared nondominium-review skill and adds no judgement of its own, so the procedure a reviewer follows does not depend on which editor they opened. Lives under pai/harnesses/claude/ because /name is a Claude Code mechanism rather than a portable one. The existing rsync copies the whole harness tree, so a command needs no flake.nix change. If a general-purpose review skill is installed on the machine, the command tells it to contribute forge mechanics only: the check order and the verdict shape stay the project's. A review that silently applied another repo's conventions is the thing this is meant to prevent.
The previous commit claimed /name was a Claude Code mechanism and gave Cursor nothing. That was wrong. In Cursor, skills ARE the slash-command mechanism: typing / lists the skills in .cursor/skills/ and .agents/skills/ and attaches the chosen one. Cursor has no .cursor/commands/ directory. So the portable command is the skill, which we already distribute to all three trees, and Claude Code is the single harness needing an adapter file because its /name reads .claude/commands/ instead. Tibi already had the command in Cursor; what was missing was saying so. CONTRIBUTING.md now gives the invocation per tool, and pai/README.md explains why one harness needs a file and the others do not.
pai/human_ai_collaboration.md arrived from #132 at the pai/ root. It reads as harness-agnostic, so pai/shared/ is the likely home, but it is Tibi's document and moving it as a side effect of this refactor is his call to make, not mine.
Soushi888
force-pushed
the
chore/shared-review-workflow
branch
from
August 30, 2026 01:02
5fc7d3c to
993a38d
Compare
Found by running /nondominium-review against this PR: every commit here uses a pai scope that the CONTRIBUTING.md scope list does not declare, so the procedure's own merge-criteria check failed on the branch introducing it. Adding the scope rather than renaming the commits, since pai/ is a real area of the repo now.
It arrived from #132 at the pai/ root, which the new structure does not use. The content is harness-agnostic reference material, so it classifies as shared by the same test as everything else there: its content would not change if we dropped support for a tool. Move only, no edits to the document. Nothing referenced the old path except the README note now replaced by the listing. Authorised by @Soushi888.
Soushi888
force-pushed
the
chore/shared-review-workflow
branch
from
August 30, 2026 01:28
5b1ba9b to
adafe0b
Compare
pai/nondominium.code-workspace is the last thing at the pai/ root. Listed rather than moved: editors resolve a workspace file by its path, so it is not ours to relocate for tidiness. The diagram now shows everything that is actually there, which is the point of a diagram.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Our review workflow works, but its method is not legible to anyone but the person running it. That is a fair objection independent of trust: a step that gates a merge should be something either maintainer can read and run, not a judgement whose procedure lives in one person's own tooling.
This makes the review procedure a repo artifact, adds the conflict-resolution rule we were missing, and cleans up
pai/so shared content and per-tool packaging stop being tangled.Changes
1. A shared review procedure
pai/shared/skills/nondominium-review/defines the order the sixREVIEW.mdareas get walked, theCONTRIBUTING.mdmerge criteria, the conflict-resolution check, and a fixed verdict block (APPROVE/CHANGES REQUESTED/BLOCKED) with per-area results, so two reviewers produce comparable output. It restates nothing:REVIEW.mdstays the single home for what gets flagged.Invocable as
/nondominium-reviewon every tool we use, with nothing installed from anywhere else:/, picknondominium-review. Skills are Cursor's slash-command mechanism; the skill lands in.cursor/skills/and.agents/skills/./nondominium-review [PR], from.claude/commands/..agents/skills/is the command.One rule in it has already cost us something: no approval while the pipeline is running. Our CI stages are chained, so early green says nothing about
e2e. An approval posted on partial green had to be retracted on #132. That is now written down rather than remembered.2. Merge conflict resolution policy (
CONTRIBUTING.md)The governing question is which side was trying to change meaning, and which was only trying to restate it. Presentational changes yield to semantic ones, always. When both sides are semantic it is a decision between two authors, not a merge mechanic. A resolution is backed by evidence (the Sweettest target passes, or the resolved doc is re-read against its
REQ-*), not asserted.Names what counts as fundamental here:
REQ-*meaning, enforced validation and permitted state transitions, Valueflows field names, NDO layer boundaries.The sharpest case is in the hotspot table:
#[hdk_entry_types]derives type indices from declaration order, so tidying an integrity enum alphabetically while resolving invalidates every entry already on the DHT. The cosmetically nicer resolution is the one that breaks the data.3.
pai/split into shared sources and harness adapterspai/shared/holds everything describing the project:conventions.md,rules/(wascursor-rules/, whose content was never Cursor-specific), andskills/(wasclaude/skills/, though every skill already fanned out to all three trees).pai/harnesses/holds only what one tool needs of its own, today Claude Code'ssettings.jsonandcommands/. Cursor gets no directory because its adapter is a pure transform innix/cursor-pai.nix.The test for where a file belongs: would its content change if we dropped support for a tool? If no, it is shared.
4. Supporting changes
.github/workflows/lint.ymlreports rustfmt status on every PR. Non-blocking on purpose, explained below.bun run pai:synccopiespai/shared/skills/from the working tree for the inner loop. Nix only sees git-tracked files, so a new skill silently does not materialize until committed, and nothing errors. Nix stays the authority; this is for iteration.pai/README.mdrewritten for the new structure. It also removes a description of aLoadProjectDocs.hook.tsSessionStart hook: a full section, two diagrams and a file-map entry for a file that does not exist and thatsettings.jsonnever wired. The@mentions in.rulesare the whole mechanism.REVIEW.md§4 correction. It told reviewers to check forawait_consistency(&[&cell_a, &cell_b]). That does not compile: 0.6.0 needs the timeout wrapper and the array by value.CONTRIBUTING.mdCI section corrected. It said tests were "non-blocking while the test suite is being stabilized", which stopped being true oncesweettestande2ebecame chained required jobs.Decisions
cargo fmt --checkcontinue-on-error: trueon the lint jobgh pr checksreports a failure. Our own review procedure treats a failing check as a merge blocker, so the advisory job would have blocked reviews it was never meant to gate. The step now always exits 0.cargo clippyhereREVIEW.md..cursor/commands/; skills are its slash-command surface, and we already distribute there.pai/human_ai_collaboration.mdat thepai/rootpai/shared/with no edits to the document. @TiberiusB, say the word if you want it elsewhere.pai/nondominium.code-workspaceHow to test
Then run
/nondominium-review 143on this PR and check the verdict block renders.Note that nix only sees git-tracked files, so a locally added skill must be committed before
nix developpicks it up.Documentation
pai/README.md— rewritten: architecture, per-tool invocation, two skill sources, the one-home rule, editing workflowCONTRIBUTING.md— review procedure and invocation table, merge conflict policy, corrected CI description, updated source tableREVIEW.md— content/procedure split noted; §4 signature correctedpai/shared/skills/nondominium-review/SKILL.md— newRelated
chore/rustfmtto clear the formatting backlog, then makelint.ymlblockingsweettest (person)flaked on run 33278757427 (get_hrea_agents_returns_matching_rea_agent,person_create_populates_hrea_agent_hash, both panicking in holochain'ssweet_conductor_handle.rs). The same job passed on an earlier run against identical Rust; every commit here is markdown, nix and config. Worth its own issue: a flaky gate is the first thing that will make someone override the wait-for-green rule.pai/human_ai_collaboration.mdmoved intopai/shared/(move only, no content edits)