@codyswann/lisa 2.211.2 → 2.212.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/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-implement/SKILL.md +16 -4
- package/plugins/lisa/hooks/enforce-verification-gate.sh +1 -1
- package/plugins/lisa/rules/eager/tool-access-gate.md +21 -0
- package/plugins/lisa/rules/reference/intent-routing.md +2 -2
- package/plugins/lisa/rules/reference/tool-access-gate.md +121 -0
- package/plugins/lisa/skills/lisa-implement/SKILL.md +16 -4
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-implement/SKILL.md +16 -4
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/hooks/enforce-verification-gate.sh +1 -1
- package/plugins/lisa-copilot/rules/eager/tool-access-gate.md +21 -0
- package/plugins/lisa-copilot/rules/reference/intent-routing.md +2 -2
- package/plugins/lisa-copilot/rules/reference/tool-access-gate.md +121 -0
- package/plugins/lisa-copilot/skills/lisa-implement/SKILL.md +16 -4
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/enforce-verification-gate.sh +1 -1
- package/plugins/lisa-cursor/rules/intent-routing-reference.mdc +2 -2
- package/plugins/lisa-cursor/rules/tool-access-gate-reference.mdc +126 -0
- package/plugins/lisa-cursor/rules/tool-access-gate.mdc +26 -0
- package/plugins/lisa-cursor/skills/lisa-implement/SKILL.md +16 -4
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/hooks/enforce-verification-gate.sh +1 -1
- package/plugins/src/base/rules/eager/tool-access-gate.md +21 -0
- package/plugins/src/base/rules/reference/intent-routing.md +2 -2
- package/plugins/src/base/rules/reference/tool-access-gate.md +121 -0
- package/plugins/src/base/skills/lisa-implement/SKILL.md +16 -4
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Tool Access Gate
|
|
2
|
+
|
|
3
|
+
A flow may only take on work it can actually finish. If completing a work item —
|
|
4
|
+
including its empirical verification — requires an external tool or system the
|
|
5
|
+
agent cannot access, the flow must **break out and report the missing access on
|
|
6
|
+
the work item**, never work around it. This is the flow-side arm of the factory
|
|
7
|
+
contract: intake validates that the factory has "the tooling *and provable
|
|
8
|
+
access to that tooling*"; this gate re-proves that promise at execution time and
|
|
9
|
+
enforces it for tools discovered mid-flow.
|
|
10
|
+
|
|
11
|
+
"Tool" means any external surface the work depends on, for example:
|
|
12
|
+
|
|
13
|
+
- Cloud/provider CLIs and APIs: AWS (CloudWatch logs, S3, …), GCP, Azure
|
|
14
|
+
- Design sources: Figma
|
|
15
|
+
- Bug/session capture: Jam
|
|
16
|
+
- Observability: Sentry, PostHog, CloudWatch
|
|
17
|
+
- Quality gates: SonarCloud
|
|
18
|
+
- Trackers and docs: JIRA/Confluence, Linear, Notion, GitHub
|
|
19
|
+
- Device/browser harnesses: Playwright, Maestro, Detox, simulators/emulators
|
|
20
|
+
- Databases, deploy targets, and protected environments
|
|
21
|
+
|
|
22
|
+
## When the gate runs
|
|
23
|
+
|
|
24
|
+
1. **Preflight** — after the completion condition is defined and before any
|
|
25
|
+
implementation task starts, enumerate every tool required by (a) the
|
|
26
|
+
implementation itself, (b) the proof command / verification plan, and
|
|
27
|
+
(c) remote verification and post-deploy checks. Sources for the enumeration:
|
|
28
|
+
the work item (description, comments, attachments — a Figma link or Jam
|
|
29
|
+
capture implies that tool), acceptance criteria, `testing_requirements`,
|
|
30
|
+
the `verification` metadata, and the deploy pipeline for the target
|
|
31
|
+
environment.
|
|
32
|
+
2. **Continuously** — the moment a previously unknown tool requirement surfaces
|
|
33
|
+
mid-flow (e.g. verification turns out to need CloudWatch log capture), probe
|
|
34
|
+
it right then and record the new tool + probe result in the same places the
|
|
35
|
+
preflight wrote to (the plan/tracker artifact and the affected tasks'
|
|
36
|
+
`metadata.required_access`) before continuing. Discovery timing changes
|
|
37
|
+
nothing about the protocol.
|
|
38
|
+
|
|
39
|
+
## Proving access
|
|
40
|
+
|
|
41
|
+
Access is proven by a **cheap, read-only probe that actually exercises the
|
|
42
|
+
authenticated surface** — tool presence on PATH is not access.
|
|
43
|
+
|
|
44
|
+
- Vendors with an access layer MUST be probed through their `*-access` skill
|
|
45
|
+
(see the `integration-access-layer` rule): `lisa-atlassian-access`,
|
|
46
|
+
`lisa-notion-access`, `lisa-linear-access`, `lisa-jam-access`,
|
|
47
|
+
`lisa-sonarcloud-access`, `lisa-sentry-access`, `lisa-posthog-access`,
|
|
48
|
+
`lisa-expo:play-store-access`. A loud access-skill failure naming a missing
|
|
49
|
+
env var IS a failed probe.
|
|
50
|
+
- Vendors without an access layer are probed with the cheapest authenticated
|
|
51
|
+
read the runtime offers (an MCP tool call, a CLI read, a REST GET).
|
|
52
|
+
|
|
53
|
+
Example probes:
|
|
54
|
+
|
|
55
|
+
| Tool | Probe |
|
|
56
|
+
|---|---|
|
|
57
|
+
| AWS CLI | `aws sts get-caller-identity`, plus the service-level read the task needs (e.g. `aws logs describe-log-groups --max-items 1`) |
|
|
58
|
+
| GitHub | a repository-scoped read against the target repo (e.g. `gh api repos/<owner>/<repo> --jq .full_name`, or the exact read the work item needs) — `gh auth status` alone only proves host auth, not access to the repository |
|
|
59
|
+
| Figma | a read call against the linked file via the available Figma MCP/API surface |
|
|
60
|
+
| Sentry / Jam / SonarCloud / PostHog / Atlassian / Linear / Notion | the matching `*-access` skill's resolve/auth check |
|
|
61
|
+
| Database | the project's documented read-only connection check |
|
|
62
|
+
| Deploy target | reach the target environment with the credentials the verify step will use |
|
|
63
|
+
| Device/browser harness | the harness's own doctor/smoke entry (e.g. `playwright --version` plus a trivial headless launch) |
|
|
64
|
+
|
|
65
|
+
A probe failure only counts **after exhausting the documented credential
|
|
66
|
+
sources** (the same order the `verification` rule mandates): project e2e
|
|
67
|
+
config/fixtures, `.lisa.config.local.json` and environment variables, then
|
|
68
|
+
documented work-item credentials (e.g. `Sign-in Required`). Missing access you
|
|
69
|
+
could have resolved from those sources is not a blocker — resolve it and
|
|
70
|
+
proceed.
|
|
71
|
+
|
|
72
|
+
Record the enumeration and probe results in the flow's plan/tracker artifact
|
|
73
|
+
(and task `metadata.required_access` where the flow's task contract carries
|
|
74
|
+
it), so the verifier can confirm the gate ran.
|
|
75
|
+
|
|
76
|
+
## On failure: break out, never work around
|
|
77
|
+
|
|
78
|
+
When a required tool fails its probe:
|
|
79
|
+
|
|
80
|
+
1. **Stop the affected work immediately.** Do not start (or continue)
|
|
81
|
+
implementation whose completion condition cannot be proven.
|
|
82
|
+
2. **Update the work item with an "Access Needed" comment** containing, for
|
|
83
|
+
each missing tool:
|
|
84
|
+
- a one-sentence plain-English summary a non-technical operator can act on
|
|
85
|
+
("Lisa needs read access to the app's AWS logs to prove this fix works");
|
|
86
|
+
- the tool and the operation it is needed for (which acceptance criterion /
|
|
87
|
+
verification step);
|
|
88
|
+
- the exact access to grant: env var name, credential/role/permission, or
|
|
89
|
+
account invitation required;
|
|
90
|
+
- the probe command that must pass once access is granted.
|
|
91
|
+
3. **Transition the work item to the configured blocked state** and apply the
|
|
92
|
+
configured `human_needed` / needs-human marker — missing access is a
|
|
93
|
+
**human-only blocker** (someone must provision credentials or grant access);
|
|
94
|
+
do not fabricate a build-ready ticket for it.
|
|
95
|
+
4. **Release the verification gate honestly**: write the verdict with
|
|
96
|
+
`status: "blocked"`, and mark each acceptance criterion whose proof depends
|
|
97
|
+
on the missing tool as `status: "blocked"` with the missing-access
|
|
98
|
+
diagnosis as its `evidence`; unaffected criteria keep their real
|
|
99
|
+
`pass`/`fail` result.
|
|
100
|
+
5. **Resume only when the probe passes.** When access is granted, re-run the
|
|
101
|
+
recorded probe before continuing; `repair-intake` re-validates blocked items
|
|
102
|
+
whose blockers cleared.
|
|
103
|
+
|
|
104
|
+
### Forbidden workarounds
|
|
105
|
+
|
|
106
|
+
None of the following ever substitutes for missing access:
|
|
107
|
+
|
|
108
|
+
- Swapping the verification for a weaker one the agent *can* run (unit tests or
|
|
109
|
+
code reading instead of the required log capture / UI observation).
|
|
110
|
+
- Mocking, stubbing, or simulating the inaccessible system to make the proof
|
|
111
|
+
"pass".
|
|
112
|
+
- Marking work done on artifact-only evidence, or asserting success without the
|
|
113
|
+
runtime evidence the completion condition demands.
|
|
114
|
+
- Guessing at the tool's contents (e.g. implementing a design without reading
|
|
115
|
+
the linked Figma file, or "fixing" a bug without the Jam/Sentry evidence the
|
|
116
|
+
ticket points at).
|
|
117
|
+
- Silently narrowing scope so the inaccessible part is "out of scope".
|
|
118
|
+
|
|
119
|
+
If a *partial* set of tasks is unaffected by the missing access, those tasks may
|
|
120
|
+
complete, but the work item as a whole must not be marked terminal-done while
|
|
121
|
+
any acceptance criterion's proof is blocked on access.
|
|
@@ -138,9 +138,18 @@ This condition is the contract the Verify flow proves and records in the verific
|
|
|
138
138
|
1. Direct deploy the changes to dev and then Write a simple API client and call the offending API
|
|
139
139
|
2. Start the server on localhost and then Use the Playwright CLI or Chrome DevTools
|
|
140
140
|
|
|
141
|
+
Using the general-purpose agent in Team Lead session, run the **tool access preflight** per the `tool-access-gate` rule (loaded via the lisa plugin) before any implementation task is created or started:
|
|
142
|
+
|
|
143
|
+
1. Enumerate every external tool or system this flow will need — for the implementation itself, for the proof command, and for remote verification (AWS CLI/CloudWatch, Figma, Jam, Sentry, SonarCloud, PostHog, device/browser harnesses, databases, deploy targets, trackers, …). Derive the list from the resolved work item (a linked Figma file, Jam capture, or Sentry issue implies that tool), the acceptance criteria, the testing requirements, and the completion condition above.
|
|
144
|
+
2. Prove access to each with its cheapest read-only probe, routing through the matching `*-access` skill where one exists (`integration-access-layer` rule). Tool presence on PATH is not access; a probe failure counts only after exhausting the documented credential sources (project e2e config/fixtures, `.lisa.config.local.json` / env vars, documented work-item credentials).
|
|
145
|
+
3. Record the enumeration and probe results in the plan artifact and in each task's `metadata.required_access`.
|
|
146
|
+
4. If any required tool fails its probe, do NOT start implementation — follow the break-out protocol in the `tool-access-gate` rule: post an "Access Needed" comment on the work item (plain-English summary, the exact credential/role/env var to grant, the probe that must pass), transition the item to the configured blocked state with the `human_needed` marker, write the verification verdict with `status: "blocked"`, and stop. Working around missing access — substituting weaker verification, mocking the inaccessible system, guessing at tool contents, or narrowing scope — is never permitted, for any tool.
|
|
147
|
+
|
|
148
|
+
The same gate applies **continuously**: if a tool requirement surfaces mid-flow (e.g. verification turns out to need CloudWatch log capture the runtime cannot authenticate to), probe it the moment it is discovered, record the new tool and probe result in the plan artifact and the affected tasks' `metadata.required_access` before continuing, and break out identically on failure.
|
|
149
|
+
|
|
141
150
|
Using the general-purpose agent in Team Lead session, create tasks needed to complete the request.
|
|
142
151
|
|
|
143
|
-
Every task MUST include this JSON metadata block. Do NOT omit `skills` (use `[]` if none), `learnings` (use `[]` if none) or `verification`.
|
|
152
|
+
Every task MUST include this JSON metadata block. Do NOT omit `skills` (use `[]` if none), `learnings` (use `[]` if none), `required_access` (use `[]` if the task needs no external tool) or `verification`.
|
|
144
153
|
|
|
145
154
|
```json
|
|
146
155
|
{
|
|
@@ -151,6 +160,9 @@ Every task MUST include this JSON metadata block. Do NOT omit `skills` (use `[]`
|
|
|
151
160
|
"testing_requirements": ["..."],
|
|
152
161
|
"skills": ["..."],
|
|
153
162
|
"learnings": ["..."],
|
|
163
|
+
"required_access": [
|
|
164
|
+
{ "tool": "<external tool/system this task or its verification needs>", "probe": "<the read-only command or *-access check that proves access>", "status": "pass|fail" }
|
|
165
|
+
],
|
|
154
166
|
"verification": {
|
|
155
167
|
"type": "ui-recording|api-test|cli-test|database-check|manual-check|documentation",
|
|
156
168
|
"command": "the proof command — must run the actual system and surface its result in the transcript (NOT test/typecheck/lint, those are quality gates). Phrase it so an independent verifier sees the evidence, e.g. `curl -s localhost:3000/health` not `check that health works`",
|
|
@@ -177,7 +189,7 @@ Before shutting down the team, execute the Verify flow:
|
|
|
177
189
|
"plan": "<plan-name>",
|
|
178
190
|
"status": "pass | fail | blocked | in_progress",
|
|
179
191
|
"criteria": [
|
|
180
|
-
{ "task": "<task id or title>", "criterion": "<the completion condition>", "status": "pass | fail", "evidence": "<the proof command run and the observed result>" }
|
|
192
|
+
{ "task": "<task id or title>", "criterion": "<the completion condition>", "status": "pass | fail | blocked", "evidence": "<the proof command run and the observed result; for a blocked criterion, the blocker diagnosis (e.g. the missing access and the probe that must pass)>" }
|
|
181
193
|
],
|
|
182
194
|
"updated_at": "<ISO8601 UTC>"
|
|
183
195
|
}
|
|
@@ -185,10 +197,10 @@ Before shutting down the team, execute the Verify flow:
|
|
|
185
197
|
|
|
186
198
|
Set `status: "pass"` only when every criterion is `pass` with real evidence (output from running the system, not a claim). The verdict must be judged by an agent that did NOT implement the change (the `verification-specialist`), never self-certified by the implementer. This is runtime scratch — it is gitignored and MUST NOT be committed (treat it like the secrets exclusion in the commit step).
|
|
187
199
|
|
|
188
|
-
On Claude, the `enforce-verification-gate.sh` Stop hook reads this file and **will not let the flow stop** until it shows a terminal, all-`pass` verdict — carrying over the non-bypassable completion gate of the `/goal` primitive, but checked deterministically against real evidence rather than by a transcript-only evaluator model. If you must stop before completion, write the verdict with `status: "blocked"` and the reason — that records the outcome and releases the gate instead of leaving it to spin. But a `blocked` verdict is a last resort, not a shortcut around fillable work: **first resolve every gap you can resolve yourself.** If the work item is thin — missing its Validation Journey, acceptance criteria, or other derivable detail — enrich it: derive the missing detail from the ticket context and the codebase, write it back, and proceed. Do **not** block on a gap you could have filled. Only a blocker that survives that attempt is real, and it is one of two kinds:
|
|
200
|
+
On Claude, the `enforce-verification-gate.sh` Stop hook reads this file and **will not let the flow stop** until it shows a terminal, all-`pass` verdict — carrying over the non-bypassable completion gate of the `/goal` primitive, but checked deterministically against real evidence rather than by a transcript-only evaluator model. If you must stop before completion, write the verdict with `status: "blocked"` and the reason — marking each criterion whose proof is blocked as `status: "blocked"` with the blocker diagnosis as its `evidence`, while unaffected criteria keep their real `pass`/`fail` result — that records the outcome and releases the gate instead of leaving it to spin. But a `blocked` verdict is a last resort, not a shortcut around fillable work: **first resolve every gap you can resolve yourself.** If the work item is thin — missing its Validation Journey, acceptance criteria, or other derivable detail — enrich it: derive the missing detail from the ticket context and the codebase, write it back, and proceed. Do **not** block on a gap you could have filled. Only a blocker that survives that attempt is real, and it is one of two kinds:
|
|
189
201
|
|
|
190
202
|
- **Actionable blocker** — an unresolved dependency or fixable technical gap that some team or repository could build (a missing or changed schema field, an unbuilt sibling work item, a required upstream fix), **including cross-repo dependencies**. Before writing the blocked verdict you MUST (1) file a build-ready fix/dependency ticket capturing the diagnosis — in the dependency's own repository/tracker when it is cross-repo (e.g. a `[<repo>] …` ticket in the shared project, or the sibling tracker) — and (2) link the current work item to it as `is blocked by`. Only then write the verdict. This is the same discipline as the regression-spec blocker and the remote-verification-fail exits above, and it is what makes the block machine-recoverable: `repair-intake` re-dispatches a blocked item once its linked `is blocked by` dependency closes, but it cannot act on a prose-only comment. Recommending the ticket "as a human follow-up" without filing and linking it is **not** a permitted exit.
|
|
191
|
-
- **Human-only blocker** — an input the agent genuinely cannot obtain or produce no matter what it does: credentials or
|
|
203
|
+
- **Human-only blocker** — an input the agent genuinely cannot obtain or produce no matter what it does: credentials, secrets, or **tool access** it does not have (AWS/CloudWatch, Figma, Jam, Sentry, SonarCloud, a database, a protected deploy target, …), or a product/design decision only a human can make. For missing tool access, follow the `tool-access-gate` rule's break-out protocol: post the "Access Needed" comment naming the exact credential/role/env var to grant and the probe that must pass — never work around the gap by substituting weaker verification, mocking the inaccessible system, or narrowing scope. Record the blocked verdict, mark it `human_needed` (the marker `repair-intake` recognizes, so it won't churn re-dispatching it), and surface or reassign to a human; do **not** fabricate a build-ready ticket, because there is no build-ready work.
|
|
192
204
|
|
|
193
205
|
Other harnesses fall back to this prose obligation.
|
|
194
206
|
3. Write the highest-practical-observation regression test encoding the verification. For user-visible bugs or user-visible Build changes with an available browser/device/e2e harness, this means a deterministic spec on the reported surface. Prove the new spec actually executed and passed in PR CI by recording a named spec log/reporter line or equivalent execution record; green CI without that named evidence does not satisfy this step.
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
# "plan": "<plan-name>",
|
|
33
33
|
# "status": "pass" | "fail" | "blocked" | "in_progress",
|
|
34
34
|
# "criteria": [
|
|
35
|
-
# { "task": "...", "criterion": "...", "status": "pass" | "fail", "evidence": "..." }
|
|
35
|
+
# { "task": "...", "criterion": "...", "status": "pass" | "fail" | "blocked", "evidence": "..." }
|
|
36
36
|
# ],
|
|
37
37
|
# "updated_at": "<ISO8601 UTC>"
|
|
38
38
|
# }
|
|
@@ -72,8 +72,8 @@ Sequence:
|
|
|
72
72
|
2. `product-specialist` -- define user goals, user flows (Gherkin), acceptance criteria, error states, UX concerns, and out-of-scope items
|
|
73
73
|
3. **Edge Case Brainstorm sub-flow** -- run the PRD candidate through the edge-case checklist; fold accepted cases into acceptance criteria, out-of-scope, or open questions
|
|
74
74
|
4. `architecture-specialist` -- assess technical feasibility, identify constraints, map existing system boundaries
|
|
75
|
-
5. Synthesize findings into a PRD containing: problem statement, user stories, acceptance criteria, technical constraints, open questions, and proposed scope
|
|
76
|
-
6. **Plan Phase Tooling** -- review all available skills and agents (project-defined, plugin-provided, and built-in) and determine which ones the Plan phase will need. For each recommended skill or agent, state why it is needed. If no skills or agents beyond the defaults are identified, explicitly justify why the standard set is sufficient. Include this as a "Recommended Tooling for Plan Phase" section in the PRD.
|
|
75
|
+
5. Synthesize findings into a PRD containing: problem statement, user stories, acceptance criteria, technical constraints, open questions, and proposed scope. Any technically viable but genuinely unresolved choice discovered during drafting (for example, a library, framework, or architecture decision with more than one live candidate) MUST be captured as an entry under open questions -- never written into any other section, including the "Recommended Tooling for Plan Phase" section in step 6, as though it were already decided. Every open-questions entry MUST include the drafter's own recommended resolution, with a one-sentence rationale, alongside the question; an open question must never be left bare.
|
|
76
|
+
6. **Plan Phase Tooling** -- review all available skills and agents (project-defined, plugin-provided, and built-in) and determine which ones the Plan phase will need. For each recommended skill or agent, state why it is needed. If no skills or agents beyond the defaults are identified, explicitly justify why the standard set is sufficient. Include this as a "Recommended Tooling for Plan Phase" section in the PRD. This section documents settled recommendations for how to run the Plan phase, meaning which skills or agents to use; it MUST NOT be used to record an unresolved product or technical decision, such as "use library X" when X vs. Y was never actually decided. If step 5 surfaced an unresolved technical choice, it belongs in open questions with a recommendation, not here.
|
|
77
77
|
7. **Create the PRD in the configured source** -- invoke `lisa-prd-source-write` with the synthesized PRD (`title`, `body`, `initial_role` resolved from the caller's `prd_ready` flag — `draft` by default, `ready` when `prd_ready=true`, plus any `dedupe_key`/`marker`/`source_ref` the caller passed). The PRD **lives in the source** (Notion page / Confluence page / GitHub issue / Linear project per `.lisa.config.json` `source`); there is no separate document artifact. A `source` must be configured — if it is not, stop and report it. `prd-source-write` dedupes by marker, so re-running against the same idea references the existing PRD instead of creating a duplicate.
|
|
78
78
|
8. **Record Research usage on the PRD artifact** -- invoke `lisa-usage-accounting` against the created PRD/source artifact so it gains a direct `research` usage entry in the canonical `## Lisa Usage` section at creation time. If the runtime cannot provide trustworthy usage, still write the row with `source: unavailable` and nullable token/cost fields; missing usage is never treated as zero or silently omitted.
|
|
79
79
|
9. `learner` -- capture discoveries for future sessions
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Tool Access Gate"
|
|
3
|
+
alwaysApply: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Tool Access Gate
|
|
7
|
+
|
|
8
|
+
A flow may only take on work it can actually finish. If completing a work item —
|
|
9
|
+
including its empirical verification — requires an external tool or system the
|
|
10
|
+
agent cannot access, the flow must **break out and report the missing access on
|
|
11
|
+
the work item**, never work around it. This is the flow-side arm of the factory
|
|
12
|
+
contract: intake validates that the factory has "the tooling *and provable
|
|
13
|
+
access to that tooling*"; this gate re-proves that promise at execution time and
|
|
14
|
+
enforces it for tools discovered mid-flow.
|
|
15
|
+
|
|
16
|
+
"Tool" means any external surface the work depends on, for example:
|
|
17
|
+
|
|
18
|
+
- Cloud/provider CLIs and APIs: AWS (CloudWatch logs, S3, …), GCP, Azure
|
|
19
|
+
- Design sources: Figma
|
|
20
|
+
- Bug/session capture: Jam
|
|
21
|
+
- Observability: Sentry, PostHog, CloudWatch
|
|
22
|
+
- Quality gates: SonarCloud
|
|
23
|
+
- Trackers and docs: JIRA/Confluence, Linear, Notion, GitHub
|
|
24
|
+
- Device/browser harnesses: Playwright, Maestro, Detox, simulators/emulators
|
|
25
|
+
- Databases, deploy targets, and protected environments
|
|
26
|
+
|
|
27
|
+
## When the gate runs
|
|
28
|
+
|
|
29
|
+
1. **Preflight** — after the completion condition is defined and before any
|
|
30
|
+
implementation task starts, enumerate every tool required by (a) the
|
|
31
|
+
implementation itself, (b) the proof command / verification plan, and
|
|
32
|
+
(c) remote verification and post-deploy checks. Sources for the enumeration:
|
|
33
|
+
the work item (description, comments, attachments — a Figma link or Jam
|
|
34
|
+
capture implies that tool), acceptance criteria, `testing_requirements`,
|
|
35
|
+
the `verification` metadata, and the deploy pipeline for the target
|
|
36
|
+
environment.
|
|
37
|
+
2. **Continuously** — the moment a previously unknown tool requirement surfaces
|
|
38
|
+
mid-flow (e.g. verification turns out to need CloudWatch log capture), probe
|
|
39
|
+
it right then and record the new tool + probe result in the same places the
|
|
40
|
+
preflight wrote to (the plan/tracker artifact and the affected tasks'
|
|
41
|
+
`metadata.required_access`) before continuing. Discovery timing changes
|
|
42
|
+
nothing about the protocol.
|
|
43
|
+
|
|
44
|
+
## Proving access
|
|
45
|
+
|
|
46
|
+
Access is proven by a **cheap, read-only probe that actually exercises the
|
|
47
|
+
authenticated surface** — tool presence on PATH is not access.
|
|
48
|
+
|
|
49
|
+
- Vendors with an access layer MUST be probed through their `*-access` skill
|
|
50
|
+
(see the `integration-access-layer` rule): `lisa-atlassian-access`,
|
|
51
|
+
`lisa-notion-access`, `lisa-linear-access`, `lisa-jam-access`,
|
|
52
|
+
`lisa-sonarcloud-access`, `lisa-sentry-access`, `lisa-posthog-access`,
|
|
53
|
+
`lisa-expo:play-store-access`. A loud access-skill failure naming a missing
|
|
54
|
+
env var IS a failed probe.
|
|
55
|
+
- Vendors without an access layer are probed with the cheapest authenticated
|
|
56
|
+
read the runtime offers (an MCP tool call, a CLI read, a REST GET).
|
|
57
|
+
|
|
58
|
+
Example probes:
|
|
59
|
+
|
|
60
|
+
| Tool | Probe |
|
|
61
|
+
|---|---|
|
|
62
|
+
| AWS CLI | `aws sts get-caller-identity`, plus the service-level read the task needs (e.g. `aws logs describe-log-groups --max-items 1`) |
|
|
63
|
+
| GitHub | a repository-scoped read against the target repo (e.g. `gh api repos/<owner>/<repo> --jq .full_name`, or the exact read the work item needs) — `gh auth status` alone only proves host auth, not access to the repository |
|
|
64
|
+
| Figma | a read call against the linked file via the available Figma MCP/API surface |
|
|
65
|
+
| Sentry / Jam / SonarCloud / PostHog / Atlassian / Linear / Notion | the matching `*-access` skill's resolve/auth check |
|
|
66
|
+
| Database | the project's documented read-only connection check |
|
|
67
|
+
| Deploy target | reach the target environment with the credentials the verify step will use |
|
|
68
|
+
| Device/browser harness | the harness's own doctor/smoke entry (e.g. `playwright --version` plus a trivial headless launch) |
|
|
69
|
+
|
|
70
|
+
A probe failure only counts **after exhausting the documented credential
|
|
71
|
+
sources** (the same order the `verification` rule mandates): project e2e
|
|
72
|
+
config/fixtures, `.lisa.config.local.json` and environment variables, then
|
|
73
|
+
documented work-item credentials (e.g. `Sign-in Required`). Missing access you
|
|
74
|
+
could have resolved from those sources is not a blocker — resolve it and
|
|
75
|
+
proceed.
|
|
76
|
+
|
|
77
|
+
Record the enumeration and probe results in the flow's plan/tracker artifact
|
|
78
|
+
(and task `metadata.required_access` where the flow's task contract carries
|
|
79
|
+
it), so the verifier can confirm the gate ran.
|
|
80
|
+
|
|
81
|
+
## On failure: break out, never work around
|
|
82
|
+
|
|
83
|
+
When a required tool fails its probe:
|
|
84
|
+
|
|
85
|
+
1. **Stop the affected work immediately.** Do not start (or continue)
|
|
86
|
+
implementation whose completion condition cannot be proven.
|
|
87
|
+
2. **Update the work item with an "Access Needed" comment** containing, for
|
|
88
|
+
each missing tool:
|
|
89
|
+
- a one-sentence plain-English summary a non-technical operator can act on
|
|
90
|
+
("Lisa needs read access to the app's AWS logs to prove this fix works");
|
|
91
|
+
- the tool and the operation it is needed for (which acceptance criterion /
|
|
92
|
+
verification step);
|
|
93
|
+
- the exact access to grant: env var name, credential/role/permission, or
|
|
94
|
+
account invitation required;
|
|
95
|
+
- the probe command that must pass once access is granted.
|
|
96
|
+
3. **Transition the work item to the configured blocked state** and apply the
|
|
97
|
+
configured `human_needed` / needs-human marker — missing access is a
|
|
98
|
+
**human-only blocker** (someone must provision credentials or grant access);
|
|
99
|
+
do not fabricate a build-ready ticket for it.
|
|
100
|
+
4. **Release the verification gate honestly**: write the verdict with
|
|
101
|
+
`status: "blocked"`, and mark each acceptance criterion whose proof depends
|
|
102
|
+
on the missing tool as `status: "blocked"` with the missing-access
|
|
103
|
+
diagnosis as its `evidence`; unaffected criteria keep their real
|
|
104
|
+
`pass`/`fail` result.
|
|
105
|
+
5. **Resume only when the probe passes.** When access is granted, re-run the
|
|
106
|
+
recorded probe before continuing; `repair-intake` re-validates blocked items
|
|
107
|
+
whose blockers cleared.
|
|
108
|
+
|
|
109
|
+
### Forbidden workarounds
|
|
110
|
+
|
|
111
|
+
None of the following ever substitutes for missing access:
|
|
112
|
+
|
|
113
|
+
- Swapping the verification for a weaker one the agent *can* run (unit tests or
|
|
114
|
+
code reading instead of the required log capture / UI observation).
|
|
115
|
+
- Mocking, stubbing, or simulating the inaccessible system to make the proof
|
|
116
|
+
"pass".
|
|
117
|
+
- Marking work done on artifact-only evidence, or asserting success without the
|
|
118
|
+
runtime evidence the completion condition demands.
|
|
119
|
+
- Guessing at the tool's contents (e.g. implementing a design without reading
|
|
120
|
+
the linked Figma file, or "fixing" a bug without the Jam/Sentry evidence the
|
|
121
|
+
ticket points at).
|
|
122
|
+
- Silently narrowing scope so the inaccessible part is "out of scope".
|
|
123
|
+
|
|
124
|
+
If a *partial* set of tasks is unaffected by the missing access, those tasks may
|
|
125
|
+
complete, but the work item as a whole must not be marked terminal-done while
|
|
126
|
+
any acceptance criterion's proof is blocked on access.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Tool Access Gate (load-bearing)"
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Tool Access Gate (load-bearing)
|
|
7
|
+
|
|
8
|
+
Only take on work you can finish. Before implementation starts — and again the
|
|
9
|
+
moment a new requirement surfaces mid-flow — enumerate every external tool the
|
|
10
|
+
work item needs (implementation, proof command, remote verification: AWS CLI,
|
|
11
|
+
Figma, Jam, Sentry, SonarCloud, PostHog, device/browser harnesses, databases,
|
|
12
|
+
deploy targets, …) and **prove access with a cheap read-only probe**, routing
|
|
13
|
+
through the matching `*-access` skill where one exists. Presence on PATH is not
|
|
14
|
+
access; a probe failure counts only after exhausting documented credential
|
|
15
|
+
sources.
|
|
16
|
+
|
|
17
|
+
If a required tool is inaccessible: **break out — never work around it.** Post
|
|
18
|
+
an "Access Needed" comment on the work item (plain-English summary, the exact
|
|
19
|
+
credential/role/env var to grant, and the probe that must pass), transition it
|
|
20
|
+
to the configured blocked state with the `human_needed` marker, and write a
|
|
21
|
+
`blocked` verification verdict. Substituting weaker verification, mocking the
|
|
22
|
+
inaccessible system, guessing at tool contents, or narrowing scope to dodge the
|
|
23
|
+
gap are all forbidden.
|
|
24
|
+
|
|
25
|
+
Full contract (probe table, comment format, resume path):
|
|
26
|
+
[reference/tool-access-gate.md](tool-access-gate-reference.mdc).
|
|
@@ -138,9 +138,18 @@ This condition is the contract the Verify flow proves and records in the verific
|
|
|
138
138
|
1. Direct deploy the changes to dev and then Write a simple API client and call the offending API
|
|
139
139
|
2. Start the server on localhost and then Use the Playwright CLI or Chrome DevTools
|
|
140
140
|
|
|
141
|
+
Using the general-purpose agent in Team Lead session, run the **tool access preflight** per the `tool-access-gate` rule (loaded via the lisa plugin) before any implementation task is created or started:
|
|
142
|
+
|
|
143
|
+
1. Enumerate every external tool or system this flow will need — for the implementation itself, for the proof command, and for remote verification (AWS CLI/CloudWatch, Figma, Jam, Sentry, SonarCloud, PostHog, device/browser harnesses, databases, deploy targets, trackers, …). Derive the list from the resolved work item (a linked Figma file, Jam capture, or Sentry issue implies that tool), the acceptance criteria, the testing requirements, and the completion condition above.
|
|
144
|
+
2. Prove access to each with its cheapest read-only probe, routing through the matching `*-access` skill where one exists (`integration-access-layer` rule). Tool presence on PATH is not access; a probe failure counts only after exhausting the documented credential sources (project e2e config/fixtures, `.lisa.config.local.json` / env vars, documented work-item credentials).
|
|
145
|
+
3. Record the enumeration and probe results in the plan artifact and in each task's `metadata.required_access`.
|
|
146
|
+
4. If any required tool fails its probe, do NOT start implementation — follow the break-out protocol in the `tool-access-gate` rule: post an "Access Needed" comment on the work item (plain-English summary, the exact credential/role/env var to grant, the probe that must pass), transition the item to the configured blocked state with the `human_needed` marker, write the verification verdict with `status: "blocked"`, and stop. Working around missing access — substituting weaker verification, mocking the inaccessible system, guessing at tool contents, or narrowing scope — is never permitted, for any tool.
|
|
147
|
+
|
|
148
|
+
The same gate applies **continuously**: if a tool requirement surfaces mid-flow (e.g. verification turns out to need CloudWatch log capture the runtime cannot authenticate to), probe it the moment it is discovered, record the new tool and probe result in the plan artifact and the affected tasks' `metadata.required_access` before continuing, and break out identically on failure.
|
|
149
|
+
|
|
141
150
|
Using the general-purpose agent in Team Lead session, create tasks needed to complete the request.
|
|
142
151
|
|
|
143
|
-
Every task MUST include this JSON metadata block. Do NOT omit `skills` (use `[]` if none), `learnings` (use `[]` if none) or `verification`.
|
|
152
|
+
Every task MUST include this JSON metadata block. Do NOT omit `skills` (use `[]` if none), `learnings` (use `[]` if none), `required_access` (use `[]` if the task needs no external tool) or `verification`.
|
|
144
153
|
|
|
145
154
|
```json
|
|
146
155
|
{
|
|
@@ -151,6 +160,9 @@ Every task MUST include this JSON metadata block. Do NOT omit `skills` (use `[]`
|
|
|
151
160
|
"testing_requirements": ["..."],
|
|
152
161
|
"skills": ["..."],
|
|
153
162
|
"learnings": ["..."],
|
|
163
|
+
"required_access": [
|
|
164
|
+
{ "tool": "<external tool/system this task or its verification needs>", "probe": "<the read-only command or *-access check that proves access>", "status": "pass|fail" }
|
|
165
|
+
],
|
|
154
166
|
"verification": {
|
|
155
167
|
"type": "ui-recording|api-test|cli-test|database-check|manual-check|documentation",
|
|
156
168
|
"command": "the proof command — must run the actual system and surface its result in the transcript (NOT test/typecheck/lint, those are quality gates). Phrase it so an independent verifier sees the evidence, e.g. `curl -s localhost:3000/health` not `check that health works`",
|
|
@@ -177,7 +189,7 @@ Before shutting down the team, execute the Verify flow:
|
|
|
177
189
|
"plan": "<plan-name>",
|
|
178
190
|
"status": "pass | fail | blocked | in_progress",
|
|
179
191
|
"criteria": [
|
|
180
|
-
{ "task": "<task id or title>", "criterion": "<the completion condition>", "status": "pass | fail", "evidence": "<the proof command run and the observed result>" }
|
|
192
|
+
{ "task": "<task id or title>", "criterion": "<the completion condition>", "status": "pass | fail | blocked", "evidence": "<the proof command run and the observed result; for a blocked criterion, the blocker diagnosis (e.g. the missing access and the probe that must pass)>" }
|
|
181
193
|
],
|
|
182
194
|
"updated_at": "<ISO8601 UTC>"
|
|
183
195
|
}
|
|
@@ -185,10 +197,10 @@ Before shutting down the team, execute the Verify flow:
|
|
|
185
197
|
|
|
186
198
|
Set `status: "pass"` only when every criterion is `pass` with real evidence (output from running the system, not a claim). The verdict must be judged by an agent that did NOT implement the change (the `verification-specialist`), never self-certified by the implementer. This is runtime scratch — it is gitignored and MUST NOT be committed (treat it like the secrets exclusion in the commit step).
|
|
187
199
|
|
|
188
|
-
On Claude, the `enforce-verification-gate.sh` Stop hook reads this file and **will not let the flow stop** until it shows a terminal, all-`pass` verdict — carrying over the non-bypassable completion gate of the `/goal` primitive, but checked deterministically against real evidence rather than by a transcript-only evaluator model. If you must stop before completion, write the verdict with `status: "blocked"` and the reason — that records the outcome and releases the gate instead of leaving it to spin. But a `blocked` verdict is a last resort, not a shortcut around fillable work: **first resolve every gap you can resolve yourself.** If the work item is thin — missing its Validation Journey, acceptance criteria, or other derivable detail — enrich it: derive the missing detail from the ticket context and the codebase, write it back, and proceed. Do **not** block on a gap you could have filled. Only a blocker that survives that attempt is real, and it is one of two kinds:
|
|
200
|
+
On Claude, the `enforce-verification-gate.sh` Stop hook reads this file and **will not let the flow stop** until it shows a terminal, all-`pass` verdict — carrying over the non-bypassable completion gate of the `/goal` primitive, but checked deterministically against real evidence rather than by a transcript-only evaluator model. If you must stop before completion, write the verdict with `status: "blocked"` and the reason — marking each criterion whose proof is blocked as `status: "blocked"` with the blocker diagnosis as its `evidence`, while unaffected criteria keep their real `pass`/`fail` result — that records the outcome and releases the gate instead of leaving it to spin. But a `blocked` verdict is a last resort, not a shortcut around fillable work: **first resolve every gap you can resolve yourself.** If the work item is thin — missing its Validation Journey, acceptance criteria, or other derivable detail — enrich it: derive the missing detail from the ticket context and the codebase, write it back, and proceed. Do **not** block on a gap you could have filled. Only a blocker that survives that attempt is real, and it is one of two kinds:
|
|
189
201
|
|
|
190
202
|
- **Actionable blocker** — an unresolved dependency or fixable technical gap that some team or repository could build (a missing or changed schema field, an unbuilt sibling work item, a required upstream fix), **including cross-repo dependencies**. Before writing the blocked verdict you MUST (1) file a build-ready fix/dependency ticket capturing the diagnosis — in the dependency's own repository/tracker when it is cross-repo (e.g. a `[<repo>] …` ticket in the shared project, or the sibling tracker) — and (2) link the current work item to it as `is blocked by`. Only then write the verdict. This is the same discipline as the regression-spec blocker and the remote-verification-fail exits above, and it is what makes the block machine-recoverable: `repair-intake` re-dispatches a blocked item once its linked `is blocked by` dependency closes, but it cannot act on a prose-only comment. Recommending the ticket "as a human follow-up" without filing and linking it is **not** a permitted exit.
|
|
191
|
-
- **Human-only blocker** — an input the agent genuinely cannot obtain or produce no matter what it does: credentials or
|
|
203
|
+
- **Human-only blocker** — an input the agent genuinely cannot obtain or produce no matter what it does: credentials, secrets, or **tool access** it does not have (AWS/CloudWatch, Figma, Jam, Sentry, SonarCloud, a database, a protected deploy target, …), or a product/design decision only a human can make. For missing tool access, follow the `tool-access-gate` rule's break-out protocol: post the "Access Needed" comment naming the exact credential/role/env var to grant and the probe that must pass — never work around the gap by substituting weaker verification, mocking the inaccessible system, or narrowing scope. Record the blocked verdict, mark it `human_needed` (the marker `repair-intake` recognizes, so it won't churn re-dispatching it), and surface or reassign to a human; do **not** fabricate a build-ready ticket, because there is no build-ready work.
|
|
192
204
|
|
|
193
205
|
Other harnesses fall back to this prose obligation.
|
|
194
206
|
3. Write the highest-practical-observation regression test encoding the verification. For user-visible bugs or user-visible Build changes with an available browser/device/e2e harness, this means a deterministic spec on the reported surface. Prove the new spec actually executed and passed in PR CI by recording a named spec log/reporter line or equivalent execution record; green CI without that named evidence does not satisfy this step.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.212.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.212.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.212.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.212.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.212.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|