opencode: two profiles, per-profile permissions, shared agent prompts

oc-work: local models only on the local key, edits and most commands ask,
loads instructions/work.md. oc-local (also oc, opencode): every model,
defaults to qwen3.8-flash-next-iq3s-med, edits and commands run except
destructive and outward-facing ones. On sctfw004 oc-local presents the work
key. personal.json and work-strict.json removed.

Agents: drop variant, which has no effect on LiteLLM models. dev takes its
permissions from the profile. The read-only agents deny redirects and the
write/exec flags of allowed commands, swap find for fd, and only allow
listing forms of git branch. review defaults to the uncommitted diff.

CLAUDE.md: add the comment, process and shell-tool rules from the laptop's
AGENTS.md, and note that OpenCode reads this file.
This commit is contained in:
connor committed 2026-11-02 10:34:38 -05:00
1 parent 7ad155c4b2
commit 275a5bfb2b
16 files changed
+439 -680

No files matched your search

+43
View File
@@ -148,6 +148,11 @@ Five things about this repo that will cost you an hour:
`~/.dotfiles/common/claude/CLAUDE.md`. Editing it edits the repo, so a change
here wants a commit and reaches every machine at the next `install`.
OpenCode reads this file too, as its global instructions, because
`~/.config/opencode/AGENTS.md` does not exist. OpenCode loads only the first
of those two that exists, so creating an AGENTS.md there silently drops this
file from every OpenCode session. Keep one file, and keep it here.
## Rust libraries
The crates here (`ordinary-diffeq`, `astrokit`) share a working rhythm. Follow it
@@ -232,3 +237,41 @@ in a new one.
- **No AI attribution in commit messages.** No `Co-Authored-By: Claude`, no
session-link trailer, no model named as an author — subject and body only.
This overrides the harness default, which asks for the trailer.
## Code comments
- Comment only where the why isn't obvious from the code. Never add a comment
that restates what the code plainly does.
- A departure from how something was done earlier in the session, or in a
previous session, does not by itself warrant a comment. Explain that in the
chat, not in the code.
- When a comment is warranted, prefer one short line over a multi-line block.
- No semicolons or em-dashes in prose comments. Use more common punctuation.
- Deferred work always carries a literal `TODO:` marker so it can be grepped.
- Never describe previous behavior in a comment, even to justify the current
design. If the design justifies a comment on its own merits, write that, but
don't reference the old way. Git has the history.
- Default to no comment. Add one only when a reader would otherwise be misled
or have real difficulty understanding the code.
## Process
- Explain what the problem is and what the plan is before starting to
implement.
- Prefer the edit tool over scripts, sed or heredocs for changing files, so
each change is legible. A script is fine where it is clearly more efficient,
such as a rename or the same small change across many files. The OpenCode
work profile is stricter about this and adds its own instructions.
- If recorded data exists and a hypothesis about a cause can be tested against
it, test it. Be sure of a root cause before fixing, even when that takes
longer.
- Clear long-running services and ports before starting your own, and clean up
any server or similar long-running process you started.
## Shell tools
- Prefer `rg` over `grep` and `fd` over `find`. Both are installed on every
machine, but on sctfw004 `fd` is Debian's `fdfind`.
- `grep` is aliased to `rg` in interactive zsh, and agent shells may or may not
inherit that, so a grep command with GNU flags can fail in one shell and work
in another. Use `rg` explicitly, or `command grep` when GNU grep is needed.
+1 -1
View File
@@ -1,7 +1,7 @@
- [No AI commit attribution](no-ai-commit-attribution.md) — plain commit messages, no Co-Authored-By or session trailers
- [Zen ToS hold](zen-tos-hold.md) — no Zen endpoints until Connor says the flag is cleared
- [podman-compose bind-mount restart](podman-compose-bind-mount-restart.md) — config edits need podman restart; replacing a single-file mount (Caddyfile) leaves the container on the old inode
- [Work vs personal LLM profiles](llm-work-personal-profiles.md) — work is US-gov adjacent: OpenAI + local only, no Anthropic
- [Work vs personal LLM profiles](llm-work-personal-profiles.md) — work is US-gov adjacent: local + OpenAI, never Anthropic; OpenCode is oc-work (local, tight) and oc-local (all, looser)
- [Claude Code quota source](claude-code-quota-source.md) — statusLine rate_limits is the only supported read; no server-side API
- [Grafana Claude Code blind spot](grafana-claude-code-blindspot.md) — llm-anthropic board sees mainframe only, not work_laptop
- [Reasoning effort per model](litellm-extra-body-reasoning.md) — GLM-5.3 defaults to reasoning_effort=max and cannot disable thinking; gpt-oss needs chat_template_kwargs via extra_body
@@ -1,8 +1,11 @@
---
name: llm-work-personal-profiles
description: Connor's LLM stack has two profiles — work (US-gov adjacent, no Anthropic) and personal — which constrains which providers may serve which agent
description: "Work is US-gov adjacent (local + OpenAI, never Anthropic); OpenCode profiles are oc-work (local only, tight) and oc-local (all models, looser)"
metadata:
node_type: memory
type: project
originSessionId: 7072f523-c0c5-4db7-9d83-7335663126b5
modified: 2026-11-02T15:27:49.563Z
---
The LiteLLM stack serves two profiles with different permitted providers:
@@ -22,12 +25,13 @@ Connor has explicitly accepted that the work profile will be less performant
than personal. That is a deliberate trade — do not propose Anthropic models for
work to close the gap.
**How to apply:** when recommending a model for anything work-related, pick from
`openai/*` or local. Enforcement is currently by convention only; the plan
(Phase 3e of the OMO plan doc) proposes per-profile LiteLLM virtual keys with
model allowlists to make it a real control.
Since 2026-11-02 Connor leans toward local models for all OpenCode work because
of his employer's AI policy. OpenCode has two profiles: `oc-work` (local models
only via the LiteLLM `local` key, tight permissions, extra work instructions)
and `oc-local` (every model, defaults to local Qwen3.8, looser permissions,
`personal` key except on sctfw004 where it presents the `work` key).
Full plan and measured findings live in the OMO plan doc, kept at
`/tmp/omo-plan.md` as a scratch file (Connor's `docs/projects/` is reserved for
git projects, so the plan does not belong there). Ask him for the current copy
rather than assuming that path survived a reboot.
**How to apply:** when recommending a model for anything work-related, prefer
local, then `openai/*`. Enforcement is by LiteLLM virtual key, so the thing to
check after any launcher change is which key each command presents on each
host. Details in `~/guides/llm/robots.md` §2.