Every feature merged to main must satisfy the acceptance criteria defined in this standard. This applies equally to new features, enhancements, bug fixes, and refactors that touch user-facing endpoints or business-critical paths.
This is not a suggestion — it is a blocking requirement. Pull requests that do not meet these criteria must not pass the pipeline gate.
AURA handles real money. A feature that works but can’t be monitored, secured, traced, or tested in production is a liability. The Access Worldpay platform taught us that operational maturity comes from discipline at the feature level, not from bolting quality onto a running system after the fact.
Define what “done” looks like before writing code.
This principle applies to everything: tests, security, observability, API contracts, and documentation. These are not separate activities performed at different stages. They are all part of answering one question before the first line of implementation is written: “What must be true for this feature to be complete?”
Every feature begins with acceptance criteria. Those criteria are written into the PR description or linked issue before the first implementation commit. The criteria cover all of the domains below. If a domain doesn’t apply (e.g., the change doesn’t introduce a new endpoint), note that explicitly — don’t leave it ambiguous.
What logic paths must be tested? What edge cases? What error conditions? What end-to-end flows must work? What database state transitions?
Before code:
What are the security requirements for this feature? What attack surfaces does it introduce or modify?
Before code, answer these questions against the API Security Baseline (docs/security/API_SECURITY_BASELINE.md):
{ preHandler: verifyAgent }. If no, document why it is safe to leave unauthenticated.WHERE id = $1 AND agent_id = $2 is.Write specific, testable security criteria. Examples of good criteria:
Examples of criteria that are too vague to be useful:
What does the request/response interface look like?
Before code:
How will this feature be monitored in production?
Before code:
Business metrics: What counters, gauges, or histograms must be emitted? Specify the metric name, labels, and the action that triggers emission. Use the metric naming conventions from metrics.js.
| Action | Required Metric | Example |
|---|---|---|
| Entity created | Counter increment | sessionsCreatedTotal.inc() |
| Entity state change | Counter increment | transactionsCommittedTotal.inc() |
| Active entity tracking | Gauge inc/dec | activeSessions.inc() / .dec() |
| External call outcome | Counter with status label | webhookDeliveriesTotal.inc({ status: 'success' }) |
getTraceHeaders(request).request.log (which automatically includes traceId and spanId), never console.log.warn level with error code and context. 5xx errors logged at error level with stack trace.slo.js.What must be updated?
Criteria are only as good as their verification. Every domain above must have corresponding tests that run in CI.
Unit and integration tests that verify the logic paths defined in domain 1.
Tests that verify the security behaviour defined in domain 2. These are not optional supplements — they are acceptance tests, same as any functional test.
Required patterns:
Tests that verify the metric emission and trace propagation defined in domain 4. Use the MetricsTestHelper from src/lib/test-helpers/metrics-helper.js.
Required patterns:
traceparent header.Example:
import { MetricsTestHelper } from '../lib/test-helpers/metrics-helper.js';
import { sessionsCreatedTotal } from '../lib/metrics.js';
test('POST /sessions increments sessions_created counter', async () => {
const helper = new MetricsTestHelper();
await helper.snapshot(); // MUST await
const response = await app.inject({
method: 'POST',
url: '/v1/sessions',
payload: { intent: 'buy running shoes' },
});
assert.equal(response.statusCode, 200);
await helper.assertCounterIncremented(sessionsCreatedTotal, 1);
});
Copy this into your PR description:
## Feature Readiness Checklist
### Acceptance Criteria (defined before code)
- [ ] Functional test criteria defined (unit paths, integration flows, state transitions)
- [ ] Security criteria defined against API Security Baseline (auth, authorization, input validation, SSRF)
- [ ] API contract defined (request/response schemas, pagination, idempotency)
- [ ] Observability criteria defined (metrics, trace propagation, logging, SLO impact)
- [ ] Documentation needs identified
### Implementation Verification
- [ ] Unit tests pass (including authorization boundary tests)
- [ ] Integration tests pass
- [ ] Security acceptance tests verify authorization, authentication, input validation
- [ ] Observability tests verify metric emission and labels
- [ ] Performance tests pass (if latency-sensitive path)
### Documentation
- [ ] API docs updated
- [ ] Decision log entry (if architectural choice made)
- [ ] DEPLOYMENT.md updated (if new env vars or infra)
- [ ] Security annotations on route handlers (OWASP categories considered)
The CI pipeline (Pipeline gate) blocks merge if any test job fails. Security tests, observability tests, and functional tests all run as part of the standard test suite. There are no separate gates — security and observability are not optional add-ons, they are part of the definition of done.
If a PR adds a new endpoint without corresponding authorization boundary tests and metric emission tests, the review must flag it as incomplete.
docs/security/API_SECURITY_BASELINE.mddocs/security/SECURITY_AUDIT_REPORT.mdsrc/lib/slo.jssrc/lib/metrics.jssrc/lib/tracing.jsdocs/decisions/DECISION_LOG.md