@nano-step/skill-manager 5.5.3 → 5.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -123,6 +123,7 @@ async function run() {
123
123
  .command("install [name]")
124
124
  .description("Install a skill from the catalog")
125
125
  .option("--all", "Install all available skills")
126
+ .option("--force", "Force reinstall even if same version is installed")
126
127
  .action(async (name, options) => {
127
128
  const paths = await (0, utils_1.detectOpenCodePaths)();
128
129
  await (0, state_1.migrateV4State)(paths.configDir, paths.stateFilePath, paths.skillsDir);
@@ -135,11 +136,11 @@ async function run() {
135
136
  return;
136
137
  }
137
138
  for (const entry of catalog) {
138
- await (0, installer_1.installSkill)(entry.manifest.name, paths);
139
+ await (0, installer_1.installSkill)(entry.manifest.name, paths, options.force);
139
140
  }
140
141
  }
141
142
  else if (name) {
142
- await (0, installer_1.installSkill)(name, paths);
143
+ await (0, installer_1.installSkill)(name, paths, options.force);
143
144
  }
144
145
  else {
145
146
  console.error(chalk_1.default.red("Please specify a skill name or use --all."));
@@ -158,11 +159,12 @@ async function run() {
158
159
  program
159
160
  .command("update [name]")
160
161
  .description("Update installed skill(s) to latest catalog version")
161
- .action(async (name) => {
162
+ .option("--force", "Force update even if same version is installed")
163
+ .action(async (name, options) => {
162
164
  const paths = await (0, utils_1.detectOpenCodePaths)();
163
165
  await (0, state_1.migrateV4State)(paths.configDir, paths.stateFilePath, paths.skillsDir);
164
166
  if (name) {
165
- await (0, installer_1.updateSkill)(name, paths);
167
+ await (0, installer_1.updateSkill)(name, paths, options.force);
166
168
  }
167
169
  else {
168
170
  const state = await (0, state_1.loadState)(paths.stateFilePath);
@@ -172,7 +174,7 @@ async function run() {
172
174
  return;
173
175
  }
174
176
  for (const skillName of installed) {
175
- await (0, installer_1.updateSkill)(skillName, paths);
177
+ await (0, installer_1.updateSkill)(skillName, paths, options.force);
176
178
  }
177
179
  }
178
180
  });
@@ -1,4 +1,4 @@
1
1
  import { OpenCodePaths } from "./utils";
2
- export declare function installSkill(name: string, paths: OpenCodePaths): Promise<void>;
2
+ export declare function installSkill(name: string, paths: OpenCodePaths, force?: boolean): Promise<void>;
3
3
  export declare function removeSkill(name: string, paths: OpenCodePaths): Promise<void>;
4
- export declare function updateSkill(name: string, paths: OpenCodePaths): Promise<void>;
4
+ export declare function updateSkill(name: string, paths: OpenCodePaths, force?: boolean): Promise<void>;
package/dist/installer.js CHANGED
@@ -14,11 +14,11 @@ const registry_1 = require("./registry");
14
14
  const state_1 = require("./state");
15
15
  const config_1 = require("./config");
16
16
  const remote_registry_1 = require("./remote-registry");
17
- async function installFromDir(manifest, sourceDir, paths, source) {
17
+ async function installFromDir(manifest, sourceDir, paths, source, force) {
18
18
  const state = await (0, state_1.loadState)(paths.stateFilePath);
19
19
  const existing = state.skills[manifest.name];
20
- if (existing && existing.version === manifest.version) {
21
- console.log(chalk_1.default.yellow(`Skill "${manifest.name}" is already installed at v${manifest.version}.`));
20
+ if (existing && existing.version === manifest.version && !force) {
21
+ console.log(chalk_1.default.yellow(`Skill "${manifest.name}" is already installed at v${manifest.version}. Use --force to reinstall.`));
22
22
  return;
23
23
  }
24
24
  await (0, utils_1.ensureDirExists)(paths.skillsDir);
@@ -34,13 +34,14 @@ async function installFromDir(manifest, sourceDir, paths, source) {
34
34
  };
35
35
  await (0, state_1.saveState)(paths.stateFilePath, state);
36
36
  const sourceLabel = source === "private" ? chalk_1.default.magenta(" (private)") : "";
37
- console.log(chalk_1.default.green(`✓ Installed ${manifest.name} v${manifest.version}${sourceLabel}`));
37
+ const forceLabel = force && existing ? " (forced)" : "";
38
+ console.log(chalk_1.default.green(`✓ Installed ${manifest.name} v${manifest.version}${sourceLabel}${forceLabel}`));
38
39
  }
39
- async function installSkill(name, paths) {
40
+ async function installSkill(name, paths, force) {
40
41
  const localManifest = await (0, registry_1.getSkillManifest)(paths.packageSkillsDir, name);
41
42
  if (localManifest) {
42
43
  const packageSkillDir = path_1.default.join(paths.packageSkillsDir, name);
43
- await installFromDir(localManifest, packageSkillDir, paths, "public");
44
+ await installFromDir(localManifest, packageSkillDir, paths, "public", force);
44
45
  return;
45
46
  }
46
47
  const remoteManifest = await (0, remote_registry_1.getRemoteSkillManifest)(name);
@@ -48,7 +49,7 @@ async function installSkill(name, paths) {
48
49
  const tempDir = await (0, remote_registry_1.downloadSkillToTemp)(name);
49
50
  if (tempDir) {
50
51
  try {
51
- await installFromDir(remoteManifest, tempDir, paths, "private");
52
+ await installFromDir(remoteManifest, tempDir, paths, "private", force);
52
53
  }
53
54
  finally {
54
55
  await fs_extra_1.default.remove(tempDir);
@@ -95,7 +96,7 @@ async function removeSkill(name, paths) {
95
96
  await (0, state_1.saveState)(paths.stateFilePath, state);
96
97
  console.log(chalk_1.default.green(`✓ Removed ${name}`));
97
98
  }
98
- async function updateSkill(name, paths) {
99
+ async function updateSkill(name, paths, force) {
99
100
  const state = await (0, state_1.loadState)(paths.stateFilePath);
100
101
  if (!state.skills[name]) {
101
102
  console.error(chalk_1.default.red(`Skill "${name}" is not installed. Use 'skill-manager install ${name}' first.`));
@@ -104,8 +105,8 @@ async function updateSkill(name, paths) {
104
105
  const installed = state.skills[name];
105
106
  const localManifest = await (0, registry_1.getSkillManifest)(paths.packageSkillsDir, name);
106
107
  if (localManifest) {
107
- if (installed.version === localManifest.version) {
108
- console.log(chalk_1.default.yellow(`Skill "${name}" is already at v${localManifest.version} (up to date).`));
108
+ if (installed.version === localManifest.version && !force) {
109
+ console.log(chalk_1.default.yellow(`Skill "${name}" is already at v${localManifest.version} (up to date). Use --force to override.`));
109
110
  return;
110
111
  }
111
112
  const packageSkillDir = path_1.default.join(paths.packageSkillsDir, name);
@@ -120,13 +121,14 @@ async function updateSkill(name, paths) {
120
121
  location: installed.location,
121
122
  };
122
123
  await (0, state_1.saveState)(paths.stateFilePath, state);
123
- console.log(chalk_1.default.green(`✓ Updated ${name} from v${installed.version} to v${localManifest.version}`));
124
+ const forceLabel = force && installed.version === localManifest.version ? " (forced)" : "";
125
+ console.log(chalk_1.default.green(`✓ Updated ${name} from v${installed.version} to v${localManifest.version}${forceLabel}`));
124
126
  return;
125
127
  }
126
128
  const remoteManifest = await (0, remote_registry_1.getRemoteSkillManifest)(name);
127
129
  if (remoteManifest) {
128
- if (installed.version === remoteManifest.version) {
129
- console.log(chalk_1.default.yellow(`Skill "${name}" is already at v${remoteManifest.version} (up to date).`));
130
+ if (installed.version === remoteManifest.version && !force) {
131
+ console.log(chalk_1.default.yellow(`Skill "${name}" is already at v${remoteManifest.version} (up to date). Use --force to override.`));
130
132
  return;
131
133
  }
132
134
  const tempDir = await (0, remote_registry_1.downloadSkillToTemp)(name);
@@ -143,7 +145,8 @@ async function updateSkill(name, paths) {
143
145
  location: installed.location,
144
146
  };
145
147
  await (0, state_1.saveState)(paths.stateFilePath, state);
146
- console.log(chalk_1.default.green(`✓ Updated ${name} from v${installed.version} to v${remoteManifest.version} (private)`));
148
+ const remoteForceLabel = force && installed.version === remoteManifest.version ? " (forced)" : "";
149
+ console.log(chalk_1.default.green(`✓ Updated ${name} from v${installed.version} to v${remoteManifest.version} (private)${remoteForceLabel}`));
147
150
  }
148
151
  finally {
149
152
  await fs_extra_1.default.remove(tempDir);
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare const MANAGER_VERSION = "5.5.3";
1
+ export declare const MANAGER_VERSION = "5.6.1";
2
2
  export interface SkillManifest {
3
3
  name: string;
4
4
  version: string;
package/dist/utils.js CHANGED
@@ -13,7 +13,7 @@ exports.writeText = writeText;
13
13
  const path_1 = __importDefault(require("path"));
14
14
  const os_1 = __importDefault(require("os"));
15
15
  const fs_extra_1 = __importDefault(require("fs-extra"));
16
- exports.MANAGER_VERSION = "5.5.3";
16
+ exports.MANAGER_VERSION = "5.6.1";
17
17
  async function detectOpenCodePaths() {
18
18
  const homeConfig = path_1.default.join(os_1.default.homedir(), ".config", "opencode");
19
19
  const cwd = process.cwd();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nano-step/skill-manager",
3
- "version": "5.5.3",
3
+ "version": "5.6.1",
4
4
  "description": "CLI tool that installs and manages AI agent skills, MCP tool routing, and workflow configurations.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -16,8 +16,8 @@
16
16
  },
17
17
  {
18
18
  "name": "pr-code-reviewer",
19
- "version": "2.6.0",
20
- "description": "Comprehensive code review with 4 parallel subagents and GitHub Copilot-style PR summaries"
19
+ "version": "7.1.0",
20
+ "description": "PR review with MANDATORY cross-repo consumer search, nano-brain code intelligence, and better-context structural analysis. READ-ONLY no comments, pushes, or code fixes."
21
21
  },
22
22
  {
23
23
  "name": "rri-t-testing",
@@ -19,15 +19,6 @@ nano-brain supports two access methods. Try MCP first; if unavailable, use CLI.
19
19
 
20
20
  ### Session Workflow
21
21
 
22
- **Start of session:** Check memory for relevant past context before exploring the codebase.
23
- ```
24
- # MCP (if available):
25
- memory_query("what have we done regarding {current task topic}")
26
-
27
- # CLI fallback:
28
- npx nano-brain query "what have we done regarding {current task topic}"
29
- ```
30
-
31
22
  **End of session:** Save key decisions, patterns discovered, and debugging insights.
32
23
  ```
33
24
  # MCP (if available):
@@ -37,10 +28,25 @@ memory_write("## Summary\n- Decision: ...\n- Why: ...\n- Files: ...")
37
28
  # File: ~/.nano-brain/memory/YYYY-MM-DD-summary.md
38
29
  ```
39
30
 
40
- ### When to Search Memory vs Codebase
31
+ ### Code Intelligence Tools
32
+
33
+ nano-brain also provides symbol-level code analysis (requires `memory_index_codebase` first):
34
+
35
+ | I want to... | MCP Tool |
36
+ |--------------|----------|
37
+ | Understand a symbol's callers/callees/flows | `code_context(name="functionName")` |
38
+ | Assess risk of changing a symbol | `code_impact(target="className", direction="upstream")` |
39
+ | Map my git changes to affected symbols | `code_detect_changes(scope="all")` |
40
+
41
+ Use `file_path` parameter to disambiguate when multiple symbols share the same name.
42
+
43
+ ### When to Search Memory vs Codebase vs Code Intelligence
41
44
 
42
45
  - **"Have we done this before?"** → `memory_query` or `npx nano-brain query` (searches past sessions)
43
46
  - **"Where is this in the code?"** → grep / ast-grep (searches current files)
44
47
  - **"How does this concept work here?"** → Both (memory for past context + grep for current code)
48
+ - **"What calls this function?"** → `code_context` (symbol graph relationships)
49
+ - **"What breaks if I change X?"** → `code_impact` (dependency + flow analysis)
50
+ - **"What did my changes affect?"** → `code_detect_changes` (git diff to symbol mapping)
45
51
 
46
52
  <!-- OPENCODE-MEMORY:END -->
@@ -1,14 +1,23 @@
1
+ ---
2
+ name: nano-brain
3
+ description: Provide persistent memory and code intelligence for AI coding agents; use for hybrid search, cross-session recall, symbol analysis, and impact checks.
4
+ compatibility: OpenCode
5
+ metadata:
6
+ author: nano-step
7
+ version: 2.1.0
8
+ ---
9
+
1
10
  # nano-brain
2
11
 
3
- Persistent memory for AI coding agents. Hybrid search (BM25 + semantic + LLM reranking) across past sessions, codebase, notes, and daily logs.
12
+ Provide persistent memory for AI coding agents. Run hybrid search (BM25 + semantic + LLM reranking) across past sessions, codebase, notes, and daily logs.
4
13
 
5
14
  ## Slash Commands
6
15
 
7
16
  | Command | When |
8
17
  |---------|------|
9
- | `/nano-brain-init` | First-time workspace setup |
10
- | `/nano-brain-status` | Health check, embedding progress |
11
- | `/nano-brain-reindex` | After branch switch, pull, or major changes |
18
+ | `/nano-brain-init` | Run first-time workspace setup |
19
+ | `/nano-brain-status` | Check health, embedding progress |
20
+ | `/nano-brain-reindex` | Run after branch switch, pull, or major changes |
12
21
 
13
22
  ## When to Use Memory
14
23
 
@@ -17,25 +26,44 @@ Persistent memory for AI coding agents. Hybrid search (BM25 + semantic + LLM rer
17
26
 
18
27
  ## Access Methods: MCP vs CLI
19
28
 
20
- nano-brain can be accessed via **MCP tools** (when the MCP server is configured) or **CLI** (always available).
29
+ Access nano-brain via **MCP tools** (when the MCP server is configured) or **CLI** (always available).
21
30
 
22
31
  **Detection:** Try calling `memory_status` MCP tool first. If it fails with "MCP server not found", fall back to CLI.
23
32
 
24
33
  ### MCP Tools (preferred when available)
25
34
 
26
- | Need | MCP Tool |
27
- |------|----------|
28
- | Exact keyword (error msg, function name) | `memory_search` via `skill_mcp(mcp_name="nano-brain", tool_name="memory_search")` |
29
- | Conceptual ("how does auth work") | `memory_vsearch` via `skill_mcp(mcp_name="nano-brain", tool_name="memory_vsearch")` |
30
- | Best quality, complex question | `memory_query` via `skill_mcp(mcp_name="nano-brain", tool_name="memory_query")` |
31
- | Retrieve specific doc | `memory_get` / `memory_multi_get` |
32
- | Save insight or decision (append to daily log) | `memory_write` via `skill_mcp(mcp_name="nano-brain", tool_name="memory_write")` |
33
- | Set/update a keyed memory (overwrites previous) | `memory_set` via `skill_mcp(mcp_name="nano-brain", tool_name="memory_set")` |
34
- | Delete a keyed memory | `memory_delete` via `skill_mcp(mcp_name="nano-brain", tool_name="memory_delete")` |
35
- | List all keyed memories | `memory_keys` via `skill_mcp(mcp_name="nano-brain", tool_name="memory_keys")` |
36
- | Check health | `memory_status` via `skill_mcp(mcp_name="nano-brain", tool_name="memory_status")` |
37
- | Rescan source files | `memory_index_codebase` |
38
- | Refresh all indexes | `memory_update` |
35
+ - **`memory_search`** recall a specific error string or function name from past sessions.
36
+ Example: `skill_mcp(mcp_name="nano-brain", tool_name="memory_search", arguments={ query: "ECONNREFUSED redis timeout" })`
37
+ - **`memory_vsearch`** explore a fuzzy concept when you do not know the exact wording.
38
+ Example: `memory_vsearch("caching strategy for user sessions")`
39
+ - **`memory_query`** get the best hybrid answer for a complex, multi-part question.
40
+ Example: `memory_query("how did we handle rate limiting in the payment service")`
41
+ - **`memory_get`** pull one known doc by ID or path.
42
+ Example: `memory_get(id="#a1b2c3")`
43
+ - **`memory_multi_get`** fetch a set of known docs by pattern.
44
+ Example: `memory_multi_get(pattern="decisions/2025-*/auth-*.md")`
45
+ - **`memory_write`** log a decision or insight for future recall.
46
+ Example: `memory_write("## Decision: Use Redis Streams over Bull queues\n- Why: retries need ordered replay")`
47
+ - **`memory_set`** store a keyed note you plan to update over time.
48
+ Example: `memory_set(key="payments-rate-limit", content="429s come from gateway, not nginx")`
49
+ - **`memory_delete`** — remove a stale keyed note that is no longer accurate.
50
+ Example: `memory_delete(key="legacy-redis-metrics")`
51
+ - **`memory_keys`** — list all keyed notes to see what is tracked.
52
+ Example: `memory_keys()`
53
+ - **`memory_status`** — verify MCP health or embedding progress before searching.
54
+ Example: `memory_status()`
55
+ - **`memory_index_codebase`** — index source files before using code intelligence tools.
56
+ Example: `memory_index_codebase(root="/Users/tamlh/workspaces/self/AI/Tools")`
57
+ - **`memory_update`** — refresh all indexes after big changes or repo syncs.
58
+ Example: `memory_update()`
59
+ - **`memory_focus`** — inspect dependencies for a specific file you are editing.
60
+ Example: `memory_focus(filePath="/src/api/routes/auth.ts")`
61
+ - **`memory_graph_stats`** — check dependency graph size and coverage.
62
+ Example: `memory_graph_stats()`
63
+ - **`memory_symbols`** — find where cross-repo infrastructure symbols are defined or used.
64
+ Example: `memory_symbols(type="redis_key", pattern="session:*")`
65
+ - **`memory_impact`** — see which repos or services are affected by a symbol.
66
+ Example: `memory_impact(type="mysql_table", pattern="orders")`
39
67
 
40
68
  ### CLI Fallback (always available)
41
69
 
@@ -69,9 +97,23 @@ Works with both MCP and CLI (`-c` flag):
69
97
  - `memory` — curated notes only
70
98
  - Omit — search everything (recommended)
71
99
 
100
+ ## Code Intelligence Tools (MCP)
101
+
102
+ Use symbol-level analysis powered by Tree-sitter AST parsing. Require codebase indexing.
103
+
104
+ - **`code_context`** — trace callers, callees, and flows around a symbol.
105
+ Example: `code_context(name="processPayment")`
106
+ - **`code_impact`** — evaluate upstream or downstream risk before refactors.
107
+ Example: `code_impact(target="DatabaseClient", direction="upstream")`
108
+ - **`code_detect_changes`** — map current git diffs to symbols and flows.
109
+ Example: `code_detect_changes(scope="all")`
110
+
111
+ **Details and examples:** `references/code-intelligence.md`
112
+
72
113
  ## Memory vs Native Tools
73
114
 
74
115
  Memory excels at **recall and semantics** — past sessions, conceptual search, cross-project knowledge.
75
116
  Native tools (grep, ast-grep, glob) excel at **precise code patterns** — exact matches, AST structure.
117
+ Code intelligence tools excel at **structural relationships** — call graphs, impact analysis, flow detection.
76
118
 
77
- **They are complementary.** Use both.
119
+ **They are complementary.** Use all three.
@@ -0,0 +1,57 @@
1
+ ---
2
+ name: nano-brain code intelligence
3
+ description: Use MCP code_context, code_impact, and code_detect_changes for symbol-level analysis, impact checks, and diff mapping.
4
+ ---
5
+
6
+ # Code Intelligence (nano-brain)
7
+
8
+ ## Overview
9
+
10
+ Run code intelligence when symbol relationships, impact analysis, or diff-to-symbol mapping is needed. Ensure indexing is done with `memory_index_codebase` before using these tools.
11
+
12
+ ## code_context — 360-degree symbol view
13
+
14
+ Return callers, callees, cluster membership, execution flows, and infrastructure connections for any function/class/method.
15
+
16
+ ```
17
+ skill_mcp(mcp_name="nano-brain", tool_name="code_context", arguments={"name": "handleRequest"})
18
+ skill_mcp(mcp_name="nano-brain", tool_name="code_context", arguments={"name": "helper", "file_path": "/src/utils.ts"})
19
+ ```
20
+
21
+ Use `file_path` to disambiguate when multiple symbols share the same name.
22
+
23
+ ## code_impact — dependency analysis
24
+
25
+ Traverse the symbol graph to find affected symbols and flows. Return a risk level (LOW/MEDIUM/HIGH/CRITICAL).
26
+
27
+ ```
28
+ skill_mcp(mcp_name="nano-brain", tool_name="code_impact", arguments={"target": "DatabaseClient", "direction": "upstream"})
29
+ skill_mcp(mcp_name="nano-brain", tool_name="code_impact", arguments={"target": "processOrder", "direction": "downstream", "max_depth": 3})
30
+ ```
31
+
32
+ - `upstream` = "who calls this?" (callers, consumers)
33
+ - `downstream` = "what does this call?" (callees, dependencies)
34
+
35
+ ## code_detect_changes — git diff to symbol mapping
36
+
37
+ Map current git changes to affected symbols and execution flows.
38
+
39
+ ```
40
+ skill_mcp(mcp_name="nano-brain", tool_name="code_detect_changes", arguments={"scope": "staged"})
41
+ skill_mcp(mcp_name="nano-brain", tool_name="code_detect_changes", arguments={"scope": "all"})
42
+ ```
43
+
44
+ Scopes: `unstaged`, `staged`, `all` (default).
45
+
46
+ ## When to Use Code Intelligence vs Memory vs Native Tools
47
+
48
+ | Question | Tool |
49
+ |----------|------|
50
+ | "What calls function X?" | `code_context` |
51
+ | "What breaks if I change X?" | `code_impact` |
52
+ | "What did I change and what's affected?" | `code_detect_changes` |
53
+ | "Have we done this before?" | `memory_query` |
54
+ | "Find exact string in code" | grep / ast-grep |
55
+ | "How does auth work conceptually?" | `memory_vsearch` |
56
+
57
+ Code intelligence requires indexing. Run `memory_index_codebase` first if the workspace has not been indexed.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nano-brain",
3
- "version": "1.0.0",
4
- "description": "Persistent memory for AI coding agents. Hybrid search (BM25 + semantic + LLM reranking) across past sessions, codebase, notes, and daily logs.",
3
+ "version": "2.1.0",
4
+ "description": "Persistent memory and code intelligence for AI coding agents. Hybrid search, cross-session recall, symbol analysis, and impact checks.",
5
5
  "compatibility": "OpenCode",
6
6
  "agent": null,
7
7
  "commands": [],
@@ -10,6 +10,9 @@
10
10
  "persistence",
11
11
  "search",
12
12
  "context",
13
- "sessions"
13
+ "sessions",
14
+ "code-intelligence",
15
+ "symbol-analysis",
16
+ "impact-analysis"
14
17
  ]
15
18
  }
@@ -0,0 +1,224 @@
1
+ ---
2
+ name: rri-t-testing
3
+ description: RRI-T v2 - Rapid Risk-Informed Testing with BMAD-enhanced risk scoring, traceability, quality gates, and nano-brain memory persistence
4
+ ---
5
+
6
+ # RRI-T v2.0 Testing Skill
7
+
8
+ Rapid Risk-Informed Testing methodology for AI agents. Guides systematic QA testing through 6 phases with risk scoring, traceability, quality gates, and cross-session memory persistence.
9
+
10
+ ## When to Use
11
+
12
+ - Testing a new feature before release
13
+ - Validating a bug fix with regression coverage
14
+ - Assessing release readiness with quality gates
15
+ - Building test cases from requirements with traceability
16
+ - Resuming interrupted testing sessions via nano-brain
17
+
18
+ ## Input Parameters
19
+
20
+ | Parameter | Required | Description |
21
+ |-----------|----------|-------------|
22
+ | `feature` | Yes | Feature name or PR reference |
23
+ | `tier` | No | Testing depth: `full` (default), `standard`, `minimal` |
24
+ | `acceptance_criteria` | No | List of acceptance criteria or link to spec |
25
+ | `environment` | No | Target environment (dev/staging/prod) |
26
+
27
+ ## Workflow Phases
28
+
29
+ ### Phase 0: ASSESS
30
+
31
+ Run testability gate, score risk, classify category, select tier, make go/no-go decision.
32
+
33
+ **Steps:**
34
+ 1. Load `assets/rri-t-testability-gate.md` template
35
+ 2. Validate prerequisites (environment, test data, deployment, acceptance criteria)
36
+ 3. Assess testability (locators, API docs, auth flows, error states, baselines)
37
+ 4. Score risk: Probability (1-3) x Impact (1-3) = Score (1-9)
38
+ 5. Classify category: TECH / SEC / PERF / DATA / BUS / OPS
39
+ 6. Select tier based on score
40
+ 7. Decision: PROCEED / CONCERNS / BLOCK
41
+
42
+ **Output:** `00-assess.md`, `risk-matrix.md`
43
+
44
+ **MEMORY SAVE:** `rri-t/{feature}/assess` - Save risk register, tier, decision
45
+
46
+ ---
47
+
48
+ ### Phase 1: PREPARE
49
+
50
+ Define test scope, assign personas, select dimensions based on tier.
51
+
52
+ **Steps:**
53
+ 1. Define test scope based on tier selection
54
+ 2. Assign personas (5 for Full, 3 for Standard, 1 for Minimal)
55
+ 3. Select dimensions (7 for Full, 4 for Standard, 2 for Minimal)
56
+ 4. Set coverage targets per tier
57
+ 5. Create output directory structure
58
+
59
+ **Output:** `01-prepare.md`
60
+
61
+ **MEMORY SAVE:** `rri-t/{feature}/prepare` - Save scope, persona assignments, dimension targets
62
+
63
+ ---
64
+
65
+ ### Phase 2: DISCOVER
66
+
67
+ Run persona interviews, map to dimensions, consolidate findings.
68
+
69
+ **Steps:**
70
+ 1. Load `assets/rri-t-persona-interview.md` template
71
+ 2. Run persona interviews using risk-tagged questions
72
+ 3. Map questions to dimensions (D1-D7)
73
+ 4. Consolidate findings into risk register update
74
+ 5. Generate raw test ideas
75
+
76
+ **Output:** `02-discover.md`
77
+
78
+ **MEMORY SAVE:** `rri-t/{feature}/discover` - Save interview findings, test ideas, updated risks
79
+
80
+ ---
81
+
82
+ ### Phase 3: STRUCTURE
83
+
84
+ Create test cases, select stress axes, build traceability matrix.
85
+
86
+ **Steps:**
87
+ 1. Load `assets/rri-t-test-case.md` template
88
+ 2. Create test cases with Q-A-R-P-T format + risk category + traceability
89
+ 3. Load `assets/rri-t-stress-matrix.md` and select relevant stress axes
90
+ 4. Build traceability matrix using `assets/rri-t-traceability-matrix.md`
91
+ 5. Identify coverage gaps
92
+
93
+ **Output:** `03-structure.md`, `traceability.md`
94
+
95
+ **MEMORY SAVE:** `rri-t/{feature}/structure` - Save test cases, traceability, gaps
96
+
97
+ ---
98
+
99
+ ### Phase 4: EXECUTE
100
+
101
+ Execute test cases via Playwright MCP, capture evidence, record results.
102
+
103
+ **Steps:**
104
+ 1. Execute test cases using Playwright MCP browser automation
105
+ 2. Capture evidence (screenshots, console logs, network requests)
106
+ 3. Record results: PASS / FAIL / PAINFUL / MISSING
107
+ 4. Calculate quality score using `assets/rri-t-quality-scorecard.md`
108
+ 5. Log bugs found
109
+
110
+ **Output:** `04-execute.md`, `quality-scorecard.md`
111
+
112
+ **MEMORY SAVE:** `rri-t/{feature}/execute` - Save results, bugs, quality score
113
+
114
+ ---
115
+
116
+ ### Phase 5: ANALYZE
117
+
118
+ Fill coverage dashboard, apply gate rules, generate final report.
119
+
120
+ **Steps:**
121
+ 1. Load `assets/rri-t-coverage-dashboard.md` template
122
+ 2. Fill coverage dashboard with results
123
+ 3. Complete traceability matrix with test results
124
+ 4. Apply gate decision rules (PASS/CONCERNS/FAIL/WAIVED)
125
+ 5. Generate final report
126
+ 6. Extract reusable patterns for knowledge base
127
+
128
+ **Output:** `05-analyze.md`, `coverage-dashboard.md`
129
+
130
+ **MEMORY SAVE:** `rri-t/{feature}/analyze` - Save gate decision, report, lessons learned, reusable patterns
131
+
132
+ ---
133
+
134
+ ## Output Directory Structure
135
+
136
+ ```
137
+ rri-t-{feature}/
138
+ 00-assess.md # Phase 0: Testability gate + risk assessment
139
+ 01-prepare.md # Phase 1: Scope, personas, dimensions
140
+ 02-discover.md # Phase 2: Interview findings, test ideas
141
+ 03-structure.md # Phase 3: Test cases, stress selections
142
+ 04-execute.md # Phase 4: Execution log, evidence
143
+ 05-analyze.md # Phase 5: Final analysis, recommendations
144
+ risk-matrix.md # Risk register with PxI scoring
145
+ traceability.md # Requirement-to-test mapping
146
+ quality-scorecard.md # 0-100 quality scoring
147
+ coverage-dashboard.md # Coverage metrics, gate decision
148
+ evidence/ # Screenshots, logs
149
+ ```
150
+
151
+ ## Templates
152
+
153
+ | Template | Purpose |
154
+ |----------|---------|
155
+ | `rri-t-testability-gate.md` | Phase 0 readiness checklist |
156
+ | `rri-t-risk-matrix.md` | PxI risk scoring template |
157
+ | `rri-t-traceability-matrix.md` | Requirement-to-test mapping |
158
+ | `rri-t-quality-scorecard.md` | 0-100 quality scoring |
159
+ | `rri-t-memory-protocol.md` | nano-brain save/resume protocol |
160
+ | `rri-t-test-case.md` | Q-A-R-P-T test case format |
161
+ | `rri-t-persona-interview.md` | 5-persona interview template |
162
+ | `rri-t-coverage-dashboard.md` | Coverage metrics dashboard |
163
+ | `rri-t-stress-matrix.md` | 8-axis stress testing scenarios |
164
+
165
+ ## 7 Dimensions
166
+
167
+ | ID | Dimension | Target Coverage |
168
+ |----|-----------|-----------------|
169
+ | D1 | UI/UX | >= 85% |
170
+ | D2 | API | >= 85% |
171
+ | D3 | Performance | >= 70% |
172
+ | D4 | Security | >= 85% |
173
+ | D5 | Data Integrity | >= 85% |
174
+ | D6 | Infrastructure | >= 70% |
175
+ | D7 | Edge Cases | >= 85% |
176
+
177
+ ## 5 Personas
178
+
179
+ | Persona | Focus |
180
+ |---------|-------|
181
+ | End User | Daily usage, speed, clarity, data safety |
182
+ | Business Analyst | Business rules, permissions, data consistency |
183
+ | QA Destroyer | Edge cases, race conditions, malformed inputs |
184
+ | DevOps Tester | Load, recovery, observability, scalability |
185
+ | Security Auditor | Auth, access control, data exposure, audit trails |
186
+
187
+ ## Tier Selection
188
+
189
+ | Tier | Risk Score | Personas | Dimensions | Stress Axes | Est. Time |
190
+ |------|------------|----------|------------|-------------|-----------|
191
+ | Full | 6-9 | 5 | 7 | 8 | 2-4 hours |
192
+ | Standard | 3-5 | 3 | 4 | 4 | 1-2 hours |
193
+ | Minimal | 1-2 | 1 | 2 | 2 | 30-60 min |
194
+
195
+ ## Release Gates
196
+
197
+ | State | Criteria |
198
+ |-------|----------|
199
+ | PASS | P0 coverage = 100% AND P1 >= 90% AND overall >= 80% |
200
+ | CONCERNS | P0 = 100% AND P1 = 80-89% AND mitigations documented |
201
+ | FAIL | P0 < 100% OR P1 < 80% OR unresolved security issues |
202
+ | WAIVED | FAIL + business approval + owner + expiry + remediation plan |
203
+
204
+ ## Risk Categories
205
+
206
+ | Code | Category | Description |
207
+ |------|----------|-------------|
208
+ | TECH | Technical | Architecture/integration fragility |
209
+ | SEC | Security | Security vulnerabilities |
210
+ | PERF | Performance | Performance/scalability issues |
211
+ | DATA | Data | Data integrity/corruption |
212
+ | BUS | Business | Business logic errors |
213
+ | OPS | Operational | Deployment/operational issues |
214
+
215
+ ## Guardrails
216
+
217
+ - Always run Phase 0 ASSESS before testing
218
+ - Score risk before testing (PxI formula)
219
+ - Use Q-A-R-P-T format for all test cases
220
+ - Map every test case to a requirement (traceability)
221
+ - Capture evidence for all FAIL and PAINFUL results
222
+ - Save to nano-brain after every phase
223
+ - Never skip security dimension for SEC-category risks
224
+ - Document all waivers with owner, expiry, remediation