Rebasely Beta: data may be purged

The .rebasely folder

One folder at the root of a repository holds what people and agents need besides the code: a knowledge base, a map of the system and the workflows that build it. Rebasely shows the first two as the Knowledge and Architecture tabs and serves them to agents over MCP.

Layout

Everything is plain files, reviewed and versioned with the code they describe. All three parts are optional; add the one you need first.

.rebasely/
  kb/
    index.md                        where to start: links to every note
    concepts/storage.md             how a part of the system works
    decisions/0001-r2-for-blobs.md  numbered, append-only decisions
    guides/local-dev.md             how to do something
  architecture/
    system.yaml                     components, the code they own, what they talk to
    views/write-path.yaml           a subset of the components
    flows/upload.yaml               a dataflow: the ordered steps of one request
  workflows/
    ci.yml                          Rebasely Actions

A .duragit folder

Rebasely used to be called duragit, and the folder was .duragit/. Repositories that still have one keep working. For each of kb, architecture and workflows, Rebasely uses .rebasely/<name> when it exists, and .duragit/<name> otherwise. The two are never merged: once .rebasely/kb/ exists, nothing in .duragit/kb/ is read. The same rule holds for the tabs, for agents over MCP, for Actions, and for rebasely kb check and rebasely arch check.

To move a repository over, rename the folder and push: git mv .duragit .rebasely.

Knowledge base

Markdown notes in .rebasely/kb/, one folder deep: concepts/ explain how something works, decisions/ record why it is that way, guides/ say how to do something. index.md is the landing page of the Knowledge tab. Each note starts with YAML frontmatter and a # Title, and links to other notes by id with [[id]]:

---
id: storage
type: concept
owner: ada
component: api
describes:
  - src/api/storage/**
reviewed: 2026-10-01
---
# Storage

Uploads stream to R2 as they arrive; see [[0001-r2-for-blobs]]
for why, and [[local-dev]] to run it on your machine.
  • id is the file name without .md, in kebab-case; type is concept, decision or guide; owner is who keeps it current; reviewed is the date someone last checked it against the code.
  • A concept says which code it describes (path patterns) and may name its component in system.yaml. The Knowledge tab links both.
  • Decisions are numbered (NNNN-name.md) and append-only: once accepted, a decision is not rewritten. A later one replaces it, and the old one gets status: superseded and superseded-by: <id>. The Knowledge tab shows each decision's number and status, and which decision replaced it.
---
id: 0002-signed-download-links
type: decision
owner: ada
status: accepted
---
# 0002 Signed download links

Private files are served through links signed for one reader...

The Knowledge tab lists the notes by folder, resolves every [[id]] to its note (a link to a note that does not exist is marked missing), shows which notes link to each one, and searches titles and text. Markdown renders as in a README: no raw HTML, and relative links go to the repository's files.

Architecture

.rebasely/architecture/system.yaml lists the components of the system: what kind each is (worker, durable-object, r2-bucket, d1, kv, queue, container, library or external), the code it owns (path patterns; every file has at most one owner), its binding in the Worker's wrangler config, and what it talks_to, with the kind of each connection:

components:
  api:
    kind: worker
    description: The HTTP API and the upload path.
    owns: [src/api/**]
    talks_to:
      - { to: repo-do, via: rpc }
      - { to: blobs, via: r2 }
  repo-do:
    kind: durable-object
    description: One per repository; owns its refs.
    binding: REPO
    owns: [src/repo/**]
  blobs:
    kind: r2-bucket
    binding: BLOBS

A view in views/<name>.yaml is a subset worth looking at on its own:

description: What an upload touches.
components: [api, blobs]

A dataflow in flows/<name>.yaml is one thing the system does, step by step: a title, a description, and steps in order, each going from one participant to another with a short label. A participant is a component of system.yaml or one of the flow's actors, the people and programs outside the system (a browser, a git client). Quote a label that has a comma in it.

title: An upload
description: A file goes to R2 and the repository records it.
actors: [browser]
steps:
  - { from: browser, to: api, label: PUT /files/:name }
  - { from: api, to: repo-do, label: reserve the name }
  - { from: api, to: blobs, label: stream the bytes }
  - { from: api, to: repo-do, label: "commit the file, then answer" }

A flow has at most 60 steps and 10 actors, a label at most 80 characters and a title at most 100; a repository has at most 50 flows, each file at most 256 KiB. When a pull request changes a flow, its Files changed page shows the flow under Visual as numbered steps between the participants, with the steps it adds, removes, reroutes (the same label between other participants), relabels and moves.

The Architecture tab draws the components and their connections, with a switcher for the views, and lists each component with its description, owned paths (linked to the files), binding and connections. Select a component to see what it talks to and what uses it. If paths a component owns are gone from the branch, the page says the map may be out of date.

Workflows

.rebasely/workflows/*.yml are Rebasely Actions workflows: push them and their jobs run on Cloudflare Sandboxes. The repository's Actions tab lists the runs and has a starter workflow to copy.

Keeping it honest

Notes and maps go stale when nothing checks them. The Rebasely CLI does, in the repository's working tree:

  • rebasely kb check checks every note's frontmatter, that each [[id]] names a note, that a superseded decision names a decision that exists, and that each component is in system.yaml. It marks a concept stale when code it describes changed in commits after the note was last edited, until someone edits the note or moves reviewed past those commits. rebasely kb list shows each note's state.
  • rebasely arch check checks system.yaml against the code: every owned pattern matches files, no file has two owners, each binding exists in the wrangler config with the right kind, and every connection it finds in the code (imports, env.BINDING reads, service bindings) is declared in talks_to, and the other way round. It checks that every view and flow names only components of system.yaml (or, in a flow, its own actors), that every step has a label and goes between two different participants, and that flows stay within the limits above.

Both exit 1 when something is wrong, so they fit in a workflow (staleness needs the history, so check out more than the last commit):

      - run: curl -fsSL https://rebasely.com/cli/rebasely.mjs -o /tmp/rebasely.mjs
      - run: node /tmp/rebasely.mjs kb check
      - run: node /tmp/rebasely.mjs arch check

Agents

Agents read the same context through the MCP server: kb.list lists the notes, kb.read returns one with its links resolved and the notes that link to it, kb.search searches them, and arch.get returns the components and connections, of one view or around one component. They answer only what the token may read; a private repository the token cannot reach gets the same answer as one that does not exist.

The Rebasely agent skill tells coding agents to read the knowledge base and the architecture before they change anything, and to update the notes, add a decision and fix system.yaml in the same change when they change behavior.