A Spektacular (Spek) project can span more than one repository, tracked together as one coherent unit of work.
Spek projects are designed to work the way that you work. For example some teams may choose to keep spektacular configuration and code in a single repository; however, some teams may prefer to keep this configuration separate. This flexibility does not tightly couple Spek to your projects enabling a team or even team members within a team freedom of choice.
A project can register any number of other repositories too, such as a application repo alongside its documentation repo, so that planning and implementation work can address both together instead of treating them as separate, disconnected efforts.
The Spectacular project is a live instance of the capability the config.yaml
registers two repositories: the spektacular repository the project is
colocated with, and the spektacular-website repository this page is built
from. The registry itself holds nothing but a name and a location for each:
name: spektacularcommand: spektacularagent: claude
repos: - name: spektacular location: . - name: docs location: ../../spektacular-website/.spektacularA location names the folder holding that repository’s repo.yaml, and
that file is where the repository describes itself. The spektacular
entry’s . resolves to the project’s own .spektacular/ folder, so this
repository’s description sits beside the registry that names it:
description: Agent-agnostic CLI tool for spec-driven developmentrole: tooltags: - go - cli
source: provider: file config: location: .. # the code is the folder above this one
knowledge: provider: file config: location: knowledge
changelog: provider: file config: directory: changelogThe spektacular-website entry points at a repo.yaml located in the
spektacular-website:
description: Marketing and documentation site for Spektacular, built with Astrorole: documentationtags: - docs - website - astro
source: provider: file config: location: ..Neither repo.yaml refers back to the project that registers it, which is
what lets the same repository belong to more than one project.
spektacular repo list reads both sides together and reports, for each
repository, the absolute folder holding its Spektacular files, the
absolute folder its code is in, whether that code is a checkout you
provided or a clone Spek made, and the description, role and tags
the repository gives for itself.
Every registered repository has two folders that matter: the one holding
its repo.yaml, knowledge and changelog, and the one holding its code.
They are usually nested, and occasionally far apart. Knowing which is
which is most of what there is to understand here.
In a simple one repository setup, the spektacular files are located in a
.spektacular/ folder next to the code base. A project created by the
command spektacular init <agent> starts this way:
my-project/├── .spektacular/│ ├── config.yaml # repos: [{name: api, location: .}]│ ├── repo.yaml # source: file, location ..│ ├── knowledge/ # this repository's own knowledge│ ├── specs/ # the project's central stores│ └── plans/└── src/ # the codeA project can also be completely independent of the code repo. The below instance has the spectacular config and knowledge base located in a separate folder completely independent of the code base. This suits teams that cannot, or would rather not, commit Spek files into a code repository: the project folder can be committed and shared while the code repository receives only code changes.
my-project/├── .spektacular/│ ├── config.yaml # repos: [{name: api, location: ../repos/api/.spektacular}]└── repos/api/.spektacular/ ├── repo.yaml # source: file or git, pointing at the code ├── knowledge/ └── changelog/ # this repository's derived records└── repos/docs/.spektacular/ ├── repo.yaml # source: file or git, pointing at the code ├── knowledge/ └── changelog/ # this repository's derived recordsAdding a repository is a short conversation. You are asked which repository you want to add, and everything else is proposed for you, drawn from the repository itself, so you confirm or correct a suggestion rather than supplying facts your own code already states.
Only the first question is asked cold, because the folder your code sits in is the one thing that cannot be worked out by reading it. Spek then reads what the repository says about itself, its README, whatever manifest its language uses, and what it is written in, and every question after that arrives with an answer already drafted:
Version matches. Here's what's registered in this project today:
┌─────────────┬─────────────────────────────────────────────────────────────┬───────────────┐│ name │ code root │ role │├─────────────┼─────────────────────────────────────────────────────────────┼───────────────┤│ spektacular │ /home/nicj/code/github.com/hivecommons/spektacular │ tool │├─────────────┼─────────────────────────────────────────────────────────────┼───────────────┤│ docs │ /home/nicj/code/github.com/hivecommons/spektacular-website │ documentation │└─────────────┴─────────────────────────────────────────────────────────────┴───────────────┘
Both are file-source repos with colocated footprints, both resolve cleanly, no stale or missing-footprint warnings.──────────────────────────────────────────────────────────────────────────────────────────────────── ☐ Repo action
What would you like to do with the repo registry?
❯ 1. Add a repo Start the guided add workflow (`repo new`) to register another repo in this project. 2. Just the listing You wanted to see what's registered — the table above is the answer, nothing further to do. 3. Repair a footprint Recreate a repo.yaml footprint that's missing or broken. (Note: neither registered repo currently reports a problem.) 4. Type something.──────────────────────────────────────────────────────────────────────────────────────────────────── 5. Chat about this
Agent: Which repo would you like to add? Tell me the folder its code lives in — a path on this machine.
You: ../jumppad
Agent: Found it — a Go tool that calls itself jumppad, for building cloud native development environments. I will call it jumppad in this project. Does that work for you? If you would rather not go through the remaining details one at a time, I can read the repo and fill them in myself — just say the word and I will take it from here.
You: ok do it
Agent: jumppad has been added to the project. It's known here as jumppad, its code stays at /home/nicj/code/github.com/jumppad-labs/jumppad, and the project's folder for it now sits at /home/nicj/code/github.com/jumppad-labs/jumppad/.spektacular/.If you look at the config.yaml, you will see that the additional repository has been added by the agent.
repos: - name: spektacular location: . - name: docs location: ../../spektacular-website/.spektacular - name: jumppad location: ../../jumppad/.spektacularAnd the jumppad repository’s own repo.yaml contains all the details about it:
description: CLI tool for building local cloud native development environments — declares OCI containers, Nomad and Kubernetes clusters and supporting resources in the Jumppad HCL configuration language and brings them up via Docker or Podman drivers.role: tooltags: - go - cli - hcl - containers - dev-environmentssource: provider: file config: location: ..knowledge: provider: file config: location: knowledgechangelog: provider: file config: directory: changelogA project’s own .spektacular/config.yaml holds membership only: which
repositories belong to this project, and where each one’s Spek
files are. Everything that describes a repository itself, its
description, role, tags, knowledge sources, changelog settings, and
where its code lives, lives instead in that repository’s own
repo.yaml. The split exists because a repository’s own file carries no
reference back to any project that registers it, so the same repository
can belong to more than one project without re-entering its description
each time.
repos section In config.yaml, each entry names a member repository and locates the
folder holding its repo.yaml: repos[].name and repos[].location.
See Configuration for the full reference.
source section repo.yamlIn the repository’s own repo.yaml: where its code lives, as a provider
block. provider: file with a config.location path names a checkout
on disk, resolved from the folder holding repo.yaml; provider: git
with a config.location address is cloned on first use. See
Configuration for the full reference.
description, role, tags fields These live only in the repository’s own repo.yaml, never in the
project’s registry entry. Planning reads them to decide which repository
a requirement belongs to, so they are worth filling in. See
Configuration for the full reference.
Planning and implementation can address requirements that belong to more than one registered repository in a single piece of work. The plan attributes each requirement to the repository it lands in, using that repository’s description, role and tags, and the implementation is carried out in each one’s own code.
Changelog records are written twice over. One central record lives in the project, covering the feature as a whole, and every repository the work touched gets its own derived entry in its own changelog store, carrying front matter that names the project and the spek and plan it came from:
---created_date: "2026-09-02"document_status: draftproject: spektacularproject_source: git@github.com:hivecommons/spektacular.gitspec: 000046_relocatable-repo-footprintplan: 000046_relocatable-repo-footprint---Entries are filed under a folder named after the project, so several projects writing into one shared repository can never collide, and each repository’s history stays readable on its own terms even though the work that produced it spanned several.
A repository whose source names a git address is cloned automatically
the first time it’s needed, into the project’s own gitignored working
folder, so clones never enter the project’s history.
Once a clone exists it is reused as-is. Spek never fetches or pulls
on your behalf. If a clone has fallen behind its remote, repo list
reports a stale_note against that repository and leaves the decision to
you:
git -C .spektacular/repos/api pullListing is otherwise free of side effects. A repository whose git source has not been cloned yet reports an empty root rather than triggering a clone, so inspecting a project never changes it.
Any repository, or the project’s own storage, can carry a
.spektacular_ignore file using gitignore-style patterns, to keep paths
such as build output or vendored code out of Spek’s own search
and listing results.
The file sits at the root of the source it applies to and affects only Spek’s own search and listing. A file named directly is still readable even when it matches a pattern, and the agent’s ordinary file tools are unaffected, so an ignore file is a way to keep results relevant rather than a way to restrict access.
The configuration reference covers both sides of the split, key by key.