.agents: adopt agentsfolder/spec v0.1 as canonical agent configuration
Per template (singularity-forge f3d84cd11). Project-specific manifest + prompts/project.md capture: post-rename namespace com.centralcloud.oncall (io.heckel.ntfy fully gone), centrally-configured-from-server design, strict-opt-in SMS relay, greenfield (no backwards compat with upstream ntfy). Legacy docs (AGENTS.md, README.md, TESTING.md) kept; .agents/ canonical going forward. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
78815896cc
commit
fb8f45e9fa
17 changed files with 427 additions and 0 deletions
53
.agents/manifest.yaml
Normal file
53
.agents/manifest.yaml
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
# .agents/ canonical agent configuration
|
||||
# Spec: https://github.com/agentsfolder/spec
|
||||
#
|
||||
# Status: pre-1.0 spec adoption. Schema may shift.
|
||||
|
||||
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: oncall-mobile-android
|
||||
description: >-
|
||||
Centralcloud OnCall — Android pager app. Forked from ntfy-android,
|
||||
fully renamed (package com.centralcloud.oncall). Includes the
|
||||
SMS-relay subsystem that forwards whitelisted incoming SMS to
|
||||
centralcloud-ops via /api/sms/inbound/phone-relay.
|
||||
languages:
|
||||
- kotlin
|
||||
- java
|
||||
frameworks:
|
||||
- android
|
||||
- okhttp
|
||||
- workmanager
|
||||
- room
|
||||
|
||||
x:
|
||||
centralcloud:
|
||||
legacy_pointers:
|
||||
- AGENTS.md
|
||||
- README.md
|
||||
- TESTING.md
|
||||
- flake.nix
|
||||
note: >-
|
||||
Package namespace post-rename is com.centralcloud.oncall. The
|
||||
io.heckel.ntfy namespace is entirely removed from the source
|
||||
tree as of commit d5694a32. Custom subsystems live under
|
||||
com.centralcloud.oncall.sms (SMS relay + device heartbeat).
|
||||
36
.agents/modes/ask.md
Normal file
36
.agents/modes/ask.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
id: ask
|
||||
title: Ask
|
||||
policy: default-safe
|
||||
enableSkills: []
|
||||
disableSkills: []
|
||||
includeSnippets: []
|
||||
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.
|
||||
40
.agents/modes/build.md
Normal file
40
.agents/modes/build.md
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
---
|
||||
id: build
|
||||
title: Build
|
||||
policy: default-safe
|
||||
enableSkills: []
|
||||
disableSkills: []
|
||||
includeSnippets: []
|
||||
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.
|
||||
50
.agents/policies/default-safe.yaml
Normal file
50
.agents/policies/default-safe.yaml
Normal file
|
|
@ -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
|
||||
44
.agents/policies/yolo.yaml
Normal file
44
.agents/policies/yolo.yaml
Normal file
|
|
@ -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
|
||||
3
.agents/profiles/.gitkeep
Normal file
3
.agents/profiles/.gitkeep
Normal file
|
|
@ -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.
|
||||
12
.agents/prompts/base.md
Normal file
12
.agents/prompts/base.md
Normal file
|
|
@ -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.
|
||||
49
.agents/prompts/project.md
Normal file
49
.agents/prompts/project.md
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# Project Prompt — oncall-mobile-android
|
||||
|
||||
## What this is
|
||||
|
||||
Centralcloud OnCall Android pager. Forked from `binwiederhier/ntfy-android`;
|
||||
fully renamed to `com.centralcloud.oncall` (no `io.heckel.ntfy` left in
|
||||
the source tree).
|
||||
|
||||
Engineer's single pane for on-call: paging, conference bridge, agent
|
||||
chat, plus an SMS-relay subsystem that forwards whitelisted incoming
|
||||
SMS from this device's number to centralcloud-ops.
|
||||
|
||||
For the long form see [`AGENTS.md`](../../AGENTS.md). For test setup
|
||||
see [`TESTING.md`](../../TESTING.md). For the build shell see
|
||||
[`flake.nix`](../../flake.nix).
|
||||
|
||||
## Non-negotiables
|
||||
|
||||
- **Package namespace is `com.centralcloud.oncall`.** Don't reintroduce
|
||||
`io.heckel.ntfy` in any file — the rename is complete and absolute.
|
||||
- **Centrally configured.** App hits
|
||||
`GET https://ops.centralcloud.com/api/android/config` on first
|
||||
launch — everything else (server URLs, default topics, FCM project)
|
||||
comes from there. Hardcode at most one URL.
|
||||
- **Strict opt-in for SMS relay.** `SmsRelayPreferences.enabled`
|
||||
defaults false. Whitelist is required (empty set → forward nothing).
|
||||
Disclosure must be clear in the settings UI — the app reads
|
||||
incoming SMS, and that's sensitive.
|
||||
- **Greenfield, no backwards compat with upstream ntfy.** Backup
|
||||
format magic was rewritten (`oncall26`), URL scheme is `oncall://`,
|
||||
intent action namespaces are `com.centralcloud.oncall.*` (e.g.
|
||||
`com.centralcloud.oncall.SEND_MESSAGE`).
|
||||
|
||||
## Workflow
|
||||
|
||||
- Build via Nix dev shell: `nix develop` then `./gradlew assembleDebug`.
|
||||
- Tests: see TESTING.md.
|
||||
- Install on ops phones: `adb install -r app/build/outputs/apk/...`.
|
||||
- SMS-relay config: launch
|
||||
`adb shell am start -n com.centralcloud.oncall/.sms.SmsRelaySettingsActivity`,
|
||||
set base URL + device ID + whitelist + toggle on.
|
||||
|
||||
## Sibling repos
|
||||
|
||||
- **`centralcloud/infra`** — the centralcloud-ops Phoenix app this
|
||||
connects to (`/api/push/*`, `/api/sms/inbound/phone-relay`,
|
||||
`/api/devices/heartbeat`, etc.).
|
||||
- **`centralcloud/operations-memory`** — Go memory service.
|
||||
- **`singularity/singularity-forge`** — SF planning tool.
|
||||
1
.agents/prompts/snippets/.gitkeep
Normal file
1
.agents/prompts/snippets/.gitkeep
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Snippets composed into modes via Mode front matter `includeSnippets`.
|
||||
3
.agents/schemas/.gitkeep
Normal file
3
.agents/schemas/.gitkeep
Normal file
|
|
@ -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.
|
||||
3
.agents/scopes/.gitkeep
Normal file
3
.agents/scopes/.gitkeep
Normal file
|
|
@ -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.
|
||||
2
.agents/skills/.gitkeep
Normal file
2
.agents/skills/.gitkeep
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# skills/ is REQUIRED per .agents spec but MAY be empty.
|
||||
# Skills declared here MUST follow https://agentskills.io/specification.
|
||||
37
.agents/skills/forge-autonomous-runtime/SKILL.md
Normal file
37
.agents/skills/forge-autonomous-runtime/SKILL.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
name: forge-autonomous-runtime
|
||||
description: Explains SF autonomous loop, UOK gates, installed-runtime drift, and recovery paths.
|
||||
user-invocable: false
|
||||
model-invocable: true
|
||||
side-effects: none
|
||||
permission-profile: restricted
|
||||
triggers:
|
||||
- "*"
|
||||
---
|
||||
|
||||
# forge-autonomous-runtime
|
||||
|
||||
## Context
|
||||
|
||||
SF's autonomous mode is governed by the Unified Operation Kernel (UOK):
|
||||
|
||||
1. **State reading** — UOK reads canonical project state from `.sf/sf.db`
|
||||
2. **Ledger recording** — Each run is recorded in the DB-backed ledger
|
||||
3. **Projection** — Runtime files under `.sf/runtime/` are generated projections
|
||||
4. **Dispatch** — UOK determines the next unit of work and creates a fresh agent session
|
||||
5. **Execution** — LLM executes with focused prompt and pre-inlined context
|
||||
6. **Reconciliation** — UOK reconciles ledger and projections before next dispatch
|
||||
|
||||
## Recovery Paths
|
||||
|
||||
- **Crash recovery** — Lock file tracks current unit; next `/autonomous` reads surviving state
|
||||
- **Stuck detection** — Loop detects stuck iterations and emits `stuck-detected` journal events
|
||||
- **Health gates** — Pre-dispatch gates check state integrity before execution
|
||||
- **Parity reports** — Ledger parity ensures no orphaned or missing unit records
|
||||
|
||||
## Rules
|
||||
|
||||
- Never modify `.sf/sf.db` directly — use UOK APIs
|
||||
- Never trust `.sf/runtime/` files as authoritative — they are projections
|
||||
- Always check `runControl` and `permissionProfile` before tool invocation
|
||||
- Journal events are best-effort; absence is a failure signal
|
||||
48
.agents/skills/forge-command-surface/SKILL.md
Normal file
48
.agents/skills/forge-command-surface/SKILL.md
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
name: forge-command-surface
|
||||
description: Use when changing SF slash commands, browser command parity, or headless command dispatch.
|
||||
user-invocable: true
|
||||
model-invocable: true
|
||||
side-effects: code-edits
|
||||
permission-profile: normal
|
||||
triggers:
|
||||
- build
|
||||
- code
|
||||
- "*"
|
||||
---
|
||||
|
||||
# forge-command-surface
|
||||
|
||||
## When to Use
|
||||
|
||||
This skill applies when:
|
||||
- Adding or modifying SF slash commands (`/mode`, `/tasks`, `/skills`, etc.)
|
||||
- Changing command handlers in `src/resources/extensions/sf/commands/handlers/`
|
||||
- Updating command catalog descriptions
|
||||
- Ensuring web/TUI/headless command parity
|
||||
- Modifying command dispatch routing
|
||||
|
||||
## Instructions
|
||||
|
||||
1. **Check existing handlers** — Look in `commands/handlers/core.js` and `commands/handlers/ops.js` for the pattern
|
||||
2. **Update catalog** — Add to `commands/catalog.js` `TOP_LEVEL_SUBCOMMANDS`
|
||||
3. **Update help text** — Add to `showHelp()` in `commands/handlers/core.js`
|
||||
4. **Wire dispatch** — Add routing in `handleCoreCommand()` or `handleOpsCommand()`
|
||||
5. **Test** — Verify with `node --check` and manual test
|
||||
|
||||
## Verification
|
||||
|
||||
- [ ] Command appears in `/help`
|
||||
- [ ] Command appears in `/help all`
|
||||
- [ ] Handler file passes `node --check`
|
||||
- [ ] No `/sf` prefix in user-facing strings
|
||||
|
||||
## Examples
|
||||
|
||||
```javascript
|
||||
// Adding a new command
|
||||
if (trimmed === "mycommand" || trimmed.startsWith("mycommand ")) {
|
||||
await handleMyCommand(trimmed.replace(/^mycommand\s*/, "").trim(), ctx);
|
||||
return true;
|
||||
}
|
||||
```
|
||||
26
.agents/skills/nix-build/SKILL.md
Normal file
26
.agents/skills/nix-build/SKILL.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
name: nix-build
|
||||
description: Build any @singularity-forge/* package (or the full stack) via nix develop. Pass a package name like "pi-coding-agent", "native", "daemon", or "all" for a full core build.
|
||||
---
|
||||
|
||||
All build commands in this repo must run inside `nix develop`. Never use bare cargo/rustc.
|
||||
|
||||
For a single package:
|
||||
```
|
||||
nix develop --command bash -c "npm run --workspace=@singularity-forge/<package> build"
|
||||
```
|
||||
|
||||
For the full core build (native + all TS packages):
|
||||
```
|
||||
nix develop --command bash -c "npm run build:core"
|
||||
```
|
||||
|
||||
For typecheck only:
|
||||
```
|
||||
nix develop --command bash -c "tsc --noEmit -p tsconfig.json"
|
||||
```
|
||||
|
||||
For extensions typecheck:
|
||||
```
|
||||
nix develop --command bash -c "tsc --noEmit -p tsconfig.extensions.json"
|
||||
```
|
||||
17
.agents/skills/smoke-test/SKILL.md
Normal file
17
.agents/skills/smoke-test/SKILL.md
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
name: smoke-test
|
||||
description: Run the standard sf-run smoke tests (--version, --help, --print). All three must pass before shipping a build.
|
||||
---
|
||||
|
||||
#!/bin/bash
|
||||
set -e
|
||||
echo "=== --version ==="
|
||||
node dist/loader.js --version
|
||||
|
||||
echo "=== --help (first 5 lines) ==="
|
||||
node dist/loader.js --help 2>&1 | head -5
|
||||
|
||||
echo "=== --print (graceful degradation) ==="
|
||||
node dist/loader.js --print 2>&1 | head -5
|
||||
|
||||
echo "All smoke tests passed."
|
||||
3
.agents/state/.gitignore
vendored
Normal file
3
.agents/state/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Per .agents/ spec: state.yaml is per-developer convenience state
|
||||
# (mode/profile/backend selection). Never commit.
|
||||
state.yaml
|
||||
Loading…
Add table
Reference in a new issue