Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 188 additions & 0 deletions specs/multi-agent-pipeline/contracts/gaps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# API Contract: gaps

## applyr gaps save <offer_id> '<json>'

### Description
Save learning gaps for a job offer to the learning_gaps table.

### Request

**Positional Arguments:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| offer_id | integer | yes | ID of the offer |
| gaps_json | string | yes | JSON array of gap objects |

**JSON Schema:**

```json
{
"gaps": [
{
"topic": "tech_stack",
"gap_detail": "Missing LangChain and RAG experience",
"severity": "high",
"suggested_action": "Build a RAG project with LangChain"
}
]
}
```

| Field | Type | Required | Default | Values |
|-------|------|----------|---------|--------|
| topic | string | yes | — | tech_stack, projects, experience, education, english, cultural_fit |
| gap_detail | string | yes | — | Free text description |
| severity | string | no | "medium" | low, medium, high |
| suggested_action | string | no | null | Free text recommendation |

### Response

**Success (stdout):**

```
Saved 3 gaps for offer #42 (American Language Academy)
```

**Success (--json):**

```json
{
"offer_id": 42,
"gaps_saved": 3
}
```

**Error Codes:**

| Exit Code | Code | When |
|-----------|------|------|
| 1 | not_found | offer_id does not exist |
| 1 | missing_field | gaps array is empty or missing |
| 1 | invalid_value | topic or severity not in valid set |

---

## applyr gaps list [--topic <topic>] [--severity <severity>]

### Description
List learning gaps with optional filters.

### Request

**Flags:**

| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| --topic | string | no | all | Filter by topic |
| --severity | string | no | all | Filter by severity |
| --json | flag | no | false | Output as JSON |

### Response

**Success (stdout):**

```
Learning Gaps (5 total)

# Offer Topic Severity Gap Detail
1 American Language Academy tech_stack high Missing LangChain
2 American Language Academy english medium B1 level, needs B2
3 Google - Backend tech_stack high No GCP experience
4 Google - Backend experience medium Junior level expected
5 Startup XYZ projects low No open source contributions
```

**Success (--json):**

```json
{
"total": 5,
"gaps": [
{
"id": 1,
"offer_id": 42,
"offer_title": "Programador Junior E-Learning",
"company": "American Language Academy",
"topic": "tech_stack",
"gap_detail": "Missing LangChain",
"severity": "high",
"suggested_action": "Build a RAG project",
"created_at": "2026-08-09"
}
]
}
```

**Empty result:**

```
No learning gaps found.
```

---

## applyr gaps stats

### Description
Show summary statistics of learning gaps.

### Request

**Flags:**

| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| --json | flag | no | false | Output as JSON |

### Response

**Success (stdout):**

```
Learning Gaps Summary

Total gaps: 12

By Topic:
tech_stack 5 ██████████████
english 3 █████████
experience 2 ██████
projects 1 ███
cultural_fit 1 ███

By Severity:
high 6 ██████████████████
medium 4 ████████████
low 2 ██████

Top Gaps (by frequency):
1. Missing LangChain/RAG experience (3 offers)
2. English B1 needs B2 (3 offers)
3. No cloud platform experience (2 offers)
```

**Success (--json):**

```json
{
"total": 12,
"by_topic": {
"tech_stack": 5,
"english": 3,
"experience": 2,
"projects": 1,
"cultural_fit": 1
},
"by_severity": {
"high": 6,
"medium": 4,
"low": 2
},
"top_gaps": [
{"detail": "Missing LangChain/RAG experience", "count": 3},
{"detail": "English B1 needs B2", "count": 3},
{"detail": "No cloud platform experience", "count": 2}
]
}
```
143 changes: 143 additions & 0 deletions specs/multi-agent-pipeline/contracts/review-blind.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# API Contract: review-blind

## applyr cv review-blind <offer_id>

### Description
Independently evaluate cv-master.md against a job offer without referencing the Matcher's compatibility score.

### Authentication
None (local CLI).

### Request

**Positional Arguments:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| offer_id | integer | yes | ID of the offer to evaluate |

**Flags:**

| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| --json | flag | no | false | Output as JSON |

### Response

**Success (stdout):**

```
ATS Score: 74/100

Verdict: CLOSE MATCH

Strengths:
✓ Strong Python and FastAPI experience
✓ Relevant project portfolio

Weaknesses:
✗ No LangChain or RAG experience
✗ English level not demonstrated

Recommendations:
1. Add a LangChain project to your portfolio
2. Include English certification in CV
3. Highlight API design experience more prominently

Conditional Advice:
Consider applying if you:
- Highlight your Python API experience in the first paragraph
- Message the recruiter about your passion for AI tooling
```

**Success (--json):**

```json
{
"offer_id": 42,
"ats_score": 74,
"verdict": "CLOSE_MATCH",
"strengths": [
"Strong Python and FastAPI experience",
"Relevant project portfolio"
],
"weaknesses": [
"No LangChain or RAG experience",
"English level not demonstrated"
],
"recommendations": [
"Add a LangChain project to your portfolio",
"Include English certification in CV",
"Highlight API design experience more prominently"
],
"conditional_advice": {
"apply_with_conditions": true,
"conditions": [
"Highlight your Python API experience in the first paragraph",
"Message the recruiter about your passion for AI tooling"
]
}
}
```

**When verdict is NO_MATCH, conditional_advice is null:**

```json
{
"offer_id": 42,
"ats_score": 35,
"verdict": "NO_MATCH",
"strengths": ["Basic Python knowledge"],
"weaknesses": [
"Missing required React experience",
"No cloud infrastructure skills",
"English level below requirement"
],
"recommendations": [
"Build 2-3 React projects before applying",
"Study AWS or GCP fundamentals",
"Obtain B2+ English certification"
],
"conditional_advice": null
}
```

**When verdict is STRONG_MATCH, conditional_advice is null:**

```json
{
"offer_id": 42,
"ats_score": 85,
"verdict": "STRONG_MATCH",
"strengths": ["Expert in all required technologies"],
"weaknesses": [],
"recommendations": ["Consider adding metrics to project descriptions"],
"conditional_advice": null
}
```

**Error Codes:**

| Exit Code | Code | When |
|-----------|------|------|
| 1 | not_found | offer_id does not exist in DB |
| 1 | cv_master_missing | cv-master.md does not exist or is still template |
| 1 | db_error | Database cannot be opened |

### Verdict Logic

| Score Range | Verdict | conditional_advice |
|-------------|---------|-------------------|
| >= 80 | STRONG_MATCH | null |
| 60–79 | CLOSE_MATCH | {apply_with_conditions: true, conditions: [...]} |
| < 60 | NO_MATCH | null |

### AC Coverage

- AC-1: Blind Recruiter command — reads cv-master.md, evaluates independently
- AC-2: Verdict logic — classifies based on thresholds from config
- AC-3: Conditional advice — included only for CLOSE_MATCH
- AC-7: Reads cv-master.md directly — not the generated CV
- AC-8: Blind — does not load compatibility_pct from DB
- AC-E1: Missing offer → exit 1, code "not_found"
- AC-E2: Missing cv-master.md → exit 1, code "cv_master_missing"
Loading
Loading