Bluefly Repository Structure Standard¶
Status: Canonical Standard ID: STD-REPO-001 Authority: Bluefly Engineering Governance Stability: Binding — capability-conditional (do not scaffold what a repo doesn't use) Version: 1.0.0
0. Relationship to Other Standards (read this first)¶
This standard governs capability placement — same capability, same location, same owner, in every repository. It does not restate rules that already have a canonical home:
| Already governed elsewhere | Canonical home | Do not restate here |
|---|---|---|
Root file contract: README.md, AGENTS.md, llms.txt (v2), OWNERSHIP.md, CLAUDE.md/GEMINI.md as thin adapters, root hygiene, prohibited root files, ecosystem-native root profiles |
documentation-governance-standard.md §6 |
Root-file rules |
.agents/ as a machine-consumable OSSA contract (project.yaml, registry.yaml, bindings/, policies/) |
agent-contract-standard.md |
The OSSA contract schema |
Naming, lifecycle states, documentation location classes (Engineering-Standard/, Playbooks/, Evidence/, etc.) |
documentation-governance-standard.md §1–§3 |
Doc naming/lifecycle |
| Git branch/worktree/repository-health governance | repository-governance-workflow.md, ossa-repository-governor-spec.md |
Git hygiene |
This standard owns: the four-tier Authority Model; the .agents/
knowledge layer (skills/, context/, roles/) and how it coexists with
the OSSA contract layer above; ownership boundaries for tool-state
directories (.beads/, .qmd/, .codegraph/, .claude/); conditional rules
for .well-known/ and .gitlab/duo/; conventions for openapi/, packages/,
scripts/, src/, container placement, and tests; and canonical minimal /
service / agent-native repository templates.
Do not create empty directories to satisfy this standard. A directory exists only when the project actually uses that capability. This is a Contribution-First doctrine: one canonical location per capability, never a second competing home for the same fact.
1. Authority Model¶
Repository knowledge divides into four classes. Canonical information must never be duplicated into a provider-specific or tool-state directory.
| Class | Contents | Examples |
|---|---|---|
| Canonical source | The actual instructions, code, and architecture | AGENTS.md, README.md, source code, .agents/skills/, .agents/context/, OpenAPI, protocol metadata (.well-known/) |
| Provider adapter | Thin, vendor-specific pointers to canonical source | CLAUDE.md, GEMINI.md, .claude/, .gitlab/duo/ |
| Tool state / index | Machine-generated indexes and caches over canonical source | .qmd/, .codegraph/, .beads/, provider caches |
| Generated output | Build/test output, never hand-edited, never authoritative | test results, coverage, build artifacts, generated indexes |
A provider adapter or a tool-state directory that starts accumulating original doctrine is a standard violation: fix it by moving the content to its canonical source class and leaving a pointer behind.
2. .agents/ — Two Coexisting Layers¶
.agents/ at repository root serves two distinct, coexisting purposes. They
do not conflict and a repository may carry either or both:
- The OSSA machine contract (
project.yaml,registry.yaml,bindings/,policies/) — normative for a repo that interacts with OpenStandardAgents. Fully specified inagent-contract-standard.md; not restated here. - The provider-independent knowledge layer —
skills/,context/,roles/— specified below. This is durable information intended for multiple agent systems (Claude, Gemini, Codex, GitLab Duo), not a runtime contract.
Both layers forbid the same things (agent-contract-standard.md §Forbidden
Artifacts applies to the whole directory): no runtime caches, no generated
projections, no hardcoded secrets, nothing belonging to .gc /
.agents-workspace scopes.
2.1 .agents/skills/ — canonical Agent Skills location¶
.agents/skills/
├── build-project/
│ ├── SKILL.md
│ ├── scripts/
│ ├── references/
│ └── assets/
└── release-project/
└── SKILL.md
Every skill follows the Agent Skills specification: minimum
<skill-name>/SKILL.md with frontmatter (name, description — what it
does and when an agent should use it). .agents/skills/ is the authoring
authority. Provider directories such as .claude/skills/ should consume,
link to, or be generated from these skills where tooling permits — never
maintain two independently edited copies of a skill.
2.2 .agents/context/ — the knowledge layer behind AGENTS.md¶
.agents/context/
├── README.md
├── architecture/
├── policy/
├── project/
├── api-cli/
├── upstreams/
├── design-systems/
├── guides/
├── plans/
└── generated/
Lowercase kebab-case names. Only create the subdirectories a repository actually populates.
architecture/— long-lived architecture (system overview, runtime model, dependency model, data flow, integration boundaries). No temporary implementation plans.policy/— repository-specific governance and invariants (security, authentication, branching, dependency policy, generated-files rules). Company-wide policy stays inEngineering-Standard/and is referenced, never copied.project/— facts specific to this repository (ownership, package model, repository map, environments). Replaces any ambiguousproject_context/naming.api-cli/— API/CLI usage guidance (cli.md,api.md,authentication.md,examples.md). Machine-readable API contracts still belong in OpenAPI (§4), not here.upstreams/— integration notes on external/upstream projects that materially affect this repository. Prefer links and concise notes; do not mirror upstream documentation.design-systems/— UI/frontend projects only (tokens, components, Storybook, Figma, accessibility).guides/— runbooks and human/agent procedures (local development, release, debugging, incident response, package publishing). If a procedure should be executable/reusable by agents, make it a Skill (§2.1) instead.plans/— intentionally committed and reviewed plans only, splitactive/andcompleted/. A committed plan is an engineering artifact; a model scratchpad is not and must never be auto-dumped here.generated/— machine-produced context (e.g. a Beads snapshot, dependency map, CodeGraph summary), always markedGENERATED / NON_AUTHORITATIVE. Beads/Gas City remains the authority for work state regardless of what is mirrored here — never place a rawbeads.jsondirectly beside canonical context.
2.3 .agents/roles/ — repository-level personas, not a generic dump¶
.agents/agents/ is not a Bluefly convention and must not be created —
no interoperability standard defines it. For Bluefly-defined durable
execution roles that genuinely belong to this repository, use:
.agents/roles/
├── architect.md
├── reviewer.md
└── release-manager.md
If a Gas City pack already owns an agent definition, Gas City remains the
owner — do not duplicate it here. .agents/roles/ holds only roles that are
repository-local, not platform-wide.
3. Tool State Is Not Documentation¶
.beads/, .qmd/, .codegraph/, and .claude/ are tool-state / provider
directories (Authority Model class 2–3, §1). None of them may become an
alternate issue tracker, architecture source, agent-memory system, or
documentation authority.
.beads/— belongs to Beads/Gas City. Agents read it through supported tooling (bd,gc), not direct file manipulation..qmd/— runtime/index state unless QMD explicitly requires version-controlled configuration there. QMD indexesAGENTS.md,.agents/context/,docs/, andEngineering-Standard/— it never becomes a fifth source of truth. Do not author doctrine into.qmd/..codegraph/— same model:CODEGRAPH = INDEX,SOURCE_CODE = AUTHORITY. Generated graph databases, caches, and indexes should normally be.gitignored. If CodeGraph needs project configuration, version only the minimal configuration required to reproduce the index — never the generated graph data..claude/— Claude-specific integration state (settings.json,rules/,commands/,skills/). Bluefly's canonical cross-agent logic stays inAGENTS.md,.agents/skills/,.agents/context/. Where practical,.claude/skills/should be materialized or linked from the canonical skill owner rather than independently authored. Never store durable Bluefly architecture exclusively under.claude/. Never commitsettings.local.json,CLAUDE.local.md, or machine-local memory unless a specific upstream contract explicitly requires it.
4. GitLab Duo Integration¶
Do not standardize .gitlab/agents/ or .gitlab/flows/ — these are not
Bluefly repository conventions; GitLab agents and flows are managed through
GitLab's own Agent Platform / AI Catalog, not repository files. Current
GitLab Duo repository execution configuration belongs under:
.gitlab/duo/agent-config.yml
Use this only when the project requires GitLab Duo flow execution
configuration (execution image, setup, network policy, cache). Repository
behavior shared across agent systems belongs in AGENTS.md, not here.
5. .well-known/ — Conditional, Deployment-Gated¶
.well-known/ is an Internet discovery surface (ossa.json, duadp.json,
did.json, and similar). Rule:
IF the deployed application actually publishes these resources at
https://<origin>/.well-known/... THEN .well-known/ is allowed in the repo
ELSE omit it
Do not add .well-known/ to a repository merely because the platform has
the concept. A repository folder named .well-known with no corresponding
published origin has no value and is DEBT_WARNING/ARCHIVE_CANDIDATE on
audit.
6. API Contracts¶
- One primary API →
openapi.yamlat repository root. - Multiple APIs or a large split spec:
openapi/
├── README.md
├── public.yaml
├── internal.yaml
├── components/
└── examples/
Do not maintain both forms in one repository unless tooling requires it.
API implementation stays under src/api/ (§8); OpenAPI is the contract,
not the code.
7. packages/ — Monorepos Only¶
packages/
├── sdk/
├── cli/
├── ui/
└── shared/
Single-package repositories keep that package at repository root — do not
add packages/ there. This extends, and does not replace, the Monorepo
ecosystem profile already defined in documentation-governance-standard.md
§6 (root README/AGENTS.md/llms.txt at the meta-repo level, component-
local interface contracts per sub-project).
8. scripts/ and src/¶
scripts/ — repository-level automation (build, test, validate,
release, generate). Scripts must be deterministic, runnable by both humans
and agents, contain no secrets, and reuse shared CI capability rather than
duplicate it. Agent-specific scripts belong inside the owning skill:
.agents/skills/<skill>/scripts/, not a generic scripts/.
src/ — create only the subdirectories a project actually uses.
Recommended vocabulary when applicable: api/, agents/, auth/, cli/,
config/, integrations/, lib/, mcp/, middleware/, routes/,
schemas/, services/, types/, utils/. Domain-specific directories
(src/a2a/, src/formulas/) only when the project implements those
concepts for real — never scaffolded speculatively.
9. Containers Are Not Source¶
Do not standardize src/docker/. Container/build infrastructure is not
application source. Prefer:
docker/
├── Dockerfile
├── compose.yaml
└── scripts/
or project-standard root files (Dockerfile, compose.yaml). DDEV
projects use .ddev/ as their primary local-environment surface (see
ddev-standard.md), not a custom docker/ tree.
10. Tests: Source vs. Generated Output¶
tests/ is source and is committed. test-results/ (not tests_results/)
is generated and is normally .gitignored — this also applies to
coverage/ and playwright-report/.
tests/
├── unit/
├── integration/
├── functional/
├── e2e/
├── fixtures/
└── support/
Rule: tests/ = SOURCE, test-results/ = GENERATED. Never commit test
output as history.
11. Deployable Services — DEPLOY.md¶
DEPLOY.md is a conditional root file for applications/services that
deploy independently (added to the conditional-root-files table in
documentation-governance-standard.md §6 — see that table for the full
list of conditional root files). Cover: deployment owner, environments, CI
owner, artifact, promotion path, rollback model, runtime authority,
verification method. Never put credentials in it. Libraries that cannot
deploy independently do not get one.
12. Canonical Repository Templates¶
Illustrative, not mandatory scaffolding — instantiate only what a given repository actually uses (§0).
12.1 Minimal repository¶
AGENTS.md, CLAUDE.md, GEMINI.md, README.md, OWNERSHIP.md,
.gitlab-ci.yml, .gitignore
.agents/{skills/,context/}
src/, tests/
12.2 Service repository¶
AGENTS.md, README.md, OWNERSHIP.md, ARCHITECTURE.md, DEPLOY.md,
CLAUDE.md, GEMINI.md, openapi.yaml
.agents/{skills/,roles/,context/}
.gitlab/duo/
.well-known/ # only if it actually publishes discovery metadata
docker/, scripts/, src/, tests/
12.3 Agent-native / platform repository¶
AGENTS.md, README.md, OWNERSHIP.md, ARCHITECTURE.md
.agents/{README.md, skills/, roles/,
context/{README.md, architecture/, policy/, project/, api-cli/,
upstreams/, guides/, plans/, generated/}}
.gitlab/duo/
openapi/, packages/, scripts/, src/, tests/
13. Deprecated / Rejected Conventions¶
Do not standardize these; use the replacement instead.
| Rejected | Replacement |
|---|---|
.agents/agents/ |
.agents/roles/ (only for genuinely repository-local roles) |
.agents/context/beads.json (bare, beside canonical context) |
.agents/context/generated/beads.json, marked GENERATED / NON_AUTHORITATIVE |
.gitlab/agents/, .gitlab/flows/ |
.gitlab/duo/agent-config.yml (§4) — GitLab's Agent Platform / AI Catalog owns the rest |
tests_results/ |
test-results/ (§10) |
src/docker/ |
docker/ or root Dockerfile/compose.yaml (§9) |
14. The Governing Rule¶
One knowledge hierarchy: AGENTS.md → .agents/context/ →
.agents/skills/ → source/APIs/tests. Provider adapters
(CLAUDE.md, GEMINI.md, GitLab Duo) sit beside it and point at it. Tools
(QMD, CodeGraph, Beads) may index it; an index never becomes the source.
Author once. Reference everywhere. Generate adapters where necessary.
AGENTS.md is the map, not the encyclopedia. .agents/ is
provider-independent. Provider directories do not own architecture. Tool
state is not project knowledge. Generated output is never confused with
source. Do not create empty architecture.
15. Project Profiles¶
Every active Bluefly repository has exactly one profile. The profile is
declared in OWNERSHIP.md under the key project_profile: (or
.agents/context/project.md when the project has a full context layer).
Profile drives which capability placeholders apply — do not scaffold
directories or files the profile does not use.
| Profile | Typical structure anchors |
|---|---|
INTERNAL_LIBRARY |
src/, tests/, ecosystem package file at root |
PUBLIC_LIBRARY |
same + LICENSE, CHANGELOG.md, CONTRIBUTING.md |
SERVICE |
src/, tests/, openapi.yaml, DEPLOY.md, docker/ |
CLI |
src/, bin/, tests/, ecosystem package file |
DRUPAL_CONTRIB_MODULE |
<machine>.info.yml, src/, config/, templates/, tests/ |
DRUPAL_PRIVATE_MODULE |
same as contrib but no Drupal.org release |
DRUPAL_THEME |
<machine>.info.yml, <machine>.libraries.yml, templates/, css/, js/ |
DRUPAL_RECIPE |
recipe.yml, config/, modules/ |
DRUPAL_SITE |
composer.json, composer.lock, config/sync/, patches/ (via BOM) |
AGENT_PROJECT |
src/, .agents/ (full OSSA contract), openapi/ |
SKILLS_PROJECT |
.agents/skills/, src/ only if runtime logic is needed |
CI_COMPONENT_LIBRARY |
templates/, examples/, ecosystem package file |
IAC |
ecosystem-native layout (Terraform/Pulumi/Ansible); no src/ |
CONTAINER_RUNTIME |
docker/ or root Dockerfile/compose.yaml, minimal source |
DOCUMENTATION |
Engineering-Standard/ or equivalent; no src/ |
POLICY |
policies/, schemas/ |
SCHEMA_REGISTRY |
openapi/, schemas/, src/ for compiler/tooling only |
ARCHIVED |
read-only; no new work; ARCHIVED.md at root explaining context |
Profile-specific Drupal conventions are authoritative in drupal-standard.md.
Do not replicate Drupal ecosystem rules here.
16. Project Context Layer — .agents/context/¶
The .agents/context/ directory holds durable, curated,
project-specific context that agents need to act correctly in this
repository. It is provider-independent and not a scratch folder.
16.1 Required Files (active projects)¶
.agents/README.md — Agent entrypoint. Required for any project where
agents are expected to operate. Specifies (concisely):
PROJECT= machine name
PROFILE= one value from §15
PURPOSE= one sentence
VISION= one sentence or link to vision.md
PRIMARY_OBJECTIVE= current cycle objective (or link to objectives.md)
SOURCE_AUTHORITY= where canonical source lives (GitLab project URL)
WORK_AUTHORITY= "Beads" or GitLab Issues if public-facing
BUILD_COMMANDS= exact commands
TEST_COMMANDS= exact commands
RELEASE_FLOW= branch → MR → CI → merge target
GLOBAL_STANDARDS= comma-separated: STD-REPO-001, STD-GIT-001, ...
LOCAL_CONTEXT= relative paths worth reading first
IMPORTANT_BOUNDARIES= what not to touch, what's generated
Keep it under 60 lines. Link to context files; do not paste them.
.agents/context/vision.md — Stable project direction. Required when
.agents/README.md cannot fully express the project's purpose. Contains:
MISSION=
VISION=
WHY_THIS_PROJECT_EXISTS=
WHAT_SUCCESS_LOOKS_LIKE=
WHAT_THIS_PROJECT_OWNS=
WHAT_THIS_PROJECT_DOES_NOT_OWN=
TARGET_CONSUMERS=
LONG_TERM_DIRECTION=
Vision should be stable across months. Do not use it as a task list.
.agents/context/objectives.md — Current cycle intent. Required when
the project has active work. Contains:
CURRENT_PRIMARY_OBJECTIVE=
SECONDARY_OBJECTIVES=
SUCCESS_CRITERIA=
MAJOR_CONSTRAINTS=
OUT_OF_SCOPE=
Beads tracks the actual work graph — objectives are not a task list. Curate objectives; do not append forever.
16.2 Conditional Files¶
Create these only when a project genuinely has them:
| File | When to create |
|---|---|
architecture.md |
Project-specific architecture that is too narrow for BluCity-Docs |
api.md |
API surface summary + link to OpenAPI spec |
dependencies.md |
Key upstream dependencies and their version contracts |
integrations.md |
How this project integrates with other Bluefly systems |
deployment.md |
Deployment model, environments, promotion path |
boundaries.md |
Explicit "do not touch" rules, generated paths, upstream territory |
project.md |
Machine-readable project identity (if OWNERSHIP.md is insufficient) |
Do not create a file for every concept. If a concept is fully covered by the source code and AGENTS.md, no extra context file is needed.
16.3 Context Freshness¶
Every .agents/context/*.md file should carry provenance metadata where
useful:
SOURCE: <where the ground truth lives — GitLab project URL, spec file, etc.>
LAST_REVIEWED: YYYY-MM-DD
AUTHORITY: CURATED | GENERATED | RUNTIME
Agents must treat stale context (>90 days without review on fast-moving projects) as potentially outdated — verify from source before acting.
Authority levels:
- CURATED — hand-authored, authoritative for agents
- GENERATED — machine output; files live in generated/ subdirectory
- RUNTIME — reflects live state; never committed unless explicitly required
16.4 .agents/context/generated/¶
Machine-generated project context (dependency graphs, API inventories, Bead snapshots) lives here. Every file must include:
GENERATED: YES
GENERATOR: <tool or script>
SOURCE: <what was read to produce this>
REFRESH_COMMAND: <how to regenerate>
DO_NOT_EDIT: YES
Never manually edit files in generated/. Regenerate from source.
16.5 Scope Boundary¶
.agents/context/ is for project-specific facts. A statement that
would apply identically to multiple Bluefly projects belongs in
BluCity-Docs, not in every project's context directory.
Rule:
QUESTION: Would another project need to obey this same rule?
YES → BluCity-Docs
NO → .agents/context/ (or docs/)
QUESTION: Is this a fact about this specific project?
YES → .agents/context/
NO → probably already in BluCity-Docs; link, don't copy
17. Work Ownership — No Parallel Planning System¶
Exactly one system owns each layer:
| Layer | Owner | Examples |
|---|---|---|
| Tasks / execution graph | Beads | what work exists, status, priority, dependencies, assignment, completion |
| Project vision / intent | .agents/context/ |
vision.md, objectives.md |
| Human documentation | docs/ |
architecture, API reference, integration guide |
| Cross-project doctrine | BluCity-Docs | standards, governance, platform architecture |
| Source truth | GitLab (canonical) | code, specs, configuration |
Forbidden parallel systems — do not create these alongside Beads:
TODO.md
tasks.md
backlog.md
work-list.md
agent-tasks.md
agent-plan.md
random planning checklists disconnected from Beads
When a Markdown plan file is needed for a bounded migration or major
refactor, it must include BEAD=<id> and STATUS= and be deleted or
archived in git after the bead is closed. It is execution support, not a
second work ledger.
GitLab Issues may exist for public/customer collaboration. They are not a replacement for Beads in internal project execution.
18. Per-Project Compliance Audit¶
Use this receipt format when auditing a repository against this standard.
Complete one receipt per repository. Do not advance to the next repository
until PROJECT_COMPLETE=YES.
PROJECT=
PROFILE= (one value from §15)
PURPOSE=
VISION=
PRIMARY_OBJECTIVE=
README_EXISTS=YES|NO
AGENTS_MD_EXISTS=YES|NO
OWNERSHIP_MD_EXISTS=YES|NO
AGENTS_DIR_EXISTS=YES|NO
AGENTS_README=YES|NO|N/A
VISION_DOC=YES|NO|N/A
OBJECTIVES_DOC=YES|NO|N/A
LOCAL_CONTEXT_FILES= (list or NONE)
GENERATED_CONTEXT= (list or NONE)
GLOBAL_STANDARDS_REFERENCED=YES|NO
GLOBAL_DOCTRINE_COPIED_LOCALLY=YES|NO (must be NO)
ROOT_FILES= (actual list)
ROOT_DIRS= (actual list)
MISSING_REQUIRED_FILES= (NONE or list)
UNEXPECTED_ROOT_FILES= (NONE or list)
SLOP_DIRECTORIES= (NONE or list from §0 forbidden list)
DUPLICATE_DOCS=NO|list
PARALLEL_TASK_SYSTEM=NO|list
PERSONAL_PATHS=NO|list
STALE_PLANS=NO|list
AGENT_TRANSCRIPT_DUMPS=NO|list
BEADS_USED=YES|NO
SOURCE_OWNER_CLEAR=YES|NO
WORK_OWNER_CLEAR=YES|NO
DOC_OWNER_CLEAR=YES|NO
CONTEXT_OWNER_CLEAR=YES|NO
FILES_MOVED= (NONE or list with destination)
FILES_REMOVED= (NONE or list)
MR= (URL or N/A)
CI= (PASS|PENDING|N/A)
STRUCTURE_COMPLIANT=YES|NO
CONTEXT_COMPLIANT=YES|NO
DOCS_COMPLIANT=YES|NO
EXCEPTIONS= (documented deviations with rationale)
PROJECT_COMPLETE=YES|NO
Audit order: master-template → gitlab_components → BluCity-Docs → blu-cli → api-schema-registry → a Drupal contrib module → a Drupal private module → a Drupal site → agent-docker → IaC → ContextControl.
One project at a time. Audit evidence in .agents/receipts/ (if the
project has that directory); otherwise in a dated file in NAS Scratch.
Provenance¶
Adapted from operator-authored doctrine (Thomas @ Bluefly.io), landed as
Bluefly canonical standard via the estate's git-flow
(docs/repository-structure-standard → release/v0.1.x → main).
Cross-references added on landing to documentation-governance-standard.md
and agent-contract-standard.md to keep one canonical home per fact,
consistent with the estate's Contribution-First Doctrine.