Skip to content

Flatbread 1.0.0

Choose a tag to compare

@tonyketcham tonyketcham released this 12 Aug 19:53
· 57 commits to main since this release
4e154e1

Flatbread 1.0

Flatbread turns files in Git into a typed relational graph. With 1.0, the project finds a new leading use case: durable memory for coding agents. All packages ship at 1.0.0 and move together from here — one version across the set, so you no longer have to match alphas.

Introducing Proof

New agent sessions forget why previous ones made particular decisions. They look at the current codebase as a lossy snapshot and try to deduce the rationale from it. Sometimes they misread the decisions themselves. Unstructured docs are no better: they go stale and contradict each other. Proof keeps that reasoning in the repository, next to the code it explains.

An agent writes an Effort, then files Issues, Findings, Decisions, Constraints, Risks, Citations, and Blobs against it. Each record is a Markdown file under .flatbread-proof/. You commit, diff, and review them like source. Next session reads them back through bounded queries.

  • flatbread proof write accepts 15 mutations covering the full record lifecycle: CreateEffort, SetEffortStatus, WriteIssue, WriteFinding, WriteDecision, WriteConstraint, WriteRisk, WriteCitation, WriteBlob, Supersede, Invalidate, ResolveIssue, AcceptDecision, MitigateRisk, SetRiskState.
  • Five bounded reads return digests, not raw records: flatbread proof list, records, relations, blocking-decisions, and get. Each caps at 25 records, one hop, 50 edges, 64 KiB, with a ≤160-token summary and named cap_reasons when it truncates.
  • Writes go through a journal. A change that touches several files either finishes in full or leaves nothing behind; if the process dies mid-write, the next run restores the earlier contents.
  • Lifecycle states derive from the mutation: WriteIssue opens, WriteDecision proposes, WriteRisk opens. AcceptDecision rejects every other proposed Decision in the Effort by default.
  • Forward edges (derives_from, supersedes, invalidates) live in payloads; reverse projections (superseded_by, invalidated_by, etc.) materialize automatically.
  • Strict read-your-writes: --strict-min-generation <token> waits server-side for a write to land, or exits nonzero with PROOF_GENERATION_WAIT_TIMEOUT. Reads never return stale data silently.
  • flatbread proof bootstrap --verify exits nonzero when proofContent() or the two .gitignore lines are missing, so it runs in CI.
  • flatbread proof cache prune trims the read cache to 100 MiB and drops digests older than 24 hours.
  • Writes flow through the committed-generation bridge: with flatbread start --watch running, a Proof write appears in GraphQL and Explorer without a restart.

Explorer

  • When config includes proofContent() and the prebuilt assets are present, flatbread start serves the Explorer SPA at / and Apollo Sandbox at /graphql.
  • An interactive force-layout canvas plots the Effort graph. Hue and silhouette encode record kind — Issue diamond, Finding circle, Decision square, Constraint slab, Risk triangle, Effort ring. Retired records dim from the edges, not the frontmatter.
  • A detail drawer renders the Markdown body (GFM, sanitized) and groups relations for in-graph navigation. Click a node to open it; arrow keys move between records; Escape closes.
  • Live updates stream over SSE at /events. The top bar shows live/connecting/partial/disconnected status, journal generation, and counts of Efforts, open Issues, proposed Decisions, and live Risks.
  • Static deploy: drop dist/static/ on any host and pass ?endpoint=https://api.example.com/graphql. Same-origin needs no query param.

Codegen

  • flatbread codegen writes generated/graphql.ts from the content model plus optional .graphql documents. Flags: --watch, --clear-cache, --documents, --verbose, --output-dir, --output-file.
  • Content-model types emit with no .graphql documents required: FlatbreadCollectionName, FlatbreadRecord<'Post'>, FlatbreadRelationTarget<'Post', 'authors'>, FlatbreadRelationCardinality.
  • createFlatbreadReadApi(execute) builds per-collection all() and find(id) helpers with a generated default selection. They still execute GraphQL. The optional selection-string argument is experimental.
  • Presets: basic (no @graphql-typed-document-node/core), operations, full (default).
  • flatbread start --watch regenerates types on content, config, and document changes — do not run flatbread codegen --watch beside it.

Flatbread CLI

  • Commands: flatbread start, init, codegen, proof. There is no flatbread dev.
  • flatbread start -- <framework command> starts GraphQL first, then the framework process. flatbread start --watch -- next dev --turbopack is the Next.js path.
  • --watch incrementally reindexes content, hot-swaps the GraphQL schema, reloads config and matchers, and refreshes codegen. Invalid edits keep the last committed generation; the loop stays up.
  • Default port 5057. -H, --https is reserved and does nothing — the server listens over plain HTTP.
  • -X, --exec overrides the detected package manager (npm/pnpm/yarn/bun). flatbread init writes a config skeleton with sourceFilesystem(), transformerMarkdown(), and Post/Author refs.

Query interface

  • Every list field takes a MongoDB-style filter: eq, ne, in, nin, includes, excludes, lt/lte/gt/gte, exists, strictlyExists, regex, wildcard. Peer paths combine with AND.
  • IDs normalize: 123 and "123" are the same record. Duplicates after normalization fail schema generation.
  • Broken refs fail before schema build with one aggregated error listing every missing target and invalid shape.
  • Field overrides (content[].overrides) change GraphQL type and resolve per field. Path syntax handles nested.object, an.array[], an.array[]with.object. fieldNameTransform rewrites field names globally.
  • exportCollectionsAsJson() and exportCollectionsAsCsv() produce deterministic snapshots after the same ID and ref validation. Re-exported from flatbread.

Plugins

  • @flatbread/source-filesystem — glob paths, refs, and capture segments like content/[category]/[title].md. fetchPaths enables --watch incremental reindex.
  • @flatbread/transformer-markdown — gray-matter frontmatter, unified/remark with gfm, externalLinks, squeezeParagraphs, custom remarkPlugins/rehypePlugins. Exposes _content { raw html excerpt(length) timeToRead(speed) } and _slug from the filename.
  • @flatbread/transformer-yaml — pair as transformer: [transformerMarkdown(), transformerYaml()] for mixed Markdown + YAML collections.
  • @flatbread/resolver-svimgcreateSvImgField('image', { inputDir, outputDir, srcGenerator, avif, webp }) as a field override. Query srcset, srcsetwebp, srcsetavif, placeholder, aspectratio.

Skills

  • The bundled Proof skill ships at packages/proof/skills/proof/. Install with npx skills add …/packages/proof/skills/proof --skill proof. It teaches an agent the 15 mutations, the five bounded reads, the Citation-before-cites order, AcceptDecision's rejectSiblings, and the strict read-your-writes contract.
  • effort-modeling grills a plan one question at a time, then journals Findings, Issues, Constraints, Risks, and Decisions into Proof.
  • grill-with-efforts runs that grilling end-to-end and refuses to implement until the user commits.

Relational content for sites, docs, and internal tools

The same engine still backs sites, docs, and internal tools. Markdown and YAML files become typed collections that link to each other. A post names its authors by id, and Flatbread resolves them. You get versioned, reviewable content with joins over files, without a CMS database.

Docs

  • The READMEs and docs/positioning.md lead with Proof: an agent's Efforts, Issues, Findings, Decisions, Constraints, Risks, Citations, and Blobs written as Markdown records in your repository. The reasoning gets committed and reviewed like code.
  • Relational content for sites, docs, and internal tools stays a first-class second path on the same engine. GraphQL is described as one read interface over the graph rather than as the product.
  • The banner that called the whole project experimental is gone. The narrower qualifiers still hold: the generated TypeScript read API is a prototype, and its selection-string escape hatch is experimental.

Upgrading

Requires Node 20.19+. Install flatbread@^1.0.0 to update.

To adopt agent memory, add proofContent() to your flatbread.config.js, run flatbread proof bootstrap, and add the two .gitignore lines for the journal and read cache. The Proof README has the full setup.