From story-coding-agent
Proactive inline guardrail that runs at two seams in the domain-agent execution loop: after db-coding-agent completes (before backend starts) and after backend-coding-agent completes (before frontend starts). Reads the actual artifact files produced by the completed agent, builds a verified inventory of tables/columns or endpoints/DTOs, enriches the next agent's context packet with the corrected inventory, and blocks progression when a critical dependency is missing.
How this skill is triggered — by the user, by Claude, or both
Slash command
/story-coding-agent:contract-validatorThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Validates cross-domain contracts at the point of handoff — before the downstream agent starts executing — so mismatches are caught and corrected early rather than discovered at the end by `cross-domain-review`.
Validates cross-domain contracts at the point of handoff — before the downstream agent starts executing — so mismatches are caught and corrected early rather than discovered at the end by cross-domain-review.
This skill operates in two checkpoint modes, selected by the checkpoint input:
db→backend — runs after db-coding-agent completes, before backend-coding-agent startsbackend→frontend — runs after backend-coding-agent completes, before frontend-coding-agent starts| Input | Source | Description |
|---|---|---|
checkpoint | domain-invoker | One of: db→backend, backend→frontend |
completedAgent | context-bridge output | Agent name + artifact file paths + context-bridge summary |
nextAgentScope | story-plan.md | Scope bullet points for the agent about to run |
storyContext | domain-invoker | Full ticket context for error messages |
Trigger: db-coding-agent just completed; backend-coding-agent is next.
Read all files listed in completedAgent.artifacts. For each file:
Migration files (.sql, **/migrations/**):
CREATE TABLE tableName (...) → record table name + all column definitionsALTER TABLE tableName ADD COLUMN columnName type → append column to existing table entryCREATE INDEX indexName ON tableName (col1, col2) → record indexREFERENCES otherTable(col) → record FK relationshipORM model files (.ts, .cs, .java, .go files in models/, entities/, domain/):
class ModelName with @Column, @Prop, or plain field declarationspublic class ModelName with [Column] attributes or by-convention properties@Entity class ModelName with @Column field declarationstype ModelName struct with gorm:"column:..." tagsBuild a verified schema inventory:
{
"tables": {
"user_sessions": {
"columns": ["id", "user_id", "token", "expires_at", "created_at"],
"indexes": ["idx_user_sessions_token"],
"foreignKeys": [{ "column": "user_id", "references": "users.id" }],
"sourceFile": "migrations/20260324_add_user_sessions.sql"
}
}
}
Read the context-bridge summary text (completedAgent.contextForNext) and extract the table and column names it mentions.
Scan nextAgentScope for:
userSessionRepository.find)For each table name found in the scope:
For each column name explicitly mentioned in the scope:
If BLOCKERs found:
Halt the domain-invoker and emit:
CONTRACT BLOCKER [db→backend]: Backend scope references column `session_token` in table
`user_sessions`, but the DB agent only created column `token`.
Scope reference: story-plan.md (backend scope, bullet 3)
DB artifact: migrations/20260324_add_user_sessions.sql
Fix the discrepancy before re-running. Options:
a) Update the DB migration to add/rename the column
b) Update story-plan.md backend scope to use the correct column name `token`
If WARNs or ENRICHMENTs only:
Continue (non-blocking). Emit a brief notice:
CONTRACT CHECK [db→backend]: context-bridge summary enriched with 2 additional columns
found in migration files. Backend context packet updated.
Return: An enriched contextForNext string that replaces the context-bridge summary's original contextForNext field in the backend agent's context packet. The enriched version lists the complete verified table/column inventory with source file references.
Trigger: backend-coding-agent just completed; frontend-coding-agent is next.
Read all files listed in completedAgent.artifacts. For each file:
Route and controller files (files in routes/, controllers/, handlers/, files named *Router.*, *Controller.*, *Handler.*):
Extract endpoint definitions across language patterns:
| Pattern | Language/Framework | Example |
|---|---|---|
@Get('/path'), @Post('/path') | NestJS, ASP.NET Core | @Get('/auth/me') |
router.get('/path', handler) | Express.js | router.post('/auth/login', ...) |
app.get('/path', handler) | Express.js, Gin, Flask | app.post('/api/users', ...) |
[HttpGet("/path")] | ASP.NET Core | [HttpPost("/auth/login")] |
r.GET("/path", handler) | Gin | r.POST("/auth/login", ...) |
@RequestMapping, @GetMapping | Spring MVC | @PostMapping("/auth/login") |
For each endpoint record: HTTP method (normalised to uppercase), URL path (strip query params, normalise trailing slash), handler function name, request DTO type name (if determinable), response DTO type name (if determinable).
DTO and schema files (files in dto/, types/, schemas/, models/, files named *Dto.*, *Request.*, *Response.*, *Schema.*):
json:"..." tags)Build verified API inventory:
{
"endpoints": [
{
"method": "POST",
"path": "/auth/login",
"requestType": "LoginRequest",
"responseType": "LoginResponse",
"sourceFile": "src/routes/auth.ts:15"
},
{
"method": "GET",
"path": "/auth/me",
"requestType": null,
"responseType": "UserProfile",
"sourceFile": "src/routes/auth.ts:28"
}
],
"dtos": {
"LoginRequest": {
"fields": ["email", "password"],
"sourceFile": "src/dto/LoginRequest.ts"
},
"LoginResponse": {
"fields": ["token", "expiresAt", "user"],
"sourceFile": "src/dto/LoginResponse.ts"
},
"UserProfile": {
"fields": ["id", "email", "name", "createdAt"],
"sourceFile": "src/dto/UserProfile.ts"
}
}
}
Read the context-bridge summary (completedAgent.contextForNext) and extract the endpoint URLs, HTTP methods, and DTO names it mentions.
Scan nextAgentScope for:
loginUser(), fetchProfile(), descriptions like "call POST /auth/login"For each API endpoint reference found in the scope:
URL + Method validation:
Response field validation (best-effort):
user.name" and the response DTO doesn't have a name field → WARNnull (backend returns untyped response) → WARN (type safety risk)If BLOCKERs found:
Halt the domain-invoker and emit:
CONTRACT BLOCKER [backend→frontend]: Frontend scope plans to call POST /api/login
but the backend agent created POST /auth/login (different path prefix).
Scope reference: story-plan.md (frontend scope, bullet 2)
Backend artifact: src/routes/auth.ts:15
Fix the discrepancy before re-running. Options:
a) Update the backend route to use /api/login
b) Update story-plan.md frontend scope to reference the correct path /auth/login
If WARNs or ENRICHMENTs only:
Continue (non-blocking). Emit:
CONTRACT CHECK [backend→frontend]: context-bridge summary enriched with 1 additional
endpoint (GET /auth/me) and full DTO field inventory. Frontend context packet updated.
Return: An enriched contextForNext string with the complete verified endpoint + DTO inventory that replaces the original context-bridge contextForNext in the frontend agent's context packet.
| Severity | Meaning | Blocking? |
|---|---|---|
| BLOCKER | Critical dependency mismatch: column not in DB schema, endpoint not created by backend, or HTTP method mismatch | Yes — halts domain-invoker |
| WARN | Possible issue: scope references ambiguous name, untyped response, or no explicit URL to validate | No — enriched context passed through |
| ENRICHMENT | Context-bridge summary was incomplete; verified inventory auto-corrects the gap | No — context packet updated silently |
db-coding-agent did not run (no DB changes in this story): skip db→backend checkpointbackend-coding-agent did not run (no backend changes in this story): skip backend→frontend checkpointexecutionSequence: no seam to validate; skip entirely{
"checkpoint": "backend→frontend",
"status": "enriched",
"blockers": [],
"warnings": [
{
"check": "response-field",
"message": "Frontend scope mentions displaying `user.avatar` but LoginResponse DTO has no `avatar` field. Only: token, expiresAt, user.",
"scopeReference": "story-plan.md (frontend scope, bullet 4)",
"backendArtifact": "src/dto/LoginResponse.ts"
}
],
"enrichments": [
{
"type": "endpoint",
"added": "GET /auth/me (UserProfile response)",
"reason": "context-bridge summary omitted this endpoint; found in src/routes/auth.ts:28"
}
],
"enrichedContextForNext": "The frontend should call POST /auth/login with body { email, password } (LoginRequest). Response shape: { token: string, expiresAt: ISO8601, user: { id, email, name, createdAt } } (LoginResponse). Additionally call GET /auth/me to validate the session — response: { id, email, name, createdAt } (UserProfile). Both routes are defined in src/routes/auth.ts."
}
npx claudepluginhub gagandeepp/software-agent-teams --plugin story-coding-agentGuides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Enforces test-driven development: write failing test first, then minimal code to pass. Use when implementing features or bugfixes.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.