@aperant/framework 0.8.4 → 0.8.7
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/CHANGELOG.md +185 -0
- package/agents/apt-planner.md +34 -3
- package/dist/cli/commands/coverage-check.d.mts.map +1 -1
- package/dist/cli/commands/coverage-check.mjs +74 -7
- package/dist/cli/commands/coverage-check.mjs.map +1 -1
- package/dist/cli/commands/detect-runtime.d.mts.map +1 -1
- package/dist/cli/commands/detect-runtime.mjs +18 -12
- package/dist/cli/commands/detect-runtime.mjs.map +1 -1
- package/dist/cli/coverage-check/user-outcomes.d.mts +84 -0
- package/dist/cli/coverage-check/user-outcomes.d.mts.map +1 -0
- package/dist/cli/coverage-check/user-outcomes.mjs +265 -0
- package/dist/cli/coverage-check/user-outcomes.mjs.map +1 -0
- package/dist/cli/host/detect.mjs +1 -1
- package/dist/cli/host/detect.mjs.map +1 -1
- package/dist/cli/install/install-from-source.mjs +3 -3
- package/dist/cli/install/legacy-paths.d.mts.map +1 -1
- package/dist/cli/install/legacy-paths.mjs +2 -0
- package/dist/cli/install/legacy-paths.mjs.map +1 -1
- package/dist/cli/install/manifest.d.mts +13 -0
- package/dist/cli/install/manifest.d.mts.map +1 -1
- package/dist/cli/install/manifest.mjs +5 -0
- package/dist/cli/install/manifest.mjs.map +1 -1
- package/dist/cli/install/pipeline.d.mts +15 -0
- package/dist/cli/install/pipeline.d.mts.map +1 -1
- package/dist/cli/install/pipeline.mjs +27 -0
- package/dist/cli/install/pipeline.mjs.map +1 -1
- package/dist/cli/install/transforms/codex.d.mts +1 -1
- package/dist/cli/install/transforms/codex.d.mts.map +1 -1
- package/dist/cli/install/transforms/codex.mjs +43 -2
- package/dist/cli/install/transforms/codex.mjs.map +1 -1
- package/dist/cli/install/version-header.d.mts.map +1 -1
- package/dist/cli/install/version-header.mjs +7 -1
- package/dist/cli/install/version-header.mjs.map +1 -1
- package/dist/cli/verify-proof/idl/index.d.mts +1 -1
- package/dist/cli/verify-proof/idl/index.mjs +7 -8
- package/dist/cli/verify-proof/idl/index.mjs.map +1 -1
- package/dist/cli/verify-proof/idl/types.d.ts +5 -4
- package/dist/cli/verify-proof/idl/types.d.ts.map +1 -1
- package/dist/cli/verify-proof/idl/types.js +4 -3
- package/dist/cli/verify-proof/idl/types.js.map +1 -1
- package/dist/cli/verify-proof/resolver.d.mts +63 -1
- package/dist/cli/verify-proof/resolver.d.mts.map +1 -1
- package/dist/cli/verify-proof/resolver.mjs +164 -4
- package/dist/cli/verify-proof/resolver.mjs.map +1 -1
- package/dist/cli/verify-proof/runtime-detect.d.mts +6 -3
- package/dist/cli/verify-proof/runtime-detect.d.mts.map +1 -1
- package/dist/cli/verify-proof/runtime-detect.mjs +104 -11
- package/dist/cli/verify-proof/runtime-detect.mjs.map +1 -1
- package/dist/cli/verify-proof/trust.d.mts +1 -1
- package/dist/cli/verify-proof/trust.d.mts.map +1 -1
- package/dist/cli/verify-proof/trust.mjs +1 -1
- package/dist/driver-sdk/conformance.d.ts +41 -0
- package/dist/driver-sdk/conformance.d.ts.map +1 -0
- package/dist/driver-sdk/conformance.js +123 -0
- package/dist/driver-sdk/conformance.js.map +1 -0
- package/dist/driver-sdk/errors.d.ts +75 -0
- package/dist/driver-sdk/errors.d.ts.map +1 -0
- package/dist/driver-sdk/errors.js +80 -0
- package/dist/driver-sdk/errors.js.map +1 -0
- package/dist/driver-sdk/idl.d.ts +221 -0
- package/dist/driver-sdk/idl.d.ts.map +1 -0
- package/dist/driver-sdk/idl.js +140 -0
- package/dist/driver-sdk/idl.js.map +1 -0
- package/dist/driver-sdk/index.d.ts +28 -0
- package/dist/driver-sdk/index.d.ts.map +1 -0
- package/dist/driver-sdk/index.js +28 -0
- package/dist/driver-sdk/index.js.map +1 -0
- package/dist/driver-sdk/manifest.d.ts +93 -0
- package/dist/driver-sdk/manifest.d.ts.map +1 -0
- package/dist/driver-sdk/manifest.js +12 -0
- package/dist/driver-sdk/manifest.js.map +1 -0
- package/dist/driver-sdk/retry.d.ts +33 -0
- package/dist/driver-sdk/retry.d.ts.map +1 -0
- package/dist/driver-sdk/retry.js +50 -0
- package/dist/driver-sdk/retry.js.map +1 -0
- package/dist/plugin/.claude-plugin/plugin.json +2 -1
- package/dist/plugin/agents/apt-planner.md +34 -3
- package/dist/plugin/skills/apt-plan/SKILL.md +50 -0
- package/dist/plugin/skills/apt-pr-review/SKILL.md +1 -1
- package/dist/plugin/skills/apt-research/SKILL.md +526 -0
- package/dist/plugin/skills/apt-research/appendices/budget-loop.md +397 -0
- package/dist/plugin/skills/apt-research/appendices/claim-graph-schema.md +206 -0
- package/dist/plugin/skills/apt-research/appendices/domain-tools.md +236 -0
- package/dist/plugin/skills/apt-spar/SKILL.md +19 -7
- package/dist/plugin/skills/apt-verify-proof/SKILL.md +41 -2
- package/dist/schemas/quick-task.d.ts +17 -17
- package/drivers/.gitkeep +0 -0
- package/drivers/api/README.md +40 -0
- package/drivers/api/driver.mjs +59 -0
- package/drivers/api/manifest.json +26 -0
- package/drivers/browser/README.md +105 -0
- package/drivers/browser/driver.mjs +134 -0
- package/drivers/browser/manifest.json +35 -0
- package/drivers/cli/README.md +44 -0
- package/drivers/cli/driver.mjs +62 -0
- package/drivers/cli/manifest.json +28 -0
- package/drivers/electron/README.md +64 -0
- package/drivers/electron/driver.mjs +87 -0
- package/drivers/electron/manifest.json +37 -0
- package/package.json +7 -3
- package/skills/apt-plan/SKILL.md +50 -0
- package/skills/apt-planner.md +16 -0
- package/skills/apt-pr-review/SKILL.md +1 -1
- package/skills/apt-research/SKILL.md +526 -0
- package/skills/apt-research/appendices/budget-loop.md +397 -0
- package/skills/apt-research/appendices/claim-graph-schema.md +206 -0
- package/skills/apt-research/appendices/domain-tools.md +236 -0
- package/skills/apt-spar/SKILL.md +19 -7
- package/skills/apt-verify-proof/SKILL.md +41 -2
- package/src/cli/commands/coverage-check.mjs +126 -44
- package/src/cli/commands/detect-runtime.mjs +23 -14
- package/src/cli/coverage-check/user-outcomes.mjs +273 -0
- package/src/cli/host/detect.mjs +1 -1
- package/src/cli/install/install-from-source.mjs +3 -3
- package/src/cli/install/legacy-paths.mjs +2 -0
- package/src/cli/install/manifest.mjs +5 -0
- package/src/cli/install/pipeline.mjs +28 -0
- package/src/cli/install/transforms/codex.mjs +51 -2
- package/src/cli/install/version-header.mjs +7 -1
- package/src/cli/verify-proof/idl/index.mjs +7 -8
- package/src/cli/verify-proof/idl/types.ts +5 -4
- package/src/cli/verify-proof/manifest-schema.json +2 -1
- package/src/cli/verify-proof/resolver.mjs +171 -4
- package/src/cli/verify-proof/runtime-detect.mjs +99 -10
- package/src/cli/verify-proof/trust.mjs +1 -1
- package/templates/proof-verification.md +32 -3
- package/workflows/verify-proof.md +78 -9
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# Domain Tools, Gates, and Output Templates
|
|
2
|
+
|
|
3
|
+
> Per-domain tool surface, reasoning gates, and synthesis output template.
|
|
4
|
+
> Load when domain has been detected (Step 1d) or when synthesizing
|
|
5
|
+
> (Step 10).
|
|
6
|
+
|
|
7
|
+
The four domains are detected from the user's question in Step 1d and
|
|
8
|
+
recorded as immutable in `research-spec.md ## Domain`. The detected
|
|
9
|
+
domain determines which tools each `apt-researcher` role gets, which
|
|
10
|
+
reasoning steps are enabled, and what shape the final `RESEARCH.md`
|
|
11
|
+
output takes.
|
|
12
|
+
|
|
13
|
+
## Domain detection signals
|
|
14
|
+
|
|
15
|
+
| Domain | Signals | Examples |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| **mechanistic** | physics, math, distributed systems, algorithms, deterministic engineering systems with provable behavior | "how does Raft handle leader election", "what does axle stiffness do to chassis dynamics", "is this algorithm O(log n)" |
|
|
18
|
+
| **empirical** | medicine, biology, nutrition, psychology, public-health, social science, anything where human variation dominates and replication matters | "does intermittent fasting cause muscle loss", "what's the effect of X on Y in older adults", "is supplement X effective" |
|
|
19
|
+
| **strategic** | tool/vendor comparison, market analysis, license/contract evaluation, anything where the answer depends on vendor disclosure + ecosystem health | "best embedded DB for offline-first 2026", "should we pick Vitest or Bun test", "is Turso safe to depend on" |
|
|
20
|
+
| **general** | catch-all when none of the above fit; usually broad knowledge questions or framing-questions | "what is consensus in distributed systems", "explain bitemporal databases" |
|
|
21
|
+
|
|
22
|
+
Ambiguous question → `general`. The user can override with explicit
|
|
23
|
+
flag (future: `--domain <name>`); for v1, signal-based detection is
|
|
24
|
+
authoritative.
|
|
25
|
+
|
|
26
|
+
## Per-domain tool surface
|
|
27
|
+
|
|
28
|
+
Each `apt-researcher` role gets the base tools (Read, Grep, Glob,
|
|
29
|
+
WebSearch, WebFetch, Context7) PLUS the domain extras below.
|
|
30
|
+
|
|
31
|
+
### mechanistic
|
|
32
|
+
|
|
33
|
+
| Tool | How invoked | Used by |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| arxiv search | `curl "http://export.arxiv.org/api/query?search_query=..."` | Retriever |
|
|
36
|
+
| PDF reader | `curl -o /tmp/x.pdf {url} && pdftotext /tmp/x.pdf -` | Builder, Skeptic, Retriever |
|
|
37
|
+
| Wolfram Alpha (if API key set) | `curl "https://api.wolframalpha.com/v2/query?..."` | Builder, Skeptic |
|
|
38
|
+
|
|
39
|
+
First-principles derivation: **ENABLED**. Builder and Skeptic may
|
|
40
|
+
produce derivations grounded in domain theory. Judge accepts them
|
|
41
|
+
into `claims.json` at `source_tier: derived-theory` (weight 0.6
|
|
42
|
+
in `uncertainty` formula).
|
|
43
|
+
|
|
44
|
+
### empirical
|
|
45
|
+
|
|
46
|
+
| Tool | How invoked | Used by |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| Crossref DOI resolve | `curl "https://api.crossref.org/works/{doi}"` | Retriever, citation audit |
|
|
49
|
+
| PubMed E-utilities | `curl "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&term=..."` | Retriever |
|
|
50
|
+
| PMC full-text fetch | `curl "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pmc&id={pmcid}"` | Builder, Skeptic |
|
|
51
|
+
| Europe PMC fallback | `curl "https://www.ebi.ac.uk/europepmc/webservices/rest/search?query=..."` | Retriever |
|
|
52
|
+
|
|
53
|
+
First-principles derivation: **DEMOTED**. Builder/Skeptic may invoke
|
|
54
|
+
theory (mechanism, leucine threshold, etc.) but Judge demotes the
|
|
55
|
+
output to `source_tier: hypothesis` (weight 0.1). Hypotheses cannot
|
|
56
|
+
reach `confidence: high` regardless of how compelling the reasoning
|
|
57
|
+
sounds — only empirical evidence at `tier ≥ independent-test` can
|
|
58
|
+
elevate a claim to `high`.
|
|
59
|
+
|
|
60
|
+
Citation audit is **MANDATORY** every iteration (not every N) in
|
|
61
|
+
empirical domains. Every new citation MUST be DOI/PMID-verified
|
|
62
|
+
via Crossref or NCBI before promotion to `sources.json`. Failures
|
|
63
|
+
go straight to `suspect-citations.md` and the claim depending on
|
|
64
|
+
them is downgraded.
|
|
65
|
+
|
|
66
|
+
### strategic
|
|
67
|
+
|
|
68
|
+
| Tool | How invoked | Used by |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| GitHub releases | `gh release list -R {owner}/{repo} --limit 20` | Retriever |
|
|
71
|
+
| GitHub code search | `gh search code "..." --limit 20` | Retriever, Skeptic |
|
|
72
|
+
| License fetch | `gh api repos/{owner}/{repo}/license` or WebFetch raw LICENSE | Retriever |
|
|
73
|
+
| Changelog fetch | WebFetch `CHANGELOG.md` or `gh api repos/{owner}/{repo}/contents/CHANGELOG.md` | Retriever |
|
|
74
|
+
| Package metadata | `npm view {pkg} --json` / `pip show {pkg} --verbose` / `cargo search {pkg}` | Retriever |
|
|
75
|
+
|
|
76
|
+
First-principles derivation: **DISABLED**. "Derive whether libSQL is
|
|
77
|
+
stable from theory" is nonsense. Builder is instructed to synthesize
|
|
78
|
+
from sources only. If Builder produces a derivation-shaped output,
|
|
79
|
+
Judge rejects it with `## reason: derivation invalid in strategic domain`.
|
|
80
|
+
|
|
81
|
+
Vendor-only evidence is a spar trigger (see `overnight-loop.md`
|
|
82
|
+
§spar-triggers). Strategic domain treats vendor-doc as
|
|
83
|
+
`source_tier: vendor-doc` (weight 0.5) — NOT a high tier.
|
|
84
|
+
|
|
85
|
+
### general
|
|
86
|
+
|
|
87
|
+
Default tool surface. First-principles is **SOFT-ENABLED with
|
|
88
|
+
hypothesis demotion** — Builder/Skeptic may derive but Judge
|
|
89
|
+
demotes to `hypothesis` until empirical or primary-doc evidence
|
|
90
|
+
elevates the claim.
|
|
91
|
+
|
|
92
|
+
## Output gates (Step 10 — synthesis)
|
|
93
|
+
|
|
94
|
+
The synthesis template in `RESEARCH.md` has a common core (defined in
|
|
95
|
+
the main SKILL.md `## 10. Synthesize`) PLUS domain-specific sections.
|
|
96
|
+
|
|
97
|
+
### mechanistic
|
|
98
|
+
|
|
99
|
+
Add:
|
|
100
|
+
|
|
101
|
+
```markdown
|
|
102
|
+
## First-principles derivations
|
|
103
|
+
|
|
104
|
+
For each derivation accepted into the claim graph at
|
|
105
|
+
`source_tier: derived-theory`:
|
|
106
|
+
|
|
107
|
+
- **{derivation name}** — claim {C-id}
|
|
108
|
+
- Premises: {what we assumed}
|
|
109
|
+
- Steps: {compact derivation}
|
|
110
|
+
- Cross-check vs sources: {which sources confirm/contradict the derivation}
|
|
111
|
+
- Failure mode: {when does this derivation break?}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
If a derivation contradicts an empirical source, the derivation is
|
|
115
|
+
flagged as bounded — Judge MUST note the boundary condition.
|
|
116
|
+
|
|
117
|
+
### empirical
|
|
118
|
+
|
|
119
|
+
Add (mandatory, non-negotiable):
|
|
120
|
+
|
|
121
|
+
```markdown
|
|
122
|
+
## Not medical / financial / safety advice
|
|
123
|
+
|
|
124
|
+
This research synthesis is informational. It is not a substitute for
|
|
125
|
+
professional advice from a licensed clinician, financial advisor, or
|
|
126
|
+
safety expert. Individual circumstances vary; outcomes that apply to
|
|
127
|
+
populations may not apply to any specific person.
|
|
128
|
+
|
|
129
|
+
## What this CAN'T tell you
|
|
130
|
+
|
|
131
|
+
- {Specific question the evidence does not address}
|
|
132
|
+
- {Specific population the evidence does not cover}
|
|
133
|
+
- {Specific interaction or confounder the evidence cannot resolve}
|
|
134
|
+
|
|
135
|
+
## Quality of evidence
|
|
136
|
+
|
|
137
|
+
For each cited study supporting a critical claim:
|
|
138
|
+
|
|
139
|
+
| Source | Design | n | Peer-reviewed | Replicated | Notes |
|
|
140
|
+
|---|---|---|---|---|---|
|
|
141
|
+
| {S-id} | {RCT/cohort/meta} | {n} | {yes/no} | {yes/no/unknown} | {note} |
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Imperatives in the synthesis prose ("you should…", "do X", "avoid Y")
|
|
145
|
+
are STRIPPED by Judge. Empirical synthesis uses descriptive language
|
|
146
|
+
("evidence suggests…", "in the populations studied…").
|
|
147
|
+
|
|
148
|
+
If the synthesis would recommend a course of action affecting health,
|
|
149
|
+
finance, or safety, Judge inserts: "**Discuss with a qualified
|
|
150
|
+
professional before acting on this synthesis.**"
|
|
151
|
+
|
|
152
|
+
### strategic
|
|
153
|
+
|
|
154
|
+
Add (mandatory):
|
|
155
|
+
|
|
156
|
+
```markdown
|
|
157
|
+
## Conditional-tree recommendation
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
if {decision-relevant condition A}:
|
|
161
|
+
→ recommend {Option X}
|
|
162
|
+
→ reason: {1-line}
|
|
163
|
+
elif {decision-relevant condition B}:
|
|
164
|
+
→ recommend {Option Y}
|
|
165
|
+
→ reason: {1-line}
|
|
166
|
+
else:
|
|
167
|
+
→ no clear winner — {what's the unresolved question}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Vendor-claim conflicts
|
|
171
|
+
|
|
172
|
+
For each option where evidence is vendor-only or vendors disagree:
|
|
173
|
+
|
|
174
|
+
- **{Option}** — {dimension}
|
|
175
|
+
- Vendor claim: {what the vendor says}
|
|
176
|
+
- Independent confirmation: {available | NOT AVAILABLE}
|
|
177
|
+
- Risk if vendor claim is wrong: {what breaks}
|
|
178
|
+
|
|
179
|
+
## Decision blockers
|
|
180
|
+
|
|
181
|
+
Questions only the user can answer that change the recommendation:
|
|
182
|
+
|
|
183
|
+
- {Question} — affects: {which option(s)}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Single-winner output is **REJECTED** by Judge when evidence is
|
|
187
|
+
vendor-only across the deciding dimension. The skill produces a
|
|
188
|
+
conditional tree or explicit "no clear winner" — never a confident
|
|
189
|
+
universal recommendation in those cases.
|
|
190
|
+
|
|
191
|
+
### general
|
|
192
|
+
|
|
193
|
+
Add:
|
|
194
|
+
|
|
195
|
+
```markdown
|
|
196
|
+
## Outstanding gaps
|
|
197
|
+
|
|
198
|
+
- {Open question that the synthesis does not close}
|
|
199
|
+
|
|
200
|
+
## Recommended next reads
|
|
201
|
+
|
|
202
|
+
- {Source} — covers {what aspect}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Mode-specific additions (orthogonal to domain)
|
|
206
|
+
|
|
207
|
+
Applied AFTER the domain gates. From the main SKILL.md `## 10.
|
|
208
|
+
Synthesize`, repeated here for the per-domain reader:
|
|
209
|
+
|
|
210
|
+
- **UNDERSTAND** → mental model section with mechanism + analogy
|
|
211
|
+
- **VERIFY** → verdict line (`confirmed | partially confirmed | false |
|
|
212
|
+
contested | unknown`)
|
|
213
|
+
- **SOLVE** → candidate approaches table + `## Falsification status`.
|
|
214
|
+
For code-domain SOLVE: blocks `CONVERGED` if no falsification was
|
|
215
|
+
run (test / simulator / model-checker / formal-method sketch).
|
|
216
|
+
Force STALLED with `## Cannot certify without falsification` and
|
|
217
|
+
enumerate what falsification harness would be needed.
|
|
218
|
+
- **COMPARE** → dimensions × options matrix + per-cell evidence
|
|
219
|
+
pointers (conditional-tree comes from the strategic domain gate)
|
|
220
|
+
|
|
221
|
+
## Tool-surface fallbacks
|
|
222
|
+
|
|
223
|
+
If a domain tool is unavailable in the current environment (e.g.
|
|
224
|
+
`gh` not installed, no network access for Crossref), the affected
|
|
225
|
+
role MUST report this in its output:
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
## Tool unavailable
|
|
229
|
+
- {tool name}: {why unavailable}
|
|
230
|
+
- Impact on this iteration: {what could not be done}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Judge records the missing capability in `iteration-log.md` and adjusts
|
|
234
|
+
stop-state evaluation: a STALLED verdict resulting from missing tools
|
|
235
|
+
gets `## Cannot resolve without` annotated with "tool {X} unavailable
|
|
236
|
+
in this environment". The user can resolve and `--resume`.
|
|
@@ -47,7 +47,7 @@ Termination posture (v1.1, amending SPAR-06): the termination headline is in-con
|
|
|
47
47
|
|
|
48
48
|
**Reads:**
|
|
49
49
|
- `AGENTS.md` — project constitution (principles, conventions, tech stack)
|
|
50
|
-
- `.aperant/config.json` — `router.llm.providers` for partner fallback (read-only)
|
|
50
|
+
- `.aperant/config.json` — `router.llm.providers` for partner fallback (read-only). **NOTE:** `router.llm.providers.<id>.model` is NOT consulted for spar partner model selection — partner CLIs inherit their own native config (codex: `~/.codex/config.toml`; gemini: `GEMINI_MODEL` env / `~/.gemini/settings.json`). The `router.llm.providers` keys serve the cheap LLM-router classifier, a separately scoped reserved surface (see `packages/framework/src/types/config.ts:222-238`); do not conflate.
|
|
51
51
|
- `.aperant/state.json` — `active_task` framing, optional
|
|
52
52
|
- The live conversation transcript (when `[topic]` is empty)
|
|
53
53
|
|
|
@@ -133,7 +133,7 @@ Do NOT proceed; self-sparring is sycophancy by construction (the host cannot obj
|
|
|
133
133
|
|
|
134
134
|
1. **Rung 1 — MCP tool** (`mcp__<partner>-mcp__*`, e.g. `mcp__codex-mcp__codex`). Detected if the host exposes its deferred-tool manifest via `CLAUDE_MCP_DEFERRED_TOOLS` and the tool is registered. When `detected: "runtime-host-only"` the framework process cannot probe the host's tool registry from outside — treat as candidate and attempt the tool call; if the tool is genuinely unavailable in the host's visible registry, fall through to rung 2.
|
|
135
135
|
2. **Rung 2 — Plugin shim** (`${CLAUDE_PLUGIN_ROOT}/scripts/<partner>-companion.mjs`). Codex only (claude / gemini have no plugin shim).
|
|
136
|
-
3. **Rung 3 — Raw CLI on `$PATH`** (`codex exec`, `claude -p`, `gemini
|
|
136
|
+
3. **Rung 3 — Raw CLI on `$PATH`** (`codex exec`, `claude -p`, `gemini`).
|
|
137
137
|
|
|
138
138
|
Walk the ladder in order; pick the first rung with `detected: true` (or `"runtime-host-only"` for MCP). **MCP rung has a hard timeout** — default 900000ms (15 min), configurable via `apt-spar.mcp_timeout_ms` in `.aperant/config.json`. The MCP rung is a structured tool call, NOT a Bash invocation, so the Bash tool's 600000ms ceiling does NOT apply — the MCP rung can carry heavy-research partner runs (e.g. Claude Code partner doing multiple minutes of Read/Grep/Bash) where the Bash rungs would hit the host ceiling. On MCP timeout, **automatically fall through to rung 2 or rung 3** — do NOT fail the whole spar. Treat MCP timeout as "rung unavailable for this invocation."
|
|
139
139
|
|
|
@@ -183,20 +183,32 @@ The table below shows the canonical command shape per (partner × rung); the act
|
|
|
183
183
|
|
|
184
184
|
| Partner | Rung | Command | Notes |
|
|
185
185
|
|---|---|---|---|
|
|
186
|
-
| codex | mcp | tool call: `mcp__codex-mcp__codex({prompt})` | Preferred. 900000ms (15 min) timeout (configurable `apt-spar.mcp_timeout_ms`); on timeout fall through to plugin then CLI. |
|
|
187
|
-
| codex | plugin | `node "${CLAUDE_PLUGIN_ROOT}/scripts/codex-companion.mjs" task "$(cat <<'APT_SPAR_PROMPT_EOF' ... APT_SPAR_PROMPT_EOF\n)"` | **NO `--write`. NO `--effort` override.** Per SPAR-04 — spar is conversation, not patching. |
|
|
188
|
-
| codex | cli | `codex exec "$(cat <<'APT_SPAR_PROMPT_EOF' ... APT_SPAR_PROMPT_EOF\n)"` | Precedent: `apt-pr-review/SKILL.md:1084`. Verify with `codex --help`. |
|
|
186
|
+
| codex | mcp | tool call: `mcp__codex-mcp__codex({prompt, model})` where `model` is parsed from `~/.codex/config.toml`'s `model = "<value>"` line (see §5a below). | Preferred. 900000ms (15 min) timeout (configurable `apt-spar.mcp_timeout_ms`); on timeout fall through to plugin then CLI. If `~/.codex/config.toml` is missing OR the `model =` line is absent/unparseable, treat MCP rung as UNAVAILABLE and fall through to plugin/CLI — never invent a default model (the MCP server's built-in fallback is stale `gpt-5.3-codex`, which is exactly the bug we are fixing). |
|
|
187
|
+
| codex | plugin | `node "${CLAUDE_PLUGIN_ROOT}/scripts/codex-companion.mjs" task "$(cat <<'APT_SPAR_PROMPT_EOF' ... APT_SPAR_PROMPT_EOF\n)"` | No `--model` flag — `codex-companion.mjs` invokes `codex exec` which inherits `~/.codex/config.toml` automatically. **NO `--write`. NO `--effort` override.** Per SPAR-04 — spar is conversation, not patching. |
|
|
188
|
+
| codex | cli | `codex exec "$(cat <<'APT_SPAR_PROMPT_EOF' ... APT_SPAR_PROMPT_EOF\n)"` | Precedent: `apt-pr-review/SKILL.md:1084`. No `--model` flag — `codex exec` inherits `~/.codex/config.toml` automatically. Verify with `codex --help`. |
|
|
189
189
|
| claude | mcp | tool call: `mcp__claude-code-mcp__claude_code({prompt})` | Preferred. Same 900000ms (15 min) timeout + fallthrough rule. |
|
|
190
190
|
| claude | plugin | n/a | No plugin shim exists for Claude. Skip this rung. |
|
|
191
191
|
| claude | cli | `claude -p "$(cat <<'APT_SPAR_PROMPT_EOF' ... APT_SPAR_PROMPT_EOF\n)" --output-format text` | Symmetric. Claude has no `--write` equivalent — asymmetric flags are a smell. |
|
|
192
192
|
| gemini | mcp | tool call: `mcp__gemini-mcp__*({prompt})` | Preferred. Same 900000ms (15 min) timeout + fallthrough rule. Any `mcp__gemini-mcp__*` tool satisfies the rung. |
|
|
193
193
|
| gemini | plugin | n/a | No plugin shim exists for Gemini. Skip this rung. |
|
|
194
|
-
| gemini | cli | `gemini
|
|
194
|
+
| gemini | cli | `gemini "$(cat <<'APT_SPAR_PROMPT_EOF' ... APT_SPAR_PROMPT_EOF\n)"` | No `-m` flag — gemini-cli resolves model via `--model` > `GEMINI_MODEL` env > `~/.gemini/settings.json` > built-in default per `docs/cli/model-routing.md:47-58`. Drop the flag, let the cascade work; users override per-shell via `GEMINI_MODEL=...` or per-project via `settings.json`. |
|
|
195
195
|
|
|
196
196
|
Set the Bash tool's `timeout` parameter to `--timeout-ms` (default 300000).
|
|
197
197
|
|
|
198
198
|
**Timeout calibration.** The 5-min Bash-rung default and 15-min MCP-rung default are sized for heavy-research partner runs — modern partner CLIs commonly spend multiple minutes doing real Read/Grep/Bash investigation before producing a round response. The two defaults are intentionally asymmetric: the Bash rungs (plugin shim, raw CLI) are capped at the Claude Code Bash tool's 600000ms (10 min) host ceiling, while the MCP rung — a structured tool call rather than a Bash invocation — has no host ceiling and can carry the worst-case 15-min Claude Code partner. For tighter budgets (e.g. CI), pass `--timeout-ms` explicitly. The MCP-rung override is downward-only: if you observe consistent partner-CLI wedges (auth handshakes, hosted-API stalls, CI lanes wanting fast failure), set `apt-spar.mcp_timeout_ms` BELOW the 15-min default in `.aperant/config.json` (e.g. `120000` for a 2-min fast-fail budget) — raising it above 15 min is unnecessary because the default already covers the documented worst case. Future versions may introduce per-partner defaults.
|
|
199
199
|
|
|
200
|
+
## 5a. Codex MCP model resolution
|
|
201
|
+
|
|
202
|
+
The codex MCP rung (table row above) requires an explicit `model` arg sourced from the user's `~/.codex/config.toml`. The MCP server (`codex-mcp-server`) does NOT read `~/.codex/config.toml` itself — when no `model` is passed it falls back to a hardcoded stale `gpt-5.3-codex`, silently overriding the user's actual configured model. Resolve the model exactly once per spar invocation, before the rung-table walk:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
# Resolve the codex MCP model exactly once per spar invocation, before the rung table walk
|
|
206
|
+
CODEX_MCP_MODEL="$(grep -E '^model = "[^"]+"' "$HOME/.codex/config.toml" 2>/dev/null | head -1 | sed -E 's/^model = "([^"]+)".*/\1/')"
|
|
207
|
+
# If empty → codex MCP rung is UNAVAILABLE; fall through to plugin/CLI.
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
If `$CODEX_MCP_MODEL` is empty (file missing, `model =` line absent, or value not double-quoted), treat the MCP rung as UNAVAILABLE and fall through to plugin → CLI. **Never invent a default** — the upstream MCP server's built-in `gpt-5.3-codex` fallback is exactly the bug this resolution path exists to fix.
|
|
211
|
+
|
|
200
212
|
**Prompt-quoting safety.** The prompt is user-controlled (it comes from `[topic]` and/or conversation context) and may legitimately contain double quotes, dollar signs, backticks, or `$(...)` substitution that bash would otherwise expand or break on. NEVER interpolate `<prompt>` directly inside a double-quoted shell argument. Instead, pipe via a here-document so the shell treats the body as opaque text:
|
|
201
213
|
|
|
202
214
|
```bash
|
|
@@ -213,7 +225,7 @@ APT_SPAR_PROMPT_EOF
|
|
|
213
225
|
)" --output-format text
|
|
214
226
|
|
|
215
227
|
# Gemini direction
|
|
216
|
-
gemini
|
|
228
|
+
gemini "$(cat <<'APT_SPAR_PROMPT_EOF'
|
|
217
229
|
<prompt body — opaque, no shell expansion>
|
|
218
230
|
APT_SPAR_PROMPT_EOF
|
|
219
231
|
)"
|
|
@@ -58,6 +58,35 @@ apt-tools detect-runtime .
|
|
|
58
58
|
# → { runtime: {is_electron, is_nextjs, ...}, selected_driver_id: "..." }
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
+
v0.8.6 — the runtime detector now walks `apps/*/package.json` by
|
|
62
|
+
default and OR-merges each child's capabilities into the root. The
|
|
63
|
+
canonical Aperant monorepo (Electron at `apps/desktop`, Next.js at
|
|
64
|
+
`apps/web`) now reports `is_electron: true` AND `is_nextjs: true`
|
|
65
|
+
without any config override.
|
|
66
|
+
|
|
67
|
+
### Per-outcome dispatch (v0.8.6+)
|
|
68
|
+
|
|
69
|
+
When the spec ships `## User Outcomes` (the verify-proof input
|
|
70
|
+
contract — see CLAUDE.md), the workflow runner imports
|
|
71
|
+
`resolveDriversForOutcomes()` from the resolver module and picks a
|
|
72
|
+
driver PER OUTCOME SURFACE instead of a single per-run driver pick.
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
import { resolveDriversForOutcomes } from '.aperant/deps/node_modules/@aperant/framework/src/cli/verify-proof/resolver.mjs'
|
|
76
|
+
|
|
77
|
+
const entries = resolveDriversForOutcomes({
|
|
78
|
+
drivers, runtime,
|
|
79
|
+
outcomes: parsed.outcomes, // from parseUserOutcomes(spec)
|
|
80
|
+
})
|
|
81
|
+
// → [{outcome_id: "O1", surface: "electron", driver: {...}}, ...]
|
|
82
|
+
// For [electron+web] outcomes, two entries share the same outcome_id.
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The legacy `apt-tools detect-runtime` still answers the per-run
|
|
86
|
+
"which driver would be picked?" question for the override preview.
|
|
87
|
+
For the per-outcome dispatch (the new contract), import
|
|
88
|
+
`resolveDriversForOutcomes` directly.
|
|
89
|
+
|
|
61
90
|
### Override
|
|
62
91
|
|
|
63
92
|
Force a specific driver chain in `.aperant/config.json`:
|
|
@@ -66,6 +95,15 @@ Force a specific driver chain in `.aperant/config.json`:
|
|
|
66
95
|
{ "verification": { "runtimes": ["electron", "cli"] } }
|
|
67
96
|
```
|
|
68
97
|
|
|
98
|
+
v0.8.6 — `verification.monorepo_globs` is the new opt-out for the
|
|
99
|
+
monorepo walk. The walk now runs by default — adopters whose
|
|
100
|
+
monorepo lives at a non-canonical prefix
|
|
101
|
+
(`packages/apps/*`, `services/*`) override via
|
|
102
|
+
`verification.monorepo_globs: ["packages/apps/*"]`; set to `[]` to
|
|
103
|
+
disable the walk entirely (root-only behaviour, backwards compat).
|
|
104
|
+
The `verification.runtimes[]` override stays the final escape hatch
|
|
105
|
+
and is now usually unnecessary because the walk runs by default.
|
|
106
|
+
|
|
69
107
|
### Bundled drivers (4)
|
|
70
108
|
|
|
71
109
|
- **browser** (priority=100, ga) — Next.js / vanilla web frontends.
|
|
@@ -83,8 +121,9 @@ apt-tools driver doctor .
|
|
|
83
121
|
# → { drivers: [{driverId, manifest_valid, idl_conformant, ...}], summary: {...} }
|
|
84
122
|
```
|
|
85
123
|
|
|
86
|
-
|
|
87
|
-
|
|
124
|
+
IDL types, error taxonomy, and conformance kit live inside the framework
|
|
125
|
+
itself under `packages/framework/src/driver-sdk/` — see that directory's
|
|
126
|
+
public-api-lock test for the surface contract.
|
|
88
127
|
|
|
89
128
|
## Execution
|
|
90
129
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
declare const VerificationStatusEnum: z.ZodEnum<{
|
|
3
3
|
skip: "skip";
|
|
4
|
-
fail: "fail";
|
|
5
4
|
pass: "pass";
|
|
5
|
+
fail: "fail";
|
|
6
6
|
}>;
|
|
7
7
|
declare const FileChangeSchema: z.ZodObject<{
|
|
8
8
|
path: z.ZodString;
|
|
@@ -11,23 +11,23 @@ declare const FileChangeSchema: z.ZodObject<{
|
|
|
11
11
|
declare const VerificationSchema: z.ZodObject<{
|
|
12
12
|
typecheck: z.ZodEnum<{
|
|
13
13
|
skip: "skip";
|
|
14
|
-
fail: "fail";
|
|
15
14
|
pass: "pass";
|
|
15
|
+
fail: "fail";
|
|
16
16
|
}>;
|
|
17
17
|
lint: z.ZodEnum<{
|
|
18
18
|
skip: "skip";
|
|
19
|
-
fail: "fail";
|
|
20
19
|
pass: "pass";
|
|
20
|
+
fail: "fail";
|
|
21
21
|
}>;
|
|
22
22
|
visual: z.ZodEnum<{
|
|
23
23
|
skip: "skip";
|
|
24
|
-
fail: "fail";
|
|
25
24
|
pass: "pass";
|
|
25
|
+
fail: "fail";
|
|
26
26
|
}>;
|
|
27
27
|
test: z.ZodEnum<{
|
|
28
28
|
skip: "skip";
|
|
29
|
-
fail: "fail";
|
|
30
29
|
pass: "pass";
|
|
30
|
+
fail: "fail";
|
|
31
31
|
}>;
|
|
32
32
|
evidence_path: z.ZodOptional<z.ZodString>;
|
|
33
33
|
}, z.core.$strip>;
|
|
@@ -50,23 +50,23 @@ export declare const QuickTaskSchema: z.ZodObject<{
|
|
|
50
50
|
verification: z.ZodObject<{
|
|
51
51
|
typecheck: z.ZodEnum<{
|
|
52
52
|
skip: "skip";
|
|
53
|
-
fail: "fail";
|
|
54
53
|
pass: "pass";
|
|
54
|
+
fail: "fail";
|
|
55
55
|
}>;
|
|
56
56
|
lint: z.ZodEnum<{
|
|
57
57
|
skip: "skip";
|
|
58
|
-
fail: "fail";
|
|
59
58
|
pass: "pass";
|
|
59
|
+
fail: "fail";
|
|
60
60
|
}>;
|
|
61
61
|
visual: z.ZodEnum<{
|
|
62
62
|
skip: "skip";
|
|
63
|
-
fail: "fail";
|
|
64
63
|
pass: "pass";
|
|
64
|
+
fail: "fail";
|
|
65
65
|
}>;
|
|
66
66
|
test: z.ZodEnum<{
|
|
67
67
|
skip: "skip";
|
|
68
|
-
fail: "fail";
|
|
69
68
|
pass: "pass";
|
|
69
|
+
fail: "fail";
|
|
70
70
|
}>;
|
|
71
71
|
evidence_path: z.ZodOptional<z.ZodString>;
|
|
72
72
|
}, z.core.$strip>;
|
|
@@ -96,10 +96,10 @@ export declare function validateQuickTask(data: unknown): z.ZodSafeParseResult<{
|
|
|
96
96
|
change: string;
|
|
97
97
|
}[];
|
|
98
98
|
verification: {
|
|
99
|
-
typecheck: "skip" | "
|
|
100
|
-
lint: "skip" | "
|
|
101
|
-
visual: "skip" | "
|
|
102
|
-
test: "skip" | "
|
|
99
|
+
typecheck: "skip" | "pass" | "fail";
|
|
100
|
+
lint: "skip" | "pass" | "fail";
|
|
101
|
+
visual: "skip" | "pass" | "fail";
|
|
102
|
+
test: "skip" | "pass" | "fail";
|
|
103
103
|
evidence_path?: string | undefined;
|
|
104
104
|
};
|
|
105
105
|
commit: {
|
|
@@ -124,23 +124,23 @@ export declare const quickTaskJsonSchema: z.core.ZodStandardJSONSchemaPayload<z.
|
|
|
124
124
|
verification: z.ZodObject<{
|
|
125
125
|
typecheck: z.ZodEnum<{
|
|
126
126
|
skip: "skip";
|
|
127
|
-
fail: "fail";
|
|
128
127
|
pass: "pass";
|
|
128
|
+
fail: "fail";
|
|
129
129
|
}>;
|
|
130
130
|
lint: z.ZodEnum<{
|
|
131
131
|
skip: "skip";
|
|
132
|
-
fail: "fail";
|
|
133
132
|
pass: "pass";
|
|
133
|
+
fail: "fail";
|
|
134
134
|
}>;
|
|
135
135
|
visual: z.ZodEnum<{
|
|
136
136
|
skip: "skip";
|
|
137
|
-
fail: "fail";
|
|
138
137
|
pass: "pass";
|
|
138
|
+
fail: "fail";
|
|
139
139
|
}>;
|
|
140
140
|
test: z.ZodEnum<{
|
|
141
141
|
skip: "skip";
|
|
142
|
-
fail: "fail";
|
|
143
142
|
pass: "pass";
|
|
143
|
+
fail: "fail";
|
|
144
144
|
}>;
|
|
145
145
|
evidence_path: z.ZodOptional<z.ZodString>;
|
|
146
146
|
}, z.core.$strip>;
|
package/drivers/.gitkeep
ADDED
|
File without changes
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# API Driver
|
|
2
|
+
|
|
3
|
+
Bundled HTTP-shape verify-proof driver for JSON-API regression tests.
|
|
4
|
+
Uses Node 18+ built-in `fetch` — no external dependencies.
|
|
5
|
+
|
|
6
|
+
## When Aperant picks this driver
|
|
7
|
+
|
|
8
|
+
`/apt:verify-proof` auto-selects `api` when:
|
|
9
|
+
|
|
10
|
+
- The project exposes HTTP endpoints (Express/Fastify/Hono/Next-API).
|
|
11
|
+
- The required IDL capabilities are: `execute_js`, `assert_network`,
|
|
12
|
+
`assert_output`, `assert_text`, `capture_logs`.
|
|
13
|
+
|
|
14
|
+
## Capabilities
|
|
15
|
+
|
|
16
|
+
| IDL verb | Behavior |
|
|
17
|
+
|----------|----------|
|
|
18
|
+
| `execute_js` | Evaluate a request-builder snippet (e.g. compute headers) |
|
|
19
|
+
| `assert_network` | Assert HTTP endpoint returns expected status/body |
|
|
20
|
+
| `assert_output` | Match pattern against captured response body |
|
|
21
|
+
| `assert_text` | Match pattern against any captured text artifact |
|
|
22
|
+
| `capture_logs` | Append request/response pairs to evidence file |
|
|
23
|
+
|
|
24
|
+
## Manifest
|
|
25
|
+
|
|
26
|
+
- **Priority:** 50 (below cli=60 — API tests are more specific).
|
|
27
|
+
- **Stability:** `ga`.
|
|
28
|
+
- **Trust:** `first_party_signed`.
|
|
29
|
+
- **Network posture:** `allowlist`. The allowlist is enforced at the
|
|
30
|
+
workflow-runner layer (fetch wrapper consults
|
|
31
|
+
`.aperant/config.json:verification.api.allowlist[]`).
|
|
32
|
+
- **Sandbox profile:** `read_only` — the driver doesn't write to the
|
|
33
|
+
workspace; only emits evidence files under `proof_dir/`.
|
|
34
|
+
- **Transport:** `{ builtin: true }`.
|
|
35
|
+
|
|
36
|
+
## V1 scope — adapter is thin
|
|
37
|
+
|
|
38
|
+
`driver.mjs` is a v1 manifest-conformant adapter shim — each verb
|
|
39
|
+
validates its args and returns a VerbResult stub. Direct-dispatch via
|
|
40
|
+
`fetch` lands in `verify-proof-driver-transport-wiring-v2` (follow-up).
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* api/driver.mjs — bundled API-shape driver.
|
|
3
|
+
*
|
|
4
|
+
* Targets HTTP-shape assertions and JSON-API regression tests. Uses
|
|
5
|
+
* built-in node:fetch (Node 18+). The transport is `{ builtin: true }` —
|
|
6
|
+
* the driver makes HTTP requests directly via fetch().
|
|
7
|
+
*
|
|
8
|
+
* Capabilities (5):
|
|
9
|
+
* - execute_js — evaluate a small request-builder snippet
|
|
10
|
+
* - assert_network — assert an HTTP endpoint returns expected status/body
|
|
11
|
+
* - assert_output — match a pattern against a captured response body
|
|
12
|
+
* - assert_text — match a pattern against any captured text artifact
|
|
13
|
+
* - capture_logs — append request/response pairs to an evidence file
|
|
14
|
+
*
|
|
15
|
+
* Network posture is `allowlist` in the manifest — only allowlisted
|
|
16
|
+
* hosts are reachable. The allowlist itself is enforced at the
|
|
17
|
+
* workflow-runner layer (fetch wrapper that consults
|
|
18
|
+
* .aperant/config.json:verification.api.allowlist[]).
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { validateVerbArgs } from '../../src/cli/verify-proof/idl/index.mjs'
|
|
22
|
+
|
|
23
|
+
function ok(evidence_paths = []) {
|
|
24
|
+
return { status: 'success', evidence_paths, duration_ms: 0, retry_count: 0 }
|
|
25
|
+
}
|
|
26
|
+
function fail(error) {
|
|
27
|
+
return { status: 'fail', evidence_paths: [], duration_ms: 0, retry_count: 0, error }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function adaptVerb(verb, args) {
|
|
31
|
+
const check = validateVerbArgs(verb, args)
|
|
32
|
+
if (!check.valid) {
|
|
33
|
+
return fail(`api.${verb}: missing required args: ${check.missing.join(', ')}`)
|
|
34
|
+
}
|
|
35
|
+
if (verb === 'capture_logs' && typeof args.output_path === 'string') {
|
|
36
|
+
return ok([args.output_path])
|
|
37
|
+
}
|
|
38
|
+
return ok()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function execute_js(args) {
|
|
42
|
+
return adaptVerb('execute_js', args)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export async function assert_network(args) {
|
|
46
|
+
return adaptVerb('assert_network', args)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export async function assert_output(args) {
|
|
50
|
+
return adaptVerb('assert_output', args)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function assert_text(args) {
|
|
54
|
+
return adaptVerb('assert_text', args)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export async function capture_logs(args) {
|
|
58
|
+
return adaptVerb('capture_logs', args)
|
|
59
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"driverId": "api",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"targets": ["api", "node"],
|
|
5
|
+
"capabilities": ["execute_js", "assert_network", "assert_output", "assert_text", "capture_logs"],
|
|
6
|
+
"evidence_capabilities": ["capture_logs"],
|
|
7
|
+
"frameworkApiRange": "^1.0.0",
|
|
8
|
+
"priority": 50,
|
|
9
|
+
"stability": "ga",
|
|
10
|
+
"trust": {
|
|
11
|
+
"tier": "first_party_signed",
|
|
12
|
+
"publisher": {
|
|
13
|
+
"name": "Aperant",
|
|
14
|
+
"npm_scope": "@aperant",
|
|
15
|
+
"github_org": "Mikalsen-AI",
|
|
16
|
+
"verified": true
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"security": {
|
|
20
|
+
"sandbox_profile": "read_only",
|
|
21
|
+
"network": "allowlist",
|
|
22
|
+
"requires_user_approval": false
|
|
23
|
+
},
|
|
24
|
+
"audit": { "log_invocations": true, "log_manifest_hash": true },
|
|
25
|
+
"transport": { "builtin": true }
|
|
26
|
+
}
|