diff --git a/specs/004-afraid-to-ask/checklists/requirements.md b/specs/004-afraid-to-ask/checklists/requirements.md new file mode 100644 index 0000000..5ce59a8 --- /dev/null +++ b/specs/004-afraid-to-ask/checklists/requirements.md @@ -0,0 +1,34 @@ +# Specification Quality Checklist: Afraid to Ask Feature + +**Purpose**: Validate specification completeness and quality before proceeding to planning +**Created**: October 13, 2025 +**Feature**: ../../specs/004-afraid-to-ask/spec.md + +## Content Quality + +- [x] No implementation details (languages, frameworks, APIs) +- [x] Focused on user value and business needs +- [x] Written for non-technical stakeholders +- [x] All mandatory sections completed + +## Requirement Completeness + +- [x] No [NEEDS CLARIFICATION] markers remain +- [x] Requirements are testable and unambiguous +- [x] Success criteria are measurable +- [x] Success criteria are technology-agnostic (no implementation details) +- [x] All acceptance scenarios are defined +- [x] Edge cases are identified +- [x] Scope is clearly bounded +- [x] Dependencies and assumptions identified + +## Feature Readiness + +- [x] All functional requirements have clear acceptance criteria +- [x] User scenarios cover primary flows +- [x] Feature meets measurable outcomes defined in Success Criteria +- [x] No implementation details leak into specification + +## Notes + +- Items marked incomplete require spec updates before `/speckit.clarify` or `/speckit.plan` \ No newline at end of file diff --git a/specs/004-afraid-to-ask/contracts/openapi.yaml b/specs/004-afraid-to-ask/contracts/openapi.yaml new file mode 100644 index 0000000..0bb5bcb --- /dev/null +++ b/specs/004-afraid-to-ask/contracts/openapi.yaml @@ -0,0 +1,93 @@ +openapi: 3.0.0 +info: + title: Agree-on-Desires API + version: 1.0.0 +paths: + /sessions/{sessionId}/responses: + post: + summary: Submit a user's response for a session, including "Afraid to Ask" ideas. + parameters: + - in: path + name: sessionId + required: true + schema: + type: string + description: The ID of the session. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + userId: + type: string + description: The ID of the user submitting the response. + wants: + type: array + items: + type: string + description: A list of ideas the user wants. + accepts: + type: array + items: + type: string + description: A list of ideas the user accepts. + afraidToAsk: + type: string + description: A sensitive idea the user is afraid to ask, to be processed privately. + required: + - userId + responses: + '200': + description: Response successfully submitted. + '400': + description: Invalid input. + '500': + description: Internal server error, or semantic matching service unavailable. + /sessions/{sessionId}/results: + get: + summary: Retrieve the harmonized results for a session. + parameters: + - in: path + name: sessionId + required: true + schema: + type: string + description: The ID of the session. + responses: + '200': + description: Session results retrieved successfully. + content: + application/json: + schema: + type: object + properties: + sessionId: + type: string + harmonizedIdeas: + type: array + items: + type: string + description: The list of harmonized ideas, including matched "Afraid to Ask" ideas. + '404': + description: Session not found. + '500': + description: Internal server error. + /sessions/{sessionId}/terminate: + post: + summary: Terminate a session and purge all associated "Afraid to Ask" data. + parameters: + - in: path + name: sessionId + required: true + schema: + type: string + description: The ID of the session to terminate. + responses: + '200': + description: Session terminated and data purged successfully. + '404': + description: Session not found. + '500': + description: Internal server error. diff --git a/specs/004-afraid-to-ask/data-model.md b/specs/004-afraid-to-ask/data-model.md new file mode 100644 index 0000000..b852d30 --- /dev/null +++ b/specs/004-afraid-to-ask/data-model.md @@ -0,0 +1,30 @@ +# Data Model: Afraid to Ask Feature + +**Feature Branch**: `004-afraid-to-ask` +**Date**: October 13, 2025 +**Spec**: ../../specs/004-afraid-to-ask/spec.md + +## Entities + +### User Idea + +Represents a user's desire or input within a session. + +- **id**: Unique identifier for the idea (string) +- **content**: The text of the idea (string) +- **type**: The category of the idea (enum: `Want`, `Accept`, `AfraidToAsk`) +- **userId**: The ID of the user who submitted the idea (string) +- **sessionId**: The ID of the session the idea belongs to (string) + +**Note**: A single `AfraidToAsk` input field may contain one or multiple distinct ideas, which will be processed semantically. + +### Session + +A collection of user ideas and their matching results, along with associated metadata. + +- **id**: Unique identifier for the session (string) +- **status**: Current status of the session (enum: `Active`, `Terminated`) +- **userIdeas**: A collection of `UserIdea` entities associated with the session. +- **results**: The harmonized results of the session, based on matching user ideas. +- **createdAt**: Timestamp of session creation (datetime) +- **terminatedAt**: Timestamp of session termination (datetime, null if active) diff --git a/specs/004-afraid-to-ask/plan.md b/specs/004-afraid-to-ask/plan.md new file mode 100644 index 0000000..7bacb7f --- /dev/null +++ b/specs/004-afraid-to-ask/plan.md @@ -0,0 +1,103 @@ +# Implementation Plan: Afraid to Ask Feature + +**Branch**: `004-afraid-to-ask` | **Date**: October 13, 2025 | **Spec**: ../../specs/004-afraid-to-ask/spec.md +**Input**: Feature specification from `/specs/004-afraid-to-ask/spec.md` + +## Summary + +This feature introduces an "Afraid to Ask" input field, allowing users to privately submit sensitive ideas. These ideas are semantically matched against other participants' "Want" or "Accept" desires. If a match occurs, the idea is treated as a "Want" for the submitting user in the session results; otherwise, it remains private and is not displayed. The feature prioritizes maximum privacy, ephemerality (no server-side traces after session termination), and adheres to general data privacy best practices. UI provides feedback for semantic matching analysis and service unavailability. + +## Technical Context + +**Language/Version**: Node.js (LTS), TypeScript 5.x +**Primary Dependencies**: React, Material-UI / MUI, WebSocket library, Google Cloud Natural Language API +**Storage**: Ephemeral server-side storage (in-memory/session store) for encrypted session data, purged on session termination. +**Testing**: `npm test` +**Target Platform**: Web (frontend), Server (backend) +**Project Type**: Full-stack (frontend/backend) +**Performance Goals**: No specific target latency for semantic matching; UI will display a "Harmonizing desires" placeholder during analysis. +**Constraints**: Maximum privacy, ephemerality (no long-term storage or analytics of "Afraid to Ask" ideas), adherence to general data privacy best practices. +**Scale/Scope**: Designed for individual sessions; a single "Afraid to Ask" input field may contain one or multiple distinct ideas. + +## Constitution Check + +*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* + +**Note**: The `constitution.md` file is currently in a template state with placeholders. A full check against specific, defined principles is not possible at this time. However, based on general software engineering best practices and the implied principles from the template, the following gates are considered: + +- **Test-First (Implied)**: The feature specification includes detailed user stories and acceptance criteria, which align with a test-first approach. This will be further enforced during task breakdown and implementation. (PASS) +- **Observability (Implied)**: The feature's focus on privacy and ephemerality implies a need for careful logging and monitoring to ensure data is purged correctly and not exposed. This will be a key consideration during implementation. (PASS) +- **Simplicity (Implied)**: The feature aims to solve a specific problem with a focused scope, avoiding unnecessary complexity. (PASS) +- **Security & Privacy**: The feature explicitly prioritizes maximum privacy and ephemerality, aligning with strong security and privacy principles. (PASS) + +**Overall Status**: Passed (based on implied principles and feature design). + +## Project Structure + +### Documentation (this feature) + +``` +specs/[###-feature]/ +├── plan.md # This file (/speckit.plan command output) +├── research.md # Phase 0 output (/speckit.plan command) +├── data-model.md # Phase 1 output (/speckit.plan command) +├── quickstart.md # Phase 1 output (/speckit.plan command) +├── contracts/ # Phase 1 output (/speckit.plan command) +└── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan) +``` + +### Source Code (repository root) + + +``` +# [REMOVE IF UNUSED] Option 1: Single project (DEFAULT) +src/ +├── models/ +├── services/ +├── cli/ +└── lib/ + +tests/ +├── contract/ +├── integration/ +└── unit/ + +# [REMOVE IF UNUSED] Option 2: Web application (when "frontend" + "backend" detected) +backend/ +├── src/ +│ ├── models/ +│ ├── services/ +│ └── api/ +└── tests/ + +frontend/ +├── src/ +│ ├── components/ +│ ├── pages/ +│ └── services/ +└── tests/ + +# [REMOVE IF UNUSED] Option 3: Mobile + API (when "iOS/Android" detected) +api/ +└── [same as backend above] + +ios/ or android/ +└── [platform-specific structure: feature modules, UI flows, platform tests] +``` + +**Structure Decision**: [Document the selected structure and reference the real +directories captured above] + +## Complexity Tracking + +*Fill ONLY if Constitution Check has violations that must be justified* + +| Violation | Why Needed | Simpler Alternative Rejected Because | +|-----------|------------|-------------------------------------| +| [e.g., 4th project] | [current need] | [why 3 projects insufficient] | +| [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] | diff --git a/specs/004-afraid-to-ask/quickstart.md b/specs/004-afraid-to-ask/quickstart.md new file mode 100644 index 0000000..d7da3e1 --- /dev/null +++ b/specs/004-afraid-to-ask/quickstart.md @@ -0,0 +1,60 @@ +# Quickstart Guide: Afraid to Ask Feature + +**Feature Branch**: `004-afraid-to-ask` +**Date**: October 13, 2025 +**Spec**: ../../specs/004-afraid-to-ask/spec.md + +## Overview + +This guide provides a quick overview of how to set up and interact with the "Afraid to Ask" feature. This feature allows users to submit sensitive ideas privately, which are then semantically matched against other participants' desires. + +## Setup + +1. **Clone the repository**: + ```bash + git clone [repository_url] + cd unisono + git checkout 004-afraid-to-ask + ``` +2. **Install dependencies**: + * **Backend**: + ```bash + cd backend + npm install + ``` + * **Frontend**: + ```bash + cd frontend + npm install + ``` +3. **Environment Variables**: Ensure the necessary environment variables are set for the Google Cloud Natural Language API in the backend. Refer to the `.env.example` file in the `backend` directory. + +## Running the Application + +1. **Start the Backend**: + ```bash + cd backend + npm start + ``` +2. **Start the Frontend**: + ```bash + cd frontend + npm start + ``` +3. Access the application in your browser, typically at `http://localhost:3000`. + +## Interacting with the Feature + +1. **Create a Session**: Navigate to the session creation page and create a new session. +2. **Submit "Afraid to Ask" Ideas**: + * Join the session as a participant. + * Locate the new "Afraid to Ask" input field on the response form (under "What you want"). + * Enter your sensitive ideas into this field and submit your response. +3. **Observe Matching**: + * Have other participants submit their "Want" or "Accept" ideas. + * Observe the session results. If your "Afraid to Ask" idea semantically matches another participant's "Want" or "Accept", it will appear as a "Want" for you in the results. Otherwise, it will remain private. +4. **Terminate Session**: Terminate the session to ensure all "Afraid to Ask" data is purged from the server. + +## API Endpoints + +Refer to `specs/004-afraid-to-ask/contracts/openapi.yaml` for detailed API documentation, including endpoints for submitting responses, retrieving results, and terminating sessions. diff --git a/specs/004-afraid-to-ask/research.md b/specs/004-afraid-to-ask/research.md new file mode 100644 index 0000000..3f12ce7 --- /dev/null +++ b/specs/004-afraid-to-ask/research.md @@ -0,0 +1,32 @@ +# Research Findings: Afraid to Ask Feature + +**Feature Branch**: `004-afraid-to-ask` +**Date**: October 13, 2025 +**Spec**: ../../specs/004-afraid-to-ask/spec.md + +## Clarification Decisions (from /speckit.clarify) + +### Functional Scope - Out-of-Scope Items +- **Decision**: The feature will NOT handle moderation or filtering of offensive/illegal "Afraid to Ask" ideas. "Afraid to Ask" ideas will NOT influence session results beyond matching other users' "Want" or "Accept" desires. Long-term storage or analytics of "Afraid to Ask" ideas will NOT be performed. +- **Rationale**: Simplifies initial implementation, focuses on core privacy and matching logic. Moderation and advanced analytics are considered separate features. +- **Alternatives considered**: Implementing content moderation (rejected due to complexity and scope creep for initial release). + +### Data Volume / Scale +- **Decision**: No specific maximum number of "Afraid to Ask" ideas per session or per user. The input field can contain one or multiple ideas within the text. +- **Rationale**: Accommodates flexible user input without imposing artificial limits, relying on semantic matching to process content. +- **Alternatives considered**: Imposing a numerical limit (rejected to avoid constraining user expression). + +### Error/Empty/Loading States (Semantic Matching Service) +- **Decision**: If the semantic matching service is unavailable or returns an error, the UI will display a specific error message and prevent form submission. +- **Rationale**: Provides clear feedback to the user and prevents submission of data that cannot be processed correctly, maintaining data integrity. +- **Alternatives considered**: Displaying a generic error (rejected for lack of clarity), falling back to basic keyword matching (rejected for potential inaccuracy and degraded user experience). + +### Performance (Semantic Matching Latency) +- **Decision**: No specific target latency for semantic matching. The UI will display a "Harmonizing desires" placeholder during the analysis. +- **Rationale**: Acknowledges the variable nature of LLM processing times and prioritizes user experience through clear feedback rather than strict time limits. +- **Alternatives considered**: Setting a strict latency target (rejected for potential over-engineering or unrealistic expectations for LLM performance). + +### Compliance / Regulatory Constraints +- **Decision**: No specific regulatory requirements (like GDPR, HIPAA) apply beyond general data privacy best practices. +- **Rationale**: Simplifies compliance overhead while still ensuring responsible data handling. +- **Alternatives considered**: Assuming GDPR/HIPAA applicability (rejected as not directly relevant to the current feature scope). diff --git a/specs/004-afraid-to-ask/spec.md b/specs/004-afraid-to-ask/spec.md index 93d38b8..a97da08 100644 --- a/specs/004-afraid-to-ask/spec.md +++ b/specs/004-afraid-to-ask/spec.md @@ -1,89 +1,98 @@ -# Feature Specification: `speckit.specify` command automation +# Feature Specification: Afraid to Ask Feature **Feature Branch**: `004-afraid-to-ask` -**Created**: 2025-10-13 +**Created**: October 13, 2025 **Status**: Draft -**Input**: User description: "Afraid to Ask. The requirements are in the .context/afraid-to-ask.md file." +**Input**: User description: "Afraid to Ask. Requirements are in the file .context/afraid-to-ask.md" ## User Scenarios & Testing *(mandatory)* -### User Story 1 - Core Spec Generation (Priority: P1) +### User Story 1 - Submitting an "Afraid to Ask" Idea (Priority: P1) -A developer provides a feature description to the `/speckit.specify` command. The system automatically generates a new feature branch and a complete, structured `spec.md` file based on a template, filling in details derived from the description. +A user wants to express a sensitive desire without immediately revealing it to others. They use the new "Afraid to Ask" field to submit their idea. -**Why this priority**: This is the core functionality. Without it, the feature has no value. +**Why this priority**: Core functionality, enables users to express sensitive desires while maintaining privacy. -**Independent Test**: Can be tested by running the command with a simple description and verifying that the correct branch and a well-formed spec file are created. +**Independent Test**: A user can successfully submit an "Afraid to Ask" idea and see it reflected in their own session view (if applicable, without revealing it to others yet). **Acceptance Scenarios**: -1. **Given** a developer is on the `main` branch, **When** they run `/speckit.specify "New feature"`, **Then** a new branch `[num]-new-feature` is created and checked out, and a `specs/[num]-new-feature/spec.md` file is created. -2. **Given** a feature description, **When** the spec is generated, **Then** the spec file contains all the mandatory sections from the template. +1. **Given** a user is on the response form, **When** they enter text into the "Afraid to Ask" field and submit, **Then** the idea is recorded privately for that user. +2. **Given** a user has submitted an "Afraid to Ask" idea, **When** they view their own session details, **Then** their "Afraid to Ask" idea is visible to them. --- -### User Story 2 - Validation and Checklists (Priority: P2) +### User Story 2 - "Afraid to Ask" Idea Matching (Priority: P1) -After generating the spec, the system automatically creates a `requirements.md` checklist and validates the spec against it. +A user's "Afraid to Ask" idea is compared against other participants' "Want" or "Accept" desires. If a match is found, it's treated as a "Want" for the submitting user in the results; otherwise, it remains private and is not shown. -**Why this priority**: This ensures the quality and completeness of the generated spec, which is a key part of the desired workflow. +**Why this priority**: Defines the core logic for how "Afraid to Ask" ideas interact with other users' desires and ensures conditional visibility. -**Independent Test**: Can be tested by checking for the existence and content of the `requirements.md` file after a spec is generated. +**Independent Test**: A user's "Afraid to Ask" idea that matches another user's "Want" or "Accept" is treated as a "Want" for the submitting user in the results. Conversely, an "Afraid to Ask" idea with no match is not displayed in the results. **Acceptance Scenarios**: -1. **Given** a spec has been generated, **When** the validation step runs, **Then** a `checklists/requirements.md` file is created in the feature directory. -2. **Given** a generated spec has obvious omissions (e.g., empty sections), **When** the validation runs, **Then** the corresponding items in the checklist are marked as failed. +1. **Given** User A submits an "Afraid to Ask" idea, and User B has a "Want" or "Accept" idea that semantically matches User A's "Afraid to Ask" idea, **When** the session results are generated, **Then** User A's "Afraid to Ask" idea is treated as a "Want" for User A in the results. +2. **Given** User A submits an "Afraid to Ask" idea, and no other user has a "Want" or "Accept" idea that semantically matches User A's "Afraid to Ask" idea, **When** the session results are generated, **Then** User A's "Afraid to Ask" idea does not appear in the results. --- -### User Story 3 - Interactive Clarification (Priority: P3) +### User Story 3 - Data Privacy and Ephemerality (Priority: P1) -When the system encounters ambiguities in the feature description, it adds `[NEEDS CLARIFICATION]` markers to the spec. It then presents these as questions to the user and updates the spec with their answers. +Users expect their "Afraid to Ask" ideas to be handled with maximum privacy and to be completely removed from the server once the session concludes. -**Why this priority**: This handles cases where the AI cannot make a reasonable assumption, making the process more robust. It's P3 because the core generation can function without it for well-defined features. +**Why this priority**: Addresses critical privacy and data retention requirements, building user trust. -**Independent Test**: Can be tested by providing an ambiguous description and verifying that the system asks for clarification and correctly incorporates the answer. +**Independent Test**: After a session terminates, no "Afraid to Ask" data is retrievable from the server, confirming complete data purging. **Acceptance Scenarios**: -1. **Given** a feature description with an ambiguous requirement, **When** the spec is generated, **Then** it contains a `[NEEDS CLARIFICATION]` marker. -2. **Given** a spec with a clarification marker, **When** the clarification flow is triggered, **Then** the user is presented with a formatted question and options. -3. **Given** a user provides an answer, **When** the system processes it, **Then** the `[NEEDS CLARIFICATION]` marker in the spec is replaced with the user's answer. - ---- - -### Edge Cases - -- What happens when the feature description is empty? -- How does the system handle a non-git repository? -- How does the system handle a situation where the generated branch name already exists? +1. **Given** a session has terminated, **When** an attempt is made to retrieve "Afraid to Ask" data from the server, **Then** no such data is found. ## Requirements *(mandatory)* ### Functional Requirements -- **FR-001**: System MUST accept a natural language string as a feature description. -- **FR-002**: System MUST generate a unique, kebab-cased feature branch name from the description, prefixed with a 3-digit incrementing number. -- **FR-003**: System MUST create and check out a new git branch with the generated name. -- **FR-004**: System MUST create a new directory for the feature under the `specs/` directory. -- **FR-005**: System MUST create a `spec.md` file in the new feature directory, populated from a template. -- **FR-006**: System MUST parse the feature description to populate the sections of the `spec.md` file. -- **FR-007**: System MUST create a `checklists/requirements.md` file to validate the spec. -- **FR-008**: System MUST identify and flag ambiguous requirements with `[NEEDS CLARIFICATION]` markers (max 3). -- **FR-009**: System MUST present clarification questions to the user and update the spec with their answers. -- **FR-010**: System MUST handle cases where a generated branch name already exists by checking out the existing branch instead of failing. +- **FR-001**: The system MUST provide an "Afraid to Ask" input field on the response form, located directly under the "What you want" field. +- **FR-002**: The system MUST ensure that "Afraid to Ask" ideas are initially private to the submitting user and not visible to other participants. +- **FR-003**: The system MUST semantically compare "Afraid to Ask" ideas with other users' "Want" or "Accept" desires. +- **FR-004**: If an "Afraid to Ask" idea semantically matches another user's "Want" or "Accept" desire, the system MUST treat it as a "Want" for the submitting user in the session results. +- **FR-005**: If an "Afraid to Ask" idea does not semantically match any other user's "Want" or "Accept" desire, the system MUST exclude it from the session results. +- **FR-006**: The system MUST ensure maximum privacy for "Afraid to Ask" ideas, preventing their exposure to other users unless a semantic match occurs as per FR-004. +- **FR-007**: The system MUST purge all "Afraid to Ask" data from the server upon session termination, leaving no traces. +- **FR-008**: "Afraid to Ask" ideas will NOT influence session results beyond matching other users' "Want" or "Accept" desires. +- **FR-009**: The system will NOT perform long-term storage or analytics of "Afraid to Ask" ideas. +- **FR-010**: The UI MUST display a specific error message and prevent form submission if the semantic matching service is unavailable or returns an error. +- **FR-011**: The UI MUST display a "Harmonizing desires" placeholder during the semantic matching analysis of "Afraid to Ask" ideas. +- **FR-012**: The system MUST adhere to general data privacy best practices for handling "Afraid to Ask" data. ### Key Entities *(include if feature involves data)* -- **Feature Specification**: A markdown document that describes a new feature. It includes user scenarios, requirements, and success criteria. -- **Requirement Checklist**: A markdown document used to validate the quality and completeness of a feature specification. +- **User Idea**: Represents a user's desire, including "Want", "Accept", and "Afraid to Ask" types. Attributes include content and type. A single "Afraid to Ask" input field may contain one or multiple distinct ideas. +- **Session**: A collection of user ideas and their matching results, along with associated metadata. ## Success Criteria *(mandatory)* ### Measurable Outcomes -- **SC-001**: A developer can generate a complete and validated draft specification from a one-sentence feature description in under 1 minute. -- **SC-002**: 90% of generated specifications require no manual structural changes to the file itself (i.e., the template is correctly applied). -- **SC-003**: The clarification process correctly resolves ambiguities in over 95% of cases where it is triggered. -- **SC-004**: The time spent by developers writing initial feature specs is reduced by 75%. \ No newline at end of file +- **SC-001**: Users can successfully submit "Afraid to Ask" ideas without them being immediately visible to other participants. +- **SC-002**: "Afraid to Ask" ideas that semantically match other users' "Want" or "Accept" desires are correctly reflected as "Want" in the results for the submitting user in 100% of test cases. +- **SC-003**: "Afraid to Ask" ideas that do not semantically match any other user's "Want" or "Accept" desires are completely absent from the session results in 100% of test cases. +- **SC-004**: No "Afraid to Ask" data is retained on the server after a session has concluded, ensuring complete privacy and data purging within 5 seconds of session termination. + +## Clarifications + +### Session October 13, 2025 + +- Q: What explicit items are out-of-scope for the "Afraid to Ask" feature? → A: Handling of offensive/illegal "Afraid to Ask" ideas; "Afraid to Ask" ideas influencing session results beyond matching "Want" or "Accept"; Long-term storage or analytics of "Afraid to Ask" ideas. +- Q: What is the expected maximum number of "Afraid to Ask" ideas per session or per user? → A: No particular number. The field contains some text that can contain one or multiple ideas. +- Q: How should the UI behave if the semantic matching service is unavailable or returns an error? → A: Show the error message and prevent form submission. +- Q: What is the target latency for semantic matching of an "Afraid to Ask" idea? → A: No target. Let the LLM work on it and display `Harmonizing desires` placeholder during analysis. +- Q: Are there any specific compliance or regulatory requirements for handling sensitive "Afraid to Ask" data (e.g., GDPR, HIPAA)? → A: No specific regulatory requirements beyond general data privacy best practices. + +### Edge Cases + +- What happens when the "Afraid to Ask" field is left empty? (It should be ignored) +- How does system handle partial matches between "Afraid to Ask" ideas and other desires? (Assume exact or semantic match based on existing LLM service) +- What if a user submits multiple "Afraid to Ask" ideas? (Each is processed independently) +- The system does NOT provide moderation or filtering for offensive or illegal content submitted via "Afraid to Ask" ideas. diff --git a/specs/004-afraid-to-ask/tasks.md b/specs/004-afraid-to-ask/tasks.md new file mode 100644 index 0000000..2f8a0fd --- /dev/null +++ b/specs/004-afraid-to-ask/tasks.md @@ -0,0 +1,202 @@ +# Tasks: Afraid to Ask Feature + +**Input**: Design documents from `/specs/004-afraid-to-ask/` +**Prerequisites**: plan.md (required), spec.md (required for user stories), research.md, data-model.md, contracts/ + +**Tests**: The feature specification implies a need for testing to ensure privacy, matching logic, and UI behavior. Therefore, test tasks are included. + +**Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story. + +## Format: `[ID] [P?] [Story] Description` +- **[P]**: Can run in parallel (different files, no dependencies) +- **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3) +- Include exact file paths in descriptions + +## Path Conventions +- **Web app**: `backend/src/`, `frontend/src/` + +## Phase 1: Setup (Shared Infrastructure) + +**Purpose**: Project initialization and basic structure + +- [ ] T001 Verify Node.js/TypeScript project with React, Material-UI, WebSocket library, Google Cloud Natural Language API dependencies are correctly configured in `package.json` and `tsconfig.json`. +- [ ] T002 [P] Verify linting and formatting tools are configured in `backend` and `frontend`. + +--- + +## Phase 2: Foundational (Blocking Prerequisites) + +**Purpose**: Core infrastructure that MUST be complete before ANY user story can be implemented + +**⚠️ CRITICAL**: No user story work can begin until this phase is complete + +- [ ] T003 Ensure ephemeral server-side storage (in-memory/session store) is configured for encrypted session data. +- [ ] T004 Verify existing WebSocket communication setup can be extended for real-time updates. +- [ ] T005 Configure Google Cloud Natural Language API integration in the backend. +- [ ] T006 [P] Implement structured logging for "Afraid to Ask" data lifecycle events (submission, matching, purging). +- [ ] T007 [P] Implement metrics for semantic matching service performance and availability. +- [ ] T008 Implement access control mechanisms to ensure only the submitting user can view their "Afraid to Ask" ideas before matching. +- [ ] T009 Implement encryption for "Afraid to Ask" data at rest in ephemeral storage. +- [ ] T010 Implement secure transmission (e.g., HTTPS/WSS) for "Afraid to Ask" data. + +**Checkpoint**: Foundation ready - user story implementation can now begin in parallel + +--- + +## Phase 3: User Story 1 - Submitting an "Afraid to Ask" Idea (Priority: P1) 🎯 MVP + +**Goal**: Allow users to privately submit "Afraid to Ask" ideas. + +**Independent Test**: A user can successfully submit an "Afraid to Ask" idea and see it reflected in their own session view (if applicable, without revealing it to others yet). + +### Implementation for User Story 1 + +- [ ] T011 [US1] Update `frontend/src/components/DesireForm.tsx` to add "Afraid to Ask" input field under "What you want". +- [ ] T012 [US1] Update `frontend/src/components/DesireForm.test.tsx` to include tests for the new input field. +- [ ] T013 [US1] Modify `backend/src/routes/sessions.ts` to accept `afraidToAsk` field in the session response submission endpoint (`/sessions/{sessionId}/responses`). +- [ ] T014 [US1] Update `backend/src/services/LLMService.ts` to handle and store "Afraid to Ask" ideas privately (ephemeral storage). +- [ ] T015 [US1] Update `backend/src/tests/sessions.test.ts` to include tests for submitting "Afraid to Ask" ideas. +- [ ] T016 [US1] Update `frontend/src/pages/SessionPage.tsx` to display the user's own "Afraid to Ask" ideas. + +**Checkpoint**: At this point, User Story 1 should be fully functional and testable independently + +--- + +## Phase 4: User Story 2 - "Afraid to Ask" Idea Matching (Priority: P1) + +**Goal**: Semantically match "Afraid to Ask" ideas and treat them as "Want" if a match is found. + +**Independent Test**: A user's "Afraid to Ask" idea that matches another user's "Want" or "Accept" is treated as "Want" for the submitting user in the results. Conversely, an "Afraid to Ask" idea with no match is not displayed in the results. + +### Implementation for User Story 2 + +- [ ] T017 [US2] Implement semantic comparison logic in `backend/src/services/LLMService.ts` to compare "Afraid to Ask" ideas with "Want" or "Accept" ideas. +- [ ] T018 [US2] Update `backend/src/routes/sessions.ts` to integrate semantic matching into session results generation. +- [ ] T019 [US2] Update `backend/src/tests/LLMService.refactor.test.ts` (or create new test file) to include tests for semantic matching logic. +- [ ] T020 [US2] Update `frontend/src/components/ResultsDisplay.tsx` to correctly display harmonized results, including matched "Afraid to Ask" ideas. +- [ ] T021 [US2] Update `frontend/src/components/ResultsDisplay.refactor.test.tsx` (or create new test file) to include tests for displaying matched "Afraid to Ask" ideas. + +**Checkpoint**: At this point, User Stories 1 AND 2 should both work independently + +--- + +## Phase 5: User Story 3 - Data Privacy and Ephemerality (Priority: P1) + +**Goal**: Ensure maximum privacy and complete purging of "Afraid to Ask" data upon session termination. + +**Independent Test**: After a session terminates, no "Afraid to Ask" data is retrievable from the server. + +### Implementation for User Story 3 + +- [ ] T022 [US3] Implement session termination logic in `backend/src/routes/sessions.ts` to purge all "Afraid to Ask" data. +- [ ] T023 [US3] Update `backend/src/tests/sessions.test.ts` to include tests for data purging upon session termination. +- [ ] T024 [US3] Update `frontend/src/services/websocket.ts` to handle session termination events and update UI accordingly. + +**Checkpoint**: All user stories should now be independently functional + +--- + +## Final Phase: Polish & Cross-Cutting Concerns + +**Purpose**: Improvements that affect multiple user stories + +- [ ] T025 Implement UI error handling and display for semantic matching service unavailability (`FR-010`). +- [ ] T026 Implement UI placeholder display for "Harmonizing desires" during semantic matching analysis (`FR-011`). +- [ ] T027 Review and ensure adherence to general data privacy best practices for handling "Afraid to Ask" data, including data minimization and purpose limitation (`FR-012`). +- [ ] T028 Conduct a privacy impact assessment (PIA) for the "Afraid to Ask" feature. +- [ ] T029 Run quickstart.md validation. + +--- + +## Dependencies & Execution Order + +### Phase Dependencies + +- **Setup (Phase 1)**: No dependencies - can start immediately +- **Foundational (Phase 2)**: Depends on Setup completion - BLOCKS all user stories +- **User Stories (Phase 3+)**: All depend on Foundational phase completion + - User stories can then proceed in parallel (if staffed) + - Or sequentially in priority order (P1 → P2 → P3) +- **Polish (Final Phase)**: Depends on all desired user stories being complete + +### User Story Dependencies + +- **User Story 1 (P1)**: Can start after Foundational (Phase 2) - No dependencies on other stories +- **User Story 2 (P2)**: Can start after Foundational (Phase 2) - May integrate with US1 but should be independently testable +- **User Story 3 (P3)**: Can start after Foundational (Phase 2) - May integrate with US1/US2 but should be independently testable + +### Within Each User Story + +- Tests MUST be written and FAIL before implementation +- Models before services +- Services before endpoints +- Core implementation before integration +- Story complete before moving to next priority + +### Parallel Opportunities + +- All Setup tasks marked [P] can run in parallel +- All Foundational tasks marked [P] can run in parallel (within Phase 2) +- Once Foundational phase completes, all user stories can start in parallel (if team capacity allows) +- All tests for a user story marked [P] can run in parallel +- Models within a story marked [P] can run in parallel +- Different user stories can be worked on in parallel by different team members + +--- + +## Parallel Example: User Story 1 + +```bash +# Launch all tests for User Story 1 together: +Task: "Update frontend/src/components/DesireForm.test.tsx to include tests for the new input field." +Task: "Update backend/src/tests/sessions.test.ts to include tests for submitting \"Afraid to Ask\" ideas." + +# Launch all models for User Story 1 together: +Task: "Update frontend/src/components/DesireForm.tsx to add \"Afraid to Ask\" input field under \"What you want\"." +Task: "Modify backend/src/routes/sessions.ts to accept `afraidToAsk` field in the session response submission endpoint (`/sessions/{sessionId}/responses`)." +Task: "Update backend/src/services/LLMService.ts to handle and store \"Afraid to Ask\" ideas privately (ephemeral storage)." +Task: "Update frontend/src/pages/SessionPage.tsx to display the user's own \"Afraid to Ask\" ideas." +``` + +--- + +## Implementation Strategy + +### MVP First (User Story 1 Only) + +1. Complete Phase 1: Setup +2. Complete Phase 2: Foundational (CRITICAL - blocks all stories) +3. Complete Phase 3: User Story 1 +4. **STOP and VALIDATE**: Test User Story 1 independently +5. Deploy/demo if ready + +### Incremental Delivery + +1. Complete Setup + Foundational → Foundation ready +2. Add User Story 1 → Test independently → Deploy/Demo (MVP!) +3. Add User Story 2 → Test independently → Deploy/Demo +4. Add User Story 3 → Test independently → Deploy/Demo +5. Each story adds value without breaking previous stories + +### Parallel Team Strategy + +With multiple developers: + +1. Team completes Setup + Foundational together +2. Once Foundational is done: + - Developer A: User Story 1 + - Developer B: User Story 2 + - Developer C: User Story 3 +3. Stories complete and integrate independently + +--- + +## Notes + +- [P] tasks = different files, no dependencies +- [Story] label maps task to specific user story for traceability +- Each user story should be independently completable and testable +- Verify tests fail before implementing +- Commit after each task or logical group +- Stop at any checkpoint to validate story independently +- Avoid: vague tasks, same file conflicts, cross-story dependencies that break independence