forgecraft-mcp 1.7.0 → 1.8.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/README.md +79 -0
- package/dist/registry/remote-gates.d.ts +16 -0
- package/dist/registry/remote-gates.d.ts.map +1 -1
- package/dist/registry/remote-gates.js +56 -0
- package/dist/registry/remote-gates.js.map +1 -1
- package/dist/registry/sentinel-domain-map.d.ts.map +1 -1
- package/dist/registry/sentinel-domain-map.js +16 -9
- package/dist/registry/sentinel-domain-map.js.map +1 -1
- package/dist/registry/sentinel-renderer.d.ts +13 -8
- package/dist/registry/sentinel-renderer.d.ts.map +1 -1
- package/dist/registry/sentinel-renderer.js +440 -162
- package/dist/registry/sentinel-renderer.js.map +1 -1
- package/dist/shared/harness-budget.d.ts +49 -0
- package/dist/shared/harness-budget.d.ts.map +1 -0
- package/dist/shared/harness-budget.js +123 -0
- package/dist/shared/harness-budget.js.map +1 -0
- package/dist/shared/hook-installer.d.ts.map +1 -1
- package/dist/shared/hook-installer.js +2 -1
- package/dist/shared/hook-installer.js.map +1 -1
- package/dist/tools/close-cycle-helpers.d.ts +9 -0
- package/dist/tools/close-cycle-helpers.d.ts.map +1 -1
- package/dist/tools/close-cycle-helpers.js.map +1 -1
- package/dist/tools/close-cycle.d.ts.map +1 -1
- package/dist/tools/close-cycle.js +29 -0
- package/dist/tools/close-cycle.js.map +1 -1
- package/dist/tools/contribute-gate.d.ts +30 -4
- package/dist/tools/contribute-gate.d.ts.map +1 -1
- package/dist/tools/contribute-gate.js +180 -66
- package/dist/tools/contribute-gate.js.map +1 -1
- package/dist/tools/gate-genesis.d.ts +47 -0
- package/dist/tools/gate-genesis.d.ts.map +1 -0
- package/dist/tools/gate-genesis.js +241 -0
- package/dist/tools/gate-genesis.js.map +1 -0
- package/dist/tools/learning-graph.d.ts +31 -0
- package/dist/tools/learning-graph.d.ts.map +1 -0
- package/dist/tools/learning-graph.js +266 -0
- package/dist/tools/learning-graph.js.map +1 -0
- package/dist/tools/setup-artifact-writers.d.ts +15 -3
- package/dist/tools/setup-artifact-writers.d.ts.map +1 -1
- package/dist/tools/setup-artifact-writers.js +149 -13
- package/dist/tools/setup-artifact-writers.js.map +1 -1
- package/dist/tools/setup-phase2.d.ts +9 -0
- package/dist/tools/setup-phase2.d.ts.map +1 -1
- package/dist/tools/setup-phase2.js +13 -0
- package/dist/tools/setup-phase2.js.map +1 -1
- package/dist/tools/setup-project.d.ts +6 -0
- package/dist/tools/setup-project.d.ts.map +1 -1
- package/dist/tools/setup-project.js +21 -4
- package/dist/tools/setup-project.js.map +1 -1
- package/package.json +99 -98
- package/templates/api/instructions.yaml +50 -188
- package/templates/universal/instructions.yaml +194 -1003
|
@@ -6,100 +6,51 @@ blocks:
|
|
|
6
6
|
title: "API Service Standards"
|
|
7
7
|
content: |
|
|
8
8
|
## API Standards
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
- Version from day one: /api/v1/...
|
|
17
|
-
- Proper HTTP semantics: GET reads, POST creates, PUT replaces, PATCH updates, DELETE removes.
|
|
18
|
-
- Pagination on ALL list endpoints. Never return unbounded results.
|
|
19
|
-
- Consistent response envelope: { data, meta, errors }.
|
|
20
|
-
- Async operations return job ID + polling endpoint, not blocking results.
|
|
21
|
-
- Rate limiting on all public endpoints.
|
|
22
|
-
|
|
23
|
-
### Validation
|
|
24
|
-
- Input validation at API boundary — reject malformed requests before they reach services.
|
|
25
|
-
- Use schema validation (Pydantic, Zod, Joi) not manual if-checks.
|
|
26
|
-
- Validate request body, query params, path params, and headers.
|
|
27
|
-
- Return 422 with specific field errors, not generic 400.
|
|
28
|
-
|
|
29
|
-
### Authentication & Authorization
|
|
30
|
-
- Auth middleware/guards at router level, not checked inside handlers.
|
|
31
|
-
- Role-based or policy-based access control via decorators/middleware.
|
|
32
|
-
- Never trust client-sent user identity — always verify from token/session.
|
|
33
|
-
|
|
34
|
-
### Database & Migrations
|
|
35
|
-
- Schema changes managed through migration files (Prisma Migrate, Knex, Flyway, Alembic).
|
|
36
|
-
- Every migration must be reversible (up + down). Test rollbacks.
|
|
37
|
-
- Never modify a deployed migration — create a new one.
|
|
38
|
-
- Seed data separate from migrations. Test seeds run in CI.
|
|
39
|
-
|
|
40
|
-
### Security (OWASP Top 10)
|
|
41
|
-
- **Injection**: Parameterized queries only. No string concatenation for SQL, commands, or LDAP.
|
|
42
|
-
- **Broken Auth**: Rate-limit login attempts. Enforce strong passwords. Rotate tokens.
|
|
43
|
-
- **Sensitive Data Exposure**: Encrypt at rest (AES-256). Never log PII, tokens, or passwords.
|
|
44
|
-
- **XXE/XSS**: Sanitize all user-generated HTML. Content-Security-Policy headers on all responses.
|
|
45
|
-
- **Broken Access Control**: Enforce ownership checks — users can't access other users' resources.
|
|
46
|
-
- **Security Misconfiguration**: No default credentials. No verbose error messages in production.
|
|
47
|
-
Security headers: X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy.
|
|
48
|
-
- **CSRF**: Token-based protection on all state-changing endpoints (unless using SameSite cookies + bearer tokens).
|
|
49
|
-
- **Audit logging**: Log WHO did WHAT, WHEN, to WHICH resource. Separate from application logs.
|
|
50
|
-
Immutable. Retained per compliance requirements.
|
|
51
|
-
|
|
52
|
-
### Graceful Shutdown
|
|
53
|
-
- Handle SIGTERM: stop accepting new requests, drain in-flight requests, close DB connections, exit.
|
|
54
|
-
- Kubernetes: readiness probe fails immediately, liveness continues during drain.
|
|
55
|
-
- Shutdown timeout configurable (default: 30s). Force exit after timeout.
|
|
9
|
+
- **Contract first**: define OpenAPI/JSON Schema before implementing; generate types from spec (no manual dupes); spec is source of truth.
|
|
10
|
+
- **Design**: version from day one (`/api/v1/...`); correct HTTP semantics (GET read, POST create, PUT replace, PATCH update, DELETE remove); pagination on ALL list endpoints; envelope `{ data, meta, errors }`; async ops return job ID + polling endpoint; rate limiting on all public endpoints.
|
|
11
|
+
- **Validation**: at the API boundary via schema (Zod/Pydantic/Joi), not manual if-checks; validate body, query, path, headers; return 422 with field errors, not generic 400.
|
|
12
|
+
- **Auth**: middleware/guards at router level (not inside handlers); RBAC/policy via middleware; never trust client-sent identity — verify from token/session.
|
|
13
|
+
- **Migrations**: through migration files (Prisma/Knex/Flyway/Alembic); reversible (up+down), test rollbacks; never modify a deployed migration; seeds separate, run in CI.
|
|
14
|
+
- **OWASP Top 10**: parameterized queries only; rate-limit logins + rotate tokens; encrypt at rest (AES-256), never log PII/tokens; sanitize user HTML + CSP; ownership checks on every resource; no default creds, no verbose prod errors; security headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy); CSRF tokens on state-changing endpoints; immutable audit log (who/what/when/which) separate from app logs.
|
|
15
|
+
- **Graceful shutdown**: SIGTERM → stop intake → drain → close DB → exit; k8s readiness fails immediately, liveness continues; configurable timeout (default 30s), force exit after.
|
|
56
16
|
|
|
57
17
|
- id: api-stack-constraints
|
|
58
18
|
tier: core
|
|
59
19
|
title: "API Stack Constraints"
|
|
60
20
|
content: |
|
|
61
21
|
## API Stack Constraints — Approved Dependency Choices
|
|
62
|
-
|
|
63
|
-
These are the **approved libraries for this API project**.
|
|
64
|
-
Every choice has a banned alternative with a concrete reason.
|
|
65
|
-
If you reach for a banned alternative, stop and use the approved one instead.
|
|
66
|
-
Rationale is stated so you understand the constraint — not so you can argue around it.
|
|
22
|
+
Use the approved library; if you reach for a banned one, stop.
|
|
67
23
|
|
|
68
24
|
{{#if language_is_typescript}}
|
|
69
|
-
### TypeScript API
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
|
74
|
-
|
|
|
75
|
-
|
|
|
76
|
-
|
|
|
77
|
-
|
|
|
78
|
-
|
|
|
79
|
-
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
**npm audit policy**: `npm audit` must return zero `high` or `critical` findings before the
|
|
83
|
-
first commit. If a dependency introduces a high/critical CVE, replace it with an alternative
|
|
84
|
-
from this table or open an ADR documenting the exception with mitigation.
|
|
25
|
+
### TypeScript API
|
|
26
|
+
| Concern | Use | Do NOT use |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| Password hashing | `argon2@^0.31` | `bcrypt`/`bcryptjs` (native tar CVE chain) |
|
|
29
|
+
| HTTP framework | `express@^4`/`fastify@^4` | `restify` (unmaintained), `hapi@<21`, `koa` |
|
|
30
|
+
| Input validation | `zod@^3` | `joi`/`express-validator` alone |
|
|
31
|
+
| JWT | `jsonwebtoken@^9` | `jwt-simple` (abandoned), `<9` |
|
|
32
|
+
| ORM | `@prisma/client@^5`/`kysely@^0.27` | `typeorm`, `sequelize` (weak TS) |
|
|
33
|
+
| Logger | `pino@^9` | `winston`, `console.log` in prod |
|
|
34
|
+
| HTTP client | `undici@^6`/native `fetch` | `axios` for Node ≥18 |
|
|
35
|
+
| ESLint | `@typescript-eslint/*@^8` | `^5`/`^6` (minimatch CVE) |
|
|
36
|
+
|
|
37
|
+
`npm audit` zero high/critical before first commit; else replace or ADR the exception.
|
|
85
38
|
{{/if}}
|
|
86
39
|
|
|
87
40
|
{{#if language_is_python}}
|
|
88
|
-
### Python API
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
|
93
|
-
|
|
|
94
|
-
|
|
|
95
|
-
|
|
|
96
|
-
|
|
|
97
|
-
|
|
|
98
|
-
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
**pip audit policy**: `pip audit` must return zero `high` or `critical` findings before the
|
|
102
|
-
first commit. If a dependency introduces a high/critical CVE, replace it or open an ADR.
|
|
41
|
+
### Python API
|
|
42
|
+
| Concern | Use | Do NOT use |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| Web framework | `fastapi@^0.110` | `flask` for async (blocks per request) |
|
|
45
|
+
| Validation | `pydantic@^2` | `pydantic@^1` (unmaintained) |
|
|
46
|
+
| Password hashing | `argon2-cffi@^23` | `hashlib`/`MD5`/`SHA256` (not a KDF) |
|
|
47
|
+
| JWT | `PyJWT@^2.8`/`python-jose[cryptography]@^3.3` | `python-jwt`, `itsdangerous` |
|
|
48
|
+
| ORM | `sqlalchemy@^2.0` + `asyncpg` | `sqlalchemy@^1.x` |
|
|
49
|
+
| HTTP client | `httpx@^0.27` | `requests` in async (blocks loop) |
|
|
50
|
+
| Logger | `structlog@^24` | bare `logging` in prod |
|
|
51
|
+
| Linting | `ruff@^0.4` | `flake8`+`isort`+`black` separately |
|
|
52
|
+
|
|
53
|
+
`pip audit` zero high/critical before first commit; else replace or ADR.
|
|
103
54
|
{{/if}}
|
|
104
55
|
|
|
105
56
|
- id: api-deployment
|
|
@@ -107,125 +58,36 @@ blocks:
|
|
|
107
58
|
title: "API Deployment & Hosting"
|
|
108
59
|
content: |
|
|
109
60
|
## API Deployment
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
-
|
|
113
|
-
- Pin base image digests, not just tags. Scan images for CVEs in CI (Trivy, Grype).
|
|
114
|
-
- Push to container registry (ECR, GCR, GHCR) on every merge to main.
|
|
115
|
-
- Orchestrate with Kubernetes, ECS, or Cloud Run. Define resource limits for every container.
|
|
116
|
-
|
|
117
|
-
### PaaS / Quick Deploy
|
|
118
|
-
- **Railway**: Git-push deploy with auto-detected Dockerfile or Nixpacks. Ideal for staging and side projects.
|
|
119
|
-
- **Render**: Free tier + auto-deploy from Git. Native cron jobs, managed Postgres.
|
|
120
|
-
- **Fly.io**: Edge deployment with Firecracker VMs. Good for low-latency APIs. `fly deploy` from CI.
|
|
121
|
-
- All PaaS platforms: use platform env vars for secrets, connect managed DB add-ons, enable auto-sleep
|
|
122
|
-
for non-production to control cost.
|
|
123
|
-
|
|
124
|
-
### Environment Management
|
|
125
|
-
- One Dockerfile, many environments. Same image runs in dev, staging, prod.
|
|
126
|
-
- Health check endpoint (`/health`) returns: status, version, uptime, dependency connectivity.
|
|
127
|
-
- Database connection pooling configured per environment (dev: 5, staging: 20, prod: 50+).
|
|
128
|
-
- Migrations run automatically on deploy (pre-deploy hook or init container). Never manually.
|
|
61
|
+
- **Containers**: multi-stage Dockerfile (builder → minimal non-root runtime); pin base image digests; scan in CI (Trivy/Grype); push to registry (ECR/GCR/GHCR) on merge to main; orchestrate (k8s/ECS/Cloud Run) with resource limits.
|
|
62
|
+
- **PaaS quick deploy**: Railway (git-push), Render (free tier, managed Postgres), Fly.io (`fly deploy`, edge). Platform env vars for secrets, managed DB add-ons, auto-sleep non-prod.
|
|
63
|
+
- **Environments**: one Dockerfile, same image dev→staging→prod; `/health` returns status/version/uptime/deps; connection pooling per env (dev 5, staging 20, prod 50+); migrations run automatically on deploy, never manually.
|
|
129
64
|
|
|
130
65
|
- id: api-testing
|
|
131
66
|
tier: recommended
|
|
132
67
|
title: "API-Specific Testing Requirements"
|
|
133
68
|
content: |
|
|
134
69
|
## API-Specific Testing Requirements
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
-
|
|
139
|
-
-
|
|
140
|
-
- Provider verification runs in CI on every build — a failed verification blocks deployment.
|
|
141
|
-
- CDC covers request schema, response schema, status codes, and error shapes. It does not cover load or security — those are separate gates.
|
|
142
|
-
|
|
143
|
-
### API / Subcutaneous Tests as Primary Integration Layer
|
|
144
|
-
The subcutaneous layer (HTTP requests to a running server with real DB and stubbed external deps) is the primary integration verification surface for API projects. Unit tests verify logic; subcutaneous tests verify contracts.
|
|
145
|
-
- Use Supertest (Node) or httpx/pytest (Python) against a locally started server instance.
|
|
146
|
-
- Stub external services with WireMock, msw, or responses (Python). Never call real external APIs in CI.
|
|
147
|
-
- Every public endpoint has a subcutaneous test for: 200 happy path, 4xx validation rejection, 401/403 auth enforcement, and at least one edge case.
|
|
148
|
-
|
|
149
|
-
### DAST at Staging — Mandatory
|
|
150
|
-
Dynamic application security testing is required before every production promotion. OWASP ZAP minimum.
|
|
151
|
-
- Run ZAP active scan against the staging environment as a post-deploy CI step.
|
|
152
|
-
- Define an acceptable risk threshold in the spec: which finding severities are blocking (High = always blocking; Medium/Low = tracked, not blocking by default).
|
|
153
|
-
- ZAP scan configuration committed to the repo (`zap-config.yaml`). Not a one-off manual step.
|
|
154
|
-
|
|
155
|
-
### Rate Limiting and Throttling in Integration Layer
|
|
156
|
-
- Rate limit behavior must be covered in the subcutaneous integration suite, not just documented.
|
|
157
|
-
- Test: normal traffic (no throttle), burst traffic (trigger rate limit, receive 429), retry-after header present and correct.
|
|
158
|
-
- Test quota exhaustion and quota reset behavior for API-key-based limits.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
### Scaling
|
|
162
|
-
- Horizontal scaling by default. No in-memory session state — use Redis or DB.
|
|
163
|
-
- Auto-scaling rules based on CPU + request queue depth, not just CPU alone.
|
|
164
|
-
- Database read replicas for read-heavy workloads. Connection pooler (PgBouncer) in front of Postgres.
|
|
70
|
+
- **CDC (mandatory)**: consumer writes pact, provider verifies in CI (Pact / Spring Cloud Contract); broker stores pacts; failed verification blocks deployment. Covers request/response schema, status codes, error shapes.
|
|
71
|
+
- **Subcutaneous tests (primary integration layer)**: HTTP to a running server, real DB, stubbed external deps (Supertest / httpx+pytest; stub with WireMock/msw/responses, never real external APIs in CI). Every endpoint: 200 happy, 4xx validation, 401/403 auth, ≥1 edge case.
|
|
72
|
+
- **DAST at staging (mandatory)**: OWASP ZAP active scan as post-deploy CI step; `zap-config.yaml` committed; High always blocking, Medium/Low tracked.
|
|
73
|
+
- **Rate limiting in integration suite**: normal (no throttle), burst (429 + correct retry-after), quota exhaustion + reset for API-key limits.
|
|
74
|
+
- **Scaling**: horizontal by default, no in-memory session (Redis/DB); auto-scale on CPU + queue depth; read replicas + PgBouncer for read-heavy.
|
|
165
75
|
|
|
166
76
|
- id: api-smoke-testing
|
|
167
77
|
tier: recommended
|
|
168
78
|
title: "API Smoke Testing (Post-Deploy)"
|
|
169
79
|
content: |
|
|
170
80
|
## API Smoke Testing
|
|
171
|
-
|
|
172
|
-
### Required: Playwright APIRequestContext (no browser overhead)
|
|
173
|
-
Tag all smoke tests `@smoke` for isolated execution:
|
|
81
|
+
Playwright APIRequestContext (no browser). Tag `@smoke`:
|
|
174
82
|
```
|
|
175
83
|
npx playwright test --config playwright.smoke.config.ts --grep @smoke
|
|
176
84
|
```
|
|
177
85
|
|
|
178
|
-
Minimum
|
|
179
|
-
-
|
|
180
|
-
-
|
|
181
|
-
-
|
|
182
|
-
-
|
|
183
|
-
-
|
|
184
|
-
|
|
185
|
-
```typescript
|
|
186
|
-
// tests/smoke/api.smoke.ts
|
|
187
|
-
import { test, expect } from '@playwright/test';
|
|
86
|
+
Minimum suite:
|
|
87
|
+
- Health: `GET /health` → 200, body has `status: ok` + `version`
|
|
88
|
+
- Auth: primary login with valid creds → token returned
|
|
89
|
+
- Primary read: representative `GET` → 200, envelope validates
|
|
90
|
+
- Primary write: representative `POST` → 2xx, verify with follow-up `GET`
|
|
91
|
+
- 404 shape: missing resource → 404, error envelope matches contract
|
|
188
92
|
|
|
189
|
-
|
|
190
|
-
const res = await request.get('/health');
|
|
191
|
-
expect(res.ok()).toBeTruthy();
|
|
192
|
-
const body = await res.json();
|
|
193
|
-
expect(body).toMatchObject({ status: 'ok' });
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
test('@smoke auth returns token', async ({ request }) => {
|
|
197
|
-
const res = await request.post('/api/v1/auth/login', {
|
|
198
|
-
data: {
|
|
199
|
-
email: process.env['SMOKE_USER'],
|
|
200
|
-
password: process.env['SMOKE_PASSWORD'],
|
|
201
|
-
},
|
|
202
|
-
});
|
|
203
|
-
expect(res.status()).toBe(200);
|
|
204
|
-
const body = await res.json();
|
|
205
|
-
expect(typeof body.token ?? body.data?.token).toBe('string');
|
|
206
|
-
});
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
```typescript
|
|
210
|
-
// playwright.smoke.config.ts
|
|
211
|
-
import { defineConfig } from '@playwright/test';
|
|
212
|
-
export default defineConfig({
|
|
213
|
-
use: { baseURL: process.env['PLAYWRIGHT_BASE_URL'] ?? 'http://localhost:3000' },
|
|
214
|
-
testMatch: '**/*.smoke.ts',
|
|
215
|
-
retries: 1,
|
|
216
|
-
timeout: 10_000,
|
|
217
|
-
});
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
Smoke tests run against the **deployed staging URL** only (`PLAYWRIGHT_BASE_URL` env var).
|
|
221
|
-
They never run against localhost in CI — that is the integration suite's job.
|
|
222
|
-
|
|
223
|
-
CI integration (post-deploy step):
|
|
224
|
-
```yaml
|
|
225
|
-
- name: Smoke Tests
|
|
226
|
-
run: npx playwright test --config playwright.smoke.config.ts
|
|
227
|
-
env:
|
|
228
|
-
PLAYWRIGHT_BASE_URL: ${{ env.STAGING_URL }}
|
|
229
|
-
SMOKE_USER: ${{ secrets.SMOKE_USER }}
|
|
230
|
-
SMOKE_PASSWORD: ${{ secrets.SMOKE_PASSWORD }}
|
|
231
|
-
```
|
|
93
|
+
Run against the deployed staging URL only (`PLAYWRIGHT_BASE_URL`), never localhost in CI (that's the integration suite). Wire as a post-deploy CI step with `PLAYWRIGHT_BASE_URL`, `SMOKE_USER`, `SMOKE_PASSWORD` from secrets.
|