@yottameta/yotta-dev-mcp-plugin 0.0.0 → 0.2.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/.agents/plugins/marketplace.json +25 -0
- package/.claude-plugin/marketplace.json +25 -0
- package/LICENSE +21 -0
- package/README.md +107 -0
- package/mcp.json +12 -0
- package/package.json +13 -10
- package/plugin.json +20 -0
- package/skills/yotta-dev-mcp/LICENSE +21 -0
- package/skills/yotta-dev-mcp/NOTICE +7 -0
- package/skills/yotta-dev-mcp/SKILL.md +81 -0
- package/skills/yotta-dev-mcp/assets/banner.png +0 -0
- package/skills/yotta-dev-mcp/bin/yotta-dev-mcp.js +57 -0
- package/skills/yotta-dev-mcp/references/adapters.md +69 -0
- package/skills/yotta-dev-mcp/references/architecture-contract.md +256 -0
- package/skills/yotta-dev-mcp/references/tools.md +257 -0
- package/skills/yotta-dev-mcp/scripts/dev_adapters.py +609 -0
- package/skills/yotta-dev-mcp/scripts/dev_architecture.py +379 -0
- package/skills/yotta-dev-mcp/scripts/dev_common.py +144 -0
- package/skills/yotta-dev-mcp/scripts/dev_contract.py +830 -0
- package/skills/yotta-dev-mcp/scripts/dev_engine.py +1138 -0
- package/skills/yotta-dev-mcp/scripts/dev_impact.py +556 -0
- package/skills/yotta-dev-mcp/scripts/dev_model.py +435 -0
- package/skills/yotta-dev-mcp/scripts/dev_rules.py +25 -0
- package/skills/yotta-dev-mcp/scripts/dev_selftest.py +534 -0
- package/skills/yotta-dev-mcp/scripts/dev_verify.py +450 -0
- package/skills/yotta-dev-mcp/scripts/yotta_dev_mcp.py +659 -0
- package/skills/yotta-dev-mcp/server.json +20 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# Architecture contract and system model
|
|
2
|
+
|
|
3
|
+
`system_model` builds a deterministic model of a local repository and attaches
|
|
4
|
+
layer data from an optional architecture contract. Everything runs offline with
|
|
5
|
+
the Python standard library; no file is written.
|
|
6
|
+
|
|
7
|
+
## Contract file
|
|
8
|
+
|
|
9
|
+
Path: `.yotta/architecture.json`. Plain JSON, version `1`.
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"version": 1,
|
|
14
|
+
"project": "demo",
|
|
15
|
+
"layers": [
|
|
16
|
+
{"id": "core", "title": "Core", "paths": ["src/core/**"], "risk": "high"},
|
|
17
|
+
{"id": "api", "paths": ["src/api/**"]},
|
|
18
|
+
{"id": "ui", "paths": ["src/ui/**"]}
|
|
19
|
+
],
|
|
20
|
+
"rules": [
|
|
21
|
+
{
|
|
22
|
+
"id": "core-no-ui",
|
|
23
|
+
"type": "forbid-dependency",
|
|
24
|
+
"from": "core",
|
|
25
|
+
"to": "ui",
|
|
26
|
+
"severity": "high",
|
|
27
|
+
"claim": "core must not import ui"
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"boundaries": [
|
|
31
|
+
{"id": "public-api", "layer": "api", "paths": ["src/api/public/**"], "visibility": "public"}
|
|
32
|
+
],
|
|
33
|
+
"data_ownership": [
|
|
34
|
+
{"store": "memory-db", "owner": "core", "paths": ["var/memory/**"], "kind": "sqlite"}
|
|
35
|
+
],
|
|
36
|
+
"invariants": [
|
|
37
|
+
{"id": "no-plaintext-secrets", "claim": "secrets are never stored in plaintext",
|
|
38
|
+
"severity": "high", "check": "static"}
|
|
39
|
+
],
|
|
40
|
+
"risk_weights": {"core": 3, "api": 2, "ui": 1}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Fields
|
|
45
|
+
|
|
46
|
+
| Field | Required | Notes |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `version` | yes | Must be `1`. |
|
|
49
|
+
| `project` | no | Free-form name. |
|
|
50
|
+
| `layers` | yes | Layer id, optional title/description, `paths` globs, optional `risk`. |
|
|
51
|
+
| `rules` | no | `forbid-dependency` (`to` is one layer) or `allow-dependency` (`to` is a layer list). `from`, `to`, `severity` and `claim` describe the invariant. |
|
|
52
|
+
| `boundaries` | no | Layer id plus globs; `visibility` is `public`, `internal` or `private`. |
|
|
53
|
+
| `data_ownership` | no | Store id, owning layer, globs and optional `kind`. |
|
|
54
|
+
| `invariants` | no | id plus a non-empty `claim`; `check` is `static`, `command` or `manual`. |
|
|
55
|
+
| `risk_weights` | no | Layer id to a number between 0 and 5. |
|
|
56
|
+
|
|
57
|
+
Ids match `[a-z0-9][a-z0-9._-]{0,63}`. Paths are repository-relative POSIX
|
|
58
|
+
globs and must not be absolute or contain `..`.
|
|
59
|
+
|
|
60
|
+
### Glob rules
|
|
61
|
+
|
|
62
|
+
`*` stays inside one path segment, `**` crosses segments, `?` matches one
|
|
63
|
+
character, and a trailing `/` means the whole directory (`pkg/` equals
|
|
64
|
+
`pkg/**`). Matching is case-sensitive. Layers are evaluated in declaration
|
|
65
|
+
order and the first match wins; a module that matches several layers is
|
|
66
|
+
reported as `layer-overlap`.
|
|
67
|
+
|
|
68
|
+
### Validation findings
|
|
69
|
+
|
|
70
|
+
Every finding carries `code`, `severity`, `message`, a JSON `pointer`, the
|
|
71
|
+
contract `path` and short `evidence`. Severity `critical` or `high` makes the
|
|
72
|
+
contract `FAIL`; `medium` and `low` are advisory.
|
|
73
|
+
|
|
74
|
+
| Code | Meaning |
|
|
75
|
+
|---|---|
|
|
76
|
+
| `contract-invalid-json` | The file is not valid JSON. |
|
|
77
|
+
| `contract-not-object` | The root value is not a JSON object. |
|
|
78
|
+
| `contract-unsupported-version` | `version` is missing or not `1`. |
|
|
79
|
+
| `contract-invalid-layer` / `contract-duplicate-layer` | Layer shape or ids are wrong. |
|
|
80
|
+
| `contract-layer-without-paths` | A layer declares no globs. |
|
|
81
|
+
| `contract-invalid-path` | A glob is absolute, escapes the root, or is empty. |
|
|
82
|
+
| `contract-invalid-rule` / `contract-duplicate-rule` | Rule shape, type or ids are wrong. |
|
|
83
|
+
| `contract-invalid-severity` / `contract-invalid-risk` | Enum values are outside the allowed set. |
|
|
84
|
+
| `contract-unknown-layer-ref` | A rule, boundary, store or risk weight points at a missing layer. |
|
|
85
|
+
| `contract-invalid-boundary` / `contract-invalid-store` / `contract-invalid-invariant` | Section entries are malformed. |
|
|
86
|
+
| `contract-unknown-key` | Unknown top-level key; reported as a warning and ignored. |
|
|
87
|
+
|
|
88
|
+
## system_model output
|
|
89
|
+
|
|
90
|
+
| Key | Content |
|
|
91
|
+
|---|---|
|
|
92
|
+
| `status` | `PASS`, `FAIL` (contract has blocking findings) or `UNKNOWN` (something still needs evidence). |
|
|
93
|
+
| `contract` | Path, presence, validity, version, layer and rule ids, findings. |
|
|
94
|
+
| `model.modules` | Repository-relative module id, language, line count and resolved layer. |
|
|
95
|
+
| `model.layers` | Declared layers with the modules that match them. |
|
|
96
|
+
| `model.imports` | `source`, `target`, `kind`, `line` and the raw specifier. |
|
|
97
|
+
| `model.entrypoints` | Files that look like executable entrypoints. |
|
|
98
|
+
| `model.tests` | Test files and the internal modules they import. |
|
|
99
|
+
| `model.configs` | Configuration files with a coarse kind. |
|
|
100
|
+
| `model.data_stores` | Declared stores (with owner and owner modules) and detected local database files. |
|
|
101
|
+
| `unknowns` | `contract-missing`, `contract-invalid`, `unassigned-module`, `layer-overlap`, `unresolved-import`. |
|
|
102
|
+
| `unverified_claims` | Verification levels that were not executed, with the reason. |
|
|
103
|
+
| `evidence` | Bounded, sorted evidence lines for the findings above. |
|
|
104
|
+
| `truncated` | True when the file limit cut the scan short. |
|
|
105
|
+
| `model_digest` | `sha256:` digest of the model, stable across runs on the same tree. |
|
|
106
|
+
|
|
107
|
+
Import kinds: `internal` (another source module), `internal-file` (a
|
|
108
|
+
repository file that is not source, such as `package.json`), `external`
|
|
109
|
+
(outside the repository) and `unresolved` (a relative path that does not
|
|
110
|
+
exist; also listed under `unknowns`).
|
|
111
|
+
|
|
112
|
+
`system_model` never asserts that a change is safe. Levels `L1` and above stay
|
|
113
|
+
listed in `unverified_claims` until a dedicated check runs them.
|
|
114
|
+
|
|
115
|
+
## architecture_review
|
|
116
|
+
|
|
117
|
+
`architecture_review` evaluates the same contract against the same system model and
|
|
118
|
+
returns every finding with file, line and severity. Per-item status is `PASS`,
|
|
119
|
+
`WARN` (advisory findings only), `FAIL` or `UNKNOWN`.
|
|
120
|
+
|
|
121
|
+
| Code | Meaning | Severity |
|
|
122
|
+
|---|---|---|
|
|
123
|
+
| `rule-forbid-dependency` | a module in the rule's `from` layer imports the forbidden `to` layer | the rule's severity |
|
|
124
|
+
| `rule-allow-dependency` | a module in the rule's `from` layer imports a layer outside `to` | the rule's severity |
|
|
125
|
+
| `boundary-visibility` | a module imports a protected boundary it may not reach | `high` for `private`, `medium` for `internal` |
|
|
126
|
+
| `data-ownership-mismatch` | a module inside the store paths is not in the owner layer | `medium` |
|
|
127
|
+
| `data-store-access-outside-owner` | a module outside the owner layer references the store path | `medium` |
|
|
128
|
+
|
|
129
|
+
Boundary visibility decides who may import the protected modules:
|
|
130
|
+
|
|
131
|
+
- `public` - any layer may import them; the declaration is recorded and never a finding.
|
|
132
|
+
- `internal` - only modules of the same layer may import them.
|
|
133
|
+
- `private` - only modules inside the boundary globs may import them.
|
|
134
|
+
|
|
135
|
+
Data ownership is checked in two ways: modules that live inside a store's paths but
|
|
136
|
+
belong to another layer, and modules outside the owner layer that reference the
|
|
137
|
+
store path literal (the part before the first wildcard).
|
|
138
|
+
|
|
139
|
+
Invariants are never reported as passing. `static`, `command` and `manual` checks
|
|
140
|
+
all land in `unverified_claims` with the reason, so a review can be `PASS` while
|
|
141
|
+
still stating what it did not verify.
|
|
142
|
+
|
|
143
|
+
The overall status is `FAIL` when the contract has blocking findings or any
|
|
144
|
+
violation reaches `critical` / `high`; `UNKNOWN` when the contract is missing or
|
|
145
|
+
anything stays undecided; otherwise `PASS` (advisory findings may still be listed).
|
|
146
|
+
|
|
147
|
+
### Unknown kinds
|
|
148
|
+
|
|
149
|
+
| Kind | Meaning |
|
|
150
|
+
|---|---|
|
|
151
|
+
| `contract-missing` / `contract-invalid` | no usable contract was found. |
|
|
152
|
+
| `model-truncated` | the file limit cut the scan short. |
|
|
153
|
+
| `unassigned-module` / `layer-overlap` | a module has no layer or matches several. |
|
|
154
|
+
| `unresolved-import` | a relative import does not resolve. |
|
|
155
|
+
| `rule-target-unassigned` | the rule's source layer matches, but the target module has no layer. |
|
|
156
|
+
| `boundary-no-modules` | the boundary globs match no module. |
|
|
157
|
+
| `boundary-importer-unassigned` | the importer has no layer, so visibility is undecided. |
|
|
158
|
+
|
|
159
|
+
## impact_analysis
|
|
160
|
+
|
|
161
|
+
`impact_analysis` starts from changed files, a unified diff or target symbols and
|
|
162
|
+
walks reverse dependencies (internal imports and repository-file imports) into a
|
|
163
|
+
bounded cone. Each node carries `depth`, `via`, `line`, `layer` and `is_test`.
|
|
164
|
+
|
|
165
|
+
Alongside the cone it reports direct consumers, affected layers, boundaries, data
|
|
166
|
+
stores, invariants scoped to the changed paths, tests mapped to the cone, the
|
|
167
|
+
architecture violations that fall inside the cone, rollback probes and an
|
|
168
|
+
explainable blast radius.
|
|
169
|
+
|
|
170
|
+
| Blast radius factor | Weight | When |
|
|
171
|
+
|---|---|---|
|
|
172
|
+
| `layer-risk` | 0-5 | highest declared risk weight or risk level of affected layers |
|
|
173
|
+
| `layer-count` | +1 / +2 | 3-4 layers / 5 or more layers are affected |
|
|
174
|
+
| `cone-depth` | +1 | the consumer chain reaches depth 2 or more |
|
|
175
|
+
| `public-boundary` | +1 | a public boundary is inside the cone |
|
|
176
|
+
| `data-store` | +1 per store, capped at 2 | declared or detected stores are touched |
|
|
177
|
+
| `architecture-violation` | +2 / +3 | a `high` / `critical` violation is inside the cone |
|
|
178
|
+
|
|
179
|
+
`level` maps the capped score (10 max): 9-10 `critical`, 6-8 `high`, 3-5 `medium`,
|
|
180
|
+
otherwise `low`. `score` is the raw sum of the weights and `reasons` lists every
|
|
181
|
+
factor with its detail, so the number can be recomputed by hand.
|
|
182
|
+
|
|
183
|
+
Rollback probes are derived, not invented: `data-store` (affected stores),
|
|
184
|
+
`entrypoint` (non-test entrypoints in the cone, capped at 5), `tests` (mapped test
|
|
185
|
+
files), `invariant` (declared `command` checks) and `model` (fallback when the cone
|
|
186
|
+
has no anchor). Test files that only guard on `__main__` are covered by the test
|
|
187
|
+
probe and are not reported as startup entrypoints.
|
|
188
|
+
|
|
189
|
+
## verification policy
|
|
190
|
+
|
|
191
|
+
`.yotta/verification.json` is optional. It declares the L2-L4 checks that
|
|
192
|
+
`verify_change` may execute, plus manual work that must stay unverified. It never
|
|
193
|
+
holds shell strings: `kind` must be one of the whitelisted runners already supported
|
|
194
|
+
by `run_checks`.
|
|
195
|
+
|
|
196
|
+
```json
|
|
197
|
+
{
|
|
198
|
+
"version": 1,
|
|
199
|
+
"checks": [
|
|
200
|
+
{
|
|
201
|
+
"id": "unit-tests",
|
|
202
|
+
"level": "L2",
|
|
203
|
+
"kind": "python-unittest",
|
|
204
|
+
"cwd": ".",
|
|
205
|
+
"timeout": 120,
|
|
206
|
+
"required": true,
|
|
207
|
+
"claim": "the unit suite passes"
|
|
208
|
+
}
|
|
209
|
+
],
|
|
210
|
+
"manual": [
|
|
211
|
+
{"id": "independent-review", "claim": "a second person reviews the change"}
|
|
212
|
+
]
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
| Field | Required | Notes |
|
|
217
|
+
|---|---|---|
|
|
218
|
+
| `version` | yes | Must be `1`. |
|
|
219
|
+
| `checks` | no | Array of L2-L4 checks. |
|
|
220
|
+
| `checks[].id` | yes | Unique slug matching the same id rule as the architecture contract. |
|
|
221
|
+
| `checks[].level` | yes | `L2`, `L3` or `L4`. |
|
|
222
|
+
| `checks[].kind` | yes | `python-unittest`, `pytest`, `python-compile`, `npm-test` or `npm-lint`. |
|
|
223
|
+
| `checks[].cwd` | no | Repository-relative directory, default `.`; absolute paths and `..` are rejected. |
|
|
224
|
+
| `checks[].timeout` | no | 1-600 seconds, default 120. |
|
|
225
|
+
| `checks[].required` | no | Default `true`; a required check that did not run keeps the overall result `UNKNOWN`. |
|
|
226
|
+
| `checks[].claim` | no | Human-readable claim recorded in the ledger. |
|
|
227
|
+
| `manual[].id` / `manual[].claim` | yes | Manual claims that are always reported as unverified. |
|
|
228
|
+
|
|
229
|
+
Verification findings use the same evidence shape as the architecture contract:
|
|
230
|
+
`code`, `severity`, `message`, JSON `pointer`, `path` and short `evidence`.
|
|
231
|
+
Blocking codes include `verification-invalid-json`,
|
|
232
|
+
`verification-unsupported-version`, `verification-invalid-id`,
|
|
233
|
+
`verification-duplicate-check`, `verification-invalid-level`,
|
|
234
|
+
`verification-invalid-kind`, `verification-invalid-cwd`,
|
|
235
|
+
`verification-invalid-timeout` and `verification-invalid-manual`.
|
|
236
|
+
|
|
237
|
+
`verify_change` runs L0/L1 in-process. L2-L4 execute only when the caller passes
|
|
238
|
+
`allow_execute=true`; L5 is always manual. A `PASS` means every required claim has
|
|
239
|
+
evidence. Unrun or manual claims remain in `unverified_claims` and are never written
|
|
240
|
+
as passing.
|
|
241
|
+
|
|
242
|
+
## Command line
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
python scripts/dev_engine.py system-model .
|
|
246
|
+
python scripts/dev_engine.py system-model . --contract config/architecture.json
|
|
247
|
+
python scripts/dev_engine.py architecture-review .
|
|
248
|
+
python scripts/dev_engine.py impact-analysis . --changed src/core/store.py
|
|
249
|
+
python scripts/dev_engine.py impact-analysis . --diff-file change.patch --depth 2
|
|
250
|
+
python scripts/dev_engine.py impact-analysis . --symbol save
|
|
251
|
+
python scripts/dev_engine.py verify-change . --changed src/core/store.py
|
|
252
|
+
python scripts/dev_engine.py verify-change . --changed src/core/store.py --level L2 --allow-execute
|
|
253
|
+
python scripts/dev_engine.py self-test .
|
|
254
|
+
python scripts/dev_engine.py adapter . --action list
|
|
255
|
+
python scripts/dev_engine.py adapter . --action run --adapter import-linter --allow-execute
|
|
256
|
+
```
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# Tool contracts
|
|
2
|
+
|
|
3
|
+
All tools are local and deterministic. Unless a section says otherwise they are
|
|
4
|
+
read-only; `run_checks`, `verify_change` and `run_adapter` require
|
|
5
|
+
`allow_execute=true` for their explicit execution paths, and `scaffold_skill` /
|
|
6
|
+
`workflow_state` require `apply=true` before writing.
|
|
7
|
+
|
|
8
|
+
## repo_map
|
|
9
|
+
|
|
10
|
+
Input:
|
|
11
|
+
|
|
12
|
+
- `path` (required): repository or source directory.
|
|
13
|
+
- `max_files` (optional, default 2000): source file limit.
|
|
14
|
+
|
|
15
|
+
Output: `root`, `modules`, `imports`, `entrypoints`, `truncated`.
|
|
16
|
+
|
|
17
|
+
## system_model
|
|
18
|
+
|
|
19
|
+
Input:
|
|
20
|
+
|
|
21
|
+
- `path` (required): repository or source directory.
|
|
22
|
+
- `max_files` (optional, default 2000): source file limit.
|
|
23
|
+
- `contract_file` (optional): contract path relative to the repository root
|
|
24
|
+
(default `.yotta/architecture.json`).
|
|
25
|
+
|
|
26
|
+
Output: `status` (`PASS` / `FAIL` / `UNKNOWN`), `contract`, `model` (`modules`,
|
|
27
|
+
`layers`, `imports`, `entrypoints`, `tests`, `configs`, `data_stores`),
|
|
28
|
+
`unknowns`, `unknowns_truncated`, `unverified_claims`, `evidence`, `truncated`
|
|
29
|
+
and `model_digest`.
|
|
30
|
+
|
|
31
|
+
Contract schema, glob rules, finding codes and import kinds are documented in
|
|
32
|
+
`references/architecture-contract.md`.
|
|
33
|
+
|
|
34
|
+
## architecture_review
|
|
35
|
+
|
|
36
|
+
Input:
|
|
37
|
+
|
|
38
|
+
- `path` (required): repository or source directory.
|
|
39
|
+
- `max_files` (optional, default 2000): source file limit.
|
|
40
|
+
- `contract_file` (optional): contract path relative to the repository root
|
|
41
|
+
(default `.yotta/architecture.json`).
|
|
42
|
+
|
|
43
|
+
Output: `status` (`PASS` / `FAIL` / `UNKNOWN`), `contract`, `checked`
|
|
44
|
+
(`rules` / `boundaries` / `data_stores` / `invariants`, each with a per-item
|
|
45
|
+
`status` of `PASS` / `WARN` / `FAIL` / `UNKNOWN`), `violations`, `blocking_findings`,
|
|
46
|
+
`advisory_findings`, `unknowns`, `unverified_claims`, `evidence`, `truncated` and
|
|
47
|
+
`model_digest`.
|
|
48
|
+
|
|
49
|
+
`critical` / `high` findings fail the review; `medium` / `low` stay advisory.
|
|
50
|
+
Anything the model cannot decide becomes `UNKNOWN`; declared invariants that this
|
|
51
|
+
tool cannot evaluate are listed in `unverified_claims` instead of being reported
|
|
52
|
+
as passing. Read-only.
|
|
53
|
+
|
|
54
|
+
## impact_analysis
|
|
55
|
+
|
|
56
|
+
Input:
|
|
57
|
+
|
|
58
|
+
- `path` (required): repository or source directory.
|
|
59
|
+
- `changed_files` (optional): repository-relative changed files.
|
|
60
|
+
- `diff` (optional): unified diff text; changed files and line numbers are parsed
|
|
61
|
+
from it, deleted files keep their declared layer.
|
|
62
|
+
- `symbols` (optional): target symbols; their definition sites become the change.
|
|
63
|
+
- `depth` (optional, default 3, 1-10): reverse-dependency depth.
|
|
64
|
+
- `max_files` (optional, default 2000): source file limit.
|
|
65
|
+
- `contract_file` (optional): contract path relative to the repository root.
|
|
66
|
+
|
|
67
|
+
At least one of `changed_files`, `diff` or `symbols` is required.
|
|
68
|
+
|
|
69
|
+
Output: `status`, `inputs`, `changed`, `direct_consumers`, `cone` (`nodes` with
|
|
70
|
+
`depth` / `via` / `layer` / `is_test`, `max_depth`, `limit`, `truncated`),
|
|
71
|
+
`affected_layers`, `affected_boundaries`, `affected_data_stores`,
|
|
72
|
+
`affected_invariants`, `relevant_tests`, `architecture` (`status`,
|
|
73
|
+
`violations_total`, `violations_in_scope`, `unknowns`), `blast_radius`
|
|
74
|
+
(`level`, `score`, `capped`, `reasons`), `rollback_probes`, `unknowns`,
|
|
75
|
+
`unverified_claims`, `evidence`, `truncated` and `model_digest`.
|
|
76
|
+
|
|
77
|
+
`status` is `FAIL` when a blocking architecture violation sits inside the cone,
|
|
78
|
+
`UNKNOWN` while anything is undecided, otherwise `PASS`. Read-only; no command is
|
|
79
|
+
executed.
|
|
80
|
+
|
|
81
|
+
## verify_change
|
|
82
|
+
|
|
83
|
+
Input:
|
|
84
|
+
|
|
85
|
+
- `path` (required): repository or source directory.
|
|
86
|
+
- `changed_files` / `diff` / `symbols` (at least one): the same change inputs as
|
|
87
|
+
`impact_analysis`.
|
|
88
|
+
- `depth` (optional, default 3, 1-10): reverse-dependency depth.
|
|
89
|
+
- `levels` (optional): additional execution levels `L2`, `L3`, `L4` or manual `L5`.
|
|
90
|
+
L0 and L1 always run.
|
|
91
|
+
- `allow_execute` (optional, default false): required before any L2-L4 check runs.
|
|
92
|
+
- `timeout` (optional, default 120, 1-600): upper bound for each policy check.
|
|
93
|
+
- `max_files` / `contract_file` (optional): model limit and contract override.
|
|
94
|
+
- `policy_file` (optional, default `.yotta/verification.json`): policy override.
|
|
95
|
+
|
|
96
|
+
Output: `status`, `inputs`, `required_levels`, `ledger`, `unverified_claims`,
|
|
97
|
+
`policy`, `evidence`, `ledger_digest`, `model_digest` and `impact_status`.
|
|
98
|
+
|
|
99
|
+
Every ledger entry has `id`, `level`, `claim`, `status` (`PASS` / `FAIL` / `UNKNOWN` /
|
|
100
|
+
`UNVERIFIED`), `severity`, `check`, `confidence`, `evidence`, `next_step` and
|
|
101
|
+
`command`. Static checks keep `command` as `null`; executed checks record the
|
|
102
|
+
whitelisted kind, relative cwd, exit code, timeout flag and `output_hash`.
|
|
103
|
+
|
|
104
|
+
The default ladder runs L0 (changed-file syntax, contract schema) and L1 (architecture
|
|
105
|
+
rules and boundaries inside the change cone). L2-L4 are skipped unless both a policy
|
|
106
|
+
check is declared and `allow_execute=true`; they never accept arbitrary commands.
|
|
107
|
+
L5 is always manual and stays in `unverified_claims`. The ledger intentionally has no
|
|
108
|
+
wall-clock timestamp: its digest and the command output hashes are the reproducible
|
|
109
|
+
evidence anchors.
|
|
110
|
+
|
|
111
|
+
## self_test
|
|
112
|
+
|
|
113
|
+
Input:
|
|
114
|
+
|
|
115
|
+
- `path` (required): source checkout or installed skill directory.
|
|
116
|
+
- `mode` (optional, default `auto`): `auto`, `source` or `installed`.
|
|
117
|
+
- `allow_execute` (optional, default false): run the target test suite.
|
|
118
|
+
- `timeout` (optional, default 120, 1-600).
|
|
119
|
+
|
|
120
|
+
Source mode checks required files, version alignment across `package.json` /
|
|
121
|
+
`SKILL.md` / `CHANGELOG.md` / `server.json` / engine `VERSION`, protocol tool names
|
|
122
|
+
and `inputSchema.additionalProperties=false`, fail-closed defaults for every write or
|
|
123
|
+
execute gate, and counterexamples. Installed mode checks `SKILL.md` and the installed
|
|
124
|
+
asset payload, and records source-only checks as out of scope.
|
|
125
|
+
|
|
126
|
+
The counterexample suite is in-process and deterministic: a seeded forbidden
|
|
127
|
+
dependency must be `FAIL`, removing the rule must stop the failure, an invalid
|
|
128
|
+
contract must be `FAIL` or `UNKNOWN`, a missing contract must be `UNKNOWN`, a seeded
|
|
129
|
+
credential must be found, and a seeded version mismatch must fail readiness. These
|
|
130
|
+
probes prove the verifier is not a rubber stamp.
|
|
131
|
+
|
|
132
|
+
## run_adapter
|
|
133
|
+
|
|
134
|
+
Input:
|
|
135
|
+
|
|
136
|
+
- `action` (required): `list` probes optional adapters without executing them;
|
|
137
|
+
`run` executes exactly one adapter.
|
|
138
|
+
- `path` (required): repository root.
|
|
139
|
+
- `adapter` (required when `action=run`): `import-linter`,
|
|
140
|
+
`dependency-cruiser` or `repomix`.
|
|
141
|
+
- `allow_execute` (optional, default false): required for `action=run`.
|
|
142
|
+
- `timeout` (optional, default 120, 1-600).
|
|
143
|
+
- `max_chars` (optional, default 120000, 1000-1000000): Repomix output cap.
|
|
144
|
+
- `token_budget` (optional): Repomix token budget; over-budget output fails.
|
|
145
|
+
- `target` (optional, default `.`): repository-relative adapter target.
|
|
146
|
+
|
|
147
|
+
`action=list` returns `status`, `adapters` with `available` / `ready` /
|
|
148
|
+
`executable` / `executable_source` / `config` / `reason`, plus `unknowns`.
|
|
149
|
+
|
|
150
|
+
`action=run` returns `status` (`PASS` / `FAIL` / `UNKNOWN`), the selected
|
|
151
|
+
`adapter` metadata, a fixed `command` record with `output_hash`, normalized
|
|
152
|
+
`findings`, Repomix `content` metadata when applicable, `next_step` and
|
|
153
|
+
`unknowns`. Missing tools, missing configs, invalid output and timeouts are
|
|
154
|
+
`UNKNOWN`, never silent passes.
|
|
155
|
+
|
|
156
|
+
Adapters are optional enhancements: no package is installed or downloaded, no
|
|
157
|
+
arbitrary argv is accepted, and adapter findings do not silently change the
|
|
158
|
+
status of the core architecture tools. See `references/adapters.md`.
|
|
159
|
+
|
|
160
|
+
## find_code
|
|
161
|
+
|
|
162
|
+
Input:
|
|
163
|
+
|
|
164
|
+
- `path` (required): repository, directory or file.
|
|
165
|
+
- `query` (required): symbol or text.
|
|
166
|
+
- `extensions` (optional): file extensions such as `.py`.
|
|
167
|
+
- `max_results` (optional, default 100).
|
|
168
|
+
- `context_lines` (optional, 0-5).
|
|
169
|
+
|
|
170
|
+
Output: `query`, `matches` (`path`, `line`, `kind`, `text`, `context`), `truncated`.
|
|
171
|
+
|
|
172
|
+
## compress_output
|
|
173
|
+
|
|
174
|
+
Input:
|
|
175
|
+
|
|
176
|
+
- `text` or `file` (one required).
|
|
177
|
+
- `max_chars` (optional, default 4000).
|
|
178
|
+
- `head_lines` / `tail_lines` (optional).
|
|
179
|
+
|
|
180
|
+
Output: text plus `original_lines`, `kept_lines`, `error_lines`, `truncated`.
|
|
181
|
+
|
|
182
|
+
## review_code
|
|
183
|
+
|
|
184
|
+
Input:
|
|
185
|
+
|
|
186
|
+
- `path` or `text` (one required).
|
|
187
|
+
- `max_findings` (optional, default 200).
|
|
188
|
+
|
|
189
|
+
Rules: bare-except, eval-exec, shell-true, debug-print, todo-comment,
|
|
190
|
+
mutable-default.
|
|
191
|
+
|
|
192
|
+
Each finding contains `path`, `line`, `rule`, `severity`, `evidence`, `suggestion`.
|
|
193
|
+
|
|
194
|
+
## review_diff
|
|
195
|
+
|
|
196
|
+
Input:
|
|
197
|
+
|
|
198
|
+
- `diff_text` or `path` (one required).
|
|
199
|
+
- `base` (optional git revision when `path` is used).
|
|
200
|
+
- `max_findings` (optional).
|
|
201
|
+
|
|
202
|
+
Only added lines are reviewed. Output: `files`, `findings`, `truncated`.
|
|
203
|
+
|
|
204
|
+
## mcp_doctor
|
|
205
|
+
|
|
206
|
+
Input:
|
|
207
|
+
|
|
208
|
+
- `skills_dirs` (optional array).
|
|
209
|
+
- `config_paths` (optional array).
|
|
210
|
+
|
|
211
|
+
Output: `skills`, `mcp_configs`, `issues`, `checked_skills`, `checked_configs`.
|
|
212
|
+
|
|
213
|
+
## scan_secrets
|
|
214
|
+
|
|
215
|
+
Input: `path` or `text`, optional `max_findings`, optional `include_git_history`
|
|
216
|
+
(bounded, default false).
|
|
217
|
+
|
|
218
|
+
Output: `findings` with `path`, `line`, `rule`, `severity`, redacted `evidence`,
|
|
219
|
+
`suggestion`; `truncated`.
|
|
220
|
+
|
|
221
|
+
## scan_dependencies
|
|
222
|
+
|
|
223
|
+
Input: `path`.
|
|
224
|
+
|
|
225
|
+
Output: `manifests`, `lockfiles`, `issues` (`missing-lockfile`,
|
|
226
|
+
`unpinned-dependency`, `insecure-source`, `local-dependency`,
|
|
227
|
+
`typosquat-suspicion`), and counts. Offline heuristics only.
|
|
228
|
+
|
|
229
|
+
## check_publish_readiness
|
|
230
|
+
|
|
231
|
+
Input: `path`.
|
|
232
|
+
|
|
233
|
+
Output: `ok`, `files`, `versions` (package / skill / changelog / engine when
|
|
234
|
+
present), `issues`.
|
|
235
|
+
|
|
236
|
+
## run_checks
|
|
237
|
+
|
|
238
|
+
Input: `kind` (`python-unittest` / `pytest` / `python-compile` / `npm-test` /
|
|
239
|
+
`npm-lint`), `cwd`, optional `timeout`, explicit `allow_execute=true`.
|
|
240
|
+
|
|
241
|
+
Output: `exit_code`, `passed`, bounded `summary`, compressed `output`,
|
|
242
|
+
`timed_out`.
|
|
243
|
+
|
|
244
|
+
## scaffold_skill
|
|
245
|
+
|
|
246
|
+
Input: `name`, `output_dir`, optional `description`, explicit `apply=true`.
|
|
247
|
+
|
|
248
|
+
Output: `target`, `files`, `applied`. Default is dry-run; existing non-empty
|
|
249
|
+
targets are rejected.
|
|
250
|
+
|
|
251
|
+
## workflow_state
|
|
252
|
+
|
|
253
|
+
Input: `root`, `action` (`read` / `append-log` / `append-file`), optional
|
|
254
|
+
`date`, `text`, `file`, explicit `apply=true`.
|
|
255
|
+
|
|
256
|
+
Output: `ok`, `files`, `missing`, `excerpts` for read; `target`, `applied`,
|
|
257
|
+
`preview` for writes. Writes are atomic and keep a `.bak` of an existing file.
|