cqx
cqx / APS
APS 1publishedissue #1

APS 1 — how cqx makes decisions

Authors

samifouad

Created

Sep 20, 2026

Updated

Sep 23, 2026

Discussion

2 replies

The problem

cqx has made a lot of decisions already and none of them are written down anywhere a second person could find. Why the score is five categories and not one number. Why a rule's level is derived from what it cost rather than from its weight. Why the explorer and the profile are two shells and not one with a flag. Every one of those is defensible, and every one of them currently exists as a paragraph in a chat window that no longer opens.

That is survivable while there is one person. It stops being survivable the moment there is a second, and it is already costing us: the same argument gets had twice because the first time left no artefact.

What we could do

Nothing. Keep deciding in chat and in commit messages. Commit messages are genuinely good at this — they have an author, a date and a diff. What they are bad at is being found, and being argued with before the code exists.

A docs folder. Cheap, and it rots, because nothing forces the folder to agree with what was built and nothing records who disagreed.

The Oxide model, as deka already runs it. Every issue is an RFD; the issue number is the RFD number; states are where the document lives rather than a label; promotion to a file is a pull request.

What we are doing

The third. It is already built once, we know where it breaks, and the two properties that make it work are the ones the other options lack: the number is assigned by GitHub so no collision logic exists anywhere, and promotion is a review rather than a click.

Two tiers, because some of this is a business and a business has documents that cannot be public. samifouad/cqx-rfd is this one. samifouad/cqx-rfd-internal is private and holds pricing, the business model, and anything naming a customer. They are cited apart — RFD n here, IRFD n there, and a bare number always means a public one.

What this rules out

  • Deciding in a pull request description. A decision that lives in the PR that implemented it cannot be disagreed with before it is implemented.
  • Moving an internal RFD into the public repository. It is superseded by a new public one instead. Moving private documents into public repositories is how private documents become public by accident.
  • A label as the source of truth. If a file exists on main, the file wins and the issue is only the discussion.

Open questions

  • Whether these get published to cqx.bio, as deka's are to deka.gg. Probably, but the sanitisation trap there is real — issue bodies come from anyone with a GitHub account — and it is not worth the blast radius yet.
  • Whether sync-labels is worth porting before there is a second author.

Discussion

2 replies
samifouadSep 20, 2026

Promoted to a file: rfd/0001-the-rfd-process.md. The file is the record from here; this issue stays open as the discussion.

Committed directly rather than by pull request, which is the one exception the process allows itself: a process cannot be adjudicated by a process that does not exist yet. Every RFD after this one is promoted by review.

-claude

samifouadSep 20, 2026

The two-tier design above is superseded by what was committed. Keeping the original body rather than editing it, because an RFD's discussion is a record of what was considered, and quietly rewriting the proposal to match the decision is how a process stops being worth having.

What changed: one repository, private, with visibility as a property of each RFD — not two repositories split by audience.

Two repositories put the storage shape into the citation. Issue numbers are per repository, so two sequences meant every reference had to say which one it came from, and RFD 7 and IRFD 7 would both exist forever and be confused for each other exactly as often as you would expect. It also forced the audience decision at the moment of least information: when somebody opens an issue to say they think there might be a problem.

Now: the frontmatter decides and the label reflects it, which is the same one-way rule that already governs state. Default private in every direction — no file, no visibility key, no label all mean not public.

The cost is written into the RFD rather than glossed: the boundary used to be GitHub's and is now ours, so a mislabelled document can leak where a private repository could not. That happened within a minute of the labels existing — I marked 2 and 3 public because they are intended to be, then corrected them, because neither has a file and under this design an RFD with no file cannot be public. The rule working on its author is the cheapest test it will ever get.

File: rfd/0001-the-rfd-process.md.

-claude