Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .cursor-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,11 @@
"grokbot": "0.49.0",
"sand": "0.49.0"
}
},
{
"name": "onprem",
"source": "onprem",
"description": "On-prem model governance and operating doctrine for Cursor agent work: a closed-allowlist hard lock, a stack of named principles, an entry mode, setup, and guide."
}
]
}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Official Cursor plugins for popular developer tools, frameworks, and SaaS produc
| `orchestrate` | [Orchestrate](orchestrate/) | Cursor | Developer Tools | Fan large tasks out across parallel cloud agents with planners, workers, verifiers, and structured handoffs. |
| `pstack` | [pstack](pstack/) | Lauren Tan | Developer Tools | if you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence. |
| `dyl-stack` | [dyl-stack](dyl-stack/) | Dylan Gattey | Developer Tools | Dylan's agent style on top of pstack: root causes over symptom patches, The Algorithm before design, terse verified delivery, a PR review that fits in a paste, and Figma-to-UI with a visual judge. |
| `onprem` | [onprem](onprem/) | Jarrod Tran | Developer Tools | On-prem model governance and operating doctrine for agent work: a closed-allowlist hard lock, a stack of named principles, an entry mode, setup, and guide. |
| `advisor` | [Advisor](advisor/) | Cursor | Developer Tools | Consult a stronger model before major decisions, when stuck, and before declaring done. |
| `grok-voice` | [Grok Voice](grok-voice/) | Eric Zakariasson | Developer Tools | Add Grok voice to an app: realtime speech-to-speech, speech-to-text dictation, text-to-speech read-aloud, and a log-driven fix loop for voice sessions. |
| `gmail` | [Gmail](third_party/gmail/) | Cursor | Productivity | Search, read, draft, and manage email. |
Expand Down
28 changes: 28 additions & 0 deletions onprem/.cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "onprem",
"displayName": "onprem stack",
"version": "0.1.0",
"description": "on-prem model governance and operating doctrine for agent work: a closed allowlist hard lock, a stack of named principles, and an entry mode that applies them.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Listing descriptions disagree across surfaces

Medium Severity · Bugbot Rules

The plugin description differs across plugin.json, marketplace.json, and the README table. Marketplace inserts Cursor and a different ending; plugin.json changes capitalization, hyphenation, and the closing clause. Installed and marketplace listings will show different copy.

Additional Locations (2)
Fix in Cursor Fix in Web

Triggered by learned rule: Plugin listing copy must match plugin.json and marketplace.json

Reviewed by Cursor Bugbot for commit 123d853. Configure here.

"author": {
"name": "Jarrod Tran"
},
"license": "MIT",
"keywords": [
"onprem",
"on-prem",
"open-weight",
"model-governance",
"hard-lock",
"principles",
"agent-style"
],
"category": "developer-tools",
"tags": [
"workflow",
"principles",
"review",
"model-governance"
],
"skills": "./skills/",
"agents": "./agents/"
}
75 changes: 75 additions & 0 deletions onprem/.cursor/skills/verify-onprem/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
name: verify-onprem
description: 'Drive the onprem plugin like its operator and prove its state with rerunnable checks. Use when asked to verify, audit, or health-check the onprem install (verify onprem, is my onprem lock intact, check the plugin after an edit, onprem doctor). Read-only; it never writes the plugin, the rule file, or the registration links.'
---

# Verify onprem

The onprem plugin is configuration, not a running app. Its user surface is the `/onprem-*` skills in Cursor, the generated rule file `~/.cursor/rules/onprem-models.mdc`, and the registration links that make the plugin visible. This skill drives that surface with a deterministic check suite and proves it with captured evidence, per the deterministic-proof principle: a check that passes is a proof, a self-report is a claim.

## Launch

There is no server to start. Launch means locating the checkout and the rule:

```bash
python3 .cursor/skills/verify-onprem/verify.py --doctor
```

Ready means the doctor JSON reports `plugin_root: true`, `manifest: true`, and (on a configured machine) `rule_file: true`. The helper self-locates the plugin root by walking up to `.cursor-plugin/plugin.json`, so it runs from any checkout of the repo. Teardown is a no-op: nothing is started.

## Doctor

One read-only check that answers "is this instance worth driving?":

- `plugin_root` and `manifest` false → not a checkout of onprem; stop and say so.
- `rule_file` false → `/setup-onprem` has not run on this machine; the suite will skip `rule-audit` and say so in its evidence. That is a valid state for a fresh clone.
- `git_origin` null → not a git checkout (a directory copy); fine for verification, wrong for a publish flow.

## Drive

Run the full suite:

```bash
python3 .cursor/skills/verify-onprem/verify.py
```

It prints a JSON summary and exits 0 on pass, 1 on any hard fail. The nine checks and what each proves:

| check | proves |
|---|---|
| `manifest` | plugin.json parses, is named `onprem`, declares skills and agents |
| `frontmatter` | every skill/agent frontmatter parses; skill `name` matches its directory |
| `mode-dashes` | the mode file obeys its own no-long-dash rule |
| `template-identity` | the 18 role lines are byte-identical between setup-onprem and role-mapping, all values in the closed set |
| `closed-set` | the four real slugs are named in all nine core files; the exact-set surfaces (audit, template comment) include both `inherit-parent` and `auto` |
| `banned-leak` | no banned-family name appears outside lock-statement files |
| `links` | every relative markdown link resolves |
| `rule-audit` | the rule file has `alwaysApply: true`, the `unlimited (max)` budget line, the full allowlist comment line, and 18 closed-set role lines |
| `registration` | the 16 skill links and the agent link resolve on this machine (skips cleanly on a fresh clone) |

For any failing check, quote the check name and its `detail` field, then open the named file and confirm the failure is real before acting. RoboDev-style review output and model self-reports are claims; this suite is the proof.

## Evidence

Capture the JSON and keep it. The named location is `~/.cursor/verify-onprem-evidence/`:

```bash
mkdir -p ~/.cursor/verify-onprem-evidence
python3 .cursor/skills/verify-onprem/verify.py > ~/.cursor/verify-onprem-evidence/verify-$(date -u +%Y%m%dT%H%M%SZ).json
echo "exit: $?"
```

A proof is the run's exit code 0 plus the JSON file on disk with `"status": "pass"` and every check `ok: true` (or an explicitly labeled `skip:` detail). Confirm the evidence file still exists after any cleanup; a cleanup that eats the proof fails this step.

## Cleanup

Read-only by construction: the suite writes nothing into the plugin, the rule file, or the registration links. The only artifact is the evidence file, which survives by design. There is nothing to kill; the doctor and suite start no processes.

## Helpers

- `verify.py` (this directory) is executable. Invocation: `python3 .cursor/skills/verify-onprem/verify.py [--doctor]`.
- No other helpers. If a check needs to grow, extend `verify.py`; do not add one-off scripts that drift from the suite.

## Maintenance

Re-run the suite after every edit to the plugin or the rule file, and after any `/setup-onprem` re-run. onprem ships no separate maintain-verification skill; this suite plus the `/onprem-mode` audit playbook (which audits the rule file against the lock, including session detection that this script cannot see) is the maintenance pass.
11 changes: 11 additions & 0 deletions onprem/.cursor/skills/verify-onprem/features/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# verify-onprem feature map

One file per check suite the helper drives. A proof that exercises one convenient suite is incomplete when the map lists others.

| feature | suites | proves |
|---|---|---|
| [lock-consistency](lock-consistency.md) | `closed-set`, `banned-leak` | the five-value closed set is stated identically everywhere; no banned family is ever presented as usable |
| [template-identity](template-identity.md) | `template-identity` | the 18 role lines agree across both template surfaces |
| [structure](structure.md) | `manifest`, `frontmatter`, `mode-dashes`, `links` | the plugin registers and renders: valid manifest, parsing frontmatter, dash-free mode file, resolving links |
| [rule-audit](rule-audit.md) | `rule-audit` | the generated rule file is a valid lock surface |
| [registration](registration.md) | `registration`, `--doctor` | the plugin is visible to sessions on this machine |
16 changes: 16 additions & 0 deletions onprem/.cursor/skills/verify-onprem/features/lock-consistency.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Lock consistency

## Sub-features
- `closed-set`: the four real slugs appear in all nine core files; the exact-set surfaces (audit playbook step 2, setup template comment line) name both `inherit-parent` and `auto`.
- `banned-leak`: no banned-family name (claude, anthropic, fable, opus, sonnet, haiku, gemini, grok, xai, gpt, openai, sol) appears in any file that carries no lock language.

## How to get to it (user POV)
An operator who suspects the lock drifted after an edit asks "is my lock intact?" in a chat, or runs the suite after a hand-edited file. The suites answer the mechanical half of that question; the `/onprem-mode` audit playbook answers the session half (whether the machine actually has the slugs).

## Driving it with verify.py
`python3 .cursor/skills/verify-onprem/verify.py` runs both suites in one pass. Observable end state: `"ok": true` on `closed-set` and `banned-leak`, plus an evidence JSON on disk. A `closed-set` failure names the file and the missing slug; a `banned-leak` failure names file:line and the word.

## Gotchas
- The leak scan exempts any file containing lock language (never/banned/allowlist/closed). A banned family name inside a ban statement is correct content, not a leak.
- `sol` as a substring is the banned-set's own token; the scan uses word boundaries, so `consolidated` never trips it.
- These suites check text consistency, not endpoint liveness. A slug can be consistently named and still not served by the local deployment; the first real `/onprem-mode` task is that check.
15 changes: 15 additions & 0 deletions onprem/.cursor/skills/verify-onprem/features/registration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Registration

## Sub-features
- `registration`: the 16 skill links under `~/.claude/skills/` resolve to plugin skill directories with a readable SKILL.md, and `~/.cursor/agents/onprem-agent.md` resolves.
- `--doctor`: the read-only readiness check (plugin root, manifest, rule file presence, git origin) that answers "is this machine worth driving at all?"

## How to get to it (user POV)
On the author's machine the plugin is wired by symlinks into the skill and agent roots so every new session sees it. A fresh clone is not wired: Cursor picks up `~/.cursor/plugins/local/` at startup, and a window reload may be needed. The suite tells the operator which of the two states they are in.

## Driving it with verify.py
`python3 .cursor/skills/verify-onprem/verify.py --doctor` for the readiness answer; the default pass for the link resolution. On a fresh clone the registration suite reports `skip:` with the missing names and exits 0.

## Gotchas
- Symlinks that resolve to a deleted plugin directory fail this suite; re-point them at the live checkout.
- The skill-link list in verify.py must track the plugin's skill directories. Adding or renaming a skill leaf means updating SKILL_LINKS in the same commit.
14 changes: 14 additions & 0 deletions onprem/.cursor/skills/verify-onprem/features/rule-audit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Rule audit

## Sub-features
- `rule-audit`: `~/.cursor/rules/onprem-models.mdc` (when present) has `alwaysApply: true`, a `# budget: unlimited (max)` line, a HARD LOCK comment line naming all four real slugs plus both aliases, and exactly 18 role lines whose values are all in the closed set.

## How to get to it (user POV)
The rule file is the configuration half of the lock. An operator who hand-edited it, or who re-ran `/setup-onprem` on a machine with different entitlements, wants a mechanical answer to "did the rule land right?" before the first real task.

## Driving it with verify.py
Part of the default pass. On a machine without the rule (fresh clone), the suite reports `skip:` and still exits 0; that is the correct, labeled state, not a pass.

## Gotchas
- This suite cannot see the session's detected model list, so it validates the closed set, not availability. The session-detected check belongs to the `/onprem-mode` audit playbook, which runs where a session exists.
- The budget line is asserted to be `unlimited (max)` because principle-unlimited-budget makes the budget a confirmation, not a choice. If the doctrine changes, change the principle and this check together.
18 changes: 18 additions & 0 deletions onprem/.cursor/skills/verify-onprem/features/structure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Structure

## Sub-features
- `manifest`: `.cursor-plugin/plugin.json` parses, is named `onprem`, declares `skills` and `agents`.
- `frontmatter`: every markdown file with YAML frontmatter parses; each skill's `name` matches its directory; every frontmatter has a description.
- `mode-dashes`: `skills/onprem-mode/SKILL.md` contains no long-dash characters (its own line 81 bans them on every reply the mode writes).
- `links`: every relative markdown link in the plugin resolves to an existing file.

## How to get to it (user POV)
This is the "will Cursor even register this plugin" suite. A broken frontmatter name silently unregisters a skill; a dead link sends a recipient down a wrong path; a mode file that violates its own writing rule erodes trust in the doctrine it carries.

## Driving it with verify.py
Part of the default pass. Observable end state: `"ok": true` on all four, with the frontmatter detail counting how many files parsed.

## Gotchas
- The dash check is scoped to the mode file on purpose. Guide pages and setup prose are human-facing and may use long dashes, mirroring pstack.
- A frontmatter `name`/dir mismatch usually means a directory was renamed without the file. Fix the directory or the name, not the check.
- HTTP(S) links are not checked for reachability, only for syntax via the link scan.
14 changes: 14 additions & 0 deletions onprem/.cursor/skills/verify-onprem/features/template-identity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Template identity

## Sub-features
- `template-identity`: the 18 role lines in setup-onprem's rule template are byte-identical to the 18 role lines in principle-role-mapping's default block, and every value is in the closed set.

## How to get to it (user POV)
Two surfaces both claim to show the default mapping. If an operator edits one and not the other, an agent reading the role-mapping principle and an agent reading setup get different defaults, and the rule file that gets written depends on which surface the session happened to load.

## Driving it with verify.py
Part of the default pass. Observable end state: `"ok": true` with the detail "18 role lines identical...". A failure reports the line counts on both sides and any out-of-set values.

## Gotchas
- The comparison is anchored on the `# onprem model configuration` marker in setup-onprem and the first fenced block in role-mapping. If either file's template moves or its marker rewords, the suite fails loudly rather than silently comparing the wrong blocks.
- This check compares templates, not the live rule file. The live file's role lines are checked by the `rule-audit` suite.
Loading