No description
  • TypeScript 90.7%
  • Shell 5.7%
  • Dockerfile 3.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
epistemophiliac 240cda4b41 Stop Sentinel PRs from bumping or advertising versions.
Prompt/skill forbid csproj and bootstrap version edits, and PR bodies strip leftover version-bump lines so agents cannot claim a release number that is not this commit.
2026-07-23 07:01:41 -04:00
config Initial Sentinel gateway: hot-reload projects, BugSink triage, Cursor SDK hotfixes. 2026-07-23 03:07:28 -04:00
prompts Stop Sentinel PRs from bumping or advertising versions. 2026-07-23 07:01:41 -04:00
scripts Bake Aexora skills pack and full agent toolchain into Docker. 2026-07-23 06:01:36 -04:00
src Stop Sentinel PRs from bumping or advertising versions. 2026-07-23 07:01:41 -04:00
vendor Stop Sentinel PRs from bumping or advertising versions. 2026-07-23 07:01:41 -04:00
.env.example Bake Aexora skills pack and full agent toolchain into Docker. 2026-07-23 06:01:36 -04:00
.gitignore Initial Sentinel gateway: hot-reload projects, BugSink triage, Cursor SDK hotfixes. 2026-07-23 03:07:28 -04:00
docker-compose.yml Bake Aexora skills pack and full agent toolchain into Docker. 2026-07-23 06:01:36 -04:00
Dockerfile Bake Aexora skills pack and full agent toolchain into Docker. 2026-07-23 06:01:36 -04:00
package-lock.json Initial Sentinel gateway: hot-reload projects, BugSink triage, Cursor SDK hotfixes. 2026-07-23 03:07:28 -04:00
package.json Initial Sentinel gateway: hot-reload projects, BugSink triage, Cursor SDK hotfixes. 2026-07-23 03:07:28 -04:00
README.md Bake Aexora skills pack and full agent toolchain into Docker. 2026-07-23 06:01:36 -04:00
tsconfig.json Initial Sentinel gateway: hot-reload projects, BugSink triage, Cursor SDK hotfixes. 2026-07-23 03:07:28 -04:00

Sentinel

Continuous multi-project BugSink → Forgejo hotfix gateway powered by the Cursor SDK.

  • Persona / prompt: Sentinel (sentinel.hotfix.v1)
  • Loop: sentinel-watch — always-on poll across enrolled projects
  • Ship mode: opens Forgejo PRs only (no auto-merge, no release publish, no BugSink resolve)
  • Config: hot-reloadable /data/config/projects.json — add/remove projects without restart

Repo: https://git.aexoradao.com/epistemophiliac/Sentinel

Logical flow

  1. Watch projects.json (and PUT /v1/projects) → live in-memory registry swap
  2. For each enabled project → BugSink triage (deterministic filters)
  3. Dedupe fingerprints / open PRs
  4. Clone Forgejo repo → Cursor SDK local agent with Sentinel prompt
  5. Commit + push sentinel/hotfix-* → open PR

Why local Cursor SDK (not managed cloud agents)

Forgejo is self-hosted. Cursor managed cloud agents are GitHub-oriented. Sentinel runs local agents (local: { cwd }) against persistent clones on the Coolify volume.

Enroll a project (no restart)

Edit /data/config/projects.json on the volume, or:

curl -sS -X PUT https://<sentinel-host>/v1/projects \
  -H "Authorization: Bearer $SENTINEL_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d @- <<'EOF'
{
  "pollIntervalSec": 300,
  "maxGlobalConcurrentAgents": 2,
  "projects": [
    {
      "id": "my-app",
      "enabled": true,
      "bugsink": "AexoLoader",
      "forgejo": "epistemophiliac/my-app",
      "defaultBranch": "main",
      "noiseDeny": [],
      "minEvents": 1,
      "promptProfile": "sentinel.hotfix.v1"
    }
  ]
}
EOF

Disable without deleting:

curl -sS -X PATCH https://<sentinel-host>/v1/projects/my-app \
  -H "Authorization: Bearer $SENTINEL_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"enabled": false}'

API

Method Path Notes
GET /health liveness, paused, skills/tools ok
GET /v1/status full surveillance snapshot (live transcript + counters)
GET /v1/ready toolchain + skills inventory (auth)
GET /v1/live SSE stream of AI transcript lines (line / begin / end / heartbeat)
POST /v1/pause master kill — stop cycles + abort active agent
POST /v1/resume clear pause
POST /v1/abort abort active agent without pausing forever
POST /v1/fingerprints/clear unlock all dedupe fingerprints
GET /v1/projects live registry
PUT /v1/projects replace registry (writes file → hot reload)
PATCH /v1/projects/:id patch one project
POST /v1/projects/reload force reload from disk
GET /v1/runs recent runs (includes truncated transcript)
GET /v1/runs/:id one run
POST /v1/run kick one watch cycle now (409 if paused)

If SENTINEL_ADMIN_TOKEN is set, all /v1/* routes require Authorization: Bearer ….

Safety defaults

  • SENTINEL_PAUSED defaults to true in compose — deploy stays idle until POST /v1/resume.
  • SENTINEL_AGENT_TIMEOUT_SEC defaults to 900 — hung agents are cancelled.
  • Boot reclaims leftover queued/running rows and unlocks fingerprints.
  • Full Cursor run.stream() transcript is logged ([ai:…]) and mirrored to /v1/status + SSE.
  • Prompt forces surgical hotfixes only (no open-ended exploration).
  • Empty-diff gate: if the agent finishes with a clean git tree, Sentinel forces one write follow-up. If still clean → status empty_diff (no commit, fingerprint stays locked). Narrative-only finishes cannot open a PR.

Skills + agent toolchain (Docker)

Sentinel vendors https://git.aexoradao.com/epistemophiliac/skills into vendor/aexora-skills and bakes them into the image at /opt/aexora-skills.

On every container start and before each agent run:

  1. Skills/rules are applied to HOME/.cursor (user) and the Forgejo clones .cursor (project).
  2. Cursor agents load settingSources: ["project", "user"].
  3. Hotfix commits exclude .cursor/ so skills are never pushed into customer PRs.

Refresh the vendor snapshot: ./scripts/sync-skills.sh

Image toolchain (verified by entrypoint): git, curl, rsync, rg, python3, jq, dotnet (SDK 8), node, plus build-essential / binutils for inspection builds.

Check after deploy: GET /v1/ready (Bearer admin token).

Note: The LaTeX skill is present as documentation; a full TeX Live stack is not installed (image size). Hotfix work uses the C#/git/python toolchain above.

Coolify deploy

  1. Create a Docker Compose resource from this repo.
  2. Set secrets in Coolify UI: CURSOR_API_KEY, BUGSINK_API_TOKEN, FORGEJO_TOKEN (and optional SENTINEL_ADMIN_TOKEN).
  3. Assign a domain to service sentinel on port 8080 (compose declares SERVICE_URL_SENTINEL_8080).
  4. After first boot, enroll projects via PUT /v1/projects or by editing the sentinel_data volume file /data/config/projects.json.
  5. Confirm readiness: curl -sS -H "Authorization: Bearer $SENTINEL_ADMIN_TOKEN" https://<host>/v1/ready — expect toolsOk: true and a non-zero skillsCount.

Note: Changing compose env defaults does not update values Coolify already stored — edit them in the Coolify UI.

Local dev

cp config/projects.example.json /tmp/sentinel-projects.json
cp .env.example .env   # fill keys
export SENTINEL_DATA_DIR=./data
export SENTINEL_CONFIG_PATH=./data/config/projects.json
mkdir -p data/config data/repos
cp config/projects.example.json data/config/projects.json
npm install
npm run dev

Dry-run (no real BugSink/Cursor/Forgejo calls for empty registry):

SENTINEL_DRY_RUN=true CURSOR_API_KEY=x BUGSINK_API_TOKEN=x FORGEJO_TOKEN=x npm run dev

License

Private Aexora tooling.