This file contains global rules for the repository root.
When starting non-trivial work (multi-step, behavior change, or anything cross-package), check these docs first:
- Documentation index:
docs/README.md - Core flow:
docs/00-context.md→docs/01-overview.md→docs/02-significance.md→docs/03-plan.md - Standards:
docs/standards/coding.md,docs/standards/commits.md,docs/standards/quality-gates.md - Architecture/ops:
docs/architecture/*,docs/ops/*,docs/adr/* - Vault rules (knowledge model):
docs/standards/vault/README.md
Use this to “fully utilize” docs without loading unrelated context:
- First contact / unclear scope →
docs/README.md, thendocs/00-context.md→docs/03-plan.md - CLI behavior/flags/indexer usage →
docs/01-overview.md,docs/ops/local-dev.md - Codex CLI sandbox/MCP startup/permissions →
docs/ops/codex-cli.md,docs/adr/0006-codex-cli-sandbox-vault-permissions.md - DB schema/index/search semantics →
docs/architecture/data-db.md,docs/adr/0005-db-migrations-and-embedding-dimensions.md - Package boundaries/entrypoints/deps →
docs/architecture/packages.md,docs/adr/0001-monorepo-packages.md - Obsidian plugin process model →
docs/adr/0003-obsidian-plugin-spawns-processes.md - Vault schema/rules (frontmatter/typed links) →
docs/standards/vault/README.md
- Node.js
>=20(package.json#engines) - pnpm
pnpm@10.20.0(package.json#packageManager) - pnpm workspace:
packages/*(pnpm-workspace.yaml) - Use pnpm only — do not commit npm/yarn lockfiles (e.g.
package-lock.json,yarn.lock)
- Native module
better-sqlite3may require a build. - In sandbox/CI environments, default cache paths may be blocked, so pin caches inside the workspace.
- Reference:
docs/ops/local-dev.md - Recommendation: keep caches inside the repo workspace (see the doc for the exact commands/flags).
- Reference:
- TypeScript + ESM (
"type": "module") - Base tsconfig is
tsconfig.base.json, and strict mode must remain enabled - Package build output defaults to
dist/
@ailss/corecontains shared logic only (must not depend on other packages)apps/apiis the active local runtime owner for indexing, MCP, retrieval, agent flow, and eval
.envis local-dev only; do not commit (.gitignore)- Centralize Python runtime env loading via
apps/api/src/ailss_api/config.py - MCP server provides read-only behavior by default:
- Write tools require
AILSS_VAULT_PATH - Write tools default to
apply=false(dry-run) and only write whenapply=true
- Write tools require
- Vault path comes from external config; guard against path traversal
- Only allow build scripts for dependencies listed in
pnpm-workspace.yaml#onlyBuiltDependencies - If adding a new native/build-script dependency, update
onlyBuiltDependencies
This repo enforces Conventional Commits (commitlint + Lefthook).
- Format:
<type>(<scope>): <subject> - Details:
docs/standards/commits.md - Agent rule (must follow): before drafting a commit message, check
commitlint.config.cjs(source of truth) and use only allowed scopes.- Allowed scopes:
monorepo,core,indexer,mcp,plugin,api,docs,ops - Example mapping: changes under
packages/obsidian-plugin/*→ scopeplugin(notobsidian-plugin) - Example mapping: changes under
apps/api/*→ scopeapi - If a change spans multiple areas, default to splitting into multiple commits with the tightest valid scope per commit; use
monorepoonly for inherently cross-cutting changes (or when the user explicitly wants a single commit)
- Allowed scopes:
- Title format:
<type>: <title>- Allowed
type:feat,fix,docs,refactor,test,chore,build,ci,perf,revert <title>must start with a lowercase letter (e.g.feat: add ..., notfeat: Add ...)- Do not use Conventional Commit scopes in PR titles (no
type(scope): ...) — scopes are for commit messages only.
- Allowed
- Body:
- Default: use the existing template at
.github/pull_request_template.mdand replace all[REPLACE ME]placeholders. - Exception (version bump only): use this exact minimal format:
Version bump only (service + plugin).- Before merge: add label release-on-merge so v<version> is auto-tagged on merge to main.
- Labels (version bump only):
- Add
ignore-for-releaseso the bump PR is excluded from auto-generated release notes. - Add
release-on-mergebefore merging tomainto trigger auto-tagging.
- Add
- Default: use the existing template at
- Language: PR title and body must be written in English.
- Sections (template-based PRs only): for each template section (
## What,## Why,## How), write content as bullet points only (no prose paragraphs). - Scope: the PR description must reflect all changes in the branch (code + docs + tests).
- Testing:
- Default: include the exact validation commands you ran (or explicitly state
Not runand why). - Exception (version bump only): omit (body is fixed); rely on CI + pre-push checks.
- Default: include the exact validation commands you ran (or explicitly state
- Issues: include
Fixes #...when applicable; omit the line otherwise.
When filing an issue, optimize for fast, high-confidence triage.
- Title: concise, specific, and action-oriented (avoid vague titles like “It doesn’t work”).
- Prefer using the Issue templates under
.github/ISSUE_TEMPLATE/(they standardize title prefixes and required fields). - Template mapping (recommended):
feature-requesttemplate →feat: ...title +enhancementlabelbug-reporttemplate →bug: ...title +buglabeldocstemplate →docs: ...title +docslabelquestiontemplate →question: ...title +questionlabelrefactortemplate →refactor: ...title +refactorlabel (do not combine withenhancement)testtemplate →test: ...title +testlabel
- Avoid encoding component or scope in the title (no
type(scope): ...and nocomponent: ...prefixes); use labels (and template fields when present) instead. - Problem statement: what you were trying to do and why.
- Reproduction: numbered steps starting from a clean state; include minimal config/snippets when possible.
- Expected vs actual: explicit “Expected:” and “Actual:” sections.
- Evidence: exact error messages/stack traces; screenshots only when text is insufficient.
- Environment (redact secrets):
- OS + version
- Node + pnpm versions
- Obsidian version (if plugin-related)
- AILSS package versions (plugin/mcp/indexer/core) and how installed (release vs local build)
- Relevant env vars (names + non-secret values), especially
AILSS_*(never include tokens/keys)
- Component tagging: clearly state which component(s) are involved (
indexer,mcp,plugin,api,core,docs). - MCP HTTP issues: include HTTP status, endpoint/path, whether
Mcp-Session-Idwas present, and whichAILSS_MCP_HTTP_*settings were used (token redacted). - Proposed solution (optional): if you have a hypothesis or fix direction, add it as a separate bullet list.
- Security: if the issue involves secrets or an exploitable vulnerability, do not file a public issue; report privately.
- Area labels (
plugin,mcp,indexer,core,api,docs,ops) are auto-applied by the GitHub Actions labeler based on changed file paths.- Config:
.github/workflows/labeler.yml+.github/labeler.yml
- Config:
- Type labels are auto-applied from PR title prefixes (
feat:,fix:,docs:,refactor:,test:) via.github/workflows/pr-title-type-labeler.yml.- Mapping:
feat→enhancement,fix→bug,docs→docs,refactor→refactor,test→test - The workflow only adds a missing mapped type label and skips when a type label already exists.
- Mapping:
- Manually apply labels that are not path-derived (for example:
ignore-for-release).
- Priority: accuracy > completeness > speed
- No guessing: if uncertain, verify via files/tools; resolve impactful ambiguity with 1–3 clarifying questions
- Scope discipline: do exactly what the user asked (no extra features/styling changes)
- Root-cause fixes: prefer fixing the root cause over workarounds
- Refactoring guideline (not a hard rule):
- Treat “~300–600 lines per file” as a smell, not a limit. Refactor when cohesion drops (multiple responsibilities), cognitive load rises (hard to explain), or changes require touching many unrelated sections.
- Prefer smaller refactors that preserve behavior and are covered by tests; avoid “mega-refactors” mixed with feature work unless explicitly requested.
- Documentation is guidance, not a gate: do not get "locked" into existing docs/notes—when docs conflict with code/tests or the user’s intent, treat the implementation as source of truth and update docs to match.
- Documentation alignment (required): after completing a job, update the minimal set of docs needed to match the current implementation and avoid drift.
- If you add a new doc under
docs/, link it fromdocs/README.mdso it stays discoverable - CLI/MCP surface changes (new/removed tools, tool args, result shapes):
docs/01-overview.md, andREADME.mdif user-facing - DB/indexing/schema changes:
docs/architecture/data-db.md - Package boundaries/entrypoints/dependency direction:
docs/architecture/packages.md - Plan/status/TODO changes:
docs/03-plan.md(use this as the repo “TODO” tracker unless a dedicated TODO doc is introduced) - Scope/principles/context changes:
docs/00-context.mdand/ordocs/02-significance.md - Dev/ops changes (install/build/env/runtime) and operational runbooks/logs:
docs/ops/local-dev.md(or add a new file underdocs/ops/and link it fromdocs/README.md) - New architectural decision or tradeoff: add/update an ADR in
docs/adr/(use the template indocs/adr/README.md) - Vault rule changes: update
docs/standards/vault/README.mdand keep prompts/templates/validators aligned
- If you add a new doc under
- Commit message drafting (required): after completing a job, draft Conventional Commit message(s) that match
commitlint.config.cjs(type + allowed scope); if the change spans multiple scopes, include a suggested commit breakdown (scope → files) and one message per commit - Destructive actions (delete/reset/rollback) require prior notice
- For URL source text, prefer
fetch - Parallelize independent reads via
multi_tool_use.parallel - Prefer
apply_patchfor edits
- Default answers: 3–6 sentences or ≤5 bullets
- Complex multi-step/multi-file work:
- 1-paragraph summary (conclusion/direction)
- Then ≤5 bullets (What / Where / Risks / Next / Open questions)
- All responses must be in English
- For technical terms, include a short plain-English explanation on first use
- Refactor only when it reduces risk or duplication for the current task; avoid “cleanup” refactors that expand scope.
- Prefer small, behavior-preserving extractions (helper functions/modules) over large rewrites; keep diffs easy to review.
- Treat line count as a signal, not a rule. Refactor when a file is hard to navigate (mixed concerns, repeated setup/teardown, long helpers) even if it’s <500 lines.
- Heuristics (non-binding): consider refactoring when a file exceeds ~500 lines, when helpers exceed ~150 lines, or when the same code block appears in 3+ places.
- Verification requirement: after refactoring, run the closest tests/lint/typecheck available and ensure no public API/CLI behavior changes unless explicitly requested.