Skip to content

Conversation

@aaronsb
Copy link
Owner

@aaronsb aaronsb commented Dec 19, 2025

Summary

Implements ADR-082 (User Scoping & Artifact Ownership) and ADR-083 (Artifact Persistence Pattern), completing Phases 1-7.

ADR-082: User Scoping

  • Unix-style ID ranges: system user (ID 1), regular users start at 1000
  • Groups system with public (implicit membership) and admins groups
  • Resource grants for fine-grained access control
  • Permission resolution checking user grants, group grants, and public access

ADR-083: Artifact Persistence

  • Multi-tier storage: PostgreSQL (metadata), Garage (large payloads)
  • Artifact types: search_result, projection, polarity_analysis, query_result
  • Graph epoch tracking for freshness detection
  • Query definitions for saved/replayable queries
  • Async job integration with artifact creation

CLI Enhancements (Phase 5-6)

  • kg artifact list/show/payload/delete commands
  • kg source list/info/get commands
  • kg group list/members/create/add-member/remove-member commands
  • kg query-def list/show/create/delete commands
  • Unix-style aliases: kg ls, kg cat, kg rm, kg stat
  • kg search <term> direct shortcut
  • kg help commandmap for introspective command tree
  • --save-artifact flag for kg projection regenerate and kg search query

MCP Tools (Phase 7)

  • New artifact tool with list/show/payload actions
  • Enhanced source tool handles both text and image sources

Changes by Phase

Phase 1: Schema Foundation

  • Migration 034: groups, user_groups, resource_grants tables
  • Unix-style ID ranges for users and groups

Phase 2: Artifact Schema

  • Migration 035: query_definitions, artifacts tables
  • ArtifactStorageService for inline/Garage routing

Phase 3a-c: APIs

  • Artifact CRUD endpoints
  • Groups & grants management endpoints
  • Query definitions endpoints

Phase 4: Async Job Integration

  • Migration 036: job_artifact_linking
  • artifact_helper.py for worker artifact creation
  • Projection and polarity workers create artifacts

Phase 5: CLI Consolidation

  • Split monolithic CLI files into modular structure
  • Standardized metadata verb (show vs details)
  • Unix shortcuts as aliases

Phase 6: CLI Enhancements

  • --save-artifact flags for projection and search
  • Fixed artifact_helper import paths

Phase 7: MCP Tools

  • artifact tool for AI agent artifact management
  • source tool enhanced for text + image retrieval

Test plan

  • Build succeeds: npm run build in cli/
  • kg artifact list shows artifacts
  • kg search "term" --save-artifact creates artifact
  • kg projection regenerate <ont> --save-artifact --force creates artifact
  • kg artifact show <id> displays metadata
  • kg group list shows public and admins groups
  • MCP server starts without errors
  • Manual testing of MCP artifact tool in Claude Desktop

Migration 034: User Scoping Groups (ADR-082)
- kg_auth.groups table with system groups (public, admins)
- kg_auth.user_groups for group membership
- kg_auth.resource_grants for instance-level access
- System user (ID 1) for system-owned resources
- Sequences reset to 1000 for regular users/groups
- has_access() function for grant-based permission checks

Migration 035: Artifact Persistence (ADR-083)
- kg_api.query_definitions for saved query recipes
- kg_api.artifacts for computed result metadata
- Graph epoch freshness tracking via get_graph_epoch()
- is_artifact_fresh() helper function
- Support for inline results (<10KB) or Garage pointers
…082)

- Migration 020: Create system user (ID 1) and admin user (ID 1000)
- Migration 034: Add admin user to admins group, document ID conventions
- Operator: Add new admin users to admins group on creation
- API: Add admin-role users to admins group via POST /users

ID ranges follow Unix convention:
- 1-999: System/reserved (system user, public/admins groups)
- 1000+: Regular users and user-defined groups
…istence (ADR-083)

- Create ArtifactStorageService with size-based routing
- Small payloads (<10KB): stored inline in PostgreSQL
- Large payloads (>=10KB): stored in Garage S3
- Key format: artifacts/{artifact_type}/{artifact_id}.json
- Add prepare_for_storage() for automatic routing decision
- Add factory function get_artifact_storage() for singleton access
- Export service and INLINE_THRESHOLD_BYTES constant
… 3a)

Implement CRUD API endpoints for artifact persistence:
- GET /artifacts - List artifacts with filtering (type, representation, ontology)
- GET /artifacts/{id} - Get artifact metadata
- GET /artifacts/{id}/payload - Get artifact with full payload
- POST /artifacts - Create artifact with automatic storage routing
- DELETE /artifacts/{id} - Delete artifact and cleanup Garage storage

Add CLI commands for validation:
- kg artifact list - List user's artifacts
- kg artifact show <id> - Show artifact metadata
- kg artifact payload <id> - Get full payload
- kg artifact create -t <type> - Create test artifact
- kg artifact delete <id> - Delete artifact

Storage routing automatically selects inline (<10KB) or Garage (>=10KB).
Ownership checks enforce user can only see/modify their own artifacts.
Graph epoch tracking enables freshness detection for stale artifacts.
Implement group management and resource grants:
- GET /groups - List groups with member counts
- POST /groups - Create group (admin only, IDs 1000+)
- GET /groups/{id}/members - List group members
- POST /groups/{id}/members - Add member to group
- DELETE /groups/{id}/members/{user_id} - Remove member

Resource grant endpoints:
- POST /grants - Create resource access grant
- GET /resources/{type}/{id}/grants - List grants for resource
- DELETE /grants/{id} - Revoke grant

Add CLI commands for validation:
- kg group list/members/create/add-member/remove-member

All endpoints require OAuth authentication.
Admin-only operations enforce role check.
Implement query definitions CRUD for saved query recipes:
- GET /query-definitions - List with type filtering
- GET /query-definitions/{id} - Get by ID
- POST /query-definitions - Create new definition
- PUT /query-definitions/{id} - Update definition
- DELETE /query-definitions/{id} - Delete definition

Definition types: block_diagram, cypher, search, polarity, connection

Add CLI commands for validation:
- kg query-def list/show/create/delete

Artifact regeneration endpoint deferred to Phase 4 (job integration).
Document 6 issues from code review of Phase 3 commits:
- Major #1: Grant ownership verification (admin-only workaround)
- Major #2: System resource NULL handling policy
- Minor #3-6: Logging, indexing, serialization, public group fixes

Refs: ac658a3..ebdd1b8
Major fixes:
- Add verify_resource_ownership() helper for grant authorization
- Clarify system resource policy: NULL owner_id = system-owned (ID 1)
- Resource owners can now create/revoke grants on their resources

Minor fixes:
- Add error logging for Garage deletion failures in artifact delete
- Add composite index (owner_id, representation) for artifact queries
- Document double JSON serialization trade-off in artifact_storage
- Add include_implicit param to public group members endpoint
- Add implicit_membership field to GroupMemberList response

Refs: ADR-082, ADR-083
Job Queue Changes:
- Migration 036: Add artifact_id column to jobs table
- Update job_queue.update_job() to support artifact_id updates

Worker Artifact Helper:
- Create artifact_helper.py with create_job_artifact() function
- Encapsulates artifact creation pattern for workers
- Handles graph epoch, storage routing, and job linking

Projection Worker Integration:
- Add create_artifact flag to job_data
- Create artifact on completion when flag is set
- Link artifact to job via artifact_id column
- Include artifact_id in job result

This establishes the pattern for other workers to create artifacts.
Polarity analysis and cleanup workers deferred to future work.

Refs: ADR-083
Add polarity analysis async job support:
- Create polarity_worker.py with artifact creation
- Add /polarity-axis/jobs endpoint for async analysis
- Update CLI kg polarity analyze with --save-artifact flag
- Add submitPolarityJob client method

Add artifact regeneration:
- Add POST /artifacts/{id}/regenerate endpoint
- Support polarity_analysis and projection types
- Trigger async job using stored parameters

Add artifact cleanup scheduled job:
- Create artifact_cleanup_worker.py for expired artifacts
- Create ArtifactCleanupLauncher for daily 2 AM schedule
- Register worker and scheduled job in migration 036

Also:
- Add BaseModel import fixes in queries.py and artifacts.py
- Add artifact_id to JobResult TypeScript type
- Update tracking file with completed items
- Add `kg search <term>` shortcut (simplifies `kg search query <term>`)
- Add `kg help commandmap` for introspective CLI structure tree
- Add Unix shortcuts: `kg ls artifact/source`, `kg cat artifact/source`, `kg rm artifact`
- Add `kg source list` command with ontology filter
- Add `/sources` API endpoint for listing source nodes
- Align descriptions in commandmap output for readability
- Use terminal width for description truncation (not fixed 45 chars)
- Add visual spacing between command groups in commandmap
- Document storage architecture (STORAGE-ARCHITECTURE.md)
Split the 1593-line vocabulary.ts into 9 focused modules:
- status.ts: status, list commands (~270 lines)
- consolidate.ts: consolidate, merge commands (~165 lines)
- embeddings.ts: generate-embeddings, category-scores, refresh-categories (~190 lines)
- similarity.ts: similar, opposite, analyze commands (~190 lines)
- config.ts: config command (~180 lines)
- profiles.ts: profiles list/show/create/delete (nested subcommands, ~170 lines)
- epistemic.ts: epistemic-status list/show/measure (~330 lines)
- sync.ts: sync command (~85 lines)
- index.ts: main command wiring (~50 lines)

Key improvements:
- All files under 350 lines (target: <500)
- profiles-* commands now use proper nested subcommands
- Removed deprecated config-update command
- Better separation of concerns
- Renamed `search details` to `search show` for consistency
- Added `details` as alias for backwards compatibility
- Aligns with pattern: system resources use `info`, user entities use `show`
- admin.ts (1124 lines) → admin/ directory (5 files):
  - utils.ts (391 lines): prompt, promptPassword, promptHoldEnter, job tracking
  - status.ts (106 lines): system status command
  - scheduler.ts (112 lines): scheduler status/cleanup commands
  - backup.ts (381 lines): backup, list-backups, restore commands
  - index.ts (62 lines): command wiring

- ai-config.ts (1036 lines) → ai-config/ directory (5 files):
  - embedding.ts (638 lines): all embedding configuration commands
  - extraction.ts (181 lines): extraction config/set commands
  - keys.ts (172 lines): API keys list/set/delete commands
  - utils.ts (51 lines): shared prompt utilities
  - index.ts (21 lines): re-exports

ADR-082/083 Phase 5 CLI improvements
…-083 Phase 6)

- Add --save-artifact flag to kg projection regenerate
- Add --save-artifact flag to kg search query and direct search shortcut
- Add create_artifact() helper for sync operations (no job linkage)
- Update projection API to support artifact creation parameter
- Improve install.sh to suppress verbose build output (show on failure only)

Artifacts are persisted with type 'projection' or 'search_result' and
representation 'cli', enabling recall and sharing of analysis results.
…ase 7)

- Add artifact tool with list, show, and payload actions
- Update source tool to handle both text and image sources
- Text sources return full_text with metadata (document, paragraph, offsets)
- Image sources return base64 image as before
- Update Phase 6 tracking in todo file

MCP server now provides complete artifact management for AI agents to
reuse stored analyses without re-running expensive computations.
@aaronsb aaronsb merged commit f7dc19b into main Dec 19, 2025
6 checks passed
@aaronsb aaronsb deleted the feature/adr-082-083-user-scoping-artifacts branch December 19, 2025 04:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants