Skip to main content

knowledge API

Table of Contents​

Top

upsquad/knowledge/v1/corpus_integrity.proto​

AdjudicateConflictRequest​

AdjudicateConflictRequest is a HUMAN verdict. There is no agent id on it and there is nowhere to put one.

FieldTypeLabelDescription
team_unit_idstringThe team whose queue holds the finding. Required; a member of team A cannot rule on team B's queue even with the capability.
conflict_idstringThe finding to rule on, by row id.
new_statusConflictStatusCONFIRMED, DISMISSED, FIXED or SUPERSEDED. OPEN is refused — a finding re-opens on evidence (TK-9.11), not on a verdict.
notestringWhy. Recorded beside the verdict, because a verdict's reasoning is a property of the verdict and TK-9.13 feeds both back into calibration.

AdjudicateConflictResponse​

AdjudicateConflictResponse returns the finding as it now stands.

FieldTypeLabelDescription
conflictConflictThe finding after the verdict.

Conflict​

Conflict is one finding.

FieldTypeLabelDescription
idstringThe row id. Machines hold this; people paste the permalink.
team_unit_idstringThe team whose queue owns this finding. A conflict is a fact about ONE team's corpus.
permalinkstring"C-###" — stable, per team, resolving to exactly one row. A fix task, an issue or a Slack message points here.
conflict_classConflictClassWhich of TK-9.1's five classes this finding is.
statusConflictStatusWhere the finding is in TK-9.10's lifecycle. Read WITH verdict_by: an OPEN finding that carries a verdict was re-opened after adjudication.
severityConflictSeverityUNKNOWN for everything the window arm raises — see the enum.
summarystringOne line: what disagrees.
first_seen_atgoogle.protobuf.TimestampWhen the finding was first raised.
last_seen_atgoogle.protobuf.TimestampThe most recent sighting. Beside sighting_count this is what tells a triager whether a finding is live or historical.
verdict_by_member_idstringThe MEMBER who ruled, empty until a human has. Never an agent (TK-9.12).

It is NOT cleared when a dismissal lapses and the finding re-opens: an open finding that carries a verdict is "re-opened after adjudication", which is a fact the queue needs and TK-9.13's judge calibration reads. Read status for the current state and this for the last human ruling. | | verdict_at | google.protobuf.Timestamp | | When the human ruled. Paired with verdict_by_member_id by a CHECK: half a verdict is not a verdict. | | verdict_note | string | | Why they ruled that way. TK-9.13 feeds verdicts AND their reasoning back into judge calibration. | | sighting_count | int32 | | How many times this finding has been reported. Carried on the LIST row, not only in the drawer: "seen four times" is the most useful triage signal a queue row has, and a signal that needs a click is a signal most readers never see. | | passages | ConflictPassage | repeated | Populated by GetConflict only. A list that fanned out to every passage of every row would be a fan-out on the surface people leave open. | | sightings | ConflictSighting | repeated | Populated by GetConflict only, newest first and bounded. A conflict an agent hits every turn accumulates sightings quickly. |

ConflictPassage​

ConflictPassage is one side of a conflict.

FieldTypeLabelDescription
idstringThe passage row id.
doc_idstringThe DOCUMENT (identity — survives content change).
version_idstringThe VERSION that was judged (content address — does not).
source_doc_idstringThe version's address, which is the handle search_knowledge prints and get_document takes. One handle, everywhere.
text_sha256stringThe extraction hash AS JUDGED. Empty when the judged version had no extraction to hash, which is what makes a later stickiness comparison UNDECIDABLE for this passage.
char_startint32Character range within the extraction, when the producer knew one. A report names documents, not offsets, so the window arm leaves both zero; the claims sweep will not.
char_endint32Exclusive end of the character range. Paired with char_start by a CHECK.
labelstringThe document's human label, resolved on READ rather than stored: a filename changes, and a stale label inside a governance citation is a confident falsehood about which document was judged.

ConflictSighting​

ConflictSighting is one report. A second report is a sighting, not a row.

FieldTypeLabelDescription
idstringThe sighting row id.
reporter_kindReporterKindWhich of the two reporters this was. Determines which id below is set.
reporter_agent_idstringExactly one of the two is set, per the exclusive arc.
reporter_member_idstringSet when reporter_kind is MEMBER; empty otherwise.
task_contextstringTK-9.4: what the reporter was doing when the disagreement bit them. This is the field that makes a repeat sighting EVIDENCE rather than noise.
detailstringWhat the reporter said was wrong, in their words. Distinct from the finding's own summary: a second reporter may name a different symptom of the same disagreement, and flattening the two loses that.
stickinessStickinessWhat TK-9.11's comparison measured for THIS sighting.
seen_atgoogle.protobuf.TimestampWhen this report arrived.

GetConflictRequest​

GetConflictRequest resolves one finding.

FieldTypeLabelDescription
team_unit_idstringThe team whose queue to read. Required; it is the gate.
refstringA row id OR a C-### permalink. One field, because the permalink is what people paste and the id is what machines hold, and a second field would be a second thing that can be wrong.

GetConflictResponse​

GetConflictResponse carries the finding with its passages and sightings.

FieldTypeLabelDescription
conflictConflictThe finding, with passages and sightings populated.

ListConflictsRequest​

ListConflictsRequest pages one team's queue.

FieldTypeLabelDescription
team_unit_idstringThe team whose queue to read. Required; it is the gate, not a filter.
statusesConflictStatusrepeatedEmpty means the DEFAULT view, which excludes dismissed. It does not mean "everything".
page_sizeint32Bounded server-side. Zero selects the default.
offsetint32Rows to skip. Negative is treated as zero.

ListConflictsResponse​

ListConflictsResponse is one page plus the facts an empty page needs.

FieldTypeLabelDescription
conflictsConflictrepeatedThe page, newest sighting first.
summaryQueueSummaryALWAYS populated, including when conflicts is non-empty. An empty list has four different meanings and a console that must issue a second RPC to learn which will render the wrong one.

QueueAggregateBucket​

QueueAggregateBucket counts one class/status pair in the full current queue.

FieldTypeLabelDescription
conflict_classConflictClassThe finding taxonomy, never UNSPECIFIED.
statusConflictStatusThe current lifecycle state, never UNSPECIFIED.
countint64Number of deduplicated findings in this bucket; zero is measured.

QueueAggregates​

QueueAggregates measures current human queue completion, NOT detector precision or historical judgement throughput. Findings are deduplicated rows, never sightings or passages. Machine funnel stages remain in SweepStatus.

FieldTypeLabelDescription
bucketsQueueAggregateBucketrepeatedAll five classes crossed with all five lifecycle states, including zero buckets, in enum order. Each finding belongs to exactly one bucket.
surfaced_countint64All findings currently in the team's queue, including dismissed.
human_judged_countint64Currently confirmed, fixed, superseded or dismissed. A reopened finding is open and no longer belongs to this numerator, even with an old verdict.
human_judged_ratedoubleoptionalServer-computed human_judged_count / surfaced_count, a fraction in [0,1]. Absent when surfaced_count is zero: no denominator, not 0% or 100%.

QueueSummary​

QueueSummary is the tab badge and the "25 of 91" denominator.

FieldTypeLabelDescription
open_countint32The badge number: findings awaiting a human. open only — a confirmed finding already has its verdict and is somebody's task, and badging it would make the badge un-clearable.
total_in_viewint32How many rows the current filter matches, so a page can say "25 of 91" rather than implying 25 is all there is. NOT the page length.
sweepSweepStatusWhere the team's detection stands. Always populated — see ListConflictsResponse.summary.
aggregatesQueueAggregatesCurrent human queue completion, across ALL findings for this org/team, including dismissed, independent of status filters and pagination. Absent on older servers; absence does not mean an empty measured queue.

ReportConflictRequest​

ReportConflictRequest is one in-context human report. The agent tool's equivalent arrives through the MCP server and lands on the same store primitive, which is what makes the two dedupe onto one finding.

FieldTypeLabelDescription
team_unit_idstringThe team whose queue receives the finding. Required.
conflict_classConflictClassWhich class the reporter says this is. Not re-classified by the server: re-classifying a report is a judgement, and this arm makes none.
summarystringOne line: what disagrees. Required — a queue entry that cannot say what it found cannot be triaged.
source_doc_idsstringrepeatedThe documents the reporter says disagree, as the source_doc_id handles search_knowledge prints. Required; doc_doc needs at least two.

Every one must be visible to the caller's effective knowledge-source set. A partially-resolvable report is REFUSED, not silently narrowed: a report of "A and B contradict" that becomes a finding about A alone says something the reporter did not say. | | task_context | string | | TK-9.4: what the reporter was doing. | | detail | string | | What the reporter says is wrong, in their words. |

ReportConflictResponse​

ReportConflictResponse says WHICH finding received the report and what happened to it, so the caller can render the mockup's sentence.

FieldTypeLabelDescription
conflictConflictThe finding the report landed on — created or matched.
createdboolFalse when the report DEDUPED onto an existing finding. The mockup's wire behaviour — "matched existing C-108, your context attached" — needs this and stickiness to be sayable at all.
stickinessStickinessWhat TK-9.11's comparison measured for this report.
reopenedboolSet when a dismissal LAPSED and this report re-opened the finding.
undecidable_passagesstringrepeatedThe labels of the passages whose hash could NOT be compared, when stickiness is STICKINESS_UNDECIDABLE. Named rather than counted: an operator asked to look at a corpus artefact needs to know which one.
sighting_countint32The count AFTER this report. Two sightings on one conflict is the shape acceptance 8 asks for, and this is where it is visible.

SweepStatus​

SweepStatus is everything H4's empty state is computed from.

FieldTypeLabelDescription
configuredboolWhether conflict detection is switched on for the team. False for every team in Phase 1 — the sweep is Phase 2+.
last_run_atgoogle.protobuf.TimestampThe last sweep ATTEMPT, successful or not.
last_success_atgoogle.protobuf.TimestampThe last sweep that COMPLETED. The distinction is the whole of state 4: a detector that runs nightly and fails nightly has a recent last_run_at and a stale last_success_at, and reporting the first would be a freshness claim about a failure.
pairs_checkedint64TK-9.7's first funnel stage from the last successful sweep. "0 conflicts" alone is not a report; "0 conflicts, checked 1,204 pairs" is.
reasonstringWhy there is no recent success. H4's rule is "the last successful sweep time, OR THE REASON there is none".
stateQueueStateThe computed state, so the console cannot derive a fifth one.
renderedstringThe server's own rendering of the state. Carried on the wire for the same reason RepoMap carries its staleness marker: the console, the CLI and any digest must not be able to describe the same state differently.

ConflictClass​

ConflictClass is TK-9.1's five first-class classes.

All five are on the wire although the window arm produces only the first three. A queue that cannot REPRESENT a class cannot receive it when its detector lands without a migration over live governance rows, and detectors (v) and (vi) are Phase 2+.

NameNumberDescription
CONFLICT_CLASS_UNSPECIFIED0Never sent by this service. Present because proto3 requires a zero value; a request carrying it is refused rather than defaulted to a class.
CONFLICT_CLASS_DOC_DOC1Two documents contradict each other.
CONFLICT_CLASS_INTRA_DOC2One document contradicts itself.
CONFLICT_CLASS_DOC_CODE3A document has drifted from the code it describes.
CONFLICT_CLASS_DUPLICATION4Duplicated content with no single owner. Detector (v), Phase 2+.
CONFLICT_CLASS_AMBIGUITY5A term used to mean different things. Detector (vi), Phase 2+ and LAST (TK-9.9) — it ships into a queue that has already demonstrated precision, or not at all.

ConflictSeverity​

ConflictSeverity drives the queue's severity chip. Colour is reserved for it; the taxonomy chips are neutral (HLD §11.7).

NameNumberDescription
CONFLICT_SEVERITY_UNSPECIFIED0Never sent by this service; UNKNOWN is the honest "not judged" value and it is a value, not an absence.
CONFLICT_SEVERITY_UNKNOWN1What the window arm writes. A report says "these disagree"; nothing in this arm judges HOW BADLY, and inventing a severity would be a number with no measurement behind it.
CONFLICT_SEVERITY_LOW2Set by a human adjudicating, or by a Phase-2 detector that measured it.
CONFLICT_SEVERITY_MEDIUM3Set by a human adjudicating, or by a Phase-2 detector that measured it.
CONFLICT_SEVERITY_HIGH4Set by a human adjudicating, or by a Phase-2 detector that measured it.

ConflictStatus​

ConflictStatus is TK-9.10's lifecycle.

NameNumberDescription
CONFLICT_STATUS_UNSPECIFIED0Never sent by this service. A status the server could not name is a bug, not a state, and defaulting it to OPEN would invent a finding.
CONFLICT_STATUS_OPEN1Raised and awaiting a human. The ONLY status a write path can create, and the only one answer-time surfacing reads.
CONFLICT_STATUS_CONFIRMED2Requires a human verdict (TK-9.12).
CONFLICT_STATUS_FIXED3The confirmed finding has been repaired. Reachable only from CONFIRMED: retiring a finding nobody ruled on would be TK-9.12 by the back door.
CONFLICT_STATUS_DISMISSED4Requires a human verdict (TK-9.12), and is STICKY until a judged passage changes (TK-9.11).
CONFLICT_STATUS_SUPERSEDED5A human decided which side wins. NG-10: the losing document is NOT edited.

QueueState​

QueueState is H4's four empty states. None may render identically to another — that is the whole content of UX acceptance 2.

NameNumberDescription
QUEUE_STATE_UNSPECIFIED0Never sent. A queue state the server could not establish renders as itself rather than as the nearest familiar sentence — see SweepStatus.rendered.
QUEUE_STATE_NOT_CONFIGURED1No sweep configured. THE DAY-0 WINDOW STATE, and every team's state throughout Phase 1.
QUEUE_STATE_NEVER_RUN2Configured, never run — the dead-detector case.
QUEUE_STATE_CLEAN3Ran, clean.
QUEUE_STATE_STALE4Ran, but the last success is stale or there has never been one. Carries the reason.

ReporterKind​

ReporterKind is the sighting's exclusive arc. Agent evidence and human evidence are different signals: "three agents hit this mid-task" and "a curator noticed it" say different things about a finding.

NameNumberDescription
REPORTER_KIND_UNSPECIFIED0Never stored: the exclusive-arc CHECK on conflict_sightings refuses a sighting whose reporter kind is not one of the two below.
REPORTER_KIND_AGENT1Reported by an agent through the report_knowledge_issue MCP tool, mid-task.
REPORTER_KIND_MEMBER2Reported by a person through the in-context report on the doc viewer or the answer surface (TK-9.4's primary entry; the console button is the fallback).

Stickiness​

Stickiness is what TK-9.11's hash comparison measured for one sighting.

NameNumberDescription
STICKINESS_UNSPECIFIED0Never stored. Every sighting records which of the four the writer measured, because an unrecorded comparison is a verdict nobody can audit.
STICKINESS_NOT_DISMISSED1The finding was not dismissed, so stickiness did not apply. Distinct from HELD: "the verdict held" and "there was no verdict" are different facts.
STICKINESS_HELD2Dismissed, and every recorded hash still matches. The dismissal SURVIVES a re-sync — without this arm the queue forgets its own verdicts.
STICKINESS_LAPSED3Dismissed, and at least one judged passage CHANGED. The dismissal lapses and the finding re-opens — without this arm the queue nags.
STICKINESS_UNDECIDABLE4Dismissed, nothing demonstrably changed, but at least one passage could not be compared. The dismissal is HELD and the unverifiability is reported.

CorpusIntegrityService​

CorpusIntegrityService is the management surface for a team's corpus-integrity queue. Every operation is tenant-scoped: the owning org and the acting member come from the request scope, never from the request body, and every statement carries an explicit org predicate on top of row-level security.

Authorization (handler_perms.go):

  • reads (ListConflicts, GetConflict) — knowledge.read
  • report (ReportConflict) — knowledge.read, deliberately: reporting is reading with a complaint attached, and requiring knowledge.manage would mean only curators can flag a contradiction — which defeats TK-9.4's "primary entry is the doc-viewer / answer surface".
  • verdict (AdjudicateConflict) — knowledge.manage, and a HUMAN.
Method NameRequest TypeResponse TypeDescription
ReportConflictReportConflictRequestReportConflictResponseReportConflict records a reported disagreement.

It DEDUPES: a report whose (class, document set) matches an existing finding becomes an additional SIGHTING on that finding, carrying the task context it was reported from. A second sighting is evidence, not a duplicate row (TK-9.4).

This is the same store primitive the report_knowledge_issue MCP tool calls, which is what makes "the agent tool and the in-context human report dedupe into ONE conflict with TWO sightings" a property of one implementation rather than an agreement between two. | | ListConflicts | ListConflictsRequest | ListConflictsResponse | ListConflicts pages a team's queue.

The DEFAULT view excludes dismissed (HLD §11.7). An empty statuses means that default, NOT "everything": a queue whose depth never drops because it shows its own dismissals is a queue people stop reading. | | GetConflict | GetConflictRequest | GetConflictResponse | GetConflict resolves ONE finding by row id or by C-### permalink, with its passages and its sightings. | | AdjudicateConflict | AdjudicateConflictRequest | AdjudicateConflictResponse | AdjudicateConflict records a HUMAN verdict (TK-9.12). It is the only way into confirmed or dismissed, and fixed / superseded are reachable only from confirmed — both are statements about a finding a human already accepted.

It cannot set open: a conflict re-opens when a judged passage CHANGES (TK-9.11), which is evidence, not a click. |

Top

upsquad/knowledge/v1/document.proto​

ByteRange​

ByteRange is a bounded window over the SERVED REPRESENTATION, in bytes.

Bytes and not runes: "byte-faithful" is the property being delivered, and a rune-indexed window over a PDF or a docx is not a window over anything the caller can address.

A RANGE IS NOT A WAY AROUND THE SIZE CEILING, and that is worth stating because the truncation notice on every other response invites paging. The stored hash is over the WHOLE artefact, so verification runs over the whole artefact before any window is taken: an artefact above the server's verification ceiling is refused outright (FAILED_PRECONDITION naming the size and the limit) and no offset can reach it.

FieldTypeLabelDescription
offsetint64offset is the first byte to serve, 0-based. An offset past the end of the representation is InvalidArgument, not an empty success.
lengthint64length is how many bytes to serve. 0 means "to the end", subject to the budget in max_bytes.

DocumentProvenance​

DocumentProvenance is everything a reader needs to say WHERE this came from and WHEN — PRD TK-2.3's "source, external id, filename, modified_at, content_hash, ingestion time", plus the fields HLD §4.3 added to make the integrity check falsifiable.

FieldTypeLabelDescription
doc_idstringdoc_id is the registry row: the DOCUMENT, whose identity is (source_id, external_id) and which survives every content change.
version_idstringversion_id is the knowledge_doc_versions row that was served.
source_idstringsource_id is the knowledge_sources row the document belongs to.
source_doc_idstringsource_doc_id is the VERSION ADDRESS — the value rag_chunks already carries and the handle search results print.
external_idstringexternal_id is the upstream stable id. A backfilled legacy row carries "legacy:<source_doc_id>" and is flagged for re-sync (LLD §3.5).
source_namestringsource_name is the human-readable corpus name. Best-effort: a soft-deleted source still has readable content, so an empty value is a missing LABEL and never a gate.
filenamestringfilename is the document's file name, where the producer recorded one.
titlestringtitle is the document's title, where the producer recorded one.
pathstringpath is the document's upstream path, where the producer recorded one.
modified_atgoogle.protobuf.Timestampmodified_at is the upstream modification time, where one was captured.
raw_sha256stringraw_sha256 is the hash of the original bytes. EMPTY means "never recorded", which is reachable only for artefact_state='raw_unavailable' rows; it is not flattened to a sentinel, because an empty hash that reads as populated is exactly what migration 228's CHECKs exist to prevent.
text_sha256stringtext_sha256 is the hash of the persisted extraction. Empty when there is no extraction to hash.
extractor_versionstringextractor_version dates text_sha256. Without it a text_sha256 mismatch cannot be told apart from corruption: a mismatch at the SAME version is corruption, a mismatch ACROSS versions is a re-extraction event (HLD §4.3, A2-b).
content_typestringcontent_type is the document's media type as recorded at ingest.
size_bytesint64size_bytes is the size of the RAW document as recorded at ingest, which is not in general the size of the representation served — see Truncation.total_bytes for that.
ingested_atgoogle.protobuf.Timestampingested_at is when this version was persisted. It is the timestamp behind the "as of the last sync" phrasing claim bound C3 requires.
artefact_statestringartefact_state is what the registry knows about this version's bytes: 'present' or 'raw_unavailable' from knowledge_doc_versions, or 'unregistered' for a document that has no registry row at all — the whole corpus ingested before the persistence path existed, until the backfill gives each one a row. It is the DISCRIMINATOR for the empty hash/type/size fields above, not a label. 'unregistered' is a WIRE value only; the database CHECK admits the other two, because a row saying "there is no row" would be a contradiction someone could persist.
doc_kindstringdoc_kind is 'document'
content_provenanceContentProvenancecontent_provenance says whether the served bytes are the persisted artefact or a reconstruction from chunks.
currency_detailstringcurrency_detail renders the currency marker in words, including the ingest timestamp behind "as of the last sync" (claim bound C3).
deleted_atgoogle.protobuf.Timestampdeleted_at is set when the registry row is soft-deleted. It is carried SEPARATELY from currency on purpose: a document deleted HERE and a document deleted UPSTREAM are different facts, and folding the first into CURRENCY_GONE_UPSTREAM would assert an upstream observation we have not made.

GetDocumentRequest​

GetDocumentRequest addresses ONE document version.

FieldTypeLabelDescription
doc_refstringdoc_ref is either a source_doc_id (a VERSION address — the handle every search hit prints) or a knowledge_docs id (a DOCUMENT identity, resolved to its current version). Both are UUIDs and the server tries them in that order; a value that is neither is answered with the SAME not-found as a document belonging to another team, because a caller able to tell those apart across a UUID space can enumerate what other teams hold.
representationRepresentationrepresentation selects the artefact. Unset means REPRESENTATION_EXTRACTED.
rangeByteRangerange bounds the window served. Unset means "from the start".
max_bytesint64max_bytes is the caller's budget for THIS RESPONSE. 0 means the server default. A value above the server ceiling is clamped, and the clamp is named in truncation.detail rather than applied quietly.

The server ceiling is also a bound on the WHOLE ARTEFACT, not only on the slice returned: an artefact larger than the server can hold in memory is an artefact it cannot hash, and it is refused with FAILED_PRECONDITION rather than served in pieces whose integrity nobody checked. Raising max_bytes does not raise that bound. | | verify_by_reassembly | bool | | verify_by_reassembly runs TK-2.8's check: assemble the document's chunks, remove the chunker's materialised overlap, and compare with the persisted extraction. OFF by default — it is a check, not the read path, and making it automatic would put de-overlap on every read for no user benefit. |

GetDocumentResponse​

GetDocumentResponse is the byte-faithful read.

FieldTypeLabelDescription
contentbytescontent is the served bytes. Empty ONLY for a hard refusal; a document that is gone upstream or whose reference no longer resolves is served ALONGSIDE its marker (PRD §11, v1.3).
representationRepresentationrepresentation is which artefact was served. Never substituted: a request for one artefact is never answered with the other, because a silent fallback is exactly what M3's red direction forbids.
truncationTruncationtruncation is ALWAYS present and always says what was omitted.
provenanceDocumentProvenanceprovenance is where the bytes came from and when.
currencyCurrencycurrency is what we know relative to upstream. Always present.
reassembly_checkReassemblyCheckreassembly_check is TK-2.8's verdict. Always present, carrying REASSEMBLY_CHECK_STATE_NOT_REQUESTED when the caller did not ask.
served_sha256stringserved_sha256 is the SHA-256 of content as sent. This is what makes M3 checkable BY THE CALLER: when truncation.kind is TRUNCATION_KIND_NONE and content_provenance is CONTENT_PROVENANCE_PERSISTED, it equals the hash of the representation served — text_sha256 for EXTRACTED, raw_sha256 for RAW.

ReassemblyCheck​

ReassemblyCheck is TK-2.5 + TK-2.8 as a CHECK rather than a read path.

PRD acceptance: "assembled documents contain no duplicated overlap region" and "an integrity check asserts that bytes returned hash to the stored hash; a mismatch is surfaced and never resolved by silently preferring one artefact over the other."

FieldTypeLabelDescription
stateReassemblyCheckStatestate is the verdict. Never REASSEMBLY_CHECK_STATE_UNSPECIFIED on the wire.
chunk_countint32chunk_count is how many chunks were assembled.
seams_de_overlappedint32seams_de_overlapped is how many of the joins carried a materialised overlap that was removed. It is a COUNT and not a claim: rows written by an older chunker carry none, and reporting the count says so where "overlap removed" would be a promise the reconstruction cannot keep.
max_seamsint32max_seams is the number of joins the chunk sequence HAS (chunk_count-1), the honest denominator for seams_de_overlapped.
assembled_sha256stringassembled_sha256 is the SHA-256 of the de-overlapped assembly.
persisted_sha256stringpersisted_sha256 is the SHA-256 the assembly was compared against — the stored text_sha256.
assembled_bytesint64assembled_bytes is the size of the assembly.
persisted_bytesint64persisted_bytes is the size of the persisted extraction.
detailstringdetail is a human-readable sentence for the state, so a text surface can render the verdict without re-deriving it from the numbers.

Truncation​

Truncation states what was served and what was omitted, in bytes.

TK-2.4: "when the request cannot be served whole, the response is explicitly marked truncated and STATES WHAT WAS OMITTED. Silent trimming is a defect." A boolean would satisfy "marked" and not "states what"; the counts are the difference between a marker and an answer.

FieldTypeLabelDescription
kindTruncationKindkind is why (or that) the response is bounded.
total_bytesint64total_bytes is the size of the WHOLE representation, always populated — it is the denominator without which served_bytes says nothing.
served_bytesint64served_bytes is len(content). Equal to total_bytes iff kind is TRUNCATION_KIND_NONE.
offsetint64offset is the index of the first byte served.
omitted_beforeint64omitted_before is how many bytes precede the window (equal to offset).
omitted_afterint64omitted_after is how many bytes follow the window.
detailstringdetail is a human-readable sentence naming what was omitted and why, for surfaces that render text to a model rather than reading the counts.

ContentProvenance​

ContentProvenance says WHERE THE SERVED BYTES CAME FROM.

This is the field that keeps LLD §3.4 decision 1 honest. The read path is the persisted artefact; a document that has none (the legacy corpus, which T4 backfills as artefact_state='raw_unavailable' because nothing ever persisted its bytes) is still served — from its chunks — and SAYS SO. Without this field the two cases are one byte stream and the caller cannot tell a byte-faithful read from a reconstruction.

NameNumberDescription
CONTENT_PROVENANCE_UNSPECIFIED0CONTENT_PROVENANCE_UNSPECIFIED is refused by the server's response validation.
CONTENT_PROVENANCE_PERSISTED1CONTENT_PROVENANCE_PERSISTED means the bytes came from the persisted artefact and were verified against its stored hash. This is the byte-faithful path and the only one M3 speaks about.
CONTENT_PROVENANCE_REASSEMBLED2CONTENT_PROVENANCE_REASSEMBLED means no persisted artefact exists for this version, so the bytes were reconstructed from the document's chunks with the chunker's materialised overlap removed. It is a RECONSTRUCTION of the segment sequence, not of the uploaded file: no hash is asserted about it and served_sha256 is over the reconstruction itself.
CONTENT_PROVENANCE_RENDERED_REPO_MAP3Virtual repository-map document rendered from its scoped stored sections; no duplicate blob or generic chunk copy exists.

Currency​

Currency is what we know about the served bytes RELATIVE TO UPSTREAM.

PRD §11 (v1.3): content is populated for GONE_UPSTREAM and REF_UNRESOLVED — the bytes are still valid and "never an empty result" would otherwise be satisfied by a bare error. Content is empty ONLY for a hard refusal.

NameNumberDescription
CURRENCY_UNSPECIFIED0CURRENCY_UNSPECIFIED is refused by the server's response validation.
CURRENCY_CURRENT1CURRENCY_CURRENT means the copy was verified against upstream on this read. It requires F4's live fetch and is therefore NOT EMITTED IN PHASE 1 — claim bound C3 forbids describing freshness as anything but "as of the last sync" until F4 ships, and a server that said CURRENT without checking would be making exactly the claim C3 bounds.
CURRENCY_UNVERIFIED2CURRENCY_UNVERIFIED means the copy is the one persisted at ingest and has not been checked against upstream. This is every Phase-1 response.
CURRENCY_GONE_UPSTREAM3CURRENCY_GONE_UPSTREAM means upstream reported the document deleted. The persisted bytes are served ALONGSIDE the marker (PRD §11 row 1).
CURRENCY_REF_UNRESOLVED4CURRENCY_REF_UNRESOLVED means a path-shaped upstream reference no longer resolves — a DIFFERENT fact from a deletion we have observed (PRD §11, v1.2 identity correction). The persisted bytes are served alongside it.

ReassemblyCheckState​

ReassemblyCheckState is TK-2.8's verdict.

NameNumberDescription
REASSEMBLY_CHECK_STATE_UNSPECIFIED0REASSEMBLY_CHECK_STATE_UNSPECIFIED is refused by the server's response validation.
REASSEMBLY_CHECK_STATE_NOT_REQUESTED1REASSEMBLY_CHECK_STATE_NOT_REQUESTED means verify_by_reassembly was false. The check is deliberately off by default: making it automatic would put TK-2.5's de-overlap on the hot path of every read, which is the cost LLD §3.4 decision 1 exists to avoid.
REASSEMBLY_CHECK_STATE_MATCH2REASSEMBLY_CHECK_STATE_MATCH means the de-overlapped assembly of the document's chunks is byte-identical to the persisted extraction.
REASSEMBLY_CHECK_STATE_DIVERGED3REASSEMBLY_CHECK_STATE_DIVERGED means they differ. This is a REPORTED STATE, not an error: the persisted extraction is still what was served, and PRD §11 forbids resolving the disagreement by silently preferring an artefact. The two hashes and both byte counts are in the message so the divergence is sizeable rather than merely announced.
REASSEMBLY_CHECK_STATE_NO_CHUNKS4REASSEMBLY_CHECK_STATE_NO_CHUNKS means the check was asked for and the document has no chunks visible to the caller, so there was nothing to assemble. Distinct from MATCH, which an empty-vs-empty comparison would otherwise produce.
REASSEMBLY_CHECK_STATE_NOT_APPLICABLE5REASSEMBLY_CHECK_STATE_NOT_APPLICABLE means there is nothing this check could assert: the raw representation was served (chunks are produced from the EXTRACTION, so assembling them can only ever reproduce the extraction), or the served bytes ARE the assembly (CONTENT_PROVENANCE_REASSEMBLED, where comparing them to themselves would be a tautology reported as a pass).

Representation​

Representation names WHICH artefact of a document version is being addressed.

A document has two persisted artefacts and they are different byte sequences for four of the six content types the extractor handles. Asking for one and silently receiving the other is the failure M3's red direction names, so the value is echoed on every response and the server never substitutes.

NameNumberDescription
REPRESENTATION_UNSPECIFIED0REPRESENTATION_UNSPECIFIED means the caller did not choose. On a REQUEST it is read as REPRESENTATION_EXTRACTED (the useful default for a model). On a RESPONSE it is refused by the server's own validation — a response that does not say what it served is exactly the ambiguity this enum exists to remove.
REPRESENTATION_EXTRACTED1REPRESENTATION_EXTRACTED is the persisted extracted text, hashed by text_sha256 and dated by extractor_version.
REPRESENTATION_RAW2REPRESENTATION_RAW is the persisted original bytes, hashed by raw_sha256.

TruncationKind​

TruncationKind says WHY the served bytes are not the whole representation — or that they are.

NameNumberDescription
TRUNCATION_KIND_UNSPECIFIED0TRUNCATION_KIND_UNSPECIFIED is refused by the server's response validation. It is the value a future return statement gets by forgetting, which is precisely the case that must not be able to reach a caller.
TRUNCATION_KIND_NONE1TRUNCATION_KIND_NONE means the whole representation was served.
TRUNCATION_KIND_RANGE2TRUNCATION_KIND_RANGE means the caller asked for a bounded window.
TRUNCATION_KIND_BUDGET3TRUNCATION_KIND_BUDGET means a byte budget (the caller's max_bytes, or the server default when it was 0) cut the response short.

Top

upsquad/knowledge/v1/knowledge.proto​

AgentSourceOverride​

AgentSourceOverride is one persisted disable row, including its original audit metadata. A row may remain after the source leaves the effective availability set; it does not grant access to that source.

FieldTypeLabelDescription
source_idstringsource_id identifies the source disabled for this agent.
created_bystringcreated_by is the member who originally disabled it.
created_atgoogle.protobuf.Timestampcreated_at is the original disable time; repeated disable is idempotent.

AttachSourceToUnitRequest​

AttachSourceToUnitRequest tags a source onto an org_unit OR org-wide. The acting member is taken from the caller's scope, not this message.

Org-attach contract (#1554): set scope='org' and leave unit_id empty to make the source retrievable org-wide (every pillar/team inherits it). For a pillar/team attach set scope='unit' (or leave it empty — 'unit' is the default) and supply unit_id. As a back-compat shim for the client placeholder (client#389), unit_id="org" with an empty scope is also treated as an org-attach; new clients SHOULD send scope='org' with an empty unit_id.

FieldTypeLabelDescription
source_idstringsource_id is the knowledge source to attach (required).
unit_idstringunit_id is the org_units.id (pillar/team) to attach it to. Required for a unit attach; MUST be empty for an org attach (scope='org').
visibilitystringvisibility is one of 'inherit_down'
scopestringscope is 'unit' (default — a pillar/team attach, requires unit_id) or 'org' (an org-wide attach, unit_id must be empty). (#1554.)

AttachSourceToUnitResponse​

AttachSourceToUnitResponse returns the created (or revived) binding.

FieldTypeLabelDescription
bindingSourceUnitBindingbinding is the resulting source⇄unit binding.

CreateSourceRequest​

CreateSourceRequest creates a new knowledge source in the org-owned catalog. The owning org and the creating member are taken from the caller's scope, not from this message. A source no longer carries an owning scope at creation (HLD-C §3.1, RA2 REPLACE) — attach it to one-or-many pillars/teams afterwards with AttachSourceToUnit. Fields 1/2 (the legacy owning_scope / unit_id) were dropped in the founder-approved breaking change DC-3 (#1382/#1377); their numbers + names are reserved.

FieldTypeLabelDescription
namestringname is the human-readable source name (required, non-empty).
descriptionstringdescription is an optional free-text description.
src_typestringsrc_type is one of the registered source types. Only upload
refresh_interval_secondsint32refresh_interval_seconds is the desired auto-refresh cadence in seconds; 0 (the default) means auto-refresh is off. Persisted as NULL when 0. (#1367.)
criticalitystringcriticality is one of 'low'
urlstringurl is the connector fetch target. Required and non-empty when src_type='web' (an https URL the connector SSRF-screens at fetch time, #1375) or src_type='gdrive' (a Google Drive folder URL or raw folder id, #1430); must be empty for all other source types. The DB CHECK is the backstop.

CreateSourceResponse​

CreateSourceResponse returns the created source.

FieldTypeLabelDescription
sourceSourcesource is the newly created source.

DeleteSourceRequest​

DeleteSourceRequest soft-deletes a source and hard-deletes its chunks.

FieldTypeLabelDescription
idstringid is the source UUID.

DeleteSourceResponse​

DeleteSourceResponse reports the outcome of a delete.

FieldTypeLabelDescription
chunks_removedint32chunks_removed is the number of rag_chunks rows cascade-deleted.

DetachSourceFromUnitRequest​

DetachSourceFromUnitRequest soft-deletes a source⇄unit binding, or the source's org-wide binding when scope='org' (#1554).

FieldTypeLabelDescription
source_idstringsource_id is the attached source (required).
unit_idstringunit_id is the org_units.id to detach it from. Required for a unit detach; MUST be empty for an org detach (scope='org'). As a back-compat shim, unit_id="org" with an empty scope is treated as an org detach.
scopestringscope is 'unit' (default) or 'org' (detach the org-wide binding). (#1554.)

DetachSourceFromUnitResponse​

DetachSourceFromUnitResponse reports whether an active binding was removed.

FieldTypeLabelDescription
detachedbooldetached is true when an active binding was soft-deleted; false when there was no active binding to remove.

DriveTypeBreakdown​

DriveTypeBreakdown tallies the previewed files of one content category so the UI can show "12 PDFs (40 MB), 3 Google Docs, 2 unsupported".

FieldTypeLabelDescription
categorystringcategory is a coarse content bucket: 'gdoc'
file_countint32file_count is the number of files in this category.
total_bytesint64total_bytes is the summed binary size of files in this category. Google- native files (gdoc/gslides/gsheets) report 0 bytes in Drive (they have no binary blob until exported), so their size is not counted here.

EffectiveSourceEntry​

EffectiveSourceEntry is one resolved binding tagged with its provenance.

FieldTypeLabelDescription
bindingSourceUnitBindingbinding is the resolved source⇄unit binding.
effective_sourcestringeffective_source is the provenance: 'direct'
source_unit_idstringsource_unit_id is the unit the binding was found on (the direct unit, the inherit_down ancestor, or the shared_siblings sibling). Empty for an 'org' provenance binding.

GetSourceRequest​

GetSourceRequest fetches a single source by id.

FieldTypeLabelDescription
idstringid is the source UUID.

GetSourceResponse​

GetSourceResponse returns the requested source.

FieldTypeLabelDescription
sourceSourcesource is the requested source.

GetSourceStatusRequest​

GetSourceStatusRequest fetches ingestion status for a source.

FieldTypeLabelDescription
idstringid is the source UUID.

GetSourceStatusResponse​

GetSourceStatusResponse reports ingestion progress for a source.

FieldTypeLabelDescription
source_idstringsource_id is the source UUID.
sync_statusstringsync_status is one of 'empty'
doc_countint32doc_count is the number of ingested documents.
chunk_countint32chunk_count is the total number of chunks for the source (authoritative COUNT over rag_chunks).
embedded_chunk_countint32embedded_chunk_count is the number of chunks with embeddings computed. (Maintained by FW3-b's embed worker; 0 until ingestion lands.)
pending_chunk_countint32pending_chunk_count is chunk_count - embedded_chunk_count.

IngestDocumentRequest​

IngestDocumentRequest feeds one document into a source. The owning org and the acting member are taken from the caller's scope, never from this message.

FieldTypeLabelDescription
source_idstringsource_id is the knowledge_sources UUID to ingest into (required). The source must be visible to the caller's scope and of an ingestable type (upload
filenamestringfilename is the original document filename, retained on each chunk's metadata for provenance (optional but recommended).
content_typestringcontent_type selects the text extractor: one of 'md'
contentbytescontent is the raw document bytes. Size caps (founder Design Call D5): 10 MB for md

IngestDocumentResponse​

IngestDocumentResponse reports the outcome of an ingestion.

FieldTypeLabelDescription
source_doc_idstringsource_doc_id is the deterministic per-document identity (derived from the content_hash) stamped on every chunk of this document.
chunk_countint32chunk_count is the number of chunks created for this document (0 on an idempotent hit).
token_countint32token_count is the total token count across the document's chunks.
idempotent_hitboolidempotent_hit is true when this document's content_hash was already ingested for the source; the call made no changes.
content_hashstringcontent_hash is the SHA-256 hex digest of the raw document bytes.

ListAgentSourceOverridesRequest​

ListAgentSourceOverridesRequest selects an agent UUID within the authenticated organisation's override rows; it does not establish ownership of the agent.

FieldTypeLabelDescription
agent_idstringagent_id is a required agent UUID.

ListAgentSourceOverridesResponse​

ListAgentSourceOverridesResponse contains all disable rows written by the authenticated organisation for the requested agent, ordered by source_id. Absence means this organisation has not disabled that source; it does not establish effective enablement. A pre-existing cross-org write/enforcement gap can hide an enforced disable from this read under BYPASSRLS connections: https://github.com/upsquad-ai/upsquad-core/issues/3413. Availability must still come from ListEffectiveSources. Errors, unimplemented RPCs and incomplete responses cannot establish even caller-org absence. No rows are truncated or filtered against the effective set, and this read is not cached. Retrieval-result freshness after writes is tracked separately in https://github.com/upsquad-ai/upsquad-core/issues/3415.

FieldTypeLabelDescription
overridesAgentSourceOverriderepeatedoverrides contains every persisted disable row for this org and agent.

ListEffectiveSourcesRequest​

ListEffectiveSourcesRequest resolves the effective source set. Exactly one of the three selectors must be set; the others must be empty.

FieldTypeLabelDescription
unit_idstringunit_id resolves the effective set anchored at a single pillar/team.
member_idstringmember_id resolves the effective set across all units a member belongs to.
agent_idstringagent_id resolves the effective set for an agent (agents are members in the unified org_unit tree, so this resolves the same way as member_id).

ListEffectiveSourcesResponse​

ListEffectiveSourcesResponse returns the resolved, de-duplicated set.

FieldTypeLabelDescription
entriesEffectiveSourceEntryrepeatedentries are the effective sources, one per distinct source_id.

ListSourceUnitsRequest​

ListSourceUnitsRequest lists the units a source is attached to.

FieldTypeLabelDescription
source_idstringsource_id is the knowledge source (required).

ListSourceUnitsResponse​

ListSourceUnitsResponse returns a source's active bindings.

FieldTypeLabelDescription
bindingsSourceUnitBindingrepeatedbindings are the source's active source⇄unit attachments. GRANTS ONLY — withholds are reported by ListSourceWithholds (#3222).

ListSourceWithholdsRequest​

ListSourceWithholdsRequest lists the active withholds on one unit.

FieldTypeLabelDescription
unit_idstringunit_id is the org_units.id whose withholds to list (required). This lists the withholds set AT this unit, not the ones it inherits from an ancestor — "what did this unit's Manager take away", which is the set that unit's Manager can act on.

ListSourceWithholdsResponse​

ListSourceWithholdsResponse returns the unit's active withholds.

FieldTypeLabelDescription
withholdsSourceWithholdrepeatedwithholds are the unit's active binding_kind='withhold' rows, ordered by source_id.

ListSourcesRequest​

ListSourcesRequest pages the org-owned source catalog. After the RA2 REPLACE (HLD-C §3.1) a source has no owning scope, so the owning_scope/unit_id/ include_inherited filters are retained for wire-compatibility but IGNORED by the server — use ListEffectiveSources(unit_id) for the "RAG on this pillar/team" view with provenance. They are not removed (no further proto break) but carry no semantics.

FieldTypeLabelDescription
owning_scopestringDeprecated: ignored after HLD-C (the catalog is org-wide). Was an 'org'
unit_idstringDeprecated: ignored after HLD-C. Was a single pillar/team filter.
include_inheritedboolDeprecated: ignored after HLD-C. Was the inherit-up listing flag.
page_sizeint32page_size bounds the page (default 50, max 100).
page_tokenstringpage_token is the opaque cursor from a previous response.

ListSourcesResponse​

ListSourcesResponse is a page of sources.

FieldTypeLabelDescription
sourcesSourcerepeatedsources is the page of visible sources.
next_page_tokenstringnext_page_token is the cursor for the next page; empty when exhausted.

PreviewDriveFolderRequest​

PreviewDriveFolderRequest asks the Drive folder connector to size a folder before a gdrive source is created (#1430). It carries no source id — nothing is persisted.

FieldTypeLabelDescription
folderstringfolder is the Google Drive folder URL (e.g. https://drive.google.com/drive/folders/&lt;ID>) or a raw folder id. The folder must already be shared (Viewer) with the connector's service-account email.

PreviewDriveFolderResponse​

PreviewDriveFolderResponse reports the size of a Drive folder without ingesting it.

FieldTypeLabelDescription
total_bytesint64total_bytes is the summed binary size of all INGESTABLE files (excludes unsupported types and Google-native files, which report 0 binary bytes). It is a download-size estimate so the UI can warn before a large sync.
file_countint32file_count is the number of ingestable files the sync would process.
unsupported_countint32unsupported_count is the number of files skipped because their MIME type is not ingestable.
breakdownDriveTypeBreakdownrepeatedbreakdown is the per-category tally (one entry per non-empty category).
truncatedbooltruncated is true when the folder hit the preview scan caps (max file count or max recursion depth); the totals are then a lower bound, not exact.

RefreshSourceRequest​

RefreshSourceRequest triggers a manual re-fetch of a source.

FieldTypeLabelDescription
source_idstringsource_id is the source UUID to refresh (required).

RefreshSourceResponse​

RefreshSourceResponse reports the outcome of a refresh trigger.

FieldTypeLabelDescription
statusstringstatus is a machine-readable outcome: 'manual' — upload
messagestringmessage is a human-readable explanation of the status.

SetAgentSourceEnabledRequest​

SetAgentSourceEnabledRequest toggles a per-agent disable override.

FieldTypeLabelDescription
agent_idstringagent_id is the agent whose source visibility is being changed.
source_idstringsource_id is the source being enabled/disabled for the agent.
enabledboolenabled=false inserts a disable override; enabled=true removes it.

SetAgentSourceEnabledResponse​

SetAgentSourceEnabledResponse echoes the resulting enabled state.

FieldTypeLabelDescription
enabledboolenabled is the effective state after the call (true = agent retrieves the source, false = disabled).

SetSourceWithholdRequest​

SetSourceWithholdRequest sets or clears a Manager subtree-withhold on a knowledge source for a unit (#3222). The acting Manager is taken from the caller's scope, never from this message.

FieldTypeLabelDescription
unit_idstringunit_id is the org_units.id at which the withhold applies (required). The caller MUST be this unit's Manager (org_units.manager_member_id). The withhold scopes to this unit AND its whole subtree.

There is no org-grain form of this request, and that is a constraint rather than an omission: migration 231's ksu_withhold_is_unit_scoped_check makes an org-scoped withhold unstorable, because such a row names no subtree — the grant predicate refuses to count it and the subtract pass never finds it, so it would be an operator action that reports success and changes nothing. | | source_id | string | | source_id is the knowledge_sources.id to withhold / un-withhold for the subtree (required). | | withheld | bool | | withheld=true sets the withhold (subtracts the source from the subtree); withheld=false clears it (the subtree may again inherit or be granted the source). Both directions are idempotent. | | reason | string | | reason is an optional free-text note recorded on the audit row. |

SetSourceWithholdResponse​

SetSourceWithholdResponse reports the resulting withhold state.

FieldTypeLabelDescription
unit_idstringunit_id echoes the unit the withhold applies at.
source_idstringsource_id echoes the withheld source.
withheldboolwithheld is the resulting state (true = an active withhold now exists).

Source​

Source is a scope-agnostic, org-owned knowledge corpus. Its retrieval visibility is decided entirely by its knowledge_source_units bindings (HLD-C §3.1), NOT by a single owning scope. Fields 4/5 (the legacy owning_scope / unit_id, HLD-A D3 1:1 model) were dropped in the RA2 REPLACE (#1382/#1377, founder-approved breaking change DC-3); their numbers + names are reserved so they can never be re-used.

FieldTypeLabelDescription
idstringid is the source's UUID.
namestringname is the human-readable source name.
descriptionstringdescription is an optional free-text description.
src_typestringsrc_type is one of 'upload'
sync_statusstringsync_status is one of 'empty'
doc_countint32doc_count is the number of ingested documents in the source.
chunk_countint32chunk_count is the cached chunk count (authoritative count is COUNT(rag_chunks WHERE source_id = id)).
created_bystringcreated_by is the member id that created the source.
created_atgoogle.protobuf.Timestampcreated_at is the source creation timestamp.
updated_atgoogle.protobuf.Timestampupdated_at is the last-modification timestamp.
last_refreshed_atgoogle.protobuf.Timestamplast_refreshed_at is the timestamp of the most recent successful refresh (manual re-fetch or scheduled connector sync). Unset until the source has been refreshed at least once. (MVP RAG refresh, #1367.)
refresh_interval_secondsint32refresh_interval_seconds is the desired auto-refresh cadence in seconds. 0 means auto-refresh is off (the column is NULL in the DB). The scheduled connector worker that honours this cadence is Track D; FW3 persists the value only. (MVP RAG refresh, #1367.)
criticalitystringcriticality is one of 'low'
urlstringurl is the connector fetch target. For src_type='web' it is the page URL (the Web URL connector enforces an https-only scheme allowlist + SSRF egress guard, #1375). For src_type='gdrive' it is the Google Drive folder URL or raw folder id the connector lists + ingests (the Drive folder connector, #1430). Empty for all other source types.

SourceUnitBinding​

SourceUnitBinding mirrors a knowledge_source_units row: a source attached to one org_unit with a visibility mode, OR an org-wide attachment (#1554). (RA1, #1381, migration 107; org scope migration 116.)

FieldTypeLabelDescription
idstringid is the binding's UUID.
org_idstringorg_id is the owning organisation.
source_idstringsource_id is the attached knowledge source.
unit_idstringunit_id is the org_units.id the source is attached to. Empty for an org-scoped binding (owning_scope='org').
visibilitystringvisibility is one of 'inherit_down'
configured_bystringconfigured_by is the member id that created the binding.
created_atgoogle.protobuf.Timestampcreated_at is the binding creation timestamp.
updated_atgoogle.protobuf.Timestampupdated_at is the last-modification timestamp.
owning_scopestringowning_scope is 'unit' (a pillar/team attachment; unit_id is set) or 'org' (an org-wide attachment; unit_id is empty). An org binding is unioned into every scope's effective set. (#1554, migration 116.)

SourceWithhold​

SourceWithhold is ONE active knowledge_source_units row with binding_kind='withhold' (#3222, migration 231).

It is a distinct message from SourceUnitBinding rather than a flag on it: a withhold carries no visibility mode that means anything (the subtract pass is scoped by the unit chain, not by visibility) and no owning_scope other than 'unit', so the fields SourceUnitBinding would contribute are precisely the ones that would mislead a reader.

FieldTypeLabelDescription
idstringid is the withhold row's UUID.
source_idstringsource_id is the source being withheld.
unit_idstringunit_id is the org_units.id the withhold applies at. Its whole subtree is covered.
configured_bystringconfigured_by is the member id of the Manager who set the withhold.
created_atgoogle.protobuf.Timestampcreated_at is when the withhold row was first written.
updated_atgoogle.protobuf.Timestampupdated_at is the last-modification timestamp.

UpdateSourceRequest​

UpdateSourceRequest mutates a source's editable attributes. Every mutable field is optional: when a field is unset it is left unchanged, when set it replaces the stored value. id is required.

FieldTypeLabelDescription
idstringid is the source UUID to update (required).
namestringoptionalname, when set, replaces the source name (must be non-empty when present).
descriptionstringoptionaldescription, when set, replaces the description (empty string clears it).
refresh_interval_secondsint32optionalrefresh_interval_seconds, when set, replaces the auto-refresh cadence; 0 turns auto-refresh off (persisted as NULL).
criticalitystringoptionalcriticality, when set, replaces the criticality ('low'
urlstringoptionalurl, when set, replaces the fetch target of a src_type='web' source. Must be a non-empty https URL; only meaningful for web sources. (#1375.)

UpdateSourceResponse​

UpdateSourceResponse returns the updated source.

FieldTypeLabelDescription
sourceSourcesource is the source after the update.

KnowledgeService​

KnowledgeService is the external (Connect / gRPC) surface for knowledge source lifecycle management. All operations are tenant-scoped via JWT-derived scope claims and PostgreSQL row-level security; the owning org and the acting member are taken from the request scope, never from the request body.

Access control (HLD §7, founder Design Call D6):

  • CreateSource / DeleteSource / SetAgentSourceEnabled: clearance >= L3 AND the knowledge.manage role capability.
  • ListSources / GetSource / GetSourceStatus: clearance >= L1 AND the knowledge.read capability; results are further filtered by the scope-visibility RLS policy on knowledge_sources.
Method NameRequest TypeResponse TypeDescription
CreateSourceCreateSourceRequestCreateSourceResponseCreateSource registers a new knowledge source in the org-owned catalog (HLD-C §3.1 — sources are scope-agnostic; attach them to pillars/teams afterwards with AttachSourceToUnit). The owning org and creator are derived from the caller's scope. The source starts empty (sync_status='empty') unless its src_type is a not-yet-implemented connector, in which case it is created 'disabled'.
ListSourcesListSourcesRequestListSourcesResponseListSources pages the org-owned source catalog (org-isolation RLS only; after HLD-C there is no per-scope owning filter). Use ListEffectiveSources to see the resolved set for a pillar/team/agent with provenance.
GetSourceGetSourceRequestGetSourceResponseGetSource returns a single source by id, subject to the same scope-visibility policy as ListSources.
UpdateSourceUpdateSourceRequestUpdateSourceResponseUpdateSource mutates the editable attributes of a source (name, description, auto-refresh cadence, criticality). All update fields are optional: an unset field is left unchanged. Clearance >= L5 AND knowledge.manage (MVP edit floor, #1367). src_type is immutable; scope is managed via AttachSourceToUnit, not UpdateSource. (MVP RAG refresh/ criticality, #1367.)
RefreshSourceRefreshSourceRequestRefreshSourceResponseRefreshSource triggers a manual re-fetch of a source's content. For the upload
DeleteSourceDeleteSourceRequestDeleteSourceResponseDeleteSource soft-deletes the source row and hard-deletes its derived chunks via ON DELETE CASCADE (founder Design Call D2). A tamper-evident audit row records the deletion and the count of chunks removed. The retained artifact for regulated tenants is the source document, not the reproducible chunks.
SetAgentSourceEnabledSetAgentSourceEnabledRequestSetAgentSourceEnabledResponseSetAgentSourceEnabled toggles a per-agent disable override for a source. enabled=false inserts an override row (the agent stops retrieving the source even though its scope grants availability); enabled=true removes the row. Availability can only be narrowed by an agent, never widened.
ListAgentSourceOverridesListAgentSourceOverridesRequestListAgentSourceOverridesResponseListAgentSourceOverrides reads the live disable rows written by the authenticated organisation for an agent UUID. Requires L1 and knowledge.read. This is separate from ListEffectiveSources availability and provenance.
GetSourceStatusGetSourceStatusRequestGetSourceStatusResponseGetSourceStatus reports ingestion progress for a source so the UI can render a sync indicator: total documents, total chunks, and the embedded-vs-pending split. (Embedded/pending are populated by FW3-b's embed worker; FW3-a returns the cached counts and the persisted status.)
PreviewDriveFolderPreviewDriveFolderRequestPreviewDriveFolderResponsePreviewDriveFolder lists a Google Drive folder (the Drive folder connector, #1430) WITHOUT ingesting anything and returns the overall size + file count + a per-type breakdown so the UI can show the user how big a sync will be BEFORE they commit to creating the gdrive source. The folder must already be shared (Viewer) with the connector's service-account email; the request carries the folder URL or raw folder id. This is a read-only dry-run: no knowledge_sources row is created and nothing is chunked or embedded. Clearance >= L5 AND knowledge.manage (same floor as CreateSource — only a source manager previews a folder, and the file listing is sensitive). When the gdrive connector is not configured on the deployment (no GDRIVE_CREDENTIALS_FILE) the call returns FailedPrecondition.
IngestDocumentIngestDocumentRequestIngestDocumentResponseIngestDocument feeds one document into a source's corpus (FW3-b, #1325). The server extracts text from the supplied bytes (markdown / html / pdf / plain), chunks it with the existing headings-aware chunker, embeds the chunks via the existing embedding pipeline, and persists them to rag_chunks + context_embeddings stamped with the source_id and the source's owning scope. Ingestion is idempotent on the document's content_hash: re-sending identical bytes for the same source is a no-op that returns the prior result (idempotent_hit=true). Access control: clearance >= L2 (founder Design Call D6 Ingest floor) AND the knowledge.manage capability. Only upload
AttachSourceToUnitAttachSourceToUnitRequestAttachSourceToUnitResponseAttachSourceToUnit tags a source onto an org_unit (pillar/team) with a visibility mode, exactly like attaching a tool to a unit (org_unit_tools, migration 064). A source may be attached to many units; availability is then computed by the same org→pillar→team inheritance walk the tool model uses. The acting member (configured_by) is taken from the caller's scope, never the request body. Clearance >= L5 (the consolidated knowledge management floor) AND knowledge.manage. (RA1, #1381, HLD-C §7.)
DetachSourceFromUnitDetachSourceFromUnitRequestDetachSourceFromUnitResponseDetachSourceFromUnit soft-deletes a source⇄unit binding (re-attach later is allowed). Clearance >= L5 AND knowledge.manage. (RA1, #1381, HLD-C §7.)
ListSourceUnitsListSourceUnitsRequestListSourceUnitsResponseListSourceUnits returns the units a source is currently attached to (its active GRANT bindings). It does NOT report withholds — a withhold is a restriction and this response says "attached", which is the one description of a withhold that is false. Read withholds with ListSourceWithholds. Clearance >= L1 AND knowledge.read. (RA1, #1381.)
SetSourceWithholdSetSourceWithholdRequestSetSourceWithholdResponseSetSourceWithhold sets or clears a Manager subtree-WITHHOLD on a knowledge source for a unit (TK-7.3 / F5c, #3222). A withhold is a knowledge_source_units row with binding_kind='withhold' (migration 231) keyed to (source, unit); it SUBTRACTS that source from the effective knowledge set of the unit AND its whole subtree, beating every grant however that grant entered the union — direct, inherited-down, shared-siblings, org-wide, or an accepted cross-offer.

AUTHORITY (founder decision on #3222, Option A): the unit's Manager (org_units.manager_member_id) — the SAME authority as the MCP binding approval machinery (ApproveMCPServerBinding / SetMCPServerWithhold), no new governance actor. The root unit's Manager reaches org-wide; a leaf's Manager reaches only their own subtree. A non-Manager caller is permission_denied and a unit with no Manager is failed_precondition (fail closed).

It is a DIRECT write and not a pending→approve two-step, exactly as MCP's own withhold is: a restriction that sits inert while awaiting approval is a deny that does not deny, which is the fail-open shape of a fail-closed control. The approval machinery contributes its AUTHORITY and its AUDIT surface here, not its pending state.

Capability knowledge.manage, unit-scoped. There is deliberately NO clearance floor — Manager identity IS the authority, matching SetMCPServerWithhold. Emits a knowledge_subtree_withheld audit row on both set and clear. | | ListSourceWithholds | ListSourceWithholdsRequest | ListSourceWithholdsResponse | ListSourceWithholds returns the ACTIVE withholds on one unit — the read the Team page renders withhold state from (F7, upsquad-client#857), and the Manager's view of the restrictions they have set.

It is a separate RPC rather than a binding_kind field on ListSourceUnits because those two responses answer opposite questions ("what does this unit have" vs "what has been taken away from it"), and one list that mixes them relies on every existing reader starting to check a discriminator it never had to check before. Every row here IS a withhold by construction.

Clearance >= L1 AND knowledge.read, unit-scoped: a restriction on a team is visible to that team, not only to the Manager who set it (PRD #2995 R6 — the named failure mode is a Manager believing a withhold is stronger than it is, and an unreadable restriction is that failure with the volume up). | | ListEffectiveSources | ListEffectiveSourcesRequest | ListEffectiveSourcesResponse | ListEffectiveSources resolves the effective source set for exactly one of {unit_id, member_id, agent_id} via the org→pillar→team inheritance walk (direct ∪ inherited-down ∪ shared-siblings; de-dup direct > inherited > sibling), each entry tagged with its provenance. Clearance >= L1 AND knowledge.read. (RA1, #1381, HLD-C §4/§7.) | | GetDocument | GetDocumentRequest | GetDocumentResponse | GetDocument returns ONE document version whole, or a bounded window of it, from the artefact PERSISTED AT INGEST (T3 #3075, LLD #3072 §3.4, HLD §4.5). Retrieval hands back the chunk that matched; this hands back the document behind it, which is #2619's relief and PRD #2995's goal G2.

Reassembly from chunks is TK-2.8's CHECK and NOT the read path: serving from reassembly would make every read depend on chunk hygiene and would put the de-overlap on the hot path for no user benefit. It runs only when the request asks (verify_by_reassembly), and its verdict is a reported state — never a silent preference for one artefact over the other.

truncation and currency are non-optional in the sense that matters: the server validates its OWN response and refuses to emit an _UNSPECIFIED in either. NFR-4 says no path may return content that LOOKS whole and is not, and a field that can be omitted is a path that can look whole.

Access control: knowledge.read AND NO CLEARANCE FLOOR. NG-3 binds content retrieval; knowledge is TEAM-scoped, and the team gate is the effective source set — the SAME set retrieval resolves, so a document reachable by search is reachable here and one that is not, is not. The knowledge MANAGEMENT floors above are untouched by this and must not be extended over it (PRD #2995 claim bound C2). |

Top

upsquad/knowledge/v1/repo.proto​

BindRepoCredentialRequest​

BindRepoCredentialRequest carries the scoped connection operation contract.

FieldTypeLabelDescription
team_unit_idstringExact owning team; authenticated org is never accepted from the request.
repo_idstringRegistered repository id scoped to the named team.
credential_idstringExact isolated team credential id.
expected_credential_epochint64Exact credential epoch observed by the caller; stale writes are refused.
expected_binding_revisionint64Zero means no binding exists; a replacement names its current revision.

BindRepoCredentialResponse​

BindRepoCredentialResponse carries the scoped connection operation contract.

FieldTypeLabelDescription
connectionRepoConnectionStatePersisted sanitized source-connection state.

CheckTeamRepoConnectionRequest​

CheckTeamRepoConnectionRequest carries the scoped connection operation contract.

FieldTypeLabelDescription
team_unit_idstringExact owning team; authenticated org is never accepted from the request.
repo_idstringRegistered repository id scoped to the named team.
expected_binding_revisionint64Exact binding revision observed by the caller; stale writes are refused.

CheckTeamRepoConnectionResponse​

CheckTeamRepoConnectionResponse carries the scoped connection operation contract.

FieldTypeLabelDescription
connectionRepoConnectionStatePersisted sanitized source-connection state.

ConfigureRepoMapGeneratorRequest​

ConfigureRepoMapGeneratorRequest never takes an org id or credentials.

FieldTypeLabelDescription
team_unit_idstringExact team managed by the authenticated caller.
expected_revisionint64Zero creates; an existing setup requires its current revision.
optionsRepoMapGeneratorOptionsExplicit finite options to save or resume.

ConfigureRepoMapGeneratorResponse​

ConfigureRepoMapGeneratorResponse reports the committed step, not fake readiness.

FieldTypeLabelDescription
setupRepoMapGeneratorStateActual setup state after the bounded owner operation.

CreateTeamRepoCredentialRequest​

CreateTeamRepoCredentialRequest carries the scoped connection operation contract.

FieldTypeLabelDescription
team_unit_idstringExact owning team; authenticated org is never accepted from the request.
providerRepoProviderDeclared provider; V1b accepts GitHub only.
provider_hoststringCanonical host; V1b accepts github.com only.
labelstringHuman-readable connection name.
secretTeamRepoCredentialSecretWrite-only replacement credential material.

CreateTeamRepoCredentialResponse​

CreateTeamRepoCredentialResponse carries the scoped connection operation contract.

FieldTypeLabelDescription
credentialTeamRepoCredentialRedacted persisted credential metadata.

Divergence​

Divergence is what a regeneration WOULD have written to a locked section.

FieldTypeLabelDescription
idstringDivergence row id; the handle SetRepoMapSectionLock acknowledges.
proposed_bodystringThe body the run proposed. Verbatim: a curator deciding whether to accept the drift needs the text, not a summary of it.
run_idstringThe generation run that proposed it.
generated_commitstringThe commit that run was pinned to.
detected_atgoogle.protobuf.TimestampWhen it was detected.

GeneratedSection​

GeneratedSection is one section a generation run produced.

FieldTypeLabelDescription
kindSectionKindWhich section it is.
bodystringThe generated text.

GetRepoMapGeneratorRequest​

GetRepoMapGeneratorRequest selects one authenticated team's setup.

FieldTypeLabelDescription
team_unit_idstringTeam whose current setup is requested.

GetRepoMapGeneratorResponse​

GetRepoMapGeneratorResponse remains truthful when nothing has been configured.

FieldTypeLabelDescription
setupRepoMapGeneratorStateCurrent setup including absence, pending dependencies and server authority.

GetRepoMapRequest​

GetRepoMapRequest reads one repository's map.

FieldTypeLabelDescription
repo_idstringThe registry entry id. Either this or path_with_namespace is required.
path_with_namespacestringThe upstream path, for callers holding a path rather than an id.
team_unit_idstringThe team unit to resolve path_with_namespace within. Required when path_with_namespace is used.
providerRepoProviderOptional path qualifier; cannot accompany repo_id.
provider_hoststringoptionalOmitted: no host filter. Explicit empty: unknown-host legacy namespace.

GetRepoMapResponse​

GetRepoMapResponse carries the map and its read-time staleness.

FieldTypeLabelDescription
mapRepoMapThe map. Its staleness is never absent.

GitHubRepoAppSecret​

GitHubRepoAppSecret is write-only. Use a dedicated read-only App; the PEM's provider-side authority can be broader than the token this adapter mints.

FieldTypeLabelDescription
app_idstringNumeric App id from its settings, not its client id or installation id.
private_key_pemstringRSA private key, never returned, logged, or included in audit metadata.

GitHubRepoPATSecret​

GitHubRepoPATSecret requires a fine-grained, selected-repository PAT with Contents:read and Metadata:read. Opaque permissions cannot be verified by possession; acknowledgement never claims the token was down-scoped.

FieldTypeLabelDescription
tokenstringWrite-only fine-grained PAT; never returned or logged.
acknowledge_unverified_scopeboolExplicit acknowledgement that opaque PAT permissions cannot be proven.
expires_atgoogle.protobuf.TimestampDeclared credential expiry; omitted when no expiry is declared.

ListRepoMapRunsRequest​

ListRepoMapRunsRequest scopes and bounds history.

FieldTypeLabelDescription
team_unit_idstringExact owning team.
repo_idstringRegistered repository.
page_sizeint32Positive maximum capped at one hundred.
page_tokenstringOpaque cursor bound to org/team/repository.

ListRepoMapRunsResponse​

ListRepoMapRunsResponse contains no source bytes.

FieldTypeLabelDescription
runsRepoMapGenerationRunrepeatedSanitized history in admission order.
next_page_tokenstringEmpty only when no further page exists.

ListReposRequest​

ListReposRequest pages a team's registry.

FieldTypeLabelDescription
team_unit_idstringThe team unit whose registry to read. Required.
include_archivedboolInclude repositories archived upstream. Default false.
page_sizeint32Page size; clamped server-side.
page_tokenstringOpaque page token.

ListReposResponse​

ListReposResponse is one page of a team's registry.

FieldTypeLabelDescription
reposReporepeatedThe page.
next_page_tokenstringToken for the next page; empty when the page is the last.

ListTeamRepoCredentialsRequest​

ListTeamRepoCredentialsRequest carries the scoped connection operation contract.

FieldTypeLabelDescription
team_unit_idstringExact owning team; authenticated org is never accepted from the request.
page_sizeint32Page size, server-clamped to at most 100.
page_tokenstringOpaque continuation from a prior page.

ListTeamRepoCredentialsResponse​

ListTeamRepoCredentialsResponse carries the scoped connection operation contract.

FieldTypeLabelDescription
credentialsTeamRepoCredentialrepeatedRedacted credentials in this bounded page.
next_page_tokenstringOpaque continuation, empty at the end.
can_managebooloptionalReal L3 management gate for check/bind/unbind/revoke, not secret supply. Omission on an older server differs from denial; writes recheck the gate.
denial_reasonstringVerbatim denial from the actual server write authority.
can_supply_secretbooloptionalReal L4 gate for create/rotate; independent of L3 management authority.
secret_denial_reasonstringVerbatim create/rotate authority denial, absent when secret supply is allowed.

PutRepoMapRequest​

PutRepoMapRequest applies a generated map at a pinned commit.

FieldTypeLabelDescription
repo_idstringThe repository the map describes.
generation_run_idstringTK-8.5: the generation run id. Required.
generated_commitstringTK-8.3: the commit the governed checkout was pinned to. Required, and a full 40-hex sha — a branch name is not a pin.
generated_refstringThe ref that commit was taken from. Required.
sectionsGeneratedSectionrepeatedThe generated sections.

PutRepoMapResponse​

PutRepoMapResponse states what the regeneration DID.

applied/preserved are reported separately because a regeneration that rewrote everything and one that changed nothing must not look alike to the caller that ran it.

FieldTypeLabelDescription
mapRepoMapThe map after the apply.
applied_sectionsSectionKindrepeatedSections whose bodies were replaced.
preserved_sectionsSectionKindrepeatedLocked sections kept verbatim.
recorded_divergencesDivergencerepeatedOne per preserved section whose generated body actually differed.

RecordRepoHeadRequest​

RecordRepoHeadRequest stores a branch-head observation.

FieldTypeLabelDescription
repo_idstringThe registry entry the observation belongs to.
head_commitstringThe observed head commit sha.
head_refstringThe ref that head belongs to. REQUIRED whenever head_commit is set: an observation of nothing nameable is what let the marker attribute it to the map's ref. The schema makes the ref-less form unrepresentable.
commits_behindint32optionalHow many commits behind_base_commit is behind that head, if measured.
behind_base_commitstringoptionalThe commit the distance was measured from. Required whenever commits_behind is set.

RecordRepoHeadResponse​

RecordRepoHeadResponse carries the updated entry.

FieldTypeLabelDescription
repoRepoThe repository with its new head observation.

RegenerateRepoMapRequest​

RegenerateRepoMapRequest requests a run, never supplies a producer identity.

FieldTypeLabelDescription
team_unit_idstringExact owning team.
repo_idstringRegistered repository, already bound through the governed connection.
request_idstringCaller UUID deduplication key, reused for a retry of this intent.

RegenerateRepoMapResponse​

RegenerateRepoMapResponse describes durable accepted intent, not completion.

FieldTypeLabelDescription
intent_idstringDurable intent id.
statestringCurrent queued/capacity/admitted state.
reasonstringSanitized limiting condition when present.

RegisterRepoRequest​

RegisterRepoRequest registers one repository to a team.

FieldTypeLabelDescription
team_unit_idstringThe team unit to register it to.
gitlab_project_idstringUpstream GitLab project id.
path_with_namespacestringUpstream path.
default_branchstringDefault branch.
primary_languagestringPrimary language, if known.
responsibilitystringREQUIRED one-line responsibility.
linksRegisterRepoRequest.LinksEntryrepeatedNamed links.
providerRepoProviderOmission retains the legacy GitLab/unknown-host byte-preserving contract.
provider_hoststringNew GitLab requires a host. GitHub owner/repo defaults to github.com.
repository_urlstringOptional HTTPS location; must agree with supplied structured identity.

RegisterRepoRequest.LinksEntry​

FieldTypeLabelDescription
keystring
valuestring

RegisterRepoResponse​

RegisterRepoResponse carries the created registry entry.

FieldTypeLabelDescription
repoRepoThe registered repository.

Repo​

Repo is a team registration, not upstream access verification.

FieldTypeLabelDescription
idstringRegistry row id.
team_unit_idstringThe team unit this repository is registered to.
gitlab_project_idstringUpstream GitLab project id.
path_with_namespacestringUpstream path, e.g. "sre/incident-tooling".
default_branchstringBranch maps are generated from unless a map says otherwise.
primary_languagestringPrimary language, if known.
responsibilitystringThe one-line statement of what this repository is responsible for.
linksRepo.LinksEntryrepeatedNamed links (issues, docs, dashboards).
archivedboolWhether the repository is archived upstream.
registered_atgoogle.protobuf.TimestampWhen it was registered to this team.
headRepoHeadLast observed head; absent means never observed.
has_mapboolWhether a map exists for this repository.
providerRepoProviderDeclared provider. Historical rows are GitLab with unknown host.
provider_hoststringCanonical host; empty means unknown, not gitlab.com.
repository_urlstringServer-derived HTTPS location, absent when host is unknown; not access proof.
source_access_statestringProvider evidence is separate from registration; unknown is not denial.
source_access_last_confirmed_atgoogle.protobuf.TimestampLast positive source-access observation; absent means never confirmed.
map_withheld_reasonstringPersisted denial; the map remains retained but its bytes are withheld.
map_withheldboolAuthoritative read barrier, independent of has_map (which means existence). True may have an empty reason when source evidence was no longer retained.
connectionRepoConnectionStateAuthorized L3 connection projection; absent for lower-clearance registry readers.

Repo.LinksEntry​

FieldTypeLabelDescription
keystring
valuestring

RepoConnectionState​

RepoConnectionState reports source readiness independently of map generation. It carries no token, PEM, raw provider message or sampled source bytes.

FieldTypeLabelDescription
repo_idstringRegistered repository id scoped to the named team.
credential_idstringExact isolated team credential id.
statusstringServer-owned lifecycle state.
source_access_statestringTyped server evidence class, independent of generator readiness.
reasonstringSanitized server reason; no raw provider error body.
binding_revisionint64Monotonic binding revision fencing older observations.
checked_credential_epochint64Credential epoch used for the latest verified binding.
access_last_confirmed_atgoogle.protobuf.TimestampLast positive exact-repository access verification, not a time lease.
last_checked_atgoogle.protobuf.TimestampLast completed provider observation.
next_check_atgoogle.protobuf.TimestampNext eligible bounded check after shared quota/backoff.
not_visible_sincegoogle.protobuf.TimestampFirst qualified not-visible observation, only when persisted.
effective_discovery_interval_secondsint32Actual cadence used for the two-observation loss rule.

RepoHead​

RepoHead is the last observed head of a repository's default branch.

Its ABSENCE is meaningful and is the Day-0 state: no observation has been made, so staleness is UNKNOWN. It is never inferred.

FieldTypeLabelDescription
commitstringThe observed commit sha.
observed_atgoogle.protobuf.TimestampWhen it was observed.
refstringThe ref this observation is OF. Not decoration: a freshness observation is a fact about a (repository, ref) PAIR, and without it a marker rendered for a map generated from another branch names THAT branch beside this sha — well-formed and false. Staleness is UNKNOWN when it differs from the map's generated_ref, and the sha is withheld.
commits_behindint32optionalHow many commits the map is behind this head. optional because 0 is a REAL answer ("level with head") that must not be confused with "not measured".
behind_base_commitstringoptionalThe map commit commits_behind was measured FROM. A distance is a fact about a pair, so the base travels with the count; a count whose base is not the current map commit is not reported.

RepoMap​

RepoMap is a repository's agent-facing map.

FieldTypeLabelDescription
idstringMap row id.
repo_idstringThe repository it describes.
path_with_namespacestringUpstream path of that repository, so a map is legible on its own.
generation_run_idstringTK-8.5: the generation run that produced it.
generated_commitstringTK-8.5: the commit it was generated from.
generated_refstringThe ref that commit was taken from.
generated_atgoogle.protobuf.TimestampWhen it was generated.
sectionsRepoMapSectionrepeatedThe sections, in rendering order.
stalenessStalenessHow current the map is. NEVER absent — see the file header.
providerRepoProviderIdentity from the resolved registry entry.
provider_hoststringCanonical host from the registry; empty means unknown.
rendered_markdownstringShared agent-facing representation, including access, coverage and C6.

RepoMapGenerationRun​

RepoMapGenerationRun is sanitized history, with real metering and pinned provenance.

FieldTypeLabelDescription
idstringDurable generation-run id and virtual historical document reference.
repo_idstringRegistered repository id.
statestringRunning means a current lease; expired leases render stalled immediately.
stagestringCurrent or terminal producer stage.
reasonstringNamed failure or refusal; no source body/provider error dump.
generated_commitstringImmutable source commit; absent before resolution.
generated_refstringExact target ref resolved by this run.
created_atgoogle.protobuf.TimestampAdmission time, after actual capacity reservation.
finished_atgoogle.protobuf.TimestampTerminal completion time, when available.
wire_attemptsint32Actual total charged wire attempts.
input_tokensint64Actual reconciled input token consumption including cache classes.
output_tokensint64Actual reconciled output tokens.
model_callsint32Actual paid attempts including unknown/failed attempts.

RepoMapGeneratorOptions​

RepoMapGeneratorOptions contains explicit choices, never hidden budget defaults.

FieldTypeLabelDescription
endpoint_idstringApproved endpoint resource; no URL or provider key is accepted here.
model_idstringExact named-provider model id declared by that endpoint.
model_providerstringNamed model provider disclosed alongside FastRouter when applicable.
agent_clearanceint32Agent deployment clearance, validated by the real AgentService gate.
budget_tokensint64Explicit positive AGENT-grain token cap; billing windows derive from owner.
automatic_interval_secondsint64Explicit automatic cadence. Zero is unconfigured, never sixty minutes.
automatic_daily_limitint32Explicit automatic admissions per team UTC day. Manual uses the same money cap.
baseline_versionstringInstalled structural policy version the user has reviewed.
confirm_baselineboolExplicit confirmation of the shipped policy, not an approval bypass.
expected_rejected_binding_idstringExplicit rejected binding to re-request through its owning service.

RepoMapGeneratorState​

RepoMapGeneratorState distinguishes partial setup from verified readiness.

FieldTypeLabelDescription
team_unit_idstringExact owning team, scoped to the authenticated org.
revisionint64Monotonic desired-configuration revision.
agent_idstringActual registered service-agent id when that stage completed.
binding_idstringActual owner binding id; never a fabricated generic approval id.
statestringNamed current setup/readiness state.
reasonstringReal owner denial or truthful missing dependency.
dependency_resource_idstringResource requiring approval or repair, when supplied by its owner.
last_checked_atgoogle.protobuf.TimestampLast completed owner-state observation; absent means never checked.
next_check_atgoogle.protobuf.TimestampScheduled independent owner-state recheck.
generation_enabledboolFalse until the real production generation switch is activated.
can_manageboolDerived by the exact same server gate that authorizes mutations.
manage_denial_reasonstringVerbatim gate reason when mutation authority is absent.
optionsRepoMapGeneratorOptionsSaved explicit choices, preserved across reload.
not_recently_checkedboolTrue when owner state has not been checked within two setup intervals.
setup_step_remainingboolTrue while an authenticated caller must advance remaining owner-write stages.

RepoMapSection​

RepoMapSection is one section of a map.

FieldTypeLabelDescription
idstringSection row id; the handle SetRepoMapSectionLock takes.
kindSectionKindWhich section this is.
bodystringThe current text.
lockedboolWhether a regeneration must leave it verbatim.
curator_kindCuratorKindHow the current text is attributed.
curator_run_idstringSet when curator_kind is CURATOR_KIND_GENERATION_RUN.
curator_member_idstringSet when curator_kind is CURATOR_KIND_MEMBER.
curated_atgoogle.protobuf.TimestampWhen the current text was written.
open_divergencesDivergencerepeatedUnacknowledged divergences against this section. Populated on reads so a lock cannot become a way to stop being told.

RevokeTeamRepoCredentialRequest​

RevokeTeamRepoCredentialRequest carries the scoped connection operation contract.

FieldTypeLabelDescription
team_unit_idstringExact owning team; authenticated org is never accepted from the request.
credential_idstringExact isolated team credential id.
expected_credential_epochint64Exact credential epoch observed by the caller; stale writes are refused.

RevokeTeamRepoCredentialResponse​

RevokeTeamRepoCredentialResponse carries the scoped connection operation contract.

FieldTypeLabelDescription
credentialTeamRepoCredentialRedacted persisted credential metadata.

RotateTeamRepoCredentialRequest​

RotateTeamRepoCredentialRequest carries the scoped connection operation contract.

FieldTypeLabelDescription
team_unit_idstringExact owning team; authenticated org is never accepted from the request.
credential_idstringExact isolated team credential id.
expected_credential_epochint64Exact credential epoch observed by the caller; stale writes are refused.
secretTeamRepoCredentialSecretWrite-only replacement credential material.

RotateTeamRepoCredentialResponse​

RotateTeamRepoCredentialResponse carries the scoped connection operation contract.

FieldTypeLabelDescription
credentialTeamRepoCredentialRedacted persisted credential metadata.

SetRepoMapSectionLockRequest​

SetRepoMapSectionLockRequest curates one section.

FieldTypeLabelDescription
section_idstringThe section to curate.
lockedboolWhether a regeneration must leave it verbatim from here on.
bodystringoptionalReplacement text. Unset leaves the body unchanged; the lock still moves.
acknowledge_divergence_idsstringrepeatedDivergences the curator has seen and is retiring. A divergence is retired ONLY here — never by a regeneration.

SetRepoMapSectionLockResponse​

SetRepoMapSectionLockResponse carries the curated section.

FieldTypeLabelDescription
sectionRepoMapSectionThe section after curation, with any divergences still open.

Staleness​

Staleness is how current a map is, computed at READ time.

It is carried on RepoMap itself so that no surface returning a map can return it without this. See the file header for why that is the mechanism rather than a convention.

FieldTypeLabelDescription
stateStalenessStateThe computed state. STALENESS_STATE_UNSPECIFIED is a server fault.
map_commitstringThe commit the map was generated from.
head_commitstringThe last observed head of ref. Empty when none has been observed, AND empty when the only observation is of a different ref — in that case there is no head of ref to report, and reporting another ref's would be the falsehood this field's emptiness prevents.
refstringThe ref the MAP was generated from — the subject of the marker sentence.
observed_refstringThe ref the observation is OF. Equal to ref in CURRENT and BEHIND (they are unreachable otherwise); different in the mismatch flavour of UNKNOWN, where naming both is what lets an agent tell "nobody looked" from "we looked at a different branch".
commits_behindint32optionalCommits behind, when measured against THIS map's commit. optional because 0 means "level", not "unmeasured".
head_observed_atgoogle.protobuf.TimestampWhen the head was observed. Absent when none has been.
markerstringThe rendered one-line marker, produced by the same renderer the MCP tool uses. Always populated: it is the sentence an agent reads, and one spelling across both surfaces is what makes M12 checkable at either.

TeamRepoCredential​

TeamRepoCredential is always redacted. org_id comes from authentication and is deliberately not an input selector. Only github.com is supported in V1b.

FieldTypeLabelDescription
idstringOpaque credential identifier.
team_unit_idstringExact owning team; authenticated org is never accepted from the request.
providerRepoProviderDeclared provider; V1b accepts GitHub only.
provider_hoststringCanonical host; V1b accepts github.com only.
labelstringHuman-readable connection name.
credential_kindstringStored kind: github_app or pat.
masked_hintstringRedacted hint only; never contains PEM or a complete token.
statusstringServer-owned lifecycle state.
credential_epochint64Monotonic epoch owned by the credential row.
scope_unverifiedboolTrue for opaque PAT scope; never a down-scope claim.
expires_atgoogle.protobuf.TimestampDeclared credential expiry; omitted when no expiry is declared.
created_atgoogle.protobuf.TimestampWhen the credential was created.
updated_atgoogle.protobuf.TimestampWhen the persisted state last changed.
app_idstringNumeric App id; absent for PAT credentials.

TeamRepoCredentialSecret​

TeamRepoCredentialSecret carries the scoped connection operation contract.

FieldTypeLabelDescription
github_appGitHubRepoAppSecretDedicated read-only App material.
github_patGitHubRepoPATSecretSelected-repository fine-grained PAT material.

UnbindRepoCredentialRequest​

UnbindRepoCredentialRequest carries the scoped connection operation contract.

FieldTypeLabelDescription
team_unit_idstringExact owning team; authenticated org is never accepted from the request.
repo_idstringRegistered repository id scoped to the named team.
expected_binding_revisionint64Exact binding revision observed by the caller; stale writes are refused.

UnbindRepoCredentialResponse​

UnbindRepoCredentialResponse carries the scoped connection operation contract.

FieldTypeLabelDescription
connectionRepoConnectionStatePersisted sanitized source-connection state.

UpdateRepoRequest​

UpdateRepoRequest edits a registry entry. Unset optional fields are left unchanged.

FieldTypeLabelDescription
repo_idstringThe registry entry to edit.
responsibilitystringoptionalNew one-line responsibility.
default_branchstringoptionalNew default branch.
primary_languagestringoptionalNew primary language.
linksUpdateRepoRequest.LinksEntryrepeatedReplacement link map (whole-map replace, not a merge).
replace_linksboolWhether links above should be applied at all — an empty map is a valid "clear the links" instruction and cannot be distinguished from "unset".
archivedbooloptionalArchive/unarchive.
removed_from_teambooloptionalRemove from the team's registry (soft). An entry removed this way stops appearing in ListRepos and frees the (team, project) key for re-registration.

UpdateRepoRequest.LinksEntry​

FieldTypeLabelDescription
keystring
valuestring

UpdateRepoResponse​

UpdateRepoResponse carries the updated entry.

FieldTypeLabelDescription
repoRepoThe updated repository.

CuratorKind​

CuratorKind attributes a section's current text.

A generated section is attributed to its RUN, never to a person who did not write it — TK-8.5 requires the curator of each curated section, and naming a human for machine-written text would make the provenance column a lie.

NameNumberDescription
CURATOR_KIND_UNSPECIFIED0Never valid on the wire.
CURATOR_KIND_GENERATION_RUN1Written by a map generation run.
CURATOR_KIND_MEMBER2Written or accepted by a team member.

RepoProvider​

Repo is one registered repository. RepoProvider is a declared upstream service; registration is not access proof.

NameNumberDescription
REPO_PROVIDER_UNSPECIFIED0Legacy request mode; stored historical provider is GitLab.
REPO_PROVIDER_GITLAB1GitLab with a declared project ID.
REPO_PROVIDER_GITHUB2GitHub declared owner/repository location.

SectionKind​

SectionKind is the closed set of map sections (TK-8.2).

NameNumberDescription
SECTION_KIND_UNSPECIFIED0Never valid on the wire.
SECTION_KIND_PURPOSE1What the repository is for.
SECTION_KIND_RESPONSIBILITIES2What it is responsible for.
SECTION_KIND_DIRECTORY_OWNERSHIP3The directory-ownership table: path -> owns -> touch-when.
SECTION_KIND_CONVENTIONS4Conventions a change is expected to follow.
SECTION_KIND_DO_NOT_TOUCH5Do-not-touch zones.
SECTION_KIND_RELATED_REPOSITORIES6Evidence-backed relationships to other repositories (founder D8). Schema support does not imply that relation extractors have run.

StalenessState​

StalenessState is how a map's pinned commit relates to the last observed head of the ref it was generated from.

There is NO valid unspecified state. The zero value exists because proto3 requires one and buf's ENUM_ZERO_VALUE_SUFFIX rule mandates the name; it is rejected by the server's response validation, so a map carrying it can never be serialised. That is M12 as a type rather than as a review checklist.

NameNumberDescription
STALENESS_STATE_UNSPECIFIED0Never valid on the wire. A response carrying it is a server fault.
STALENESS_STATE_CURRENT1The map's commit IS the last observed head of its ref.
STALENESS_STATE_BEHIND2The map's commit is not the observed head: the repository has moved.
STALENESS_STATE_UNKNOWN3No head has been observed for this repository, so how current the map is CANNOT BE KNOWN. It is a distinct answer from CURRENT and must never be rendered as one — an unobserved repository is the Day-0 state.

RepoConnectionService​

RepoConnectionService manages isolated team source credentials. It is mounted on the authenticated Context Engine; it does not run a generator or expose stored secrets. Registration alone is never evidence of provider access.

Method NameRequest TypeResponse TypeDescription
CreateTeamRepoCredentialCreateTeamRepoCredentialRequestCreateTeamRepoCredentialResponseCreateTeamRepoCredential creates a write-only GitHub team connection.
ListTeamRepoCredentialsListTeamRepoCredentialsRequestListTeamRepoCredentialsResponseListTeamRepoCredentials returns paginated redacted metadata and the real server authority projection. It never decrypts a secret for display.
RotateTeamRepoCredentialRotateTeamRepoCredentialRequestRotateTeamRepoCredentialResponseRotateTeamRepoCredential replaces the secret at the exact current epoch, fences old work, and requires positive re-verification of each binding. Only active credentials rotate: revoked is terminal; create and bind a replacement.
RevokeTeamRepoCredentialRevokeTeamRepoCredentialRequestRevokeTeamRepoCredentialResponseRevokeTeamRepoCredential fences the epoch and withholds dependent maps immediately. Revocation is terminal; late probes cannot undo it.
CheckTeamRepoConnectionCheckTeamRepoConnectionRequestCheckTeamRepoConnectionResponseCheckTeamRepoConnection runs a bounded, deduplicated check of an existing binding through its credential's shared quota. It never rebinds silently.
BindRepoCredentialBindRepoCredentialRequestBindRepoCredentialResponseBindRepoCredential verifies the registered canonical repository using an exact team credential before committing its provider identity. App installation and repository IDs are derived, never supplied by a user.
UnbindRepoCredentialUnbindRepoCredentialRequestUnbindRepoCredentialResponseUnbindRepoCredential records an explicit human denial and fences in-flight checks. It does not revoke a credential shared by other repositories.

RepoMapGenerationService​

RepoMapGenerationService is the finite, tool-less Context Engine producer. These operations handle no source secret. Every write uses knowledge.manage and the registry's actual L3 gate; owner operations retain their own authority.

Method NameRequest TypeResponse TypeDescription
ConfigureRepoMapGeneratorConfigureRepoMapGeneratorRequestConfigureRepoMapGeneratorResponseConfigureRepoMapGenerator advances resumable owner-service setup. It never approves bindings or endpoints. Repeating the same desired state is safe.
GetRepoMapGeneratorGetRepoMapGeneratorRequestGetRepoMapGeneratorResponseGetRepoMapGenerator returns actual persisted dependencies and check times.
RegenerateRepoMapRegenerateRepoMapRequestRegenerateRepoMapResponseRegenerateRepoMap durably deduplicates a human request under the same caps.
ListRepoMapRunsListRepoMapRunsRequestListRepoMapRunsResponseListRepoMapRuns returns bounded sanitized history, never source excerpts.

RepoService​

RepoService is the management surface for the team repo registry and its curated maps. Every operation is tenant-scoped: the owning org and the acting member are taken from the request scope, never from the request body, and every statement carries an explicit org predicate on top of row-level security.

Authorization (mirroring KnowledgeService, handler_perms.go):

  • reads (ListRepos, GetRepoMap) — knowledge.read
  • writes (RegisterRepo, UpdateRepo, PutRepoMap, RecordRepoHead, SetRepoMapSectionLock) — knowledge.manage
Method NameRequest TypeResponse TypeDescription
RegisterRepoRegisterRepoRequestRegisterRepoResponseRegisterRepo adds a repository to a team's registry. The one-line responsibility is REQUIRED: a registry entry that cannot say what the repository is for does not satisfy TK-8.1, and F8 acceptance 1 would otherwise be dischargeable by an empty string.
ListReposListReposRequestListReposResponseListRepos returns a team's registered repositories. Team-scoped: a repository registered to another team is not returned, whatever the caller's clearance.
UpdateRepoUpdateRepoRequestUpdateRepoResponseUpdateRepo edits a registry entry. Every editable field is optional, so "leave unchanged" and "set to empty" are distinguishable — with a bare proto3 string they are the same wire value and a partial update silently clears whatever it did not mention.
RecordRepoHeadRecordRepoHeadRequestRecordRepoHeadResponseRecordRepoHead stores an observation of the head of ONE REF. It is the freshness WRITER: Phase 2's GitLab webhook calls it, and until then a repository with no observation renders staleness UNKNOWN rather than CURRENT. It never touches a map.

head_ref is REQUIRED. An observation carries the ref it is OF, because staleness for a map generated from release/1.2 cannot be answered by an observation of main — and answering it anyway produced a confident falsehood in the rendered marker (R1 on PR #3090). | | PutRepoMap | PutRepoMapRequest | PutRepoMapResponse | PutRepoMap applies a legacy/manual map at a pinned commit. It refuses an admitted governed run ID or replacement of a governed map; those writes require the server-owned RegenerateRepoMap producer.

LOCK SEMANTICS, both halves (TK-8.4): - an UNLOCKED section is replaced by the generated body; - a LOCKED section survives VERBATIM, and if the generated body differs the difference is recorded as a divergence.

A lock suppresses the EDIT, never the NOTIFICATION. Proving only the survival half would leave a lock that silences. | | GetRepoMap | GetRepoMapRequest | GetRepoMapResponse | GetRepoMap returns a repository's current map with its staleness computed at read time and the open divergences attached to the sections they concern. | | SetRepoMapSectionLock | SetRepoMapSectionLockRequest | SetRepoMapSectionLockResponse | SetRepoMapSectionLock is the curation surface: lock or unlock a section, optionally replace its body, and acknowledge divergences the curator has seen. Acknowledging is what retires a divergence — it is never retired by a regeneration, because that would let a lock stop the notification after all. |

Scalar Value Types​

.proto TypeNotesC++JavaPythonGoC#PHPRuby
doubledoubledoublefloatfloat64doublefloatFloat
floatfloatfloatfloatfloat32floatfloatFloat
int32Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.int32intintint32intintegerBignum or Fixnum (as required)
int64Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.int64longint/longint64longinteger/stringBignum
uint32Uses variable-length encoding.uint32intint/longuint32uintintegerBignum or Fixnum (as required)
uint64Uses variable-length encoding.uint64longint/longuint64ulonginteger/stringBignum or Fixnum (as required)
sint32Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.int32intintint32intintegerBignum or Fixnum (as required)
sint64Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.int64longint/longint64longinteger/stringBignum
fixed32Always four bytes. More efficient than uint32 if values are often greater than 2^28.uint32intintuint32uintintegerBignum or Fixnum (as required)
fixed64Always eight bytes. More efficient than uint64 if values are often greater than 2^56.uint64longint/longuint64ulonginteger/stringBignum
sfixed32Always four bytes.int32intintint32intintegerBignum or Fixnum (as required)
sfixed64Always eight bytes.int64longint/longint64longinteger/stringBignum
boolboolbooleanbooleanboolboolbooleanTrueClass/FalseClass
stringA string must always contain UTF-8 encoded or 7-bit ASCII text.stringStringstr/unicodestringstringstringString (UTF-8)
bytesMay contain any arbitrary sequence of bytes.stringByteStringstr[]byteByteStringstringString (ASCII-8BIT)