/speckit-specify output for 004-product-knowledge (roadmap Phase 3): 3 user stories (authoring/versioning/publishing knowledge entries, structured error-code/known-issue/runbook records, filtered retrieval), 14 functional requirements. Full semantic/vector retrieval is explicitly deferred to the future AI-support feature (doc 11 gap B1) -- this feature's retrieval is structured filtering, a real usable contract rather than a placeholder. Quality checklist passes with no NEEDS CLARIFICATION markers. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
219 lines
14 KiB
Markdown
219 lines
14 KiB
Markdown
# Feature Specification: Product Knowledge Management & Retrieval
|
|
|
|
**Feature Branch**: `004-product-knowledge`
|
|
|
|
**Created**: 2026-09-02
|
|
|
|
**Status**: Draft
|
|
|
|
**Input**: User description: "Phase 3 of docs/10-implementation-roadmap.md: Knowledge/KnownIssue/
|
|
ErrorCode/Runbook models, admin CRUD, versioning + publish state, retrieval (RAG) layer. Per
|
|
docs/03-ai-support-architecture.md section 2-3 and docs/06-database-schema.md."
|
|
|
|
## User Scenarios & Testing *(mandatory)*
|
|
|
|
### User Story 1 - An admin authors, versions, and publishes knowledge entries (Priority: P1)
|
|
|
|
An administrator creates a knowledge entry for a product (a known issue, FAQ, resolution
|
|
procedure, or operations note), scoped to the right product/feature/category. The entry starts
|
|
as a draft, invisible to retrieval. When the admin publishes it, it becomes eligible for
|
|
retrieval from its effective date onward. Editing a published entry creates a new version rather
|
|
than silently rewriting history, and the admin can mark an entry as validated once it's been
|
|
confirmed to actually work.
|
|
|
|
**Why this priority**: Nothing else in this feature (or the future AI-support feature that
|
|
depends on it) has anything to retrieve until knowledge exists, is scoped correctly, and has a
|
|
trustworthy draft/published/validated lifecycle — retrieving an unreviewed draft as if it were
|
|
trustworthy guidance would be worse than retrieving nothing.
|
|
|
|
**Independent Test**: Create a draft knowledge entry, confirm it's not retrievable; publish it,
|
|
confirm it becomes retrievable from its effective date; edit it, confirm the edit produces a new
|
|
version and the prior version remains inspectable.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** an admin creates a knowledge entry, **When** it's saved without being published,
|
|
**Then** it exists with `status: draft` and is never returned by any retrieval query.
|
|
2. **Given** a draft entry, **When** an admin publishes it with an effective date, **Then** it
|
|
becomes eligible for retrieval starting at that date — not before.
|
|
3. **Given** a published entry, **When** an admin edits its content, **Then** the edit is
|
|
recorded as a new version (incrementing `version`), and the entry's prior content remains
|
|
retrievable by version rather than being overwritten.
|
|
4. **Given** a published entry, **When** an admin marks it `validationStatus: validated`,
|
|
**Then** that status is visible on every retrieval result that includes it.
|
|
5. **Given** a published entry, **When** an admin unpublishes it, **Then** it immediately stops
|
|
being returned by retrieval, without being deleted.
|
|
|
|
---
|
|
|
|
### User Story 2 - Known issues, error codes, and runbooks are modeled as first-class, product-scoped records (Priority: P2)
|
|
|
|
Beyond general knowledge entries, an admin can catalog specific known issues (linked to a
|
|
structured error code) and author runbooks — ordered, versioned step sequences for a specific
|
|
problem type. These are distinct from freeform knowledge entries because they're referenced
|
|
structurally (by error code, by runbook key) rather than only found through search.
|
|
|
|
**Why this priority**: Knowledge entries alone (User Story 1) already deliver standalone value —
|
|
this story adds the structured lookup paths (a specific error code, a specific runbook key) doc
|
|
03's example ("searches: feature documentation → error catalog → known issues → troubleshooting →
|
|
runbooks") depends on, but a knowledge base without them is still useful.
|
|
|
|
**Independent Test**: Create an error code and a known issue referencing it; look the known issue
|
|
up by error code and confirm it resolves; create a runbook with an ordered step sequence for a
|
|
product; look it up by its key and confirm the exact step order is preserved.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** an admin creates an error code for a product, **When** it's saved, **Then** it has a
|
|
unique, product-scoped code (e.g. `LAYOUT_PARSE_042`) and a description.
|
|
2. **Given** an existing error code, **When** an admin creates a known issue referencing it,
|
|
**Then** the known issue can be looked up directly by that error code.
|
|
3. **Given** an admin creates a runbook for a product with an ordered list of steps, **When** it's
|
|
saved, **Then** the step order is preserved exactly as authored — never reordered or
|
|
deduplicated by the system.
|
|
4. **Given** an existing runbook, **When** an admin edits its steps, **Then** the edit is recorded
|
|
as a new version, matching User Story 1's versioning behavior for knowledge entries.
|
|
5. **Given** a runbook, **When** an admin deactivates it, **Then** it's excluded from lookup
|
|
without being deleted — the same active/inactive convention as User Story 1's publish state.
|
|
|
|
---
|
|
|
|
### User Story 3 - Retrieval returns only relevant, filtered, validation-aware knowledge for a given context (Priority: P3)
|
|
|
|
Given a product, and optionally a feature/category/problem-type context, a retrieval query
|
|
returns only the knowledge entries that are published, past their effective date, and scoped to
|
|
that context — never an unfiltered dump of everything in the knowledge base. When both a
|
|
validated and an unvalidated entry are otherwise equally relevant, the validated one is
|
|
preferred.
|
|
|
|
**Why this priority**: This is what makes the knowledge base actually usable by a future
|
|
caller (the AI-support feature) instead of just an admin content library — but it depends on
|
|
User Stories 1 and 2 existing first, and doc 03 itself frames full semantic retrieval as a later
|
|
design decision (see Assumptions), so this story delivers the retrieval *contract* now without
|
|
requiring a vector/embedding pipeline to exist yet.
|
|
|
|
**Independent Test**: Seed knowledge entries across two different products, query retrieval
|
|
scoped to one product, and confirm only that product's published, effective entries are
|
|
returned — never the other product's, never drafts, never entries not yet effective; seed one
|
|
validated and one unvalidated entry that are otherwise equally relevant, and confirm the
|
|
validated one is ranked first.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** knowledge entries across multiple products, **When** a retrieval query is scoped to
|
|
one product, **Then** only that product's entries are ever returned.
|
|
2. **Given** a mix of draft and published entries, **When** a retrieval query runs, **Then**
|
|
drafts are never returned, regardless of how well they'd otherwise match.
|
|
3. **Given** a published entry whose effective date is in the future, **When** a retrieval query
|
|
runs before that date, **Then** the entry is not returned.
|
|
4. **Given** a validated and an unvalidated entry that both match a query, **When** results are
|
|
returned, **Then** the validated entry is ranked ahead of the unvalidated one.
|
|
5. **Given** a retrieval query with no matches, **When** it runs, **Then** it returns an empty
|
|
result — never an error, and never a fallback to unrelated knowledge.
|
|
|
|
---
|
|
|
|
### Edge Cases
|
|
|
|
- What happens when an admin tries to publish a knowledge entry with no content (empty
|
|
problem/solution fields)? Out of scope for strict validation here — this feature stores what's
|
|
given; a content-quality review workflow is not part of this phase.
|
|
- What happens when two knowledge entries could both plausibly answer the same query (e.g. a
|
|
known issue and a general FAQ)? Both are returned if both match the filters — ranking beyond
|
|
validation-status preference (User Story 3 Scenario 4) is explicitly not solved here; true
|
|
relevance ranking is the future semantic-retrieval work in Assumptions.
|
|
- What happens when a runbook is looked up by a key that doesn't exist, or exists but is
|
|
inactive? It's treated as not found either way — an inactive runbook is not distinguishable
|
|
from a nonexistent one to a retrieval caller, only to an admin managing it directly.
|
|
- What happens when an error code is deleted while a known issue still references it? Out of
|
|
scope — this feature doesn't implement deletion of error codes that have active references;
|
|
only unpublish/deactivate operations are defined (Scenarios above), matching the rest of the
|
|
system's "never hard-delete support-domain records" convention.
|
|
|
|
## Requirements *(mandatory)*
|
|
|
|
### Functional Requirements
|
|
|
|
- **FR-001**: The system MUST let an admin create a knowledge entry scoped to a product, and
|
|
optionally to a feature and one or more categories.
|
|
- **FR-002**: A knowledge entry MUST have a `status` of `draft`, `published`, or `unpublished`,
|
|
and MUST default to `draft` on creation.
|
|
- **FR-003**: A knowledge entry MUST only be returned by retrieval when its status is
|
|
`published` AND its effective date is at or before the current time.
|
|
- **FR-004**: Editing a published knowledge entry's content MUST create a new version
|
|
(incrementing a version counter) rather than overwriting the existing version in place; prior
|
|
versions MUST remain retrievable by their own identity.
|
|
- **FR-005**: A knowledge entry MUST carry a `validationStatus` (`unvalidated` or `validated`),
|
|
independently settable by an admin from its publish status.
|
|
- **FR-006**: The system MUST let an admin create an error code scoped to a product, unique
|
|
within that product.
|
|
- **FR-007**: The system MUST let an admin create a known issue referencing an error code, and
|
|
retrieve a known issue directly by its error code.
|
|
- **FR-008**: The system MUST let an admin create a runbook for a product as an ordered list of
|
|
steps, preserving the authored order exactly.
|
|
- **FR-009**: Editing a runbook's steps MUST create a new version, matching FR-004's behavior for
|
|
knowledge entries.
|
|
- **FR-010**: A runbook MUST have an active/inactive state; lookup by key MUST NOT return an
|
|
inactive runbook, and MUST NOT distinguish "inactive" from "does not exist" in its response.
|
|
- **FR-011**: A retrieval query MUST be scoped to at least a product, and MAY be further filtered
|
|
by feature and/or category; it MUST NEVER return entries outside the specified product scope.
|
|
- **FR-012**: A retrieval query MUST NEVER return a `draft` or `unpublished` entry, or an entry
|
|
whose effective date has not yet arrived.
|
|
- **FR-013**: When multiple retrieved entries are otherwise equally relevant to a query, entries
|
|
with `validationStatus: validated` MUST be ranked ahead of unvalidated ones.
|
|
- **FR-014**: Every knowledge entry MUST carry `owner` and `lastReview` fields an admin can set,
|
|
supporting future staleness detection — this feature does not implement staleness detection
|
|
itself, only the fields it depends on.
|
|
|
|
### Key Entities
|
|
|
|
- **Knowledge Entry**: A versioned, product-scoped piece of guidance (known issue, FAQ,
|
|
resolution procedure, or operations note) with a draft/published/unpublished lifecycle, a
|
|
validation status, and retrieval-filtering scope (product/feature/category).
|
|
- **Error Code**: A structured, product-scoped error identifier (e.g. `LAYOUT_PARSE_042`) with a
|
|
description, referenced by known issues.
|
|
- **Known Issue**: A product-scoped problem record, optionally linked to an Error Code,
|
|
describing a recognized issue and its status.
|
|
- **Runbook**: A versioned, ordered sequence of troubleshooting steps for a product, looked up by
|
|
a stable key, with an active/inactive state — the step *sequence itself* is data owned by this
|
|
feature; *executing* a runbook against a live conversation is the future AI-support feature's
|
|
job, not this one's.
|
|
|
|
## Success Criteria *(mandatory)*
|
|
|
|
### Measurable Outcomes
|
|
|
|
- **SC-001**: 100% of draft knowledge entries are absent from every retrieval query result,
|
|
verified across every entry type.
|
|
- **SC-002**: 100% of retrieval queries scoped to one product return zero entries belonging to
|
|
any other product.
|
|
- **SC-003**: An admin can publish a knowledge entry and have it appear in retrieval results
|
|
within the same request cycle — no propagation delay.
|
|
- **SC-004**: Editing a published entry never loses the prior version's content — it remains
|
|
retrievable by an admin after the edit, 100% of the time.
|
|
- **SC-005**: A validated entry is ranked ahead of an equally-matching unvalidated one in 100% of
|
|
retrieval results that include both.
|
|
- **SC-006**: A known issue is resolvable by its error code in a single lookup, without a
|
|
separate search step.
|
|
|
|
## Assumptions
|
|
|
|
- **Full semantic (embedding/vector) retrieval is explicitly out of scope for this feature** —
|
|
per `docs/11-architect-additions-gaps-and-recommendations.md` §B1, the embedding model,
|
|
chunking strategy, and re-ranking approach are technical decisions for the future AI-support
|
|
feature (Phase 4) to make, not this one. This feature implements retrieval as structured,
|
|
deterministic filtering (product/feature/category scope, status, effective date,
|
|
validation-status preference) — a real, usable retrieval contract, not a placeholder — that a
|
|
future semantic layer can sit in front of without changing the underlying data model or the
|
|
guarantee that filters apply before any ranking (doc 11 §B1's explicit ordering requirement).
|
|
- Runbook *execution* (the workflow engine that controls which step is permitted next during a
|
|
live AI conversation, per `docs/03-ai-support-architecture.md` §6) is explicitly out of scope —
|
|
this feature only stores and versions the step data; the future AI-support feature interprets
|
|
and executes it.
|
|
- Content-quality validation (e.g. requiring non-empty fields before publish) is not enforced by
|
|
this feature — an admin can publish sparse content; a content-review workflow is not part of
|
|
this phase.
|
|
- Deletion of knowledge entries, error codes, known issues, or runbooks is out of scope — only
|
|
publish/unpublish and active/inactive state changes are defined, consistent with this system's
|
|
broader convention of never silently losing support-domain history.
|