Skip to content

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:

  1. The OSSA machine contract (project.yaml, registry.yaml, bindings/, policies/) — normative for a repo that interacts with OpenStandardAgents. Fully specified in agent-contract-standard.md; not restated here.
  2. 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 in Engineering-Standard/ and is referenced, never copied.
  • project/ — facts specific to this repository (ownership, package model, repository map, environments). Replaces any ambiguous project_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, split active/ and completed/. 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 marked GENERATED / NON_AUTHORITATIVE. Beads/Gas City remains the authority for work state regardless of what is mirrored here — never place a raw beads.json directly 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 indexes AGENTS.md, .agents/context/, docs/, and Engineering-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 in AGENTS.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 commit settings.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.yaml at 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.