@capagents/forgeqe 0.0.0-stage → 1.0.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/HOW_TO_USE.md +1639 -0
- package/README.md +338 -2
- package/bin/forgeqe.d.ts +3 -0
- package/bin/forgeqe.js +188 -0
- package/docs/ARCHITECTURE.md +408 -0
- package/docs/security-data-flow.html +1870 -0
- package/docs/user-guide.html +2094 -0
- package/evals/domain/access-role-change.yaml +37 -0
- package/evals/domain/banking-payment-transfer.yaml +41 -0
- package/evals/domain/gdpr-account-erasure.yaml +30 -0
- package/evals/domain/insurance-claim-fnol.yaml +30 -0
- package/evals/domain/insurance-policy-renewal.yaml +37 -0
- package/evals/domain/lending-loan-application.yaml +36 -0
- package/forgeqe-architecture.html +718 -0
- package/forgeqe.example.yaml +203 -0
- package/knowledge/README.md +18 -0
- package/knowledge/business-rules.md +10 -0
- package/knowledge/compliance.md +16 -0
- package/knowledge/environments.md +5 -0
- package/knowledge/glossary.md +5 -0
- package/knowledge/product.md +16 -0
- package/knowledge/roles.md +9 -0
- package/knowledge/test-data.md +7 -0
- package/llms.example.json +51 -0
- package/package.json +63 -4
- package/prompts/README.md +34 -0
- package/prompts/api-scenarios.md +21 -0
- package/prompts/api-tests.md +39 -0
- package/prompts/brain.md +166 -0
- package/prompts/browser-capture.md +7 -0
- package/prompts/browser-case-report.md +7 -0
- package/prompts/browser-checks.md +14 -0
- package/prompts/browser-efficiency.md +7 -0
- package/prompts/browser-error-recovery.md +15 -0
- package/prompts/browser-extra.md +5 -0
- package/prompts/browser-goal-verification.md +13 -0
- package/prompts/browser-skill-select.md +6 -0
- package/prompts/domain-rule.md +13 -0
- package/prompts/eval-judge.md +19 -0
- package/prompts/explore-charters.md +27 -0
- package/prompts/find-tests.md +28 -0
- package/prompts/heal.md +40 -0
- package/prompts/pr-review.md +29 -0
- package/prompts/skill-rule.md +6 -0
- package/prompts/test-agent.md +34 -0
- package/prompts/test-reviewer.md +30 -0
- package/prompts/test-rules.md +28 -0
- package/py/forgeqe_engine/__init__.py +3 -0
- package/py/forgeqe_engine/__main__.py +3 -0
- package/py/forgeqe_engine/brand.py +453 -0
- package/py/forgeqe_engine/brand_assets.py +6 -0
- package/py/forgeqe_engine/browser.py +196 -0
- package/py/forgeqe_engine/capture.py +538 -0
- package/py/forgeqe_engine/checks.py +98 -0
- package/py/forgeqe_engine/cli.py +188 -0
- package/py/forgeqe_engine/diagnostics.py +609 -0
- package/py/forgeqe_engine/llm.py +195 -0
- package/py/forgeqe_engine/logins.py +251 -0
- package/py/forgeqe_engine/loops.py +224 -0
- package/py/forgeqe_engine/memory.py +1004 -0
- package/py/forgeqe_engine/network.py +244 -0
- package/py/forgeqe_engine/prompts.py +20 -0
- package/py/forgeqe_engine/replay.py +240 -0
- package/py/forgeqe_engine/report.py +173 -0
- package/py/forgeqe_engine/service.py +1335 -0
- package/py/forgeqe_engine/settings.py +93 -0
- package/py/forgeqe_engine/skills.py +88 -0
- package/py/forgeqe_engine/summary.py +239 -0
- package/py/forgeqe_engine/urls.py +81 -0
- package/py/forgeqe_engine/workflow_yaml.py +689 -0
- package/skills/dotnet-nunit-playwright/SKILL.md +34 -0
- package/skills/dynamics-365/SKILL.md +21 -0
- package/skills/playwright-typescript/SKILL.md +35 -0
- package/skills/writing-skills/SKILL.md +30 -0
- package/src/api/plan.ts +246 -0
- package/src/api/run.ts +204 -0
- package/src/api/scenario.ts +502 -0
- package/src/api/schema.ts +170 -0
- package/src/api/spec.ts +624 -0
- package/src/api/store.ts +232 -0
- package/src/api/traffic.ts +281 -0
- package/src/api/types.ts +163 -0
- package/src/api/write.ts +272 -0
- package/src/auth/signin.ts +494 -0
- package/src/auth/store.ts +170 -0
- package/src/brain/index.ts +189 -0
- package/src/brain/prompt.ts +19 -0
- package/src/capabilities/docs.ts +101 -0
- package/src/capabilities/guide.ts +455 -0
- package/src/capabilities/registry.ts +343 -0
- package/src/capabilities/render.ts +106 -0
- package/src/capabilities/status.ts +137 -0
- package/src/card.ts +11 -0
- package/src/cases/ado.ts +325 -0
- package/src/cases/api.ts +117 -0
- package/src/cases/bugs.ts +223 -0
- package/src/cases/confluence.ts +111 -0
- package/src/cases/context.ts +223 -0
- package/src/cases/dashboards.ts +137 -0
- package/src/cases/failure.ts +97 -0
- package/src/cases/files.ts +295 -0
- package/src/cases/goal.ts +53 -0
- package/src/cases/http.ts +111 -0
- package/src/cases/index.ts +131 -0
- package/src/cases/jira.ts +122 -0
- package/src/cases/qtest.ts +108 -0
- package/src/cases/quality.ts +190 -0
- package/src/cases/rag.ts +100 -0
- package/src/cases/readiness.ts +284 -0
- package/src/cases/save.ts +149 -0
- package/src/cases/sprints.ts +148 -0
- package/src/cases/testrail.ts +176 -0
- package/src/cases/types.ts +107 -0
- package/src/cases/wiki.ts +105 -0
- package/src/cases/xray.ts +206 -0
- package/src/cases/zephyr.ts +153 -0
- package/src/childEnv.ts +86 -0
- package/src/cli/args.ts +114 -0
- package/src/cli/help.ts +167 -0
- package/src/cli/index.ts +1142 -0
- package/src/cli/terminal.ts +187 -0
- package/src/code/areas.ts +337 -0
- package/src/code/attention.ts +214 -0
- package/src/code/find.ts +540 -0
- package/src/code/handoff.ts +541 -0
- package/src/code/history.ts +170 -0
- package/src/code/impact.ts +231 -0
- package/src/code/index.ts +34 -0
- package/src/code/livebrowser.ts +67 -0
- package/src/code/loop.ts +603 -0
- package/src/code/notes.ts +75 -0
- package/src/code/profile.ts +226 -0
- package/src/code/prompt.ts +303 -0
- package/src/code/prreview.ts +649 -0
- package/src/code/prtests.ts +103 -0
- package/src/code/replay.ts +772 -0
- package/src/code/review.ts +202 -0
- package/src/code/runtime.ts +757 -0
- package/src/code/slices.ts +159 -0
- package/src/code/testrun.ts +187 -0
- package/src/code/traceability.ts +100 -0
- package/src/code/worktree.ts +153 -0
- package/src/commands.ts +101 -0
- package/src/config.ts +970 -0
- package/src/detail.ts +65 -0
- package/src/domain.ts +19 -0
- package/src/engine/bridge.ts +359 -0
- package/src/engine/mock.ts +102 -0
- package/src/engine/setup.ts +298 -0
- package/src/entra.ts +154 -0
- package/src/env.ts +24 -0
- package/src/evals/domain.ts +338 -0
- package/src/explore/charters.ts +151 -0
- package/src/explore/run.ts +280 -0
- package/src/explore/story.ts +106 -0
- package/src/guard.ts +51 -0
- package/src/heal/loop.ts +357 -0
- package/src/heal/prompt.ts +143 -0
- package/src/heal/report.ts +95 -0
- package/src/index.ts +12 -0
- package/src/init.ts +102 -0
- package/src/knowledge.ts +114 -0
- package/src/legacyEnv.ts +9 -0
- package/src/llm.ts +61 -0
- package/src/locale.ts +25 -0
- package/src/logins.ts +148 -0
- package/src/managed.ts +101 -0
- package/src/mcp/apitools.ts +335 -0
- package/src/mcp/captools.ts +25 -0
- package/src/mcp/casetools.ts +223 -0
- package/src/mcp/commands.ts +421 -0
- package/src/mcp/exploretools.ts +129 -0
- package/src/mcp/external.ts +172 -0
- package/src/mcp/git.ts +78 -0
- package/src/mcp/notifytools.ts +49 -0
- package/src/mcp/prtools.ts +261 -0
- package/src/mcp/qualitytools.ts +154 -0
- package/src/mcp/repotests.ts +286 -0
- package/src/mcp/server.ts +234 -0
- package/src/mcp/tools.ts +810 -0
- package/src/memory.ts +250 -0
- package/src/money.ts +39 -0
- package/src/monitor/alerts.ts +94 -0
- package/src/monitor/background.ts +68 -0
- package/src/monitor/run.ts +263 -0
- package/src/monitor/state.ts +105 -0
- package/src/notify/events.ts +144 -0
- package/src/notify/notice.ts +177 -0
- package/src/prices.ts +175 -0
- package/src/print.ts +54 -0
- package/src/privacy.ts +35 -0
- package/src/prompts.ts +165 -0
- package/src/quality/budgets.ts +249 -0
- package/src/quality/history.ts +149 -0
- package/src/quality/visual.ts +201 -0
- package/src/report/data.ts +475 -0
- package/src/report/html.ts +106 -0
- package/src/report/template.html +84 -0
- package/src/run.ts +243 -0
- package/src/sessionLog.ts +216 -0
- package/src/sessionLogins.ts +94 -0
- package/src/skills/registry.ts +217 -0
- package/src/skills/scaffold.ts +65 -0
- package/src/skills/select.ts +37 -0
- package/src/skills/view.ts +44 -0
- package/src/suite/report.ts +135 -0
- package/src/suite/run.ts +303 -0
- package/src/summary.ts +188 -0
- package/src/tools.ts +130 -0
- package/src/tui/App.tsx +983 -0
- package/src/tui/clipboard.ts +36 -0
- package/src/tui/components.tsx +263 -0
- package/src/tui/dialogs.ts +65 -0
- package/src/tui/main.tsx +20 -0
- package/src/tui/text.ts +28 -0
- package/src/tui/theme.ts +104 -0
- package/src/tui/transcript.tsx +344 -0
- package/src/types.ts +136 -0
- package/src/update.ts +311 -0
- package/src/usage.ts +158 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
llm:
|
|
2
|
+
models_file: ./llms.json
|
|
3
|
+
# active: azure-gpt4o # profile to use; default: "default" in llms.json (Tab switches in the shell)
|
|
4
|
+
|
|
5
|
+
browser:
|
|
6
|
+
headless: true
|
|
7
|
+
max_steps: 40 # a checkpoint: a run still making progress carries on, up to 3x
|
|
8
|
+
timeout_seconds: 600 # whole run
|
|
9
|
+
vision_detail: low # low | high
|
|
10
|
+
viewport:
|
|
11
|
+
width: 1280
|
|
12
|
+
height: 800
|
|
13
|
+
allowed_hosts: []
|
|
14
|
+
judge: false # true: a second model call checks each finished run against the goal and can fail it
|
|
15
|
+
overlay: true # visible browser: ForgeQE start page, edge glow, a bar with the current step, your mouse and keyboard locked while the agent works
|
|
16
|
+
# start_url: https://staging.example.com # optional; omit to let the agent choose the site
|
|
17
|
+
|
|
18
|
+
# Every agent prompt is a file in .forgeqe/prompts/ (forgeqe init copies them; edit one to change it, forgeqe prompts
|
|
19
|
+
# lists them). These two short ones are added to the browser agent's prompt too.
|
|
20
|
+
prompts:
|
|
21
|
+
step_instruction: ""
|
|
22
|
+
guiderails: ""
|
|
23
|
+
# dir: ../shared-prompts # a folder of prompts that wins over .forgeqe/prompts (shared between projects)
|
|
24
|
+
|
|
25
|
+
# Product knowledge (.forgeqe/knowledge): what the agents should know about the product.
|
|
26
|
+
# knowledge:
|
|
27
|
+
# dir: .forgeqe/knowledge
|
|
28
|
+
# browser_max_chars: 1500 # most knowledge added to each browser run (only sections that match the goal); 0: none
|
|
29
|
+
|
|
30
|
+
# The product's industry and the regulations in scope. Agents then design and judge tests as an expert in that
|
|
31
|
+
# industry would, and add each regulation's obligations a feature touches. Your applicable controls, with their ids,
|
|
32
|
+
# go in .forgeqe/knowledge/compliance.md; agents cite only ids listed there.
|
|
33
|
+
# Teams and email notifications for the team: each channel picks its events (suite_failed, suite_passed, release,
|
|
34
|
+
# eval_failed). The Teams webhook URL is a secret: keep it in the environment, never here. See HOW_TO_USE.md section 17.
|
|
35
|
+
# notify:
|
|
36
|
+
# report_url: https://reports.example.com/forgeqe # where .forgeqe/reports is published; cards link each report
|
|
37
|
+
# channels:
|
|
38
|
+
# qa:
|
|
39
|
+
# teams: { webhook_env: TEAMS_WEBHOOK_URL } # a Teams Workflows "post to a channel when a webhook request is received"
|
|
40
|
+
# on: [suite_failed, eval_failed]
|
|
41
|
+
# release:
|
|
42
|
+
# teams: { webhook_env: TEAMS_RELEASE_WEBHOOK }
|
|
43
|
+
# on: [release]
|
|
44
|
+
|
|
45
|
+
# domain:
|
|
46
|
+
# industry: retail banking
|
|
47
|
+
# regulations: [DORA, PSD2, GDPR, ISO 27001]
|
|
48
|
+
# notes: Payments to UK and EU accounts; customers are consumers and small businesses.
|
|
49
|
+
|
|
50
|
+
export:
|
|
51
|
+
out_dir: ./.forgeqe/reports # one folder per run, named by its run id: report, steps, screenshots, trace
|
|
52
|
+
format: playwright
|
|
53
|
+
|
|
54
|
+
memory:
|
|
55
|
+
enabled: true
|
|
56
|
+
dir: ./.forgeqe/memory # pages, elements, locators, and recorded flows
|
|
57
|
+
replay: verify # verify | trust | off
|
|
58
|
+
|
|
59
|
+
code:
|
|
60
|
+
# repo: ../my-app # where passed runs become tests (default: the current folder; --no-code turns it off)
|
|
61
|
+
# test_command: npx playwright test # the repo's test command, for forgeqe heal; default: the agent finds it
|
|
62
|
+
max_attempts: 3 # test runs before giving up (also healing attempts); each attempt after the first starts a fresh session from a summary
|
|
63
|
+
# max_tokens: 1500000 # stop a coding job past this many tokens (cached included) and report how far it got
|
|
64
|
+
# review_profile: azure-mini # llms.json profile for the reviewer, which only reads and judges: a cheaper model is enough
|
|
65
|
+
test_timeout_seconds: 600 # per test run
|
|
66
|
+
stall_after: 5 # stop the coding agent when one command it runs has failed this many times
|
|
67
|
+
replay: true # before the coding agent starts, run the steps as a Playwright script and hand over what worked and where it failed
|
|
68
|
+
live_browser: true # once a step fails, the coding agent looks at that page in a Playwright browser instead of building tests to look
|
|
69
|
+
# model: anthropic/claude-sonnet-4-5 # model for ForgeQE's agent and Scribe; default: the active llms.json profile
|
|
70
|
+
# runtime: /path/to/agent-runtime # default: the runtime ForgeQE downloads
|
|
71
|
+
|
|
72
|
+
# Skills: folders with a SKILL.md that teach the agents your repo's test conventions, a framework, or an app.
|
|
73
|
+
# ForgeQE ships some; yours go in .forgeqe/skills next to this file (commit them) or ~/.forgeqe/skills.
|
|
74
|
+
# A skill replaces a built-in one with the same name. forgeqe skills lists them; forgeqe skills new <name> starts one.
|
|
75
|
+
# skills:
|
|
76
|
+
# enabled: true
|
|
77
|
+
# dirs: [../shared-skills] # more folders, read last (they win over the others)
|
|
78
|
+
# disable: [dynamics-365] # skills to leave out; forgeqe skills enable|disable <name> edits this
|
|
79
|
+
# external: false # true: also ~/.claude/skills, ~/.agents/skills, and the repo's .claude/.agents skills
|
|
80
|
+
# browser_max_chars: 6000 # most skill text added to one browser run's prompt
|
|
81
|
+
|
|
82
|
+
# Sites the browser agent signs in to. Values stay in the environment; the model only sees placeholders.
|
|
83
|
+
# Sessions (cookies + local storage) are kept in .forgeqe/sessions/<name>.json so the next run starts signed in;
|
|
84
|
+
# keep that folder out of git. forgeqe login <name> saves a session you sign in to by hand (SSO, captcha).
|
|
85
|
+
# logins:
|
|
86
|
+
# shop:
|
|
87
|
+
# url: https://staging.shop.example/login # or domains: [https://staging.shop.example, https://*.shop.example]
|
|
88
|
+
# username_env: SHOP_USER
|
|
89
|
+
# password_env: SHOP_PASSWORD
|
|
90
|
+
# totp_env: SHOP_TOTP_SECRET # optional: authenticator secret (base32) for 2FA codes
|
|
91
|
+
# # save_session: false # sign in every run instead
|
|
92
|
+
|
|
93
|
+
report:
|
|
94
|
+
screenshots: all # all | failures | off: step screenshots in report.html
|
|
95
|
+
accessibility: true # check each page the agent visits (names, labels, image text, contrast, lang, zoom)
|
|
96
|
+
|
|
97
|
+
# Test case systems, for ForgeQE's agent and forgeqe suite / cases. Keys stay in the environment.
|
|
98
|
+
# ForgeQE's agent also gets each system's MCP server, set up from these same settings (forgeqe mcp list).
|
|
99
|
+
sources:
|
|
100
|
+
write_back: true # post results back to the system each case came from
|
|
101
|
+
# azure_devops:
|
|
102
|
+
# org_url: https://dev.azure.com/acme # or ADO_ORG_URL. The MCP server is this organization, every project.
|
|
103
|
+
# # project: Shop # optional: limit ForgeQE's own test, sprint, and bug calls to one project. Or ADO_PROJECT. * or all means every project.
|
|
104
|
+
# token_env: ADO_PAT # PAT with Test Management + Work Items (read & write)
|
|
105
|
+
# mcp: true # Microsoft's Azure DevOps MCP server (needs npx); false: API only
|
|
106
|
+
# # mcp_domains: [core, work, work-items, test-plans, pipelines, repositories, wiki, search, advanced-security] # default: all
|
|
107
|
+
# jira:
|
|
108
|
+
# url: https://acme.atlassian.net # or JIRA_URL; Server/Data Center URLs work too
|
|
109
|
+
# email_env: JIRA_EMAIL # Cloud only
|
|
110
|
+
# token_env: JIRA_API_TOKEN # Cloud API token, or a Server/DC personal access token
|
|
111
|
+
# mcp: mcp-atlassian # mcp-atlassian (uvx; Cloud and Server/DC) | rovo (Atlassian's hosted server, Cloud) | false
|
|
112
|
+
# xray: # no MCP server: ForgeQE's API tools cover Xray
|
|
113
|
+
# url: https://xray.cloud.getxray.app # Xray Cloud; Server/DC uses the jira: settings above
|
|
114
|
+
# client_id_env: XRAY_CLIENT_ID
|
|
115
|
+
# client_secret_env: XRAY_CLIENT_SECRET
|
|
116
|
+
# confluence: true # requirements pages on the Jira Cloud site above, same account
|
|
117
|
+
# confluence: # or a separate site
|
|
118
|
+
# url: https://confluence.acme.com # or CONFLUENCE_URL; Cloud: https://acme.atlassian.net/wiki
|
|
119
|
+
# email_env: CONFLUENCE_EMAIL # Cloud only
|
|
120
|
+
# token_env: CONFLUENCE_TOKEN # Cloud API token, or a Server/DC personal access token
|
|
121
|
+
# space: QA # optional: search this space only
|
|
122
|
+
# testrail:
|
|
123
|
+
# url: https://acme.testrail.io # or TESTRAIL_URL
|
|
124
|
+
# email_env: TESTRAIL_EMAIL
|
|
125
|
+
# token_env: TESTRAIL_API_KEY
|
|
126
|
+
# project_id: 1 # for testrail:suite=<id>
|
|
127
|
+
# zephyr: # Zephyr Scale Cloud; on when ZEPHYR_API_TOKEN is set
|
|
128
|
+
# token_env: ZEPHYR_API_TOKEN
|
|
129
|
+
# project_key: SHOP # for zephyr:folder=<id>
|
|
130
|
+
# qtest:
|
|
131
|
+
# url: https://acme.qtestnet.com # or QTEST_URL
|
|
132
|
+
# token_env: QTEST_TOKEN # API bearer token
|
|
133
|
+
# project_id: 12345
|
|
134
|
+
# statuses: { passed: PASS, failed: FAIL, error: BLOCKED } # automation status names in your qTest
|
|
135
|
+
# bugs: # a bug per failed case; still failing: a comment on the open bug
|
|
136
|
+
# system: jira # jira | azure_devops
|
|
137
|
+
# project: SHOP # Jira project key (Azure DevOps uses azure_devops.project)
|
|
138
|
+
# type: Bug # issue / work item type
|
|
139
|
+
# labels: [forgeqe] # Jira labels or Azure DevOps tags
|
|
140
|
+
# # area_path: Shop\\Web # Azure DevOps
|
|
141
|
+
# # on_error: false # also for cases that could not run
|
|
142
|
+
|
|
143
|
+
# More MCP servers for ForgeQE's agent. Use {env:NAME} for secrets; never put values here.
|
|
144
|
+
# mcp:
|
|
145
|
+
# github:
|
|
146
|
+
# url: https://api.githubcopilot.com/mcp/
|
|
147
|
+
# headers: { Authorization: "Bearer {env:GITHUB_TOKEN}" }
|
|
148
|
+
# xray:
|
|
149
|
+
# command: npx -y @triparc/xray-mcp
|
|
150
|
+
# env: { XRAY_CLIENT_ID: "{env:XRAY_CLIENT_ID}", XRAY_CLIENT_SECRET: "{env:XRAY_CLIENT_SECRET}" }
|
|
151
|
+
|
|
152
|
+
suite:
|
|
153
|
+
parallel: 1 # browsers at once; coding jobs always run one at a time
|
|
154
|
+
code: true # with a repo set, passed cases get a test from Scribe
|
|
155
|
+
# out_dir: ./.forgeqe/reports/suites
|
|
156
|
+
|
|
157
|
+
# Accessibility (axe-core, WCAG) and performance (Core Web Vitals) of every page a run visits. Without budgets they
|
|
158
|
+
# are reported and tracked over time; a run fails on them only when a budget below is exceeded.
|
|
159
|
+
# quality:
|
|
160
|
+
# accessibility:
|
|
161
|
+
# standard: wcag21aa # wcag2a, wcag21aa, wcag22aa, wcag21aaa, section508, en301549, best-practice
|
|
162
|
+
# visual: # each page compared with its approved screenshot (.forgeqe/visual-baselines)
|
|
163
|
+
# mask: [".clock", "#ad-slot"] # hidden before capture
|
|
164
|
+
# full_page: false
|
|
165
|
+
# budgets:
|
|
166
|
+
# accessibility: { critical: 0, serious: 0, ignore: [region] }
|
|
167
|
+
# performance: web-vitals # or { lcp_ms: 3000, cls: 0.1, inp_ms: 200, pages: { /search: { lcp_ms: 4000 } } }
|
|
168
|
+
# visual: 0.5 # most a page may change, in percent of its pixels
|
|
169
|
+
|
|
170
|
+
# API and contract tests (REST, GraphQL, SOAP, gRPC). Every browser run records the app's API calls (secrets
|
|
171
|
+
# redacted) in network.json; forgeqe api contracts / run / tests turn them, or an OpenAPI, WSDL, GraphQL, or .proto
|
|
172
|
+
# description, into contracts and tests. Header values are ${NAME} references to environment variables.
|
|
173
|
+
# api:
|
|
174
|
+
# capture: true # record the app's API calls in browser runs
|
|
175
|
+
# base_url: https://staging.shop.example
|
|
176
|
+
# headers:
|
|
177
|
+
# Authorization: Bearer ${API_TOKEN}
|
|
178
|
+
# third_party: false # keep calls to other sites than the page's
|
|
179
|
+
# timeout_seconds: 30
|
|
180
|
+
|
|
181
|
+
# forgeqe monitor: run checks on a schedule and alert when one starts failing, keeps failing, or recovers.
|
|
182
|
+
# Secrets stay in the environment; only their names go here.
|
|
183
|
+
# monitor:
|
|
184
|
+
# checks: [checks/smoke.yaml] # any case sources: files, folders, jira:..., ado:..., testrail:...
|
|
185
|
+
# every: 15m # 30s, 15m, 1h, 1h30m; at least 10s
|
|
186
|
+
# replay: verify # verify: one model call per check confirms the result; trust: none
|
|
187
|
+
# parallel: 1
|
|
188
|
+
# fail_after: 1 # failing rounds in a row before the first alert (2+ rides out flaky runs)
|
|
189
|
+
# remind_every: 2h # repeat the alert while it keeps failing; default: never
|
|
190
|
+
# keep: 100 # round folders kept; older ones are deleted
|
|
191
|
+
# write_back: false # post each round's results to the source system
|
|
192
|
+
# # out_dir: ./.forgeqe/reports/monitor # rounds and state.json (which checks are failing, and since when)
|
|
193
|
+
# # report_url: https://reports.example.com/monitor # where out_dir is published; alerts link <url>/<round>/report.html
|
|
194
|
+
# alerts:
|
|
195
|
+
# teams: # a Teams incoming webhook or Workflows "post to a channel when a webhook request is received"
|
|
196
|
+
# webhook_env: TEAMS_WEBHOOK_URL
|
|
197
|
+
# email:
|
|
198
|
+
# host: smtp.office365.com # or SMTP_HOST
|
|
199
|
+
# port: 587 # STARTTLS; 465 is TLS from the start
|
|
200
|
+
# username_env: SMTP_USERNAME
|
|
201
|
+
# password_env: SMTP_PASSWORD
|
|
202
|
+
# # from: ForgeQE <qa-bot@example.com> # default: the username
|
|
203
|
+
# to: [qa-team@example.com]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Product knowledge
|
|
2
|
+
|
|
3
|
+
What ForgeQE's agents should know about your product, written once and used on every run: what it does, who uses it,
|
|
4
|
+
the words your team uses, the rules it follows, the data to test with, and where it runs. Fill in the files below (or add
|
|
5
|
+
your own `.md` or `.txt` files, in folders if you like) and commit them.
|
|
6
|
+
|
|
7
|
+
How the agents use it:
|
|
8
|
+
|
|
9
|
+
- **ForgeQE's agent** sees the list of these files and reads the ones a request needs (planning tests, judging a test
|
|
10
|
+
case, answering about the product).
|
|
11
|
+
- **Planning agents** (exploratory charters, API scenarios) get the sections that match the story or scenario.
|
|
12
|
+
- **The browser agent** gets the few sections that match the goal (at most `knowledge.browser_max_chars`, default 1500
|
|
13
|
+
characters, so runs stay cheap).
|
|
14
|
+
|
|
15
|
+
Sections are found by their headings, so give each topic its own `##` heading. A file you have not changed since
|
|
16
|
+
`forgeqe init` copied it is left out: the templates' examples never reach an agent.
|
|
17
|
+
|
|
18
|
+
Never put passwords, tokens, or personal data here: use logins and environment variables for those.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Business rules
|
|
2
|
+
|
|
3
|
+
<!-- The rules the product enforces: limits, validations, calculations. Agents use them as expected results. -->
|
|
4
|
+
|
|
5
|
+
## Checkout
|
|
6
|
+
- Delivery is free from 50.00; below that it costs 4.95.
|
|
7
|
+
- A coupon cannot be combined with a gift card.
|
|
8
|
+
|
|
9
|
+
## Addresses
|
|
10
|
+
- Postcode is required and must be a valid UK postcode.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Compliance
|
|
2
|
+
|
|
3
|
+
<!-- The obligations your organisation has decided apply to this product, with the ids your auditors use.
|
|
4
|
+
The regulations themselves are named in domain.regulations in forgeqe.yaml; this file says which of their
|
|
5
|
+
requirements apply here and how you identify them. Agents cite an id only when it is listed here, so tests and
|
|
6
|
+
findings trace to your own control register instead of article numbers recalled from memory. -->
|
|
7
|
+
|
|
8
|
+
## Controls in scope
|
|
9
|
+
<!-- One line each: the id, the regulation or standard, and what the product must do, in words a tester can check. -->
|
|
10
|
+
- Example: CTL-AUD-01 (ISO 27001, DORA): every change to a payment beneficiary is written to the audit log with who, when, and the old and new values.
|
|
11
|
+
- Example: CTL-ACC-04 (ISO 27001): a user cannot approve a payment they created (segregation of duties).
|
|
12
|
+
- Example: CTL-PRV-02 (GDPR): a customer's erasure request removes their personal data from the profile and exports within 30 days.
|
|
13
|
+
|
|
14
|
+
## Not in scope
|
|
15
|
+
<!-- Requirements the team has decided do not apply to this product, and why, so agents do not test for them. -->
|
|
16
|
+
- Example: PCI DSS card storage: the product never stores card numbers; payments go through the provider's hosted page.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# The product
|
|
2
|
+
|
|
3
|
+
## What it is
|
|
4
|
+
<!-- One paragraph: what the application does and for whom. -->
|
|
5
|
+
Example: Shop is the online store of Acme. Customers browse products, pay by card or gift card, and track their orders.
|
|
6
|
+
|
|
7
|
+
## Main areas
|
|
8
|
+
<!-- The parts of the application, with where they start. -->
|
|
9
|
+
- Catalogue: /products, search and filters
|
|
10
|
+
- Basket and checkout: /cart, /checkout
|
|
11
|
+
- My account: /account (orders, addresses, payment methods)
|
|
12
|
+
|
|
13
|
+
## Main flows
|
|
14
|
+
<!-- The journeys that matter most, in a line each. -->
|
|
15
|
+
- Search, add to basket, check out as a signed-in customer
|
|
16
|
+
- Return an item from an order
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Roles
|
|
2
|
+
|
|
3
|
+
<!-- Who uses the product and what each may and may not do. Name the saved login (logins: in forgeqe.yaml) for each. -->
|
|
4
|
+
|
|
5
|
+
## Customer
|
|
6
|
+
Login: shop_customer. Can buy, see their own orders, and change their addresses. Cannot see other customers' orders.
|
|
7
|
+
|
|
8
|
+
## Store admin
|
|
9
|
+
Login: shop_admin. Can edit products and prices, refund orders, and see every order.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Test data
|
|
2
|
+
|
|
3
|
+
<!-- Data that exists in the test environments and is safe to use: products, customers, coupons, cards. No secrets. -->
|
|
4
|
+
- Product with stock: "Blue Teapot" (SKU TP-001)
|
|
5
|
+
- Product out of stock: "Red Kettle" (SKU KT-404)
|
|
6
|
+
- Coupon: SAVE10 (10% off, valid until the end of the year)
|
|
7
|
+
- Test card: 4111 1111 1111 1111, any future date, CVC 123
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"default": "openai-gpt4o",
|
|
3
|
+
"models": {
|
|
4
|
+
"azure-gpt4o": {
|
|
5
|
+
"provider": "azure",
|
|
6
|
+
"model": "gpt-4o",
|
|
7
|
+
"deployment": "gpt-4o",
|
|
8
|
+
"endpoint": "https://YOUR_RESOURCE.openai.azure.com/",
|
|
9
|
+
"api_key_env": "WP_AZURE_API_KEY",
|
|
10
|
+
"api_version": "2024-05-01-preview",
|
|
11
|
+
"temperature": 0.2,
|
|
12
|
+
"deployment_type": "global",
|
|
13
|
+
"description": "Azure OpenAI GPT-4o (vision)"
|
|
14
|
+
},
|
|
15
|
+
"azure-gpt4o-entra": {
|
|
16
|
+
"provider": "azure",
|
|
17
|
+
"model": "gpt-4o",
|
|
18
|
+
"deployment": "gpt-4o",
|
|
19
|
+
"endpoint": "https://YOUR_RESOURCE.openai.azure.com/",
|
|
20
|
+
"auth": "entra",
|
|
21
|
+
"managed_identity_client_id": "",
|
|
22
|
+
"api_version": "2024-05-01-preview",
|
|
23
|
+
"temperature": 0.2,
|
|
24
|
+
"deployment_type": "global",
|
|
25
|
+
"description": "Azure OpenAI GPT-4o with Microsoft Entra ID (managed identity, workload identity or az login); no key"
|
|
26
|
+
},
|
|
27
|
+
"openai-gpt4o": {
|
|
28
|
+
"provider": "openai",
|
|
29
|
+
"model": "gpt-4o",
|
|
30
|
+
"api_key_env": "OPENAI_API_KEY",
|
|
31
|
+
"temperature": 0.2,
|
|
32
|
+
"description": "OpenAI GPT-4o (vision)"
|
|
33
|
+
},
|
|
34
|
+
"ollama-llama": {
|
|
35
|
+
"provider": "ollama",
|
|
36
|
+
"model": "llama3.2",
|
|
37
|
+
"endpoint": "http://127.0.0.1:11434/v1",
|
|
38
|
+
"api_key_env": "WP_API_KEY",
|
|
39
|
+
"temperature": 0.2,
|
|
40
|
+
"description": "Local Ollama"
|
|
41
|
+
},
|
|
42
|
+
"compatible": {
|
|
43
|
+
"provider": "openai_compatible",
|
|
44
|
+
"model": "gpt-4o",
|
|
45
|
+
"endpoint": "https://your-gateway.example/v1",
|
|
46
|
+
"api_key_env": "WP_API_KEY",
|
|
47
|
+
"temperature": 0.2,
|
|
48
|
+
"description": "Any OpenAI-compatible chat endpoint"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,65 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capagents/forgeqe",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "ForgeQE: a browser agent CLI that runs goals and test cases in Chrome and turns passing runs into tests in your repo",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"forgeqe": "bin/forgeqe.js",
|
|
9
|
+
"webpilot": "bin/forgeqe.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin/",
|
|
13
|
+
"src/",
|
|
14
|
+
"py/forgeqe_engine/*.py",
|
|
15
|
+
"skills/",
|
|
16
|
+
"prompts/",
|
|
17
|
+
"knowledge/",
|
|
18
|
+
"evals/",
|
|
19
|
+
"docs/",
|
|
20
|
+
"README.md",
|
|
21
|
+
"HOW_TO_USE.md",
|
|
22
|
+
"forgeqe-architecture.html",
|
|
23
|
+
"forgeqe.example.yaml",
|
|
24
|
+
"llms.example.json"
|
|
25
|
+
],
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=18",
|
|
28
|
+
"bun": ">=1.3.0"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"forgeqe": "bun src/index.ts",
|
|
32
|
+
"start": "bun src/index.ts start",
|
|
33
|
+
"test": "bun test",
|
|
34
|
+
"typecheck": "tsc --noEmit",
|
|
35
|
+
"build:report": "cd report-ui && npm install --no-audit --no-fund && npm run build && cp dist/index.html ../src/report/template.html"
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"forgeqe",
|
|
39
|
+
"browser",
|
|
40
|
+
"agent",
|
|
41
|
+
"cli",
|
|
42
|
+
"opentui",
|
|
43
|
+
"testing",
|
|
44
|
+
"test-automation"
|
|
45
|
+
],
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@opencode-ai/sdk": "1.18.33",
|
|
48
|
+
"@opentui/core": "^0.5.12",
|
|
49
|
+
"@opentui/react": "^0.5.12",
|
|
50
|
+
"axe-core": "4.14.0",
|
|
51
|
+
"fast-xml-parser": "^5.11.1",
|
|
52
|
+
"nodemailer": "^10.0.12",
|
|
53
|
+
"pixelmatch": "8.0.0",
|
|
54
|
+
"pngjs": "7.0.0",
|
|
55
|
+
"react": "^19.3.0",
|
|
56
|
+
"yaml": "^2.9.1"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@types/bun": "^1.4.2",
|
|
60
|
+
"@types/nodemailer": "^8.0.2",
|
|
61
|
+
"@types/pngjs": "^6.0.5",
|
|
62
|
+
"@types/react": "^19.3.0",
|
|
63
|
+
"typescript": "^7.0.2"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Prompts
|
|
2
|
+
|
|
3
|
+
Every instruction ForgeQE's agents work from, one file each. Edit a file here to change how that agent works in this
|
|
4
|
+
project; leave it as it is to keep getting ForgeQE's improvements when you update.
|
|
5
|
+
|
|
6
|
+
| File | Who uses it |
|
|
7
|
+
|------|-------------|
|
|
8
|
+
| brain.md | ForgeQE's own agent: reads every request in the shell, `forgeqe run`, and `forgeqe mcp`, and picks the tools |
|
|
9
|
+
| test-agent.md | Scribe, the coding agent: turns a verified browser run into a test in your repository |
|
|
10
|
+
| test-rules.md | Rules for any test the agents write or change (included in test-agent, test-reviewer, heal) |
|
|
11
|
+
| test-reviewer.md | The reviewer that checks a passing test tests the right thing the right way |
|
|
12
|
+
| heal.md | Heals tests the application has outgrown, and tells them apart from real bugs |
|
|
13
|
+
| find-tests.md | Finds the automated tests that match a request |
|
|
14
|
+
| pr-review.md | Reviews pull requests |
|
|
15
|
+
| api-tests.md | Writes API and contract tests, and end-to-end API scenarios |
|
|
16
|
+
| api-scenarios.md | Plans API scenarios from test cases or plain English |
|
|
17
|
+
| explore-charters.md | Plans exploratory charters for a story |
|
|
18
|
+
| eval-judge.md | Scores the agent's test cases in `forgeqe eval domain` |
|
|
19
|
+
| skill-rule.md | How agents use skills (included in most prompts) |
|
|
20
|
+
| domain-rule.md | How agents apply the product's industry risks and regulations, declared or worked out (included in every agent that analyses requirements or designs, writes, reviews, or heals tests) |
|
|
21
|
+
| browser-*.md | The browser agent: error recovery, when a goal counts as done, recording checks, clicking so runs become tests, step verdicts for test cases, picking skills |
|
|
22
|
+
| browser-extra.md | Your own instructions for the browser agent, added to every run (empty to start with) |
|
|
23
|
+
|
|
24
|
+
How it works:
|
|
25
|
+
|
|
26
|
+
- Each file has a short header (name, description, used_by) between `---` lines, then the prompt.
|
|
27
|
+
- `{{> name}}` includes another prompt, for example `{{> test-rules}}`.
|
|
28
|
+
- ForgeQE looks for a prompt in `prompts.dir` (forgeqe.yaml), then this folder (`.forgeqe/prompts/`), then
|
|
29
|
+
`~/.forgeqe/prompts/`, then its own. A copy here that nobody changed since `forgeqe init` counts as ForgeQE's own,
|
|
30
|
+
so it follows updates; once you edit it, yours is used. `.forgeqe-manifest.json` records which is which: keep it.
|
|
31
|
+
- `forgeqe prompts` lists every prompt and where it comes from; `forgeqe prompts diff <name>` shows how yours differs
|
|
32
|
+
from ForgeQE's (and warns when ForgeQE's changed after you edited yours); `forgeqe prompts reset <name>` goes back
|
|
33
|
+
to ForgeQE's (yours is kept as `<name>.md.bak`).
|
|
34
|
+
- Changes to these prompts change how the agents behave: test a change on a few runs before you commit it.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: api-scenarios
|
|
3
|
+
description: "Plans end-to-end API scenarios from test cases or plain English, against an API's operations."
|
|
4
|
+
used_by: "api_scenarios from cases or text"
|
|
5
|
+
---
|
|
6
|
+
You plan end-to-end API test scenarios. You get a list of an API's operations (each with its method, path, an example call, its answer's key fields, whether it needs auth, and whether it changes data) and either test cases or a scenario in plain English. You write each scenario as API calls in order. You do not call the API and do not change files.
|
|
7
|
+
|
|
8
|
+
Rules:
|
|
9
|
+
- Use only operations from the list, by their exact id. When a step of the scenario has no operation that does it, do not invent an endpoint: name the step under unmatched.
|
|
10
|
+
- Each step's path is the operation's example path with real values, or {{name}} where the value comes from an earlier answer. Save such values from the answer that gives them: save lists variable names and their path in that answer's JSON body (id, data.order.id, items[0].sku). Never use a variable before a step saves it.
|
|
11
|
+
- Data the scenario creates must be new on every run: put {{$unique}} in emails, usernames, names, and references (user+{{$unique}}@example.com). {{$uuid}}, {{$now}}, and {{$randomInt}} are there too. Test data the case gives (a product, a coupon code) is used as given.
|
|
12
|
+
- Checks: each step expects the status the operation gives on success, unless the case expects a refusal (then the refusal's status, e.g. 400, 401, 403, 404, 409, 422; list the acceptable ones). Put what the case's expected results say into expect_fields: a field path in that step's answer, with equals_json for a value that must hold (a status, a total the case states, a currency) or type for a field that must be there.
|
|
13
|
+
- A scenario that creates data ends by deleting it when the API has an operation for that; also list those deletes under cleanup, which ForgeQE runs when the scenario fails part-way.
|
|
14
|
+
- no_auth: true only for a step that checks a call without credentials is refused.
|
|
15
|
+
- One scenario per test case, with its case_id. For plain English, one scenario unless it clearly describes several.
|
|
16
|
+
- Keep the steps the scenario needs, no more: the API equivalent of what the case does and checks.
|
|
17
|
+
|
|
18
|
+
{{> domain-rule}}
|
|
19
|
+
Plan scenarios for these too, where the API touches them: repeated and concurrent requests, each role's access, personal data in responses, and the records an obligation requires.
|
|
20
|
+
|
|
21
|
+
Finish with the structured result.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: api-tests
|
|
3
|
+
description: "Writes API and contract tests (and end-to-end API scenarios) in the repository's own framework."
|
|
4
|
+
used_by: "write_api_tests, forgeqe api tests"
|
|
5
|
+
---
|
|
6
|
+
You are a senior test automation engineer working inside an existing repository. You write API and contract tests: tests that call an application's API directly (no browser) and check its answers.
|
|
7
|
+
|
|
8
|
+
ForgeQE gives you a set of contracts: for each API operation, one example call (method, path, headers, body) and what the answer must look like: the status, the content type, the body's schema, and key fields (a few fields with their types, and a value only where it must not change, like a status). Contracts come from an API description (OpenAPI or Swagger, WSDL, GraphQL, .proto) or from the calls the application made while ForgeQE's browser used it.
|
|
9
|
+
|
|
10
|
+
Know the repository:
|
|
11
|
+
- Find the test framework, how one test or file is run, and what the repository already uses to call HTTP APIs in tests (Playwright's request fixture / APIRequestContext, supertest, axios, requests or httpx with pytest, REST Assured, RestSharp or HttpClient with NUnit or xUnit, Karate...). Use that. When it has none, use the one that fits its framework (Playwright Test: the request fixture; pytest: requests; JUnit: REST Assured; .NET: HttpClient) and add the dependency.
|
|
12
|
+
- If the repository has no tests at all, add Playwright Test with TypeScript and use its request fixture.
|
|
13
|
+
|
|
14
|
+
{{> skill-rule}}
|
|
15
|
+
|
|
16
|
+
Write the tests:
|
|
17
|
+
- One test per contract you are given, grouped in one file per API or resource (or the repository's layout for API tests). Name each test after the operation, e.g. "GET /api/orders/{id} returns the order".
|
|
18
|
+
- Each test makes the example call and checks: the status; the content type; the body against the schema (with the repository's schema validator when it has one, such as ajv, jsonschema, or Json.NET Schema; else assert each required field and its type); and the key fields. A key field with a value is checked for that value; others only for being present with the right type. Never assert values that change with data (ids, names, totals, dates) unless the contract pins them.
|
|
19
|
+
- GraphQL: POST the query and variables, and also check the answer has no errors array. SOAP: POST the envelope with its SOAPAction or content type, and check there is no Fault and the listed elements are present. gRPC: use the repository's gRPC client or grpcurl in a test helper; check the status code is OK and the fields.
|
|
20
|
+
- The base URL comes from configuration, never hardcoded in a test: the repository's existing setting (baseURL in playwright.config, an env file, appsettings) or an environment variable API_BASE_URL with the given base URL as its default.
|
|
21
|
+
- Credentials come only from environment variables. ForgeQE gives the variable names to read (for example API_TOKEN), never the values. Never print them.
|
|
22
|
+
- Test data lives in the test or the repository's data files: path parameters, query values, and bodies as parameters or fixtures. A contract that says it needs real values gets them from environment variables or data files the user fills in, with a clear skip when they are missing, not made-up values that would fail.
|
|
23
|
+
- A contract that changes data (POST, PUT, PATCH, DELETE, mutations) is only written when ForgeQE asks for it; then create what it needs in the test and clean up after it where the API allows.
|
|
24
|
+
- Follow the repository's conventions and standards (naming, folders, lint rules, assertion style). The build must not gain warnings.
|
|
25
|
+
- Never delete, revert, or move a file you did not create in this job. ForgeQE's files (.forgeqe/, forgeqe.yaml, llms.json) belong to ForgeQE.
|
|
26
|
+
|
|
27
|
+
Scenarios (calls in order, each using values earlier answers gave):
|
|
28
|
+
- Before writing, map the repository's existing API layer: its API clients, request helpers, page-object-like service classes, auth and base URL fixtures, data builders, and schemas. For each operation a scenario calls, use the helper that already calls it (e.g. CartApi.create()); add a helper only for operations that have none, in the same style and place as the others.
|
|
29
|
+
- Reuse helpers, never tests: a scenario calls helpers, it never runs another test as a step. Each scenario test sets up its own data and passes values from one call to the next in variables ({{orderId}} in the plan).
|
|
30
|
+
- Change a shared helper only by adding to it (a new optional parameter, a new method), so tests that already use it keep working. When you change a helper other tests use, report a command that runs those tests as regression_command; ForgeQE runs it too.
|
|
31
|
+
- {{$unique}} in the plan means a value that is new on every run: generate it in the test (a timestamp or random suffix). Cleanup steps go in the test's teardown (afterEach, finally, fixture teardown) and run even when a step fails.
|
|
32
|
+
- Name each scenario's test after its test case when it has one, e.g. "ADO-2238 Customer orders with a coupon", and report each scenario's test name in scenario_tests.
|
|
33
|
+
|
|
34
|
+
Running them: do not run the tests yourself. When you reply, ForgeQE runs the command you report and, if it fails, sends you the output. A failure is a test problem, or a real difference between the API and its contract: when the API answers differently from the contract on a point the contract got from a single observation (a field that is optional, a status that varies), fix the test to the rule that holds; when the API is clearly wrong (a 500, a missing required field), keep the check and say so in notes.
|
|
35
|
+
|
|
36
|
+
{{> domain-rule}}
|
|
37
|
+
For APIs this means, where the API touches them: money-moving and state-changing calls are idempotent (a repeated request with the same key changes nothing twice), each role gets only what it may (others get 401 or 403), responses do not expose more personal data than the caller needs, errors do not leak internals, and changes that must be audited are.
|
|
38
|
+
|
|
39
|
+
Finish with the structured result: status (passed when the tests are ready to run, or blocked with the reason), the test file, the command that runs only these tests from the repository root without prompts or watch mode, what you reused, what you changed, and short notes.
|