feat: add diagnostic interview loop

This commit is contained in:
user
2026-04-26 16:24:35 +09:00
parent 0e232ff405
commit 4a4240fea2
21 changed files with 926 additions and 23 deletions

View File

@@ -18,12 +18,12 @@ interview-ready after each short practice loop.
### Interview Practice
- [ ] **INT-01**: User can select target role, stack, and interview timeline.
- [ ] **INT-02**: User can complete a diagnostic technical interview.
- [ ] **INT-03**: System can generate role-specific interview questions.
- [ ] **INT-04**: System can grade user answers against explicit rubrics.
- [ ] **INT-05**: System can ask targeted follow-up questions for weak answers.
- [ ] **INT-06**: System preserves original answers and grading evidence.
- [x] **INT-01**: User can select target role, stack, and interview timeline.
- [x] **INT-02**: User can complete a diagnostic technical interview.
- [x] **INT-03**: System can generate role-specific interview questions.
- [x] **INT-04**: System can grade user answers against explicit rubrics.
- [x] **INT-05**: System can ask targeted follow-up questions for weak answers.
- [x] **INT-06**: System preserves original answers and grading evidence.
### Learner Memory
@@ -95,7 +95,7 @@ interview-ready after each short practice loop.
| Requirement | Phase | Status |
|-------------|-------|--------|
| BACK-01..BACK-05 | Phase 1 | Complete |
| INT-01..INT-06 | Phase 2 | Pending |
| INT-01..INT-06 | Phase 2 | Complete |
| MEM-01..MEM-05 | Phase 3 | Pending |
| PROG-01..PROG-05 | Phase 4 | Pending |
| ONTO-01..ONTO-04 | Phase 5 | Pending |
@@ -108,4 +108,4 @@ interview-ready after each short practice loop.
---
*Requirements defined: 2026-04-26*
*Last updated: 2026-04-26 after Phase 1 execution.*
*Last updated: 2026-04-26 after Phase 2 execution.*

View File

@@ -7,7 +7,7 @@ See: `.planning/PROJECT.md` (updated 2026-04-26)
**Core value:** The user should feel and prove that they are becoming more
interview-ready after each short practice loop.
**Current focus:** Phase 2 planning: Diagnostic Interview Loop.
**Current focus:** Phase 3 planning: Learner Memory.
## Current Decisions
@@ -22,14 +22,16 @@ interview-ready after each short practice loop.
- First interview track is Backend Developer Interview.
- Phase 1 has context, research, and plan artifacts.
- Phase 1 Go backend scaffold is implemented and verified.
- Phase 2 diagnostic interview loop is implemented and verified with in-memory
sessions.
## Next Actions
1. Plan Phase 2 diagnostic interview loop with GSD.
1. Plan Phase 3 learner memory with GSD.
2. Keep `docs/planning/WORKFLOW_CONTRACTS.md` aligned with Go structs during
future workflow implementation.
3. Decide whether Phase 2 starts with in-memory diagnostic sessions or a small
persistence boundary.
3. Decide whether Phase 3 learner memory remains in-memory for MVP proof or
introduces a small persistence boundary.
## Validation Log
@@ -40,6 +42,9 @@ interview-ready after each short practice loop.
- 2026-04-26: Phase 1 implementation verified with `go test ./...`,
`openspec validate bootstrap-job-tutor-platform --strict`, and Go source
line-count check.
- 2026-04-26: Phase 2 implementation verified with `go test ./...`, live
`/healthz` smoke, live diagnostic create/answer/get smoke, OpenSpec, and Go
source line-count check.
---
*State initialized: 2026-04-26.*

View File

@@ -0,0 +1,93 @@
# Phase 2: Diagnostic Interview Loop - Context
**Gathered:** 2026-04-26
**Status:** Ready for planning
**Source:** GSD continuation after Phase 1 completion
<domain>
## Phase Boundary
Phase 2 proves the first job-seeker loop from target role/stack selection
through a graded diagnostic answer. It should create a thin backend product
surface for diagnostic sessions while avoiding persistent storage and real LLM
calls until later phases require them.
</domain>
<decisions>
## Implementation Decisions
### Persistence
- Use an in-memory session store in Phase 2.
- Do not add a database or migrations yet.
- Persisting original answers and grading evidence means preserving them inside
the in-memory diagnostic session record for this phase.
### Interview Track
- Use the Backend Developer Interview track from
`docs/planning/INTERVIEW_TRACKS.md`.
- Seed questions should cover the canonical concept clusters, starting with a
small representative set.
### Workflow Boundary
- Grading must go through the typed `workflows.Runner` interface.
- The default implementation can remain deterministic/stubbed, but it must
return typed `GradedAnswer` data rather than freeform prose.
- HTTP handlers must not shell out or parse arbitrary assistant text.
</decisions>
<canonical_refs>
## Canonical References
Downstream agents MUST read these before planning or implementing.
### Product and Track
- `docs/planning/PRD.md` - diagnostic interview product flow.
- `docs/planning/INTERVIEW_TRACKS.md` - first track and concept seed list.
- `docs/planning/WORKFLOW_CONTRACTS.md` - typed workflow result shape.
### Engineering and Requirements
- `docs/planning/ENGINEERING.md` - 600-line, SOLID, KISS, YAGNI constraints.
- `.planning/REQUIREMENTS.md` - INT-01 through INT-06 requirements.
- `.planning/ROADMAP.md` - Phase 2 goal and success criteria.
- `openspec/changes/bootstrap-job-tutor-platform/specs/job-seeker-tutor/spec.md`
- diagnostic and first-track requirements.
- `openspec/changes/bootstrap-job-tutor-platform/specs/tutor-workflows/spec.md`
- typed workflow requirements.
</canonical_refs>
<specifics>
## Specific Ideas
- Add `internal/interview` for sessions, questions, answers, and in-memory store.
- Add endpoints:
- `POST /api/v1/diagnostic-sessions`
- `GET /api/v1/diagnostic-sessions/{id}`
- `POST /api/v1/diagnostic-sessions/{id}/answers`
- Keep routing simple with standard library `http.ServeMux`.
- Add deterministic grading in the workflow stub so tests can prove typed
evidence is recorded.
</specifics>
<deferred>
## Deferred Ideas
- Real `third-one` grading execution.
- Database persistence.
- Authentication and user identity provider integration.
- Memory extraction and durable learner memory.
- Frontend UI.
</deferred>
---
*Phase: 002-diagnostic-interview-loop*
*Context gathered: 2026-04-26*

View File

@@ -0,0 +1,77 @@
# Phase 2 Plan: Diagnostic Interview Loop
**Status:** Ready for execution
**Phase Goal:** Prove the first job-seeker loop from role selection through
graded diagnostic interview.
## Requirements Covered
- INT-01: User can select target role, stack, and interview timeline.
- INT-02: User can complete a diagnostic technical interview.
- INT-03: System can generate role-specific interview questions.
- INT-04: System can grade user answers against explicit rubrics.
- INT-05: System can ask targeted follow-up questions for weak answers.
- INT-06: System preserves original answers and grading evidence.
## Tasks
### 1. Add interview domain package
- Create `internal/interview`.
- Define session, question, answer, and store types.
- Add in-memory store implementation.
- Add backend developer diagnostic question catalog.
### 2. Add diagnostic service
- Create session from target role, stack, and optional interview timeline.
- Select first diagnostic questions from the backend developer track.
- Record submitted answers.
- Invoke `workflows.Runner.GradeInterviewAnswer`.
- Attach typed grading result and evidence to the answer record.
### 3. Add HTTP endpoints
- `POST /api/v1/diagnostic-sessions`
- `GET /api/v1/diagnostic-sessions/{id}`
- `POST /api/v1/diagnostic-sessions/{id}/answers`
### 4. Extend workflow stub
- Return deterministic typed grades.
- Include follow-up recommendation for weak answers.
- Include evidence references.
### 5. Add tests
- Domain tests for session creation and answer grading.
- HTTP tests for create/get/answer flow.
- Existing config/workflow tests remain passing.
### 6. Update GSD/OpenSpec state
- Mark INT-01 through INT-06 complete if all success criteria pass.
- Add Phase 2 summary and verification artifacts.
## Verification
```powershell
gofmt -w cmd internal
go test ./...
openspec validate bootstrap-job-tutor-platform --strict
```
Run Go line-count check and confirm every manually authored Go file is at or
below 600 lines.
## Out of Scope
- Database persistence.
- Authentication.
- Real LLM grading.
- Durable learner memory.
- Progression map.
- Frontend.
---
*Plan created: 2026-04-26*

View File

@@ -0,0 +1,43 @@
# Phase 2 Research
## Question
How should the diagnostic interview loop be implemented while preserving the
Phase 1 typed workflow boundary and avoiding premature infrastructure?
## Findings
### In-memory persistence is enough for Phase 2
The goal is to prove request/response flow and evidence preservation. A database
would add migration, repository, and lifecycle complexity before the product loop
is proven. An in-memory store with clear interface boundaries keeps the future
database replacement straightforward.
### Standard library routing remains sufficient
The current backend already uses `http.ServeMux`. Phase 2 can add route patterns
with path variables using Go 1.23's standard mux support. No router dependency
is needed.
### Deterministic grading is acceptable as a workflow stub
Phase 2 requires typed grading through the workflow boundary. It does not require
live LLM grading. A deterministic stub can grade on answer length and preserve
evidence. This proves the product state flow and keeps live model integration
for a later phase.
### Keep interview domain separate from HTTP
`internal/interview` should own session creation, question catalog selection,
answer recording, and grade attachment. HTTP handlers should translate requests
and responses only.
## Recommendation
1. Add `internal/interview` domain service and in-memory store.
2. Add a small backend developer question catalog.
3. Add typed endpoints for creating/getting sessions and submitting answers.
4. Extend workflow stub to return deterministic `GradedAnswer`.
5. Add tests at domain and HTTP layers.
6. Verify with `go test ./...`, OpenSpec, and line-count checks.

View File

@@ -0,0 +1,50 @@
# Phase 2 Summary
**Status:** Complete
**Completed:** 2026-04-26
## Delivered
- Added in-memory diagnostic interview domain package.
- Added Backend Developer Interview seed question catalog.
- Added diagnostic session create/get/answer service.
- Added session status that becomes `complete` after all diagnostic questions
have answers.
- Added HTTP endpoints:
- `POST /api/v1/diagnostic-sessions`
- `GET /api/v1/diagnostic-sessions/{id}`
- `POST /api/v1/diagnostic-sessions/{id}/answers`
- Extended workflow stub to return deterministic typed grading results.
- Added grading evidence to `GradedAnswer`.
- Added domain, workflow, and HTTP flow tests.
## Files Added
- `internal/httpapi/diagnostic.go`
- `internal/httpapi/diagnostic_test.go`
- `internal/interview/catalog.go`
- `internal/interview/service.go`
- `internal/interview/service_test.go`
- `internal/interview/store.go`
- `internal/interview/types.go`
## Verification
```powershell
gofmt -w cmd internal
go test ./...
openspec validate bootstrap-job-tutor-platform --strict
```
Additional live smoke checks:
- `GET /healthz` returned status `ok`.
- Diagnostic create/answer/get flow returned a session id, 3 questions, a
`solid` typed grade, 1 evidence item, and 1 stored answer.
## Deferred
- Durable database persistence.
- Authentication.
- Real `third-one` grading calls.
- Learner memory extraction and readiness progression.

View File

@@ -0,0 +1,32 @@
# Phase 2 Verification
## Verdict
PASS
## Requirement Coverage
- INT-01: PASS. Diagnostic session request accepts target role, stack, and
interview timeline.
- INT-02: PASS. Diagnostic sessions can progress to `complete` after all seed
questions are answered.
- INT-03: PASS. Backend Developer Interview questions are generated from the
role-specific seed catalog.
- INT-04: PASS. Answers are graded through the typed workflow runner boundary.
- INT-05: PASS. Weak or partial answers receive typed follow-up recommendations.
- INT-06: PASS. Original answer text and grading evidence are preserved in the
in-memory session record.
## Evidence
- `go test ./...` passed.
- `openspec validate bootstrap-job-tutor-platform --strict` passed.
- Live `GET /healthz` smoke passed.
- Live diagnostic create/answer/get smoke passed.
- Go source line-count check passed.
## Residual Risk
Persistence is intentionally in-memory. Data is lost on process restart. Phase 3
should decide whether learner memory remains in-memory for proof or introduces a
small persistent boundary.