Skip to content

Add lifecycle_status as Core Node Property with Semantic Search Exclusion #755

Description

@malibio

Overview

Add lifecycleStatus as a core hub property on all nodes to support knowledge governance. The lifecycle transitions will be policy-driven, allowing users to customize archival and retention behavior according to their needs.

Architecture Context (Updated January 2026)

This issue is part of the Universal Graph Architecture Transition (Epic #783).

The lifecycleStatus field should be added to the hub table now, before the spoke table elimination. This is a clean addition that:

  • Works with current Hub-and-Spoke architecture
  • Will carry forward unchanged to Pure JSON architecture
  • Enables semantic search filtering immediately

Key Design Decision: Lifecycle transitions are controlled by policies (declarative rules), not workflows (reactive events). Policies are evaluated periodically by the Policy Evaluation Engine (#785).

This can be worked on in parallel with or after Stream B (Data Model Transition).

Problem Statement

Users need to archive outdated content without relying on collection naming conventions. Currently:

  • No system-level way to mark content as archived
  • Semantic search returns all content regardless of relevance/staleness
  • Users might create collections named "Archive", "Old", "Historical" - no consistent pattern

Industry standard (SharePoint/Purview, Confluence) uses a system-level status field that search respects by default, with policy-driven transitions.

Proposed Solution

1. Add lifecycleStatus as Core Hub Property

Every node gets this property in the hub table (like nodeType, version, createdAt):

DEFINE FIELD lifecycleStatus ON TABLE node TYPE string DEFAULT "active";
DEFINE INDEX idx_node_lifecycle ON TABLE node COLUMNS lifecycleStatus;

Allowed values:

  • active (default) - included in search, visible in UI
  • archived - excluded from search by default, hidden from default views, restorable
  • deleted - soft-deleted, in trash, excluded from all queries, purgeable

2. Define policy Schema (Lifecycle Type)

Policies are nodes that define declarative rules for lifecycle transitions:

{
  "id": "node:<uuid>",
  "node_type": "policy",
  "content": "Archive completed tasks after 90 days",
  "properties": {
    "policy_type": "lifecycle",
    "applies_to": ["task"],
    "enabled": true,
    "priority": 0,
    "trigger": {
      "type": "last_modified",
      "days": 90,
      "condition": "properties.status == 'done'"
    },
    "action": "archive"
  }
}

3. Update Semantic Search

Add include_archived parameter (defaults to false):

-- Default: exclude archived and deleted
SELECT * FROM node
WHERE vector::similarity::cosine(embedding, $query_vec) > $threshold
  AND lifecycleStatus = 'active'
ORDER BY similarity DESC
LIMIT $limit;

-- With include_archived: true
SELECT * FROM node
WHERE vector::similarity::cosine(embedding, $query_vec) > $threshold
  AND lifecycleStatus IN ['active', 'archived']
ORDER BY similarity DESC
LIMIT $limit;

4. MCP Tool Update

// search_semantic tool
{
  name: "search_semantic",
  parameters: {
    query: string,
    limit?: number,
    threshold?: number,
    include_archived?: boolean  // NEW - defaults to false
  }
}

Acceptance Criteria

Phase 1: Core Infrastructure

  • lifecycleStatus field added to SurrealDB node hub table with default active
  • Index created for efficient lifecycle filtering
  • policy schema defined with policy_type: "lifecycle" support
  • Manual archive/restore actions work (UI buttons)

Phase 2: Search Integration

  • search_semantic excludes archived/deleted nodes by default
  • search_semantic includes archived nodes when include_archived: true
  • All node queries filter by lifecycle status appropriately

Phase 3: UI

  • UI provides "Archive" action that sets lifecycleStatus: 'archived'
  • UI provides "Restore" action that sets lifecycleStatus: 'active'
  • UI provides "Delete" action that sets lifecycleStatus: 'deleted'
  • Archived nodes display visual indicator (banner, muted styling)
  • Deleted nodes only visible in Trash view

Phase 4: Quality

  • Documentation updated (architecture docs, MCP tool docs)
  • Tests cover archive/restore/delete and search exclusion
  • Code passes bun run quality:fix
  • Tests pass (bun run test:all)

Technical Specifications

Reference Files

  • Architecture: See architecture-target-state.md
  • Node hub table: packages/desktop-app/src-tauri/src/db/ - Add lifecycleStatus field
  • Semantic search: packages/desktop-app/src-tauri/src/services/ - Add filter parameter
  • MCP handler: packages/desktop-app/src-tauri/src/mcp/ - Update search_semantic tool

Why Core Hub Property (Not Spoke)?

  • System-level concern: Like nodeType or createdAt, applies to ALL nodes
  • Search integration: Must filter at database level for performance
  • Consistent behavior: All nodes support archival regardless of type
  • Industry standard: SharePoint/Purview, Confluence use system-level flags

Policy vs Workflow Distinction

Concept Nature Example
Policy Declarative (continuous filter/rule) "Archive done tasks after 90 days"
Workflow Reactive (event → action) "When archived, notify owner"

Policies are evaluated periodically by the Policy Evaluation Engine (#785).
Policies can trigger workflows (e.g., archiving a node triggers "on_archive" workflow).

Dependencies

Related Issues

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions