We currently don’t store the schema of Data Slice files in metadata.The closest thing we have is the read-stage schemas defined in SetPollingSource event, but those schemas are only applied to external data when reading it, can be reshaped by the preprocess queries, and also get extended with system columns.This creates several problems:
One cannot understand the data schema from metadata alone and needs to inspect the last Parquet file, which can be costly
The data schema is effectively undefined until the first data file is written
It’s not possible to pre-define the dataset schema before writing data into it (which poses a problem for “push”-style ingestion, see RFC-011)
A new metadata event SetDataSchema is introduced that will contain full schema of the Data Slice files that are written following it.Multiple SetDataSchema events can appear in the metadata chain, allowing for schema evolution.SetDataSchema event will not normally be specified in Dataset Snapshots, but instead will be generated by ODF implementations by inferring the final schema based on:
First root ingestion / derivative transformation to take place
{ "$id": "http://open-data-fabric.github.com/schemas/SetDataSchema", "$schema": "http://json-schema.org/draft-07/schema#", "description": "Specifies the complete schema of Data Slices added to the Dataset following this event.", "type": "object", "additionalProperties": false, "required": [ "schema" ], "properties": { "schema": { "type": "object", "format": "flatbuffers", "description": "Apache Arrow schema encoded in its native flatbuffers representation." } }}
Note the introduction of new format flatbuffers. It will handle the data as a plain byte array. Libraries will be able to add special accessors that provide typed access to the underlying object - in this case Arrow Schema type. Due to the nature of flatbuffers this can be done without extra allocations.
This change is backwards-compatible, as existing implementations can continue to fall back to reading schema from Data Slice files if SetDataSchema event is not found.This change is forwards-incompatible as older implementation will fail to parse the new core event (we still lack the mechanism to mark some events as “OK to disregard”).
It was debated whether to require the existence of SetDataSchema prior to definition of any ingest sources or transformations.This would require:
Either making users specify schema explicitly - deemed too complex and impractical.
Or implementations to infer the schema from the defined sources - deemed as something that would slow down the dataset creation from snapshots, since inferring the schema would require instantiating an Engine.
The compromise was reached in requiring SetDataSchema before any Data Slices are added, but allowing it to follow the SetPollingSource and SetTransform events from which it will be inferred during the first processing.
We chose to use Arrow schema instead of Parquet because:
Arrow is our cross-system data interchange format
Arrow schema is more expressive and can represent types more accurately (e.g. timezones)
We care about more about logical schema rather than how data appears on disk, and this will allow us in future to support other on-disk formats as long as their schemas can be mapped to Arrow.
Arrow Schema currently does not have a standard human-readable representation - it is specified only by its flatbuffers schema.We therefore store the schema as flatbuffer-in-flatbuffer in the metadata chain, which gives us optimal encoding, and leave it up to implementations to present in human-readable format of their choice to the users.For now, we don’t expect users ever having to manually specify the schema, but if needed we could explore flatbuffers own standard way to serialize data to JSON.See also:
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Kamu Docs","colors":{"primary":"#ec6e2a","light":"#ec6e2a","dark":"#ec6e2a"},"logo":{"light":"https://mintcdn.com/kamu/j1tx5fgzyFHd1DYS/images/kamu-logo-light.svg?fit=max\u0026auto=format\u0026n=j1tx5fgzyFHd1DYS\u0026q=85\u0026s=a09261b617da6e1515dea3d28495f633","dark":"https://mintcdn.com/kamu/j1tx5fgzyFHd1DYS/images/kamu-logo-dark.svg?fit=max\u0026auto=format\u0026n=j1tx5fgzyFHd1DYS\u0026q=85\u0026s=8c6d0d7ffa23ef050859453f64354192"},"favicon":"https://mintcdn.com/kamu/j1tx5fgzyFHd1DYS/images/favicon.svg?fit=max\u0026auto=format\u0026n=j1tx5fgzyFHd1DYS\u0026q=85\u0026s=a7b01f8f352427f5a4afe3aef1f8a9d3","background":{"color":{"dark":"#050C1E"}},"navbar":{"links":[{"href":"https://discord.gg/nU6TXRQNXC","label":"Get Help"}],"primary":{"type":"button","label":"Install","href":"/cli/install/"}},"footer":{"socials":{"github":"https://github.com/kamu-data","discord":"https://discord.gg/nU6TXRQNXC","youtube":"https://www.youtube.com/@kamudata","linkedin":"https://www.linkedin.com/company/kamu-data","medium":"https://medium.com/kamu-data","bluesky":"https://bsky.app/profile/kamu.dev","x":"https://x.com/kamu_data"},"links":[{"header":"Company","items":[{"label":"Blog","href":"https://kamu.dev/blog"},{"label":"Careers","href":"https://kamu.dev/jobs"}]}]},"seo":{"metatags":{"canonical":"https://docs.kamu.dev"}},"styling":{"eyebrows":"breadcrumbs","latex":false},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"metadata":{"timestamp":true},"navigation":{"global":{"anchors":[]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"kamu","hasAudioNarration":false,"actualSubdomain":"kamu","customDomains":["docs.kamu.dev"],"gitSource":{"type":"github","owner":"kamu-data","repo":"kamu-docs","deployBranch":"master","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ad05633011b02bffcb4463d","collectionId":"0127742b-6059-4668-b046-f443923b1bdd","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ad05633011b02bffcb4463d"},"entitlements":{},"buildId":"6ad05633011b02bffcb4463d","clientVersion":"0.0.3965","searchFilterCounts":[{"language":"default","tag":"Guides","count":75},{"language":"default","tag":"Reference","count":42},{"language":"default","tag":"Open Data Fabric","count":39},{"language":"default","tag":"Kamu CLI","count":31},{"language":"default","tag":"RFCs","count":22},{"language":"default","tag":"Kamu Node","count":17},{"language":"default","tag":"Specification","count":15},{"language":"default","tag":"APIs","count":13},{"language":"default","tag":"Get Started","count":12},{"language":"default","tag":"Datasets","count":10}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"isAtlas":false,"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":"a.card:is(.dark *),div.card:is(.dark *){background:#09162d}a.card:is(.light *),div.card:is(.light *){background:#fafafa}a:has(svg[style*=\"wrench.svg\"]){pointer-events:none;opacity:.7}button:has(svg[style*=\"wrench.svg\"]){opacity:.7}a:has(svg[style*=\"wrench.svg\"])>div:first-child,button:has(svg[style*=\"wrench.svg\"])>svg[style*=\"wrench.svg\"]{order:2;margin-left:auto}.prose a.glossary-term:is(.dark *, .light *){color:inherit;font-weight:inherit;border-bottom:2px dotted #325495}.prose a.schema-object:is(.dark *, .light *){color:inherit;font-weight:inherit;border-bottom:2px dotted #2c802c}h4.project-title:is(.dark *, .light *){display:block;text-align:center}div.badges a,h4.project-title a{border-bottom:0}a.project-quicklink:is(.dark *, .light *){font-size:15px;font-weight:300;color:#ec6e2a;border-bottom:0}.prose div img:is(\n [src*=\"projects/odf.svg\"],\n [src*=\"projects/kamu-cli.svg\"],\n [src*=\"projects/kamu-node.svg\"],\n [src*=\"projects/kamu-platform.svg\"]\n ){display:block;margin:30px auto 0;height:100px;width:auto}div.badges{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:center;gap:10px;margin:20px}div.badges img{display:inline;margin:0}"}],"page":{"pagePath":"odf/rfcs/010-data-schema-in-metadata","slug":"/odf/rfcs/010-data-schema-in-metadata","pageMetadata":{"title":"RFC-010: Data Schema in Metadata","description":null,"href":"/odf/rfcs/010-data-schema-in-metadata"},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];const YouTubeList=({id})=>{const src=`https://www.youtube.com/embed/videoseries?list=${id}`;return _jsx(`iframe`,{className:`mint-w-full mint-aspect-video mint-rounded-xl`,src,allow:`accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture`,allowFullScreen:true})};const YouTube=({id,width})=>{const src=`https://www.youtube.com/embed/${id}`;return _jsx(`iframe`,{className:`mint-w-full mint-aspect-video mint-rounded-xl`,src,allow:`accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture`,allowFullScreen:true,width})};const Schema=({t,id})=>{const _components={a:`a`,..._provideComponents()};const anchor=id?id:t.toLowerCase().replace(/\\s+/g,`-`);const link=`/odf/schemas#${anchor}`;return _jsx(_components.a,{class:`schema-object`,href:link,children:t})};const Term=({t,id})=>{const _components={a:`a`,..._provideComponents()};const anchor=id?id:t.toLowerCase().replace(/\\s+/g,`-`);const link=`/general/glossary#${anchor}`;return _jsx(_components.a,{class:`glossary-term`,href:link,children:t})};const Diagram=({src,alt})=>{return _jsxs(`div`,{style:{display:`flex`,\"flex-direction\":`column`,\"align-items\":`center`},children:[_jsx(`img`,{src,alt,style:{background:`#dddddd`,\"margin-bottom\":0}}),_jsx(`span`,{children:alt})]})};function _createMdxContent(props){const _components={a:`a`,code:`code`,em:`em`,img:`img`,input:`input`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[_jsx(_components.a,{href:`https://github.com/kamu-data/open-data-fabric/issues/55`,children:_jsx(_components.img,{src:`https://img.shields.io/github/issues/detail/state/kamu-data/open-data-fabric/62?label=Issue`,alt:`Issue`})}),`\n`,_jsx(_components.a,{href:`https://github.com/kamu-data/open-data-fabric/pull/63`,children:_jsx(_components.img,{src:`https://img.shields.io/github/pulls/detail/state/kamu-data/open-data-fabric/63?label=PR`,alt:`Spec PR`})})]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Start Date`}),`: 2023-10-25`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Specs`}),`:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/odf/spec/datasets/metadata-chain`,children:`Metadata Chain`})}),`\n`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Authors`}),`:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`mailto:sergiy.zaychenko@kamu.dev`,children:`Sergiy Zaychenko`}),`, `,_jsx(_components.a,{href:`https://kamu.dev`,children:`Kamu`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`mailto:sergii.mikhtoniuk@kamu.dev`,children:`Sergii Mikhtoniuk`}),`, `,_jsx(_components.a,{href:`https://kamu.dev`,children:`Kamu`})]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Compatibility`}),`:`]}),`\n`,_jsxs(_components.ul,{className:`contains-task-list`,children:[`\n`,_jsx(_components.li,{children:`[V] Backwards-compatible`}),`\n`,_jsxs(_components.li,{className:`task-list-item`,children:[_jsx(_components.input,{type:`checkbox`,disabled:true}),` `,`Forwards-compatible`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`summary`,children:`Summary`}),`\n`,_jsxs(_components.p,{children:[`Introduces a new metadata event `,_jsx(_components.code,{children:`SetDataSchema`}),` that specifies the Arrow schema of the Data Slices added to the dataset following this event.`]}),`\n`,_jsx(Heading,{level:`2`,id:`motivation`,children:`Motivation`}),`\n`,_jsx(_components.p,{children:`We currently don’t store the schema of Data Slice files in metadata.`}),`\n`,_jsxs(_components.p,{children:[`The closest thing we have is the `,_jsx(_components.code,{children:`read`}),`-stage schemas defined in `,_jsx(_components.code,{children:`SetPollingSource`}),` event, but those schemas are only applied to external data when reading it, can be reshaped by the `,_jsx(_components.code,{children:`preprocess`}),` queries, and also get extended with system columns.`]}),`\n`,_jsx(_components.p,{children:`This creates several problems:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`One cannot understand the data schema from metadata alone and needs to inspect the last Parquet file, which can be costly`}),`\n`,_jsxs(_components.li,{children:[`The data schema is effectively `,_jsx(_components.em,{children:`undefined`}),` until the first data file is written`]}),`\n`,_jsx(_components.li,{children:`It’s not possible to pre-define the dataset schema before writing data into it (which poses a problem for “push”-style ingestion, see RFC-011)`}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`guide-level-explanation`,children:`Guide-level explanation`}),`\n`,_jsxs(_components.p,{children:[`A new metadata event `,_jsx(_components.code,{children:`SetDataSchema`}),` is introduced that will contain full schema of the Data Slice files that are written following it.`]}),`\n`,_jsxs(_components.p,{children:[`Multiple `,_jsx(_components.code,{children:`SetDataSchema`}),` events can appear in the metadata chain, allowing for schema evolution.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`SetDataSchema`}),` event will not normally be specified in Dataset Snapshots, but instead will be generated by ODF implementations by inferring the final schema based on:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`First root ingestion / derivative transformation to take place`}),`\n`,_jsxs(_components.li,{children:[`Column names defined in `,_jsx(_components.code,{children:`SetVocab`}),` events`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`reference-level-explanation`,children:`Reference-level explanation`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`SetDataSchema`}),` event schema:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`17`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`17`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"$id\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"http://open-data-fabric.github.com/schemas/SetDataSchema\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"$schema\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"http://json-schema.org/draft-07/schema#\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"description\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Specifies the complete schema of Data Slices added to the Dataset following this event.\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"object\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"additionalProperties\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`false`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"required\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"schema\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ],`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"properties\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"schema\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"object\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"format\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"flatbuffers\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"description\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Apache Arrow schema encoded in its native flatbuffers representation.\"`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Note the introduction of new format `,_jsx(_components.code,{children:`flatbuffers`}),`. It will handle the data as a plain byte array. Libraries will be able to add special accessors that provide typed access to the underlying object - in this case Arrow Schema type. Due to the nature of flatbuffers this can be done without extra allocations.`]}),`\n`,_jsx(Heading,{level:`2`,id:`compatibility`,children:`Compatibility`}),`\n`,_jsxs(_components.p,{children:[`This change is `,_jsx(_components.strong,{children:`backwards-compatible`}),`, as existing implementations can continue to fall back to reading schema from Data Slice files if `,_jsx(_components.code,{children:`SetDataSchema`}),` event is not found.`]}),`\n`,_jsxs(_components.p,{children:[`This change is `,_jsx(_components.strong,{children:`forwards-incompatible`}),` as older implementation will fail to parse the new core event (we still lack the mechanism to mark some events as “OK to disregard”).`]}),`\n`,_jsx(Heading,{level:`2`,id:`drawbacks`,children:`Drawbacks`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`More complexity in metadata`}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`alternatives`,children:`Alternatives`}),`\n`,_jsx(Heading,{level:`3`,id:`event-order-rules`,children:`Event order rules`}),`\n`,_jsxs(_components.p,{children:[`It was debated whether to require the existence of `,_jsx(_components.code,{children:`SetDataSchema`}),` prior to definition of any ingest sources or transformations.`]}),`\n`,_jsx(_components.p,{children:`This would require:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`Either making users specify schema explicitly - deemed too complex and impractical.`}),`\n`,_jsx(_components.li,{children:`Or implementations to infer the schema from the defined sources - deemed as something that would slow down the dataset creation from snapshots, since inferring the schema would require instantiating an Engine.`}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`The compromise was reached in requiring `,_jsx(_components.code,{children:`SetDataSchema`}),` before any Data Slices are added, but allowing it to follow the `,_jsx(_components.code,{children:`SetPollingSource`}),` and `,_jsx(_components.code,{children:`SetTransform`}),` events from which it will be `,_jsx(_components.strong,{children:`inferred during the first processing`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`schema-format`,children:`Schema format`}),`\n`,_jsx(_components.p,{children:`We chose to use Arrow schema instead of Parquet because:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`Arrow is our cross-system data interchange format`}),`\n`,_jsx(_components.li,{children:`Arrow schema is more expressive and can represent types more accurately (e.g. timezones)`}),`\n`,_jsx(_components.li,{children:`We care about more about logical schema rather than how data appears on disk, and this will allow us in future to support other on-disk formats as long as their schemas can be mapped to Arrow.`}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`schema-representation`,children:`Schema representation`}),`\n`,_jsxs(_components.p,{children:[`Arrow Schema currently does not have a standard human-readable representation - it is specified only by its `,_jsx(_components.code,{children:`flatbuffers`}),` schema.`]}),`\n`,_jsx(_components.p,{children:`We therefore store the schema as flatbuffer-in-flatbuffer in the metadata chain, which gives us optimal encoding, and leave it up to implementations to present in human-readable format of their choice to the users.`}),`\n`,_jsx(_components.p,{children:`For now, we don’t expect users ever having to manually specify the schema, but if needed we could explore flatbuffers own standard way to serialize data to JSON.`}),`\n`,_jsx(_components.p,{children:`See also:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`https://github.com/apache/arrow/issues/25078`,children:`https://github.com/apache/arrow/issues/25078`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`https://stackoverflow.com/questions/48215929/can-i-serialize-dserialize-flatbuffers-to-from-json`,children:`https://stackoverflow.com/questions/48215929/can-i-serialize-dserialize-flatbuffers-to-from-json`})}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`prior-art`,children:`Prior art`}),`\n`,_jsx(_components.p,{children:`N/A`}),`\n`,_jsx(Heading,{level:`2`,id:`unresolved-questions`,children:`Unresolved questions`}),`\n`,_jsx(_components.p,{children:`N/A`}),`\n`,_jsx(Heading,{level:`2`,id:`future-possibilities`,children:`Future possibilities`}),`\n`,_jsx(_components.p,{children:`N/A`})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{YouTubeList,YouTube,Schema,Term,Diagram,default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"RFC-010: Data Schema in Metadata","description":null,"href":"/odf/rfcs/010-data-schema-in-metadata"}}},"mdxSourceWithNoJs":null,"noJsSplices":[[147,1427,")=>null;const YouTube=()=>null;const Schema=()=>null;const Term=()=>null;const Diagram=()=>null;func"]]},"mdxExtracts":{"tableOfContents":[{"title":"Summary","slug":"summary","depth":2,"children":[]},{"title":"Motivation","slug":"motivation","depth":2,"children":[]},{"title":"Guide-level explanation","slug":"guide-level-explanation","depth":2,"children":[]},{"title":"Reference-level explanation","slug":"reference-level-explanation","depth":2,"children":[]},{"title":"Compatibility","slug":"compatibility","depth":2,"children":[]},{"title":"Drawbacks","slug":"drawbacks","depth":2,"children":[]},{"title":"Alternatives","slug":"alternatives","depth":2,"children":[{"title":"Event order rules","slug":"event-order-rules","depth":3,"children":[]},{"title":"Schema format","slug":"schema-format","depth":3,"children":[]},{"title":"Schema representation","slug":"schema-representation","depth":3,"children":[]}]},{"title":"Prior art","slug":"prior-art","depth":2,"children":[]},{"title":"Unresolved questions","slug":"unresolved-questions","depth":2,"children":[]},{"title":"Future possibilities","slug":"future-possibilities","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"dynamicCss":".mint-aspect-video {\n aspect-ratio: 16 / 9\n}\n.mint-w-full {\n width: 100%\n}\n.mint-rounded-xl {\n border-radius: 0.75rem\n}","subdomain":"kamu","siteName":"Kamu Docs","title":"RFC-010: Data Schema in Metadata - Kamu Docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-15T04:13:42.409Z","gitLastModified":"2026-10-15T04:13:20.000Z","originalFileLocation":"odf/rfcs/010-data-schema-in-metadata.md"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"application-name\" content=\"Kamu Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/kamu/FxhmdHpAfy0cwcpV/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/kamu/FxhmdHpAfy0cwcpV/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/kamu/FxhmdHpAfy0cwcpV/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/kamu/FxhmdHpAfy0cwcpV/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/kamu/FxhmdHpAfy0cwcpV/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/kamu/FxhmdHpAfy0cwcpV/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/kamu/FxhmdHpAfy0cwcpV/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/kamu/FxhmdHpAfy0cwcpV/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/kamu/FxhmdHpAfy0cwcpV/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"RFC-010: Data Schema in Metadata - Kamu Docs\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Kamu Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.kamu.dev/odf/rfcs/010-data-schema-in-metadata\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://kamu.mintlify.app/_mintlify/api/og/v2?division=RFCs\u0026amp;title=RFC-010%3A+Data+Schema+in+Metadata\u0026amp;theme=4425de33767c8dc7c1d6072e\u0026amp;signature=a22e670b5f124f3f721d34592ad369a09b091e10e1b020d9b95facf31753c92e\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"RFC-010: Data Schema in Metadata - Kamu Docs\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://kamu.mintlify.app/_mintlify/api/og/v2?division=RFCs\u0026amp;title=RFC-010%3A+Data+Schema+in+Metadata\u0026amp;theme=4425de33767c8dc7c1d6072e\u0026amp;signature=a22e670b5f124f3f721d34592ad369a09b091e10e1b020d9b95facf31753c92e\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/kamu/FxhmdHpAfy0cwcpV/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Kamu Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#ec6e2a\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.kamu.dev/odf/rfcs/010-data-schema-in-metadata\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/odf/rfcs/010-data-schema-in-metadata.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.kamu.dev/#organization\",\"name\":\"Kamu Docs\",\"url\":\"https://docs.kamu.dev\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/kamu/j1tx5fgzyFHd1DYS/images/kamu-logo-light.svg?fit=max\u0026auto=format\u0026n=j1tx5fgzyFHd1DYS\u0026q=85\u0026s=a09261b617da6e1515dea3d28495f633\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.kamu.dev#website\",\"name\":\"Kamu Docs\",\"url\":\"https://docs.kamu.dev\",\"publisher\":{\"@id\":\"https://docs.kamu.dev/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.kamu.dev/odf/rfcs/010-data-schema-in-metadata#webpage\",\"url\":\"https://docs.kamu.dev/odf/rfcs/010-data-schema-in-metadata\",\"name\":\"RFC-010: Data Schema in Metadata\",\"dateModified\":\"2026-10-15T04:13:20.000Z\",\"isPartOf\":{\"@id\":\"https://docs.kamu.dev#website\"},\"breadcrumb\":{\"@id\":\"https://docs.kamu.dev/odf/rfcs/010-data-schema-in-metadata#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.kamu.dev/odf/rfcs/010-data-schema-in-metadata#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Open Data Fabric\",\"item\":\"https://docs.kamu.dev/odf/about\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"RFCs\",\"item\":\"https://docs.kamu.dev/odf/rfcs/index\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"RFC-010: Data Schema in Metadata\",\"item\":\"https://docs.kamu.dev/odf/rfcs/010-data-schema-in-metadata\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.kamu.dev/odf/rfcs/010-data-schema-in-metadata#article\",\"headline\":\"RFC-010: Data Schema in Metadata\",\"name\":\"RFC-010: Data Schema in Metadata\",\"url\":\"https://docs.kamu.dev/odf/rfcs/010-data-schema-in-metadata\",\"mainEntityOfPage\":{\"@id\":\"https://docs.kamu.dev/odf/rfcs/010-data-schema-in-metadata#webpage\"},\"dateModified\":\"2026-10-15T04:13:20.000Z\",\"publisher\":{\"@id\":\"https://docs.kamu.dev/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.kamu.dev#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Kamu Docs\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Kamu Docs","nav":{"global":{"anchors":[]},"tabs":[{"tab":"Guides","icon":"person-chalkboard","pages":[{"title":"Guides","href":"/start/welcome"}]},{"tab":"Reference","icon":"book-open-cover","groups":[{"group":"Open Data Fabric","pages":[{"title":null,"href":"/odf/about"},{"group":"Specification","root":{"title":"Overview","href":"/odf/spec/overview"},"pages":[{"group":"Datasets","pages":[{"title":"Logical Structure","href":"/odf/spec/datasets/logical-structure"},{"title":"Identity","href":"/odf/spec/datasets/identity"},{"title":"Data Model","href":"/odf/spec/datasets/data-model"},{"title":"Data Schema","href":"/odf/spec/datasets/data-schema"},{"title":"Metadata Chain","href":"/odf/spec/datasets/metadata-chain"},{"title":"Data \u0026 Checkpoint Hashing","href":"/odf/spec/datasets/data-and-checkpoint-hashing"},{"title":"Storage Layout","href":"/odf/spec/datasets/storage-layout"},{"title":"Ingestion","href":"/odf/spec/datasets/ingestion"}]},{"group":"Transformations","pages":[{"title":"Processing Model","href":"/odf/spec/transformations/processing-model"},{"title":"Engine Contract","href":"/odf/spec/transformations/engine-contract"}]},{"group":"Exchange","pages":[{"title":"Transfer Protocols","href":"/odf/spec/exchange/transfer-protocols"},{"title":"Verifiable Batch Queries","href":"/odf/spec/exchange/verifiable-batch-queries"}]},{"group":"Automation","pages":[{"title":"Resource Framework","href":"/odf/spec/automation/resource-framework"},{"title":"Tasks and Flows","href":"/odf/spec/automation/tasks-and-flows"}]},{"group":"Auth \u0026 Privacy","pages":[{"title":"Authorization","href":"/odf/spec/auth-and-privacy/authorization"}]}]},{"title":"Schemas","href":"/odf/schemas"},{"group":"RFCs","root":{"title":"RFCs","href":"/odf/rfcs/index"},"pages":[{"title":"RFC-001: Record Offsets","href":"/odf/rfcs/001-record-offsets"},{"title":"RFC-002: Logical Data Digests","href":"/odf/rfcs/002-logical-data-hashes"},{"title":"RFC-003: Content Addressability","href":"/odf/rfcs/003-content-addressability"},{"title":"RFC-004: Metadata Extensibility","href":"/odf/rfcs/004-metadata-extensibility"},{"title":"RFC-005: New Annotation Metadata Events","href":"/odf/rfcs/005-dataset-annotations"},{"title":"RFC-006: Store Checkpoints as Files","href":"/odf/rfcs/006-checkpoints-as-files"},{"title":"RFC-007: Simple Transfer Protocol","href":"/odf/rfcs/007-simple-transfer-protocol"},{"title":"RFC-008: Smart Transfer Protocol","href":"/odf/rfcs/008-smart-transfer-protocol"},{"title":"RFC-009: Ingestion Source State","description":null,"href":"/odf/rfcs/009-ingest-source-state"},{"title":"RFC-010: Data Schema in Metadata","href":"/odf/rfcs/010-data-schema-in-metadata"},{"title":"RFC-011: Push Ingest Sources","description":null,"href":"/odf/rfcs/011-push-ingest-sources"},{"title":"RFC-012: Recommend `base16` encoding for textual representation of hashes and DIDs","href":"/odf/rfcs/012-recommend-base16-encoding"},{"title":"RFC-013: Enum representation in YAML encoding","href":"/odf/rfcs/013-yaml-enum-representation"},{"title":"RFC-014: Minimizing scanning for last offset and block","href":"/odf/rfcs/014-minimize-offset-scanning"},{"title":"RFC-015: Unified changelog stream schema","href":"/odf/rfcs/015-unified-changelog-stream-schema"},{"title":"RFC-016: ODF Schema Format","href":"/odf/rfcs/016-odf-schema"},{"title":"RFC-017: Large Files Linking","href":"/odf/rfcs/017-large-files-linking"},{"title":"RFC-018: Infrastructure-as-Code Resource Framework","href":"/odf/rfcs/018-iac-resource-framework"},{"title":"RFC-019: IaC Task and Flow System","href":"/odf/rfcs/019-iac-task-flow-system"},{"title":"RFC-020: Authorization Model","href":"/odf/rfcs/020-auth"},{"title":"RFC-021: ODF Spec Restructuring","href":"/odf/rfcs/021-spec-restructuring"},{"title":"RFC-022: Batch Query Commitments","href":"/odf/rfcs/022-batch-query-commitments"}]}]},{"group":"Kamu CLI","pages":[{"title":"Commands Reference","href":"/cli/commands"},{"title":"Config Reference","href":"/cli/config"}]},{"group":"Kamu Node","pages":[{"title":"Config Reference","href":"/node/config"}]}]},{"tab":"APIs","icon":"code","pages":[{"title":"APIs","href":"/api/overview"}]},{"tab":"Integrations","icon":"network-wired","pages":[{"title":"Integrations","href":"/integrations/overview"}]}]},"title":"RFC-010: Data Schema in Metadata - Kamu Docs","buildId":"dpl_849ArpqvBiCczQiT1Y1stNGpbqHT","deploymentId":"dpl_849ArpqvBiCczQiT1Y1stNGpbqHT","dynamics":["a74be98ba7"],"chunks":["zoom-image-lightbox-CaUwvYH3.js","lightbox-handle-r17bVUz3.js"]}