diff --git a/.agents/manifest.yaml b/.agents/manifest.yaml new file mode 100644 index 000000000..c4e282fe3 --- /dev/null +++ b/.agents/manifest.yaml @@ -0,0 +1,50 @@ +# .agents/ canonical agent configuration +# Spec: https://github.com/agentsfolder/spec +# +# Status: pre-1.0 spec adoption — schema may shift. Pin specVersion; +# track upstream for breaking changes. + +specVersion: "0.1.0" + +defaults: + mode: build + policy: default-safe + +enabled: + modes: + - ask + - build + policies: + - default-safe + - yolo + skills: [] + +resolution: + enableUserOverlay: false + denyOverridesAllow: true + onConflict: error + +project: + name: singularity-forge + description: >- + SF is a purpose-to-software compiler. Plans milestones, triages + TODO inboxes, runs autonomous build cycles. The foundational + product contract is docs/adr/0000-purpose-to-software-compiler.md. + languages: + - typescript + - javascript + frameworks: [] + +x: + centralcloud: + legacy_pointers: + - AGENTS.md + - CLAUDE.md + - .github/copilot-instructions.md + - .sf/STYLE.md + - .sf/PRINCIPLES.md + - .sf/NON-GOALS.md + note: >- + These pointer / prose files predate .agents/ adoption. They are + kept in-tree during the transition. .agents/ is the canonical + source going forward; the legacy pointers point here. diff --git a/.agents/modes/ask.md b/.agents/modes/ask.md new file mode 100644 index 000000000..70896486f --- /dev/null +++ b/.agents/modes/ask.md @@ -0,0 +1,39 @@ +--- +id: ask +title: Ask +policy: default-safe +enableSkills: [] +disableSkills: [] +includeSnippets: + - style + - principles + - non-goals +toolIntent: + allow: + - read + - search + - web_fetch + deny: + - write + - exec_command + - git_commit + - git_push +--- + +# Ask Mode + +Read-only investigation. Answer questions about the codebase, propose +plans, but **make no changes**. + +Use this mode when: + +- The user is exploring or trying to understand something. +- A plan needs review before implementation. +- The right next step is unclear and probing the code base will help. + +Switch to Build (Shift+Tab) when the user is ready for the agent to +make changes. + +This mode's policy denies writes, command execution, and git mutation. +If a task requires any of those, surface that fact rather than +attempting and failing. diff --git a/.agents/modes/build.md b/.agents/modes/build.md new file mode 100644 index 000000000..8bc1da4cc --- /dev/null +++ b/.agents/modes/build.md @@ -0,0 +1,43 @@ +--- +id: build +title: Build +policy: default-safe +enableSkills: [] +disableSkills: [] +includeSnippets: + - style + - principles + - non-goals +toolIntent: + allow: + - read + - search + - web_fetch + - write + - exec_command + - git_commit + deny: + - git_push_force + - rm_rf + - drop_table +--- + +# Build Mode + +Active development. Make changes, run tests, commit. + +Confirmations are required for destructive operations per the +default-safe policy (rm -rf, git push --force, git reset --hard, +drop_table, etc.). Toggle the YOLO flag (Ctrl+Y) to drop those +confirmations — that's a flag on Build, not a separate mode. + +In this mode the agent is expected to: + +- Run tests before committing. +- Group related changes in a single commit; don't bundle unrelated + work. +- Use Git history as the rationale store — clear commit messages, + rationale in the body, link to ADRs when relevant. +- Update tests when changing behaviour. +- Promote durable decisions to `docs/adr/` rather than burying them + in commit messages. diff --git a/.agents/policies/default-safe.yaml b/.agents/policies/default-safe.yaml new file mode 100644 index 000000000..1d2d5a5ee --- /dev/null +++ b/.agents/policies/default-safe.yaml @@ -0,0 +1,50 @@ +id: default-safe +description: >- + Conservative default. Confirmations required for destructive + filesystem and git operations; network and exec allowed but logged. + +capabilities: + filesystem: + read: allow + write: confirm + delete: confirm + exec: + enabled: confirm + network: + enabled: allow + allow_hosts: + - "*" + deny_hosts: [] + mcp: + enabled: allow + +paths: + allow: + - "**" + deny: + - "~/.ssh/**" + - "**/.env" + - "**/.env.*" + - "**/secrets/**" + - ".sf/sf.db" + - ".sf/sf.db-*" + - ".sf/backups/**" + redact: + - "**/*api_key*" + - "**/*token*" + - "**/*password*" + - "**/.env*" + +confirmations: + requiredFor: + - rm -rf + - git push --force + - git push -f + - git reset --hard + - git clean -fdx + - drop_table + - drop_database + +limits: + max_files_per_op: 100 + max_command_runtime_sec: 600 diff --git a/.agents/policies/yolo.yaml b/.agents/policies/yolo.yaml new file mode 100644 index 000000000..de42e80d6 --- /dev/null +++ b/.agents/policies/yolo.yaml @@ -0,0 +1,44 @@ +id: yolo +description: >- + Confirmation-free build mode. Use deliberately — destructive + operations execute without prompting. Still respects path denies + and redactions; only the confirmation gate is removed. + +capabilities: + filesystem: + read: allow + write: allow + delete: allow + exec: + enabled: allow + network: + enabled: allow + allow_hosts: + - "*" + deny_hosts: [] + mcp: + enabled: allow + +paths: + allow: + - "**" + deny: + - "~/.ssh/**" + - "**/.env" + - "**/.env.*" + - "**/secrets/**" + - ".sf/sf.db" + - ".sf/sf.db-*" + - ".sf/backups/**" + redact: + - "**/*api_key*" + - "**/*token*" + - "**/*password*" + - "**/.env*" + +confirmations: + requiredFor: [] + +limits: + max_files_per_op: 1000 + max_command_runtime_sec: 3600 diff --git a/.agents/profiles/.gitkeep b/.agents/profiles/.gitkeep new file mode 100644 index 000000000..759f0cd42 --- /dev/null +++ b/.agents/profiles/.gitkeep @@ -0,0 +1,3 @@ +# profiles/ is REQUIRED per .agents spec but MAY be empty. +# Profiles are named overlays (e.g., "dev", "ci") that modify +# canonical configuration. None defined yet. diff --git a/.agents/prompts/base.md b/.agents/prompts/base.md new file mode 100644 index 000000000..109f1f27b --- /dev/null +++ b/.agents/prompts/base.md @@ -0,0 +1,12 @@ +# Base Prompt + +You are an AI agent working in this repository. Before changing code: + +1. Read the file you're editing in full. +2. Read related files (callers, callees, tests). +3. Match existing patterns and style. +4. Add or update tests for behavior changes. + +Default to the smallest change that solves the problem. Prefer fixing +the root cause over patching the symptom. Surface uncertainties to the +operator rather than guessing. diff --git a/.agents/prompts/project.md b/.agents/prompts/project.md new file mode 100644 index 000000000..20d485cbc --- /dev/null +++ b/.agents/prompts/project.md @@ -0,0 +1,43 @@ +# Project Prompt — singularity-forge + +## What this is + +SF — Singularity Forge — is a **purpose-to-software compiler**. The +foundational contract is documented in +[`docs/adr/0000-purpose-to-software-compiler.md`](../../docs/adr/0000-purpose-to-software-compiler.md). +Every milestone exists to serve a stated purpose; mechanics (paths, +schemas, commit refs) are subordinate to that purpose. + +For the longer narrative form see [`AGENTS.md`](../../AGENTS.md) and +[`CLAUDE.md`](../../CLAUDE.md). For style decisions see +[`.sf/STYLE.md`](../../.sf/STYLE.md). For invariants see +[`.sf/PRINCIPLES.md`](../../.sf/PRINCIPLES.md). For things we +explicitly will not do see [`.sf/NON-GOALS.md`](../../.sf/NON-GOALS.md). + +## Non-negotiables + +- **DB-first**: all state lives in SQLite via Node's built-in + `node:sqlite` (`DatabaseSync`). Never use `better-sqlite3` or any + native SQLite addon. Never use file-based fallbacks for state that + belongs in the DB (milestone context, sessions, memories, mode + state). If a pattern uses files as a proxy for DB state, that's a + bug to fix, not a convention to follow. +- **Two work modes**: Ask and Build. Shift+Tab cycles between them. + YOLO (Ctrl+Y) is a flag on Build that drops confirmations; it is + never a third mode and is not a Shift+Tab stop. +- **Build pipeline**: source TypeScript files under + `src/resources/extensions/sf/` compile to `dist/resources/...` via + `npm run copy-resources`. Files installed at + `~/.sf/agent/extensions/sf/` are not auto-redirected to TS source — + edits to `.ts` only take effect after `copy-resources`. +- **Tests**: vitest, no pre-compile. + +## Workflow + +- `/todo triage` empties `TODO.md` and routes items into structured + plan artifacts (`docs/plans/`), backlog rows, and BUILD_PLAN tier + lists. Run before starting work if the inbox has content. +- New milestones via `sf headless new-milestone --context ` — + see SF's own TODO.md for the headless-unattended-mode caveat. +- Bulk import of a flat roadmap via `sf headless import-backlog + ` (this one works headless). diff --git a/.agents/prompts/snippets/.gitkeep b/.agents/prompts/snippets/.gitkeep new file mode 100644 index 000000000..1476e4694 --- /dev/null +++ b/.agents/prompts/snippets/.gitkeep @@ -0,0 +1 @@ +# Snippets composed into modes via Mode front matter `includeSnippets`. diff --git a/.agents/prompts/snippets/non-goals.md b/.agents/prompts/snippets/non-goals.md new file mode 100644 index 000000000..0dd3cd56d --- /dev/null +++ b/.agents/prompts/snippets/non-goals.md @@ -0,0 +1,10 @@ +# Non-Goals — quick reference + +For the full set see [`.sf/NON-GOALS.md`](../../../.sf/NON-GOALS.md). + +- Not a code-completion product. SF is a planning + workflow control + plane; the agent generates code, not autocomplete suggestions. +- Not a chatbot. Sessions are structured around milestones and modes. +- Not a knowledge graph product. Memory and recall are operational + concerns, not the product itself. +- Not a registry. SF doesn't host a public skill/plugin marketplace. diff --git a/.agents/prompts/snippets/principles.md b/.agents/prompts/snippets/principles.md new file mode 100644 index 000000000..0789dfccf --- /dev/null +++ b/.agents/prompts/snippets/principles.md @@ -0,0 +1,13 @@ +# Principles — quick reference + +For the full set see [`.sf/PRINCIPLES.md`](../../../.sf/PRINCIPLES.md). + +- **Purpose-first.** Every milestone, slice, task ties back to a + stated purpose. Refuse work that doesn't. +- **Promote-only state.** `.sf/` artifacts are append/promote — don't + rewrite history of promoted artifacts; create new revisions if + something changed. +- **Spec-first TDD.** Write the contract before the code; tests + before the implementation. +- **Deterministic resolution.** Given the same inputs, agents must + produce the same canonical configuration. diff --git a/.agents/prompts/snippets/style.md b/.agents/prompts/snippets/style.md new file mode 100644 index 000000000..b64c87594 --- /dev/null +++ b/.agents/prompts/snippets/style.md @@ -0,0 +1,14 @@ +# Style — quick reference + +For the full guide see [`.sf/STYLE.md`](../../../.sf/STYLE.md). + +- DB access via `node:sqlite` `DatabaseSync`. Never `better-sqlite3`, + never native addons. +- No file-based proxies for DB state. Query the DB. +- Comments are sparing — explain WHY a non-obvious choice was made, + never WHAT the code does (the code says that). +- Functions/classes get docstrings only when their purpose is + non-obvious from the name. +- TypeScript-first for new code under `src/`. JavaScript-first under + `src/resources/extensions/sf/` (loaded directly, no compile step + beyond `copy-resources`). diff --git a/.agents/schemas/.gitkeep b/.agents/schemas/.gitkeep new file mode 100644 index 000000000..d4d1efcbb --- /dev/null +++ b/.agents/schemas/.gitkeep @@ -0,0 +1,3 @@ +# schemas/ is REQUIRED per .agents spec but MAY be generated. +# Tooling that validates .agents/ configuration writes JSON Schema +# files here. Treat as generated output, not hand-edited. diff --git a/.agents/scopes/.gitkeep b/.agents/scopes/.gitkeep new file mode 100644 index 000000000..faf80b72a --- /dev/null +++ b/.agents/scopes/.gitkeep @@ -0,0 +1,3 @@ +# scopes/ is REQUIRED per .agents spec but MAY be empty. +# Scopes provide path-based overrides for monorepos. SF is a single +# tree today; add scopes if/when subprojects need different policies. diff --git a/.agents/skills/.gitkeep b/.agents/skills/.gitkeep new file mode 100644 index 000000000..c97906d51 --- /dev/null +++ b/.agents/skills/.gitkeep @@ -0,0 +1,2 @@ +# skills/ is REQUIRED per .agents spec but MAY be empty. +# Skills declared here MUST follow https://agentskills.io/specification. diff --git a/.agents/state/.gitignore b/.agents/state/.gitignore new file mode 100644 index 000000000..04928aed3 --- /dev/null +++ b/.agents/state/.gitignore @@ -0,0 +1,3 @@ +# Per .agents/ spec: state.yaml is per-developer convenience state +# (mode/profile/backend selection). Never commit. +state.yaml