Skip to content
Open
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 .agents/rules/code-doc-style.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,4 @@ Where IDs *do* belong:
- Documents the contract of a public function (inputs, outputs, errors raised) when it crosses a module boundary.
- Stays silent by default. If code needs a comment to explain *what* it does, rename or extract until it doesn't. A comment that restates the code is worse than none — noise that rots the moment the code changes.
- When a why-comment is warranted, one sentence. If the why needs a paragraph, it belongs in the function's docstring or a `dev/knowledge/` page, not inline. Reviewers repeatedly ask for multi-line inline comments to be condensed.
- Don't narrate the approach *not* taken. A paragraph on the alternative rejected, or the call deliberately avoided, belongs in the PR description; keep the line stating what the code does. Reviewers repeatedly ask for these paragraphs to be deleted. A negative statement that is part of the contract stays — "this never raises", "does not commit the transaction", "not thread-safe".
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ CI validates that all generated files are committed — the `validate-generated-
- Before diagnosing _or_ modifying code in any domain, read the relevant docs in `dev/knowledge/` for that domain. The architectural intent (which layer owns a concern) is often the answer to the bug — don't reason from code alone
- Run formatters before committing (`uv run invoke format`, `pnpm biome:fix`)
- Write tests for new functionality
- Add a towncrier changelog fragment for any user-visible change, UI styling included (use the `creating-changelog-entries` skill); internal maintenance still gets a `housekeeping` fragment, and only a refactor with no user-visible or maintenance impact needs none
- Use type hints for Python (backend) and TypeScript types (frontend)
- In `tasks/*.py`, use the shared helpers for project-scoped Docker Compose operations rather than hard-coding `docker compose` or service names: build the command with `get_compose_cmd` (it selects the required `--profile`/`--ansi never` options) plus `get_env_vars`, run it through `execute_command` (which handles `sudo`), and reference named services via the shared constants (e.g. `SERVICE_WORKER_NAME`). Literal `docker compose` is acceptable only for genuinely global, project-agnostic discovery commands.
- Before pushing, run `/pre-ci` (`.agents/commands/pre-ci.md`) — it runs the locally-executable CI checks, including generated-file and generated-doc validation (`docs.validate`); CI fails if any generated file is stale
Expand Down
1 change: 1 addition & 0 deletions dev/guidelines/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ agents with a job to finish.
- Focus on "how to" instead of "how it works" (in topics)
- Reference Jira tickets, GitHub issues, PR numbers, or spec files as the reason for a rule — describe the underlying behavior or constraint instead. These rot once the item closes and the spec is forgotten, and a reader can't verify a closed reference the way a reviewer could at review time. Work-item IDs belong in commit messages, PR descriptions, and changelog fragments; track a significant architectural decision in `dev/adr/` (see `dev/adr/README.md`) instead, written as a self-contained Context/Decision/Consequences record independent of the spec that prompted it
- Cite a `file.py:123` or `file.py:100-140` line location — reference the module path and symbol only (`some/module.py::SomeClass`). A symbol reference survives the code moving within a file or being renamed at the call site; a line number does not, and a spec's own line-numbered citations routinely rot before the feature it describes even merges
- Reference another step by its number ("see step 4") — numbering shifts when a step is added or removed; name the action instead ("after restarting the workers")

## Documentation Workflow

Expand Down
23 changes: 23 additions & 0 deletions dev/guidelines/frontend/styling.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,29 @@ export const Button = ({ variant, size, className, ref, ...props }: ButtonProps)
);
```

## Theme tokens

Style with the semantic theme tokens (`bg-surface`, `text-foreground-muted`, ...) instead of raw
palette classes, so surfaces follow the active light/dark theme. When migrating a hard-coded color
to a token:

- **A token swap is a visual change unless the rendered value is identical.** Check the token's
computed value in both themes against the class it replaces before claiming "light theme
unchanged" in a PR, and list any deliberate visual change in the description. A solid fill
replaced by a translucent overlay, or `neutral-100` replaced by a `stone-600/10` wash, is a
user-visible change even though the diff looks mechanical.
- **Stay in the theme's palette family.** Don't map a surface to a `gray-*`-backed token when the
surrounding theme uses `neutral`/`stone` — pick the token whose family and shade match what the
surface rendered before.
- **Keep readable text at WCAG AA (4.5:1).** Secondary text (labels, badges, nav items, hints) takes
the muted-foreground tier; the faintest tier is only for decorative or placeholder content that
may fall below AA. Demoting readable text to the faintest tier is the most-repeated review finding.
- **Fixed-scheme surfaces don't take theme tokens.** A component hardcoded to one scheme (an
always-dark code viewer) needs values readable on that surface; a token that flips with the theme
is unreadable in one mode.
- **Identical sibling controls take identical tokens**, and a token added to `theme.css` needs a
consumer in the same PR.

## Forbidden

| Don't | Do |
Expand Down
3 changes: 3 additions & 0 deletions dev/guidelines/git-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ Git workflow and commit conventions for the project.
- **Verify the base before cutting:** check that the code the ticket references actually exists on
the chosen base (`git ls-tree <base> -- <path>`); follow-up tickets often reference modules that
are only on `develop`
- **Lint/tooling changes follow the same split:** enabling a lint rule that rewrites runtime call
sites is development work — target `develop`; a tooling change that touches only config or docs
may target `stable`
- **Branch naming:** `<initials>-<short-description>` (e.g., `jd-add-breadcrumbs`)

## Versioning
Expand Down
1 change: 1 addition & 0 deletions dev/guidelines/markdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ from infrahub_sdk import InfrahubClient
- Use relative paths for internal documentation links
- All documentation URLs should be relative (not absolute)
- When referencing Infrahub source files (models, sample scripts), link the file on GitHub (`https://github.com/opsmill/infrahub/blob/stable/<path>`); never cite a bare repo path — docs readers have no checkout
- Never route a relative link through a repo symlink (the root `specs` is a symlink to `dev/specs`) — GitHub's renderer does not follow symlinks, so the link 404s on the web UI even though it resolves in a checkout; link the real path

```markdown
<!-- ✅ Good -->
Expand Down
3 changes: 3 additions & 0 deletions dev/knowledge/backend/database-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ Implementation: `Branch.get_query_filter_path()` in `backend/infrahub/core/branc

Outbound on `n1`, inbound on `n2`.

A node is never its own relationship peer: instance-level self-loops (`n1` = `n2`) are unsupported.
Same-kind relationships between two distinct nodes are the supported case (the unidirectional form).

### Node Existence

```cypher
Expand Down
2 changes: 1 addition & 1 deletion dev/knowledge/backend/schema-definitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ core_standard_webhook = NodeSchema(
| `on_delete` | `RelationshipDeleteBehavior \| None` | `None` | `None` (no-action) or `cascade` |
| `allow_override` | `AllowOverrideType` | `ANY` | Whether inheriting nodes can override this relationship |
| `read_only` | `bool` | `False` | Prevents user modification |
| `deprecation` | `str \| None` | `None` | Deprecation message shown to users |
| `deprecation` | `str \| None` | `None` | Deprecation message shown to users; name the version after which the field is removed (applies to GraphQL `deprecation_reason` too) |
| `common_parent` | `str \| None` | `None` | Constrains peer's parent to match this object's parent |
| `common_relatives` | `list[str] \| None` | `None` | Peer relationships that must share the same set of peers |

Expand Down
10 changes: 5 additions & 5 deletions dev/knowledge/frontend/design-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ Most components wrap `react-aria-components` primitives with Tailwind styling. C

| Component family | Purpose |
|---|---|
| `Button` / `LinkButton` | Any clickable styled button (+ `buttonVariants`). Migrated in #9065. |
| `Card` (`CardHeader`, `CardContent`) | Bordered + rounded + shadowed content surface. Migrated in #9048. |
| `Modal` (`ModalOverlay`) | Dialog/overlay with focus trap and escape handling. Migrated in #9088. |
| `Button` / `LinkButton` | Any clickable styled button (+ `buttonVariants`). |
| `Card` (`CardHeader`, `CardContent`) | Bordered + rounded + shadowed content surface. |
| `Modal` (`ModalOverlay`) | Dialog/overlay with focus trap and escape handling. |
| `Sheet` | Side-panel overlay; integrates the dismiss guard (see hooks below). |
| `Popover` (`PopoverDialog`, `PopoverTrigger`) | React-aria popover. See the app-popover duality note below. |
| `Tooltip` | Hover/focus tooltip with arrow; supports non-interactive triggers. |
Expand All @@ -29,8 +29,8 @@ Most components wrap `react-aria-components` primitives with Tailwind styling. C
| `Tree` (`TreeItem`, `TreeItemContent`, `TreeItemLoader`) | Expandable tree with lazy loading. |
| `SortableList` / `SortableItem` | Drag-and-drop reorderable list (react-aria `useDragAndDrop`). |
| `ResizablePanelGroup` / `ResizablePanel` / `ResizableHandle` | Split panes built on `react-resizable-panels`. |
| `ScrollArea` | Styled scroll container. Migrated in #9101. |
| `Meter` | Progress/utilization bar. Migrated in #9100. |
| `ScrollArea` | Styled scroll container. |
| `Meter` | Progress/utilization bar. |
| `Spinner` | Loading indicator. |
| `DismissGuardContext` / `useDismissGuard` | Hook + context to block overlay dismissal (used by `Sheet`; consumers such as dirty forms mark themselves undismissable). |

Expand Down
4 changes: 3 additions & 1 deletion docs/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ Capitalize these Infrahub-specific terms when referring to the feature:

**Never use "transform" or "transforms" as a noun.** Always use "Transformation" or "Transformations".

**Call a populated instance an "object", not a "node"**, in user-facing text (docs, error messages, UI copy). "Node" stays where it names a schema kind — the counterpart of "Generic" — which is the term the schema docs and the UI already use.

## Documentation Workflow

1. **Choose documentation type** using the table above (if not specified)
Expand Down Expand Up @@ -121,7 +123,7 @@ The `migrate-feature-page` skill documents the full workflow.
- Include language tags on code blocks
- Choose the appropriate documentation type (guide vs. topic)
- Define technical terms on first use
- Verify factual claims (attribute kinds, GraphQL fields, defaults) against the code on the branch the PR targets — docs PRs frequently target a release branch whose features differ from the development branch; this applies doubly before acting on a bot review claim that something "does not exist"
- Verify factual claims (attribute kinds, GraphQL fields, defaults) against the code on the branch the PR targets — docs PRs frequently target a release branch whose features differ from the development branch; this applies doubly before acting on a bot review claim that something "does not exist". For `infrahubctl`/SDK features, the reference is the commit the `python_sdk` submodule pins (`git -C python_sdk show $(git rev-parse HEAD:python_sdk):<path>`), not an SDK branch tip — and never bump the pin just to make docs resolve
- When documenting marketplace items, verify each item actually resolves in the live catalog at <https://marketplace.infrahub.app>; if an item is planned but unpublished, get an explicit decision on release timing before referencing it
- Prefer plain Markdown/MDX over custom React components in doc pages; before adding anything to `docs/src/components/`, check the existing components for reuse, and give a genuinely new component typed props (the docs package typechecks with `tsc`)

Expand Down
Loading