agent-quality-police 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/anti-bypass-audit/SKILL.md +63 -0
- package/.agents/skills/anti-bypass-audit/checklists/audit-checklist.md +7 -0
- package/.agents/skills/anti-bypass-audit/examples/bad/explicit-bypass.ts +32 -0
- package/.agents/skills/anti-bypass-audit/examples/good/fixed-bypass.ts +21 -0
- package/.agents/skills/anti-bypass-audit/examples/good/fixed-bypass.types.ts +20 -0
- package/.agents/skills/anti-bypass-audit/references/report-format.md +9 -0
- package/.agents/skills/governance-installation/SKILL.md +55 -0
- package/.agents/skills/governance-installation/checklists/install-checklist.md +6 -0
- package/.agents/skills/governance-installation/examples/bad/stale-projection.md +12 -0
- package/.agents/skills/governance-installation/examples/good/install-sequence.md +7 -0
- package/.agents/skills/governance-installation/references/install-steps.md +28 -0
- package/.agents/skills/quality-index/SKILL.md +66 -0
- package/.agents/skills/quality-index/checklists/routing-checklist.md +6 -0
- package/.agents/skills/quality-index/examples/bad/task-routing.md +15 -0
- package/.agents/skills/quality-index/examples/good/task-routing.md +18 -0
- package/.agents/skills/quality-index/references/system-entrypoints.md +9 -0
- package/.agents/skills/react-public-api-testing/SKILL.md +65 -0
- package/.agents/skills/react-public-api-testing/checklists/query-checklist.md +5 -0
- package/.agents/skills/react-public-api-testing/examples/bad/primary-button.component-antipattern.tsx +35 -0
- package/.agents/skills/react-public-api-testing/examples/bad/primary-button.conditional-setup-bloat.tsx +32 -0
- package/.agents/skills/react-public-api-testing/examples/bad/primary-button.duplicated-branch.tsx +30 -0
- package/.agents/skills/react-public-api-testing/examples/bad/primary-button.internal.test.tsx +23 -0
- package/.agents/skills/react-public-api-testing/examples/good/primary-button.test.tsx +36 -0
- package/.agents/skills/react-public-api-testing/examples/good/primary-button.tsx +27 -0
- package/.agents/skills/react-public-api-testing/examples/good/primary-button.types.ts +5 -0
- package/.agents/skills/react-public-api-testing/references/query-order.md +11 -0
- package/.agents/skills/refactoring-with-safety/SKILL.md +52 -0
- package/.agents/skills/refactoring-with-safety/checklists/refactor-checklist.md +6 -0
- package/.agents/skills/refactoring-with-safety/examples/bad/behavior-change-masquerading.md +12 -0
- package/.agents/skills/refactoring-with-safety/examples/good/characterization-sequence.md +12 -0
- package/.agents/skills/refactoring-with-safety/references/refactor-sequence.md +7 -0
- package/.agents/skills/typescript-zero-bypass/SKILL.md +62 -0
- package/.agents/skills/typescript-zero-bypass/checklists/review-checklist.md +6 -0
- package/.agents/skills/typescript-zero-bypass/examples/bad/assertion-shortcuts.ts +13 -0
- package/.agents/skills/typescript-zero-bypass/examples/good/no-assertion-model.ts +31 -0
- package/.agents/skills/typescript-zero-bypass/references/modeling-patterns.md +17 -0
- package/.agents/skills/vite-vitest-tdd/SKILL.md +58 -0
- package/.agents/skills/vite-vitest-tdd/checklists/tdd-checklist.md +6 -0
- package/.agents/skills/vite-vitest-tdd/examples/bad/fraudulent-mock.test.ts +13 -0
- package/.agents/skills/vite-vitest-tdd/examples/bad/helper-noise.test.ts +28 -0
- package/.agents/skills/vite-vitest-tdd/examples/bad/implementation-detail.test.ts +15 -0
- package/.agents/skills/vite-vitest-tdd/examples/good/checkout-service.test.ts +42 -0
- package/.agents/skills/vite-vitest-tdd/examples/good/direct-factory.test.ts +29 -0
- package/.agents/skills/vite-vitest-tdd/examples/good/discount.test.ts +23 -0
- package/.agents/skills/vite-vitest-tdd/examples/good/discount.ts +16 -0
- package/.agents/skills/vite-vitest-tdd/references/mock-policy.md +9 -0
- package/.claude/agents/bypass-auditor.md +45 -0
- package/.claude/agents/implementer.md +44 -0
- package/.claude/agents/pr-gatekeeper.md +41 -0
- package/.claude/agents/tdd-warden.md +40 -0
- package/.claude/rules/core-non-negotiables.md +8 -0
- package/.claude/rules/review-and-gates.md +7 -0
- package/.claude/rules/testing-and-tdd.md +13 -0
- package/.claude/rules/typescript-zero-bypass.md +14 -0
- package/.claude/skills/anti-bypass-audit/SKILL.md +63 -0
- package/.claude/skills/anti-bypass-audit/checklists/audit-checklist.md +7 -0
- package/.claude/skills/anti-bypass-audit/examples/bad/explicit-bypass.ts +32 -0
- package/.claude/skills/anti-bypass-audit/examples/good/fixed-bypass.ts +21 -0
- package/.claude/skills/anti-bypass-audit/examples/good/fixed-bypass.types.ts +20 -0
- package/.claude/skills/anti-bypass-audit/references/report-format.md +9 -0
- package/.claude/skills/governance-installation/SKILL.md +55 -0
- package/.claude/skills/governance-installation/checklists/install-checklist.md +6 -0
- package/.claude/skills/governance-installation/examples/bad/stale-projection.md +12 -0
- package/.claude/skills/governance-installation/examples/good/install-sequence.md +7 -0
- package/.claude/skills/governance-installation/references/install-steps.md +28 -0
- package/.claude/skills/quality-index/SKILL.md +66 -0
- package/.claude/skills/quality-index/checklists/routing-checklist.md +6 -0
- package/.claude/skills/quality-index/examples/bad/task-routing.md +15 -0
- package/.claude/skills/quality-index/examples/good/task-routing.md +18 -0
- package/.claude/skills/quality-index/references/system-entrypoints.md +9 -0
- package/.claude/skills/react-public-api-testing/SKILL.md +65 -0
- package/.claude/skills/react-public-api-testing/checklists/query-checklist.md +5 -0
- package/.claude/skills/react-public-api-testing/examples/bad/primary-button.component-antipattern.tsx +35 -0
- package/.claude/skills/react-public-api-testing/examples/bad/primary-button.conditional-setup-bloat.tsx +32 -0
- package/.claude/skills/react-public-api-testing/examples/bad/primary-button.duplicated-branch.tsx +30 -0
- package/.claude/skills/react-public-api-testing/examples/bad/primary-button.internal.test.tsx +23 -0
- package/.claude/skills/react-public-api-testing/examples/good/primary-button.test.tsx +36 -0
- package/.claude/skills/react-public-api-testing/examples/good/primary-button.tsx +27 -0
- package/.claude/skills/react-public-api-testing/examples/good/primary-button.types.ts +5 -0
- package/.claude/skills/react-public-api-testing/references/query-order.md +11 -0
- package/.claude/skills/refactoring-with-safety/SKILL.md +52 -0
- package/.claude/skills/refactoring-with-safety/checklists/refactor-checklist.md +6 -0
- package/.claude/skills/refactoring-with-safety/examples/bad/behavior-change-masquerading.md +12 -0
- package/.claude/skills/refactoring-with-safety/examples/good/characterization-sequence.md +12 -0
- package/.claude/skills/refactoring-with-safety/references/refactor-sequence.md +7 -0
- package/.claude/skills/typescript-zero-bypass/SKILL.md +62 -0
- package/.claude/skills/typescript-zero-bypass/checklists/review-checklist.md +6 -0
- package/.claude/skills/typescript-zero-bypass/examples/bad/assertion-shortcuts.ts +13 -0
- package/.claude/skills/typescript-zero-bypass/examples/good/no-assertion-model.ts +31 -0
- package/.claude/skills/typescript-zero-bypass/references/modeling-patterns.md +17 -0
- package/.claude/skills/vite-vitest-tdd/SKILL.md +58 -0
- package/.claude/skills/vite-vitest-tdd/checklists/tdd-checklist.md +6 -0
- package/.claude/skills/vite-vitest-tdd/examples/bad/fraudulent-mock.test.ts +13 -0
- package/.claude/skills/vite-vitest-tdd/examples/bad/helper-noise.test.ts +28 -0
- package/.claude/skills/vite-vitest-tdd/examples/bad/implementation-detail.test.ts +15 -0
- package/.claude/skills/vite-vitest-tdd/examples/good/checkout-service.test.ts +42 -0
- package/.claude/skills/vite-vitest-tdd/examples/good/direct-factory.test.ts +29 -0
- package/.claude/skills/vite-vitest-tdd/examples/good/discount.test.ts +23 -0
- package/.claude/skills/vite-vitest-tdd/examples/good/discount.ts +16 -0
- package/.claude/skills/vite-vitest-tdd/references/mock-policy.md +9 -0
- package/.claude-plugin/plugin.json +22 -0
- package/.codex/agents/bypass-auditor.toml +40 -0
- package/.codex/agents/implementer.toml +34 -0
- package/.codex/agents/pr-gatekeeper.toml +35 -0
- package/.codex/agents/tdd-warden.toml +35 -0
- package/.codex-plugin/plugin.json +40 -0
- package/.opencode/agents/bypass-auditor.md +43 -0
- package/.opencode/agents/implementer.md +37 -0
- package/.opencode/agents/pr-gatekeeper.md +38 -0
- package/.opencode/agents/tdd-warden.md +38 -0
- package/.opencode/skills/anti-bypass-audit/SKILL.md +63 -0
- package/.opencode/skills/anti-bypass-audit/checklists/audit-checklist.md +7 -0
- package/.opencode/skills/anti-bypass-audit/examples/bad/explicit-bypass.ts +32 -0
- package/.opencode/skills/anti-bypass-audit/examples/good/fixed-bypass.ts +21 -0
- package/.opencode/skills/anti-bypass-audit/examples/good/fixed-bypass.types.ts +20 -0
- package/.opencode/skills/anti-bypass-audit/references/report-format.md +9 -0
- package/.opencode/skills/governance-installation/SKILL.md +55 -0
- package/.opencode/skills/governance-installation/checklists/install-checklist.md +6 -0
- package/.opencode/skills/governance-installation/examples/bad/stale-projection.md +12 -0
- package/.opencode/skills/governance-installation/examples/good/install-sequence.md +7 -0
- package/.opencode/skills/governance-installation/references/install-steps.md +28 -0
- package/.opencode/skills/quality-index/SKILL.md +66 -0
- package/.opencode/skills/quality-index/checklists/routing-checklist.md +6 -0
- package/.opencode/skills/quality-index/examples/bad/task-routing.md +15 -0
- package/.opencode/skills/quality-index/examples/good/task-routing.md +18 -0
- package/.opencode/skills/quality-index/references/system-entrypoints.md +9 -0
- package/.opencode/skills/react-public-api-testing/SKILL.md +65 -0
- package/.opencode/skills/react-public-api-testing/checklists/query-checklist.md +5 -0
- package/.opencode/skills/react-public-api-testing/examples/bad/primary-button.component-antipattern.tsx +35 -0
- package/.opencode/skills/react-public-api-testing/examples/bad/primary-button.conditional-setup-bloat.tsx +32 -0
- package/.opencode/skills/react-public-api-testing/examples/bad/primary-button.duplicated-branch.tsx +30 -0
- package/.opencode/skills/react-public-api-testing/examples/bad/primary-button.internal.test.tsx +23 -0
- package/.opencode/skills/react-public-api-testing/examples/good/primary-button.test.tsx +36 -0
- package/.opencode/skills/react-public-api-testing/examples/good/primary-button.tsx +27 -0
- package/.opencode/skills/react-public-api-testing/examples/good/primary-button.types.ts +5 -0
- package/.opencode/skills/react-public-api-testing/references/query-order.md +11 -0
- package/.opencode/skills/refactoring-with-safety/SKILL.md +52 -0
- package/.opencode/skills/refactoring-with-safety/checklists/refactor-checklist.md +6 -0
- package/.opencode/skills/refactoring-with-safety/examples/bad/behavior-change-masquerading.md +12 -0
- package/.opencode/skills/refactoring-with-safety/examples/good/characterization-sequence.md +12 -0
- package/.opencode/skills/refactoring-with-safety/references/refactor-sequence.md +7 -0
- package/.opencode/skills/typescript-zero-bypass/SKILL.md +62 -0
- package/.opencode/skills/typescript-zero-bypass/checklists/review-checklist.md +6 -0
- package/.opencode/skills/typescript-zero-bypass/examples/bad/assertion-shortcuts.ts +13 -0
- package/.opencode/skills/typescript-zero-bypass/examples/good/no-assertion-model.ts +31 -0
- package/.opencode/skills/typescript-zero-bypass/references/modeling-patterns.md +17 -0
- package/.opencode/skills/vite-vitest-tdd/SKILL.md +58 -0
- package/.opencode/skills/vite-vitest-tdd/checklists/tdd-checklist.md +6 -0
- package/.opencode/skills/vite-vitest-tdd/examples/bad/fraudulent-mock.test.ts +13 -0
- package/.opencode/skills/vite-vitest-tdd/examples/bad/helper-noise.test.ts +28 -0
- package/.opencode/skills/vite-vitest-tdd/examples/bad/implementation-detail.test.ts +15 -0
- package/.opencode/skills/vite-vitest-tdd/examples/good/checkout-service.test.ts +42 -0
- package/.opencode/skills/vite-vitest-tdd/examples/good/direct-factory.test.ts +29 -0
- package/.opencode/skills/vite-vitest-tdd/examples/good/discount.test.ts +23 -0
- package/.opencode/skills/vite-vitest-tdd/examples/good/discount.ts +16 -0
- package/.opencode/skills/vite-vitest-tdd/references/mock-policy.md +9 -0
- package/AGENTS.md +71 -0
- package/CLAUDE.md +79 -0
- package/LICENSE +21 -0
- package/README.md +21 -0
- package/bin/aqp.mjs +138 -0
- package/docs/policy/quality-definition.md +132 -0
- package/docs/policy/system-layout.md +33 -0
- package/docs/policy/workflow.md +31 -0
- package/lib/install.mjs +376 -0
- package/opencode.json +9 -0
- package/package.json +46 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: anti-bypass-audit
|
|
3
|
+
description: Audit a diff for type, test, config, and review fraud. Use when a change looks suspicious, when an LLM-generated diff may have hidden bypasses, or before any final approval.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Objective
|
|
7
|
+
|
|
8
|
+
Find and report bypasses with short, evidence-based language. This skill is not for rewriting code. It is for blocking unsafe diffs.
|
|
9
|
+
|
|
10
|
+
## When To Use
|
|
11
|
+
|
|
12
|
+
- Reviewing TypeScript changes
|
|
13
|
+
- Reviewing tests, helpers, mocks, or config
|
|
14
|
+
- Checking a diff before merge or publication
|
|
15
|
+
|
|
16
|
+
## When Not To Use
|
|
17
|
+
|
|
18
|
+
- Greenfield implementation before any diff exists
|
|
19
|
+
|
|
20
|
+
## Workflow
|
|
21
|
+
|
|
22
|
+
1. Scan the diff for banned tokens and suspicious structure.
|
|
23
|
+
2. Check whether tests prove behavior or merely confirm implementation.
|
|
24
|
+
3. Check whether config was weakened.
|
|
25
|
+
4. Produce a terse report with findings, evidence, and required correction.
|
|
26
|
+
|
|
27
|
+
## Quality Criteria
|
|
28
|
+
|
|
29
|
+
- Findings cite file evidence.
|
|
30
|
+
- Reports separate blockers from optional cleanup.
|
|
31
|
+
- The audit stays hostile to bypasses and calm in tone.
|
|
32
|
+
|
|
33
|
+
## Banned Diff Signals
|
|
34
|
+
|
|
35
|
+
- `any`
|
|
36
|
+
- assertions
|
|
37
|
+
- non-null assertions
|
|
38
|
+
- `Map` used as a lookup-bag in public or domain-facing contracts
|
|
39
|
+
- ts-comments
|
|
40
|
+
- `eslint-disable`
|
|
41
|
+
- lowered strictness in config
|
|
42
|
+
- fake narrowing branches
|
|
43
|
+
- helper or factory noise hiding test intent
|
|
44
|
+
- mocks that replace the behavior under test
|
|
45
|
+
|
|
46
|
+
## Report Format
|
|
47
|
+
|
|
48
|
+
- `Finding:`
|
|
49
|
+
- `Evidence:`
|
|
50
|
+
- `Required correction:`
|
|
51
|
+
|
|
52
|
+
## Examples
|
|
53
|
+
|
|
54
|
+
- Good correction: `examples/good/fixed-bypass.types.ts`, `examples/good/fixed-bypass.ts`
|
|
55
|
+
- Bad diff: `examples/bad/explicit-bypass.ts`
|
|
56
|
+
|
|
57
|
+
## Checklist
|
|
58
|
+
|
|
59
|
+
- See `checklists/audit-checklist.md`
|
|
60
|
+
|
|
61
|
+
## References
|
|
62
|
+
|
|
63
|
+
- `references/report-format.md`
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Audit Checklist
|
|
2
|
+
|
|
3
|
+
- Did you search for banned syntax and weakened config?
|
|
4
|
+
- Did you flag `Map` when it was used to avoid explicit contract modeling?
|
|
5
|
+
- Did you inspect tests for behavior proof instead of implementation detail?
|
|
6
|
+
- Did you reject helper or mock noise when it weakened the claim?
|
|
7
|
+
- Did you end with a blocker-oriented report?
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface LookupHit {
|
|
2
|
+
kind: 'hit';
|
|
3
|
+
email: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface LookupMiss {
|
|
7
|
+
kind: 'miss';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type LookupResult = LookupHit | LookupMiss;
|
|
11
|
+
|
|
12
|
+
export function findCustomerEmail(
|
|
13
|
+
emailsByCustomerId: Map<string, string>,
|
|
14
|
+
customerId: string,
|
|
15
|
+
): LookupResult {
|
|
16
|
+
const rawEmail = emailsByCustomerId.get(customerId) as string;
|
|
17
|
+
|
|
18
|
+
if (rawEmail.length === 0) {
|
|
19
|
+
return { kind: 'miss' };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
kind: 'hit',
|
|
24
|
+
email: rawEmail!,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Reprovado porque:
|
|
29
|
+
// - usa Map para evitar modelar uma entrada nomeada e explícita
|
|
30
|
+
// - mistura interfaces e função no mesmo arquivo, quebrando o padrão adotado aqui
|
|
31
|
+
// - usa assertion para mentir sobre um lookup potencialmente ausente
|
|
32
|
+
// - usa non-null assertion para esconder o caso ausente em vez de modelá-lo
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type CustomerEmailLookupInput,
|
|
3
|
+
type LookupResult,
|
|
4
|
+
} from './fixed-bypass.types';
|
|
5
|
+
|
|
6
|
+
export function findCustomerEmail(
|
|
7
|
+
input: CustomerEmailLookupInput,
|
|
8
|
+
): LookupResult {
|
|
9
|
+
const customerEmail = input.customerEmails.find(
|
|
10
|
+
(entry) => entry.customerId === input.customerId,
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
if (customerEmail === undefined) {
|
|
14
|
+
return { kind: 'miss' };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
kind: 'hit',
|
|
19
|
+
email: customerEmail.email,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface CustomerEmailEntry {
|
|
2
|
+
customerId: string;
|
|
3
|
+
email: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface CustomerEmailLookupInput {
|
|
7
|
+
customerEmails: readonly CustomerEmailEntry[];
|
|
8
|
+
customerId: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface LookupHit {
|
|
12
|
+
kind: 'hit';
|
|
13
|
+
email: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface LookupMiss {
|
|
17
|
+
kind: 'miss';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type LookupResult = LookupHit | LookupMiss;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: governance-installation
|
|
3
|
+
description: Install or update this governance framework in another repository. Use when copying the pack, regenerating projections, or validating that a target repository is aligned with the canonical policy.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Objective
|
|
7
|
+
|
|
8
|
+
Install or refresh the framework without letting generated projections drift away from the canonical policy.
|
|
9
|
+
|
|
10
|
+
## When To Use
|
|
11
|
+
|
|
12
|
+
- Copying the framework into another repository
|
|
13
|
+
- Updating skills, rules, or agent specs and rebuilding projections
|
|
14
|
+
- Verifying that generated files were refreshed after a policy change
|
|
15
|
+
|
|
16
|
+
## When Not To Use
|
|
17
|
+
|
|
18
|
+
- Day-to-day feature work inside a repository that already has the framework installed
|
|
19
|
+
|
|
20
|
+
## Workflow
|
|
21
|
+
|
|
22
|
+
1. Copy the canonical files first.
|
|
23
|
+
2. Run `python3 scripts/build_framework.py`.
|
|
24
|
+
3. Run `python3 scripts/validate_framework.py`.
|
|
25
|
+
4. If scripts or package installer sources changed, run `python3 -m unittest tests/test_framework_tools.py` and `node --test tests/node/install.test.mjs`.
|
|
26
|
+
5. Commit only after projections and validation are green.
|
|
27
|
+
|
|
28
|
+
## Quality Criteria
|
|
29
|
+
|
|
30
|
+
- Repository entrypoints are generated from the canonical entrypoint source instead of being hand-authored per tool.
|
|
31
|
+
- Canonical and generated layers are both present.
|
|
32
|
+
- `.agents/skills/` matches `.claude/skills/`.
|
|
33
|
+
- Agent projections exist for Claude, OpenCode, and Codex.
|
|
34
|
+
- Package-ready plugin distribution and marketplace metadata exist for Claude and Codex.
|
|
35
|
+
- No placeholders, missing links, or stale projections remain.
|
|
36
|
+
|
|
37
|
+
## Anti-Patterns
|
|
38
|
+
|
|
39
|
+
- Hand-maintaining separate root entrypoints for Claude, Codex, and OpenCode
|
|
40
|
+
- Editing generated files by hand
|
|
41
|
+
- Copying only the generated layers and skipping the canonical source
|
|
42
|
+
- Publishing without running build and validation
|
|
43
|
+
|
|
44
|
+
## Examples
|
|
45
|
+
|
|
46
|
+
- Good install flow: `examples/good/install-sequence.md`
|
|
47
|
+
- Bad install flow: `examples/bad/stale-projection.md`
|
|
48
|
+
|
|
49
|
+
## Checklist
|
|
50
|
+
|
|
51
|
+
- See `checklists/install-checklist.md`
|
|
52
|
+
|
|
53
|
+
## References
|
|
54
|
+
|
|
55
|
+
- `references/install-steps.md`
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Bad Install Sequence
|
|
2
|
+
|
|
3
|
+
1. Copy only `.agents/skills/` because it “already works in Codex.”
|
|
4
|
+
2. Skip `.claude/skills/` and `framework/agents/specs/`.
|
|
5
|
+
3. Edit generated agent files directly.
|
|
6
|
+
4. Publish without rebuilding.
|
|
7
|
+
|
|
8
|
+
Why this is bad:
|
|
9
|
+
|
|
10
|
+
- The canonical source is gone.
|
|
11
|
+
- The next update cannot be regenerated safely.
|
|
12
|
+
- Different tools will drift apart.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Install Steps
|
|
2
|
+
|
|
3
|
+
Copy these paths into the target repository:
|
|
4
|
+
|
|
5
|
+
- `docs/policy/`
|
|
6
|
+
- `.claude/`
|
|
7
|
+
- `.agents/`
|
|
8
|
+
- `.claude-plugin/marketplace.json`
|
|
9
|
+
- `.opencode/agents/`
|
|
10
|
+
- `.codex/agents/`
|
|
11
|
+
- `plugins/agent-quality-police/`
|
|
12
|
+
- `opencode.json`
|
|
13
|
+
- `scripts/`
|
|
14
|
+
- `tests/`
|
|
15
|
+
|
|
16
|
+
Canonical source paths that must be present before build:
|
|
17
|
+
|
|
18
|
+
- `framework/entrypoints/`
|
|
19
|
+
- `framework/agents/specs/`
|
|
20
|
+
- `framework/agents/prompts/`
|
|
21
|
+
- `framework/distribution/`
|
|
22
|
+
- `framework/package/`
|
|
23
|
+
|
|
24
|
+
Then run the build and validation commands from the repository root.
|
|
25
|
+
|
|
26
|
+
For package-style global installation after build, use the generated package entrypoint:
|
|
27
|
+
|
|
28
|
+
- `node plugins/agent-quality-police/bin/aqp.mjs install all`
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: quality-index
|
|
3
|
+
description: Navigate this governance framework. Use when the task spans multiple concerns, when you need to choose the right policy skill, or when you need to decide which audit agent must run.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Objective
|
|
7
|
+
|
|
8
|
+
Use this skill as the entry point to the framework. It maps task types to the right quality policy, examples, and police agents.
|
|
9
|
+
|
|
10
|
+
## When To Use
|
|
11
|
+
|
|
12
|
+
- The task touches more than one policy area.
|
|
13
|
+
- You are unsure which skill to load first.
|
|
14
|
+
- You need to decide which auditor or gatekeeper must run.
|
|
15
|
+
|
|
16
|
+
## When Not To Use
|
|
17
|
+
|
|
18
|
+
- The task is already clearly scoped to a single skill and the choice is obvious.
|
|
19
|
+
|
|
20
|
+
## Workflow
|
|
21
|
+
|
|
22
|
+
1. Read `docs/policy/quality-definition.md`.
|
|
23
|
+
2. Read `docs/policy/workflow.md`.
|
|
24
|
+
3. Classify the task.
|
|
25
|
+
4. Load only the skills required by that task.
|
|
26
|
+
5. Pair the work with the correct audit agent before final approval.
|
|
27
|
+
|
|
28
|
+
## Routing
|
|
29
|
+
|
|
30
|
+
- TypeScript modeling or type repair:
|
|
31
|
+
read `../typescript-zero-bypass/SKILL.md`
|
|
32
|
+
- Vite or Vitest TDD:
|
|
33
|
+
read `../vite-vitest-tdd/SKILL.md`
|
|
34
|
+
- React behavior tests:
|
|
35
|
+
read `../react-public-api-testing/SKILL.md`
|
|
36
|
+
- Suspicious diff review:
|
|
37
|
+
read `../anti-bypass-audit/SKILL.md`
|
|
38
|
+
- Refactor with legacy uncertainty:
|
|
39
|
+
read `../refactoring-with-safety/SKILL.md`
|
|
40
|
+
- Installing or updating this framework:
|
|
41
|
+
read `../governance-installation/SKILL.md`
|
|
42
|
+
|
|
43
|
+
## Quality Criteria
|
|
44
|
+
|
|
45
|
+
- The chosen skill set is the smallest set that covers the task.
|
|
46
|
+
- The chosen auditors match the actual risk surface.
|
|
47
|
+
- Canonical policy stays in `docs/policy/`, not in generated projections.
|
|
48
|
+
|
|
49
|
+
## Anti-Patterns
|
|
50
|
+
|
|
51
|
+
- Loading every skill by default.
|
|
52
|
+
- Starting implementation before deciding what behavior must be proven.
|
|
53
|
+
- Skipping the auditors because the change “looks small.”
|
|
54
|
+
|
|
55
|
+
## Examples
|
|
56
|
+
|
|
57
|
+
- Good routing: `examples/good/task-routing.md`
|
|
58
|
+
- Bad routing: `examples/bad/task-routing.md`
|
|
59
|
+
|
|
60
|
+
## Checklist
|
|
61
|
+
|
|
62
|
+
- See `checklists/routing-checklist.md`
|
|
63
|
+
|
|
64
|
+
## References
|
|
65
|
+
|
|
66
|
+
- `references/system-entrypoints.md`
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Bad Routing
|
|
2
|
+
|
|
3
|
+
Task: rename a private helper and add a feature.
|
|
4
|
+
|
|
5
|
+
Routing mistake:
|
|
6
|
+
|
|
7
|
+
1. load every skill in the repository
|
|
8
|
+
2. skip tests because the rename is “minor”
|
|
9
|
+
3. ship without `bypass-auditor`
|
|
10
|
+
|
|
11
|
+
Why this is bad:
|
|
12
|
+
|
|
13
|
+
- It hides the real feature risk under irrelevant context.
|
|
14
|
+
- It assumes rename and behavior change can share a shortcut.
|
|
15
|
+
- It skips the mandatory audit flow.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Good Routing
|
|
2
|
+
|
|
3
|
+
Task: fix a React bug in a Vite app where the disabled button label is wrong.
|
|
4
|
+
|
|
5
|
+
Routing:
|
|
6
|
+
|
|
7
|
+
1. `quality-index`
|
|
8
|
+
2. `typescript-zero-bypass`
|
|
9
|
+
3. `vite-vitest-tdd`
|
|
10
|
+
4. `react-public-api-testing`
|
|
11
|
+
5. Run `tdd-warden`
|
|
12
|
+
6. Run `bypass-auditor`
|
|
13
|
+
7. Run `pr-gatekeeper`
|
|
14
|
+
|
|
15
|
+
Why this is good:
|
|
16
|
+
|
|
17
|
+
- It covers typing, behavior testing, and audit.
|
|
18
|
+
- It avoids unrelated skills.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# System Entrypoints
|
|
2
|
+
|
|
3
|
+
- `AGENTS.md`: cross-tool root router
|
|
4
|
+
- `CLAUDE.md`: Claude-specific root router
|
|
5
|
+
- `docs/policy/quality-definition.md`: canonical definition of quality
|
|
6
|
+
- `docs/policy/workflow.md`: mandatory execution sequence
|
|
7
|
+
- `.claude/rules/`: always-on policy for Claude
|
|
8
|
+
- `.claude/skills/`: canonical skill source
|
|
9
|
+
- `framework/agents/specs/`: canonical agent source
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: react-public-api-testing
|
|
3
|
+
description: Behavior-focused React component testing through the public API. Use when testing components, hooks through components, or rendered output in a way that must survive refactoring.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Objective
|
|
7
|
+
|
|
8
|
+
Test React through what the user can perceive: roles, names, text, states, and callbacks exposed by the component contract.
|
|
9
|
+
|
|
10
|
+
## When To Use
|
|
11
|
+
|
|
12
|
+
- Component tests in React or Vite projects
|
|
13
|
+
- Review of suspicious Testing Library queries
|
|
14
|
+
- Replacing brittle DOM-detail assertions
|
|
15
|
+
|
|
16
|
+
## When Not To Use
|
|
17
|
+
|
|
18
|
+
- Pure domain functions without UI behavior
|
|
19
|
+
- Low-level rendering details that are not part of the contract
|
|
20
|
+
|
|
21
|
+
## Workflow
|
|
22
|
+
|
|
23
|
+
1. Identify the component’s public contract.
|
|
24
|
+
2. Render through the same props a caller would use.
|
|
25
|
+
3. Query by role, accessible name, label text, visible text, or user-visible state.
|
|
26
|
+
4. Assert the observable result.
|
|
27
|
+
5. Reject container selectors and implementation-specific details unless the contract truly exposes them.
|
|
28
|
+
|
|
29
|
+
## Quality Criteria
|
|
30
|
+
|
|
31
|
+
- Queries follow the Testing Library priority order.
|
|
32
|
+
- Assertions describe visible outcomes.
|
|
33
|
+
- The test would stay meaningful after a structural refactor that preserves the UI contract.
|
|
34
|
+
- Component examples should prefer inferred return types instead of explicit `JSX.Element`.
|
|
35
|
+
- Optional UI props should use `?` when absence is the intended caller experience.
|
|
36
|
+
|
|
37
|
+
## Anti-Patterns
|
|
38
|
+
|
|
39
|
+
- `container.querySelector` for elements that already have an accessible role
|
|
40
|
+
- asserting hook state directly
|
|
41
|
+
- asserting CSS class names when a semantic state is available
|
|
42
|
+
- clicking internal nodes instead of the public control
|
|
43
|
+
- declaring component types in the same file when the example should keep types and implementation separate
|
|
44
|
+
- explicit `JSX.Element` return annotations in React component examples
|
|
45
|
+
- duplicating nearly identical JSX through an early-return branch
|
|
46
|
+
- deriving render state through temporary setup variables when the component contract can express it directly
|
|
47
|
+
- forcing callers to pass `null` when an optional prop expresses absence more clearly
|
|
48
|
+
- unnecessary ternaries in TSX when an explicit branch is clearer
|
|
49
|
+
- building conditional prop-spread objects when direct rendering is simpler
|
|
50
|
+
|
|
51
|
+
## Examples
|
|
52
|
+
|
|
53
|
+
- Good component and test: `examples/good/primary-button.types.ts`, `examples/good/primary-button.tsx`, `examples/good/primary-button.test.tsx`
|
|
54
|
+
- Bad component example: `examples/bad/primary-button.component-antipattern.tsx`
|
|
55
|
+
- Bad conditional-setup example: `examples/bad/primary-button.conditional-setup-bloat.tsx`
|
|
56
|
+
- Bad duplicated-branch example: `examples/bad/primary-button.duplicated-branch.tsx`
|
|
57
|
+
- Bad implementation-detail test: `examples/bad/primary-button.internal.test.tsx`
|
|
58
|
+
|
|
59
|
+
## Checklist
|
|
60
|
+
|
|
61
|
+
- See `checklists/query-checklist.md`
|
|
62
|
+
|
|
63
|
+
## References
|
|
64
|
+
|
|
65
|
+
- `references/query-order.md`
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
interface PrimaryButtonProps {
|
|
2
|
+
label: string;
|
|
3
|
+
disabledReason?: string;
|
|
4
|
+
onPress(): void;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function PrimaryButton(props: PrimaryButtonProps): JSX.Element {
|
|
8
|
+
const isDisabled = props.disabledReason !== undefined;
|
|
9
|
+
const accessibilityProps = isDisabled
|
|
10
|
+
? { 'aria-describedby': 'primary-button-reason' }
|
|
11
|
+
: {};
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<div>
|
|
15
|
+
<button
|
|
16
|
+
disabled={isDisabled}
|
|
17
|
+
onClick={props.onPress}
|
|
18
|
+
{...accessibilityProps}
|
|
19
|
+
type="button"
|
|
20
|
+
>
|
|
21
|
+
{props.label}
|
|
22
|
+
</button>
|
|
23
|
+
{isDisabled ? (
|
|
24
|
+
<p id="primary-button-reason">{props.disabledReason}</p>
|
|
25
|
+
) : null}
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Reprovado porque:
|
|
31
|
+
// - mistura o tipo do componente com a função no mesmo arquivo
|
|
32
|
+
// - usa `JSX.Element` explicitamente em vez de deixar o retorno ser inferido
|
|
33
|
+
// - usa ternário para montar props condicionais
|
|
34
|
+
// - usa ternário no TSX onde um branch explícito é mais legível
|
|
35
|
+
// - usa prop spread para esconder uma diferença simples de renderização
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { PrimaryButtonProps } from '../good/primary-button.types';
|
|
2
|
+
|
|
3
|
+
export function PrimaryButton(props: PrimaryButtonProps) {
|
|
4
|
+
const isDisabled = props.disabledReason !== undefined;
|
|
5
|
+
let describedById: string | undefined;
|
|
6
|
+
|
|
7
|
+
if (isDisabled) {
|
|
8
|
+
describedById = 'primary-button-reason';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<div>
|
|
13
|
+
<button
|
|
14
|
+
aria-describedby={describedById}
|
|
15
|
+
disabled={isDisabled}
|
|
16
|
+
onClick={props.onPress}
|
|
17
|
+
type="button"
|
|
18
|
+
>
|
|
19
|
+
{props.label}
|
|
20
|
+
</button>
|
|
21
|
+
{isDisabled && (
|
|
22
|
+
<p id="primary-button-reason">{props.disabledReason}</p>
|
|
23
|
+
)}
|
|
24
|
+
</div>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Reprovado porque:
|
|
29
|
+
// - cria estado derivado e setup temporário desnecessários para uma renderização simples
|
|
30
|
+
// - espalha a lógica de acessibilidade e de renderização em variáveis intermediárias
|
|
31
|
+
// - mantém um `if` e um `&&` que deveriam ter virado funções explícitas para legibilidade
|
|
32
|
+
// - espalha a intenção entre variáveis intermediárias em vez de manter o contrato explícito
|
package/.agents/skills/react-public-api-testing/examples/bad/primary-button.duplicated-branch.tsx
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PrimaryButtonProps } from '../good/primary-button.types';
|
|
2
|
+
|
|
3
|
+
export function PrimaryButton(props: PrimaryButtonProps) {
|
|
4
|
+
if (props.disabledReason === undefined) {
|
|
5
|
+
return (
|
|
6
|
+
<button onClick={props.onPress} type="button">
|
|
7
|
+
{props.label}
|
|
8
|
+
</button>
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<div>
|
|
14
|
+
<button
|
|
15
|
+
aria-describedby="primary-button-reason"
|
|
16
|
+
disabled
|
|
17
|
+
onClick={props.onPress}
|
|
18
|
+
type="button"
|
|
19
|
+
>
|
|
20
|
+
{props.label}
|
|
21
|
+
</button>
|
|
22
|
+
<p id="primary-button-reason">{props.disabledReason}</p>
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Reprovado porque:
|
|
28
|
+
// - duplica quase todo o markup do botão em dois branches
|
|
29
|
+
// - espalha a regra de renderização em vez de manter uma estrutura única
|
|
30
|
+
// - torna a manutenção mais frágil sem ganhar legibilidade real
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { render } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
|
|
4
|
+
import { PrimaryButton } from '../good/primary-button';
|
|
5
|
+
|
|
6
|
+
describe('PrimaryButton', () => {
|
|
7
|
+
it('locks onto internal markup details', () => {
|
|
8
|
+
const { container } = render(
|
|
9
|
+
<PrimaryButton
|
|
10
|
+
disabledReason="Quota reached"
|
|
11
|
+
label="Save invoice"
|
|
12
|
+
onPress={() => {}}
|
|
13
|
+
/>,
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
expect(container.querySelector('p')?.textContent).toBe('Quota reached');
|
|
17
|
+
expect(container.querySelector('button')?.className).toBe('');
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Reprovado porque:
|
|
22
|
+
// - usa querySelector em vez de API acessível
|
|
23
|
+
// - acopla o teste ao markup interno e a classes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { fireEvent, render, screen } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
3
|
+
|
|
4
|
+
import { PrimaryButton } from './primary-button';
|
|
5
|
+
|
|
6
|
+
describe('PrimaryButton', () => {
|
|
7
|
+
it('renders an enabled public control and calls onPress', () => {
|
|
8
|
+
const onPress = vi.fn();
|
|
9
|
+
|
|
10
|
+
render(
|
|
11
|
+
<PrimaryButton
|
|
12
|
+
label="Save invoice"
|
|
13
|
+
onPress={onPress}
|
|
14
|
+
/>,
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
const button = screen.getByRole('button', { name: 'Save invoice' });
|
|
18
|
+
|
|
19
|
+
expect(button).toBeEnabled();
|
|
20
|
+
fireEvent.click(button);
|
|
21
|
+
expect(onPress).toHaveBeenCalledTimes(1);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('renders the disabled reason as visible public behavior', () => {
|
|
25
|
+
render(
|
|
26
|
+
<PrimaryButton
|
|
27
|
+
disabledReason="Quota reached"
|
|
28
|
+
label="Save invoice"
|
|
29
|
+
onPress={() => {}}
|
|
30
|
+
/>,
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
expect(screen.getByRole('button', { name: 'Save invoice' })).toBeDisabled();
|
|
34
|
+
expect(screen.getByText('Quota reached')).toBeVisible();
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { PrimaryButtonProps } from './primary-button.types';
|
|
2
|
+
|
|
3
|
+
export function PrimaryButton(props: PrimaryButtonProps) {
|
|
4
|
+
const isDisabled = props.disabledReason !== undefined;
|
|
5
|
+
|
|
6
|
+
function renderDisabledReasonParagraph() {
|
|
7
|
+
if (!isDisabled) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return <p id="primary-button-reason">{props.disabledReason}</p>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<div>
|
|
16
|
+
<button
|
|
17
|
+
aria-describedby="primary-button-reason"
|
|
18
|
+
disabled={isDisabled}
|
|
19
|
+
onClick={props.onPress}
|
|
20
|
+
type="button"
|
|
21
|
+
>
|
|
22
|
+
{props.label}
|
|
23
|
+
</button>
|
|
24
|
+
{renderDisabledReasonParagraph()}
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
}
|