@sema-agent/server 1.196.0 → 1.197.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -1
- package/dist/config.js.map +1 -1
- package/package.json +2 -1
- package/skills/code-review.md +28 -0
- package/skills/commit-push-pr.md +77 -0
- package/skills/dataviz/SKILL.md +112 -0
- package/skills/dataviz/references/anti-patterns.md +119 -0
- package/skills/dataviz/references/choosing-a-form.md +57 -0
- package/skills/dataviz/references/color-formula.md +113 -0
- package/skills/dataviz/references/components.md +39 -0
- package/skills/dataviz/references/interaction.md +60 -0
- package/skills/dataviz/references/marks-and-anatomy.md +97 -0
- package/skills/dataviz/references/palette.md +149 -0
- package/skills/dataviz/scripts/validate_palette.js +262 -0
- package/skills/find-skills.md +148 -0
- package/skills/init.md +28 -0
- package/skills/keybindings-help.md +294 -0
- package/skills/loop.md +50 -0
- package/skills/run-skill-generator.md +493 -0
- package/skills/run.md +148 -0
- package/skills/schedule.md +48 -0
- package/skills/security-review.md +181 -0
- package/skills/simplify.md +64 -0
- package/skills/update-config.md +93 -0
- package/skills/verify.md +334 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-review
|
|
3
|
+
description: Complete a security review of the pending changes on the current branch — high-confidence, exploitable findings only, with severity, exploit scenario, and fix recommendation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are a senior security engineer conducting a focused security review of the changes on this branch.
|
|
7
|
+
|
|
8
|
+
## Gather the change set
|
|
9
|
+
|
|
10
|
+
Run these and read the output before analyzing:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
git status
|
|
14
|
+
git diff --name-only origin/HEAD... # files modified
|
|
15
|
+
git log --no-decorate origin/HEAD... # commits
|
|
16
|
+
git diff origin/HEAD... # the full diff under review
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
(No upstream/origin? Use `main...HEAD` or `HEAD~1`, and include
|
|
20
|
+
`git diff HEAD` if there are uncommitted changes.) The diff is the
|
|
21
|
+
complete review scope.
|
|
22
|
+
|
|
23
|
+
OBJECTIVE:
|
|
24
|
+
Perform a security-focused code review to identify HIGH-CONFIDENCE security vulnerabilities that could have real exploitation potential. This is not a general code review - focus ONLY on security implications newly added by this change set. Do not comment on existing security concerns.
|
|
25
|
+
|
|
26
|
+
CRITICAL INSTRUCTIONS:
|
|
27
|
+
1. MINIMIZE FALSE POSITIVES: Only flag issues where you're >80% confident of actual exploitability
|
|
28
|
+
2. AVOID NOISE: Skip theoretical issues, style concerns, or low-impact findings
|
|
29
|
+
3. FOCUS ON IMPACT: Prioritize vulnerabilities that could lead to unauthorized access, data breaches, or system compromise
|
|
30
|
+
4. EXCLUSIONS: Do NOT report the following issue types:
|
|
31
|
+
- Denial of Service (DOS) vulnerabilities, even if they allow service disruption
|
|
32
|
+
- Secrets or sensitive data stored on disk (these are handled by other processes)
|
|
33
|
+
- Rate limiting or resource exhaustion issues
|
|
34
|
+
|
|
35
|
+
SECURITY CATEGORIES TO EXAMINE:
|
|
36
|
+
|
|
37
|
+
**Input Validation Vulnerabilities:**
|
|
38
|
+
- SQL injection via unsanitized user input
|
|
39
|
+
- Command injection in system calls or subprocesses
|
|
40
|
+
- XXE injection in XML parsing
|
|
41
|
+
- Template injection in templating engines
|
|
42
|
+
- NoSQL injection in database queries
|
|
43
|
+
- Path traversal in file operations
|
|
44
|
+
|
|
45
|
+
**Authentication & Authorization Issues:**
|
|
46
|
+
- Authentication bypass logic
|
|
47
|
+
- Privilege escalation paths
|
|
48
|
+
- Session management flaws
|
|
49
|
+
- JWT token vulnerabilities
|
|
50
|
+
- Authorization logic bypasses
|
|
51
|
+
|
|
52
|
+
**Crypto & Secrets Management:**
|
|
53
|
+
- Hardcoded API keys, passwords, or tokens
|
|
54
|
+
- Weak cryptographic algorithms or implementations
|
|
55
|
+
- Improper key storage or management
|
|
56
|
+
- Cryptographic randomness issues
|
|
57
|
+
- Certificate validation bypasses
|
|
58
|
+
|
|
59
|
+
**Injection & Code Execution:**
|
|
60
|
+
- Remote code execution via deserialization
|
|
61
|
+
- Pickle injection in Python
|
|
62
|
+
- YAML deserialization vulnerabilities
|
|
63
|
+
- Eval injection in dynamic code execution
|
|
64
|
+
- XSS vulnerabilities in web applications (reflected, stored, DOM-based)
|
|
65
|
+
|
|
66
|
+
**Data Exposure:**
|
|
67
|
+
- Sensitive data logging or storage
|
|
68
|
+
- PII handling violations
|
|
69
|
+
- API endpoint data leakage
|
|
70
|
+
- Debug information exposure
|
|
71
|
+
|
|
72
|
+
Additional notes:
|
|
73
|
+
- Even if something is only exploitable from the local network, it can still be a HIGH severity issue
|
|
74
|
+
|
|
75
|
+
ANALYSIS METHODOLOGY:
|
|
76
|
+
|
|
77
|
+
Phase 1 - Repository Context Research (use file search tools):
|
|
78
|
+
- Identify existing security frameworks and libraries in use
|
|
79
|
+
- Look for established secure coding patterns in the codebase
|
|
80
|
+
- Examine existing sanitization and validation patterns
|
|
81
|
+
- Understand the project's security model and threat model
|
|
82
|
+
|
|
83
|
+
Phase 2 - Comparative Analysis:
|
|
84
|
+
- Compare new code changes against existing security patterns
|
|
85
|
+
- Identify deviations from established secure practices
|
|
86
|
+
- Look for inconsistent security implementations
|
|
87
|
+
- Flag code that introduces new attack surfaces
|
|
88
|
+
|
|
89
|
+
Phase 3 - Vulnerability Assessment:
|
|
90
|
+
- Examine each modified file for security implications
|
|
91
|
+
- Trace data flow from user inputs to sensitive operations
|
|
92
|
+
- Look for privilege boundaries being crossed unsafely
|
|
93
|
+
- Identify injection points and unsafe deserialization
|
|
94
|
+
|
|
95
|
+
REQUIRED OUTPUT FORMAT:
|
|
96
|
+
|
|
97
|
+
You MUST output your findings in markdown. The markdown output should contain the file, line number, severity, category (e.g. `sql_injection` or `xss`), description, exploit scenario, and fix recommendation.
|
|
98
|
+
|
|
99
|
+
For example:
|
|
100
|
+
|
|
101
|
+
# Vuln 1: XSS: `foo.py:42`
|
|
102
|
+
|
|
103
|
+
* Severity: High
|
|
104
|
+
* Description: User input from `username` parameter is directly interpolated into HTML without escaping, allowing reflected XSS attacks
|
|
105
|
+
* Exploit Scenario: Attacker crafts URL like /bar?q=<script>alert(document.cookie)</script> to execute JavaScript in victim's browser, enabling session hijacking or data theft
|
|
106
|
+
* Recommendation: Use the framework's escaping function or templates with auto-escaping enabled for all user inputs rendered in HTML
|
|
107
|
+
|
|
108
|
+
SEVERITY GUIDELINES:
|
|
109
|
+
- **HIGH**: Directly exploitable vulnerabilities leading to RCE, data breach, or authentication bypass
|
|
110
|
+
- **MEDIUM**: Vulnerabilities requiring specific conditions but with significant impact
|
|
111
|
+
- **LOW**: Defense-in-depth issues or lower-impact vulnerabilities
|
|
112
|
+
|
|
113
|
+
CONFIDENCE SCORING:
|
|
114
|
+
- 0.9-1.0: Certain exploit path identified, tested if possible
|
|
115
|
+
- 0.8-0.9: Clear vulnerability pattern with known exploitation methods
|
|
116
|
+
- 0.7-0.8: Suspicious pattern requiring specific conditions to exploit
|
|
117
|
+
- Below 0.7: Don't report (too speculative)
|
|
118
|
+
|
|
119
|
+
FINAL REMINDER:
|
|
120
|
+
Focus on HIGH and MEDIUM findings only. Better to miss some theoretical issues than flood the report with false positives. Each finding should be something a security engineer would confidently raise in a PR review.
|
|
121
|
+
|
|
122
|
+
FALSE POSITIVE FILTERING:
|
|
123
|
+
|
|
124
|
+
> You do not need to run commands to reproduce the vulnerability, just read the code to determine if it is a real vulnerability. Do not use the shell tool or write to any files.
|
|
125
|
+
>
|
|
126
|
+
> HARD EXCLUSIONS - Automatically exclude findings matching these patterns:
|
|
127
|
+
> 1. Denial of Service (DOS) vulnerabilities or resource exhaustion attacks.
|
|
128
|
+
> 2. Secrets or credentials stored on disk if they are otherwise secured.
|
|
129
|
+
> 3. Rate limiting concerns or service overload scenarios.
|
|
130
|
+
> 4. Memory consumption or CPU exhaustion issues.
|
|
131
|
+
> 5. Lack of input validation on non-security-critical fields without proven security impact.
|
|
132
|
+
> 6. Input sanitization concerns for CI workflow files unless they are clearly triggerable via untrusted input.
|
|
133
|
+
> 7. A lack of hardening measures. Code is not expected to implement all security best practices, only flag concrete vulnerabilities.
|
|
134
|
+
> 8. Race conditions or timing attacks that are theoretical rather than practical issues. Only report a race condition if it is concretely problematic.
|
|
135
|
+
> 9. Vulnerabilities related to outdated third-party libraries. These are managed separately and should not be reported here.
|
|
136
|
+
> 10. Memory safety issues such as buffer overflows or use-after-free vulnerabilities are impossible in Rust. Do not report memory safety issues in Rust or any other memory safe languages.
|
|
137
|
+
> 11. Files that are only unit tests or only used as part of running tests.
|
|
138
|
+
> 12. Log spoofing concerns. Outputting un-sanitized user input to logs is not a vulnerability.
|
|
139
|
+
> 13. SSRF vulnerabilities that only control the path. SSRF is only a concern if it can control the host or protocol.
|
|
140
|
+
> 14. Including user-controlled content in AI system prompts is not a vulnerability.
|
|
141
|
+
> 15. Regex injection. Injecting untrusted content into a regex is not a vulnerability.
|
|
142
|
+
> 16. Regex DOS concerns.
|
|
143
|
+
> 17. Insecure documentation. Do not report any findings in documentation files such as markdown files.
|
|
144
|
+
> 18. A lack of audit logs is not a vulnerability.
|
|
145
|
+
>
|
|
146
|
+
> PRECEDENTS -
|
|
147
|
+
> 1. Logging high value secrets in plaintext is a vulnerability. Logging URLs is assumed to be safe.
|
|
148
|
+
> 2. UUIDs can be assumed to be unguessable and do not need to be validated.
|
|
149
|
+
> 3. Environment variables and CLI flags are trusted values. Attackers are generally not able to modify them in a secure environment. Any attack that relies on controlling an environment variable is invalid.
|
|
150
|
+
> 4. Resource management issues such as memory or file descriptor leaks are not valid.
|
|
151
|
+
> 5. Subtle or low impact web vulnerabilities such as tabnabbing, XS-Leaks, prototype pollution, and open redirects should not be reported unless they are extremely high confidence.
|
|
152
|
+
> 6. React and Angular are generally secure against XSS. These frameworks do not need to sanitize or escape user input unless it is using dangerouslySetInnerHTML, bypassSecurityTrustHtml, or similar methods. Do not report XSS vulnerabilities in React or Angular components or tsx files unless they are using unsafe methods.
|
|
153
|
+
> 7. Most vulnerabilities in CI workflow files are not exploitable in practice. Before validating a CI workflow vulnerability ensure it is concrete and has a very specific attack path.
|
|
154
|
+
> 8. A lack of permission checking or authentication in client-side JS/TS code is not a vulnerability. Client-side code is not trusted and does not need to implement these checks, they are handled on the server-side. The same applies to all flows that send untrusted data to the backend, the backend is responsible for validating and sanitizing all inputs.
|
|
155
|
+
> 9. Only include MEDIUM findings if they are obvious and concrete issues.
|
|
156
|
+
> 10. Most vulnerabilities in notebook files (*.ipynb) are not exploitable in practice. Before validating a notebook vulnerability ensure it is concrete and has a very specific attack path where untrusted input can trigger the vulnerability.
|
|
157
|
+
> 11. Logging non-PII data is not a vulnerability even if the data may be sensitive. Only report logging vulnerabilities if they expose sensitive information such as secrets, passwords, or personally identifiable information (PII).
|
|
158
|
+
> 12. Command injection vulnerabilities in shell scripts are generally not exploitable in practice since shell scripts generally do not run with untrusted user input. Only report command injection vulnerabilities in shell scripts if they are concrete and have a very specific attack path for untrusted input.
|
|
159
|
+
>
|
|
160
|
+
> SIGNAL QUALITY CRITERIA - For remaining findings, assess:
|
|
161
|
+
> 1. Is there a concrete, exploitable vulnerability with a clear attack path?
|
|
162
|
+
> 2. Does this represent a real security risk vs theoretical best practice?
|
|
163
|
+
> 3. Are there specific code locations and reproduction steps?
|
|
164
|
+
> 4. Would this finding be actionable for a security team?
|
|
165
|
+
>
|
|
166
|
+
> For each finding, assign a confidence score from 1-10:
|
|
167
|
+
> - 1-3: Low confidence, likely false positive or noise
|
|
168
|
+
> - 4-6: Medium confidence, needs investigation
|
|
169
|
+
> - 7-10: High confidence, likely true vulnerability
|
|
170
|
+
|
|
171
|
+
START ANALYSIS:
|
|
172
|
+
|
|
173
|
+
Begin your analysis now. Do this in 3 steps:
|
|
174
|
+
|
|
175
|
+
1. Use a subagent (e.g. the Task tool) to identify vulnerabilities. It should use the repository exploration tools to understand the codebase context, then analyze the changes for security implications. In the prompt for this subagent, include all of the above.
|
|
176
|
+
2. Then for each vulnerability identified by the above subagent, create a new subagent to filter out false-positives. Launch these subagents in parallel. In the prompt for these subagents, include everything in the "FALSE POSITIVE FILTERING" instructions.
|
|
177
|
+
3. Filter out any vulnerabilities where the subagent reported a confidence less than 8.
|
|
178
|
+
|
|
179
|
+
If subagents are unavailable in this session, do the same three passes yourself, strictly separating the find pass from the false-positive filtering pass.
|
|
180
|
+
|
|
181
|
+
Your final reply must contain the markdown report and nothing else.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: simplify
|
|
3
|
+
description: Review the changed code for reuse, simplification, efficiency, and altitude cleanups, then apply the fixes. Quality only — it does not hunt for bugs; use a code-review pass for that.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are improving the quality of the changed code, not hunting for bugs. Review
|
|
7
|
+
it for reuse, simplification, efficiency, and altitude issues, then fix what you
|
|
8
|
+
find. Do not look for correctness bugs — that is what a code-review pass is for.
|
|
9
|
+
|
|
10
|
+
## Phase 0 — Gather the diff
|
|
11
|
+
|
|
12
|
+
Run `git diff @{upstream}...HEAD` (or `git diff main...HEAD` / `git diff HEAD~1`
|
|
13
|
+
if there's no upstream) to get the unified diff under review. If there are
|
|
14
|
+
uncommitted changes, or the range diff is empty, also run `git diff HEAD` and
|
|
15
|
+
include the working-tree changes in scope — the review often runs before the
|
|
16
|
+
commit. If a branch name or file path was given as the target, review that
|
|
17
|
+
target instead. Treat this diff as the review scope.
|
|
18
|
+
|
|
19
|
+
## Phase 1 — Review (4 cleanup agents in parallel)
|
|
20
|
+
|
|
21
|
+
Launch **4 independent review agents** via your subagent tool (e.g. Task), all
|
|
22
|
+
in a single message so they run concurrently. Pass each agent the diff and one
|
|
23
|
+
of the four angles below. Each returns its findings with `file`, `line`, a
|
|
24
|
+
one-line `summary`, and the concrete cost (what is duplicated, wasted, or
|
|
25
|
+
harder to maintain). If subagents are unavailable in this session, work the
|
|
26
|
+
four angles yourself, one at a time.
|
|
27
|
+
|
|
28
|
+
### Reuse
|
|
29
|
+
|
|
30
|
+
Flag new code that re-implements something the codebase
|
|
31
|
+
already has — grep shared/utility modules and files adjacent to the change,
|
|
32
|
+
and name the existing helper to call instead.
|
|
33
|
+
|
|
34
|
+
### Simplification
|
|
35
|
+
|
|
36
|
+
Flag unnecessary complexity the diff adds: redundant or derivable state,
|
|
37
|
+
copy-paste with slight variation, deep nesting, dead code left behind. Name
|
|
38
|
+
the simpler form that does the same job.
|
|
39
|
+
|
|
40
|
+
### Efficiency
|
|
41
|
+
|
|
42
|
+
Flag wasted work the diff introduces: redundant computation or repeated I/O,
|
|
43
|
+
independent operations run sequentially, blocking work added to startup or
|
|
44
|
+
hot paths. Also flag long-lived objects built from closures or captured
|
|
45
|
+
environments — they keep the entire enclosing scope alive for the object's
|
|
46
|
+
lifetime (a memory leak when that scope holds large values); prefer a
|
|
47
|
+
class/struct that copies only the fields it needs. Name the cheaper
|
|
48
|
+
alternative.
|
|
49
|
+
|
|
50
|
+
### Altitude
|
|
51
|
+
|
|
52
|
+
Check that each change is implemented at the right depth, not as a fragile
|
|
53
|
+
bandaid. Special cases layered on shared infrastructure are a sign the fix
|
|
54
|
+
isn't deep enough — prefer generalizing the underlying mechanism over adding
|
|
55
|
+
special cases.
|
|
56
|
+
|
|
57
|
+
## Phase 2 — Apply the fixes
|
|
58
|
+
|
|
59
|
+
Wait for all four agents to complete, dedup findings that point at the same
|
|
60
|
+
line or mechanism, and fix each remaining one directly. Skip any finding whose
|
|
61
|
+
fix would change intended behavior, require changes well outside the reviewed
|
|
62
|
+
diff, or that you judge to be a false positive — note the skip rather than
|
|
63
|
+
arguing with it. Finish with a brief summary of what was fixed and what was
|
|
64
|
+
skipped (or confirm the code was already clean).
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: update-config
|
|
3
|
+
description: Use this skill to configure sema via its settings files. Automated behaviors ("from now on when X", "each time X", "whenever X", "before/after X") require hooks configured in settings files - the harness executes these, not the model, so memory/preferences cannot fulfill them. Also use for permissions ("allow X", "add permission", "move permission to"), env vars ("set X=Y"), model catalog changes (config.d/models.json), hook troubleshooting, or any changes to settings.json/settings.local.json files.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Updating sema configuration
|
|
7
|
+
|
|
8
|
+
sema is configured through layered JSON settings files plus a model catalog. This skill covers where each file lives, which layer wins, what the schema accepts, and the safety rules the resolver enforces.
|
|
9
|
+
|
|
10
|
+
## Config home directory
|
|
11
|
+
|
|
12
|
+
All user-level configuration lives under the sema config home, resolved in this priority order:
|
|
13
|
+
|
|
14
|
+
1. `SEMA_CONFIG_DIR` env var (explicit override)
|
|
15
|
+
2. `CLAUDE_CONFIG_DIR` env var (upstream-CLI compatibility fallback)
|
|
16
|
+
3. `~/.sema` — the default. sema does NOT silently read `~/.claude`; users migrating from the upstream CLI import explicitly with `sema config sync` (idempotent; `--project`, `--merge`, `--overwrite`, `--dry-run` supported). Setting `SEMA_CLAUDE_FALLBACK=1` opts back in to automatic `~/.claude` reads.
|
|
17
|
+
|
|
18
|
+
Below, `<config-home>` means the directory resolved above.
|
|
19
|
+
|
|
20
|
+
## Settings file locations and precedence
|
|
21
|
+
|
|
22
|
+
Choose the file by scope. Later layers override earlier ones on value conflicts:
|
|
23
|
+
|
|
24
|
+
| Precedence | Layer | File | Git | Use for |
|
|
25
|
+
|---|---|---|---|---|
|
|
26
|
+
| 1 (lowest) | userSettings | `<config-home>/settings.json` | N/A | Personal preferences for all projects |
|
|
27
|
+
| 2 | projectSettings | `<project>/.claude/settings.json` | Commit | Team-wide hooks, permissions, env |
|
|
28
|
+
| 3 | localSettings | `<project>/.claude/settings.local.json` | Gitignore | Personal overrides for this project |
|
|
29
|
+
| 4 | flagSettings | `--settings <file>` CLI flag | N/A | One-shot launch overrides |
|
|
30
|
+
| 5 (highest) | policySettings | `managed-settings.json` + `managed-settings.d/*.json` (admin-owned), or remote managed settings | N/A | Managed/MDM policy ceiling |
|
|
31
|
+
|
|
32
|
+
Project-scoped files intentionally keep the `.claude/` directory name for upstream ecosystem compatibility.
|
|
33
|
+
|
|
34
|
+
## Trust model (independent of precedence)
|
|
35
|
+
|
|
36
|
+
sema separates "whose value wins" (precedence above) from "who is allowed to set a key" (trust). Trust per layer: userSettings = `global`, projectSettings = `project`, localSettings and `--settings` flag = `local`, policySettings = `managed`. The resolver fails CLOSED with an error (never silently applies) when:
|
|
37
|
+
|
|
38
|
+
- **SettingsTrustViolation** — a layer sets a key above its trust ceiling (e.g. a committed project file trying to set a global-trust security key).
|
|
39
|
+
- **OverrideLockViolation** — a tighten-only key would be LOOSENED by a later layer. Permission denies fold deny-first: a later `allow` can never widen back a capability an earlier layer denied.
|
|
40
|
+
- `permissionMode: "bypassPermissions"` in ANY settings file is rejected outright — bypass is a launch-flag-only mode, never file-configurable.
|
|
41
|
+
- `disableBypassPermissionsMode` and `disableAutoMode` are managed-only kill switches: only the policy layer may set them, and `true` (the strict pole) cannot be relaxed by lower layers.
|
|
42
|
+
|
|
43
|
+
When an edit you made produces one of these errors, move the key to a sufficiently trusted file instead of fighting the resolver.
|
|
44
|
+
|
|
45
|
+
## Settings schema
|
|
46
|
+
|
|
47
|
+
The core resolved units (`SemaSettings`):
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"permissions": {
|
|
52
|
+
"allow": ["Bash(npm:*)", "Read"],
|
|
53
|
+
"deny": ["Bash(rm -rf:*)"],
|
|
54
|
+
"ask": ["Write(/etc/*)"],
|
|
55
|
+
"defaultMode": "default" | "acceptEdits" | "plan",
|
|
56
|
+
"additionalDirectories": ["/extra/dir"],
|
|
57
|
+
"disableBypassPermissionsMode": true,
|
|
58
|
+
"disableAutoMode": true
|
|
59
|
+
},
|
|
60
|
+
"hooks": {
|
|
61
|
+
"PreToolUse": [{ "matcher": "Bash", "hooks": [{ "type": "command", "command": "./check.sh", "timeout": 30 }] }],
|
|
62
|
+
"PostToolUse": [],
|
|
63
|
+
"UserPromptSubmit": []
|
|
64
|
+
},
|
|
65
|
+
"env": { "DEBUG": "true" },
|
|
66
|
+
"model": "model-name",
|
|
67
|
+
"outputStyle": "style-name",
|
|
68
|
+
"webSearch": { "provider": "brave" | "tavily" | "searxng", "apiKey": "...", "endpoint": "...", "maxResults": 5 },
|
|
69
|
+
"ultracode": true
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Notes:
|
|
74
|
+
|
|
75
|
+
- **Permission rule syntax** is upstream-compatible: exact match `"Bash(npm run test)"`, prefix wildcard `"Bash(git:*)"`, tool-only `"Read"`.
|
|
76
|
+
- `webSearch` and `ultracode` are sema-only keys (no upstream equivalent).
|
|
77
|
+
- Settings files accept the wider upstream settings.json superset; unknown keys are tolerated, but the units above are what the sema resolver folds across layers.
|
|
78
|
+
|
|
79
|
+
## Model configuration (sema-specific)
|
|
80
|
+
|
|
81
|
+
Models are NOT configured via a bare `"model": "sonnet"` alias. Two channels, both under the user layer:
|
|
82
|
+
|
|
83
|
+
1. **Model catalog** — `<config-home>/config.d/models.json`: a multi-slot catalog of entries `{ name, id, api, baseUrl, apiKeyEnv, contextWindow, maxTokens }` where `api` is `"anthropic-messages"` or `"openai-completions"`. A catalog with enabled models REPLACES the env catalog, and the FIRST enabled entry is the default model. Secrets never go in this file: `apiKeyEnv` names an env var (convention `SEMA_MODEL_KEY_<ENTRY>`) whose value lives in the userSettings `env` block.
|
|
84
|
+
2. **Env two-slot fallback** — when no catalog exists, the settings `env` block drives models directly: `MODEL_ID` (main), `MODEL_CHEAP_ID` (cheap/summarize slot), `MODEL_API_KEY` (or `ANTHROPIC_AUTH_TOKEN`), `ANTHROPIC_BASE_URL` (anthropic-messages routes) or `MODEL_GATEWAY_BASEURL` (openai-completions routes), plus optional `MODEL_CONTEXT_WINDOW` / `MODEL_MAX_TOKENS`.
|
|
85
|
+
|
|
86
|
+
Prefer editing the catalog when it exists; only touch the env slots for catalog-less installs.
|
|
87
|
+
|
|
88
|
+
## How to apply a change
|
|
89
|
+
|
|
90
|
+
1. Pick the narrowest file that satisfies the scope and trust rules above.
|
|
91
|
+
2. Read the existing file first; merge your key in — never clobber unrelated keys.
|
|
92
|
+
3. Settings files are watched: edits hot-reload without a restart. If a change appears ignored, check for a resolver rejection (trust/tighten violation) before assuming a bug.
|
|
93
|
+
4. For "do X automatically every time Y" requests, configure a hook — do not promise behavior from memory.
|
package/skills/verify.md
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: verify
|
|
3
|
+
description: Verify that a code change actually does what it's supposed to by exercising it end-to-end and observing behavior — drive the affected flow, not just tests or typecheck. Run before committing nontrivial changes. Don't invoke it on a diff that only touches tests, docs, or other code with no runtime surface to drive (a change to product source always has one) — there's nothing to observe.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
**Verification is runtime observation.** You build the app, run it,
|
|
7
|
+
drive it to where the changed code executes, and capture what you
|
|
8
|
+
see. That capture is your evidence. Nothing else is.
|
|
9
|
+
|
|
10
|
+
**Don't run tests. Don't typecheck.** Running them here proves you
|
|
11
|
+
can run CI — not that the change works. Not as a warm-up,
|
|
12
|
+
not "just to be sure," not as a regression sweep after. The time
|
|
13
|
+
goes to running the app instead.
|
|
14
|
+
|
|
15
|
+
**Don't import-and-call.** `import { foo } from './src/...'` then
|
|
16
|
+
`console.log(foo(x))` is a unit test you wrote. The function did what
|
|
17
|
+
the function does — you knew that from reading it. The app never ran.
|
|
18
|
+
Whatever calls `foo` in the real codebase ends at a CLI, a socket, or
|
|
19
|
+
a window. Go there.
|
|
20
|
+
|
|
21
|
+
## Find the change
|
|
22
|
+
|
|
23
|
+
The scope is what you're verifying — usually a diff, sometimes just
|
|
24
|
+
"does X work." In a git repo, establish the full range (a branch may
|
|
25
|
+
be many commits, or the change may still be uncommitted):
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git log --oneline @{u}.. # count commits (if upstream set)
|
|
29
|
+
git diff @{u}.. --stat # full range, not HEAD~1
|
|
30
|
+
git diff origin/HEAD... --stat # no upstream: committed vs base
|
|
31
|
+
git diff HEAD --stat # uncommitted: working tree vs HEAD
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
State the commit count. Large diff truncating? Redirect to a file
|
|
35
|
+
then read it. Repo but no diff from any of these → say so, stop.
|
|
36
|
+
**No repo → the scope is whatever the user named; ask if they
|
|
37
|
+
didn't.**
|
|
38
|
+
|
|
39
|
+
**The diff is ground truth. Any description is a claim about it.**
|
|
40
|
+
Read both. If they disagree, that's a finding.
|
|
41
|
+
|
|
42
|
+
## Surface
|
|
43
|
+
|
|
44
|
+
The surface is where a user — human or programmatic — meets the
|
|
45
|
+
change. That's where you observe.
|
|
46
|
+
|
|
47
|
+
| Change reaches | Surface | You |
|
|
48
|
+
|---|---|---|
|
|
49
|
+
| CLI / TUI | terminal | type the command, capture the pane — see the CLI example below |
|
|
50
|
+
| Server / API | socket | send the request, capture the response — see the server example below |
|
|
51
|
+
| GUI | pixels | drive it headless (xvfb / a browser driver), screenshot |
|
|
52
|
+
| Library | package boundary | sample code through the public export — `import pkg`, not `import ./src/...` |
|
|
53
|
+
| Prompt / agent config | the agent | run the agent, capture its behavior |
|
|
54
|
+
| CI workflow | the CI system | dispatch it, read the run |
|
|
55
|
+
|
|
56
|
+
**Internal function? Not a surface.** Something in the repo calls it
|
|
57
|
+
and that caller ends at one of the rows above. Follow it there. A
|
|
58
|
+
shell security gate's surface isn't the function's return value — it's
|
|
59
|
+
the CLI prompting or auto-allowing when you type the command.
|
|
60
|
+
|
|
61
|
+
**No runtime surface at all** — docs-only, type declarations with no
|
|
62
|
+
emit, build config that produces no behavioral diff — report
|
|
63
|
+
**SKIP — no runtime surface: (reason).** Don't run tests to fill
|
|
64
|
+
the space.
|
|
65
|
+
|
|
66
|
+
**Tests in the diff are the author's evidence, not a surface.** CI
|
|
67
|
+
runs them. You'd be re-running CI. Tests-only change → SKIP, one line.
|
|
68
|
+
Mixed src+tests → verify the src, ignore the test files. Reading a
|
|
69
|
+
test to learn what to check is fine — it's a spec. But then go run
|
|
70
|
+
the app. Checking that assertions match source is code review.
|
|
71
|
+
|
|
72
|
+
## Get a handle
|
|
73
|
+
|
|
74
|
+
**Check your available skills first — even if you already know how to
|
|
75
|
+
build and run.** A skill that matches your surface (a verifier or
|
|
76
|
+
run recipe for this kind of app) is a verified path: follow its
|
|
77
|
+
setup. A stale recipe (fails on mechanics unrelated to the change)
|
|
78
|
+
→ note it; don't FAIL the change for recipe rot. Also check the
|
|
79
|
+
repo's own entry points: README, package.json scripts, Makefile,
|
|
80
|
+
docs.
|
|
81
|
+
|
|
82
|
+
- **A matching launch/verify recipe exists** → use its build/launch
|
|
83
|
+
primitives as your handle.
|
|
84
|
+
- **Nothing** → cold start from README/package.json/Makefile. Timebox
|
|
85
|
+
~15min. Stuck → BLOCKED with exactly where it stopped. Got
|
|
86
|
+
through → **persist what you learned** in your report: the exact
|
|
87
|
+
build/launch/drive commands that worked, the flows worth driving,
|
|
88
|
+
any gotchas — so the recipe can be captured as a project skill and
|
|
89
|
+
the next session skips this cold start.
|
|
90
|
+
|
|
91
|
+
## Drive it
|
|
92
|
+
|
|
93
|
+
Smallest path that makes the changed code execute:
|
|
94
|
+
|
|
95
|
+
- Changed a flag? Run with it.
|
|
96
|
+
- Changed a handler? Hit that route.
|
|
97
|
+
- Changed error handling? Trigger the error.
|
|
98
|
+
- Changed an internal function? Find the CLI command / request / render
|
|
99
|
+
that reaches it. Run that.
|
|
100
|
+
|
|
101
|
+
**Read your plan back before running.** If every step is build /
|
|
102
|
+
typecheck / run test file — you've planned a CI rerun, not a
|
|
103
|
+
verification. Find a step that reaches the surface or report BLOCKED.
|
|
104
|
+
|
|
105
|
+
**The verdict is table stakes. Your observations are the signal.**
|
|
106
|
+
A PASS with three sharp "hey, I noticed…" lines is worth more than a
|
|
107
|
+
bare PASS. You're the only reviewer who actually *ran* the thing —
|
|
108
|
+
anything that made you pause, work around, or go "huh" is information
|
|
109
|
+
the author doesn't have. Don't filter for "is this a bug." Filter for
|
|
110
|
+
"would I mention this if they were sitting next to me."
|
|
111
|
+
|
|
112
|
+
**End-to-end, through the real interface.** Pieces passing in
|
|
113
|
+
isolation doesn't mean the flow works — seams are where bugs hide.
|
|
114
|
+
If users click buttons, test by clicking buttons, not by curling the
|
|
115
|
+
API underneath.
|
|
116
|
+
|
|
117
|
+
**Destructive path?** If the change touches code that deletes,
|
|
118
|
+
publishes, sends, or writes outside the workspace and there's no
|
|
119
|
+
dry-run or safe target, don't drive it live. Verify what you can
|
|
120
|
+
around it and say which path you didn't exercise and why.
|
|
121
|
+
|
|
122
|
+
## Push on it
|
|
123
|
+
|
|
124
|
+
The claim checked out — that's the first half. Confirming is step
|
|
125
|
+
one, not the job. The description is what the author intended;
|
|
126
|
+
your value is what they didn't.
|
|
127
|
+
|
|
128
|
+
You know exactly what changed. Probe *around* it, at the same
|
|
129
|
+
surface you just drove:
|
|
130
|
+
|
|
131
|
+
- **New flag / option** → empty value, passed twice, combined with a
|
|
132
|
+
conflicting flag, typo'd (does the error name it?)
|
|
133
|
+
- **New handler / route** → wrong method, malformed body, missing
|
|
134
|
+
required field, oversized payload
|
|
135
|
+
- **Changed error path** → the adjacent errors it didn't touch —
|
|
136
|
+
did the refactor catch them too, or only the one in the diff?
|
|
137
|
+
- **Interactive / TUI** → Ctrl-C mid-op, resize the pane, paste
|
|
138
|
+
garbage, rapid-fire the key, Esc at the wrong moment
|
|
139
|
+
- **State / persistence** → do it twice, do it with stale state
|
|
140
|
+
underneath, do it in two sessions at once
|
|
141
|
+
- **Wander** → what's adjacent? What looked off while you were
|
|
142
|
+
confirming? Go back to it.
|
|
143
|
+
|
|
144
|
+
These aren't a checklist — pick the ones the change points at. Stop
|
|
145
|
+
when you've covered the obvious adjacents or hit something worth a
|
|
146
|
+
⚠️. A probe that finds nothing is still a step: "🔍 passed `--from ''`
|
|
147
|
+
→ clean `error: --from requires a value`, exit 2." That the author
|
|
148
|
+
didn't test it is exactly why it's worth knowing it holds.
|
|
149
|
+
|
|
150
|
+
Still not a test run. You're at the surface, typing what a user
|
|
151
|
+
would type wrong.
|
|
152
|
+
|
|
153
|
+
## Capture
|
|
154
|
+
|
|
155
|
+
Stdout, response bodies, screenshots, pane dumps. Captured output is
|
|
156
|
+
evidence; your memory isn't. Something unexpected? Don't route around
|
|
157
|
+
it — capture, note, decide if it's the change or the environment.
|
|
158
|
+
Unrelated breakage is a finding, not noise.
|
|
159
|
+
|
|
160
|
+
Shared process state (tmux, ports, lockfiles) — isolate. `tmux -L
|
|
161
|
+
name`, bind `:0`, `mktemp -d`. You share a namespace with your host.
|
|
162
|
+
|
|
163
|
+
## Report
|
|
164
|
+
|
|
165
|
+
Inline, final message:
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
## Verification: <one-line what changed>
|
|
169
|
+
|
|
170
|
+
**Verdict:** PASS | FAIL | BLOCKED | SKIP
|
|
171
|
+
|
|
172
|
+
**Claim:** <what it's supposed to do — your read of the diff and/or
|
|
173
|
+
the stated claim; note any mismatch>
|
|
174
|
+
|
|
175
|
+
**Method:** <how you got a handle — which recipe/skill, or cold
|
|
176
|
+
start; what you launched>
|
|
177
|
+
|
|
178
|
+
### Steps
|
|
179
|
+
|
|
180
|
+
Each step is one thing you did to the **running app** and what it
|
|
181
|
+
showed. Build/install/checkout are setup, not steps. Test runs and
|
|
182
|
+
typecheck don't belong here — they're CI's output.
|
|
183
|
+
|
|
184
|
+
1. ✅/❌/⚠️/🔍 <what you did to the running app> → <what you observed>
|
|
185
|
+
<evidence: the app's own output — pane capture, response body,
|
|
186
|
+
screenshot>
|
|
187
|
+
|
|
188
|
+
🔍 marks a probe — a step off the claim's happy path, trying to
|
|
189
|
+
break it. At least one. A Steps list that's all ✅ and no 🔍 is a
|
|
190
|
+
happy-path replay: still PASS, but you stopped at the first half.
|
|
191
|
+
|
|
192
|
+
**Screenshot / sample:** <the one frame a reviewer looks at to see
|
|
193
|
+
the feature — an image for GUI/TUI, code block for library/API;
|
|
194
|
+
omit for build/types-only>
|
|
195
|
+
|
|
196
|
+
### Findings
|
|
197
|
+
<Things you noticed. Not just bugs — friction, surprises, anything
|
|
198
|
+
a first-time user would trip on. "Took three tries to find the right
|
|
199
|
+
flag." "Error message on typo was unhelpful." "Default seems odd for
|
|
200
|
+
the common case." "Works, but slower than I expected." Lower the bar:
|
|
201
|
+
if it made you pause, it goes here. But the pause has to be yours,
|
|
202
|
+
from running the app — not from reading the change description. A red
|
|
203
|
+
CI check, a review comment, someone else's bot: visible to anyone
|
|
204
|
+
already, and you relaying it isn't an observation. Claim/diff
|
|
205
|
+
mismatch, pre-existing breakage, and env notes also belong.
|
|
206
|
+
|
|
207
|
+
Each probe gets a line here even when it held — "🔍 empty `--from`
|
|
208
|
+
→ clean error" tells the author what *was* covered, which they
|
|
209
|
+
can't see from a bare PASS.
|
|
210
|
+
|
|
211
|
+
Lead with ⚠️ for lines worth interrupting the reviewer for; plain
|
|
212
|
+
bullets are context. Empty is fine if nothing stuck out — but nothing
|
|
213
|
+
sticking out is itself rare.>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**Evidence has to reach the reader.** A file path is only evidence
|
|
217
|
+
if the person reading the report can open it. If the `SendUserFile`
|
|
218
|
+
tool is in your toolset, you're on a remote surface where they
|
|
219
|
+
can't — send the screenshots and recordings with it and let the
|
|
220
|
+
report name what you sent. Without it, reference the path and keep
|
|
221
|
+
the evidence that matters inline — pane captures and response
|
|
222
|
+
bodies travel in the report; a bare path only works when the reader
|
|
223
|
+
shares your filesystem.
|
|
224
|
+
|
|
225
|
+
**Verdicts:**
|
|
226
|
+
- **PASS** — you ran the app, the change did what it should at its
|
|
227
|
+
surface. Not: tests pass, builds clean, code looks right.
|
|
228
|
+
- **FAIL** — you ran it and it doesn't. Or it breaks something else.
|
|
229
|
+
Or claim and diff disagree materially.
|
|
230
|
+
- **BLOCKED** — couldn't reach a state where the change is observable.
|
|
231
|
+
Build broke, env missing a dep, handle wouldn't come up. Not a
|
|
232
|
+
verdict on the change. Never report an approach blocked or
|
|
233
|
+
impossible until you've checked the skills and recipes available
|
|
234
|
+
to you — environment-specific unlocks (headless runners, login
|
|
235
|
+
helpers, VM harnesses) usually live there. Say exactly where it
|
|
236
|
+
stopped.
|
|
237
|
+
- **SKIP** — no runtime surface exists. Docs-only, types-only,
|
|
238
|
+
tests-only. Nothing went wrong; there's just nothing here to run.
|
|
239
|
+
One line why.
|
|
240
|
+
|
|
241
|
+
No partial pass. "3 of 4 passed" is FAIL until 4 passes or is
|
|
242
|
+
explained away.
|
|
243
|
+
|
|
244
|
+
**When in doubt, FAIL.** False PASS ships broken code; false FAIL
|
|
245
|
+
costs one more human look. Ambiguous output is FAIL with the raw
|
|
246
|
+
capture attached — don't interpret.
|
|
247
|
+
|
|
248
|
+
## Appendix: verifying a CLI change
|
|
249
|
+
|
|
250
|
+
The handle is direct invocation. The evidence is stdout/stderr/exit code.
|
|
251
|
+
|
|
252
|
+
1. Build (if the CLI needs building)
|
|
253
|
+
2. Run with arguments that exercise the changed code
|
|
254
|
+
3. Capture output and exit code
|
|
255
|
+
4. Compare to expected
|
|
256
|
+
|
|
257
|
+
Worked example — **diff:** adds a `--json` flag to the `status`
|
|
258
|
+
subcommand. **Claim:** "machine-readable status output."
|
|
259
|
+
**Inference:** `tool status --json` now exists, emits valid JSON with
|
|
260
|
+
the same fields the human output shows; `tool status` without the
|
|
261
|
+
flag is unchanged.
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
go build -o /tmp/tool ./cmd/tool
|
|
265
|
+
|
|
266
|
+
/tmp/tool status
|
|
267
|
+
# → Status: healthy / Uptime: 3h12m / Connections: 47
|
|
268
|
+
|
|
269
|
+
/tmp/tool status --json
|
|
270
|
+
# → {"status":"healthy","uptime_seconds":11520,"connections":47}
|
|
271
|
+
|
|
272
|
+
/tmp/tool status --json | jq -e .status
|
|
273
|
+
# → "healthy" (jq -e exits nonzero if the path is null/false)
|
|
274
|
+
echo $?
|
|
275
|
+
# → 0
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**Verdict:** PASS — flag works, JSON is valid, fields line up.
|
|
279
|
+
|
|
280
|
+
What FAIL looks like: `unknown flag: --json` → not wired up, or a
|
|
281
|
+
stale build; output isn't valid JSON → serialization bug; `tool
|
|
282
|
+
status` (no flag) changed → regression; JSON field names differ from
|
|
283
|
+
expected → claim/code mismatch, note it.
|
|
284
|
+
|
|
285
|
+
If the CLI reads stdin → pipe in test data. If it writes files / hits
|
|
286
|
+
a network / deletes things → point it at a tmp dir / a mock / a
|
|
287
|
+
dry-run flag. No safe mode and the diff touches the destructive
|
|
288
|
+
path → say so and verify what you can around it.
|
|
289
|
+
|
|
290
|
+
## Appendix: verifying a server/API change
|
|
291
|
+
|
|
292
|
+
The handle is `curl` (or equivalent). The evidence is the response.
|
|
293
|
+
|
|
294
|
+
1. Start the server (background, with a readiness poll)
|
|
295
|
+
2. `curl` the route the diff touches, with inputs that hit the changed branch
|
|
296
|
+
3. Capture the full response (status + headers + body)
|
|
297
|
+
4. Compare to expected
|
|
298
|
+
|
|
299
|
+
Lifecycle, when no launch recipe exists:
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
<start-command> &> /tmp/server.log &
|
|
303
|
+
SERVER_PID=$!
|
|
304
|
+
for i in {1..30}; do curl -sf localhost:PORT/health >/dev/null && break; sleep 1; done
|
|
305
|
+
# ... your curls ...
|
|
306
|
+
kill $SERVER_PID
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
No readiness endpoint? Poll the route you're about to test until it
|
|
310
|
+
stops returning connection-refused, then add a beat.
|
|
311
|
+
|
|
312
|
+
Worked example — **diff:** adds a `Retry-After` header to 429
|
|
313
|
+
responses in `rateLimit.ts`. **Claim:** "clients can now back off
|
|
314
|
+
correctly." **Inference:** hitting the rate limit should now return
|
|
315
|
+
`Retry-After: <n>` in the response headers; it didn't before.
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
# trigger the limit — 10 fast requests, limit is 5/sec per the diff
|
|
319
|
+
for i in {1..10}; do curl -s -o /dev/null -w "%{http_code}\n" localhost:3000/api/thing; done
|
|
320
|
+
# → 200 200 200 200 200 429 429 429 429 429
|
|
321
|
+
|
|
322
|
+
# capture the 429 headers
|
|
323
|
+
curl -si localhost:3000/api/thing | head -20
|
|
324
|
+
# → HTTP/1.1 429 Too Many Requests
|
|
325
|
+
# → Retry-After: 12
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Verdict:** PASS — `Retry-After: 12` present, positive integer.
|
|
329
|
+
|
|
330
|
+
What FAIL looks like: header absent → the diff didn't take effect, or
|
|
331
|
+
you're not actually hitting the 429 path (check the status code
|
|
332
|
+
first); header present but `NaN` / `undefined` / negative → the logic
|
|
333
|
+
is wrong; 200s all the way through → you never triggered the changed
|
|
334
|
+
path — tighten the burst or check the limit config.
|