Skip to content

Add numbered analysis artifacts backed by Knowledge Pages #223

Description

@oshuej198

Summary

Introduce a first-class Analysis / Specifications workspace module for business and systems analysis artifacts while reusing Knowledge Pages for document content, hierarchy, editing, permissions, revisions, attachments, diagrams, search, and printing.

The module should give selected pages stable, human-readable document identifiers such as CRM-DOC-42, structured artifact types and lifecycle status, and traceability to other pages, work items, test cases, and assets.

This is documentation and requirements management, not the existing delivery-metrics Analytics page.

Problem

Knowledge Pages already provide a strong documentation foundation, but they currently lack the structure needed for managed analysis artifacts:

  • Pages have an internal numeric database id, but no workspace-scoped human-readable document number.
  • slug is display-only, non-unique, and is not used for page resolution.
  • There is no workspace registry for requirements, use cases, specifications, decisions, processes, or data models.
  • Artifact type, lifecycle status, owner, and approval state are not first-class fields.
  • Page metadata is not included in page_revisions, so storing lifecycle fields only in pages.metadata would not provide a complete revision/audit trail.
  • The generic link backend supports page endpoints, but Pages only expose a focused work-item linking UI. There is no traceability matrix or analysis-specific relationship view.
  • Existing wiki pages should remain lightweight and should not automatically become managed analysis artifacts.

Goals

  1. Reuse Pages as the canonical content engine.
  2. Add immutable, workspace-scoped artifact numbering.
  3. Keep ordinary wiki pages unchanged.
  4. Allow an existing page to be promoted to an analysis artifact.
  5. Provide a workspace Analysis registry with filtering and search.
  6. Add structured artifact type, status, and owner fields.
  7. Reuse existing page ACLs for visibility and edit authorization.
  8. Reuse the polymorphic link system for traceability.
  9. Support both SQLite and PostgreSQL.
  10. Preserve compatibility with existing page routes, search, history, diagrams, attachments, and printing.

Non-goals

  • Replacing Knowledge Pages or creating a second Markdown editor.
  • Replacing the existing workspace Analytics metrics page.
  • Implementing this through the current WASM plugin system.
  • Automatically numbering or migrating every existing page.
  • Implementing a full configurable approval engine in the first slice.

Proposed UX

Add an Analysis entry to workspace navigation.

Registry

The default view is a permission-filtered artifact registry with columns such as:

  • Key
  • Title
  • Type
  • Status
  • Owner
  • Updated
  • Traceability / coverage summary

Suggested filters:

  • text/key
  • artifact type
  • lifecycle status
  • owner
  • page label
  • linked/unlinked
  • covered/not covered by test cases

Artifact detail

Reuse the existing Pages editor and supporting UI. Add an analysis header containing:

  • copyable artifact key, for example CRM-DOC-42
  • artifact type
  • status
  • owner
  • traceability action
  • history/audit access

Existing page capabilities should continue to work:

  • Markdown editing and autosave
  • nested page hierarchy
  • revision history
  • page-level ACLs
  • Mermaid and Excalidraw diagrams
  • attachments
  • labels
  • linked work items
  • print view
  • knowledge search

Creation

“Create analysis artifact” should allow:

  • title
  • artifact type
  • optional parent page
  • optional template
  • initial owner
  • initial status, defaulting to draft

An existing page can be promoted to an artifact. Promotion allocates a number once; demotion should not recycle that number.

Identifier design

Use a stable generic document segment rather than encoding the mutable artifact type into the identifier:

<workspace-key>-DOC-<number>
CRM-DOC-42

Artifact type is displayed separately. This avoids breaking external references when a document changes from, for example, a functional requirement to a business rule.

Persist the numeric identity and derive the display key consistently. The behavior when a workspace key is renamed should be explicitly documented and aligned with work-item key behavior.

Numbers must be:

  • unique within a workspace
  • allocated atomically
  • immutable after allocation
  • never reused after archive or demotion
  • preserved across edits, title changes, intra-workspace moves, archive, and unarchive

Proposed data model

Keep analysis lifecycle data separate from pages.metadata. Workspace ownership must be enforced by the database, not only by route/service checks. Because the composite foreign key below requires a matching candidate key, add a unique constraint or index on pages(id, workspace_id) in both database schemas.

CREATE UNIQUE INDEX idx_pages_id_workspace_id
    ON pages (id, workspace_id);
CREATE TABLE analysis_artifacts (
    id INTEGER PRIMARY KEY,
    page_id INTEGER NOT NULL UNIQUE,
    workspace_id INTEGER NOT NULL,
    artifact_number INTEGER NOT NULL,
    artifact_type TEXT NOT NULL,
    status TEXT NOT NULL DEFAULT 'draft',
    owner_id INTEGER,
    created_by INTEGER NOT NULL,
    created_at TIMESTAMP NOT NULL,
    updated_by INTEGER,
    updated_at TIMESTAMP NOT NULL,
    FOREIGN KEY (page_id, workspace_id) REFERENCES pages(id, workspace_id) ON DELETE CASCADE,
    FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE,
    FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE SET NULL,
    FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE RESTRICT,
    FOREIGN KEY (updated_by) REFERENCES users(id) ON DELETE SET NULL,
    UNIQUE (workspace_id, artifact_number)
);

CREATE TABLE analysis_artifact_sequences (
    workspace_id INTEGER PRIMARY KEY,
    last_number INTEGER NOT NULL,
    FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE
);

Allocate the next number inside the same transaction as artifact creation. A cross-database UPSERT with RETURNING last_number, or the existing per-workspace item-number locking pattern, can be used. The unique constraint remains the final integrity guard.

Suggested initial artifact types:

  • business_requirement
  • functional_requirement
  • non_functional_requirement
  • business_rule
  • use_case
  • business_process
  • system_specification
  • api_specification
  • data_model
  • architecture_decision
  • glossary_entry

Suggested initial statuses:

  • draft
  • in_review
  • approved
  • deprecated

Initial values can be fixed system values. Configurable types/status workflows can be a later slice.

Workspace ownership invariants

Every analysis artifact belongs to exactly the same workspace as its backing Page:

  • analysis_artifacts.workspace_id must equal pages.workspace_id; the composite foreign key makes mismatches impossible even if a service bug bypasses validation.
  • Number sequences, artifact lookup, registry filters, create/promote/update routes, and permissions are workspace-scoped.
  • The same artifact number may exist in different workspaces, but (workspace_id, artifact_number) is unique.
  • Artifact keys use the owning workspace key, while the immutable numeric identity remains workspace-local.
  • Moving a normal Page across workspaces continues to use the existing Page behavior. Moving an artifact-backed Page follows the explicit restrictions below.
  • API handlers must derive and validate workspace ownership from both the route and stored Page; a caller cannot attach a Page from workspace A to an artifact in workspace B.

History and audit

Type, status, owner, promotion, demotion, and traceability changes must be auditable.

Either:

  1. add an immutable analysis_artifact_history table, or
  2. extend page revision snapshots so analysis metadata is revisioned explicitly.

A separate history table is preferred because artifact status can change without modifying Markdown content.

Service boundaries

Introduce an AnalysisArtifactService rather than placing analysis behavior directly into PageService.

Responsibilities:

  • create a page-backed artifact
  • promote an existing page
  • allocate numbers atomically
  • update type/status/owner
  • list/filter artifacts with page ACL enforcement
  • resolve an artifact by workspace and number/key
  • enforce archive/move invariants
  • emit audit events

Creation of a new page-backed artifact should be atomic. This may require extracting a transaction-aware page creation helper from PageService.Create so the page and artifact rows can be committed or rolled back together.

Page content remains owned by Page services and endpoints.

Permissions and information disclosure

The artifact registry must not reveal titles, keys, status, ownership, counts, or relationship information for pages the user cannot view.

Rules:

  • listing requires the appropriate workspace Page permission and per-page ACL visibility
  • reading an artifact requires Page view permission
  • editing artifact metadata requires Page edit permission
  • lifecycle administration may initially require Page admin permission
  • linking must reuse existing endpoint permission checks and page ACL filtering
  • permission failures should follow the existing opaque 404 behavior

Traceability

Treat Pages as first-class nodes in the existing relationship graph. Reuse the polymorphic item_links infrastructure, which already accepts page as an entity type, and extend the product UI so users can link:

  • an analysis artifact or ordinary Knowledge Page to any work item type, including workspace-defined Epic, Story, Task, Bug, or other custom types
  • Epic/Story/work item back to the Page or artifact that specifies it
  • requirement to test case for verification coverage
  • Page/artifact to another Page/artifact for refinement, dependency, impact, or decomposition
  • Page/artifact to asset where supporting evidence or design material is stored

Suggested typed, directional relationships include:

  • specifies / is specified by
  • implements / is implemented by
  • refines / is refined by
  • verifies / is verified by
  • depends on / is depended on by
  • affects / is affected by
  • parent of / decomposes into where hierarchy alone is insufficient

The same relationship must be visible from both ends. The Page/artifact detail should provide a searchable link action by key or title and grouped backlinks. Work-item detail should show linked Pages with artifact key, title, type, status, and relationship. This makes it possible to navigate from a business requirement to the implementing Epic and Stories, then to validating test cases, and back to the source specification.

For analysis artifacts, add a structured traceability view and registry rollups such as:

  • requirements with no linked implementation Epic/Story/work item
  • requirements with no verifying test case
  • Epics/Stories without a source requirement or specification
  • test cases without linked requirements
  • deprecated documents with active dependents
  • coverage grouped by artifact type, status, or owner

Link creation, lookup, backlinks, counts, and coverage calculations must enforce both endpoint permissions and Page ACLs. Hidden entities must not leak through titles, keys, counts, autocomplete, or aggregate coverage. Cross-workspace links should be blocked by default unless the existing link service already defines an explicit, permission-safe cross-workspace policy.

The generic Page linking capability should remain useful for ordinary Knowledge Pages. Analysis artifacts add stable keys, lifecycle semantics, registry filters, and coverage reporting on top of that shared link model. Avoid a second relationship table unless the existing link model cannot express typed, directional analysis relationships.

Workspace moves

Pages currently support cross-workspace moves. Artifact numbering makes this an explicit product decision.

Recommended MVP behavior:

  • intra-workspace hierarchy moves preserve the artifact number
  • block cross-workspace moves for artifact-backed pages with a clear conflict response
  • add a dedicated artifact move flow later that allocates a destination number and optionally stores an alias/redirect for the previous key

Silent renumbering during the generic Page move is not acceptable because external references would break without an audit trail.

API sketch

Possible workspace-scoped endpoints:

GET    /workspaces/{workspaceId}/analysis-artifacts
POST   /workspaces/{workspaceId}/analysis-artifacts
GET    /workspaces/{workspaceId}/analysis-artifacts/{artifactNumber}
PATCH  /workspaces/{workspaceId}/analysis-artifacts/{artifactNumber}
POST   /workspaces/{workspaceId}/pages/{pageId}/promote-to-analysis
GET    /workspaces/{workspaceId}/analysis-artifacts/{artifactNumber}/traceability

List endpoint filters should be server-side and permission-aware.

The normal Page endpoints continue to own title, Markdown content, metadata used by the generic page UI, hierarchy, ACLs, diagrams, attachments, and revision restore.

Migration and compatibility

  • Add matching canonical schema for SQLite and PostgreSQL.
  • Add catalog migrations for existing installations.
  • Do not backfill all existing pages.
  • Existing pages can be promoted explicitly.
  • Existing URLs remain valid.
  • Artifact deep links may redirect to or render the underlying Page detail.
  • Archive must retain the artifact record and number.
  • Permanent page deletion may cascade to the artifact row, but allocated numbers must not be reused.

Acceptance criteria

  • Ordinary Knowledge Pages continue working without an artifact record or displayed document key.
  • Creating an analysis artifact creates or associates exactly one Page.
  • The database prevents an artifact row from referencing a Page in a different workspace.
  • Artifact registry, lookup, numbering, promotion, and updates are scoped to the workspace in the route and the backing Page.
  • Concurrent creation in the same workspace cannot allocate duplicate numbers.
  • Creation in different workspaces remains independent.
  • The displayed key uses the workspace key, DOC, and the artifact number.
  • Artifact number remains unchanged through edits, rename, intra-workspace move, archive, and unarchive.
  • Existing pages can be promoted and receive a number exactly once.
  • Archived/demoted artifact numbers are never reused.
  • Registry results are filtered through page ACLs and do not leak hidden-page metadata.
  • Type, status, and owner changes are audited/history-backed.
  • Artifact content, attachments, diagrams, labels, printing, and revisions continue using Pages.
  • Artifact links reuse existing permission-checked link services.
  • A Page/artifact can be linked to Epic, Story, Task, Bug, other workspace-defined work-item types, test cases, assets, and other Pages where supported.
  • Links and typed relationships are navigable from both Page/artifact and linked-entity detail views.
  • Traceability lookup, backlinks, counts, autocomplete, and coverage summaries do not disclose hidden entities.
  • The registry can identify requirements without implementation or test coverage.
  • Cross-workspace moves have explicit safe behavior.
  • Key/title search and deep linking are supported.
  • SQLite and PostgreSQL behavior is covered by tests.
  • API and UI include empty, loading, permission-denied, validation, and conflict states.

Suggested implementation slices

  1. Data model and numbering

    • schemas and migrations
    • repository/model types
    • atomic number allocation
    • promotion and immutable identity
    • concurrency and rollback tests
  2. Service and API

    • create/get/update/list
    • page ACL filtering
    • audit/history
    • archive and workspace-move invariants
  3. Registry and detail integration

    • workspace navigation
    • filtered artifact table
    • artifact header on the reused Page editor
    • key copy, search, and deep links
  4. Traceability and templates

    • page/page, page/item, and page/test-case UI
    • coverage summaries
    • starter templates by artifact type

Open questions

  • Should the display key follow live workspace-key renames, matching work items, or preserve the original prefix forever?
  • Should artifact types and statuses be configurable in the first release?
  • Should demotion be allowed, and if so, how should inactive artifact identities appear in lookup?
  • Is a dedicated review/approval permission needed, or is page.admin sufficient for the initial release?
  • Should cross-workspace artifact moves remain blocked permanently or gain alias/redirect support?
  • Which relationship types should be built in, and which should be workspace-configurable?
  • Should all cross-workspace entity links be blocked, or is there a secure opt-in use case?

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions