@dombaras/agent-harness 0.1.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.
Files changed (41) hide show
  1. package/README.md +77 -0
  2. package/bin/agent-harness.js +169 -0
  3. package/package.json +29 -0
  4. package/templates/.agents/AGENTS.md +103 -0
  5. package/templates/.agents/memory/domain-map.md +29 -0
  6. package/templates/.agents/memory/handoff.md +12 -0
  7. package/templates/.agents/memory/locations.md +10 -0
  8. package/templates/.agents/memory/model-routing.md +47 -0
  9. package/templates/.agents/memory/stack-versions.md +12 -0
  10. package/templates/.agents/rules/00-operating.md +85 -0
  11. package/templates/.agents/skills/data-engineer/SKILL.md +29 -0
  12. package/templates/.agents/skills/devops-engineer/SKILL.md +28 -0
  13. package/templates/.agents/skills/diagnostics-expert/SKILL.md +43 -0
  14. package/templates/.agents/skills/frontend-engineer/SKILL.md +78 -0
  15. package/templates/.agents/skills/handoff/SKILL.md +50 -0
  16. package/templates/.agents/skills/mobile-engineer/SKILL.md +40 -0
  17. package/templates/.agents/skills/planner/SKILL.md +23 -0
  18. package/templates/.agents/skills/product-manager/SKILL.md +102 -0
  19. package/templates/.agents/skills/qa-architect/SKILL.md +40 -0
  20. package/templates/.agents/skills/qa-runner/SKILL.md +26 -0
  21. package/templates/.agents/skills/security-engineer/SKILL.md +51 -0
  22. package/templates/.agents/skills/system-architect/SKILL.md +40 -0
  23. package/templates/.agents/skills/ui-designer/SKILL.md +69 -0
  24. package/templates/.opencode/agents/data-engineer.md +16 -0
  25. package/templates/.opencode/agents/devops-engineer.md +16 -0
  26. package/templates/.opencode/agents/diagnostics-expert.md +16 -0
  27. package/templates/.opencode/agents/frontend-engineer.md +16 -0
  28. package/templates/.opencode/agents/handoff.md +14 -0
  29. package/templates/.opencode/agents/mobile-engineer.md +16 -0
  30. package/templates/.opencode/agents/planner.md +14 -0
  31. package/templates/.opencode/agents/product-manager.md +14 -0
  32. package/templates/.opencode/agents/qa-architect.md +14 -0
  33. package/templates/.opencode/agents/qa-runner.md +14 -0
  34. package/templates/.opencode/agents/security-engineer.md +16 -0
  35. package/templates/.opencode/agents/system-architect.md +16 -0
  36. package/templates/.opencode/agents/ui-designer.md +16 -0
  37. package/templates/AGENTS.md +17 -0
  38. package/templates/opencode.json +5 -0
  39. package/templates/scripts/qa/check-dispatch-config.js +113 -0
  40. package/templates/scripts/qa/governance.js +57 -0
  41. package/templates/scripts/qa/models.allowlist.txt +64 -0
package/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # @dombaras/agent-harness
2
+
3
+ A reusable multi-agent harness for AI-assisted development. Ships a persona
4
+ fleet (planner, engine engineer, mobile, QA architect/runner, security,
5
+ architecture, product, data, devops, handoff), operating rules, model routing,
6
+ and QA gates — then deploys them into any project.
7
+
8
+ > Extracted from a production project so the "agents / subagents / guardrails /
9
+ > personas" layer is **not** an inherent part of the app codebase. It lives in its
10
+ > own repo and is installed via `npx @dombaras/agent-harness init`.
11
+
12
+ ## Why
13
+
14
+ - The agent harness is tooling, not application code. It should not be committed
15
+ into every app repo.
16
+ - One canonical, versioned source of truth for personas/rules/QA tiers, deployed
17
+ on demand and updatable via `npx @dombaras/agent-harness update`.
18
+
19
+ ## Install & initialize
20
+
21
+ ```bash
22
+ # from anywhere (uses a target dir or defaults to cwd)
23
+ npx @dombaras/agent-harness init --target /path/to/project --name "MyApp" --domain "a widget catalog"
24
+
25
+ # non-interactive
26
+ npx @dombaras/agent-harness init --target . --yes
27
+ ```
28
+
29
+ `init` writes:
30
+
31
+ | Path | Content | Ownership |
32
+ |---|---|---|
33
+ | `AGENTS.md` | root dispatcher | harness (overwrite) |
34
+ | `.opencode/agents/*.md` | 13 persona subagent defs (with `model:` pins) | harness (overwrite) |
35
+ | `.agents/AGENTS.md` | full operating rulebook | harness (overwrite) |
36
+ | `.agents/rules/00-operating.md` | always-loaded rules summary | harness (overwrite) |
37
+ | `.agents/skills/*/SKILL.md` | persona instruction skills | harness (overwrite) |
38
+ | `opencode.json` | main/small model routing | harness (overwrite) |
39
+ | `scripts/qa/*` | `test:dispatch` / `test:governance` gates | harness (overwrite) |
40
+ | `.agents/memory/*` | project data (domain-map, stack-versions, handoff, locations, model-routing) | **project** (create-if-missing) |
41
+ | `.harness.json` | deployed version + project profile | harness |
42
+
43
+ ## Placeholders
44
+
45
+ Templates use `{{PROJECT_NAME}}` and `{{PROJECT_DOMAIN}}`; `init` substitutes
46
+ them from `--name` / `--domain` (or prompts, or `.harness.json`). Domain facts
47
+ that are genuinely project-specific (entity model, catalog sources, visibility
48
+ tiers, trust tiers) live in `.agents/memory/domain-map.md`, which `init`
49
+ scaffolds for you to fill in — the skills reference it instead of hardcoding
50
+ domain assumptions.
51
+
52
+ ## Model routing
53
+
54
+ - Concrete models are set in `.opencode/agents/<name>.md` (`model:` field) and
55
+ `opencode.json` (`model` + `small_model`).
56
+ - `.agents/skills/*/SKILL.md` carries a `model:` label only (informational).
57
+ - `npx @dombaras/agent-harness list` prints the persona → model mapping.
58
+ - `npm run test:dispatch` mechanically verifies model pins against
59
+ `scripts/qa/models.allowlist.txt`.
60
+
61
+ ## Update
62
+
63
+ ```bash
64
+ npx @dombaras/agent-harness update --target /path/to/project
65
+ ```
66
+
67
+ Overwrites harness-owned files, preserves `.agents/memory/*`.
68
+
69
+ ## Develop
70
+
71
+ ```bash
72
+ node bin/agent-harness.js list
73
+ node bin/agent-harness.js init --target /tmp/demo --name Demo --yes
74
+ ```
75
+
76
+ Clear the data-test except keep `templates/` generic; do not commit a target
77
+ project's `.agents/memory/` into this repo.
@@ -0,0 +1,169 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /*
4
+ * agent-harness — deploy the LibraryOS agent harness (personas, skills, rules,
5
+ * model routing, QA gates) into a target project.
6
+ *
7
+ * Commands:
8
+ * init [--target <dir>] [--name <project>] [--domain <desc>] [--yes]
9
+ * update [--target <dir>]
10
+ * list (list personas + models)
11
+ *
12
+ * `init` materializes templates/ into the target and substitutes {{
13
+ * PROJECT_NAME }} / {{ PROJECT_DOMAIN }}. `.agents/memory/*` files are only
14
+ * created when absent (project data). Harness-owned files are overwritten.
15
+ */
16
+
17
+ const fs = require("fs");
18
+ const path = require("path");
19
+ const readline = require("readline");
20
+
21
+ const PKG = require("../package.json");
22
+ const TEMPLATES_DIR = path.resolve(__dirname, "..", "templates");
23
+ const CONFIG_FILE = ".harness.json";
24
+
25
+ // Files the harness owns and overwrites on every run.
26
+ // `.agents/memory/*` is project data -> create-if-missing only.
27
+ function listFiles(dir, base = dir) {
28
+ const out = [];
29
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
30
+ const abs = path.join(dir, entry.name);
31
+ if (entry.isDirectory()) out.push(...listFiles(abs, base));
32
+ else out.push({ abs, rel: path.relative(base, abs) });
33
+ }
34
+ return out;
35
+ }
36
+
37
+ function substitute(text, vars) {
38
+ let out = text;
39
+ for (const [key, value] of Object.entries(vars)) {
40
+ out = out.split("{{" + key + "}}").join(value);
41
+ }
42
+ return out;
43
+ }
44
+
45
+ function isMemoryFile(rel) {
46
+ return rel.split(path.sep).includes(".agents") &&
47
+ rel.split(path.sep).includes("memory");
48
+ }
49
+
50
+ function writeFileIfAbsent(targetAbs, content) {
51
+ if (fs.existsSync(targetAbs)) return "skip";
52
+ fs.mkdirSync(path.dirname(targetAbs), { recursive: true });
53
+ fs.writeFileSync(targetAbs, content, "utf8");
54
+ return "create";
55
+ }
56
+
57
+ function readConfig(target) {
58
+ const p = path.join(target, CONFIG_FILE);
59
+ if (fs.existsSync(p)) {
60
+ try { return JSON.parse(fs.readFileSync(p, "utf8")); } catch (_) { return {}; }
61
+ }
62
+ return {};
63
+ }
64
+
65
+ function ask(question, fallback) {
66
+ if (process.argv.includes("--yes")) return Promise.resolve(fallback || "");
67
+ if (!process.stdin.isTTY) return Promise.resolve(fallback || "");
68
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
69
+ return new Promise((resolve) => {
70
+ rl.question(question, (answer) => { rl.close(); resolve(answer.trim()); });
71
+ });
72
+ }
73
+
74
+ function resolveVars(target, args) {
75
+ const existing = readConfig(target);
76
+ const nameFlag = args["--name"];
77
+ const domainFlag = args["--domain"];
78
+ const projectName = nameFlag || existing.projectName || path.basename(target);
79
+ return { projectName, domainFlag, existing, VARIABLES: { PROJECT_NAME: projectName, PROJECT_DOMAIN: domainFlag || existing.projectDomain || "" } };
80
+ }
81
+
82
+ function printPersonas(templatesDir) {
83
+ const agents = path.join(templatesDir, ".opencode", "agents");
84
+ console.log("Personas (model routing):\n");
85
+ for (const f of fs.readdirSync(agents).sort()) {
86
+ const src = fs.readFileSync(path.join(agents, f), "utf8");
87
+ const model = (src.match(/^model:\s*(.+)$/m) || [])[1] || "?";
88
+ console.log(` ${f.replace(/\.md$/, "").padEnd(22)} -> ${model}`);
89
+ }
90
+ }
91
+
92
+ async function init(target, args) {
93
+ if (!fs.existsSync(TEMPLATES_DIR)) {
94
+ console.error("templates/ directory not found next to this CLI.");
95
+ process.exit(1);
96
+ }
97
+ const { projectName, domainFlag, VARIABLES } = resolveVars(target, args);
98
+
99
+ let projectDomain = VARIABLES.PROJECT_DOMAIN;
100
+ if (!domainFlag && !readConfig(target).projectDomain) {
101
+ projectDomain = await ask(`Project domain (one line) for "${projectName}": `, "");
102
+ }
103
+ VARIABLES.PROJECT_DOMAIN = projectDomain;
104
+
105
+ const stats = { overwritten: 0, created: 0, skipped: 0 };
106
+ for (const { abs, rel } of listFiles(TEMPLATES_DIR)) {
107
+ const content = substitute(fs.readFileSync(abs, "utf8"), VARIABLES);
108
+ const targetAbs = path.join(target, rel);
109
+ if (isMemoryFile(rel)) {
110
+ const r = writeFileIfAbsent(targetAbs, content);
111
+ if (r === "create") stats.created++; else stats.skipped++;
112
+ } else {
113
+ fs.mkdirSync(path.dirname(targetAbs), { recursive: true });
114
+ fs.writeFileSync(targetAbs, content, "utf8");
115
+ stats.overwritten++;
116
+ }
117
+ }
118
+
119
+ const config = {
120
+ version: PKG.version,
121
+ projectName,
122
+ projectDomain,
123
+ initializedAt: new Date().toISOString(),
124
+ };
125
+ fs.writeFileSync(path.join(target, CONFIG_FILE), JSON.stringify(config, null, 2) + "\n", "utf8");
126
+
127
+ console.log(`\nagent-harness v${PKG.version} initialized "${projectName}" in ${target}`);
128
+ console.log(` ${stats.overwritten} harness files written, ${stats.created} memory files created, ${stats.skipped} existing memory files preserved.\n`);
129
+ console.log(" Next steps:");
130
+ console.log(" 1. Fill in `.agents/memory/domain-map.md` and `.agents/memory/stack-versions.md`.");
131
+ console.log(" 2. Add QA gate scripts to package.json:");
132
+ console.log(' "test:dispatch": "node scripts/qa/check-dispatch-config.js",');
133
+ console.log(' "test:governance": "node scripts/qa/governance.js"');
134
+ console.log(" 3. Restart your agent CLI (config is read once at startup).\n");
135
+ }
136
+
137
+ function update(target) {
138
+ const { projectName, VARIABLES } = resolveVars(target, {});
139
+ console.log(`Updating harness in ${target} (project "${projectName}")...`);
140
+ return init(target, { "--name": projectName, "--domain": VARIABLES.PROJECT_DOMAIN });
141
+ }
142
+
143
+ function main() {
144
+ const args = process.argv.slice(2);
145
+ const cmd = args[0] || "help";
146
+ const flags = {};
147
+ for (let i = 1; i < args.length; i++) {
148
+ if (args[i] === "--target" || args[i] === "--name" || args[i] === "--domain") {
149
+ flags[args[i]] = args[i + 1]; i++;
150
+ }
151
+ }
152
+ const target = path.resolve(flags["--target"] || process.cwd());
153
+
154
+ switch (cmd) {
155
+ case "init":
156
+ init(target, flags).catch((e) => { console.error(e); process.exit(1); });
157
+ break;
158
+ case "update":
159
+ update(target).catch((e) => { console.error(e); process.exit(1); });
160
+ break;
161
+ case "list":
162
+ printPersonas(TEMPLATES_DIR);
163
+ break;
164
+ default:
165
+ console.log(`agent-harness v${PKG.version}\n\nUsage:\n agent-harness init [--target <dir>] [--name <project>] [--domain <desc>] [--yes]\n agent-harness update [--target <dir>]\n agent-harness list`);
166
+ }
167
+ }
168
+
169
+ main();
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@dombaras/agent-harness",
3
+ "version": "0.1.0",
4
+ "description": "Reusable multi-agent harness for AI-assisted development: personas, skills, operating rules, model routing, and QA gates. Deploy into any project with `npx @dombaras/agent-harness init`.",
5
+ "bin": {
6
+ "agent-harness": "bin/agent-harness.js"
7
+ },
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "files": [
12
+ "bin/",
13
+ "templates/",
14
+ "README.md"
15
+ ],
16
+ "keywords": [
17
+ "opencode",
18
+ "agents",
19
+ "subagents",
20
+ "personas",
21
+ "ai-harness",
22
+ "claude-code",
23
+ "copilot"
24
+ ],
25
+ "license": "MIT",
26
+ "engines": {
27
+ "node": ">=18"
28
+ }
29
+ }
@@ -0,0 +1,103 @@
1
+ # Project Rules & Operating Guidelines
2
+
3
+ ## 1. Fact-Based, Zero-Guessing SDLC (Strict Operating Law Across All Roles & Personas)
4
+ - **Zero-Speculation Rule**: NEVER guess, hypothesize without evidence, or assume the root cause of an error, performance lag, or system behavior. Speculation is strictly forbidden across all personas and workflow stages.
5
+ - **Evidence-First Engineering**: Every diagnostic conclusion, bug fix, architectural decision, and feature enhancement MUST be grounded in observable facts: live server logs, telemetry traces (`/api/debug/logs`, `scratch/mobile-debug.log`), database records (`ExternalServiceLog`, Prisma queries), or verified runtime execution.
6
+ - **Mandatory Telemetry Before Fixes**: If logs or telemetry are absent or insufficient to isolate the root cause, you MUST FIRST add structured logging/instrumentation, execute or have the user reproduce, inspect the resulting log file, and ONLY THEN implement the solution based on the captured data.
7
+ - **Authentic Runtime Execution**: NEVER substitute real application runtime calls with ad-hoc external test scripts that might bypass actual configurations, environment variables, middleware, or request pipelines. Always test and verify behavior using the actual APIs and functions the application uses.
8
+ - **Scientific Progression Gate**: A fix is NEVER complete until live logs or automated runtime tests explicitly demonstrate the bug is eliminated and that the failure mode no longer occurs in real runtime conditions.
9
+
10
+ ## 2. Dynamic Data & Business Logic Integrity
11
+ - **No Hardcoded Mock Lists**: NEVER create hardcoded lists (e.g. fake records, mock reviews, static fallback arrays) without explicit user approval. Always prefer dynamic database queries and database-backed system settings (`SystemSetting`).
12
+
13
+ ## 3. UI, Mobile Ergonomics & RTL Support
14
+ - **Zero Native Popups**: NEVER use `Alert.alert()`, `alert()`, `confirm()`, or `prompt()`. Replace all dialogs with inline toast notifications, bottom sheets, inline state transitions, or haptic feedback.
15
+ - **Progressive Hydration & Cold-Start**: Never render empty dashboard/hub states while waiting for asynchronous auth/community sync. Always use local cache hydration (`AsyncStorage` / SQLite) so UI renders immediately without blank loading lags.
16
+ - **The 5 Essential UI States**: Every screen and list component must explicitly handle: Ideal State, Empty State (with onboarding CTA), Loading Skeleton, Error State (with retry action), and Partial/Single-item State.
17
+ - **Error Handling Contract (Mobile)**: Every `catch` block in a React Native screen MUST:
18
+ 1. Trigger `Haptics.notificationAsync(NotificationFeedbackType.Error)` for tactile feedback.
19
+ 2. Set a user-visible error state variable (e.g., `setActionError('Failed to approve loan')`) that renders an inline error banner or toast — NOT just `console.warn`.
20
+ 3. Include a retry mechanism (re-call the failed function) or a clear dismissal path.
21
+ - `console.warn` alone is NEVER acceptable as error handling in production code. It is invisible to the user.
22
+ - **Reference pattern** (use this exact structure in every async action handler):
23
+ ```typescript
24
+ try {
25
+ await api.someAction(userId, ...args);
26
+ await Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
27
+ await refreshSync();
28
+ } catch (err: any) {
29
+ await Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error);
30
+ setActionError(err?.message || t('errors.genericRetry'));
31
+ // Error banner auto-renders via actionError state
32
+ }
33
+ ```
34
+ - **Cross-Screen Consistency Rule**: Whenever you implement a UX pattern in one screen (error handling shape, haptic feedback, loading skeleton, animation style, empty state CTA), you MUST:
35
+ 1. Grep for all other screens that have analogous patterns (e.g., all `catch` blocks, all `isLoading` states, all empty-list branches).
36
+ 2. Apply the same pattern globally if it's missing or inconsistent.
37
+ 3. If the scope is too large for the current session, explicitly log it as a deferred item in the handoff with the exact files and patterns that need alignment.
38
+ - **The "Fix One, Fix All" mandate**: A local fix applied to one screen but not others is a regression-in-waiting. If you fix an error handler in `transactions.tsx`, check `shelf.tsx`, `index.tsx`, `discover.tsx`, `community.tsx`, and `scan.tsx` for the same issue.
39
+ - **Bidirectional & RTL Support**:
40
+ - Always use logical Tailwind / CSS properties (`ps-*`, `pe-*`, `ms-*`, `me-*`, `text-start`, `text-end`) instead of physical ones (`pl-*`, `pr-*`, `ml-*`, `mr-*`, `left-*`, `right-*`).
41
+ - In React Native RTL mode, use inverted horizontal lists (`inverted={isRTL}`) or direction-aware flex layouts so items begin on the right in Hebrew and left in English.
42
+ - Pass dynamic `dir={isRTL ? "rtl" : "ltr"}` to all Radix UI and shadcn primitives.
43
+ - **Physical Paradigm Alignment & Legacy Pruning Rule**:
44
+ - Whenever introducing or refactoring a flow, model, or paradigm (e.g. async drop-off vs in-person handoff, neighbor trust vs stranger marketplace), you MUST explicitly audit existing steps and PRUNE legacy mechanisms that create contradictory friction with the new flow. Never bolt new features on top of obsolete verification steps without removing what they replace.
45
+ - Every transaction or physical interaction flow MUST be traced step-by-step through a literal physical walkthrough from both actors' perspectives to ensure zero unnecessary friction gates (such as PINs, redundant codes, or mandatory face-to-face requirements).
46
+
47
+ ## 4. Framework & Backend Architecture
48
+ - **Verify Stack Versions First**: Before writing framework-specific code, confirm versions in `package.json` / `mobile/package.json` against `.agents/memory/stack-versions.md`. Never assume a newer/older framework convention; read the relevant guide in `node_modules/next/dist/docs/` (or the equivalent).
49
+ - **Async Route Params**: Dynamic route params in the App Router (`page.tsx`, `route.ts`) are Promises: always use `const { id } = await params;`.
50
+ - **Framer Motion Types**: Always import `Variants` from `framer-motion` to avoid TypeScript build failures.
51
+ - **Privacy & Visibility Tiers**: Enforce the project's visibility/privacy tier model (see `.agents/memory/domain-map.md` §Visibility tiers) across all data-access endpoints.
52
+
53
+ ## 5. Token Efficiency & Workflow Discipline
54
+ - **When NOT to Plan**: Do not generate heavy `implementation_plan.md` planning ceremonies for simple bug fixes, CSS/layout tweaks, single-file adjustments, or minor follow-ups. Execute directly to conserve tokens.
55
+ - **Precise File Inspections**: Avoid reading whole 800+ line files. Use `grep_search` with line numbers to locate the relevant region, then `read_file` with targeted line ranges.
56
+ - **Search Before Reading**: For questions about code, search first (`grep_search` / `file_search`) rather than opening files blind. Batch multiple independent searches/reads in parallel in a single turn.
57
+ - **Don't Re-read Unchanged Files**: If a file's content is already in context, edit it directly; only re-read the specific lines you need if context is stale.
58
+ - **Delegate Big Searches**: For broad, multi-file exploration ("where is X used?", "find all callers of Y"), use the `Explore` subagent instead of many manual search+read round-trips in the main conversation.
59
+ - **Prefer Memory over Re-derivation**: Persist non-obvious facts to `.agents/memory/` (stack versions, gotchas, handoff state) so future sessions never re-discover them. Read relevant memory files before starting.
60
+ - **Locations Map (read first)**: Before starting, read `.agents/memory/locations.md` — the canonical index of where sessions, logs, docs, and data live. Never re-hunt for a planning doc or a log path; it is (or should be) recorded there.
61
+ - **Subagent & Model Routing (Step Zero — non-negotiable)**: Before reading/editing any file for a task, satisfy the dispatch gate in `.agents/rules/00-operating.md` (§"Step Zero"). Personas: `planner`, `frontend-engineer`, `mobile-engineer`, `ui-designer`, `qa-architect`, `qa-runner`, `security-engineer`, `product-manager`, `system-architect`, `diagnostics-expert`, `data-engineer`, `devops-engineer`, `handoff`. Dispatch via the `task` tool — each runs on its own `model:` from `.opencode/agents/<name>.md`. Do NOT gather deep context inline first, and do NOT inline persona-owned work on the main conversation model; use the `skill` tool only for instruction-only context. Read `.agents/memory/model-routing.md` at session start for persona→model tiers. Dispatch **independent** subagents in **parallel**; serialize only on dependencies.
62
+ - **Synchronous Terminal Commands**: Prefer sync one-shot terminal commands (build, test, lint) that return output inline, rather than background servers/watchers, unless the process must keep running.
63
+ - **No Output Bloat**: Never paste large files or diffs into chat unless asked. Never print a code block of a change — apply the edit with the edit tool instead.
64
+ - **Right-Size the QA Tier**: Never run the full regression suite for a CSS/copy tweak — pick the minimal QA tier (see §6).
65
+
66
+ ## 6. Smart Tiered Testing & Progression Protocol (QA Architect + QA Runner)
67
+ - NEVER run full heavy regression suites blindly for small changes.
68
+ - Adopt the split QA personas: `qa-architect` (`.agents/skills/qa-architect/SKILL.md`) inspects the diff, audits testing gaps, selects the right-sized test plan, and authors progression tests; `qa-runner` (`.agents/skills/qa-runner/SKILL.md`) executes the chosen tier and reports pass/fail — the thinker never runs, the doer never designs:
69
+ - **The "Static ≠ Runtime" Rule**: Never declare UI, Mobile, or API changes verified based solely on static typing (`tsc`). Always execute live headless rendering or HTTP routes.
70
+ - **Tier 1 (UI, CSS, Mobile, Copy)**: Run `npm run test:quick` (Types + Translation Parity + Mobile Headless Component Smoke in ~3s).
71
+ - **Tier 2 (Route / Web Page layout)**: Run `npm run test:routes` or `node scripts/verify-all.js --route=<path>` (Web route render in ~4s).
72
+ - **Tier 3 (API, Prisma, Transactions)**: Run `npm run test:api` (API edge cases & governance in ~6s).
73
+ - **Tier 4 (Data Ingestion)**: Run `npx ts-node scripts/test-catalog.ts` (100-record E2E simulation).
74
+ - **Tier 5 (Major Release / Breaking Refactor)**: Run `npm run test:verify` (Full regression).
75
+ - **Tier 6 (Security / Dependencies)**: Run `npm run test:security` (`npm audit --audit-level=high`).
76
+ - **Progression Testing Workflow**: When introducing new routes, API endpoints, or database states:
77
+ 1. Author dedicated assertion pathways for the new feature in `scripts/verify-all.js`.
78
+ 2. Execute the targeted progression test to verify happy path and error boundaries.
79
+ 3. Graduate the new test into the permanent regression suite.
80
+
81
+ ## 7. Definition of Done & Continuous GitHub Backup
82
+ Every completed task MUST pass this gate, in order:
83
+ 0. **Feature Completeness Gate** — before running QA, verify the change against this checklist:
84
+ - [ ] **5 UI States**: Does every affected screen/component handle Ideal, Empty (with CTA), Loading (skeleton), Error (user-visible + retry), and Partial states? List each state explicitly.
85
+ - [ ] **Error handling**: Are there any `catch` blocks that only `console.warn`/`console.error` without user-facing feedback? (Zero tolerance — every catch must have haptic + visible error state.)
86
+ - [ ] **Haptic consistency**: Does every user-initiated action (button press, swipe, submit) produce haptic feedback (success or error)?
87
+ - [ ] **RTL verification**: If the change touches layout, has it been mentally traced through the project's RTL mode? Are all spacing/alignment properties logical (`ps-*`, `ms-*`, `text-start`)?
88
+ - [ ] **Cross-screen audit**: If you introduced a new UX pattern (e.g., a new error banner style, a new loading skeleton, a new action handler shape), grep for all similar patterns across other screens and apply consistently.
89
+ - [ ] **File size check**: If the modified file exceeds 500 lines, extract new or modified sections into separate component files before committing.
90
+ 1. **QA tier** — have `qa-architect` pick the right-sized tier (and author any progression tests), then `qa-runner` execute it and make it pass (§6).
91
+ 2. **Security check** — if the change touches data access, input, auth, external services, or secrets, apply the `security-engineer` skill and run `npm run test:security` when dependencies changed.
92
+ 3. **Commit** — stage changes, commit with a concise descriptive message (`feat:`, `fix:`, `refactor:`).
93
+ 4. **Push** — `git push origin main`.
94
+ - **Mechanical floor**: a git `pre-push` hook (husky) automatically runs `npm run test:quick` on every push — keep it green.
95
+ - **Lean permissions**: grant only the narrowest `git`/`gh` action needed; ask for escalated permission only after a command has actually failed — never preemptively.
96
+ - Git may not be on PATH in the default shell; use the full path to `git.exe` (see `.agents/memory/locations.md`).
97
+
98
+ ## 8. Session & Traceability Discipline
99
+ - **One session = one coherent task**. Do not bundle unrelated work into a single session; keep a short task checklist as the single source of truth.
100
+ - **Planned vs. Shipped**: At the end of each session, record a one-line "planned → shipped → deferred" delta so future agents can tell aspirational design docs from implemented reality. Never treat old planning docs as ground truth — always verify against the live code and the DB schema.
101
+ - **Dispatch Log (mandatory)**: Every session wrap-up MUST open with a dispatch log — `subagent → model → shipped/deferred`. An empty log is a non-compliant session (Step Zero gate was skipped).
102
+ - **Persist Continuity**: At session end, use the `handoff` skill to update `.agents/memory/handoff.md`. Project history lives in `.agents/memory/antigravity-history.md`; stack facts in `.agents/memory/stack-versions.md`.
103
+ - **Pointers Map Hygiene**: Whenever you create, discover, or change an important location during a session — a new external AI session archive, a scratch script, a log file, a doc, a DB target, an env file — you MUST record it in `.agents/memory/locations.md` so it never becomes unfindable. Each agent front-end records its own session/log paths. The `handoff` skill's pointer step enforces this at session end.
@@ -0,0 +1,29 @@
1
+ # Domain map — {{PROJECT_NAME}}
2
+
3
+ Project-specific domain facts the persona skills reference. Fill this in during
4
+ `npx @dombaras/agent-harness init`; keep it current as the domain evolves. The skills read
5
+ this instead of hardcoding domain assumptions.
6
+
7
+ ## Entity model
8
+ <!-- canonical → edition → item chain, plus supporting entities (author, etc.) -->
9
+ _TODO: describe the core and supporting entities and how they relate._
10
+
11
+ ## External sources
12
+ <!-- data sources / integrations, auth, and rate-limit notes -->
13
+ _TODO: list external catalog/data APIs this project ingests from._
14
+
15
+ ## Visibility / privacy tiers
16
+ <!-- e.g. community / private / public — and what each permits -->
17
+ _TODO: enumerate the access tiers and their rules._
18
+
19
+ ## Core state machine(s)
20
+ <!-- the central domain process/FSM that `system-architect` governs -->
21
+ _TODO: name and outline the domain's central lifecycle/state machine._
22
+
23
+ ## Trust & gamification
24
+ <!-- user progression tiers and activity badges -->
25
+ _TODO: define user tiers and rewards._
26
+
27
+ ## Domain identifiers & acronyms
28
+ <!-- ID formats (ISBN/barcode/etc.), domain-specific terms -->
29
+ _TODO: list identifier patterns and glossary terms._
@@ -0,0 +1,12 @@
1
+ # Where we stopped (handoff)
2
+
3
+ Date: <YYYY-MM-DD>
4
+
5
+ ## Dispatch log
6
+ - <subagent → model → shipped/deferred> (empty log = non-compliant session)
7
+
8
+ ## Done this session (planned → shipped → deferred)
9
+ -
10
+
11
+ ## Still open / next
12
+ -
@@ -0,0 +1,10 @@
1
+ # Locations map
2
+
3
+ Canonical index of where sessions, logs, docs, and data live. Update whenever a
4
+ session creates, discovers, or changes an important location.
5
+
6
+ - **Repos**:
7
+ - **Logs / telemetry**:
8
+ - **DB / env**:
9
+ - **Docs**:
10
+ - **AI session archives**: (each agent front-end records its own paths)
@@ -0,0 +1,47 @@
1
+ # Model routing
2
+
3
+ This project's subagent personas run on their own models via the `model:`
4
+ frontmatter in `.opencode/agents/<name>.md`. This file documents the tiering
5
+ policy — the concrete model IDs are the source of truth in the agent files
6
+ (and `opencode.json` for the main conversation).
7
+
8
+ ## Tiers (recommended — override per-project)
9
+
10
+ | Tier | Purpose |
11
+ |---|---|
12
+ | reasoning | Planning, architecture, security review, debugging, product design, QA architecture |
13
+ | general | Everyday coding, UI design, mobile native, infra/devops, data, QA execution |
14
+ | mechanical | File reads, commits, handoffs |
15
+
16
+ The harness ships a recommended concrete mapping (`reasoning` → a strong
17
+ reasoning model, `general` → a strong coder model, `mechanical` → a cheap fast
18
+ model). Change it only by editing `.opencode/agents/<name>.md` `model:` — the
19
+ `model:` label in `.agents/skills/*/SKILL.md` is informational only and does NOT
20
+ route models.
21
+
22
+ ## Subagent output contract
23
+
24
+ Every subagent must return a single final message with, in order:
25
+
26
+ 1. **Result** — what was shipped / decided.
27
+ 2. **Evidence** — commands run or files changed with observed output.
28
+ 3. **Deferred & risks** — what remains and follow-ups the orchestrator must handle.
29
+
30
+ ## Dispatch failure ladder (never silent)
31
+
32
+ 1. Retry once (resume the same `task_id`).
33
+ 2. Degrade inline on the main model and log `degraded: <persona> model: <reason>`.
34
+ 3. Never silently skip or re-scope — only waive via the explicit waiver path.
35
+
36
+ ## Dispatch preflight (`npm run test:dispatch`)
37
+
38
+ `scripts/qa/check-dispatch-config.js` verifies model pins, persona↔skill parity,
39
+ and the output-contract marker. Run it after editing any agent/skill path:
40
+
41
+ ```
42
+ npm run test:dispatch
43
+ ```
44
+
45
+ ## Gotchas
46
+
47
+ - Restart the agent CLI after editing `opencode.json` or agent files (read once at startup).
@@ -0,0 +1,12 @@
1
+ # Stack versions — {{PROJECT_NAME}}
2
+
3
+ Confirmed framework / runtime versions. Verify against `package.json` and
4
+ `mobile/package.json` before trusting this file.
5
+
6
+ _TODO: record web framework, styling, ORM, mobile SDK/native, and key libraries with versions._
7
+
8
+ - **Web**:
9
+ - **Styling**:
10
+ - **ORM / DB**:
11
+ - **Mobile**:
12
+ - **Key native libs**:
@@ -0,0 +1,85 @@
1
+ # {{PROJECT_NAME}} Operating Rules
2
+
3
+ These rules apply to the entire repository. They are enforced across all agent
4
+ front-ends (VS Code Copilot, Claude Code, Zoo Code, Antigravity).
5
+
6
+ ## Step Zero — Subagent dispatch gate (NON-NEGOTIABLE)
7
+
8
+ Before reading or editing any file for a task, STOP and dispatch:
9
+
10
+ 1. Decompose the task and identify which personas it touches using the mapping below (lookup, not judgment). For non-trivial tasks, dispatch `planner` first to emit the dispatch plan.
11
+ 2. Dispatch each persona via the `task` tool — the subagent runs on its own `model:` from `.opencode/agents/<name>.md`.
12
+ 3. Dispatch **independent** subagents in **parallel** (one message, multiple `task` calls); serialize only when one depends on another's output.
13
+ 4. Keep only coordination/mechanical work (git, commits, reads, final integration) on the main model.
14
+
15
+ Do NOT gather deep context inline first — that is exactly what causes the "might as well finish inline" collapse. Skipping dispatch is a rules violation, not a style preference.
16
+
17
+ > **Waivers (the ONLY way to skip a persona — explicit and recordable):** A persona may be skipped ONLY when the change is (a) fully covered by an automated gate that runs on push or in the QA tiers (`lint:hooks`, `test:schema`, `test:dispatch`, `test:governance`, `test:security`, or a peer `test:*`), AND (b) the skip was pre-audited in `.agents/memory/` with a cited pointer. Any other skip is a HIGH-severity rules violation. Every waiver MUST be written into the wrap-up dispatch log as `waived: <persona>` with `reason: <gate or pointer>`.
18
+ >
19
+ > **Dispatch failure ladder (never silent):** if a `task` dispatch fails, (1) retry the same task once (resume the same `task_id`); (2) if it still fails, degrade by doing the persona work inline on the main model AND log `degraded: <persona> model: <failure>` in the wrap-up dispatch log; (3) never silently re-scope or skip. Mirror in `.agents/memory/model-routing.md` §"Dispatch failure ladder".
20
+
21
+ Every subagent must return the **output contract** (`result` → `evidence` → `deferred & risks`); see `.agents/memory/model-routing.md`.
22
+
23
+ | Work area | Persona subagent |
24
+ |---|---|
25
+ | Task decomposition → dispatch plan | `planner` |
26
+ | Web app code (React / Next.js / Tailwind / shadcn) | `frontend-engineer` |
27
+ | Mobile native (Expo / React Native) | `mobile-engineer` |
28
+ | Design system / tokens / shared components | `ui-designer` |
29
+ | QA strategy (risk + tier + progression tests) | `qa-architect` |
30
+ | QA execution (run tiers, catalog E2E, data cleanup) | `qa-runner` |
31
+ | DB schema / data model / tenancy / sync protocol | `system-architect` |
32
+ | Auth, secrets, input validation, external services, deps | `security-engineer` |
33
+ | Error / performance / API debugging | `diagnostics-expert` |
34
+ | Features, gamification, product journeys | `product-manager` |
35
+ | Data/catalog ingestion / entity resolution | `data-engineer` |
36
+ | Deployment / cron / secrets / build & release | `devops-engineer` |
37
+ | Session wrap-up / handoff | `handoff` |
38
+
39
+ Every session wrap-up MUST open with a **dispatch log** — `subagent → model → shipped/deferred`. An empty log is a non-compliant session.
40
+
41
+ ## 1. Fact-Based, Zero-Guessing SDLC — Evidence Over Speculation
42
+ - NEVER speculate, guess, or assume the root cause of an error or system behavior across any persona.
43
+ - Inspect live logs, telemetry (debug-log endpoints, mobile debug logs), structured telemetry records (e.g. `ExternalServiceLog`), or database state before proposing fixes.
44
+ - If logs/telemetry are insufficient, FIRST add structured instrumentation, run it, reproduce, capture actual data, and base the fix exclusively on observed facts.
45
+ - Verify against the real application runtime — never ad-hoc scripts that bypass real config/middleware.
46
+
47
+ ## 2. Data & business-logic integrity
48
+ - NEVER create hardcoded mock lists or fake data (records, reviews, fallback arrays) without explicit approval.
49
+ - Prefer dynamic database queries and database-backed `SystemSetting` values.
50
+
51
+ ## 3. UI, mobile ergonomics, RTL & flow alignment
52
+ - NEVER use `Alert.alert()`, `alert()`, `confirm()`, or `prompt()`. Use toasts, bottom sheets, or inline states.
53
+ - Hydrate from local cache (AsyncStorage / SQLite) so the UI never renders blank loading states.
54
+ - Handle the 5 UI states: ideal, empty (with CTA), loading, error (with retry), partial/single-item.
55
+ - Use logical CSS/props (`ps-*`, `ms-*`, `text-start`), never physical (`pl-*`, `left-*`).
56
+ - In React Native RTL, use inverted horizontal lists and direction-aware flex.
57
+ - **Legacy Pruning & Physical Roleplay Rule**: When refactoring or introducing a new flow/paradigm (e.g. async drop-off vs in-person handoff), ALWAYS audit and prune contradictory legacy friction steps (e.g. PINs, redundant codes) and roleplay the physical real-world user journey step-by-step.
58
+
59
+ ## 4. Stack — verify versions first
60
+ - Never assume framework versions from memory. Read `.agents/memory/stack-versions.md` (the project-specific version manifest) before writing framework code.
61
+ - Read the relevant framework guide shipped in `node_modules/<framework>/dist/docs/` (if present) before writing against it; heed deprecation notices.
62
+ - Framework-specific gotchas (e.g. async route params, strict typing) live in the `frontend-engineer` / `mobile-engineer` skills.
63
+
64
+ ## 5. Token & workflow discipline
65
+ - No heavy planning docs for simple fixes.
66
+ - Search before reading; use targeted line reads; batch independent searches/reads.
67
+ - Delegate broad searches; persist non-obvious facts to `.agents/memory/`.
68
+ - **Subagent & model routing**: Satisfy the **Step Zero dispatch gate** (top of this file) before touching any code. Read `.agents/memory/model-routing.md` at session start for the persona→concrete-model tiers. Do NOT inline persona-owned work in the main conversation; load a persona via the `skill` tool only for instruction-only context.
69
+
70
+ ## 6. Testing — right-sized QA tier & Static ≠ Runtime rule
71
+ - Never declare code verified based solely on static typing (`tsc`); always execute runtime component or API pathways.
72
+ - Tier 1: `npm run test:quick` (Types + Translations + Mobile Headless Render Smoke in ~3s) · Tier 2: `npm run test:routes` · Tier 3: `npm run test:api` · Tier 5: `npm run test:verify` · Tier 6: `npm run test:security`.
73
+ - Audit testing gaps per subsystem and graduate progression tests into the permanent regression suite.
74
+
75
+ ## 7. Definition of Done
76
+ 1. Run the right-sized QA tier and make it pass.
77
+ 2. Apply the security lens when the change touches data, auth, input, or secrets.
78
+ 3. Commit with a concise `feat:` / `fix:` / `refactor:` message.
79
+ 4. Push to `main` (the pre-push hook runs `npm run test:quick`).
80
+
81
+ ## 8. Session discipline
82
+ - One session = one coherent task.
83
+ - At the end, record a planned → shipped → deferred delta (see `.agents/skills/handoff/SKILL.md`).
84
+ - Every wrap-up MUST open with the **dispatch log** (`subagent → model → shipped/deferred`). Empty log = non-compliant session.
85
+ - Read `.agents/memory/locations.md` at session start (canonical map of sessions, logs, docs, data). Update it at session end with any new/changed locations (external session archives, scratch scripts, log files, DB targets), so each front-end's data stays discoverable.
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: data-engineer
3
+ description: Use for catalog/data ingestion and entity resolution — external-source ingestion, canonical-record dedup, external service telemetry.
4
+ model: general
5
+ ---
6
+
7
+ # Data / Catalog Engineer
8
+
9
+ You own catalog/data ingestion, entity resolution, and external service integration — not the core domain state machine (that's `system-architect`) and not UI.
10
+
11
+ > **Project specifics live in memory, not here.** Read `.agents/memory/domain-map.md` (external sources, entity model chain, canonical/dedup rules) before touching ingestion code.
12
+
13
+ ## Output contract (always return)
14
+
15
+ 1. **What changed** — files + one-line summaries.
16
+ 2. **Entity-resolution impact** — how dedup/canonicalization behavior changed and any migration seed needed.
17
+ 3. **External-service notes** — new endpoints/keys, rate-limit handling, telemetry-log coverage.
18
+
19
+ ## Scope
20
+
21
+ - Ingest from your project's external sources (see `.agents/memory/domain-map.md` §External sources) and map them into the canonical entity chain (see §Entity model).
22
+ - Entity resolution / dedup heuristics (canonical-vs-edition matching, cross-source reconciliation).
23
+ - External-service telemetry via a structured log (`ExternalServiceLog`): status, latency, rate-limit, auth errors.
24
+
25
+ ## Rules
26
+
27
+ - NEVER hardcode mock/sample data or static fallback lists — always dynamic DB queries and database-backed `SystemSetting` values.
28
+ - New ingestion code requires a progression test at Tier 4 (data E2E simulation), handed to `qa-runner`.
29
+ - Preserve the project's visibility tiers and the attribution of external ratings/sources (e.g. `externalRatingSource`).
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: devops-engineer
3
+ description: Use for deployment, CI/CD, cron/scheduling, env & secrets management, hosting config, and mobile build/release setup.
4
+ model: general
5
+ ---
6
+
7
+ # DevOps / Infrastructure Engineer
8
+
9
+ You own deployment, scheduling, secrets, and build/release pipelines — not application logic.
10
+
11
+ ## Output contract (always return)
12
+
13
+ 1. **What changed** — config/env files + one-line summaries.
14
+ 2. **Post-deploy steps** — anything the user must do manually (add env vars, approve a build, rotate a secret).
15
+ 3. **Rollback/risk** — how to revert and what the failure mode is.
16
+
17
+ ## Scope
18
+
19
+ - **Cron / scheduling**: the project's hosting cron config (e.g. `vercel.json` `crons`, where the provider sends a cron secret as an `Authorization: Bearer` header and never follows redirects; verify the plan's run-frequency cap).
20
+ - **Env & secrets**: `.env` (gitignored) / `.env.example` (tracked). Never commit a real secret; document the variable in `.env.example`.
21
+ - **Deployment**: the project's hosting config (build settings, `maxDuration`, etc.) — see `.agents/memory/locations.md` for the canonical deploy targets.
22
+ - **Mobile releases**: `eas build`, TestFlight, Play internal track.
23
+
24
+ ## Rules
25
+
26
+ - Verify cron cadence is idempotent before deploying (reconciliation-based, safe on duplicate/missed runs).
27
+ - Update `.agents/memory/locations.md` if you add a new deploy/env/scheduler target.
28
+ - Refer `npm audit` to `qa-runner` under Tier 6 (`npm run test:security`) rather than running it yourself when it's QA context.