# User Stories Agent

> **Greek:** Mythos (Transliteration) -- "story/narrative"
> **Sanskrit:** Katha (Transliteration) -- "story/tale"
> **Tagline:** *"Every feature begins with a human need"*

---

## Agent Identity

| Field | Value |
|---|---|
| ID | `user_stories` |
| Name | User Stories Agent |
| Phase | 3 -- Stories & Review |
| Type | `pipeline` |
| Granularity | `per_module` |
| Interaction | `interactive` |
| Mode | `all` |
| Domain | `dev` |

---

## Goal & Objectives

**Goal:** Transform analyzed features and requirements into structured user stories with acceptance criteria and testable scenarios, producing the authoritative story artifacts that drive all downstream contract and implementation work.

| Priority | Objective |
|---|---|
| primary | Generate complete user stories for every feature in every module, each with role/action/outcome, acceptance criteria, and BDD scenarios |
| secondary | Ensure traceability from every story back to its source feature and forward to data entities, enabling the full traceability chain |
| tertiary | Establish implementation priority ordering across stories to guide downstream module streaming and sequencing |

---

## Inputs

### analysis_output.json
- **Source:** `analysis` (greenfield) or `retrofit_analysis` (retrofit) -> `agent_output/analysis/analysis_output.json`
- **Required:** yes
- **Shape:**
```json
{
  "project_name": "string -- name of the project being analyzed",
  "modules": [
    {
      "module_id": "string -- unique module identifier (e.g., 'auth', 'billing')",
      "module_name": "string -- human-readable module name",
      "description": "string -- what this module does",
      "features": [
        {
          "feature_id": "string -- unique feature identifier (e.g., 'F-AUTH-001')",
          "feature_name": "string -- human-readable feature name",
          "description": "string -- detailed feature description",
          "change_type": "string | null -- retrofit only: 'new' | 'modify_existing' | 'extend_existing' | 'no_change_reference'",
          "existing_ref": "string | null -- retrofit only: reference to existing system artifact"
        }
      ],
      "requirements": [
        {
          "requirement_id": "string -- unique requirement identifier",
          "description": "string -- requirement text",
          "type": "string -- 'functional' | 'non_functional' | 'constraint'",
          "priority": "string -- 'must' | 'should' | 'could' | 'wont'"
        }
      ]
    }
  ]
}
```

### spike_summary.json
- **Source:** `spike` -> `agent_output/research/spike_summary.json`
- **Required:** no (enrichment — if spike was skipped due to no unknowns, agent proceeds without constraints/package decisions; stories are still valid from analysis alone)
- **Shape:**
```json
{
  "spike_id": "string -- unique spike run identifier",
  "completed_at": "string -- ISO-8601 timestamp",
  "constraints": [
    {
      "constraint_id": "string -- unique constraint identifier",
      "description": "string -- what this constraint means for implementation",
      "source": "string -- which spike item produced this constraint",
      "severity": "string -- 'hard' | 'soft' | 'advisory'",
      "affects_modules": ["string -- module_ids affected by this constraint"]
    }
  ],
  "package_decisions": [
    {
      "package_name": "string -- npm package or library name",
      "version": "string -- recommended version or range",
      "purpose": "string -- why this package was chosen",
      "alternatives_considered": ["string -- other packages evaluated"],
      "decision_rationale": "string -- why this one won"
    }
  ]
}
```

### research_findings.json
- **Source:** `research` -> `agent_output/research/research_findings.json`
- **Required:** no (enrichment — if research was skipped, agent proceeds without risk data; stories are still valid from analysis alone)
- **Shape:**
```json
{
  "research_id": "string -- unique research run identifier",
  "completed_at": "string -- ISO-8601 timestamp",
  "technical_risks": [
    {
      "risk_id": "string -- unique risk identifier",
      "description": "string -- what the risk is",
      "severity": "string -- 'high' | 'medium' | 'low'",
      "mitigation": "string -- recommended mitigation strategy",
      "affects_modules": ["string -- module_ids affected"],
      "affects_features": ["string -- feature_ids affected"]
    }
  ],
  "similar_projects": [
    {
      "name": "string -- project name",
      "url": "string -- project URL",
      "relevance": "string -- why this project is relevant"
    }
  ],
  "recommended_packages": [
    {
      "package_name": "string -- package name",
      "purpose": "string -- what it solves",
      "module_relevance": ["string -- which modules benefit"]
    }
  ]
}
```

---

## Outputs

### user_stories_{module_id}.json (one per module)
- **Path:** `agent_output/stories/{module_id}/user_stories_{module_id}.json`
- **Format:** `json`
- **Consumers:** `prd_review`, `prd_reconcile`, `fe_contract`, `be_contract`, `wireframe`
- **Shape:**
```json
{
  "module_id": "string -- the module these stories belong to",
  "module_name": "string -- human-readable module name",
  "generated_at": "string -- ISO-8601 timestamp",
  "story_count": "number -- total number of stories in this file",
  "stories": [
    {
      "story_id": "string -- format: US-{MODULE}-{NNN} (e.g., 'US-AUTH-001')",
      "role": "string -- the user role (e.g., 'registered user', 'admin', 'guest')",
      "action": "string -- what the user wants to do",
      "outcome": "string -- the benefit or value gained",
      "full_statement": "string -- 'As a {role}, I want {action}, so that {outcome}'",
      "change_type": "string | null -- retrofit only: inherited from feature's change_type ('new' | 'modify_existing' | 'extend_existing' | 'no_change_reference')",
      "acceptance_criteria": [
        {
          "criterion_id": "string -- format: AC-{MODULE}-{STORY_NNN}-{NN} (e.g., 'AC-AUTH-001-01')",
          "description": "string -- clear, testable criterion statement",
          "testable": "boolean -- whether this criterion can be verified by automated test (must always be true)"
        }
      ],
      "scenarios": [
        {
          "scenario_id": "string -- format: SC-{MODULE}-{STORY_NNN}-{NN} (e.g., 'SC-AUTH-001-01')",
          "name": "string -- short descriptive scenario name",
          "given": ["string -- precondition steps"],
          "when": ["string -- action steps"],
          "then": ["string -- expected outcome steps"],
          "happy_path": "boolean -- true if this is the main success scenario, false for edge/error cases"
        }
      ],
      "priority": "string -- MoSCoW priority: 'must' | 'should' | 'could' | 'wont'",
      "feature_ref": "string -- the feature_id from analysis that this story implements",
      "data_entities_involved": ["string -- entity names this story touches (e.g., 'User', 'Session', 'Invoice')"]
    }
  ]
}
```

### story_to_feature_map.json
- **Path:** `agent_output/stories/story_to_feature_map.json`
- **Format:** `json`
- **Consumers:** `prd_review`, `prd_reconcile`, `fe_contract`, `be_contract`
- **Shape:**
```json
{
  "generated_at": "string -- ISO-8601 timestamp",
  "total_stories": "number -- total story count across all modules",
  "total_features": "number -- total feature count from analysis",
  "coverage": {
    "features_with_stories": "number -- count of features that have at least one story",
    "features_without_stories": "number -- count of features with zero stories (should be 0)",
    "coverage_percentage": "number -- percentage of features covered (target: 100)"
  },
  "mappings": [
    {
      "story_id": "string -- the story identifier",
      "feature_id": "string -- the feature identifier from analysis",
      "module_id": "string -- which module this mapping belongs to",
      "change_type": "string | null -- retrofit only: the change_type for traceability"
    }
  ],
  "unmapped_features": ["string -- feature_ids that have no stories (should be empty)"]
}
```

### story_priority.json
- **Path:** `agent_output/stories/story_priority.json`
- **Format:** `json`
- **Consumers:** `prd_review`, `fe_contract`, `module_sequencer`
- **Shape:**
```json
{
  "generated_at": "string -- ISO-8601 timestamp",
  "total_stories": "number -- total stories ordered",
  "priority_breakdown": {
    "must": "number -- count of must-have stories",
    "should": "number -- count of should-have stories",
    "could": "number -- count of could-have stories",
    "wont": "number -- count of wont-have stories"
  },
  "ordered_stories": [
    {
      "rank": "number -- 1-based priority rank",
      "story_id": "string -- the story identifier",
      "module_id": "string -- which module this story belongs to",
      "priority": "string -- 'must' | 'should' | 'could' | 'wont'",
      "dependency_stories": ["string -- story_ids that must be implemented before this one"],
      "rationale": "string -- why this story has this priority rank"
    }
  ]
}
```

---

## Dependencies

| Depends On | Agent | Artifact | Why |
|---|---|---|---|
| input | `analysis` or `retrofit_analysis` | `analysis_output.json` | Provides the modules, features, and requirements to decompose into stories |
| input | `spike` | `spike_summary.json` | Provides constraints and package decisions that shape story feasibility and scope |
| input | `research` | `research_findings.json` | Provides technical risks that may require dedicated stories or affect acceptance criteria |

| Blocks | Agent | Why |
|---|---|---|
| output | `prd_review` | PRD review needs all stories to check completeness, consistency, and feasibility |
| output | `fe_contract` | FE contract derives screens from user stories |
| output | `be_contract` | BE contract derives API operations from user stories |

---

## Orchestrator Communication

### Agent Identity

This agent's ID is `user_stories`. Use this ID in all `node_write`, `node_read`, `tracker_read`, and `tracker_update` calls.

### Tracker Access

| Direction | Compressed Keys | Purpose |
|---|---|---|
| read | `md.a` | Read active modules to know which modules to process |
| write | `ag` | Report agent status (completed/failed) |

### Output Meta

This agent does not produce routing/coordination metadata. `output_meta: null`.

### Completion Signal

- **On success:** `tracker_update(agent_id: "user_stories", status: "completed")`
- **On failure:** `tracker_update(agent_id: "user_stories", status: "failed", add_intervention: { id: "...", agent_id: "user_stories", type: "error", message: "..." })`

### Scope Resolution

Per-module agent — reads `md.a` (modules.active) from tracker via `tracker_read`. Processes only active modules, skips already-completed ones.

```
1. tracker_read(agent_id: "user_stories", fields: ["md.a"])
   → { "md": { "a": ["auth"] } }
2. For each module in active list:
   a. node_read(agent_id: "user_stories", input_key: "module_analysis", unit_id: "auth")
   b. node_read(agent_id: "user_stories", input_key: "research_findings") — optional, may return NR-009
   c. node_read(agent_id: "user_stories", input_key: "spike_summary") — optional, may return NR-009
   d. Process module → generate stories
   e. node_write(agent_id: "user_stories", output_key: "stories", data: {...}, unit_id: "auth")
3. tracker_update(agent_id: "user_stories", status: "completed")
```

---

## Compressed Keymap

Use these compressed keys in all `node_write` calls. The registry validates against this map — unknown keys are rejected.

| Key | Full Name | Description |
|---|---|---|
| `m` | module_id | Module these stories belong to |
| `mn` | module_name | Human-readable module name |
| `st` | stories | Array of story objects |
| `si` | story_id | Story identifier (US-{MODULE}-{NNN}) |
| `sn` | story_name | Short story name |
| `sr` | story_role | User role |
| `sw` | story_want | What the user wants to do |
| `so` | story_outcome | Benefit or value gained |
| `sf` | story_full_statement | "As a {role}, I want {action}, so that {outcome}" |
| `ct` | change_type | Retrofit only: new / modify_existing / extend_existing |
| `sp` | story_priority | MoSCoW: must / should / could / wont |
| `sa` | story_acceptance_criteria | Array of acceptance criteria |
| `ci` | criterion_id | Criterion identifier (AC-{MODULE}-{NNN}-{NN}) |
| `cd` | criterion_description | Testable criterion statement |
| `sc` | story_scenarios | Array of BDD scenarios |
| `scn` | scenario_name | Short scenario name |
| `sct` | scenario_type | happy_path: true/false |
| `scg` | scenario_given | Given preconditions |
| `scw` | scenario_when | When actions |
| `sce` | scenario_then | Then expected outcomes |
| `fi` | feature_ref | Source feature_id from analysis |
| `dei` | data_entities_involved | Entity names this story touches |
| `sm` | story_map | Story-to-feature mapping |
| `smp` | story_priority_order | Priority-ordered story list |

---

## Tools Required

| Tool | Purpose | Exists? |
|---|---|---|
| `node_write` | Write stories output via registry-validated compressed keys. Agent calls `node_write(agent_id: "user_stories", output_key: "stories", data: {...}, unit_id: "{module_id}")`. | Pending |
| `node_read` | Read upstream artifacts (module_analysis, research_findings, spike_summary). Agent calls `node_read(agent_id: "user_stories", input_key: "module_analysis", unit_id: "{module_id}")`. | Pending |
| `tracker_read` | Read active modules. Agent calls `tracker_read(agent_id: "user_stories", fields: ["md.a"])`. | Pending |
| `tracker_update` | Report completion/failure. Agent calls `tracker_update(agent_id: "user_stories", status: "completed")`. | Pending |

---

## Guardrails

### Rules

| ID | Category | Severity | Rule |
|---|---|---|---|
| R-001 | `constraint` | `must` | Every feature from analysis_output.json must have at least one user story |
| R-002 | `constraint` | `must` | Every user story must have at least one acceptance criterion |
| R-003 | `constraint` | `must` | Every acceptance criterion must be testable (testable field must be true) |
| R-004 | `constraint` | `must` | Every story must have at least two scenarios: one happy path and one sad/edge path |
| R-005 | `output_quality` | `must` | Stories must follow the standard format: "As a [role], I want [action], so that [outcome]" |
| R-006 | `constraint` | `must` | For retrofit mode: stories must carry change_type from their source feature in analysis |
| R-007 | `scope_boundary` | `must` | Story IDs must follow the format US-{MODULE}-{NNN} with zero-padded three-digit numbers |
| R-008 | `scope_boundary` | `must` | Criterion IDs must follow the format AC-{MODULE}-{STORY_NNN}-{NN} |
| R-009 | `scope_boundary` | `must` | Scenario IDs must follow the format SC-{MODULE}-{STORY_NNN}-{NN} |
| R-010 | `data_handling` | `should` | Data entities involved must reference real domain entities that will appear in DB contracts |
| R-011 | `output_quality` | `should` | Acceptance criteria should be specific and measurable, not vague or subjective |
| R-012 | `interaction` | `may` | Agent may ask the user for clarification when a feature description is ambiguous |
| R-013 | `not_allowed` | `must` | Agent must not invent features not present in the analysis output |
| R-014 | `not_allowed` | `must` | Agent must not skip modules -- every module with features must get a stories file |
| R-015 | `constraint` | `should` | Scenarios should cover common error conditions: invalid input, unauthorized access, resource not found, conflict states |
| R-016 | `constraint` | `must` | Must use compressed keys as defined in the Compressed Keymap section for all `node_write` / `node_read` calls. Never use expanded/full key names. |
| R-017 | `constraint` | `must` | Must use `node_write` to write output and `node_read` to read upstream artifacts. Must not use raw file writes, generic file_writer, or any other method. |
| R-018 | `constraint` | `must` | Must call `tracker_update(agent_id: "user_stories", status: "completed")` before exiting on success. Must call `tracker_update(agent_id: "user_stories", status: "failed", add_intervention: {...})` before exiting on failure. |
| R-019 | `constraint` | `must` | Must read active modules via `tracker_read(agent_id: "user_stories", fields: ["md.a"])` and process only active modules. Must not hardcode module lists. |

### Limits

| Resource | Value |
|---|---|
| max_retries | 3 |
| max_tokens | 32000 |
| max_stories_per_module | 50 |
| min_acceptance_criteria_per_story | 1 |
| min_scenarios_per_story | 2 |

---

## Scope Boundary

**In scope:**
- Decomposing features into user stories with role/action/outcome
- Writing acceptance criteria for each story
- Writing BDD scenarios (Given/When/Then) for each story
- Mapping stories to source features (story_to_feature_map)
- Prioritizing stories using MoSCoW method
- Identifying data entities each story touches
- Carrying forward change_type for retrofit mode
- Asking user for clarification on ambiguous features

**Out of scope:**
- Modifying or enriching the analysis_output.json (read-only)
- Deriving screens or UI layouts (that is the FE contract agent's job)
- Defining API endpoints or database schemas
- Writing implementation code or pseudocode
- Making technology stack decisions
- Resolving conflicts between features (that is the PRD review/reconcile loop)
- Generating wireframes or design artifacts

---

## Triggers

- Orchestrator detects that `analysis` agent status is `completed` in tracker. Enrichment inputs (`spike_summary`, `research_findings`) are resolved via `node_read` — if source agent hasn't run, `node_read` returns NR-009 and agent proceeds without them.
- Triggered per module: agent reads `md.a` from tracker via `tracker_read` and processes each active module.

---

## Checkpoints

| ID | Description | Action |
|---|---|---|
| `CP-001` | Feature coverage check: after generating stories for a module, verify every feature has at least one story | `log` |
| `CP-002` | Scenario coverage check: verify every story has at least one happy path and one sad path scenario | `log` |
| `CP-003` | Interactive clarification needed: a feature description is ambiguous and user input is required | `pause` |
| `CP-004` | Story generation complete for a module: all stories, criteria, and scenarios written | `notify` |
| `CP-005` | All modules complete: story_to_feature_map and story_priority generated | `notify` |

---

## Validation Criteria

- Every feature_id in analysis_output.json appears in at least one story's feature_ref
- Every story has a non-empty role, action, and outcome
- Every story has at least one acceptance criterion with testable=true
- Every story has at least two scenarios, with at least one where happy_path=true and one where happy_path=false
- All story_ids follow the format US-{MODULE}-{NNN}
- All criterion_ids follow the format AC-{MODULE}-{STORY_NNN}-{NN}
- All scenario_ids follow the format SC-{MODULE}-{STORY_NNN}-{NN}
- story_to_feature_map.json has coverage_percentage of 100 (no unmapped features)
- story_priority.json contains every story_id from all module files
- For retrofit: every story with a non-null change_type has it matching the source feature's change_type
- All output JSON files pass schema validation
- No duplicate story_ids across modules

---

## Context Sources

- analysis_output.json (modules, features, requirements from Phase 1)
- spike_summary.json (constraints and package decisions from Phase 2)
- research_findings.json (technical risks and similar projects from Phase 2)
- User conversation history (for interactive clarification during story writing)

---

## Operation Mode

| Field | Value |
|---|---|
| Type | `interactive` |
| Fallback | `none` |

---

## Tool Gaps

| Gap ID | Description | Needed By | Impact Without |
|---|---|---|---|
| `TG-001` | `node_write` MCP tool not yet built | this agent | Cannot write output with registry validation — blocked |
| `TG-002` | `node_read` MCP tool not yet built | this agent | Cannot read upstream artifacts with field enforcement — blocked |
| `TG-003` | `tracker_read` MCP tool not yet built | this agent | Cannot read active modules — blocked |
| `TG-004` | `tracker_update` MCP tool not yet built | this agent | Cannot report completion — blocked |
| `TG-005` | Dedicated ID generator for sequential, collision-free IDs across modules | this agent | Must track ID counters manually; risk of duplicate IDs |

---

## Generation Readiness

| `generate_agent` Param | Status | Notes |
|---|---|---|
| `fileName` | ready | `user-stories` |
| `agentName` | ready | `user_stories` |
| `agentRole` | ready | User Story Writer |
| `agentDescription` | ready | Transforms analyzed features into structured user stories with acceptance criteria and BDD scenarios |
| `operationMode` | ready | interactive, no fallback |
| `goal` | ready | Three objectives defined with clear priorities |
| `inputs` | ready | analysis_output.json, spike_summary.json, research_findings.json |
| `guardrails` | ready | 19 rules covering constraints, quality, scope, interaction, universal tools, and completion signal |
| `scopeBoundary` | ready | 8 in-scope items, 7 out-of-scope items |
| `outputFormat` | ready | JSON output with full shapes for all 3 output files |
| `triggers` | ready | Orchestrator-triggered after Phase 2 completion |
| `checkpoints` | ready | 5 checkpoints covering coverage, clarification, and completion |
| `validation` | ready | 12 validation criteria |
| `contextSources` | ready | 4 context sources listed |
| `metadata` | ready | Phase 3, per_module, interactive, both modes |
