How knowledge earns trust

An agent can write anything into Project Knowledge. Nothing it writes reaches another agent until something else confirms it. This page is the rule that sits in between.

The rule

An entry becomes trusted when both of these hold:

(a) one of:

  • K distinct promoting issuers support it. The default K is 2, and the entire CI system counts as one issuer - a hundred green runs are one voice.
  • or a project owner confirms it explicitly. An owner promotes alone.

(b) and there are no contradictions on it inside the window (default 30 days).

Promotion only ever goes candidate -> trusted. A contradicted or retired entry is never resurrected by new support arriving.

Who can move trust, and which way

ActorCan promoteCan demote
AgentNo, by any pathYes
CI attestationYes, as one issuerNo
Project ownerYes, aloneYes, by refuting

Agents can only demote

learn writes a candidate. There is no argument, no flag, and no second tool that writes trusted. An agent refutes an entry with an event of type error carrying detail.contradicts, and that path is fixed to the contradict signal - no event payload can be shaped into support.

The asymmetry is the point. An agent asserting something is a claim; an agent hitting a failure is an observation. Letting the first one promote would mean a single confident agent could put its own mistake into every other agent's context, which is exactly how a shared memory turns into a shared error. Letting the second one demote costs almost nothing if it is wrong: the entry goes back to being unconfirmed, which is where it started.

The demotion path is rate-limited, so an agent stuck in a loop cannot quietly retire an entry by refuting it over and over.

CI counts as one issuer, however many times it runs

A green build is real evidence, so CI attestation can support a claim. But every attestation from a project's CI shares one issuer identity, and promotion counts distinct issuers, not signatures. Re-running a job a hundred times does not get you to K=2.

Two other things do not count:

  • The same source twice. Validations are deduplicated on a fingerprint of issuer plus source, so a rerun of the same check is one support, not two.
  • An unmapped check. An attestation whose check has no entry in the check map is recorded but comes back counted: false. The evidence is kept; it just has no vote, because nobody decided in advance that this check speaks for this claim.

A project owner promotes alone

An owner confirming a candidate in the dashboard promotes it immediately, on that one act. This is a deliberate exception to K, not a gap in it, and the audit row records it as an override so the ledger shows the entry was promoted because a person decided, not because signals accumulated.

The reason is what K is actually for. K exists to stop an automated system holding a signing key from deciding truth on its own. A project owner is not something to be constrained by K; they are the authority that decides what counts as a norm in their own project. Requiring a second issuer before an owner's decision takes effect would not add safety, it would just mean the project cannot state its own conventions.

Contradictions block promotion - including for owners

Condition (b) applies to both branches. One unexpired contradiction stops an entry from being promoted no matter how much support arrives, and that includes an owner's confirmation.

Known limitation. There is no UI to clear a contradiction. If a stale one is sitting on an entry, an owner's confirm does nothing until the window expires - up to 30 days by default, and the button does not explain itself.

The reason it works this way: if a person could confirm over a live contradiction, demotion would be toothless - anything refuted could simply be reinstated by clicking. Waiting out the window is the current price of keeping demotion meaningful.

Demotion itself is immediate and applies to a trusted entry as much as a candidate; recall has to stop returning something that has been refuted. promoted_at is left in place, because it is history rather than current state.

The numbers

SettingDefaultPer project
Distinct issuers to promote (K)2knowledgeConfig.kDistinctIssuers
Contradiction window30 daysknowledgeConfig.windowDays

The 30 days was picked, not derived. No specification gives a number for it, and the source says so where it is defined. Treat it as a starting value rather than a tuned one.

One boundary, four rules

These look like four small restrictions when you meet them separately. They are one line:

  • learn always writes a candidate.
  • Automatic extraction from threads always writes a candidate.
  • Approving a reflection proposal registers a candidate.
  • Agents can demote but never promote.

Everything a machine produces enters as unconfirmed, and only a human or an independent check moves it across. Remove any one of them and there is a path from "an agent said so" to "every agent is told so" with nothing in between.

Next