# MarketplaceCertificationPipeline — A2A Spec

**Product:** JarvisJr  
**Trigger:** `POST /marketplace/listings/:id/submit-for-review` (author action)  
**Output:** Listing status updated to `verified` or `rejected` in `marketplace_listings` Cosmos container

---

## Agent roster

| Step | Agent                        | Input                          | Output                                                 |
| ---- | ---------------------------- | ------------------------------ | ------------------------------------------------------ |
| 1    | `SubmissionIngestionAgent`   | Listing doc + `listingId`      | Validated field set or validation errors               |
| 2    | `ContentSafetyAgent`         | `systemPrompt` + `description` | Safety verdict (`pass` / `flag` / `reject`)            |
| 3    | `QualityEvalAgent`           | Agent config + sample phrases  | Quality score (0–1) + transcript                       |
| 4    | `CertificationDecisionAgent` | Verdicts from agents 1–3       | Final decision, `isVerified` flag, author notification |

---

## Agent contracts

### SubmissionIngestionAgent

```typescript
// Tool: jarvisjr.marketplace.getListing
// Endpoint: GET /marketplace/listings/:id
input: { listingId: string; submitterId: string }
output: {
  valid: boolean;
  errors: string[];            // missing fields
  listing: MarketplaceListingDoc;
}
// Required fields: name, systemPrompt, coachingFramework, category, tags, voiceId
// Rejected immediately if any required field is blank
```

### ContentSafetyAgent

```typescript
// Tool: extraction.extract { taskId: 'triage' }
// Checks systemPrompt + description against policy classes
input: {
  listingId: string;
  text: string; // systemPrompt + "\n\n" + description
}
output: {
  verdict: 'pass' | 'flag' | 'reject';
  reasons: string[];
  confidenceScore: number;
}
// 'reject': contains prohibited content → pipeline halts
// 'flag':   borderline → escalates to human review queue
// 'pass':   proceed to quality eval
```

### QualityEvalAgent

```typescript
// Tool: jarvisjr.sessions.createEval
// Runs a synthetic 3-turn session against the agent config
input: {
  listingId: string;
  agentConfig: AgentConfig;
  evalPhrases: string[]; // 3 sample user prompts
}
output: {
  score: number;       // 0–1; threshold: 0.6 to pass
  transcript: string;
  coherenceIssues: string[];
}
// Calls backend POST /jarvis/sessions/eval (internal, no auth required)
```

### CertificationDecisionAgent

```typescript
// Tool: jarvisjr.marketplace.updateListing
// Endpoint: PUT /marketplace/listings/:id
// Tool: platform.notifications.send (push to listing author)
input: {
  listingId: string;
  submitterId: string;
  ingestionResult: SubmissionIngestionResult;
  safetyResult: ContentSafetyResult;
  qualityResult: QualityEvalResult;
}
output: {
  decision: 'approved' | 'rejected' | 'pending_human_review';
  isVerified: boolean;
  rejectionReasons?: string[];
  notified: boolean;
}
// Approval: ingestionValid && safetyVerdict === 'pass' && qualityScore >= 0.6
// Human review: safetyVerdict === 'flag'
// Rejection: ingestionInvalid || safetyVerdict === 'reject' || qualityScore < 0.6
```

---

## Data model changes

```typescript
// Additions to MarketplaceListingDoc
interface MarketplaceListingDoc {
  // existing fields …
  certificationStatus:
    | 'draft'
    | 'pending_review'
    | 'approved'
    | 'rejected'
    | 'pending_human_review';
  certificationReviewedAt: string | null;
  certificationReasons: string[];
  certificationQualityScore: number | null;
  certificationSafetyVerdict: 'pass' | 'flag' | 'reject' | null;
}
```

---

## Error handling

- Pipeline halts and returns `pending_human_review` if `ContentSafetyAgent` returns `flag`.
- Pipeline retries `QualityEvalAgent` once on network error; on second failure, logs and continues with `score: null` → human review.
- All agent results are stored on the listing doc for audit trail.
- Author always receives a notification (approved / rejected / pending).

---

## MCP tool surface

```typescript
jarvisjr.marketplace.submitForReview(listingId: string): CertificationResult
jarvisjr.marketplace.getCertificationStatus(listingId: string): CertificationStatus
jarvisjr.marketplace.listPendingReview(limit?: number): MarketplaceListingDoc[]
```

---

## Implementation checklist

- [ ] `SubmissionIngestionAgent` — validate required fields against schema
- [ ] `ContentSafetyAgent` — call extraction-service `triage` task, map classes to policy
- [ ] `QualityEvalAgent` — `POST /jarvis/sessions/eval` internal endpoint + scoring logic
- [ ] `CertificationDecisionAgent` — decision tree + `PUT /marketplace/listings/:id` update
- [ ] `POST /marketplace/listings/:id/submit-for-review` trigger endpoint
- [ ] MCP tool registrations in `backend/src/modules/marketplace/routes.ts`
- [ ] Author notification via `platform-service /push-triggers`
