{
  "document": {
    "id": "STORY-PACK-001",
    "version": "1.0.0",
    "status": "draft",
    "title": "Harbor Lantern support-request backlog",
    "productRequirementRefs": ["PRD-EXAMPLE-001"],
    "owner": "Product owner",
    "reviewedAt": "2026-08-01",
    "fictionalExample": true,
    "boundaries": {
      "isProductRequirementsDocument": false,
      "isUatSignoff": false,
      "guaranteesDelivery": false,
      "containsProductionData": false
    }
  },
  "definitions": {
    "ready": {
      "id": "READY-001",
      "statement": "A story may enter implementation only when the product intent is linked and the team can test the observable outcome without inventing policy.",
      "checks": [
        {
          "id": "READY-CHECK-001",
          "text": "Actor, context, need, observable outcome, and value are specific.",
          "evidenceRequired": "Reviewed story fields"
        },
        {
          "id": "READY-CHECK-002",
          "text": "Acceptance examples cover the important success or failure boundary.",
          "evidenceRequired": "Linked acceptance example IDs"
        },
        {
          "id": "READY-CHECK-003",
          "text": "Dependencies and risks resolve to owned records.",
          "evidenceRequired": "Linked dependency and risk IDs"
        },
        {
          "id": "READY-CHECK-004",
          "text": "Open product-policy questions have an owner or block implementation.",
          "evidenceRequired": "Decision owner or explicit blocker"
        }
      ]
    },
    "done": {
      "id": "DONE-001",
      "statement": "A story is done only when its acceptance examples pass in the intended environment and evidence is linked without treating delivery as product success or release approval.",
      "checks": [
        {
          "id": "DONE-CHECK-001",
          "text": "Each linked acceptance example has current test evidence.",
          "evidenceRequired": "Test result or reviewed observation"
        },
        {
          "id": "DONE-CHECK-002",
          "text": "Authorization, invalid input, retry, conflict, and recovery boundaries relevant to the story were checked.",
          "evidenceRequired": "Boundary test references"
        },
        {
          "id": "DONE-CHECK-003",
          "text": "Monitoring and rollback ownership are recorded for changed production behavior.",
          "evidenceRequired": "Named owner and recovery reference"
        },
        {
          "id": "DONE-CHECK-004",
          "text": "The story result is not presented as PRD approval, UAT signoff, adoption, or business success.",
          "evidenceRequired": "Release decision remains outside this pack"
        }
      ]
    }
  },
  "stories": [
    {
      "id": "US-001",
      "title": "Submit one support request",
      "actor": {
        "role": "Signed-in requester",
        "context": "A member of the fictional Harbor Lantern workspace needs help with an internal service"
      },
      "need": "Submit a request with a category, title, and description",
      "outcome": {
        "observable": "The requester sees one stable request ID and the submitted request in the workspace list",
        "evidence": "Browser test checks the returned ID and list row"
      },
      "value": "The requester can refer to one durable request instead of repeating the issue in messages",
      "acceptanceExampleIds": ["AE-001", "AE-002"],
      "dependencyIds": [],
      "riskIds": ["RISK-001"],
      "readyBoundaryId": "READY-001",
      "doneBoundaryId": "DONE-001",
      "status": "ready",
      "owner": "Product owner"
    },
    {
      "id": "US-002",
      "title": "Correct an invalid request",
      "actor": {
        "role": "Signed-in requester",
        "context": "The requester submits an incomplete or malformed support request"
      },
      "need": "See field-specific validation without losing valid input",
      "outcome": {
        "observable": "The requester sees the rejected fields, keeps valid values, and no request ID is created",
        "evidence": "Browser and API tests compare the form state and request count"
      },
      "value": "The requester can fix the request without creating unusable records",
      "acceptanceExampleIds": ["AE-003", "AE-004"],
      "dependencyIds": [],
      "riskIds": ["RISK-001"],
      "readyBoundaryId": "READY-001",
      "doneBoundaryId": "DONE-001",
      "status": "ready",
      "owner": "Product owner"
    },
    {
      "id": "US-003",
      "title": "Resolve a stale status update",
      "actor": {
        "role": "Support coordinator",
        "context": "Two coordinators opened the same request before either changed its status"
      },
      "need": "Avoid overwriting a newer decision with a stale edit",
      "outcome": {
        "observable": "The second coordinator sees a conflict with the current version and can reload before deciding again",
        "evidence": "Concurrency test asserts one accepted version and one conflict response"
      },
      "value": "The team preserves the latest reviewed state and can explain why an update was rejected",
      "acceptanceExampleIds": ["AE-005", "AE-006"],
      "dependencyIds": ["DEP-001"],
      "riskIds": ["RISK-002"],
      "readyBoundaryId": "READY-001",
      "doneBoundaryId": "DONE-001",
      "status": "ready",
      "owner": "Workflow owner"
    },
    {
      "id": "US-004",
      "title": "Retry a timed-out submission",
      "actor": {
        "role": "Signed-in requester",
        "context": "The network times out after the service may already have saved the request"
      },
      "need": "Retry the same submission without creating a duplicate request",
      "outcome": {
        "observable": "The retry returns the original request ID and the workspace list contains one matching request",
        "evidence": "Retry test compares both responses and the persisted request count"
      },
      "value": "The requester can recover from uncertainty without creating duplicate work",
      "acceptanceExampleIds": ["AE-007", "AE-008"],
      "dependencyIds": ["DEP-002"],
      "riskIds": ["RISK-003"],
      "readyBoundaryId": "READY-001",
      "doneBoundaryId": "DONE-001",
      "status": "ready",
      "owner": "Technical owner"
    },
    {
      "id": "US-005",
      "title": "Deny cross-workspace request access",
      "actor": {
        "role": "Signed-in member of another workspace",
        "context": "The member guesses or receives a request ID that belongs to Harbor Lantern"
      },
      "need": "Remain unable to read or change a request outside the active workspace",
      "outcome": {
        "observable": "The member receives the same bounded denial for read and update attempts without request details",
        "evidence": "Two-account authorization test checks read, update, response shape, and audit record"
      },
      "value": "Workspace request details stay available only to authorized members",
      "acceptanceExampleIds": ["AE-009", "AE-010"],
      "dependencyIds": ["DEP-003"],
      "riskIds": ["RISK-004"],
      "readyBoundaryId": "READY-001",
      "doneBoundaryId": "DONE-001",
      "status": "ready",
      "owner": "Security reviewer"
    }
  ],
  "acceptanceExamples": [
    {
      "id": "AE-001",
      "storyId": "US-001",
      "kind": "happy",
      "given": "A signed-in requester belongs to workspace WRK-001 and the request form is valid",
      "when": "The requester submits the form once",
      "then": "The response and workspace list show the same new USREQ-prefixed request ID",
      "evidenceOwner": "QA owner"
    },
    {
      "id": "AE-002",
      "storyId": "US-001",
      "kind": "recovery",
      "given": "The request was saved but the optional notification adapter is unavailable",
      "when": "The requester opens the workspace request list",
      "then": "The request remains visible with a pending-notification state and no delivery claim",
      "evidenceOwner": "Workflow owner"
    },
    {
      "id": "AE-003",
      "storyId": "US-002",
      "kind": "invalid",
      "given": "The title is blank and the description is valid",
      "when": "The requester submits the form",
      "then": "The title error is visible, the description remains, and no request ID exists",
      "evidenceOwner": "QA owner"
    },
    {
      "id": "AE-004",
      "storyId": "US-002",
      "kind": "invalid",
      "given": "The category is not in the server allowlist",
      "when": "The API receives the request",
      "then": "The server rejects the category without saving a partial request",
      "evidenceOwner": "Technical owner"
    },
    {
      "id": "AE-005",
      "storyId": "US-003",
      "kind": "conflict",
      "given": "Two coordinators loaded request USREQ-001 at version 4",
      "when": "Both submit different status changes with expected version 4",
      "then": "One update creates version 5 and the other returns the current version as a conflict",
      "evidenceOwner": "Technical owner"
    },
    {
      "id": "AE-006",
      "storyId": "US-003",
      "kind": "happy",
      "given": "A coordinator reloads the current request after a conflict",
      "when": "The coordinator reviews version 5 and submits a valid next transition",
      "then": "The interface shows version 6 and an audit event linked to the coordinator",
      "evidenceOwner": "Workflow owner"
    },
    {
      "id": "AE-007",
      "storyId": "US-004",
      "kind": "retry",
      "given": "The first valid submission saved USREQ-002 but the response timed out",
      "when": "The requester repeats the exact body with the same retry key",
      "then": "The service returns USREQ-002 and the request count remains one",
      "evidenceOwner": "Technical owner"
    },
    {
      "id": "AE-008",
      "storyId": "US-004",
      "kind": "invalid",
      "given": "A retry key is already bound to the first request body",
      "when": "The requester reuses the key with a changed title",
      "then": "The service returns a conflict and does not create or change a request",
      "evidenceOwner": "Technical owner"
    },
    {
      "id": "AE-009",
      "storyId": "US-005",
      "kind": "authorization",
      "given": "A member of workspace WRK-002 has the request ID USREQ-001 from workspace WRK-001",
      "when": "The member requests the detail route",
      "then": "The response reveals no title, description, actor, status, or workspace detail",
      "evidenceOwner": "Security reviewer"
    },
    {
      "id": "AE-010",
      "storyId": "US-005",
      "kind": "authorization",
      "given": "The same WRK-002 member submits an update for USREQ-001",
      "when": "The server derives workspace scope from the signed-in session",
      "then": "The update is denied, the request version is unchanged, and the denial is audited without sensitive detail",
      "evidenceOwner": "Security reviewer"
    }
  ],
  "dependencies": [
    {
      "id": "DEP-001",
      "predecessorId": "US-001",
      "successorId": "US-003",
      "reason": "A durable versioned request must exist before status conflicts can be exercised."
    },
    {
      "id": "DEP-002",
      "predecessorId": "US-001",
      "successorId": "US-004",
      "reason": "The base submission identity defines the retry fingerprint and original request ID."
    },
    {
      "id": "DEP-003",
      "predecessorId": "US-001",
      "successorId": "US-005",
      "reason": "A workspace-owned request is required before cross-workspace denial can be verified."
    }
  ],
  "risks": [
    {
      "id": "RISK-001",
      "storyIds": ["US-001", "US-002"],
      "trigger": "Client-only validation or a partial save permits an unusable request",
      "effect": "The requester sees success while operators receive incomplete work",
      "response": "Keep authoritative server validation and save one complete request or none",
      "owner": "Technical owner",
      "status": "open"
    },
    {
      "id": "RISK-002",
      "storyIds": ["US-003"],
      "trigger": "A stale status update overwrites a newer reviewed transition",
      "effect": "The current decision and audit history become misleading",
      "response": "Require an expected version and return a reviewable conflict",
      "owner": "Workflow owner",
      "status": "open"
    },
    {
      "id": "RISK-003",
      "storyIds": ["US-004"],
      "trigger": "A timed-out client retries without a stable request fingerprint",
      "effect": "The workspace receives duplicate support requests",
      "response": "Bind one retry key to one actor, route, and normalized request body",
      "owner": "Technical owner",
      "status": "open"
    },
    {
      "id": "RISK-004",
      "storyIds": ["US-005"],
      "trigger": "Authorization trusts a request ID or client-provided workspace ID",
      "effect": "A member can read or change another workspace's request",
      "response": "Derive scope from the session and test with two ordinary accounts",
      "owner": "Security reviewer",
      "status": "open"
    }
  ]
}
