| name | contribute-knowledge-to-cogni |
| description | Umbrella skill for contributing durable knowledge to a Cogni node hub. Triggers when an agent has — or is about to research — context worth compounding for future agents/humans, AND the knowledge is durable enough to survive the syntropy bar. Routes to the right sub-skill by content shape (falsifiable prediction → `edo-loop`; visual for humans → `dolt-human-visuals`; AI-readable text → direct contribution). Use whenever you'd otherwise drop a research finding into a chat log or PR description that should outlive the session. RARE by design — most agent context dies with the session; only what compounds earns an entry. |
contribute-knowledge-to-cogni — route any knowledge contribution
Knowledge entries are precious. The right question is rarely "what do I write?" — it's "should I write anything, or refine what already exists?"
ONE PRINCIPAL · ONE OPEN CONTRIBUTION · refine via /commits — never fork
This is the rule the rest of the skill hangs on. Get it wrong and you sprawl the
inbox with N single-commit branches for one unit of work (the noob failure).
- One principal. Reuse your saved API key. Do not register a fresh agent
per write — each registration is a new principal, and the inbox fills with
orphan one-commit contributions nobody can attribute to one author.
- One open contribution at a time. A principal holds a single open
contrib/* branch. Everything you contribute this session lands on it.
- First write creates the branch; every write after that appends.
POST /contributions always forks a new branch — call it exactly once.
All subsequent edits (a new entry or a refinement) go to
POST /contributions/{id}/commits. Re-POSTing /contributions is the
fracturing bug: it does not compound, it spawns a second branch.
- Start something genuinely unrelated? Close the current one first
(
POST /contributions/{id}/close), then create. Don't run two open branches.
Asymmetry to remember: the EDO endpoints (/api/v1/edo/*) auto-compound
onto your one open contribution server-side. The raw /contributions
endpoint does not — you compound it yourself by using /commits.
Action hierarchy (mirrors knowledge-syntropy-expert)
Walk top-to-bottom. Most agent work stops at step 1.
- STAY SILENT. Is this context: ephemeral (dies with session), routine work-item state, an in-PR finding, an obvious factual lookup, OR something an existing entry already says? → write nothing. Knowledge entries are precious; sprawl is the failure mode. ≥80% of contributable-feeling moments belong here.
- RECALL — both planes. (a) The merged plane:
/knowledge?mode=browse filtered by domain, or core__knowledge_search. (b) Your own open contribution branch: GET /contributions?state=open for the id, then GET /contributions/{id}/diff to read the entries already on it. Branch-local entries do not appear in /knowledge?domain= (it returns merged-main only) — so an agent who recalls the merged plane alone will re-discover, re-author, or outright deny knowledge it wrote minutes ago on its own branch. Read the branch before you write or before you answer "does X exist / is it linked." Cite the siblings you find; append rather than fork.
- REFINE. Found a related entry that's slightly off, stale, or bloated? Sharpen it in place via an
op: update edit. Shorter + sharper + raises confidence. This is the most valuable knowledge move; most contribution work should look like this.
- CITE. Your claim is a relationship between existing atoms or an example of one? Add a
citation edge — supports, contradicts, extends, supersedes. Or write a sibling atom that cites the parent. Never inline "companion to X" prose. Cite across planes freely: an entry on your open branch may cite one already merged to main (cross-plane) — this resolves correctly and the edge becomes live in main's DAG when your contribution merges. (Before bug.5024 this silently 500'd; it now works, so don't avoid citing merged atoms from a long-lived compounding branch.) Work-item links are also citations: use citationType: "tracks" to connect exactly one work item (task.*, bug.*, spike.*, story.*, or subtask.*) with one knowledge entry already present on main; both endpoints are validated before the edge is accepted.
- WRITE ATOMIC. No existing atom fits AND the claim earns its keep → file new entry. See routing below for which entry type / sub-skill. Nearly always cite at least one existing entry in the same edit (
supports/extends/contradicts/supersedes) — a new atom should compound onto the graph, not land as an island. RECALL almost always surfaces a parent or sibling to link; a brand-new entry with zero edges is the silent failure mode that keeps the hub a flat document store instead of a compounding DAG.
- EXTEND. Anti-pattern. Don't bloat an existing atom to cover more cases — write a sibling, cite the parent.
Routing by content shape
After RECALL confirms a new write is genuinely needed, pick exactly one path:
| Content shape | Audience | Entry type | Sub-skill |
|---|
| Falsifiable prediction that resolves in a later session and shapes future agent action | agent | hypothesis / decision / outcome (atomic chain) | edo-loop |
| Visual artifact (diagram, scorecard, roadmap, status grid, design diff) for human review | human | html (sandboxed iframe) | dolt-human-visuals |
| Atomic factual claim with provenance, recallable by future agent search | agent | observation / finding / conclusion / rule / scorecard / skill / guide | direct (this skill) |
One entry, one shape. Don't mix — a "scorecard with embedded prediction" is two entries, one cites the other. But both still land as edits on your one open contribution — separate shape ≠ separate branch.
EDO vs knowledge entry vs spec — what truth goes where
Three durable homes. Pick by the shape of the truth, not by which is easiest.
| You have… | Home | Why |
|---|
| As-built fact about how the system works right now — architecture, a contract, an invariant a future agent needs as ground truth | docs/spec/* in the repo (refine an existing spec; ship it in the PR) | SPECS_ARE_AS_BUILT. Versioned with the code, reviewed in the PR that makes it true. Not in the hub. |
| Atomic learning with provenance — "we found X", a rule, a scorecard — not a prediction, not architecture | knowledge entry (this skill) | Recallable by agent search, confidence-rated, compounds in the Dolt hub. |
| Falsifiable prediction that resolves in a later session, is contestable, and changes what the next agent does | EDO chain (edo-loop) | Time-bound belief → action → outcome; confidence recomputes when the outcome lands. |
EDO linked to a spec — when your prediction is about a spec'd subsystem:
- The spec stays the as-built description (what the system does).
- The EDO carries the time-bound belief (whether a change moves a metric).
- Wire them, don't merge them:
hypothesize.content references the spec id; the decide row's source_ref points at the PR that changes the spec'd behavior; the outcome reads the deployed system at sha:<deployed>.
- Don't fold the prediction into the spec (specs aren't predictions). Don't restate the spec inside the EDO (cite it).
Tie-breakers:
- Tempted to write a
docs/spec/knowledge-* doc for a one-off learning? Almost always wrong — refine a hub entry. Specs are for durable as-built contracts, not findings.
- Tempted to file a
finding for a prediction because EDO feels heavy? If it's falsifiable + session-separated + contestable, it's an EDO or it's silence — not a finding.
Text entry types render their content as GFM markdown in the human UI (structure it — see "Format the content field"). html is reserved for visual artifacts markdown can't express.
Picking the right node
Cogni nodes own niche hubs. Pick by primary subject:
- operator (
https://cognidao.org / https://test.cognidao.org) — cross-cutting infrastructure, knowledge platform itself, syntropy, deploy + flight, work-item lifecycle, governance. Default when in doubt.
- poly (
poly.cognidao.org) — Polymarket CLOB, copy-trade mirror, wallet provisioning, market-data analytics.
- resy (
resy.cognidao.org) — reservation knowledge.
- Other nodes — see each node's charter.
If a claim is genuinely cross-node (e.g. "Doltgres WITH RECURSIVE works at 1k rows"), file once on operator and cite from per-node hubs as they need it. Don't duplicate.
Picking the right domain
domain is a registered FK on every entry (DOMAIN_FK_ENFORCED_AT_WRITE). Pick from existing — register a new one ONLY if no existing domain fits and the new one will accumulate ≥5 entries.
Common operator-node domains (seeded): meta, infrastructure, prediction-market, governance, reservations.
If unsure → use meta (knowledge about the knowledge system itself) or the closest existing match. Register new via POST /api/v1/knowledge/domains (bearer or session auth, post-W2).
Mechanics — direct text path
For text entry types (observation/finding/conclusion/rule/scorecard/skill/guide). For html use dolt-human-visuals; for EDO chains use edo-loop. Full envelope contract: docs/design/knowledge-contribution-api.md.
KEY=$(grep -E "^COGNI_API_KEY_TEST=" .env.cogni | cut -d= -f2- | tr -d "\"")
BASE=https://test.cognidao.org
Step 1 — recall your open contribution AND read what's already on its branch:
CID=$(curl -sS "$BASE/api/v1/knowledge/contributions?state=open&limit=20" \
-H "Authorization: Bearer $KEY" | jq -r '.contributions[0].contributionId // empty')
[ -n "$CID" ] && curl -sS "$BASE/api/v1/knowledge/contributions/$CID/diff" \
-H "Authorization: Bearer $KEY" | jq -r '.entries[] | "\(.rowId): \((.after // .before).title)"'
Step 2 — only if you have none open, create ONCE and capture the id:
CID=$(curl -sS -X POST "$BASE/api/v1/knowledge/contributions" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{
"message": "<one-line intent for this unit of work>",
"edits": [{
"op": "insert",
"entry": {
"id": "<kebab-slug, ≤4 dash segments>",
"domain": "<registered>",
"title": "<use-when-X framing>",
"content": "<atomic claim with provenance>",
"entryType": "finding",
"tags": ["<short>", "<discoverable>"]
}
}]
}' | jq -r .contributionId)
Step 3 — every further edit appends to that SAME branch via /commits:
curl -sS -X POST "$BASE/api/v1/knowledge/contributions/$CID/commits" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{
"message": "append: <what this commit changes>",
"edits": [{ "op": "insert", "entry": { ... } }]
}'
One POST can carry a mixed-op batch (insert + update + deprecate, up to 50) in a single commit when the changes belong together — that's one review for one coherent unit, not N branches.
Work-item↔knowledge tracking links. Use a cite edit with
citationType: "tracks" when a work item is the operational owner of a
knowledge entry, or when a knowledge entry explains/proves a work item. The edge
must connect exactly one work-item id and one merged knowledge id; branch-local
knowledge rows are not accepted for tracks because work-item detail pages read
the merged DAG.
curl -sS -X POST "$BASE/api/v1/knowledge/contributions/$CID/commits" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{
"message": "link story.5017 to knowledge invariant",
"edits": [{
"op": "cite",
"citingId": "story.5017",
"citedId": "<merged-knowledge-id>",
"citationType": "tracks",
"context": "story.5017 implements and validates this knowledge invariant"
}]
}'
Do not add work-item link columns or duplicate the relationship in work
metadata. The citations row is the source of truth and renders from both the
knowledge and work-item detail surfaces after merge.
Two distinct "refine" cases — don't conflate them:
| You want to refine… | How |
|---|
| a row you wrote earlier on your open branch | POST /contributions/{id}/commits with {op:"update", targetRowId, entry} — targetRowId resolves on the branch |
an entry already merged to main | POST /contributions once with {op:"update", targetRowId:<main id>}, then keep refining that via /commits |
Format the content field as Markdown
The human UI renders content for text entries through <Markdown> (GFM: headings, bold, lists, tables, code, links). The same bytes stay plain-text for AI search + embeddings. One source of truth, both audiences — so write structured markdown, not a prose blob. A wall of prose renders as a wall of prose; it's the failure mode in most existing entries.
Lead with a use-when / claim line in bold, then structure the evidence. Reach for a table when you have ≥2 parallel facts.
❌ Prose blob — unscannable, renders identically to its raw source:
We found that the Doltgres adapter cannot use postgres.js extended protocol
because prepared statements break on Doltgres, so the adapter uses sql.unsafe()
with manual escapeValue and JSONB containment operators like @> and ILIKE are
not supported which means queries must avoid them.
✅ Structured markdown — same claim, scannable, renders as formatted HTML:
**Use when:** writing a query adapter against Doltgres.
Doltgres breaks `postgres.js` **extended protocol** (prepared statements fail),
so the adapter routes around it:
| Constraint | Workaround |
| ------------------------- | --------------------------------------- |
| No prepared statements | `sql.unsafe()` + manual `escapeValue()` |
| No JSONB `@>` containment | rewrite as key extraction |
| No `ILIKE` | `LOWER(col) LIKE` |
Source: `spike.0229` — 13 integration tests passing.
A scorecard entry is a markdown table of dimension | us | optimal | gap rows. A rule is a bold imperative + a short rationale list. A guide is ## sections with fenced commands. Keep it atomic — structure sharpens one claim; it is not license to lengthen.
Markdown text vs html entry. Markdown covers ~all knowledge: headings, tables, lists, code. Reach for an html entry (via dolt-human-visuals) only when the artifact is genuinely visual — an SVG architecture diagram, a chart, a status grid markdown can't express. Default is markdown text; html is the rare escape hatch, not "anything a human reads." Raw HTML is not rendered in the markdown lane (it's escaped) — full HTML only runs in the sandboxed-iframe html path.
Confidence — what you set vs what the system computes
Don't set confidencePct on the request unless you have a defensible reason. Initial confidence comes from your principal's sourceType (agent=30 = draft; human=70). Recompute raises it as citation evidence lands. Manual overrides undermine the recompute contract — let the resolver do its job.
When to invoke this skill
- Before opening any
core__knowledge_write tool call
- Before posting to
/api/v1/knowledge/contributions directly
- When tempted to "just write it in the PR description" but the claim is reusable
- When tempted to write a doc under
docs/spec/knowledge-* — almost never the right home; refine an existing knowledge entry or write a new atomic one in the hub
Anti-patterns
- Re-POSTing
/contributions for related work instead of appending via /commits — the fracturing failure: N single-commit branches for one unit of work (and an inbox no human wants to triage).
- Recalling the merged plane only — never reading your own open branch.
/knowledge?domain= returns merged-main; your contrib/* branch entries are invisible to it. Answering "does X exist / is it linked" or deciding to write without GET /contributions/{id}/diff is how an agent denies or duplicates knowledge it authored minutes ago (the exact failure that prompted this rule).
- Registering a fresh agent key per contribution — multiplies principals; reuse your one saved key.
- Filing a new entry when RECALL would surface an existing match
- Filing a new atom with zero citation edges — the island failure. A new entry should nearly always
cite a parent/sibling RECALL surfaced (cross-plane to merged atoms works); islands don't compound and leave the hub a flat document store
- Linking work items outside
citations — work↔knowledge relationships use one tracks edge, not duplicated columns, tags, or prose.
- Writing a
content prose blob instead of structured markdown (headings / bold lead / table / list) — renders as an unscannable wall; see "Format the content field"
- Reaching for
html for ordinary human-facing content that a markdown table or list expresses fine — html is the rare visual escape hatch (SVG / chart), not the default for "a human reads it"
- Filing a falsifiable prediction as
finding to avoid EDO overhead — use edo-loop or stay silent
- Authoring a genuinely visual artifact (diagram, chart) as plain text (loses the styling contract from
knowledge-html-style.md)
- Putting a one-off learning in
docs/spec/* — specs are durable as-built contracts, not findings
- Setting
confidencePct manually because the draft (30) looked low
- Duplicating cross-node — file once, cite from other nodes
Cross-references
knowledge-syntropy-expert — action hierarchy + REFINE_OVER_EXTEND + RECALL_BEFORE_WRITE
edo-loop — falsifiable predictions (auto-compounds onto your one open contribution)
dolt-human-visuals — HTML entries for human review
contribute-to-cogni — separate skill for code contributions (PRs); this skill is for knowledge contributions
docs/spec/knowledge-syntropy.md — schema, invariants, write/read protocol
docs/spec/knowledge-html-style.md — tokens + utility classes for entryType: html
docs/design/knowledge-contribution-api.md — full request/response envelope contract (/contributions create vs /commits append)