aegis-stack
Copilot instructions144 starsChanged 15 months agoMITView on GitHub
Purpose: Guide Copilot to produce code aligned with Aegis Stack architecture and conventions.
We split this copilot-instructions.md into the rules it gives an agent
24 rules. About 2 are common, 19 are distinctive, and 3 are very specific to this project.
≈2
Common · estimate
Many files like this have a rule of this kind.
≈19
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 9
Do NOT call components “services.” Never generate names like scheduler_service.
- Distinctive: line 14
Prefer small, focused, testable functions.
- Very specific: line 19
Place in app/services/<domain>_service.py.
- Very specific: line 27
Add FastAPI routes under app/components/backend/api/.
- Very specific: line 30
Place session/page logic in app/components/frontend/.
- Distinctive: line 32
Add jobs in scheduler component factory (create_scheduler()) using scheduler.add_job().
- Distinctive: line 33
Do not put APScheduler setup in services/.
- Distinctive: line 38
Use max_instances=1 for idempotent recurring jobs unless concurrency required.
- Distinctive: line 39
Use coalesce=True for periodic tasks where catching up is safe.
- Distinctive: line 42
Use structlog logger from app.core.log (logger).
- Distinctive: line 43
Prefer structured context (logger.info("msg", key=value)) if existing pattern allows.
- Distinctive: line 46
Import from app.core.config import settings.
- Distinctive: line 47
Do NOT re-instantiate Settings.
- Common: line 51
Before generating code that repeats logic (file paths, error handling, settings access, logging setup), search for existing utilities in:
- Common: line 57
Avoid swallowing exceptions silently.
- Distinctive: line 62
Prefer Pydantic models for structured payloads crossing component boundaries.
- Distinctive: line 65
Place tests in tests/ mirroring module structure.
- Distinctive: line 71
When adding a new capability:
- Distinctive: line 80
Avoid suffix “util” unless generic.
- Distinctive: line 91
When extending code, think:
- Distinctive: line 143
After code generation or edits: run make check (ruff + mypy + pytest).
- Distinctive: line 147
Keep changes atomic: one capability or refactor per commit.
- Distinctive: line 148
Update docs if a new capability is introduced.
- Distinctive: line 153
Avoid generating large monolithic modules.
≈ “Common” is an estimate: at least 1 in 5 of the 3,669 Copilot instructions 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
GitHub Copilot Instructions for Aegis Stack
Purpose: Guide Copilot to produce code aligned with Aegis Stack architecture and conventions.
Core Architectural Truths
- Components (app/components/*) define capability + orchestration (backend, frontend, scheduler, etc.).
- Services (app/services/*) contain pure business logic. No routes, jobs, hooks, or infra config.
- Components call services. Services never import components.
- Do NOT call components “services.” Never generate names like scheduler_service. Use scheduler component.
- Async-first: prefer async functions where I/O occurs (FastAPI endpoints, scheduler jobs, integrations).
- Explicit > magic: always import what you use; no hidden auto-discovery except documented backend hook folders.
When Generating Code
Prefer small, focused, testable functions. Keep side effects in components; keep computation in services.
Services Pattern
- Pure logic, stateless except via parameters.
- Return data structures (dict / pydantic model), not framework responses.
- Place in app/services/
<domain>_service.py. - Example function signature pattern:
async def generate_report(user_id: str) -> ReportResult: ...Component Additions
Backend:
- Add FastAPI routes under app/components/backend/api/.
- Register routers in routing.py (do not instantiate new FastAPI app). Frontend:
- Place session/page logic in app/components/frontend/. Scheduler:
- Add jobs in scheduler component factory (create_scheduler()) using scheduler.add_job().
- Do not put APScheduler setup in services/.
Scheduler Jobs
- Define business logic in services.
- In component: import service function, schedule with clear id, name, and reasonable trigger.
- Use max_instances=1 for idempotent recurring jobs unless concurrency required.
- Use coalesce=True for periodic tasks where catching up is safe.
Logging
- Use structlog logger from app.core.log (logger).
- Prefer structured context (logger.info("msg", key=value)) if existing pattern allows; otherwise concise message strings.
Configuration
- Import from app.core.config import settings.
- Do NOT re-instantiate Settings.
- Feature flags / tunables exposed as settings attributes.
DRY Enforcement
Before generating code that repeats logic (file paths, error handling, settings access, logging setup), search for existing utilities in:
- app/core/
- existing services modules.
Error Handling
- Raise domain-specific exceptions (create them in a local exceptions module) rather than broad Exception.
- Avoid swallowing exceptions silently; log and re-raise or convert to meaningful error.
Type Safety
- Include type hints everywhere.
- For async functions returning nothing: -> None.
- Prefer Pydantic models for structured payloads crossing component boundaries.
Testing Guidance
- Place tests in tests/ mirroring module structure.
- Async tests: use pytest.mark.asyncio.
- For services: isolate by mocking external integrations (not yet defined? leave TODO).
- For scheduler jobs: test underlying service function, not the scheduling loop.
Documentation Prompts
When adding a new capability:
- What capability (not just implementation)?
- Why this implementation vs alternatives?
- Integration points (hooks, entrypoints, jobs).
- Swapping guidance (what would change).
Naming Conventions
- snake_case for modules/functions.
<domain>_service.py for service modules.- Avoid suffix “util” unless generic; prefer descriptive noun/verb.
- Jobs: id and name human-readable (e.g., "system_status_check", "System Health Check").
Anti-Patterns (Reject / Refactor)
- Putting job definitions inside services.
- Creating new FastAPI app instances inside routes.
- Direct environment variable reads outside config module.
- Copy-pasted logging or setup code.
- Calling components “microservices” or “services.”
Prompts to Bias Copilot
When extending code, think:
- Can this logic live in a service function?
- Does a component already handle orchestration?
- Is there existing shared utility?
- Are type hints and error paths complete?
Example: Adding a New Scheduled Job
Service (business logic):
# app/services/cleanup_service.py
from datetime import datetime
async def purge_expired_sessions(now: datetime) -> int:
"""
Remove expired sessions. Return count removed.
Pure logic; no scheduler or logging side effects besides minimal info if needed.
"""
# ...implementation...
return removedScheduler component modification:
# app/components/scheduler/main.py (inside create_scheduler)
from app.services.cleanup_service import purge_expired_sessions
scheduler.add_job(
purge_expired_sessions,
trigger="cron",
minute="*/30",
id="purge_expired_sessions",
name="Purge Expired Sessions",
max_instances=1,
coalesce=True,
)Example: Adding Backend Route
# app/components/backend/api/routes/session.py
from fastapi import APIRouter
from app.services.cleanup_service import purge_expired_sessions
from datetime import datetime
router = APIRouter(prefix="/sessions", tags=["sessions"])
@router.post("/purge")
async def purge():
removed = await purge_expired_sessions(datetime.utcnow())
return {"removed": removed}Register router in routing.py (do not create new FastAPI app).
Make & Tooling
- After code generation or edits: run make check (ruff + mypy + pytest).
- Maintain zero warnings baseline.
Commit Discipline
- Keep changes atomic: one capability or refactor per commit.
- Update docs if a new capability is introduced.
Output Expectations
Copilot should:
- Suggest focused, typed, async-aware functions.
- Avoid generating large monolithic modules.
- Preserve architectural boundaries (components vs services).
- Include minimal but clear docstrings (one-line summary + detail if complex).
Copilot should NOT:
- Introduce new external dependencies without explicit directive.
- Autogenerate environment variable parsing outside config.
- Rename established modules or break template structure.
Quick Reference Paths
- CLI entry: aegis/main.py
- Template root: aegis/templates/copier-aegis-project/
- Generated project sample component: app/components/
- Scheduler logic: app/components/scheduler/main.py
- Logging setup: app/core/log.py
- Settings: app/core/config.py
- Integration layer: app/integrations/main.py
Style Recap
- Concise, explicit, typed, async-first, DRY, capability-focused.
- Correct terminology: COMPONENT (capability) vs SERVICE (business logic).
- Avoid “microservice” language.
End of instructions.
Where files are headingNew Copilot instructions files have more rules about branches and pull requests, and fewer about code style.
Of the Copilot instructions files we read, the 2,297 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 repository14 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- docs/CLAUDE.mdCLAUDE.md
- tests/CLAUDE.mdCLAUDE.md
- llms.txtllms.txt
- add-cli-commandSkill
- add-componentSkill
- add-serviceSkill
- create-pluginSkill
- example-skillSkill
- execute-issueSkill
- i18nSkill
- releaseSkill
- squash-branchSkill
- template-devSkill
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.

