Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .claude/commands
1 change: 1 addition & 0 deletions .claude/skills
63 changes: 27 additions & 36 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
# AGENTS.md

## Project Overview
# Infrahub

Infrahub is a graph-based infrastructure data management platform by OpsMill. It combines Git-like branching and version control with a flexible graph database (Neo4j) and a modern UI/API layer.

Expand All @@ -22,6 +20,7 @@ Infrahub is a graph-based infrastructure data management platform by OpsMill. It
- `tasks/` – Invoke task definitions
- `schema/` – JSON/GraphQL schema definitions
- `changelog/` – Towncrier changelog fragments
- `dev/` – Internal developer documentation - see [dev/README.md](dev/README.md)

## Commands

Expand Down Expand Up @@ -58,6 +57,13 @@ cd frontend/app && npm run build # Build frontend
cd docs && npm run build # Build documentation
```

## Coding Standards

- Python: `dev/guidelines/backend/python.md`
- TypeScript: `dev/guidelines/frontend/typescript.md`
- Git workflow: `dev/guidelines/git-workflow.md`
- Markdown: `dev/guidelines/markdown.md`

## Generated Files (Do Not Edit)

- `backend/infrahub/core/schema/generated/` – Schema definitions
Expand All @@ -69,39 +75,6 @@ cd docs && npm run build # Build documentation

Regenerate with: `uv run invoke backend.generate` or `cd frontend/app && npm run codegen`

## Markdown Formatting

When editing markdown files (enforced by markdownlint):

- Use `-` for unordered lists
- Add blank line before/after headings, code blocks, and lists
- Use fenced code blocks with language identifier
- No trailing spaces or multiple consecutive blank lines
- No bare URLs (use `[text](url)` format)

## Towncrier for changelog

Towncrier is used to manage the changelog which is being published with every release.
Every issue that is being fixed, or new feature that gets implemented should be accompanied by a proper changelog entry.

The changelog message should be a short and user-facing. It should describe what has been fixed or implemented without focusing on the technical aspects of the implementation.

To create a new changelog entry use the following command.
The filename should be in the format `${ISSUE}.{ACTION}.md`:

- ${ISSUE}: the id of the GitHub issue or feature request, if you are not working on an issue or feature request use `+`.
- ${ACTION}: one of added, fixed, housekeeping

```bash
uv run towncrier -c "content of changelog entry" ${ISSUE}.{ACTION}.md
```

## Git Workflow

- **Main branches:** `stable` (production), `develop` (development), `release-*` (releases)
- **Commit messages:** Conventional commits; include issue references
- **Changelog:** Add fragment to `changelog/` using Towncrier format

## Boundaries

### Always Do
Expand All @@ -124,3 +97,21 @@ uv run towncrier -c "content of changelog entry" ${ISSUE}.{ACTION}.md
- Edit generated files manually
- Skip linting in CI
- Force push to `stable` or `develop`

## Navigation

| Question | Location |
|----------|----------|
| How does the system work? | `dev/knowledge/` |
| How do I do X? | `dev/guides/` |
| Why was this decided? | `dev/adr/` |
| What are we building? | `dev/specs/` |
| How should I write code? | `dev/guidelines/` |
| What commands are available? | `dev/commands/` |

## Component Maps

- Backend: `backend/AGENTS.md`
- Frontend: `frontend/app/AGENTS.md`
- Documentation: `docs/AGENTS.md`
- Python SDK: `python_sdk/AGENTS.md`
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) and the chang

<!-- towncrier release notes start -->

## [Infrahub - v1.6.2](https://github.com/opsmill/infrahub/tree/infrahub-v1.6.2) - 2025-12-22

### Fixed

- Fix Migration041 to determine edge uniqueness correctly and account for incoming Relationship edges. Add new migration to un-delete improperly deleted Relationship metadata. This would only be a problem for Relationships between schemas that have both had their name, namespace, or kind updated multiple times. ([#7916](https://github.com/opsmill/infrahub/issues/7916))

## [Infrahub - v1.6.1](https://github.com/opsmill/infrahub/tree/infrahub-v1.6.1) - 2025-12-11

### Added
Expand Down
83 changes: 13 additions & 70 deletions backend/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,78 +27,16 @@ uv run invoke backend.lint # Lint with ruff + mypy
uv run invoke backend.generate # Regenerate schemas/protocols
```

## Code Style
## Coding Standards

### Async-First
See `dev/guidelines/backend/python.md` for detailed coding standards including:

```python
# ✅ Good
async def get_node(db: InfrahubDatabase, node_id: str) -> Node:
query = await NodeGetQuery.init(db=db, node_id=node_id)
await query.execute(db=db)
return query.get_node()

# ❌ Bad - blocks event loop, no type hints
def get_node(db, node_id):
return db.get(node_id)
```

### Pydantic Models

```python
# ✅ Good
from pydantic import BaseModel, Field

class BranchCreateInput(BaseModel):
name: str = Field(..., min_length=1, max_length=250, description="name of the branch")
description: str | None = Field(default=None, description="Description of the branch")

# ❌ Bad
branch_data = {"name": "feature-x", "description": None}
```

### Docstrings (Google-style)

```python
async def create_branch(
db: InfrahubDatabase,
name: str,
description: str | None = None,
) -> Branch:
"""Create a new branch in the database.

Args:
db: Database connection instance.
name: Name for the new branch.
description: Optional description.

Returns:
The newly created Branch object.

Raises:
BranchExistsError: If branch name already exists.
"""
```

### Naming Conventions

- **Functions/variables:** `snake_case`
- **Classes:** `PascalCase`
- **Constants:** `UPPER_SNAKE_CASE`
- **Test files:** `test_<module>.py`

### Query Pattern

```python
from infrahub.core.query import Query

class MyQuery(Query):
name: str = "my_query"

async def query_init(self, db: InfrahubDatabase, **kwargs) -> None:
self.params["node_id"] = kwargs["node_id"]
self.add_to_query("MATCH (n:Node {uuid: $node_id}) RETURN n")
```
- Async-first patterns
- Pydantic models
- Docstring conventions
- Naming conventions
- Query patterns
- Type hints

## Testing

Expand Down Expand Up @@ -127,3 +65,8 @@ class MyQuery(Query):
- Unparameterized Cypher queries
- Block event loop with sync I/O
- Edit files in `infrahub/core/schema/generated/`

## See Also

- `dev/guidelines/backend/python.md` - Detailed Python coding standards
- `dev/knowledge/backend/` - Backend architecture documentation (to be created)
64 changes: 64 additions & 0 deletions dev/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Developer Documentation

Internal documentation for contributors. For user-facing docs, see `/docs/`.

## Quick Navigation

| I want to... | Go to |
|--------------|-------|
| Understand the architecture | `knowledge/` |
| Follow coding standards | `guidelines/` |
| Learn why we made a decision | `adr/` |
| Complete a specific task | `guides/` |
| See what's being built | `specs/` |
| Explore rough ideas | `explorations/` |
| Use agent commands | `commands/` |

## Directory Guide

- **explorations/**: Rough ideas, spikes, "what if" thinking. Not approved.
- **specs/**: Approved designs. Living during development, then archived.
- **guidelines/**: Prescriptive rules. How code should be written.
- `backend/` - Python backend standards
- `frontend/` - TypeScript/React frontend standards
- **knowledge/**: Descriptive reference. How the system works.
- `backend/` - Backend architecture and patterns
- `frontend/` - Frontend architecture and patterns
- **guides/**: Step-by-step procedures for specific tasks.
- `docs/` - Documentation-specific guides
- `frontend/` - Frontend-specific guides
- **adr/**: Architecture Decision Records. Why we chose what we chose.
- **commands/**: Reusable agent commands (canonical source).
- **prompts/**: Prompt templates for common thinking tasks.
- **skills/**: Domain-specific skill guides for AI agents (e.g., Neo4j Cypher).

## Document Lifecycle

```text
explorations/ → specs/ → knowledge/ or guidelines/
(rough) (approved) (stable)
```

Mark deprecated docs clearly. Don't delete—update with pointers to replacements.

## Current Guidelines

- **Repository Organization**: `guidelines/repository-organization.md` - How to organize content in dev/
- **Python Backend**: `guidelines/backend/python.md`
- **TypeScript Frontend**: `guidelines/frontend/typescript.md`
- **Git Workflow**: `guidelines/git-workflow.md`
- **Markdown Formatting**: `guidelines/markdown.md`
- **Writing Documentation**: `guidelines/documentation.md` - How to write user-facing documentation

## Current Commands

Available agent commands in `commands/`:

- `_shared.md` - Shared instructions for all flows
- `new-component.md` - React component creation flow
- `guided-task.md` - General task flow
- `add-docs.md` - Documentation flow
- `fix-bug.md` - Bug fixing flow
- `fix-github-issue.md` - GitHub issue fixing
- `fix-mypy-module.md` - Mypy type fixes
- `fix-ruff-rule.md` - Ruff linting fixes
112 changes: 112 additions & 0 deletions dev/adr/0001-context-nuggets-pattern.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# 1. Context Nuggets Pattern for Repository Organization

**Status:** Accepted
**Date:** 2024-12-24
**Author:** @opsmill-team

## Context

As we scale our projects and integrate more AI agents alongside our team, we face a crucial challenge: maintaining velocity without sacrificing structure. AI coding assistants like Claude Code, Cursor, and others need context about our project to generate appropriate code, but traditional approaches have limitations:

1. **Context Window Overload**: A single large `AGENTS.md` file becomes unwieldy, causing AI agents to overfit on irrelevant content or miss important constraints buried in thousands of lines.

2. **Tool-Specific Configuration**: Each AI tool wants its own configuration:
- Claude Code reads `CLAUDE.md`
- Cursor uses `.cursor/rules/*.mdc`
- Others converge on `AGENTS.md`
This creates duplication, inconsistency, and maintenance burden.

3. **Discoverability**: When everything is in one place, nothing is findable. Humans and AI agents struggle to locate the specific information they need for a given task.

4. **Decision Traceability**: Without structured documentation, it's difficult to understand why architectural decisions were made, leading to AI agents making choices that conflict with past decisions.

5. **Maintenance Burden**: Large documentation files are hard to review, update, and keep current. Changes become risky because the impact is unclear.

## Decision

We adopt the **Context Nuggets** pattern for organizing our repository, based on the framework developed at OpsMill. This pattern treats documentation like code: small, focused files with clear ownership, linked together rather than duplicated.

### Core Structure

- **Root `AGENTS.md`**: Serves as a lightweight map (~2-3KB) with glossary and pointers to detailed documentation, not a knowledge dump.

- **`dev/` directory**: Centralizes all internal developer documentation as "context nuggets" (200-400 lines each), organized by purpose:
- `explorations/` - Rough ideas, spikes
- `specs/` - Approved designs
- `guidelines/` - Prescriptive rules (how to write code)
- `knowledge/` - Descriptive reference (how the system works)
- `guides/` - Step-by-step procedures
- `adr/` - Architecture Decision Records
- `commands/` - Reusable agent commands
- `prompts/` - Reusable prompt templates
- `skills/` - Domain-specific skill guides for AI agents

- **Tool Compatibility**: Use symlinks to maintain a single source of truth:
- `.claude/commands` → `dev/commands`
- `.claude/skills` → `dev/skills`

### Key Principles

1. **Context nuggets, not dumps**: Small, focused files (200-400 lines) covering one concept each
2. **Map, not encyclopedia**: `AGENTS.md` routes to details; it doesn't contain them
3. **Link, don't duplicate**: Cross-reference between files rather than copying content
4. **Treat docs like code**: PRs, reviews, ownership, version control
5. **Task-scoped loading**: Load what's needed for this task, not everything
6. **Document lifecycle**: Documents evolve from explorations → specs → stable reference

## Consequences

### Positive

- **Task-scoped context loading**: AI agents fetch what they need per task instead of loading everything, improving relevance and reducing context window waste
- **Maintainable documentation**: Small files are easier to review, update, and keep current
- **Version-controlled decisions**: ADRs provide permanent record of why decisions were made
- **Clear ownership**: Each file has a clear purpose and can be owned by specific teams/individuals
- **Tool compatibility**: Single source of truth with symlinks eliminates duplication
- **Better discoverability**: Organized structure makes it easier for humans and AI to find relevant information
- **Scalable**: Structure supports growth from small projects to large monorepos

### Negative

- **Initial setup overhead**: Requires upfront investment to organize existing documentation
- **Link maintenance**: Need to actively maintain cross-references; broken links need fixing
- **Learning curve**: Team members need to understand the structure and where to find/create content
- **Potential fragmentation**: Risk of creating too many small files if not disciplined about organization

### Neutral

- **Treats docs like code**: Documentation changes go through PRs and reviews, same as code changes
- **Requires discipline**: Team must follow the structure and not revert to dumping everything in one file
- **Ongoing maintenance**: Structure requires active curation, but less than maintaining monolithic files

## Alternatives Considered

### Single AGENTS.md File

**Why we didn't choose it**: Becomes unwieldy at scale, causes context window overload, difficult to maintain and review. AI agents struggle to find relevant information in large files.

### Tool-Specific Configurations

**Why we didn't choose it**: Creates duplication and inconsistency. Each tool would have its own version of the same information, leading to drift and maintenance burden.

### No Structure

**Why we didn't choose it**: Leads to chaos, repeated questions, AI-generated code that doesn't match patterns, and decisions that conflict with past choices. The maintenance burden of answering the same questions repeatedly outweighs the cost of structure.

### Separate Documentation Repository

**Why we didn't choose it**: Creates disconnect between code and documentation. Documentation should live with code for better discoverability and easier maintenance. Version control provides safety net for all changes.

## Implementation Notes

- The `dev/` directory is separate from `docs/` (user-facing documentation)
- Subdirectories like `backend/`, `frontend/`, `docs/` within `guides/` and `guidelines/` are used for domain-specific organization
- The `skills/` directory extends the base pattern for domain-specific AI agent guidance (e.g., Neo4j Cypher queries)
- File size target is 200-400 lines, with maximum of 500 lines before splitting
- Documents follow a lifecycle: explorations → specs → knowledge/guidelines

## References

- Repository Organization for AI-Assisted Development @ OpsMill
- `dev/guidelines/repository-organization.md` - Detailed guidelines for organizing content
- `dev/README.md` - Quick navigation guide
Loading
Loading