agenticos
AGENTS.md241 starsChanged 29 days agoApache-2.0View on GitHub
The one instruction file for coding agents in this repository - Claude Code, Codex and any other. There is no CLAUDE.md; this is it. Project-wide decisions and pointers to task-specific guidance. Read relevant rules, skills and documentation as needed. Keep detailed procedures and incident history outside this file. Current user instructions and higher-priority session rules take precedence. A self-hosted, open-source, multi-tenant platform for a company's AI agents. An agent is a versioned spec. Users configure instructions, models, capabilities and budgets…
- Reads credentials
- Commits and pushes
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,700 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository22 other files it gives its agents.
- frontend/AGENTS.mdAGENTS.md
- llms.txtllms.txt
- agent-capabilitySkill
- agent-specSkill
- alembic-migrationSkill
- backend-testsSkill
- background-taskSkill
- channel-botSkill
- dev-agentSkill
- e2e-testsSkill
- frontend-featureSkill
- mcp-connectionsSkill
- permissions-rbacSkill
- pr-commentsSkill
- pr-descriptionSkill
- project-docsSkill
- rag-knowledgeSkill
- resolve-changelog-conflictSkill
- review-mapSkill
- ste-writingSkill
- vault-secretsSkill
- vstorm-code-reviewSkill
The file
Show its rules and text
We split this AGENTS.md into the rules it gives an agent
18 rules. About 0 are common, 6 are distinctive, and 12 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈6
Distinctive · estimate
This author's own choices. Worth a look.
12
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 33
Use domain exceptions with message and details.
- Very specific: line 35
Keep changes scoped. Avoid speculative abstractions, unused code and unrelated cleanup.
- Distinctive: line 38
Test new behaviour and add regression tests for bugs.
- Distinctive: line 74
Keep service and repository return types precise.
- Very specific: line 81
Use datetime.now(UTC) and secrets.compare_digest() for API key comparisons.
- Very specific: line 88
Read the relevant files under .claude/rules/.
- Distinctive: line 174
Use the repository's pgvector-enabled PostgreSQL image.
- Very specific: line 178
Check the interpreter actually used by uv run before relying on test results.
- Very specific: line 182
Read docs/testing.md, .claude/rules/testing.md and the relevant testing skill for fixtures and patterns.
- Very specific: line 188
When adding a platform module, keep [tool.coverage.run] include and the matching [[tool.ty.overrides]] include aligned, including order.
- Distinctive: line 200
Update existing documentation in the same change when described behaviour changes.
- Very specific: line 205
Read the project-docs skill for site structure, writing conventions, generated pages and build checks.
- Distinctive: line 286
Never commit on main. Use a feature or fix branch, one PR per coherent change, squashed on merge.
- Very specific: line 291
No AI attribution in commits or PR descriptions: no Co-Authored-By: Claude, Generated with Claude Code or equivalent footer.
- Very specific: line 295
Use Conventional Commits: type(scope): summary, imperative, lower case after the colon, no trailing period, at most 72 characters.
- Very specific: line 300
Add a body when the reason, verification or tradeoffs are not clear from the subject.
- Very specific: line 336
After the cut merges, publish the release and its tag in one step: gh release create vX.Y.Z --target <cut merge commit> --notes-file <its …
- Distinctive: line 345
Never propose 2.0.0 or any later major.
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md — AgenticOS
The one instruction file for coding agents in this repository - Claude Code, Codex
and any other. There is no CLAUDE.md; this is it.
Project-wide decisions and pointers to task-specific guidance. Read relevant rules, skills and documentation as needed. Keep detailed procedures and incident history outside this file. Current user instructions and higher-priority session rules take precedence.
What this is
A self-hosted, open-source, multi-tenant platform for a company's AI agents.
An agent is a versioned spec. Users configure instructions, models, capabilities and budgets in the UI, publish a version and can export it as YAML. The same agent runs through web chat, the HTTP API and channel integrations. Change an individual agent through its spec; change Python when implementing platform behaviour or capabilities. Tools reach models through the capability registry.
Stack: FastAPI, Pydantic v2, Pydantic AI, PostgreSQL with pgvector, Redis,
Next.js, React, bun, next-intl and MkDocs Material. Use versions from the
repository manifests and lockfiles; Python is pinned in backend/.python-version.
The repository originated from the Full-Stack AI Agent Template. Platform and template-inherited subsystems have different coverage gates, described below.
Quality and scope
- Type owned boundaries and nontrivial helpers. Do not use
Anyor suppressions to hide errors. Necessary suppressions need a specific explanation; route return annotations below are an explicit project convention. - Use domain exceptions with
messageanddetails. Do not swallow exceptions or mask bugs with fallbacks. - Keep changes scoped. Avoid speculative abstractions, unused code and unrelated
cleanup. Comments explain non-obvious constraints; API contracts belong in
docstrings. See
.claude/rules/code-style.md. - Test new behaviour and add regression tests for bugs. Documentation-only changes need documentation checks, not artificial application tests.
- Integrate new user-facing features with the existing product: onboarding for new
pages and creation flows, and dashboard widgets for activity or state that belongs
at a glance. Follow
.claude/rules/frontend.mdfor registries, permissions, translations and anchors.
Hard boundaries
- Routes call services; services coordinate repositories. Routes must not import or call repositories directly.
- Repositories use
db.flush()anddb.refresh(), neverdb.commit(). UseDBSession: itsscope="function"commits after the route returns and before the response is written. A bareDepends(get_db_session)has different timing. The agent run paths inAgentRunnerService._runandChatAgentRunner.runexplicitly commit before the model call and in terminal cleanup;app.services.telephony.runtimecommits telephone admission, submission, transfer, hang-up and single-use media claims before external effects; unknown acceptance is retained for signed callbacks and cleanup, never automatic redial.VoiceCallStarter.startcommits a call's row and its run before the call connects andVoiceCallSessioncommits again in its teardown (per-turn messages, heartbeats and approval writes use their ownget_db_context()sessions);SessionService.detect_refresh_reusecommits the security response its caller is about to raise past; andWorkflowExposureService._answercommits a webhook's admission before waiting for its Respond to webhook step. Seedocs/architecture.md#the-requests-transaction. - Queue background work that must happen as a job with
app.services.background_jobs.enqueue, in the request's own transaction, so it commits with the rows it reads. Best-effort work that may be lost goes tospawn_after_commit. Seedocs/architecture.md#dispatching-background-work-from-a-requestand thebackground-taskskill. - Collection routes use
require(...)gates. Per-resource routes for agents, skills and collections delegate to a service usingresolve_access; a role gate must not reject access allowed by a resource grant. Followpermissions-rbac. - Route handlers return
-> Anyand declareresponse_modelfor serialization. Keep service and repository return types precise. - Store credentials through
app/core/vault.py. Connector sources reference vault secret IDs; do not put credentials in a connector'sCONFIG_MODELor introduce deployment-wide Fernet keys,CHANNEL_ENCRYPTION_KEYorapp/core/crypto.py. - Organization authority comes from membership and the permission catalog. Do not
restore
UserRole,User.has_role(),RoleChecker,CurrentAdmin,CurrentSuperuseror the oldusers.rolecolumn. - Use
datetime.now(UTC)andsecrets.compare_digest()for API key comparisons. - Migration numbering restarted after a baseline squash. Verify references against
backend/alembic/versions/and cite full filenames; use git history for removed revisions rather than assuming an old number still identifies the same migration.
Read the matching rule before writing code
Read the relevant files under .claude/rules/; their frontmatter defines the file
scope. Load only the rules that apply to the change.
| Editing | Read |
Any backend/app/** Python | architecture.md — Routes → Services → Repositories, DI, thin vs. thick domains |
schemas/, db/models/ | schemas-models.md — *Create/*Update/*Read/*List, SQLAlchemy |
api/ | api-conventions.md — REST structure, status codes, pagination, auth aliases |
core/, services/ | exceptions-security.md — domain exceptions, JWT, the permission model |
| Any Python | code-style.md — formatting, naming, imports, type hints |
tests/ | testing.md — the layers, anyio, fixtures, the 100% gate |
frontend/ | frontend.md — App Router, data layer, stores, i18n, permissions |
Read the matching skill before starting a task
Skills live in .claude/skills/<name>/SKILL.md. Read the skills matching the task;
.claude/README.md explains the layout.
| Doing | Skill |
| Giving an agent a new tool, or a capability | agent-capability |
Changing AgentSpec, SPEC_VERSION or publish validation | agent-spec |
| Anything authorization | permissions-rbac |
| Anything with a credential at rest | vault-secrets |
| MCP servers, or an integration with a SaaS product | mcp-connections |
| Ingestion, retrieval, connectors, parsers | rag-knowledge |
| Telegram / Slack / Mattermost | channel-bot |
| Background jobs, schedules, or work that outlives a request | background-task |
| A schema change or a backfill | alembic-migration |
| Backend tests, or a failing coverage gate | backend-tests |
| A Playwright spec | e2e-tests |
| A page, store, hook or permission-gated control | frontend-feature |
| The docs site | project-docs |
Commands
make dev # postgres, redis, api, worker, frontend
make platform-bootstrap BOOTSTRAP_API_KEY=sk-... # an org, an owner, a model, an agent
make check # every CI job but e2e - CI runs it, not your laptopmake help lists the rest. Day to day:
make lint / make format | ruff + ty + vulture + deptry + eslint + prettier + tsc + the guard scripts + codespell |
make lint-backend / make lint-frontend | one half of it — CI runs them in two jobs |
make dead-code | vulture + knip, unused functions — a report to read, not a gate |
make test-fast | no coverage — the write-run-write loop |
make test | backend + the 100% gate on the platform layer |
make test-integration | only the tests needing a real database |
make test-frontend / make test-frontend-cov | vitest / vitest with the gate CI applies |
make test-e2e | Playwright — needs a backend and its seed |
make test-migrations | the whole chain forwards and back |
make db-check | alembic check — a model change with no migration fails here (in make check) |
make db-migrate / make db-upgrade | autogenerate / apply |
make docs / make docs-build | serve on :8001 (DOCS_PORT= to move it) / --strict |
uv run agenticos cmd doctor | can this deployment actually run an agent? |
uv run agenticos cmd --help | every custom command, including all rag-* |
Verification
Do not run the full suites on a laptop; CI runs them. make test,
make test-frontend-cov, make check, make test-e2e and a whole-directory pytest
or vitest take tens of minutes and load the machine somebody is working on. Locally,
run small batches: the test files covering what you changed, make lint or the half
of it for the side you touched, and make db-check after a model change. Run
frontend commands from frontend/, backend commands from backend/ and make
targets from the root.
cd backend && uv run pytest tests/test_attachments.py tests/test_transcript.py -q
cd frontend && bunx vitest run src/components/chat/chat-container.integration.test.tsxThe coverage gates, integration tests, e2e and the rest of make check are what
GitHub Actions runs on every push. Push, then read the run for that commit's SHA:
gh run list --branch <branch>, then gh run view <id> --log-failed for a red job.
A later push can cancel an earlier run, and path-filtered jobs may be skipped, so a
green run belongs to the SHA it ran on. Report failures with the job and the error,
and say when a gate has not run yet. See docs/branching.md and the workflow files
for CI behaviour, and .claude/rules/testing.md for scoped commands.
Environment
- Use the repository's pgvector-enabled PostgreSQL image; stock PostgreSQL lacks the vector extension required by RAG. Check the image if ingestion fails in a fresh environment.
- Match
backend/.python-versionwhen creating or syncing the backend environment. Check the interpreter actually used byuv runbefore relying on test results.
Testing
Read docs/testing.md, .claude/rules/testing.md and the relevant testing skill
for fixtures and patterns.
- The platform layer has a 100% coverage gate. Exact modules are configured in
backend/pyproject.toml; template-inherited subsystems are additionally reported bymake coverage-allwithout that gate. - When adding a platform module, keep
[tool.coverage.run] includeand the matching[[tool.ty.overrides]] includealigned, including order.backend/tests/test_coverage_gate.pychecks this contract. - Async tests use anyio:
pytestmark = pytest.mark.anyio. - Cover refusal and failure paths: tenant isolation, scopes and grants, budgets checked before model calls and recorded on failure, invalid specs rejected at publish, and secrets excluded from responses, logs and audit entries. Also cover channel sender identity, parser/routing compatibility and existing stored JSONB when tightening validation. The testing skills contain worked examples.
Documentation
Update existing documentation in the same change when described behaviour changes. Refactors with unchanged behaviour and test-only changes do not require unrelated prose edits. Update rules and skills when referenced paths or contracts change. API reference changes belong in the generating docstrings.
Read the project-docs skill for site structure, writing conventions, generated
pages and build checks. Add new pages to mkdocs.yml, relevant cross-links and
the topic map below. scripts/docs_drift.py contains the code-to-page trigger map;
its Stop hook is a reminder, not a completeness check or a gate.
The site publishes in four languages, so a published page owes a .pl.md, a
.de.md and an .es.md beside it, and editing an English page makes all three
stale. The same is true of README.md, CONTRIBUTING.md, SECURITY.md and
CODE_OF_CONDUCT.md, which GitHub renders rather than MkDocs: those record the
fingerprint in an HTML comment, cannot pin an anchor, rewrite their own in-page
links per language, and point every other link at the reader's own language.
scripts/check_docs_i18n.py gates make lint on all of it and names what is
missing; docs/howto/translate.md is the workflow. Record a retranslated page
with --update <page>.<locale>.md — it takes paths, because stamping one nobody
retranslated is how a stale translation stops being visible.
| Topic | Page |
| Spec, version, exposure, run | docs/concepts.md |
| The three permission layers, scopes, grants | docs/permissions.md |
| Groups, directory group mappings, LDAP and Kerberos sign-in | docs/directory.md |
| Departments: groups as audiences, the group page, where an agent's knowledge comes from | docs/departments.md |
| Budgets, approvals, alerts, audit | docs/governance.md |
| What ships as a capability, its tools and config | docs/reference/capabilities.md |
| The agent spec, field by field | docs/reference/spec.md |
| Every workflow node: config, ports, errors, retries | docs/reference/workflow-nodes.md |
| What the console calls each thing, and its name in the API and spec | docs/reference/glossary.md |
| MCP connections, the server catalog, OAuth | docs/mcp.md |
| Providers, model profiles, fallbacks, cost | docs/models.md |
| Which model to pick, open weights vs closed | docs/choosing-models.md |
| Adoption, roles, cost, the security review | docs/rollout.md |
| The vault, secret kinds, what never leaks | docs/secrets.md |
| Where personal data lives, what leaves, deletion, the controls and the open gaps | docs/data-protection.md |
| Third-party licences, the notices, the review and its open findings | docs/licenses.md |
| Every component a deployment is made of, and the release SBOM | docs/reference/components.md |
| Threat model, data flow, at-rest, the controls matrix | docs/security.md |
| Skills — format, library, skills vs knowledge | docs/skills.md |
| Context files — standing knowledge bound to agents | docs/context.md |
Virtual Tables — typed records, schema versions, revisions, idempotent writes, the /tables API | docs/virtual-tables.md |
| Agent and team tasks: research and proposal only | docs/design/agent-tasks.md (repo only) |
| Workflows — the visual editor: canvas, palette, bindings, autosave, publish, versions | docs/workflows.md |
| Projects: shared files, instructions and chats | docs/projects.md |
| Named environments, promotion, per-environment tracing | docs/environments.md |
| Surfaces: widget, WebSocket, Slack, Telegram | docs/channels.md |
| Voice conversations: calls, realtime models, limits, hang-up | docs/voice.md |
| Published pages: artifacts, versions, public links, isolation | docs/artifacts.md |
| The desktop app: the console, blobby, quick ask, local work and the screen | docs/desktop.md |
| macOS Gatekeeper warnings, install verification and release signing | docs/howto/macos-warning.md |
| The phone app: live activities, widgets, push, offline | docs/mobile.md |
| Upload, parsing, ingestion | docs/file-processing.md |
| The console: dashboard widgets, chat, slash commands, the map | docs/console.md |
| Every module, screenshotted in both themes | docs/screens.md |
| The sandbox: sessions, runtimes, isolation, lifetimes | docs/sandbox.md |
| Routes → services → repositories | docs/architecture.md |
| The Next.js console, for a contributor | docs/frontend.md |
| Authenticating and calling the HTTP API | docs/api.md |
| The ML services called without an agent, and what each one is | docs/ml-services.md |
| Adding a feature end to end | docs/adding_features.md |
| Test layers and what belongs in each | docs/testing.md |
| The load suite: the workload, the thresholds, the measured runs | docs/load-testing.md |
| Why the job queue is Postgres: ten engines, the OOM test, the limits | docs/task-queue-benchmark.md |
| The automated pull request reviewer | docs/code-review.md |
Branches, rulesets and what protects main | docs/branching.md |
| Recurring patterns | docs/patterns.md |
| Translating a page, and the terminology that has to be exact | docs/howto/translate.md |
| Getting it onto a host: sizing, TLS, the approved deploy | docs/deploy.md |
| Past one host: an external Postgres, connection counts, more API hosts and workers, several deployments | docs/scaling.md |
| The deployment's identity, sign-up policy, notices | docs/deployment.md |
| Settings and the production checklist | docs/configuration.md |
| What the platform does, on one page | docs/features.md |
| Choosing a first task, and the 30 use-case tutorials it indexes | docs/use-cases.md (tutorials live in docs/howto/) |
| The Learn track's own landing | docs/learn/index.md |
| Help, contributing, extending the platform | docs/resources/index.md |
| Why it exists, and what it is not | docs/about/index.md |
| How it compares with other products, and its own gaps | docs/about/comparison.md |
| The six decisions that shape the codebase | docs/about/design.md (repo only) |
| Delivery state and what is left | docs/ROADMAP.md (repo only) |
| Every notable change | docs/release-notes.md (reads CHANGELOG.md) |
Git
- Never commit on
main. Use a feature or fix branch, one PR per coherent change, squashed on merge. - On a branch, commit and push each finished, verified piece without being asked. This is the project's exception to the global commit-on-request preference; explicit session instructions still take precedence.
- No AI attribution in commits or PR descriptions: no
Co-Authored-By: Claude,Generated with Claude Codeor equivalent footer. - Stage only intended changes and review the staged diff. Exclude secrets, unrelated work and tool caches.
- Use Conventional Commits:
type(scope): summary, imperative, lower case after the colon, no trailing period, at most 72 characters. Types:feat,fix,refactor,perf,test,docs,ci,build,chore. Scope names the subsystem; omit it for repository-wide changes. Use!and aBREAKING CHANGE:footer for breaking changes. - Add a body when the reason, verification or tradeoffs are not clear from the
subject; wrap it at 72 characters. Put issue references in footers (
Closes,Refs,Part-of); useClosesonly when the issue is fully resolved. - PR descriptions explain the problem, resulting behaviour, verification and
material limitations. Review the diff and surrounding code before declaring work
finished.
.claude/commands/review.mddefines the local review standard.docs/code-review.mdand.github/workflows/ai-review.ymldescribe automated review. A failed reviewer is not a clean review; assess findings against the code and explain rejected ones. - Fix confirmed in-scope defects; record out-of-scope defects without expanding the
change. Before filing or triaging issues, read
.claude/references/issue-triage.mdfor the repository's board conventions.
Releases
Versions follow Semantic Versioning from 1.0.0 onwards, except
that the major stays 1 (below); every release before 1.0.0 was 0.0.N. CHANGELOG.md
and docs/release-notes.md state that exception to operators. A release is numbered by the largest change it ships,
judged by someone running a deployment, not by the size of the diff:
| Bump | When the release contains |
| MAJOR | Not used: AgenticOS stays on major version 1. A change an existing deployment has to act on - a removed or renamed API route, field or setting, a spec that no longer loads or must be republished, a migration that drops data, a changed default that alters stored behaviour - ships as the next MINOR. Its commit still carries ! and a BREAKING CHANGE: footer, and its changelog entry says what to do |
| MINOR | Something new a member or operator can do: a feature, a capability or tool, an endpoint, a setting, a new screen. Backwards compatible |
| PATCH | Fixes, documentation, dependency updates and refactors with no new behaviour |
- Cut after the merge, never beside it. Once a PR lands on
main, achore: cut X.Y.ZPR renames the[Unreleased]block inCHANGELOG.mdto## [X.Y.Z] - YYYY-MM-DDunder a new empty[Unreleased], and bumpsbackend/pyproject.toml,backend/uv.lockandfrontend/package.json. Feature PRs write their changelog entries under[Unreleased]; the cut does not add new ones. - Prepare a release train with
make release-cut BUMP=patch(orminor); addCREATE_PR=1to create the cut PR from freshorigin/main. The default only prints a plan. CI and CodeQL may reuse successful full runs for a proven version-only cut; missing evidence runs full checks. Seedocs/branching.md. - After the cut merges, publish the release and its tag in one step:
gh release create vX.Y.Z --target <cut merge commit> --notes-file <its changelog section>. Never push the tag first: it startsimages.ymlat once, and that attaches the release SBOMs only to a release that already exists. Production deploys wait for approval (deploy.yml). - One release per merged change, or one for a train merged together, numbered by the largest change in it. Stacked PRs are released in merge order, each with its own number.
- An agent asked to release may pick a PATCH or MINOR number by the table above. Never propose 2.0.0 or any later major; a number the maintainer has named is the maintainer's decision.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

