From 21ed51d5c1315986f5f6dd91f4280196a907e7e0 Mon Sep 17 00:00:00 2001 From: egallmann Date: Thu, 12 Mar 2026 00:13:43 -0400 Subject: [PATCH 1/2] Remove stale submodule references from ste-runtime --- .gitignore | 3 +++ .gitmodules | 6 ------ spec | 1 - 3 files changed, 3 insertions(+), 7 deletions(-) delete mode 100644 .gitmodules delete mode 160000 spec diff --git a/.gitignore b/.gitignore index bd7fb16..82ca8d9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Cursor IDE workspace and plans +.cursor/ + # Dependencies node_modules/ diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 1014fa2..0000000 --- a/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "spec"] - path = spec - url = https://github.com/egallmann/ste-spec.git -[submodule "ste-runtime"] - path = ste-runtime - url = https://github.com/egallmann/ste-runtime.git diff --git a/spec b/spec deleted file mode 160000 index 90bde07..0000000 --- a/spec +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 90bde07a20ee75c364ec1d25bf9c585f75007497 From ab4cf41e04648a32c9287e29d2cd743ae14a457d Mon Sep 17 00:00:00 2001 From: egallmann Date: Thu, 12 Mar 2026 01:49:54 -0400 Subject: [PATCH 2/2] Clean up runtime hygiene and ADR-driven docs surface --- .gitignore | 12 +- CONTRIBUTING.md | 568 +----- MATURITY.md | 10 +- PROJECT.yaml | 59 + README.md | 45 +- SYSTEM-OVERVIEW.md | 260 +++ adrs/manifest.yaml | 39 +- adrs/rendered/ADR-L-0001.md | 12 + adrs/rendered/ADR-L-0002.md | 12 + adrs/rendered/ADR-L-0003.md | 12 + adrs/rendered/ADR-L-0004.md | 12 + adrs/rendered/ADR-L-0005.md | 11 + adrs/rendered/ADR-L-0006.md | 11 + adrs/rendered/ADR-P-0001.md | 12 + adrs/rendered/ADR-P-0002.md | 12 + adrs/rendered/ADR-P-0003.md | 12 + adrs/rendered/ADR-P-0004.md | 12 + adrs/rendered/ADR-P-0005.md | 12 + documentation/architecture.md | 40 +- .../E-ADR-001-RECON-Provisional-Execution.md | 348 ---- .../E-ADR-002-RECON-Self-Validation.md | 292 --- .../e-adr-archived/E-ADR-003-CEM-Deferral.md | 145 -- .../E-ADR-004-RSS-CLI-Implementation.md | 276 --- .../E-ADR-005-JSON-Data-Extraction.md | 390 ---- .../E-ADR-006-Angular-Semantic-Extraction.md | 1019 ---------- .../E-ADR-007-Watchdog-Authoritative-Mode.md | 1149 ------------ .../E-ADR-008-Extractor-Development-Guide.md | 922 ---------- ...R-009-Self-Configuring-Domain-Discovery.md | 629 ------- ...-ADR-010-Conversational-Query-Interface.md | 384 ---- .../E-ADR-011-ste-runtime-MCP-Server.md | 1099 ----------- ...R-013-Extractor-Validation-Requirements.md | 624 ------- documentation/e-adr-archived/README.md | 90 - documentation/guides/README.md | 23 + .../guides/configuration-reference.md | 3 +- documentation/guides/dual-repo-workflow.md | 359 ---- .../guides/extractor-validation-quickstart.md | 314 ---- documentation/guides/faq.md | 676 ------- documentation/guides/getting-started.md | 409 ----- documentation/guides/glossary.md | 398 ---- documentation/guides/mcp-setup.md | 3 +- documentation/guides/pre-commit-hook-setup.md | 131 -- documentation/guides/troubleshooting.md | 13 +- .../extractor-validation-status.md | 6 +- .../inference-phase-enhancements.md | 4 +- .../innovations/Two-Layer-Context-Assembly.md | 487 ----- .../innovations/prior-art-research.md | 477 ----- .../plan/e-adr-implementation-status.md | 439 ----- .../plan/e-adr-spec-validation-assessment.md | 333 ---- .../reference/alternatives-comparison.md | 3 +- eslint.config.js | 53 + .../.ste-self/state/graph-metrics.json | 18 + .../api/endpoints/api-GET-api-greet-name.yaml | 2 +- .../endpoints/api-GET-api-users-user-id.yaml | 2 +- .../api/endpoints/api-GET-api-users.yaml | 2 +- .../api/endpoints/api-POST-api-users.yaml | 2 +- .../python-sample/.ste/state/api/index.yaml | 2 +- .../data/entities/data-GreetingConfig.yaml | 2 +- .../.ste/state/data/entities/data-User.yaml | 2 +- .../python-sample/.ste/state/data/index.yaml | 2 +- .../.ste/state/graph-metrics.json | 2 +- .../.ste/state/graph/internal/index.yaml | 2 +- .../internal/modules/module-app-__init__.yaml | 2 +- .../internal/modules/module-app-api.yaml | 2 +- .../modules/module-app-services-__init__.yaml | 2 +- .../modules/module-app-services-greeting.yaml | 2 +- .../module-app-services-user_service.yaml | 2 +- .../.ste/state/manifest/recon-manifest.json | 12 +- instructions/adaptive-tool-parameters.md | 3 +- package-lock.json | 1636 ++++++++++++++--- package.json | 29 +- src/aidoc/python-aidoc-generator.ts | 8 - src/cli/discovery-cli.ts | 124 -- src/cli/index.ts | 1 - src/cli/recon-cli.ts | 172 +- src/cli/watch-cli.ts | 126 -- src/config/boundary-validation.test.ts | 3 - src/config/index.ts | 284 +-- src/discovery/project-discovery.ts | 25 +- src/extractors/angular/angular-extractor.ts | 23 +- .../python-extractor-validation.test.ts | 2 - src/mcp/context-source-loader.test.ts | 1 - src/mcp/context-source-loader.ts | 4 +- src/mcp/graph-topology-analyzer.test.ts | 1 - src/mcp/graph-topology-analyzer.ts | 3 +- src/mcp/mcp-server.test.ts | 5 +- src/mcp/obligation-projector.ts | 8 +- src/mcp/preflight.ts | 8 +- src/mcp/tools-context.test.ts | 2 +- src/mcp/tools-context.ts | 3 +- src/mcp/tools-obligation.test.ts | 5 - src/mcp/tools-obligation.ts | 3 - src/mcp/tools-operational.ts | 15 +- src/mcp/tools-optimized.ts | 3 +- src/mcp/tools-structural.ts | 2 +- src/recon/incremental-recon.ts | 1 - src/recon/index.ts | 2 - src/recon/phases/discovery.ts | 2 +- src/recon/phases/divergence.test.ts | 2 +- src/recon/phases/divergence.ts | 3 +- src/recon/phases/extraction-cloudformation.ts | 3 +- src/recon/phases/extraction.ts | 4 +- src/recon/phases/index.ts | 2 +- src/recon/phases/inference.test.ts | 2 - src/recon/phases/inference.ts | 31 +- src/recon/phases/normalization.test.ts | 2 - src/recon/phases/normalization.ts | 4 +- src/recon/phases/population.ts | 6 +- src/recon/validation/coverage-validator.ts | 2 - src/recon/validation/graph-validator.ts | 1 - src/recon/validation/history-manager.ts | 2 +- src/recon/validation/identity-validator.ts | 2 - .../repeatability-validator.test.ts | 3 +- src/recon/validation/report-generator.test.ts | 2 +- src/recon/validation/schema-validator.ts | 2 - src/rss/conversational-query.test.ts | 2 +- src/rss/conversational-query.ts | 13 +- src/rss/graph-loader.test.ts | 2 +- src/rss/rss-operations.test.ts | 2 - src/rss/rss-operations.ts | 4 +- src/watch/change-detector.test.ts | 1 - src/watch/edit-queue-manager.test.ts | 2 +- src/watch/full-reconciliation.test.ts | 1 - src/watch/full-reconciliation.ts | 3 +- src/watch/write-tracker.ts | 3 +- 124 files changed, 2223 insertions(+), 13108 deletions(-) create mode 100644 PROJECT.yaml create mode 100644 SYSTEM-OVERVIEW.md delete mode 100644 documentation/e-adr-archived/E-ADR-001-RECON-Provisional-Execution.md delete mode 100644 documentation/e-adr-archived/E-ADR-002-RECON-Self-Validation.md delete mode 100644 documentation/e-adr-archived/E-ADR-003-CEM-Deferral.md delete mode 100644 documentation/e-adr-archived/E-ADR-004-RSS-CLI-Implementation.md delete mode 100644 documentation/e-adr-archived/E-ADR-005-JSON-Data-Extraction.md delete mode 100644 documentation/e-adr-archived/E-ADR-006-Angular-Semantic-Extraction.md delete mode 100644 documentation/e-adr-archived/E-ADR-007-Watchdog-Authoritative-Mode.md delete mode 100644 documentation/e-adr-archived/E-ADR-008-Extractor-Development-Guide.md delete mode 100644 documentation/e-adr-archived/E-ADR-009-Self-Configuring-Domain-Discovery.md delete mode 100644 documentation/e-adr-archived/E-ADR-010-Conversational-Query-Interface.md delete mode 100644 documentation/e-adr-archived/E-ADR-011-ste-runtime-MCP-Server.md delete mode 100644 documentation/e-adr-archived/E-ADR-013-Extractor-Validation-Requirements.md delete mode 100644 documentation/e-adr-archived/README.md create mode 100644 documentation/guides/README.md delete mode 100644 documentation/guides/dual-repo-workflow.md delete mode 100644 documentation/guides/extractor-validation-quickstart.md delete mode 100644 documentation/guides/faq.md delete mode 100644 documentation/guides/getting-started.md delete mode 100644 documentation/guides/glossary.md delete mode 100644 documentation/guides/pre-commit-hook-setup.md delete mode 100644 documentation/innovations/Two-Layer-Context-Assembly.md delete mode 100644 documentation/innovations/prior-art-research.md delete mode 100644 documentation/plan/e-adr-implementation-status.md delete mode 100644 documentation/plan/e-adr-spec-validation-assessment.md create mode 100644 eslint.config.js create mode 100644 fixtures/python-sample/.ste-self/state/graph-metrics.json delete mode 100644 src/aidoc/python-aidoc-generator.ts delete mode 100644 src/cli/discovery-cli.ts delete mode 100644 src/cli/watch-cli.ts diff --git a/.gitignore b/.gitignore index 82ca8d9..ab9e8b0 100644 --- a/.gitignore +++ b/.gitignore @@ -11,8 +11,9 @@ dist/ # .ste/state/ - Only track README.md (ignore all other files) .ste/state/* !.ste/state/README.md -# .ste-self/ - Track everything (example for reviewers) -!.ste-self/ +# .ste-self/state/ - Only track README.md (ignore all other files) +.ste-self/state/* +!.ste-self/state/README.md # Runtime cache (downloaded specs, auto-regenerated) .ste/cache/ @@ -48,7 +49,8 @@ test-output.txt *.tmp .tmp/ -# Internal development issues (pre-release) -# Remove this line once project is public and issues should be tracked -documentation/issues/ +# Legacy archived docs kept locally only +documentation/e-adr-archived/ +documentation/plan/ + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f0069e8..dd4b65a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,558 +1,70 @@ -# Contributing to STE Runtime +# Contributing to ste-runtime ## Current Status -**STE Runtime is currently in active development and not accepting external contributions at this time.** +ste-runtime is a public experimental repository and reference implementation. Direct pull requests are not the primary collaboration model right now. -This repository is being published to document a stable implementation that converges with the [STE Specification](https://github.com/egallmann/ste-spec). The codebase is still evolving, and significant changes are planned. +What is welcome: +- Bug reports +- Questions about behavior or documentation +- Architectural discussion +- Forks and downstream experimentation -**This contributing guide is provided for future reference** when the project is ready to accept contributions. The structure and standards documented here represent the intended contribution process for when that time comes. +What to expect: +- Maintainer-driven changes land first +- The public repo may change quickly as the runtime is cleaned up and refactored +- Forks are the recommended path for custom features or production hardening ---- +## Local Development -## For Future Contributors +Prerequisites: +- Node.js 18 or later +- npm +- Python 3 for Python extractor development -When STE Runtime is ready to accept contributions, this guide will outline the development process, code standards, and contribution workflow. - ---- - -## Table of Contents - -- [Code of Conduct](#code-of-conduct) -- [Getting Started](#getting-started) -- [Development Setup](#development-setup) -- [Project Structure](#project-structure) -- [Development Workflow](#development-workflow) -- [Code Style](#code-style) -- [Testing](#testing) -- [Documentation](#documentation) -- [Pull Request Process](#pull-request-process) -- [Extractor Development](#extractor-development) - ---- - -## Code of Conduct - -This project adheres to professional standards: - -- **Be respectful** - Treat all contributors with respect -- **Be constructive** - Provide helpful feedback -- **Be professional** - Maintain enterprise-grade code quality -- **Be collaborative** - Work together to improve the project - ---- - -## Getting Started - -### Prerequisites - -- **Node.js** 18.0.0 or higher -- **npm** or **yarn** -- **Git** -- **TypeScript** knowledge -- **Python 3.x** (for Python extractor development) - -### Fork and Clone - -```bash -# Fork the repository on GitHub -# Then clone your fork -git clone https://github.com/your-username/ste-runtime.git -cd ste-runtime - -# Add upstream remote -git remote add upstream https://github.com/egallmann/ste-runtime.git -``` - ---- - -## Development Setup - -### 1. Install Dependencies +Setup: ```bash npm install -``` - -### 2. Build the Project - -```bash npm run build -``` - -### 3. Run Tests - -```bash -# All tests -npm test - -# Watch mode -npm run test:watch - -# Coverage -npm run test:coverage -``` - -### 4. Verify Setup - -```bash -# Test self-documentation -npm run recon:self - -# Check RSS stats npm run rss:stats -``` - ---- - -## Project Structure - -``` -ste-runtime/ -├── src/ # TypeScript source code -│ ├── cli/ # CLI entry points -│ ├── config/ # Configuration loader -│ ├── extractors/ # Language extractors -│ ├── mcp/ # MCP server -│ ├── recon/ # RECON engine -│ ├── rss/ # RSS operations -│ ├── watch/ # File watching (watchdog) -│ └── test/ # Test utilities -├── python-scripts/ # Python AST parser -├── fixtures/ # Test fixtures -├── documentation/ # Documentation -│ ├── e-adr/ # Architectural decisions -│ ├── guides/ # User guides -│ └── reference/ # Technical reference -├── instructions/ # Usage instructions -└── scripts/ # Utility scripts -``` - ---- - -## Development Workflow - -### 1. Create a Branch - -```bash -# From main -git checkout main -git pull upstream main - -# Create feature branch -git checkout -b feature/your-feature-name -# or -git checkout -b fix/your-bug-fix -``` - -**Branch naming:** -- `feature/` - New features -- `fix/` - Bug fixes -- `docs/` - Documentation -- `refactor/` - Code refactoring -- `test/` - Test improvements - -### 2. Make Changes - -- Write code following [Code Style](#code-style) -- Add tests for new features -- Update documentation as needed -- Follow [Git Commit Standards](#commit-messages) - -### 3. Test Your Changes - -```bash -# Run all tests -npm test - -# Run specific test file -npm test -- src/your-file.test.ts - -# Check coverage -npm run test:coverage - -# Verify build -npm run build - -# Test RECON npm run recon:self ``` -### 4. Pre-Commit Checks - -The pre-commit hook automatically runs: - -1. **Build check** - TypeScript compilation -2. **RECON self-check** - Self-documentation -3. **Tests** - All test suites -4. **RSS stats** - RSS functionality -5. **Test coverage** - Minimum 50% coverage - -**To bypass (not recommended):** -```bash -git commit --no-verify -``` - -### 5. Commit Your Changes - -Follow [Git Commit Standards](#commit-messages): +Useful commands: ```bash -git add . -git commit -m "PROJECT-1234 Add feature description" -``` - -### 6. Push and Create Pull Request - -```bash -git push origin feature/your-feature-name -``` - -Then create a Pull Request on GitHub. - ---- - -## Code Style - -### TypeScript - -- **Formatting:** Use Prettier (configured) or match existing style -- **Naming:** - - `camelCase` for variables and functions - - `PascalCase` for classes and types - - `UPPER_SNAKE_CASE` for constants -- **Imports:** Group by type (external, internal, types) -- **Comments:** JSDoc for public APIs - -**Example:** -```typescript -/** - * Extracts semantic assertions from a TypeScript file. - * - * @param filePath - Absolute path to the TypeScript file - * @param content - File content as string - * @param projectRoot - Project root directory - * @returns Array of raw semantic assertions - */ -export async function extractTypeScript( - filePath: string, - content: string, - projectRoot: string -): Promise { - // Implementation -} -``` - -### File Organization - -- One class/interface per file (when possible) -- Related utilities grouped together -- Test files: `*.test.ts` next to source files - -### Error Handling - -- Use descriptive error messages -- Include context (file path, line number) -- Don't swallow errors silently - -**Example:** -```typescript -if (!fileExists) { - throw new Error( - `File not found: ${filePath}\n` + - `Project root: ${projectRoot}\n` + - `This file should exist for extraction to proceed.` - ); -} -``` - ---- - -## Testing - -### Test Structure - -```typescript -import { describe, it, expect } from 'vitest'; - -describe('FeatureName', () => { - it('should do something', () => { - // Arrange - const input = 'test'; - - // Act - const result = functionUnderTest(input); - - // Assert - expect(result).toBe('expected'); - }); -}); -``` - -### Test Requirements - -- **Unit tests** for all new functions -- **Integration tests** for complex workflows -- **Edge cases** covered -- **Error cases** tested - -### Running Tests - -```bash -# All tests npm test - -# Watch mode (development) -npm run test:watch - -# Specific file -npm test -- src/path/to/file.test.ts - -# Coverage report npm run test:coverage +npm run recon:full +npm run recon:self +npm run rss:stats ``` -### Coverage Requirements - -- **Minimum:** 50% statement coverage -- **Target:** 70%+ for new code -- **Critical paths:** 90%+ (extractors, RECON phases) - ---- - -## Documentation - -### When to Update Documentation - -**Always update documentation when:** -- Adding new features -- Changing APIs -- Modifying configuration -- Adding new extractors -- Changing behavior - -### Documentation Types - -1. **User Guides** (`documentation/guides/`) - - Setup instructions - - Usage examples - - Configuration reference - -2. **E-ADRs** (`documentation/e-adr/`) - - Architectural decisions - - Design rationale - -3. **Reference** (`documentation/reference/`) - - Technical deep-dives - - Implementation details - -4. **Instructions** (`instructions/`) - - CLI usage - - API documentation - -### Documentation Standards - -- **Clear and concise** - Explain concepts simply -- **Examples** - Include code examples -- **Cross-references** - Link related docs -- **Professional tone** - Enterprise-grade writing - ---- - -## Pull Request Process - -### Before Submitting - -1. **Update documentation** - Add/update relevant docs -2. **Add tests** - Ensure all tests pass -3. **Check coverage** - Maintain or improve coverage -4. **Run pre-commit** - All checks must pass -5. **Self-review** - Review your own changes - -### PR Description Template - -```markdown -## Description -Brief description of changes - -## Type of Change -- [ ] Bug fix -- [ ] New feature -- [ ] Breaking change -- [ ] Documentation update - -## Testing -- [ ] Tests added/updated -- [ ] All tests passing -- [ ] Coverage maintained - -## Checklist -- [ ] Code follows style guidelines -- [ ] Documentation updated -- [ ] Tests added/updated -- [ ] Pre-commit checks passing -- [ ] No breaking changes (or documented) -``` - -### Review Process - -1. **Automated checks** - CI/CD runs tests -2. **Code review** - Maintainer reviews code -3. **Feedback** - Address review comments -4. **Approval** - Maintainer approves -5. **Merge** - Squash and merge (preferred) - ---- - -## Commit Messages - -Follow the Git Commit Message Standards: - -**Format:** -``` -JIRA-1234 Brief summary (50 chars max) - -Optional detailed explanation of what and why. -``` - -**Examples:** -``` -PROJECT-4030 Add indirect employment verification - -Implemented verification flow with API integration. -``` - -``` -PROJECT-4055 Fix Python extractor import resolution - -Resolved issue where relative imports weren't creating -graph edges. Added resolvePythonRelativeImport function. -``` - -**Rules:** -- Start with JIRA ticket ID -- Use imperative mood ("Add" not "Added") -- Capitalize first word after ticket ID -- No period at end of summary -- Add body for complex changes - ---- - -## Extractor Development - -### Creating a New Extractor - -1. **Study existing extractors:** - - `src/extractors/typescript/` - AST-based - - `src/extractors/python/` - Subprocess-based - -2. **Follow E-ADR-008:** - - [Extractor Development Guide](documentation/e-adr/E-ADR-008-Extractor-Development-Guide.md) - -3. **Create extractor:** - ```bash - mkdir src/extractors/mylanguage/ - # Create extractor files - ``` - -4. **Add validation tests:** - - See [Extractor Validation Quickstart](documentation/guides/extractor-validation-quickstart.md) - -5. **Register extractor:** - - Update `src/discovery/` to detect language - - Update `src/recon/phases/extraction.ts` - - Add to `SupportedLanguage` enum - -### Extractor Requirements - -- **Extract semantics** - Not syntax -- **Handle errors** - Don't crash on invalid code -- **Create relationships** - Emit import/dependency assertions -- **Validation tests** - Pass all validation requirements -- **Documentation** - Document extraction patterns +## Repository Standards ---- +- Keep changes focused and reviewable. +- Add or update tests when behavior changes. +- Update docs when CLI behavior, configuration, or architecture claims change. +- Prefer current ADR Kit records in `adrs/` and `SYSTEM-OVERVIEW.md` over legacy narrative docs. -## Common Development Tasks +## Architecture References -### Adding a New Feature +- Generated repo overview: `SYSTEM-OVERVIEW.md` +- Current ADRs: `adrs/` +- Rendered ADR docs: `adrs/rendered/` +- Project metadata: `PROJECT.yaml` +- Architecture overview: `documentation/architecture.md` -1. Create feature branch -2. Implement feature -3. Add tests -4. Update documentation -5. Run pre-commit checks -6. Create PR +## Reporting Issues -### Fixing a Bug - -1. Create fix branch -2. Write failing test (if possible) -3. Fix bug -4. Verify test passes -5. Update documentation if behavior changed -6. Create PR - -### Refactoring - -1. Create refactor branch -2. Ensure tests cover area -3. Refactor incrementally -4. Keep tests passing -5. Update documentation if APIs change -6. Create PR - ---- - -## Getting Help - -### Questions? - -- **Documentation:** Check `documentation/` and `instructions/` -- **E-ADRs:** See `documentation/e-adr/` for design decisions -- **Issues:** Search existing issues before creating new ones - -### Reporting Bugs - -Include: -- ste-runtime version: `ste --version` -- Node.js version: `node --version` -- Error messages (full output) -- Steps to reproduce -- Configuration (sanitized) - -### Feature Requests - -Include: -- Use case description -- Expected behavior -- Why it's valuable -- Potential implementation approach - ---- - -## Recognition - -When contributions are accepted, contributors will be recognized in: -- `CONTRIBUTORS.md` (if created) -- Release notes -- Project documentation - ---- +When reporting a bug, include: +- ste-runtime version +- Node.js version +- command run +- full error output +- relevant config snippets ## License -STE Runtime is licensed under the Apache 2.0 License. - ---- - -## Questions or Feedback? - -While external contributions are not currently being accepted, questions, feedback, and discussions are welcome through: -- GitHub Issues (for bug reports and feature requests) -- Documentation improvements (via issues or discussions) - ---- - -**Note:** This guide will be updated when the project is ready to accept contributions. Thank you for your interest in STE Runtime! - +By contributing ideas, issues, or documentation feedback, you agree that resulting project changes remain under the Apache 2.0 license used by this repository. diff --git a/MATURITY.md b/MATURITY.md index d17ba6b..650d117 100644 --- a/MATURITY.md +++ b/MATURITY.md @@ -35,7 +35,7 @@ ste-runtime is a **component implementation and research prototype** of the [STE ### Why No Autonomy? -Per [E-ADR-003: CEM Implementation Deferral](documentation/e-adr/E-ADR-003-CEM-Deferral.md): +Per [E-ADR-003: CEM Implementation Deferral](documentation/e-adr-archived/E-ADR-003-CEM-Deferral.md): - **CEM (domain invariants) not implemented** — No definitions of valid software engineering semantics - **RSS invariant mapping missing** — RSS outputs graph + source, but not the invariants that bound LLM reasoning @@ -85,7 +85,7 @@ ste-runtime lacks critical components for robust local tool: **Impact:** RSS currently outputs semantic graph + source code, but not the invariants that constrain what the LLM can reason over. This is the critical missing piece for governed AI assistance. -**Blocker:** CEM deferred per [E-ADR-003](documentation/e-adr/E-ADR-003-CEM-Deferral.md) +**Blocker:** CEM deferred per [E-ADR-003](documentation/e-adr-archived/E-ADR-003-CEM-Deferral.md) #### 2. Robustness and Performance @@ -228,7 +228,7 @@ To make ste-runtime production-ready **as a local developer tool** would require **Why critical:** RSS currently outputs semantic graph + source code. Without invariants, the LLM has no constraints on what it can reason over. CEM provides the domain knowledge that bounds AI cognition. -**Blocker:** CEM deferred per [E-ADR-003](documentation/e-adr/E-ADR-003-CEM-Deferral.md) +**Blocker:** CEM deferred per [E-ADR-003](documentation/e-adr-archived/E-ADR-003-CEM-Deferral.md) ### 2. Robustness and Error Handling @@ -351,7 +351,7 @@ Production-readiness would require significant additional work (see "Path to Pro ## Related Documentation -- [E-ADR-003: CEM Implementation Deferral](documentation/e-adr/E-ADR-003-CEM-Deferral.md) — Why autonomy is not supported +- [E-ADR-003: CEM Implementation Deferral](documentation/e-adr-archived/E-ADR-003-CEM-Deferral.md) — Why autonomy is not supported - [CONTRIBUTING.md](CONTRIBUTING.md) — Development status and future contribution process - [Architecture Documentation](documentation/architecture.md) — Technical architecture (current implementation) - [STE Specification](https://github.com/egallmann/ste-spec) — Complete STE Runtime architecture @@ -362,3 +362,5 @@ Production-readiness would require significant additional work (see "Path to Pro All claims about capabilities, maturity, and production-readiness should reference this document. + + diff --git a/PROJECT.yaml b/PROJECT.yaml new file mode 100644 index 0000000..f621023 --- /dev/null +++ b/PROJECT.yaml @@ -0,0 +1,59 @@ +schema_version: "1.0" +type: project_metadata + +project: + name: "ste-runtime" + description: "STE Runtime experimental component implementing RECON, RSS, MCP integration, and self-documenting semantic extraction workflows." + type: "tool" + +ownership: + team: "architecture-systems" + tech_lead: "@egallmann" + +repository: + url: "github.com/egallmann/ste-runtime" + primary_branch: "develop" + +implementation_identifiers: + package_name: "ste-runtime" + module_path: "src/" + +automation: + auto_merge_allowed: false + requires_human_review: true + comfort_level: "conservative" + +development_methodology: + approach: "test-after" + testing_framework: "vitest" + quality_gates: + - type_checking + - test_suite_passing + - linting + - dependency_security_audit + rationale: | + The repository currently enforces compilation, automated tests, and RECON + self-documentation through CI. Linting is part of local and contributor + hygiene expectations. + authority: "README.md, .github/workflows/test.yml, package.json" + +integrations: + scm: + type: github + required_approvers: ["@egallmann"] + ci: + type: github_actions + workflow_path: ".github/workflows/test.yml" + required_checks: + - build + - test + - recon-self-documentation + +compliance: + security_level: medium + data_classification: public + license: "Apache-2.0" + +architecture_documentation: + adr_directory: "adrs/" + manifest_path: "adrs/manifest.yaml" diff --git a/README.md b/README.md index 86d4759..bf2c398 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,14 @@ --- +## Start Here + +If you need fast repo orientation, start with [SYSTEM-OVERVIEW.md](SYSTEM-OVERVIEW.md). + +`SYSTEM-OVERVIEW.md` is a generated artifact from ADR Kit. Refresh generated ADR docs with ADR Kit tooling, not by hand-editing generated outputs. + +--- + > **⚠️ EXPERIMENTAL STATUS — NOT PRODUCTION-READY** > > ste-runtime is a **research prototype and component implementation** of the STE Specification. @@ -293,25 +301,20 @@ const impact = blastRadius(ctx, 'data/entity/UsersTable'); ## Documentation ### Architecture Decision Records -- [Architecture Decisions](adrs/) - Machine-verifiable ADRs in ADR Kit format -- [ADR Manifest](adrs/manifest.yaml) - Discovery index (11 ADRs, 13 invariants) +- [System Overview](SYSTEM-OVERVIEW.md) - Generated AI-first orientation for this repo +- [ADR Directory](adrs/) - Machine-verifiable ADR source records +- [ADR Manifest](adrs/manifest.yaml) - Generated ADR discovery index +- [Rendered ADR Docs](adrs/rendered/) - Generated markdown views of ADR source - [Migration History](adrs/MIGRATION.md) - E-ADR to ADR Kit migration details -- [Archived E-ADRs](documentation/e-adr-archived/) - Original exploratory ADRs (deprecated) ### Architecture - [System Architecture](documentation/architecture.md) - Complete technical architecture of ste-runtime - [Architecture Diagrams](documentation/diagrams/) - Visual architecture documentation -### Getting Started -- [Getting Started Tutorial](documentation/guides/getting-started.md) - Step-by-step guide for new users +### Guides +- [Guides Index](documentation/guides/README.md) - Curated operational guide set - [Configuration Reference](documentation/guides/configuration-reference.md) - Complete `ste.config.json` reference -- [FAQ](documentation/guides/faq.md) - Frequently asked questions -- [Glossary](documentation/guides/glossary.md) - Terminology and definitions - -### User Guides - [MCP Setup Guide](documentation/guides/mcp-setup.md) - Set up ste-runtime with Cursor IDE -- [Pre-Commit Hook Setup](documentation/guides/pre-commit-hook-setup.md) - Code quality enforcement -- [Dual-Repo Workflow](documentation/guides/dual-repo-workflow.md) - Managing ste-runtime in projects - [Troubleshooting Guide](documentation/guides/troubleshooting.md) - Common issues and solutions ### Instructions @@ -323,16 +326,16 @@ const impact = blastRadius(ctx, 'data/entity/UsersTable'); | [instructions/recon-incremental.md](instructions/recon-incremental.md) | Incremental mode internals | Contributors | ### Architecture & Design -- [System Architecture](documentation/architecture.md) - Complete technical architecture of ste-runtime +- [System Overview](SYSTEM-OVERVIEW.md) - Fastest correct orientation path +- [Architecture Decision Records](adrs/) - ADR Kit source authority +- [Rendered ADR Docs](adrs/rendered/) - Generated markdown projections - [Alternatives Comparison](documentation/reference/alternatives-comparison.md) - How ste-runtime compares to tree-sitter, LSP, Kythe, Sourcegraph -- [Architecture Decision Records](adrs/) - ADR Kit format (machine-verifiable) - [Architecture Diagrams](documentation/diagrams/) - Visual architecture documentation -- [Reference Documentation](documentation/reference/) - Technical deep-dives ### Contributing - [Contributing Guide](CONTRIBUTING.md) - Development standards and future contribution process - **Note:** External contributions are not currently being accepted. This guide is for future reference. -- [Extractor Development Guide](documentation/e-adr-archived/E-ADR-008-Extractor-Development-Guide.md) - Create custom extractors +- [PROJECT Metadata](PROJECT.yaml) - Repo metadata for ADR Kit tooling --- @@ -441,7 +444,7 @@ ste-runtime/ ├── fixtures/ # Test fixtures ├── .ste/ # Example: Semantic state for parent project ├── .ste-self/ # Self-documentation (npm run recon:self) -└── ste-spec/ # Git submodule: STE specification +└── adrs/ # ADR Kit decisions and migration metadata ``` **Note:** `.ste-self/` contains ste-runtime's own semantic graph, generated by running RECON on itself. This serves as both a reference implementation and a working example of AI-DOC structure. @@ -460,8 +463,6 @@ The complete STE architecture includes additional runtime services not implement **See:** [STE Architecture Specification](https://github.com/egallmann/ste-spec/tree/main/ste-spec/architecture) for the complete system architecture. -The full specification is available via git submodule: [spec/ste-spec](spec/ste-spec/) - **Key architectural concepts:** - **AI-DOC**: 13-domain documentation structure - **RECON**: Reconciliation engine for semantic extraction @@ -469,7 +470,7 @@ The full specification is available via git submodule: [spec/ste-spec](spec/ste- - **Invariants**: Constraints that bound system behavior - **Validation Protocols**: Multi-phase validation pipeline -**See [ste-spec/ste-spec/README.md](ste-spec/ste-spec/README.md) for the full specification.** +**See the public [ste-spec repository](https://github.com/egallmann/ste-spec) for the full specification.** --- @@ -492,7 +493,6 @@ The full specification is available via git submodule: [spec/ste-spec](spec/ste- **Known Limitations:** - ⚠️ TypeScript extractor does not capture JSDoc comments (search by name works, search by purpose limited) - ⚠️ RSS search works on function names and paths, not inline documentation text -- See `documentation/issues/ISSUE-001-typescript-extractor-missing-jsdoc.md` for details **In Progress:** - JSDoc extraction for TypeScript (description, params, returns, examples) @@ -533,7 +533,7 @@ ste-runtime is **designed to be forked and extended**. Expected use cases: 5. **Run `npm run recon:self`** to document your changes 6. **Use RSS** to query and validate your implementation -See [documentation/e-adr-archived/E-ADR-008-Extractor-Development-Guide.md](documentation/e-adr-archived/E-ADR-008-Extractor-Development-Guide.md) for detailed guidance. +Use [PROJECT.yaml](PROJECT.yaml), [SYSTEM-OVERVIEW.md](SYSTEM-OVERVIEW.md), and [CONTRIBUTING.md](CONTRIBUTING.md) as the current extension starting points. ### Contributions to Main Repository @@ -595,3 +595,6 @@ Built on the shoulders of: **Questions?** See [instructions/README.md](instructions/README.md) for detailed guides. + + + diff --git a/SYSTEM-OVERVIEW.md b/SYSTEM-OVERVIEW.md new file mode 100644 index 0000000..55c9083 --- /dev/null +++ b/SYSTEM-OVERVIEW.md @@ -0,0 +1,260 @@ + + +--- +document_type: system-overview +audience: ai-first +project: ste-runtime +status: active +purpose: > + Single-file orientation for AI and human contributors. Use this file first to discover repository authority, canonical workflows, generated documentation, and safe extension points before making changes. +authority_order: + - PROJECT.yaml PROJECT.yaml + - adrs/ adrs/ + - adrs/manifest.yaml adrs/manifest.yaml + - package.json package.json + - src/ src/ +first_read: true +last_updated: generated-from-source +generation_rule: > + Generated by SystemOverviewGenerator. Edit repository metadata, ADRs, or the generator/template, not this file directly. +--- + +# SYSTEM-OVERVIEW + +## Why This File Exists + +This file is the fastest correct orientation path for an AI working in this repository. + +Its job is to prevent two common failures: + +1. Missing project-native capabilities that already exist, such as generators, validators, and CLI commands. +2. Making path, scope, or artifact assumptions that conflict with repository authority. + +Read this file before writing code, generating artifacts, or hand-crafting repository outputs. + +## System Purpose + +`ste-runtime` is a tool with architecture described through ADR Kit artifacts. + +STE Runtime experimental component implementing RECON, RSS, MCP integration, and self-documenting semantic extraction workflows. + +It currently declares 11 ADRs, 13 invariants, and 2 tracked gaps. + +It provides: + +- JSON Schema contracts for ADR artifacts +- Pydantic models for typed parsing +- ADR records under `adrs/` +- generated manifest and rendered documentation +- repository-specific implementation and validation workflows + +Primary package manager: `npm`. + +## Authority Hierarchy + +Use this order when resolving ambiguity: + +1. [`PROJECT.yaml`](PROJECT.yaml) + Project-local metadata: ownership, automation posture, repository intent, and ADR locations. +2. [`adrs/`](adrs/) + Architectural authority for this repository. +3. [`adrs/manifest.yaml`](adrs/manifest.yaml) + Generated ADR index used for fast discovery and summary-level reasoning. +4. [`package.json`](package.json) + Runtime, scripts, package metadata, and Node-based workflow authority. +5. [`src/`](src/), [`scripts/`](scripts/), [`python-scripts/`](python-scripts/) + Primary implementation surface. + +If code and ADRs disagree, treat the ADRs and project policy as authoritative unless the task is explicitly to correct the ADRs. + +## First Discovery Order + +When an AI enters this repo cold, use this order: + +1. Read [`PROJECT.yaml`](PROJECT.yaml). +2. Read this file. +3. Inspect [`adrs/`](adrs/) and [`adrs/manifest.yaml`](adrs/manifest.yaml). +4. Inspect [`adrs/rendered/`](adrs/rendered/) for generated human-readable ADR views. +5. Inspect [`package.json`](package.json) for scripts, runtime boundaries, and entrypoints. +6. Inspect the primary implementation surface: [`src/`](src/), [`scripts/`](scripts/), [`python-scripts/`](python-scripts/). +7. Inspect [`.github/workflows/test.yml`](.github/workflows/test.yml) for enforced CI checks. +8. Only then decide whether new code or documentation is needed. + +Do not start by hand-writing artifacts if a generator or validator already exists. + +## Canonical Capabilities + +Core implementation areas: + +- ADR authority: [`adrs/`](adrs/) +- Generated ADR index: [`adrs/manifest.yaml`](adrs/manifest.yaml) +- Rendered ADR markdown: [`adrs/rendered/`](adrs/rendered/) +- Implementation surface: [`src/`](src/), [`scripts/`](scripts/), [`python-scripts/`](python-scripts/) +- ADR inventory: 11 ADRs, 13 invariants, 2 total gaps. + +Primary CLI capabilities: + +- `adr generate-rendered-docs --scope C:\Users\Erik\Documents\Projects\ste-runtime` +- `adr generate-system-overview --scope C:\Users\Erik\Documents\Projects\ste-runtime` +- `adr validate-generated-docs --scope C:\Users\Erik\Documents\Projects\ste-runtime` +- `adr validate-system-overview --scope C:\Users\Erik\Documents\Projects\ste-runtime` +- `npm run build` +- `npm run lint` +- `npm run test` +- `npm run recon:self` + +## Artifact Model + +Repository artifact classes: + +- ADRs: [`adrs/logical/`](adrs/logical/) and [`adrs/physical/`](adrs/physical/) +- Derived manifest: [`adrs/manifest.yaml`](adrs/manifest.yaml) +- Rendered ADR markdown: [`adrs/rendered/`](adrs/rendered/) +- AI-first overview: [`SYSTEM-OVERVIEW.md`](SYSTEM-OVERVIEW.md) +- Project metadata: [`PROJECT.yaml`](PROJECT.yaml) +- Node package metadata: [`package.json`](package.json) + +Subtype authority comes from document content, not folders: + +- `adr_type` +- `id` + +Do not infer physical subtype from directory names when frontmatter already tells you the type. + +## ADR Taxonomy + +Use this type model when reasoning about repository architecture artifacts: + +- `ADR-L-XXXX`: Conceptual logical design: capabilities, boundaries, contracts, constraints, and invariants. +- `ADR-V-XXXX`: Vision-oriented logical ADRs that describe future-state capabilities and target evolution. +- `ADR-P-XXXX`: Broad physical implementation specifications. +- `ADR-PS-XXXX`: High-level system design with major component boxes, relationships, and topology. +- `ADR-PC-XXXX`: Implementation-ready physical component specifications. + +## Canonical Workflows + +### Generate rendered ADR markdown + +Run `adr generate-rendered-docs --scope C:\Users\Erik\Documents\Projects\ste-runtime`. Do not hand-edit files under `adrs/rendered/`. + +### Regenerate this overview + +Run `adr generate-system-overview --scope C:\Users\Erik\Documents\Projects\ste-runtime`. Do not hand-edit `SYSTEM-OVERVIEW.md`. + +### Validate generated documentation + +Run `adr validate-generated-docs --scope C:\Users\Erik\Documents\Projects\ste-runtime` and `adr validate-system-overview --scope C:\Users\Erik\Documents\Projects\ste-runtime`. + +### Build the project + +Run `npm run build`. + +### Lint the project + +Run `npm run lint`. + +### Run automated tests + +Run `npm test`. + +### Refresh semantic self-documentation + +Run `npm run recon:self` and review generated state noise before committing. + +### Respect project quality gates + +Current declared gates: type_checking, test_suite_passing, linting, dependency_security_audit. + +## Tooling Priority Rules + +These are operational rules for AI contributors: + +1. If a generator exists for the target artifact, use or extend it before hand-crafting output. +2. If a validator exists for the target artifact, run it before declaring work complete. +3. Treat ADR source and project metadata as authoritative over stale narrative docs. +4. Generated artifacts should be regenerated, not edited in place. + +## Path and Scope Rules + +These rules are mandatory: + +1. Resolve repository work from the explicit project scope root, not an arbitrary parent workspace folder. +2. Treat sibling repositories as separate scopes unless a workflow explicitly says otherwise. +3. Place architectural authority under `adrs/` and keep generated views under `adrs/rendered/`. +4. Do not infer authority from folder names alone when structured metadata already exists. + +Use ADR metadata and project metadata as placement authority before relying on directory folklore. + +## High-Value Invariants + +Start here when you need the non-negotiables: + +- [`INV-0001`](adrs/manifest.yaml) - Single repository only: RECON discovers files within the current repository. Cross-repository reconciliation is out of scope. +- [`INV-0002`](adrs/manifest.yaml) - Incremental reconciliation: Only files that have changed since the last run are re-extracted (when timestamp detection is available). +- [`INV-0003`](adrs/manifest.yaml) - Configurable source directories: Specified via `ste.config.json` or auto-detected. +- [`INV-0004`](adrs/manifest.yaml) - Shallow extraction: Extract structural elements (functions, classes, imports, exports) without deep semantic analysis. +- [`INV-0005`](adrs/manifest.yaml) - No deep semantic analysis: Do not attempt to understand function behavior, side effects, or complex type flows. +- [`INV-0006`](adrs/manifest.yaml) - Multi-language support: TypeScript, Python, CloudFormation, JSON (see E-ADR-005), Angular, CSS/SCSS (see E-ADR-006). +- [`INV-0007`](adrs/manifest.yaml) - Portable execution: RECON must work when dropped into any project. +- [`INV-0008`](adrs/manifest.yaml) - Provisional mapping: Normalization to AI-DOC schema is best-effort, not canonical. +- [`INV-0009`](adrs/manifest.yaml) - Schema evolution expected: The AI-DOC schema is still evolving; normalization will change. +- [`INV-0010`](adrs/manifest.yaml) - ID stability: Element IDs should be stable across runs for the same source element. + +Practical meaning: + +- schema-invalid artifacts are not acceptable +- deprecated runtime APIs are not acceptable +- dependency security must be checked +- dependency freshness must be surfaced continuously +- derived artifacts must be regenerated, not manually drifted + +## Fast Target Discovery + +Use these heuristics before implementing: + +- "Need the current architecture decision?": + Start in `adrs/` and use `adrs/rendered/` only as generated views. +- "Need a repo summary quickly?": + Read `adrs/manifest.yaml` before sampling individual ADR files. +- "Need the implementation surface?": + Inspect `src/`, `scripts/`, `python-scripts/` before searching the entire repo. +- "Need runtime entrypoints?": + Inspect the `bin` map in `package.json` before tracing CLI files manually. + +## Common Failure Modes + +Avoid these: + +- editing generated artifacts directly instead of regenerating them +- treating archived or local-only docs as current authority +- skipping manifest or ADR review and relying on stale README prose +- assuming the parent workspace folder is the project scope + +## Completion Criteria + +A change is not complete unless relevant checks were run. + +Minimum close-out expectation: + +- regenerate derived ADR artifacts if ADR inputs changed +- validate `SYSTEM-OVERVIEW.md` if orientation-relevant workflows or authority changed +- run `npm run lint` when the change touches that concern +- run `npm run build` when the change touches that concern +- run `npm run test` when the change touches that concern +- run `npm run recon:self` when the change touches that concern +- satisfy declared quality gates: type_checking, test_suite_passing, linting, dependency_security_audit + +## One-Line Orientation + +If you only remember one thing: + +ste-runtime is ADR-first, generated-doc-aware, and scope-bound. Start from structured authority, then move into implementation. \ No newline at end of file diff --git a/adrs/manifest.yaml b/adrs/manifest.yaml index 9443952..cb339ea 100644 --- a/adrs/manifest.yaml +++ b/adrs/manifest.yaml @@ -1,10 +1,18 @@ +# integrity_schema_version: 1 +# generated: deterministic_projection_v1 +# artifact_kind: manifest +# generator_id: adr-manifest +# generator_version: 1 +# hash_algorithm: sha256 +# source_hash: 35089a8f409a9a8caa5a8218027b4a64fd5e7ba930f47c8b62ceb8c96a363a91 +# rendered_hash: 893aeea4594bb2fe538f14239fb3b69400dfffcd41ed8b8cfc7324b8c1c21d0d + # manifest.yaml - GENERATED FROM ADRs, DO NOT EDIT # This file is automatically generated by 'adr generate-manifest' # To update: modify ADRs, then regenerate manifest - schema_version: '1.0' type: manifest -generated_date: '2026-03-08T07:38:42.165256Z' +generated_date: '2026-03-12T05:40:10Z' generated_from: adrs/**/*.yaml adrs: - id: ADR-L-0001 @@ -201,7 +209,7 @@ adrs: type: physical title: Angular and CSS/SCSS Semantic Extraction status: proposed - file_path: adrs\physical\ADR-P-0003-angular-and-css\scss-semantic-extraction.yaml + file_path: adrs\physical\ADR-P-0003-angular-and-cssscss-semantic-extraction.yaml domains: - extraction - frontend @@ -449,6 +457,7 @@ logical_to_physical_map: - ADR-P-0004 ADR-L-0006: - ADR-P-0004 +system_to_components_map: {} invariants: - id: INV-0001 statement: 'Single repository only: RECON discovers files within the current repository. @@ -527,6 +536,25 @@ invariants: defined_in: ADR-L-0001 enforced_by: [] enforcement_level: must +entities: +- entity_id: DEC-0001 + entity_type: decision + name: RECON executes provisionally, generating semantic pressure without assuming + correctness. + introduced_by: ADR-L-0001 + lifecycle_stage: accepted +- entity_id: COMP-0001 + entity_type: component + name: RSS CLI + introduced_by: ADR-P-0001 + lifecycle_stage: accepted +- entity_id: COMP-0002 + entity_type: component + name: CSS/SCSS Extractor + introduced_by: ADR-P-0003 + lifecycle_stage: proposed +requirements_snapshots: [] +decision_ledgers: [] gaps_summary: total: 2 blocking: 0 @@ -538,9 +566,14 @@ statistics: total_adrs: 11 logical_adrs: 6 physical_adrs: 5 + physical_system_adrs: 0 + physical_component_adrs: 0 decision_adrs: 0 total_decisions: 6 total_invariants: 13 total_components: 7 total_gaps: 2 blocking_gaps: 0 + total_entities: 3 + total_requirements_snapshots: 0 + total_decision_ledgers: 0 diff --git a/adrs/rendered/ADR-L-0001.md b/adrs/rendered/ADR-L-0001.md index 4979b35..081c299 100644 --- a/adrs/rendered/ADR-L-0001.md +++ b/adrs/rendered/ADR-L-0001.md @@ -1,3 +1,14 @@ + + # ADR-L-0001: RECON Provisional Execution for Project-Level Semantic State **Status:** accepted @@ -6,6 +17,7 @@ **Domains:** recon, architecture, governance **Tags:** recon, provisional-execution, semantic-state, ste-compliance +**Related ADRs:** ADR-L-0002, ADR-L-0003 diff --git a/adrs/rendered/ADR-L-0002.md b/adrs/rendered/ADR-L-0002.md index c7a78db..a0c27ed 100644 --- a/adrs/rendered/ADR-L-0002.md +++ b/adrs/rendered/ADR-L-0002.md @@ -1,3 +1,14 @@ + + # ADR-L-0002: RECON Self-Validation Strategy **Status:** accepted @@ -6,6 +17,7 @@ **Domains:** recon, validation, governance **Tags:** recon, validation, self-validation, ste-compliance +**Related ADRs:** ADR-L-0001 diff --git a/adrs/rendered/ADR-L-0003.md b/adrs/rendered/ADR-L-0003.md index a25fadf..d731304 100644 --- a/adrs/rendered/ADR-L-0003.md +++ b/adrs/rendered/ADR-L-0003.md @@ -1,3 +1,14 @@ + + # ADR-L-0003: CEM Implementation Deferral **Status:** accepted @@ -6,6 +17,7 @@ **Domains:** architecture, governance, cem **Tags:** cem, deferral, meta-decision, build-order +**Related ADRs:** ADR-L-0001 diff --git a/adrs/rendered/ADR-L-0004.md b/adrs/rendered/ADR-L-0004.md index b7f1668..5d5b804 100644 --- a/adrs/rendered/ADR-L-0004.md +++ b/adrs/rendered/ADR-L-0004.md @@ -1,3 +1,14 @@ + + # ADR-L-0004: Watchdog Authoritative Mode for Workspace Boundary **Status:** accepted @@ -6,6 +17,7 @@ **Domains:** watchdog, governance, workspace-boundary **Tags:** watchdog, file-watching, workspace-boundary, ste-compliance +**Related ADRs:** ADR-L-0001 diff --git a/adrs/rendered/ADR-L-0005.md b/adrs/rendered/ADR-L-0005.md index 635fa53..8ef9b15 100644 --- a/adrs/rendered/ADR-L-0005.md +++ b/adrs/rendered/ADR-L-0005.md @@ -1,3 +1,14 @@ + + # ADR-L-0005: Self-Configuring Domain Discovery **Status:** proposed diff --git a/adrs/rendered/ADR-L-0006.md b/adrs/rendered/ADR-L-0006.md index c94d2b9..c8320ca 100644 --- a/adrs/rendered/ADR-L-0006.md +++ b/adrs/rendered/ADR-L-0006.md @@ -1,3 +1,14 @@ + + # ADR-L-0006: Conversational Query Interface for RSS **Status:** proposed diff --git a/adrs/rendered/ADR-P-0001.md b/adrs/rendered/ADR-P-0001.md index 42c66be..dbf9428 100644 --- a/adrs/rendered/ADR-P-0001.md +++ b/adrs/rendered/ADR-P-0001.md @@ -1,3 +1,14 @@ + + # ADR-P-0001: RSS CLI Implementation for Developer-Invoked Graph Traversal **Status:** accepted @@ -8,6 +19,7 @@ **Implements Logical:** ADR-L-0002 **Technologies:** cli, file-discovery, file-watching, graph-traversal, mcp, node.js, schema-validation, testing, typescript, yaml +**Related ADRs:** ADR-L-0003, ADR-P-0004 --- diff --git a/adrs/rendered/ADR-P-0002.md b/adrs/rendered/ADR-P-0002.md index 7293a85..8813a38 100644 --- a/adrs/rendered/ADR-P-0002.md +++ b/adrs/rendered/ADR-P-0002.md @@ -1,3 +1,14 @@ + + # ADR-P-0002: JSON Data Extraction for Compliance Controls and Schemas **Status:** proposed @@ -8,6 +19,7 @@ **Implements Logical:** ADR-L-0001 **Technologies:** cli, data-extraction, file-discovery, file-watching, json, mcp, node.js, schema-validation, testing, typescript, yaml +**Related ADRs:** ADR-P-0003, ADR-P-0005 --- diff --git a/adrs/rendered/ADR-P-0003.md b/adrs/rendered/ADR-P-0003.md index 6c43f80..c549965 100644 --- a/adrs/rendered/ADR-P-0003.md +++ b/adrs/rendered/ADR-P-0003.md @@ -1,3 +1,14 @@ + + # ADR-P-0003: Angular and CSS/SCSS Semantic Extraction **Status:** proposed @@ -8,6 +19,7 @@ **Implements Logical:** ADR-L-0001 **Technologies:** angular, ast-parsing, cli, css, file-discovery, file-watching, mcp, node.js, schema-validation, scss, testing, typescript, yaml +**Related ADRs:** ADR-P-0002, ADR-P-0005 --- diff --git a/adrs/rendered/ADR-P-0004.md b/adrs/rendered/ADR-P-0004.md index e007762..5b18dd0 100644 --- a/adrs/rendered/ADR-P-0004.md +++ b/adrs/rendered/ADR-P-0004.md @@ -1,3 +1,14 @@ + + # ADR-P-0004: ste-runtime MCP Server Implementation **Status:** accepted @@ -8,6 +19,7 @@ **Implements Logical:** ADR-L-0004, ADR-L-0006 **Technologies:** cli, file-discovery, file-watching, incremental-recon, mcp, node.js, schema-validation, stdio, testing, typescript, yaml +**Related ADRs:** ADR-P-0001 --- diff --git a/adrs/rendered/ADR-P-0005.md b/adrs/rendered/ADR-P-0005.md index 92717a4..d8c8ef9 100644 --- a/adrs/rendered/ADR-P-0005.md +++ b/adrs/rendered/ADR-P-0005.md @@ -1,3 +1,14 @@ + + # ADR-P-0005: Extractor Validation Requirements **Status:** accepted @@ -8,6 +19,7 @@ **Implements Logical:** ADR-L-0002 **Technologies:** cli, file-discovery, file-watching, mcp, node.js, schema-validation, testing, typescript, validation, yaml +**Related ADRs:** ADR-P-0002, ADR-P-0003 --- diff --git a/documentation/architecture.md b/documentation/architecture.md index c6b49b4..d6bb804 100644 --- a/documentation/architecture.md +++ b/documentation/architecture.md @@ -17,8 +17,8 @@ This document describes the **actual architecture of ste-runtime** — what has - Reference for contributors and users **Related Documents:** -- [STE Architecture Specification](../../spec/ste-spec/architecture/STE-Architecture.md) — Complete STE Runtime architecture -- [E-ADRs](../e-adr/) — Component-level architectural decisions +- [STE Architecture Specification](https://github.com/egallmann/ste-spec/tree/main/ste-spec/architecture) — Complete STE Runtime architecture +- [ADR Kit Records](../adrs/) — Component-level architectural decisions - [Architecture Diagrams](../diagrams/README.md) — Visual architecture diagrams --- @@ -108,7 +108,7 @@ flowchart TB - **Content-addressable** — Deterministic, reproducible state - **Self-validating** — 6-phase pipeline with validation -**See:** [E-ADR-001: RECON Provisional Execution](../e-adr/E-ADR-001-RECON-Provisional-Execution.md) +**See:** [ADR-L-0001: RECON Provisional Execution](../adrs/rendered/ADR-L-0001.md) --- @@ -135,9 +135,7 @@ flowchart TB - **Two-layer architecture** — Token efficiency + precision - **Deterministic traversal** — Same entry points → same context -**See:** -- [E-ADR-004: RSS CLI Implementation](../e-adr/E-ADR-004-RSS-CLI-Implementation.md) -- [Two-Layer Context Assembly](../innovations/Two-Layer-Context-Assembly.md) +**See:** [ADR-P-0001: RSS CLI Implementation](../adrs/rendered/ADR-P-0001.md) --- @@ -162,7 +160,7 @@ flowchart TB - **Auto-discovery** — Cursor automatically finds tools - **Context reload** — Automatic RSS graph reload after RECON -**See:** [E-ADR-011: ste-runtime MCP Server](../e-adr/E-ADR-011-ste-runtime-MCP-Server.md) +**See:** [ADR-P-0004: ste-runtime MCP Server](../adrs/rendered/ADR-P-0004.md) --- @@ -204,7 +202,7 @@ flowchart TB - **Smart debouncing** — Handles Cursor's streaming edits - **Transaction awareness** — Batches multi-file refactors -**See:** [E-ADR-007: Watchdog Authoritative Mode](../e-adr/E-ADR-007-Watchdog-Authoritative-Mode.md) +**See:** [ADR-L-0004: Watchdog Authoritative Mode](../adrs/rendered/ADR-L-0004.md) --- @@ -435,7 +433,7 @@ MCP query received ### 2. CEM Not Implemented -**Status:** Deferred per [E-ADR-003](../e-adr/E-ADR-003-CEM-Deferral.md). +**Status:** Deferred per [ADR-L-0003](../adrs/rendered/ADR-L-0003.md). **Impact:** No formal 9-stage execution lifecycle. @@ -512,7 +510,7 @@ MCP query received 3. Register in language detection 4. Add to normalization phase -**See:** [E-ADR-008: Extractor Development Guide](../e-adr/E-ADR-008-Extractor-Development-Guide.md) +**See:** [SYSTEM-OVERVIEW](../SYSTEM-OVERVIEW.md) ### Adding New RSS Operations @@ -526,21 +524,21 @@ MCP query received ## References -### E-ADRs (Exploratory Architectural Decision Records) +### ADR Kit Records -- [E-ADR-001: RECON Provisional Execution](../e-adr/E-ADR-001-RECON-Provisional-Execution.md) -- [E-ADR-002: RECON Self-Validation](../e-adr/E-ADR-002-RECON-Self-Validation.md) -- [E-ADR-003: CEM Deferral](../e-adr/E-ADR-003-CEM-Deferral.md) -- [E-ADR-004: RSS CLI Implementation](../e-adr/E-ADR-004-RSS-CLI-Implementation.md) -- [E-ADR-007: Watchdog Authoritative Mode](../e-adr/E-ADR-007-Watchdog-Authoritative-Mode.md) -- [E-ADR-011: ste-runtime MCP Server](../e-adr/E-ADR-011-ste-runtime-MCP-Server.md) +- [ADR-L-0001: RECON Provisional Execution](../adrs/rendered/ADR-L-0001.md) +- [ADR-L-0002: RECON Self-Validation](../adrs/rendered/ADR-L-0002.md) +- [ADR-L-0003: CEM Deferral](../adrs/rendered/ADR-L-0003.md) +- [ADR-P-0001: RSS CLI Implementation](../adrs/rendered/ADR-P-0001.md) +- [ADR-L-0004: Watchdog Authoritative Mode](../adrs/rendered/ADR-L-0004.md) +- [ADR-P-0004: ste-runtime MCP Server](../adrs/rendered/ADR-P-0004.md) ### Related Documentation - [Architecture Diagrams](../diagrams/README.md) — Visual architecture -- [Getting Started Guide](../guides/getting-started.md) — User onboarding +- [SYSTEM-OVERVIEW](../SYSTEM-OVERVIEW.md) — User onboarding - [Configuration Reference](../guides/configuration-reference.md) — Configuration options -- [STE Specification Architecture](../../spec/ste-spec/architecture/STE-Architecture.md) — Complete STE Runtime architecture +- [STE Specification Architecture](https://github.com/egallmann/ste-spec/tree/main/ste-spec/architecture) — Complete STE Runtime architecture --- @@ -557,3 +555,7 @@ MCP query received **Maintainer:** ste-runtime contributors + + + + diff --git a/documentation/e-adr-archived/E-ADR-001-RECON-Provisional-Execution.md b/documentation/e-adr-archived/E-ADR-001-RECON-Provisional-Execution.md deleted file mode 100644 index d767ac5..0000000 --- a/documentation/e-adr-archived/E-ADR-001-RECON-Provisional-Execution.md +++ /dev/null @@ -1,348 +0,0 @@ -# E-ADR-001: Provisional Execution of RECON for Project-Level Semantic State Pressure - -**Status:** Accepted -**Implementation:** Complete -**Date:** 2026-01-07 -**Author:** Erik Gallmann -**Authority:** Exploratory ADR (Reversible) - -> **Next Step:** Validate against ste-spec Section 4.5 (RECON) for ADR graduation. - ---- - -## Context - -The STE Architecture Specification defines RECON (Reconciliation Engine) as the mechanism for extracting semantic state from source code and populating AI-DOC. The question arose: How should RECON operate during the exploratory development phase when foundational components are still being built? - -Key tensions: - -1. **Canonical vs. Provisional State:** Should RECON produce canonical state that is authoritative for downstream systems? -2. **Automatic Resolution vs. Conflict Surfacing:** Should RECON automatically resolve conflicts or surface them for human judgment? -3. **Blocking vs. Non-Blocking:** Should RECON block development workflows when conflicts are detected? -4. **Single Repository vs. Multi-Repository:** What is the scope of RECON's reconciliation? - ---- - -## Decision - -**RECON executes provisionally, generating semantic pressure without assuming correctness.** - -RECON operates under the following constraints: - -| Constraint | Decision | -|------------|----------| -| State Authority | Provisional, not canonical | -| Conflict Resolution | Surface conflicts, do not resolve | -| Workflow Blocking | Never block commits or development | -| Scope | Single repository only | -| Execution Mode | Developer-invoked, not CI/CD | - ---- - -## Rationale - -### 1. Semantic Pressure Over Semantic Truth - -RECON exists to **observe how semantic truth breaks under change**, not to declare what truth is. During exploratory development, the extraction algorithms, normalization schemas, and conflict detection heuristics are all evolving. Declaring any output as "canonical" would be premature. - -By generating pressure without claiming correctness, RECON: -- Forces execution of incomplete implementations -- Surfaces edge cases and extraction gaps -- Generates learning evidence for future refinement -- Avoids false confidence in evolving algorithms - -### 2. Conflicts Require Human Judgment - -Automatic conflict resolution assumes the system understands developer intent. During this phase, RECON cannot reliably determine: -- Was a function renamed or deleted? -- Is a signature change intentional or accidental? -- Which version of a conflicting definition is correct? - -All conflicts are written to disk as YAML files in `.ste/state/conflicts/active/` for human review. RECON surfaces evidence; humans render judgment. - -### 3. Development Must Not Be Blocked - -RECON is a learning tool, not an enforcement mechanism. Blocking commits would: -- Create friction disproportionate to RECON's maturity -- Force developers to work around false positives -- Reduce willingness to run RECON frequently - -By remaining non-blocking, RECON encourages frequent execution and generates more learning data. - ---- - -## Specification - -### §5.1 Discovery Constraints - -- **Single repository only:** RECON discovers files within the current repository. Cross-repository reconciliation is out of scope. -- **Incremental reconciliation:** Only files that have changed since the last run are re-extracted (when timestamp detection is available). -- **Configurable source directories:** Specified via `ste.config.json` or auto-detected. - -### §5.2 Extraction Constraints - -- **Shallow extraction:** Extract structural elements (functions, classes, imports, exports) without deep semantic analysis. -- **No deep semantic analysis:** Do not attempt to understand function behavior, side effects, or complex type flows. -- **Multi-language support:** TypeScript, Python, CloudFormation, JSON (see E-ADR-005), Angular, CSS/SCSS (see E-ADR-006). -- **Portable execution:** RECON must work when dropped into any project. - -### §5.3 Normalization Constraints - -- **Provisional mapping:** Normalization to AI-DOC schema is best-effort, not canonical. -- **Schema evolution expected:** The AI-DOC schema is still evolving; normalization will change. -- **ID stability:** Element IDs should be stable across runs for the same source element. - -### §5.4 Self-Healing Semantic Maintenance - -**Updated 2026-01-07**: Corrected to comply with STE System Specification (normative). - -**Previous E-ADR (non-compliant):** Defined "exploratory mode" that surfaced all changes as conflicts. -**STE-spec (normative):** Defines slices as derived artifacts with self-healing maintenance. -**This E-ADR (now compliant):** Aligns with spec's derived artifacts model. - -#### Slices Are Like `dist/` - 100% Regenerated From Source - -``` -Source Code (Truth) - ↓ -RECON (Deterministic) - ↓ -Slices (Derived Artifacts) -``` - -**Principle**: Slices are to source code what `dist/app.js` is to `src/app.ts`. - -#### Self-Healing Behavior - -| Scenario | RECON Action | Rationale | -|----------|--------------|-----------| -| Source file modified | Extract fresh, update slice | Source changed → semantics changed | -| Source file unchanged, slice differs | Regenerate from source | Slice corrupted/manually edited → self-heal | -| Source file deleted | Delete corresponding slice | Source gone → semantics gone | -| New extractor added (E-ADR-006) | Extract with new extractor | Richer semantics available | -| Extractor logic improved | Re-extract all files | Better semantics available | - -**In ALL cases**: RECON authoritatively regenerates slices from source. No conflicts. No human review. - -#### The ONLY Way to Change Semantic State - -```yaml -To change semantic state: - 1. Modify source code → RECON extracts → Slices update - 2. Modify ste-runtime extractors → RECON extracts → Slices update - -You CANNOT change semantic state by: - Manually editing slices (will be overwritten on next RECON) - Manually editing graph files (will be regenerated) - Requesting AI to "update semantics" (AI must modify SOURCE CODE) -``` - -#### Validation Errors (NOT Conflicts) - -RECON may surface **validation errors** (not conflicts): - -| Error Class | Trigger | Action | -|-------------|---------|--------| -| `extractor_failure` | Extractor crashed | Log error, skip file, continue | -| `source_corruption` | Unparseable source file | Log error, skip file, continue | -| `filesystem_error` | Cannot read/write file | Log error, retry, escalate if persistent | - -These are **operational errors**, not semantic conflicts. They require fixing the source file or extractor, not human semantic judgment. - -#### Phase 6 Renamed: "State Validation & Self-Healing" - -Phase 6 is NOT "conflict detection" - it is: -1. **Validation**: Verify slices match source checksums -2. **Self-Healing**: Regenerate any slices that don't match -3. **Cleanup**: Remove orphaned slices (source deleted) - -**No conflicts exist in this model.** - -### §5.5 Population Constraints - -- **State is authoritative, not historical:** Each run produces the current truth, not a delta. -- **Create/Update/Delete semantics:** New slices are created, changed slices are updated, orphaned slices are deleted. -- **Orphan detection:** Slices from processed source files that no longer exist in code are removed. - ---- - -## Execution Model - -### Manual, Developer-Invoked - -RECON is designed for manual execution by developers: - -```bash -cd ste-runtime -npm run recon # Incremental reconciliation -npm run recon:full # Full reconciliation -npm run recon:self # Self-documentation mode -``` - -### NOT for Continuous Execution - -At this stage, RECON is **not designed for CI/CD or automatic execution**. Reasons: - -1. Extraction algorithms are evolving -2. False positive rate is unknown -3. Performance characteristics not established -4. Human oversight required for conflict resolution - ---- - -## Slice Storage: Content-Addressable Filenames - -**Decision Date:** 2026-01-07 -**Failure Mode Discovered:** Angular component filenames exceeded filesystem limits (200+ characters) - -### Problem Statement - -Initial implementation used descriptive filenames based on slice IDs: -``` -component-frontend-src-app-features-reports-report-views-control-effectiveness-report-control-effectiveness-report.component.ts-ControlEffectivenessReportComponent.yaml -``` - -**Failures observed:** -- Windows path limit: 260 characters (exceeded) -- Unix filename limit: 255 characters (exceeded) -- Special character sanitization complexity -- Performance degradation with long paths - -### Design Decision - -**Switched to content-addressable hashing for slice filenames.** - -**Rationale:** -1. **AI-DOC philosophy**: Slices are machine-readable, not human-edited -2. **Filesystem portability**: Works on all platforms (Windows, Unix, network drives) -3. **Performance**: Shorter paths improve I/O operations -4. **Determinism**: Same slice ID always produces same filename -5. **Source of truth**: Slice ID inside file is authoritative, not filename - -### Implementation - -```typescript -// Hash the slice ID (SHA-256, first 16 chars = 64 bits) -const hash = createHash('sha256') - .update(sliceId) - .digest('hex') - .substring(0, 16); - -const filename = `${hash}.yaml`; // "009bd442b992f055.yaml" -``` - -**Collision probability:** Effectively zero (<0.000000002% for 864 slices) - -### Example - -**Slice ID (inside file):** -```yaml -_slice: - id: function:backend/scripts/parser.py:parse_cloudformation - domain: graph - type: function -``` - -**Filename:** `009bd442b992f055.yaml` - -### Impact - -| Aspect | Before | After | -|--------|--------|-------| -| Max filename length | 250+ chars | 16 chars | -| Filesystem compatibility | Windows issues | Universal | -| Population throughput | 687 slices/sec | 766 slices/sec | -| Human readability | High (not needed) | Low (not needed) | - -**Debugging workflow:** -1. **Primary:** RSS graph traversal - `rss.query('component', { name: 'MyComponent' })` -2. **Secondary:** Grep on slice IDs - `grep -r "component:frontend" .ste/state/` -3. **Never:** Browse filenames (content-addressable hashes) - ---- - -## Consequences - -### Positive - -- RECON can execute immediately, generating learning pressure -- Conflicts surface early, before they become entrenched -- Developers maintain full control over semantic state acceptance -- Extraction algorithms can evolve without breaking workflows - -### Negative - -- No automated enforcement of semantic consistency -- Conflicts may accumulate if not reviewed -- Provisional state cannot be used for authoritative downstream systems - -### Mitigation - -- Document all conflicts for periodic human review -- Track conflict patterns to improve extraction algorithms -- Plan transition to canonical execution once algorithms stabilize - ---- - -## Constraints on Downstream Systems - -1. **No canonical consumption:** Downstream systems MUST NOT treat RECON output as canonical. Use ADF-published state for canonical consumption. - -2. **Conflict awareness required:** Any system reading RECON state MUST check for active conflicts. - -3. **Idempotency expected:** Running RECON multiple times on unchanged source SHOULD produce identical output. - ---- - -## Seven-Phase Execution Pipeline - -RECON executes seven phases per run: - -| Phase | Name | Purpose | -|-------|------|---------| -| 1 | Discovery | Identify files to process | -| 2 | Extraction | Extract semantic assertions | -| 3 | Inference | Infer relationships (DEFERRED) | -| 4 | Normalization | Map to AI-DOC schema | -| 5 | Population | Update AI-DOC state | -| 6 | Divergence | Detect and record conflicts | -| 7 | Self-Validation | Validate state (non-blocking, see E-ADR-002) | - ---- - -## Relationship to Other Decisions - -- **E-ADR-002 (RECON Self-Validation):** Validation is non-blocking and exploratory -- **E-ADR-003 (CEM Deferral):** CEM will orchestrate RECON in the future - ---- - -## Review Trigger - -This decision should be revisited when: - -1. Extraction algorithms reach stability -2. Conflict detection false positive rate is measured -3. CI/CD integration is required -4. Canonical state publication is needed -5. Human review of conflicts becomes prohibitive - ---- - -## Learning Log - -This section tracks observations from RECON execution to inform future refinement. - -| Date | Observation | Implication | -|------|-------------|-------------| -| 2026-01-07 | E-ADR created from code references | Documented implicit decisions explicitly | - ---- - -## References - -- STE Architecture Specification, Section 4.5: RECON -- STE Architecture Specification, Section 4.6: RSS Operations -- ISO/IEC/IEEE 42010:2022 Architecture Description - - diff --git a/documentation/e-adr-archived/E-ADR-002-RECON-Self-Validation.md b/documentation/e-adr-archived/E-ADR-002-RECON-Self-Validation.md deleted file mode 100644 index 4cfcb74..0000000 --- a/documentation/e-adr-archived/E-ADR-002-RECON-Self-Validation.md +++ /dev/null @@ -1,292 +0,0 @@ -# E-ADR-002: RECON Self-Validation, Non-Blocking - -**Status:** Accepted -**Implementation:** Complete -**Date:** 2026-01-07 -**Author:** Erik Gallmann -**Authority:** Exploratory ADR (Reversible) - -> **Next Step:** Validate against ste-spec validation requirements for ADR graduation. - ---- - -## Context - -RECON generates AI-DOC state from source code extraction. The question arose: How should RECON validate its own output to ensure consistency and quality? - -Key tensions: - -1. **Blocking vs. Non-Blocking:** Should validation failures halt RECON execution? -2. **Verdict vs. Evidence:** Should validation declare correctness or surface observations? -3. **Scope:** What aspects of AI-DOC state should be validated? -4. **Integration:** When does validation run in the RECON pipeline? - ---- - -## Decision - -**RECON self-validation is non-blocking, report-only, and exploratory.** - -Self-validation executes as Phase 7 of the RECON pipeline and: - -| Constraint | Decision | -|------------|----------| -| Execution | Never throws, never halts | -| Output | Generates evidence, not verdicts | -| Categories | ERROR / WARNING / INFO findings | -| Persistence | Reports written to `.ste/state/validation/` | - ---- - -## Rationale - -### 1. Non-Blocking Preserves Learning - -If validation blocked execution on every finding, RECON would become unusable during exploratory development. Many validation findings are informational or represent known limitations in extraction algorithms. - -By remaining non-blocking, validation: -- Captures all findings without losing work -- Allows developers to review findings at their discretion -- Generates historical data for pattern analysis -- Avoids false positive friction - -### 2. Evidence Over Verdicts - -During exploratory development, the validators themselves are evolving. A "verdict" implies confidence that is premature. Instead, validators generate: -- Observations about state structure -- Anomalies that may indicate issues -- Coverage gaps in extraction -- Repeatability concerns - -Developers interpret findings; validators do not judge. - -### 3. Categorization Enables Prioritization - -All findings are categorized: - -| Category | Meaning | Action | -|----------|---------|--------| -| ERROR | Structural issue that may indicate a bug | Investigate promptly | -| WARNING | Anomaly that may indicate a problem | Review when convenient | -| INFO | Observation for awareness | Log for future reference | - ---- - -## Validation Categories - -Self-validation covers five categories: - -### 1. Schema Integrity - -Validates that generated AI-DOC slices conform to expected structure: - -- Required fields present (`_slice.id`, `_slice.domain`, `_slice.type`) -- Field types correct -- Provenance metadata complete -- Reference structure valid - -### 2. Repeatability - -Validates that re-running RECON on unchanged source produces identical output: - -- Checksum comparison between runs -- Detects non-determinism in extraction -- Tracks historical checksums for trend analysis - -**Note:** Repeatability checks are optional and enabled via `--repeatability-check` flag. - -### 3. Graph Consistency - -Validates the relationship graph for structural integrity: - -- Forward references (`references`) point to existing slices -- Reverse references (`referenced_by`) are symmetric -- No orphaned references -- Import/export relationships consistent - -### 4. Identity Stability - -Validates that element IDs remain stable across runs: - -- Same source element produces same ID -- ID format follows conventions -- No ID collisions between different elements -- Renamed elements detected as new IDs - -### 5. Extraction Coverage - -Validates extraction completeness: - -- Source files in scope have corresponding AI-DOC entries -- No source files skipped unexpectedly -- Language-specific extractors ran successfully -- Extraction errors logged - ---- - -## Validator Implementation - -Each validator implements a common interface: - -```typescript -interface ValidatorContext { - assertions: NormalizedAssertion[]; - projectRoot: string; - sourceRoot: string; - stateDir: string; - repeatabilityCheck: boolean; -} - -type ValidationFinding = { - category: 'ERROR' | 'WARNING' | 'INFO'; - validator: string; - affected_artifacts: string[]; - description: string; - suggested_investigation?: string; -}; -``` - -Validators: - -| Validator | File | Purpose | -|-----------|------|---------| -| Schema | `schema-validator.ts` | Structural integrity | -| Repeatability | `repeatability-validator.ts` | Determinism verification | -| Graph | `graph-validator.ts` | Reference consistency | -| Identity | `identity-validator.ts` | ID stability | -| Coverage | `coverage-validator.ts` | Extraction completeness | - ---- - -## Report Generation - -Validation reports are written to `.ste/state/validation/`: - -``` -.ste/state/validation/ -├── latest.yaml # Most recent validation report -└── runs/ - └── .yaml # Historical validation runs -``` - -### Report Structure - -```yaml -validation_run: - timestamp: "2026-01-07T12:00:00.000Z" - recon_run_id: "recon-1736251200000" - validation_version: "1.0.0" - -summary: - total_findings: 5 - errors: 0 - warnings: 2 - info: 3 - -findings: - - category: WARNING - validator: coverage - affected_artifacts: - - "backend/lambda/handler.py" - description: "Source file has no corresponding AI-DOC entries" - suggested_investigation: "Check if file contains extractable elements" -``` - -### Report Verbosity - -Configurable via `--validation-verbosity`: - -| Level | Behavior | -|-------|----------| -| `summary` | Log summary counts only (default) | -| `detailed` | Log each finding | -| `silent` | No console output, write report only | - ---- - -## Integration with RECON Pipeline - -Self-validation executes as **Phase 7**, after divergence detection: - -``` -Phase 1: Discovery -Phase 2: Extraction -Phase 3: Inference -Phase 4: Normalization -Phase 5: Population -Phase 6: Divergence Detection -Phase 7: Self-Validation ← Runs here -``` - -### Phase 7 Guarantees - -- **Never throws exceptions:** All errors are caught and converted to findings -- **Always completes:** Even if individual validators crash -- **Always reports:** At minimum, a summary is logged -- **Never blocks:** RECON result is returned regardless of findings - ---- - -## Consequences - -### Positive - -- Continuous quality visibility without workflow disruption -- Historical trend data for extraction algorithm improvement -- Early detection of regression in extractors -- Developer confidence through transparency - -### Negative - -- Findings may be ignored if too numerous -- No enforcement of quality gates -- Report accumulation without review - -### Mitigation - -- Periodic finding review as part of development process -- Track finding counts over time for trend analysis -- Prioritize ERROR findings for immediate investigation -- Use findings to guide extractor improvements - ---- - -## Constraints - -1. **Non-blocking is absolute:** Validation MUST NOT throw exceptions or halt RECON. - -2. **Crash isolation:** If a validator crashes, the crash is logged as an ERROR finding and other validators continue. - -3. **No side effects:** Validators MUST NOT modify AI-DOC state; they are read-only observers. - -4. **Deterministic output:** Given the same input, validators MUST produce the same findings. - ---- - -## Relationship to Other Decisions - -- **E-ADR-001 (RECON Provisional Execution):** Self-validation supports provisional execution by generating evidence without blocking -- **E-ADR-003 (CEM Deferral):** CEM will eventually orchestrate validation with governance policies - ---- - -## Review Trigger - -This decision should be revisited when: - -1. Validators reach maturity and false positive rate is low -2. Quality gates are needed for CI/CD integration -3. Findings consistently go unreviewed -4. Canonical state publication requires validation guarantees - ---- - -## References - -- STE Architecture Specification, Section 4.5: RECON -- E-ADR-001: Provisional Execution of RECON -- ISO/IEC/IEEE 42010:2022 Architecture Description - - - - diff --git a/documentation/e-adr-archived/E-ADR-003-CEM-Deferral.md b/documentation/e-adr-archived/E-ADR-003-CEM-Deferral.md deleted file mode 100644 index 02db416..0000000 --- a/documentation/e-adr-archived/E-ADR-003-CEM-Deferral.md +++ /dev/null @@ -1,145 +0,0 @@ -# E-ADR-003: CEM Implementation Deferral - -**Status:** Accepted -**Implementation:** N/A (Deferral Decision) -**Date:** 2026-01-07 -**Author:** Erik Gallmann -**Authority:** Exploratory ADR (Reversible) - -> **Next Step:** Revisit when foundation components (RECON, AI-DOC, RSS) reach stability. - ---- - -## Context - -The STE Architecture Specification (ste-spec) defines a 9-stage Cognitive Execution Model (CEM): - -``` -Perception → Orientation → Analysis → Deliberation → -Planning → Execution → Observation → Reflection → Adaptation -``` - -CEM is intended to orchestrate governed AI cognition, calling RSS for context assembly, enforcing DAP for human-in-the-loop decisions, and maintaining audit trails. - -The question arose: Should CEM be implemented early in ste-runtime development, or deferred until foundational components are stable? - ---- - -## Decision - -**CEM implementation is intentionally deferred.** - -CEM will be built as one of the final components of ste-runtime, after the governing components it orchestrates are in place: - -| Build Now (Foundation) | Build Later (Orchestration) | -|------------------------|----------------------------| -| RECON (extraction pipeline) | CEM (cognitive execution) | -| AI-DOC (semantic state) | DAP (deliberation protocol) | -| RSS (graph traversal) | Agent governance | -| Inference (relationships) | Audit/compliance trails | - ---- - -## Rationale - -### 1. CEM Orchestrates Components That Must Exist First - -CEM's stages call into foundational components: -- **Orientation** calls RSS for context assembly -- **Analysis** reads AI-DOC semantic state -- **Deliberation** invokes DAP for human judgment -- **Observation** checks divergence state - -Building CEM before these components are stable would result in: -- Premature abstractions -- Rework as component APIs evolve -- Incomplete orchestration coverage - -### 2. Human-in-Loop Provides Implicit CEM Today - -During development, Cursor/Claude interaction with the developer satisfies CEM governance: - -| CEM Stage | Current Implementation | -|-----------|----------------------| -| Perception | Developer provides task | -| Orientation | Agent queries RSS / searches codebase | -| Analysis | Agent reads code, understands context | -| Deliberation | Agent asks clarifying questions (implicit DAP) | -| Planning | Agent proposes solution | -| Execution | Agent edits files, runs commands | -| Observation | Developer/agent observe results | -| Reflection | Developer accepts/rejects; agent adjusts | -| Adaptation | Future responses incorporate learning | - -This implicit CEM is acceptable per ste-spec Section 4.7 because governance is maintained through human oversight. - -### 3. CEM is the Hardest Component - -CEM requires: -- State machine formalization -- Integration with all other components -- Audit trail persistence -- Configurable governance policies -- Error recovery and rollback semantics - -Tackling this complexity after foundations are solid reduces risk. - ---- - -## Constraints - -1. **Human-in-loop required:** Until CEM is implemented, all agent operations require human oversight. Autonomous execution is not supported. - -2. **No formal audit trail:** Agent decisions are traceable via chat/edit history, not structured audit logs. - -3. **DAP is implicit:** Deliberation activation occurs through natural conversation, not formalized protocol. - ---- - -## Consequences - -### Positive -- Foundation components can be built and tested independently -- API surfaces stabilize before CEM integration -- Reduced rework and premature abstraction -- Faster iteration on extraction/inference/traversal - -### Negative -- Autonomous agent execution blocked until CEM exists -- Formal governance auditing deferred -- Potential for API drift if CEM requirements not considered - -### Mitigation -- Document CEM's expected API contracts in ste-spec -- Periodically review foundation components against CEM needs -- Use execution pressure to surface integration gaps - ---- - -## Relationship to Other Decisions - -- **E-ADR-001 (RECON Provisional Execution):** RECON proceeds without CEM orchestration -- **E-ADR-002 (AI-DOC State Population):** AI-DOC writes occur without CEM governance -- **Future:** E-ADR-00X will formalize CEM implementation approach when ready - ---- - -## Review Trigger - -This decision should be revisited when: -1. Foundation components (RECON, AI-DOC, RSS, Inference) reach stability -2. Autonomous agent execution is required -3. Formal compliance/audit requirements emerge -4. Human-in-loop overhead becomes prohibitive - ---- - -## References - -- STE Architecture Specification, Section 4.7: Cognitive Execution Model -- STE Architecture Specification, Section 4.8: Deliberation Activation Protocol -- ISO/IEC/IEEE 42010:2022 Architecture Description - - - - diff --git a/documentation/e-adr-archived/E-ADR-004-RSS-CLI-Implementation.md b/documentation/e-adr-archived/E-ADR-004-RSS-CLI-Implementation.md deleted file mode 100644 index 5a5dde2..0000000 --- a/documentation/e-adr-archived/E-ADR-004-RSS-CLI-Implementation.md +++ /dev/null @@ -1,276 +0,0 @@ -# E-ADR-004: RSS CLI Implementation for Developer-Invoked Graph Traversal - -**Status:** Accepted -**Implementation:** Complete -**Date:** 2026-01-07 -**Author:** Erik Gallmann -**Authority:** Exploratory ADR (Reversible) - -> **Next Step:** Validate against ste-spec Section 4.6 (RSS) for ADR graduation. - ---- - -## Context - -The STE Architecture Specification Section 4.6 defines RSS (Runtime State-Slicing) as the component responsible for graph traversal and context assembly from AI-DOC state. RSS provides six core operations: - -| Operation | Description | -|-----------|-------------| -| `lookup(domain, id)` | Direct item retrieval | -| `dependencies(item, depth)` | Forward traversal (what does this depend on?) | -| `dependents(item, depth)` | Backward traversal (what depends on this?) | -| `blast_radius(item, depth)` | Bidirectional traversal (full impact surface) | -| `by_tag(tag)` | Cross-domain query | -| `assemble_context(task)` | Main context assembly function | - -The question arose: How should RSS be exposed for developer use during the exploratory phase? - ---- - -## Decision - -**RSS is exposed via a CLI (`rss-cli`) for developer-invoked graph traversal and context assembly.** - -The RSS CLI provides: - -| Feature | Decision | -|---------|----------| -| Invocation | Developer-invoked via `npm run rss` | -| Operations | All six spec-defined operations plus `search` and `stats` | -| Output Formats | Table (default), JSON, Compact | -| Graph Source | AI-DOC state generated by RECON | -| Scope | Local traversal over `.ste/state/` directory | - ---- - -## Rationale - -### 1. CLI Enables Exploration Without CEM - -Per E-ADR-003, CEM is deferred. However, developers need to: -- Explore the semantic graph generated by RECON -- Validate that relationships are correctly inferred -- Test context assembly before agent integration -- Debug graph traversal behavior - -A CLI provides these capabilities without requiring CEM orchestration. - -### 2. CLI is a Wrapper, Not the Integration Point - -The RSS CLI is a **human-friendly wrapper** around the core RSS API (`rss-operations.ts`). The integration model is: - -| Consumer | Interface | Reason | -|----------|-----------|--------| -| Human developers | CLI (`rss-cli.ts`) | Formatted output, interactive exploration | -| CEM (future) | TypeScript API (`rss-operations.ts`) | Type safety, no text parsing, direct integration | -| MCP Server (future) | TypeScript API → MCP protocol | Same API, different transport | -| CI/CD scripts | CLI with `--json` | Machine-readable, stable schema | - -**CEM MUST NOT invoke the CLI** to perform RSS operations. CEM will integrate directly with the TypeScript API: - -```typescript -// CEM integration (future) -import { initRssContext, assembleContext, findEntryPoints } from './rss/rss-operations.js'; - -const ctx = await initRssContext(stateDir); -const { entryPoints } = findEntryPoints(ctx, task.query); -const context = assembleContext(ctx, entryPoints, { maxDepth: 2 }); -``` - -This ensures: -- No process spawning overhead -- Full type safety -- Structured error handling -- No text parsing required - -### 3. Symmetric to RECON CLI - -RECON has `recon-cli` for extraction. RSS has `rss-cli` for traversal. This symmetry: -- Creates consistent developer experience -- Allows independent testing of each component -- Supports iterative development of both - -### 4. Multiple Output Formats Support Different Use Cases - -| Format | Use Case | -|--------|----------| -| `table` | Human exploration and debugging | -| `json` | Programmatic consumption, piping to other tools | -| `compact` | Quick scans, listing many results | - ---- - -## Specification - -### §4.1 CLI Commands - -| Command | Description | Spec Reference | -|---------|-------------|----------------| -| `stats` | Graph statistics (nodes, edges, domains, types) | Extension | -| `search ` | Entry point discovery by keyword | Extension (insertion protocol) | -| `lookup ` | Direct item retrieval | Section 4.6: lookup | -| `dependencies ` | Forward traversal | Section 4.6: dependencies | -| `dependents ` | Backward traversal | Section 4.6: dependents | -| `blast-radius ` | Bidirectional traversal | Section 4.6: blast_radius | -| `by-tag ` | Cross-domain query | Section 4.6: by_tag | -| `context ` | Full context assembly from NL query | Section 4.6: assemble_context | - -### §4.2 Key Format - -Graph keys follow the format: `domain/type/id` - -Examples: -- `graph/function/backend-lambda-handler.py-lambda_handler` -- `infrastructure/resource/cfn_resource:template-DataTable` -- `data/entity/DataTable` -- `data/control/aws-foundational-security-best-practices/v/1.0.0/S3.1` (E-ADR-005) -- `data/schema/Finding` (E-ADR-005) -- `frontend/component/UserPanelComponent` (E-ADR-006) -- `frontend/service/DataService` (E-ADR-006) - -### §4.3 Tag Format - -Tags follow the format: `category:value` - -Supported tag patterns: -- `handler:lambda` - Lambda handler functions -- `aws:` - AWS service resources (e.g., `aws:dynamodb`) -- `lang:` - Language-specific elements (e.g., `lang:python`) -- `layer:` - Architectural layer (e.g., `layer:api`) -- `storage:` - Storage backends (e.g., `storage:dynamodb`) - -### §4.4 Options - -| Option | Description | Default | -|--------|-------------|---------| -| `--depth=N` | Traversal depth | 2 | -| `--max=N` | Maximum results | 50 | -| `--format=FORMAT` | Output format (table, json, compact) | table | -| `--state-dir=PATH` | AI-DOC state directory | .ste/state | - -### §4.5 Extensions Beyond Spec - -Two operations are extensions not in the base specification: - -1. **`search`**: Entry point discovery via keyword matching. Implements the "insertion protocol" described in spec but not as a named operation. - -2. **`stats`**: Graph statistics for debugging and exploration. Not in spec but essential for development. - -These extensions are provisional and may be formalized or removed based on execution pressure. - ---- - -## Implementation - -### Files - -| File | Purpose | -|------|---------| -| `src/cli/rss-cli.ts` | CLI entry point and command routing | -| `src/rss/rss-operations.ts` | Core RSS operations implementation | -| `src/rss/graph-loader.ts` | AI-DOC graph loading from YAML files | -| `src/rss/graph-traversal.ts` | Graph traversal algorithms | -| `src/rss/schema.ts` | Type definitions | - -### npm Scripts - -```json -"rss": "node dist/cli/rss-cli.js", -"rss:stats": "node dist/cli/rss-cli.js stats", -"rss:search": "node dist/cli/rss-cli.js search", -"rss:context": "node dist/cli/rss-cli.js context" -``` - ---- - -## Constraints - -1. **Requires RECON State**: RSS CLI requires AI-DOC state generated by RECON. Running RSS without prior RECON execution will fail with a clear error message. - -2. **Local Scope Only**: RSS operates on local `.ste/state/` directory. Cross-repository traversal is not supported. - -3. **Non-Blocking**: Like RECON, RSS never blocks development workflows. All operations are read-only. - -4. **Provisional Tag Matching**: Tag matching uses pattern heuristics, not explicit tag storage. This is provisional pending tag storage improvements in RECON. - ---- - -## Consequences - -### Positive - -- Developers can explore semantic graph immediately -- Validates RECON extraction and inference quality -- Supports debugging of relationship inference -- Enables testing of context assembly before agent integration -- Provides foundation for future MCP server exposure - -### Negative - -- CLI output is not machine-stable (may change between versions) -- Tag matching is heuristic, not exhaustive -- No caching or performance optimization - -### Mitigation - -- Use `--json` for stable machine-readable output -- Document tag patterns explicitly -- Add caching if performance becomes an issue - ---- - -## Relationship to Other Decisions - -- **E-ADR-001 (RECON Provisional Execution)**: RSS consumes RECON-generated state -- **E-ADR-002 (RECON Self-Validation)**: RSS can validate graph integrity -- **E-ADR-003 (CEM Deferral)**: RSS API exists as foundation; CEM will consume it when built -- **E-ADR-005 (JSON Data Extraction)**: JSON entities (controls, schemas, configs) become queryable via RSS -- **E-ADR-006 (Angular and CSS/SCSS Extraction)**: Angular entities (components, services, routes, templates) and CSS entities (styles, design-tokens) become queryable via RSS - -## Dependency Direction - -The RSS TypeScript API is a **foundation component** that must exist before CEM: - -``` -RECON → AI-DOC → RSS API → [ CLI (now), CEM (future), MCP (future) ] -``` - -This is correct per E-ADR-003's build order: - -| Build Now (Foundation) | Build Later (Orchestration) | -|------------------------|----------------------------| -| RECON | CEM | -| AI-DOC | DAP | -| **RSS API ** | Agent governance | -| Inference | Audit/compliance trails | - -The CLI is a thin wrapper for developer use. The API is the integration point for all consumers. - ---- - -## Future Considerations - -1. **MCP Server**: Expose RSS operations via MCP for Cursor/Claude integration -2. **Watch Mode**: Automatic graph reload on RECON re-execution -3. **Caching**: Performance optimization for large graphs -4. **Tag Storage**: Move from pattern matching to explicit tag storage in slices - ---- - -## Review Trigger - -This decision should be revisited when: - -1. MCP server integration is required -2. Graph size exceeds performance thresholds -3. Tag matching accuracy becomes insufficient -4. CEM is implemented and requires RSS integration - ---- - -## References - -- STE Architecture Specification, Section 4.6: Runtime Components (RSS) -- E-ADR-001: Provisional Execution of RECON -- E-ADR-003: CEM Implementation Deferral - diff --git a/documentation/e-adr-archived/E-ADR-005-JSON-Data-Extraction.md b/documentation/e-adr-archived/E-ADR-005-JSON-Data-Extraction.md deleted file mode 100644 index 874366b..0000000 --- a/documentation/e-adr-archived/E-ADR-005-JSON-Data-Extraction.md +++ /dev/null @@ -1,390 +0,0 @@ -# E-ADR-005: JSON Data Model and Configuration Extraction - -**Status:** Proposed -**Implementation:** Complete -**Date:** 2026-01-07 -**Author:** Erik Gallmann -**Authority:** Exploratory ADR (Reversible) - -> **Next Step:** Validate extraction patterns against ste-spec requirements for ADR graduation. - ---- - -## Context - -Many enterprise codebases contain JSON files with semantic value beyond simple configuration: - -| Category | Examples | Semantic Value | -|----------|----------|----------------| -| Controls/Rules Catalog | Security controls, compliance rules, policy definitions | High - governance metadata | -| Data Schemas | Entity definitions, API contracts, validation schemas | High - data contracts | -| Deployment Parameters | CFN parameters, environment configs, feature flags | High - deployment configuration | -| Reference Data | Seed data, lookup tables, static catalogs | Medium - reference data | -| Test Fixtures | Mock data, test inputs | Low - test data | -| Package Manifests | `package.json`, `tsconfig.json` | Low - tooling configuration | - -Currently, RECON extracts: -- Python code (functions, classes, imports, SDK usage, API endpoints) -- TypeScript code (functions, classes, imports) -- CloudFormation templates (resources, outputs, parameters, GSIs) - -**JSON files are not extracted**, leaving semantic gaps: -- Infrastructure resources may reference control/rule IDs, but definitions are not in the graph -- Data schemas define entity structure, but schemas are not linked to code that uses them -- Deployment parameters configure resources, but parameter values are not visible - -The question arose: Should RECON extract JSON data models and configuration files? - ---- - -## Decision - -**RECON will extract JSON files with semantic structure, producing AI-DOC slices for data models and configuration.** - -Extraction scope (configurable per project): - -| JSON Category | Extract? | Domain | Type | Rationale | -|---------------|----------|--------|------|-----------| -| Controls/Rules Catalog | Yes | `data` | `control` | Links resources to governance definitions | -| Data Schemas | Yes | `data` | `schema` | Defines entity contracts | -| Deployment Parameters | Yes | `infrastructure` | `config` | Deployment configuration | -| Reference Data | Selective | `data` | `reference` | Only if referenced by code | -| Test Fixtures | No | - | - | Test data, not semantic | -| Package Manifests | No | - | - | Tooling configuration, not semantic | - ---- - -## Rationale - -### 1. Controls Catalog Bridges Infrastructure and Governance - -Many projects maintain catalogs of controls, rules, or policies. Infrastructure resources implement these controls, but the semantic link is often missing: - -``` -Current State: - CFN Resource (DataTable) ──?──> Control Definition (???) - -After Extraction: - CFN Resource (DataTable) ───────> Control (security-control/v/1.0.0/S3.1) -``` - -This enables queries like: -- "What resources implement control S3.1?" -- "What controls apply to the DataTable?" -- "Show blast radius of changing control SC-123" - -### 2. Data Schemas Define Entity Contracts - -Data schema files define the structure of entities (DynamoDB tables, API payloads, etc.): - -```json -{ - "entity": "Order", - "attributes": ["orderId", "customerId", "status", "items"], - "keys": { "pk": "orderId", "sk": "customerId" } -} -``` - -Extracting schemas enables: -- Linking code that reads/writes entities to their schemas -- Validating that functions respect entity contracts -- Detecting schema drift between code and definition - -### 3. Deployment Parameters Are Configuration - -Parameter files define environment-specific configuration: - -```json -{ - "Environment": "prod", - "TableReadCapacity": "100", - "EnableStream": "true" -} -``` - -Extracting parameters enables: -- Linking templates to their parameter sets -- Understanding deployment configuration by environment -- Detecting configuration drift - ---- - -## Specification - -### §5.1 JSON Discovery - -JSON files are discovered using configurable patterns in `ste.config.json`: - -```json -{ - "languages": ["typescript", "python", "cloudformation", "json"], - "jsonPatterns": { - "controls": "**/controls/**/*.json", - "schemas": "**/schemas/**/*.json", - "parameters": "**/parameters/**/*.json" - } -} -``` - -Default ignore patterns: - -```typescript -const JSON_IGNORES = [ - '**/package.json', - '**/package-lock.json', - '**/tsconfig.json', - '**/angular.json', - '**/*.test.json', - '**/fixtures/**', - '**/node_modules/**', -]; -``` - -### §5.2 Controls Catalog Extraction - -Controls catalog files follow a known structure: - -```json -{ - "controlId": "security-framework/v/1.0.0/S3.1", - "title": "S3 buckets should have server-side encryption enabled", - "severity": "MEDIUM", - "service": "S3", - "complianceFrameworks": ["FRAMEWORK-A", "FRAMEWORK-B"], - "remediationGuidance": "..." -} -``` - -**Extracted Slice:** - -```yaml -_slice: - id: control:security-framework/v/1.0.0/S3.1 - domain: data - type: control - source_files: - - data/controls/s3/S3.1.json - tags: - - service:s3 - - severity:medium - - framework:framework-a - - framework:framework-b - -element: - controlId: security-framework/v/1.0.0/S3.1 - title: S3 buckets should have server-side encryption enabled - severity: MEDIUM - service: S3 - complianceFrameworks: - - FRAMEWORK-A - - FRAMEWORK-B -``` - -### §5.3 Data Schema Extraction - -Data schema files define entity structure: - -```json -{ - "$schema": "...", - "entity": "Order", - "tableName": "OrdersTable", - "attributes": [ - { "name": "orderId", "type": "string", "required": true }, - { "name": "customerId", "type": "string", "required": true } - ], - "keys": { - "partitionKey": "orderId", - "sortKey": "customerId" - } -} -``` - -**Extracted Slice:** - -```yaml -_slice: - id: schema:Order - domain: data - type: schema - source_files: - - data/schemas/order-schema.json - references: - - domain: infrastructure - type: resource - id: cfn_resource:cloudformation/infrastructure.yaml:OrdersTable - tags: - - entity:order - - table:orderstable - -element: - entity: Order - tableName: OrdersTable - attributes: - - name: orderId - type: string - required: true - - name: customerId - type: string - required: true - keys: - partitionKey: orderId - sortKey: customerId -``` - -### §5.4 CFN Parameters Extraction - -Parameter files configure deployments: - -```json -{ - "Parameters": [ - { "ParameterKey": "Environment", "ParameterValue": "prod" }, - { "ParameterKey": "TableReadCapacity", "ParameterValue": "100" } - ] -} -``` - -**Extracted Slice:** - -```yaml -_slice: - id: config:cloudformation/parameters/prod-infrastructure.json - domain: infrastructure - type: config - source_files: - - cloudformation/parameters/prod-infrastructure.json - references: - - domain: infrastructure - type: template - id: cfn_template:cloudformation/infrastructure.yaml:main - tags: - - env:prod - - config:parameters - -element: - environment: prod - parameters: - Environment: prod - TableReadCapacity: "100" -``` - -### §5.5 Inference: Controls to Resources - -During inference phase, link controls to resources: - -1. Extract `controlId` references from CloudFormation resource tags or metadata -2. Link CFN resources to control slices -3. Enable bidirectional traversal: - - Resource → "implements" → Control - - Control → "implemented_by" → Resources - ---- - -## Implementation - -### Files to Create/Modify - -| File | Action | Purpose | -|------|--------|---------| -| `src/extractors/json/json-extractor.ts` | Create | JSON extraction logic | -| `src/extractors/json/controls-extractor.ts` | Create | Controls catalog extraction | -| `src/extractors/json/schema-extractor.ts` | Create | Data schema extraction | -| `src/extractors/json/params-extractor.ts` | Create | CFN parameters extraction | -| `src/extractors/json/index.ts` | Create | Extractor exports | -| `src/config/index.ts` | Modify | Add `json` to SupportedLanguage | -| `src/recon/phases/discovery.ts` | Modify | Add JSON patterns | -| `src/recon/phases/extraction.ts` | Modify | Route JSON files to extractor | -| `src/recon/phases/normalization.ts` | Modify | Normalize JSON assertions | -| `src/recon/phases/inference.ts` | Modify | Link controls to resources | - -### Configuration - -Add to `ste.config.json`: - -```json -{ - "languages": ["typescript", "python", "cloudformation", "json"], - "jsonPatterns": { - "controls": "**/controls/**/*.json", - "schemas": "**/schemas/**/*.json", - "parameters": "**/parameters/**/*.json" - } -} -``` - ---- - -## Constraints - -1. **Schema Detection**: JSON files must be identified by path pattern, not content inspection (unlike CloudFormation which checks for `AWSTemplateFormatVersion`). - -2. **Versioned Controls**: Control IDs may contain version strings. ID stability must account for version changes. - -3. **Environment-Specific Parameters**: Parameter files are environment-specific. Tags must capture environment. - -4. **No Deep Validation**: Extractor reads structure, does not validate correctness of control definitions or schema syntax. - -5. **Project-Specific Patterns**: JSON patterns are configured per-project in `ste.config.json`, not hardcoded. - ---- - -## Consequences - -### Positive - -- Controls catalog becomes queryable via RSS -- Resource → Control relationships are explicit -- Data schemas linked to infrastructure -- Deployment parameters visible as configuration - -### Negative - -- Increased extraction time -- JSON structure variance may cause extraction errors -- Path-based detection requires configuration - -### Mitigation - -- JSON patterns configurable in `ste.config.json` -- Graceful handling of malformed JSON -- Validation report includes JSON extraction coverage - ---- - -## Relationship to Other Decisions - -- **E-ADR-001 (RECON Provisional Execution)**: JSON extraction follows same provisional model -- **E-ADR-002 (RECON Self-Validation)**: Validation covers JSON extraction quality -- **E-ADR-004 (RSS CLI)**: JSON entities queryable via RSS - ---- - -## Acceptance Criteria - -1. RECON discovers and extracts controls catalog files (when configured) -2. RECON discovers and extracts data schema files (when configured) -3. RECON discovers and extracts CFN parameter files (when configured) -4. Extracted slices appear in RSS graph (`rss stats` shows `control`, `schema`, `config` types) -5. RSS query `rss search ""` returns control slice -6. RSS query `rss by-tag "service:"` returns service-related controls -7. Inference links CFN resources to controls (bidirectional) - ---- - -## Review Trigger - -This decision should be revisited when: - -1. JSON structure requirements change -2. New JSON data categories emerge -3. Extraction accuracy falls below acceptable threshold -4. Performance impact is prohibitive - ---- - -## References - -- STE Architecture Specification, Section 4.5: RECON -- E-ADR-001: Provisional Execution of RECON -- E-ADR-004: RSS CLI Implementation diff --git a/documentation/e-adr-archived/E-ADR-006-Angular-Semantic-Extraction.md b/documentation/e-adr-archived/E-ADR-006-Angular-Semantic-Extraction.md deleted file mode 100644 index 7a87862..0000000 --- a/documentation/e-adr-archived/E-ADR-006-Angular-Semantic-Extraction.md +++ /dev/null @@ -1,1019 +0,0 @@ -# E-ADR-006: Angular and CSS/SCSS Semantic Extraction - -**Status:** Proposed -**Implementation:** Complete -**Date:** 2026-01-07 -**Author:** Erik Gallmann -**Authority:** Exploratory ADR (Reversible) - -> **Next Step:** Validate Angular and CSS extraction patterns against ste-spec for ADR graduation. - -**Related E-ADRs:** -- E-ADR-001: Content-addressable slice naming (discovered via Angular long filenames) - ---- - -## Context - -The TypeScript extractor currently processes Angular files as standard TypeScript, capturing: -- Functions and their signatures -- Classes and their methods -- Import/export relationships -- Module structure - -However, Angular-specific semantics are not captured: - -| Pattern | Current Extraction | Semantic Gap | -|---------|-------------------|--------------| -| `@Component({ selector: 'app-dashboard' })` | Class with decorator | Selector, templateUrl, styleUrls missing | -| `@Injectable({ providedIn: 'root' })` | Class with decorator | Dependency injection scope missing | -| Route definitions | Array of objects | Navigation structure, guards, lazy loading missing | -| HTML templates | Not extracted | Template bindings, component usage, directives missing | - -Additionally, CSS/SCSS files contain semantic information valuable for **any** frontend project: -- Design tokens (CSS variables, SCSS variables) -- Responsive breakpoints -- Animation definitions -- Component styling patterns - -**Impact**: Frontend components cannot be linked to: -- Their templates (component ↔ template relationship) -- Their styles (component ↔ styles relationship) -- Backend services they consume (HTTP calls → API endpoints) -- Other components they render (parent → child relationships) -- Routes that load them (route → component mapping) - -The question arose: Should RECON extract Angular-specific semantics and CSS/SCSS beyond basic TypeScript? - ---- - -## Decision - -**RECON will extract Angular-specific semantics and CSS/SCSS as two separate but coordinated extractors.** - -### Architecture: Decoupled Extractors - -CSS/SCSS extraction is implemented as a **standalone extractor** that can be: -1. Used independently for any frontend project (React, Vue, plain HTML) -2. Delegated to by the Angular extractor for component styles - -``` -src/extractors/ -├── angular/ # Angular-specific (decorators, routes, templates) -├── css/ # Standalone CSS/SCSS extractor (framework-agnostic) -└── ... -``` - -### Extraction Scope - -**Angular Extractor** (`angular` language): - -| Angular Pattern | Extract? | Domain | Type | Rationale | -|-----------------|----------|--------|------|-----------| -| `@Component` decorator | Yes | `frontend` | `component` | Core UI building block | -| `@Injectable` decorator | Yes | `frontend` | `service` | Backend integration point | -| Route definitions | Yes | `frontend` | `route` | Navigation structure | -| HTML templates | Yes | `frontend` | `template` | UI structure and bindings | -| `@Pipe` decorator | Yes | `frontend` | `pipe` | Data transformation | -| `@Directive` decorator | Yes | `frontend` | `directive` | DOM manipulation | -| `@NgModule` decorator | Selective | `frontend` | `module` | Only standalone: false modules | - -**CSS Extractor** (`css` language): - -| CSS/SCSS Pattern | Extract? | Domain | Type | Rationale | -|------------------|----------|--------|------|-----------| -| Component styles | Yes | `frontend` | `styles` | Class names, variables used | -| Global design tokens | Yes | `frontend` | `design-tokens` | CSS variables, SCSS variables | -| Breakpoints | Yes | `frontend` | `design-tokens` | Responsive system | -| Animations | Yes | `frontend` | `design-tokens` | Reusable motion | - -### Language Configuration - -| Project Type | Languages Config | Result | -|--------------|------------------|--------| -| Angular | `["angular", "css"]` | Full Angular + CSS extraction | -| Angular (auto) | `["angular"]` | Angular delegates to CSS for styleUrls | -| React/Vue | `["typescript", "css"]` | TypeScript + standalone CSS | -| Plain HTML | `["css"]` | Just CSS extraction | -| Backend only | `["typescript", "python"]` | No CSS extraction | - ---- - -## Rationale - -### 1. Components Are the Primary UI Abstraction - -Angular components encapsulate: -- Template (HTML structure) -- Styles (CSS/SCSS) -- Logic (TypeScript class) -- Metadata (selector, inputs, outputs) - -Current extraction captures only the class. Enriched extraction captures the full component: - -```typescript -@Component({ - selector: 'app-data-list', - templateUrl: './data-list.component.html', - styleUrls: ['./data-list.component.css'] -}) -export class DataListComponent { - @Input() filters: FilterState; - @Output() itemSelected = new EventEmitter(); -} -``` - -**Extracted semantics**: -- Selector: `app-data-list` -- Template binding: `./data-list.component.html` -- Inputs: `filters` (type: FilterState) -- Outputs: `itemSelected` (type: EventEmitter) - -### 2. Services Bridge Frontend to Backend - -Injectable services typically make HTTP calls to backend APIs: - -```typescript -@Injectable({ providedIn: 'root' }) -export class DataService { - constructor(private http: HttpClient) {} - - getData(): Observable { - return this.http.get('/api/data'); - } -} -``` - -Extracting services enables: -- Linking service methods to API endpoints -- Tracing data flow from UI to backend -- Blast radius analysis: "If API changes, which components are affected?" - -### 3. Routes Define Navigation Structure - -Route definitions map URLs to components: - -```typescript -export const routes: Routes = [ - { path: 'home', component: HomeComponent }, - { path: 'users', component: UserListComponent, canActivate: [AuthGuard] }, - { path: 'reports', loadChildren: () => import('./reports/reports.module') } -]; -``` - -Extracting routes enables: -- Understanding application navigation -- Identifying protected routes (guards) -- Lazy-loaded module relationships - -### 4. Templates Reveal Component Composition - -HTML templates show: -- Which child components are used -- Data bindings and event handlers -- Structural directives (ngIf, ngFor) - -```html - - - -``` - -Extracting templates enables: -- Component composition graph (parent → child) -- Input/output binding verification -- Template-driven navigation - -### 5. Styles Provide Design System Context - -CSS/SCSS files contain semantic information essential for consistent UI changes: - -**Design Tokens (CSS Variables)** -```scss -:root { - --color-primary: #1a73e8; - --color-error: #d32f2f; - --spacing-md: 16px; - --border-radius-lg: 8px; -} -``` - -An AI modifying a component must know these tokens exist to maintain design consistency. - -**Component Styling Patterns** -```scss -.data-table { - &__header { ... } // BEM naming = semantic structure - &--loading { ... } // State modifier = behavior hint - &--error { ... } // Error state styling exists -} -``` - -Understanding class naming patterns enables: -- Following established conventions when adding styles -- Knowing which states are already styled -- Avoiding duplication of existing patterns - -**Responsive Breakpoints** -```scss -$breakpoint-tablet: 768px; -$breakpoint-mobile: 480px; - -@media (max-width: $breakpoint-tablet) { ... } -``` - -Extracting breakpoints enables: -- Consistent responsive behavior across components -- Understanding the responsive design system -- Proper mobile-first or desktop-first patterns - -**Animation Definitions** -```scss -@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } -@keyframes slideUp { from { transform: translateY(20px); } to { transform: translateY(0); } } -``` - -Existing animations should be reused, not recreated. - ---- - -## Specification - -### §6.1 Angular Discovery - -Angular files are identified by: - -1. **Components**: TypeScript files with `@Component` decorator -2. **Services**: TypeScript files with `@Injectable` decorator -3. **Routes**: TypeScript files exporting `Routes` array -4. **Templates**: HTML files in same directory as component files -5. **Styles**: CSS/SCSS files referenced by components or containing design tokens - -Discovery patterns: - -```typescript -const ANGULAR_PATTERNS = { - components: '**/*.component.ts', - services: '**/*.service.ts', - guards: '**/*.guard.ts', - pipes: '**/*.pipe.ts', - directives: '**/*.directive.ts', - routes: ['**/app.routes.ts', '**/*-routing.module.ts', '**/routes.ts'], - templates: '**/*.component.html', - styles: ['**/*.component.css', '**/*.component.scss', '**/styles.scss', '**/variables.scss'], -}; -``` - -### §6.2 Component Extraction - -**Input:** - -```typescript -@Component({ - selector: 'app-user-panel', - templateUrl: './user-panel.component.html', - styleUrls: ['./user-panel.component.css'], - standalone: true, - imports: [CommonModule, RouterModule, UserTableComponent] -}) -export class UserPanelComponent implements OnInit { - @Input() title: string = 'User Panel'; - @Output() refresh = new EventEmitter(); - - users$: Observable; - - constructor(private dataService: DataService) {} -} -``` - -**Extracted Slice:** - -```yaml -_slice: - id: component:frontend/src/app/features/user-panel/user-panel.component.ts:UserPanelComponent - domain: frontend - type: component - source_files: - - frontend/src/app/features/user-panel/user-panel.component.ts - - frontend/src/app/features/user-panel/user-panel.component.html - references: - - domain: frontend - type: service - id: service:frontend/src/app/core/services/data.service.ts:DataService - - domain: frontend - type: component - id: component:frontend/src/app/shared/user-table.component.ts:UserTableComponent - tags: - - layer:frontend - - angular:component - - standalone:true - -element: - id: component:UserPanelComponent - name: UserPanelComponent - selector: app-user-panel - templateUrl: ./user-panel.component.html - styleUrls: - - ./user-panel.component.css - standalone: true - imports: - - CommonModule - - RouterModule - - UserTableComponent - inputs: - - name: title - type: string - default: User Panel - outputs: - - name: refresh - type: EventEmitter - injectedServices: - - DataService -``` - -### §6.3 Service Extraction - -**Input:** - -```typescript -@Injectable({ providedIn: 'root' }) -export class DataService { - private apiUrl = '/api/data'; - - constructor(private http: HttpClient) {} - - getData(filters?: FilterState): Observable { - return this.http.get(this.apiUrl, { params: filters }); - } - - updateData(id: string, data: Partial): Observable { - return this.http.put(`${this.apiUrl}/${id}`, data); - } -} -``` - -**Extracted Slice:** - -```yaml -_slice: - id: service:frontend/src/app/core/services/data.service.ts:DataService - domain: frontend - type: service - source_files: - - frontend/src/app/core/services/data.service.ts - references: - - domain: api - type: endpoint - id: endpoint:/api/data:GET - - domain: api - type: endpoint - id: endpoint:/api/data/{id}:PUT - tags: - - layer:frontend - - angular:injectable - - scope:root - - http:client - -element: - id: service:DataService - name: DataService - providedIn: root - httpCalls: - - method: GET - urlPattern: /api/data - functionName: getData - - method: PUT - urlPattern: /api/data/{id} - functionName: updateData - injectedDependencies: - - HttpClient -``` - -### §6.4 Route Extraction - -**Input:** - -```typescript -export const routes: Routes = [ - { path: '', redirectTo: 'dashboard', pathMatch: 'full' }, - { path: 'home', component: HomeComponent }, - { - path: 'items', - component: DataListComponent, - canActivate: [AuthGuard], - children: [ - { path: ':id', component: FindingDetailComponent } - ] - }, - { - path: 'reports', - loadChildren: () => import('./reports/reports.routes').then(m => m.routes) - } -]; -``` - -**Extracted Slice:** - -```yaml -_slice: - id: routes:frontend/src/app/app.routes.ts:main - domain: frontend - type: routes - source_files: - - frontend/src/app/app.routes.ts - references: - - domain: frontend - type: component - id: component:UserPanelComponent - - domain: frontend - type: component - id: component:DataListComponent - - domain: frontend - type: guard - id: guard:AuthGuard - tags: - - layer:frontend - - angular:routing - - has:lazy-loading - - has:guards - -element: - id: routes:app.routes - routes: - - path: "" - redirectTo: dashboard - - path: dashboard - component: HomeComponent - - path: items - component: DataListComponent - guards: - - AuthGuard - children: - - path: ":id" - component: FindingDetailComponent - - path: reports - lazyLoad: ./reports/reports.routes -``` - -### §6.5 Template Extraction - -**Input:** `user-panel.component.html` - -```html -
- - -
- - -
- - - -
-``` - -**Extracted Slice:** - -```yaml -_slice: - id: template:frontend/src/app/features/user-panel/user-panel.component.html - domain: frontend - type: template - source_files: - - frontend/src/app/features/user-panel/user-panel.component.html - references: - - domain: frontend - type: component - id: component:SummaryCardsComponent - - domain: frontend - type: component - id: component:DataChartComponent - - domain: frontend - type: component - id: component:DataTableComponent - referenced_by: - - domain: frontend - type: component - id: component:UserPanelComponent - tags: - - layer:frontend - - angular:template - -element: - id: template:user-panel.component.html - parentComponent: UserPanelComponent - childComponents: - - selector: app-summary-cards - inputs: [data] - - selector: app-data-chart - inputs: [items] - outputs: [chartClick] - - selector: app-data-table - inputs: [items, filters] - outputs: [rowSelect] - conditionals: [ngIf] - directives: - - ngIf - pipes: - - async -``` - -### §6.6 Styles Extraction - -**Input:** `user-panel.component.scss` - -```scss -@import '../../styles/variables'; - -.dashboard-container { - display: grid; - gap: var(--spacing-lg); - padding: var(--spacing-md); - - &--loading { - opacity: 0.5; - pointer-events: none; - } -} - -.charts-row { - display: flex; - gap: var(--spacing-md); - - @media (max-width: $breakpoint-tablet) { - flex-direction: column; - } -} -``` - -**Input:** `_variables.scss` (global design tokens) - -```scss -// Design Tokens -:root { - --color-primary: #1a73e8; - --color-primary-dark: #1557b0; - --color-error: #d32f2f; - --color-success: #2e7d32; - --color-warning: #f57c00; - - --spacing-xs: 4px; - --spacing-sm: 8px; - --spacing-md: 16px; - --spacing-lg: 24px; - --spacing-xl: 32px; - - --border-radius-sm: 4px; - --border-radius-md: 8px; - --border-radius-lg: 12px; -} - -// Breakpoints -$breakpoint-mobile: 480px; -$breakpoint-tablet: 768px; -$breakpoint-desktop: 1024px; -$breakpoint-wide: 1440px; - -// Animations -@keyframes fadeIn { - from { opacity: 0; } - to { opacity: 1; } -} - -@keyframes slideUp { - from { transform: translateY(20px); opacity: 0; } - to { transform: translateY(0); opacity: 1; } -} -``` - -**Extracted Slice (Component Styles):** - -```yaml -_slice: - id: styles:frontend/src/app/features/user-panel/user-panel.component.scss - domain: frontend - type: styles - source_files: - - frontend/src/app/features/user-panel/user-panel.component.scss - references: - - domain: frontend - type: styles - id: styles:frontend/src/styles/_variables.scss - referenced_by: - - domain: frontend - type: component - id: component:UserPanelComponent - tags: - - layer:frontend - - angular:styles - - has:responsive - -element: - id: styles:user-panel.component.scss - parentComponent: UserPanelComponent - imports: - - ../../styles/variables - classNames: - - .dashboard-container - - .dashboard-container--loading - - .charts-row - cssVariablesUsed: - - --spacing-lg - - --spacing-md - scssVariablesUsed: - - $breakpoint-tablet - stateModifiers: - - --loading - mediaQueries: - - type: max-width - breakpoint: $breakpoint-tablet -``` - -**Extracted Slice (Global Design Tokens):** - -```yaml -_slice: - id: styles:frontend/src/styles/_variables.scss - domain: frontend - type: design-tokens - source_files: - - frontend/src/styles/_variables.scss - tags: - - layer:frontend - - design:tokens - - scope:global - -element: - id: design-tokens:_variables.scss - cssVariables: - colors: - --color-primary: "#1a73e8" - --color-primary-dark: "#1557b0" - --color-error: "#d32f2f" - --color-success: "#2e7d32" - --color-warning: "#f57c00" - spacing: - --spacing-xs: "4px" - --spacing-sm: "8px" - --spacing-md: "16px" - --spacing-lg: "24px" - --spacing-xl: "32px" - borders: - --border-radius-sm: "4px" - --border-radius-md: "8px" - --border-radius-lg: "12px" - scssVariables: - breakpoints: - $breakpoint-mobile: "480px" - $breakpoint-tablet: "768px" - $breakpoint-desktop: "1024px" - $breakpoint-wide: "1440px" - animations: - - fadeIn - - slideUp -``` - -### §6.7 Inference: Frontend to Backend Linking - -During inference phase, link frontend services to backend APIs: - -1. Extract HTTP call patterns from services (url, method) -2. Match against extracted API endpoints -3. Create bidirectional references: - - Service → "calls" → API Endpoint - - API Endpoint → "called_by" → Service - -``` -Frontend Service (DataService) - │ - ├─── GET /api/data ──────────> Lambda (get_data) - │ │ - └─── PUT /api/data/{id} ─────> Lambda (update_data) -``` - ---- - -## Implementation - -### Files to Create - -**Angular Extractor** (`src/extractors/angular/`): - -| File | Purpose | -|------|---------| -| `src/extractors/angular/index.ts` | Module exports | -| `src/extractors/angular/angular-extractor.ts` | Main extraction coordinator | -| `src/extractors/angular/component-extractor.ts` | @Component decorator extraction | -| `src/extractors/angular/service-extractor.ts` | @Injectable decorator extraction | -| `src/extractors/angular/route-extractor.ts` | Routes array extraction | -| `src/extractors/angular/template-extractor.ts` | HTML template extraction | - -**CSS Extractor** (`src/extractors/css/`) - Standalone, framework-agnostic: - -| File | Purpose | -|------|---------| -| `src/extractors/css/index.ts` | Module exports | -| `src/extractors/css/css-extractor.ts` | Main CSS/SCSS extraction coordinator | -| `src/extractors/css/styles-extractor.ts` | Component styles extraction | -| `src/extractors/css/design-tokens-extractor.ts` | CSS variables, SCSS variables, animations | - -### Delegation Pattern - -Angular extractor delegates to CSS extractor for component styles: - -```typescript -// In angular/component-extractor.ts -import { extractStyles } from '../css/css-extractor.js'; - -async function extractComponent(file: DiscoveredFile): Promise { - const component = parseComponentDecorator(file); - - // Delegate style extraction to CSS extractor - if (component.styleUrls) { - const styleAssertions = await extractStyles(component.styleUrls, { - parentComponent: component.className, - parentFile: file.relativePath, - }); - assertions.push(...styleAssertions); - } - - return assertions; -} -``` - -### Files to Modify - -| File | Change | -|------|--------| -| `src/config/index.ts` | Add `angular` and `css` to SupportedLanguage | -| `src/recon/phases/discovery.ts` | Add Angular and CSS file patterns | -| `src/recon/phases/extraction.ts` | Route Angular/CSS files to extractors | -| `src/recon/phases/normalization.ts` | Normalize to frontend domain | -| `src/recon/phases/inference.ts` | Link services to APIs, components to templates/styles | - -### Configuration - -**Angular project:** - -```json -{ - "languages": ["typescript", "python", "cloudformation", "json", "angular"], - "angularPatterns": { - "components": "**/src/app/**/*.component.ts", - "services": "**/src/app/**/*.service.ts", - "templates": "**/src/app/**/*.component.html" - }, - "cssPatterns": { - "styles": "**/src/app/**/*.component.{css,scss}", - "designTokens": "**/src/styles/**/*.scss" - } -} -``` - -**React/Vue project (CSS only, no Angular):** - -```json -{ - "languages": ["typescript", "css"], - "cssPatterns": { - "styles": "**/src/**/*.{css,scss,module.css}", - "designTokens": "**/src/styles/**/*.{css,scss}" - } -} -``` - -**Any project with just design tokens:** - -```json -{ - "languages": ["css"], - "cssPatterns": { - "designTokens": "**/styles/**/*.{css,scss}" - } -} -``` - ---- - -## Architectural Principle: Cross-Cutting Extractor Decoupling - -CSS/SCSS extraction demonstrates a broader architectural principle: **extractors for cross-cutting concerns should be standalone modules that can be delegated to by framework-specific extractors**. - -### The Pattern - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ Cross-Cutting Extractors │ -│ (Standalone, framework-agnostic, can be used independently) │ -├─────────────────────────────────────────────────────────────────┤ -│ CSS/SCSS │ GraphQL │ OpenAPI │ Env Vars │ Markdown │ -└──────┬─────┴─────┬─────┴─────┬─────┴──────┬─────┴───────┬──────┘ - │ │ │ │ │ - ▼ ▼ ▼ ▼ ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ Framework Extractors │ -│ (Delegate to cross-cutting extractors as needed) │ -├─────────────────────────────────────────────────────────────────┤ -│ Angular │ React │ Vue │ Python │ CloudFormation │ -└─────────────────────────────────────────────────────────────────┘ -``` - -### Known Cross-Cutting Concerns - -When implementing future extractors, consider whether they should be standalone: - -| Concern | Cross-Cutting? | Used By | Standalone Extractor? | -|---------|----------------|---------|----------------------| -| **CSS/SCSS** | Yes | Angular, React, Vue, HTML | `src/extractors/css/` | -| **GraphQL** | Yes | Angular, React, Vue, Node | Future: `src/extractors/graphql/` | -| **OpenAPI/Swagger** | Yes | Any frontend, any backend | Future: `src/extractors/openapi/` | -| **Environment Variables** | Yes | All languages, all frameworks | Future: `src/extractors/env/` | -| **Markdown/ADRs** | Yes | All projects | Future: `src/extractors/markdown/` | -| **SQL Migrations** | Yes | Python, TypeScript, Java | Future: `src/extractors/sql/` | -| **Protocol Buffers** | Yes | Multi-language services | Future: `src/extractors/protobuf/` | -| **YAML Config** | Partial | Docker, K8s, GitHub Actions | Future: `src/extractors/yaml/` | -| **JSON Schema** | Partial | Validation, API contracts | Covered by E-ADR-005 | - -### Implementation Guidance - -When building a new extractor, ask: - -1. **Is this concern framework-specific?** - - Yes → Build inside framework extractor (e.g., `@Component` is Angular-only) - - No → Build as standalone extractor - -2. **Can multiple frameworks use this?** - - Yes → Standalone extractor with delegation pattern - - No → Framework-specific extractor - -3. **Does it have value without the framework?** - - Yes → Must be independently invocable via language config - - No → Can be internal to framework extractor - -### Delegation Example - -```typescript -// Framework extractor delegates to cross-cutting extractor -import { extractGraphQL } from '../graphql/graphql-extractor.js'; - -// In React component extraction -if (usesApolloClient(file)) { - const graphqlAssertions = await extractGraphQL(file.graphqlQueries); - assertions.push(...graphqlAssertions); -} - -// In Angular service extraction -if (usesApolloAngular(file)) { - const graphqlAssertions = await extractGraphQL(file.graphqlQueries); - assertions.push(...graphqlAssertions); -} -``` - -This ensures: -- GraphQL extraction works for React, Angular, Vue, or standalone -- Consistent slice format regardless of which framework uses it -- No duplication of extraction logic across framework extractors - ---- - -## Constraints - -1. **Decorator Parsing**: Angular decorators contain object literals. Must parse decorator arguments, not just detect decorator presence. - -2. **Template Parsing**: HTML templates require lightweight parsing to extract component selectors and bindings. Full Angular template compilation is not required. - -3. **Selector Resolution**: Component selectors (e.g., `app-data-table`) must be resolved to component classes across the codebase. - -4. **HTTP URL Patterns**: Service HTTP calls may use string interpolation. Extract URL patterns with placeholders (e.g., `/api/data/{id}`). - -5. **Lazy Loading**: Route lazy loading uses dynamic imports. Must parse import paths to resolve loaded modules. - -6. **Standalone vs Module**: Angular supports both standalone components and NgModule-based components. Extraction must handle both patterns. - -7. **CSS/SCSS Parsing**: Style extraction uses regex-based parsing for CSS variables, class names, and SCSS variables. Full CSS AST parsing is not required. Focus on semantic elements: design tokens, breakpoints, animations. - -8. **Design Token Scope**: Global design tokens (in `styles/` directory) are extracted as `design-tokens` type. Component-scoped styles are extracted as `styles` type linked to their parent component. - ---- - -## Consequences - -### Positive - -- Component → template relationships explicit in graph -- Component → styles relationships explicit in graph -- Service → API endpoint tracing enabled -- Route structure visible for navigation analysis -- Full-stack blast radius analysis possible -- Frontend layer queryable via RSS -- Design tokens (CSS variables) discoverable for consistent styling -- AI can use existing patterns instead of inventing new ones - -### Negative - -- Increased extraction complexity -- HTML parsing introduces new failure modes -- Selector resolution requires cross-file analysis -- Angular version differences may affect extraction - -### Mitigation - -- Graceful fallback to basic TypeScript extraction on failure -- Selector resolution uses best-effort matching -- Template parsing uses lightweight regex, not full Angular compiler -- Version-specific patterns configurable - ---- - -## Relationship to Other Decisions - -- **E-ADR-001 (RECON Provisional Execution)**: Angular extraction follows same provisional model -- **E-ADR-002 (RECON Self-Validation)**: Validation covers Angular extraction quality -- **E-ADR-004 (RSS CLI)**: Angular entities queryable via RSS -- **E-ADR-005 (JSON Extraction)**: JSON schemas may define API contracts consumed by services - ---- - -## Acceptance Criteria - -1. RECON extracts `@Component` decorators with selector, templateUrl, styleUrls, inputs, outputs -2. RECON extracts `@Injectable` decorators with providedIn scope and HTTP calls -3. RECON extracts route definitions with components, guards, and lazy loading -4. RECON extracts HTML templates with child component selectors and bindings -5. RECON extracts CSS/SCSS files with class names, CSS variables used, and media queries -6. RECON extracts global design tokens (CSS variables, SCSS variables, animations) -7. RSS `stats` shows `frontend` domain with component, service, route, template, styles, design-tokens types -8. RSS `dependencies component:UserPanelComponent` returns template, styles, services, child components -9. RSS `dependents service:DataService` returns components that inject it -10. RSS `search "--color-primary"` returns design-tokens slice containing the variable -11. Service HTTP calls linked to API endpoints (when endpoints exist in graph) -12. Component styles linked to design tokens they reference - ---- - -## Review Trigger - -This decision should be revisited when: - -1. Angular major version changes decorator syntax -2. New Angular patterns emerge (signals, control flow) -3. Extraction accuracy falls below acceptable threshold -4. Performance impact is prohibitive - ---- - -## References - -- STE Architecture Specification, Section 4.5: RECON -- E-ADR-001: Provisional Execution of RECON (slice naming design decision) -- E-ADR-004: RSS CLI Implementation -- E-ADR-005: JSON Data Model Extraction -- E-ADR-008: Extractor Development Guide -- [Angular Component Documentation](https://angular.io/guide/component-overview) -- [Angular Dependency Injection](https://angular.io/guide/dependency-injection) - ---- - -## Appendix: Discovery of Content-Addressable Naming - -**Date:** 2026-01-07 -**Impact:** Critical design change - -### Problem Discovered - -During specification of Angular extraction, a failure mode was identified: - -**Angular component slice filenames exceeded filesystem limits:** -``` -component-frontend-src-app-features-reports-report-views-control-effectiveness-report-control-effectiveness-report.component.ts-ControlEffectivenessReportComponent.yaml -``` -- Length: 180-250 characters -- Windows limit: 260 characters (path + filename) -- Unix limit: 255 characters (filename only) - -### Resolution - -**Switched to content-addressable hashing (see E-ADR-001 update):** -- Filenames are now 16-character SHA-256 hashes -- Example: `009bd442b992f055.yaml` -- Slice ID remains inside file as source of truth -- Performance improved: 766 slices/sec (up from 687) - -### Rationale - -1. **AI-DOC is machine-readable**, not human-edited -2. **Filesystem portability** across all platforms -3. **Performance** improvement with shorter paths -4. **Aligns with philosophy**: Slice ID is authoritative, not filename - -This discovery validates the exploratory ADR approach: implementing E-ADR-006 surfaced a real failure mode that improved the overall system design. - diff --git a/documentation/e-adr-archived/E-ADR-007-Watchdog-Authoritative-Mode.md b/documentation/e-adr-archived/E-ADR-007-Watchdog-Authoritative-Mode.md deleted file mode 100644 index 9922ccd..0000000 --- a/documentation/e-adr-archived/E-ADR-007-Watchdog-Authoritative-Mode.md +++ /dev/null @@ -1,1149 +0,0 @@ -# E-ADR-007: ste-runtime MCP Server (Workspace Boundary Operation) - -**Status:** Accepted -**Implementation:** In Progress -**Date:** 2026-01-11 (Updated) -**Author:** Erik Gallmann -**Authority:** Exploratory ADR (Reversible) - -> **Updated 2026-01-11:** Clarified that ste-runtime operates in Workspace Development Boundary (STE Architecture Section 3.1), not as "Authoritative Mode". Integrated with MCP protocol for Cursor integration. - -> **Implementation Note (2026-02-08):** The current MCP server exposes 8 AI-optimized tools (`find`, `show`, `usages`, `impact`, `similar`, `overview`, `diagnose`, `refresh`). Tool names listed below reflect the original layered tool plan. - ---- - -## Context - -Per STE Architecture (Section 3.1), STE operates across two distinct governance boundaries: -1. **Workspace Development Boundary** - Provisional state, soft + hard enforcement, post-reasoning validation -2. **Runtime Execution Boundary** - Canonical state, cryptographic enforcement, pre-reasoning admission control - -This E-ADR defines ste-runtime's operation within the **Workspace Development Boundary**, where developers need a **live semantic graph** that stays fresh automatically during local development. - -### Workspace Development Boundary (STE Architecture Section 3.1) - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ WORKSPACE DEVELOPMENT BOUNDARY │ -│ │ -│ ┌─────────────────────────────────────────────────────────┐ │ -│ │ CURSOR (Governed) │ │ -│ │ • MCP client │ │ -│ │ • Context assembly via RSS (ste-runtime MCP) │ │ -│ └────────────────────┬────────────────────────────────────┘ │ -│ │ MCP Protocol (stdio) │ -│ ▼ │ -│ ┌─────────────────────────────────────────────────────────┐ │ -│ │ ste-runtime MCP Server │ │ -│ │ • File Watcher → Incremental RECON │ │ -│ │ • In-Memory RSS Context │ │ -│ │ • MCP Tools (RSS operations) │ │ -│ └─────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌─────────────────────────────────────────────────────────┐ │ -│ │ .ste/state/ (AI-DOC) │ │ -│ │ • Provisional state (pre-merge) │ │ -│ │ • Updated by incremental RECON │ │ -│ └─────────────────────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────────────────┘ -``` - -**State Type:** Provisional, experimental (uncommitted, feature branches) -**Authority:** Source code is truth → RECON extracts → AI-DOC (local, pre-merge) -**Enforcement:** Soft (LLM) + Hard (validation tools + human approval) -**Validation:** Post-reasoning (toolchain catches violations) - ---- - -## Decision - -**Updated 2026-01-11**: Implement ste-runtime as a unified MCP server operating in the Workspace Development Boundary. - -### Core Architecture - -**ste-runtime is a single process that combines:** -1. **File Watcher** - Monitors project files, triggers incremental RECON on changes -2. **Incremental RECON Engine** - Maintains fresh AI-DOC state (O(changed files)) -3. **In-Memory RSS Context** - Fast semantic graph queries (<100ms) -4. **MCP Server** - Exposes RSS operations as tools for Cursor integration - -### MCP Integration (Primary Interface) - -**Decision:** Use MCP (Model Context Protocol) as the primary interface, not HTTP REST API. - -**Rationale:** -- Native Cursor integration (stdio transport) -- Tool auto-discovery (Cursor sees available tools automatically) -- Schema validation (MCP enforces input/output schemas) -- Standardized protocol (works with any MCP-compatible AI assistant) - -**MCP Tools Exposed:** -- `search_semantic_graph` - Entry point discovery -- `get_dependencies` - Forward traversal -- `get_dependents` - Backward traversal -- `get_blast_radius` - Full impact surface -- `assemble_context` - CEM Stage 2 (State Loading) -- `lookup`, `by_tag`, `get_graph_stats` - Additional RSS operations - -### Workspace Boundary Operation - -**Authority Model:** -- **Source code** is the single source of truth -- **RECON** extracts semantic state authoritatively -- **AI-DOC** is derived artifact (like compiled code) -- **ste-runtime** serves provisional state (pre-merge, local) - -**NOT Canonical State:** -- ste-runtime does NOT operate in Runtime Execution Boundary -- ste-runtime does NOT provide cryptographic attestation (that's Fabric's role) -- ste-runtime does NOT enforce pre-reasoning admission control (that's Gateway's role) -- ste-runtime serves **provisional state** for local development - -### CLI Commands - -```bash -# Start MCP server with file watching -ste watch - -# One-shot RECON (no server) -ste recon [--incremental] - -# Query operations (hits running server if available, else reads from disk) -ste query [args] -``` - ---- - -**Key Clarifications (2026-01-11):** - -1. **Workspace vs Runtime Boundaries:** - - ste-runtime operates in **Workspace Boundary** (provisional state, local development) - - Fabric/Gateway operate in **Runtime Boundary** (canonical state, cryptographic enforcement) - - These are different trust models for different use cases - -2. **Authority Scope:** - - ste-runtime is authoritative for **project-level state** (pre-merge, feature branches) - - Source code → RECON → AI-DOC (local extraction) - - NOT authoritative for org-wide canonical state (that's ADF/Fabric) - -3. **MCP as Primary Interface:** - - Enables CEM Stage 2 (State Loading) for Cursor - - Deterministic context assembly via RSS graph traversal - - Replaces probabilistic semantic search with explicit state - ---- - -## Rationale - -### The Watchdog IS the Conflict Resolution Process - -When a file moves: -1. Watchdog detects the move (authoritative: it observed the file system event) -2. Migration detection scores confidence (1.0 = certain same element) -3. High confidence → Watchdog resolves automatically (correct resolution) -4. Low confidence → Surfaces to human (ambiguous, needs judgment) - -This is correct because: -- Watchdog has ground truth (observed actual file system changes) -- Migration detection is deterministic (same inputs → same decision) -- Confidence thresholds ensure safety (humans review ambiguous cases) -- Developer opts in (explicit choice to delegate authority) - -### Slice Files Are Derived Artifacts - -``` -Source of Truth: - user-panel.component.ts (source code) - -Derived Artifact: - .ste/state/frontend/component/component-abc123.yaml (slice) - -Relationship: - Source → RECON → Slice (one-way) -``` - -**Like:** `src/app.ts` → `dist/app.js` (compiled) - -If you manually edit `dist/app.js`, the compiler overwrites it on next build. -If you manually edit a slice file, watchdog overwrites it on next RECON (self-healing). - ---- - -## Authority Scope - -**Updated 2026-01-07**: Clarified project-level vs. organization-level authority boundaries. - -### Two Levels of Semantic Authority - -``` -┌─────────────────────────────────────────────────┐ -│ PROJECT LEVEL (Pre-Merge) │ -│ Authority: ste-runtime RECON │ -│ Scope: Feature branches, local development │ -│ Visibility: Developer only (not org-wide) │ -│ Purpose: Help developer understand their changes│ -└─────────────────────────────────────────────────┘ - ↓ - [git merge] - [CI/CD deploy] - ↓ -┌─────────────────────────────────────────────────┐ -│ ORGANIZATION LEVEL (Post-Merge/Deploy) │ -│ Authority: ADF (Authoritative Derived Facts) │ -│ Scope: main/master branch, deployed code │ -│ Visibility: Organization-wide │ -│ Purpose: Cross-project semantic index │ -└─────────────────────────────────────────────────┘ -``` - -### ste-runtime RECON IS Authoritative For: - -**Scope: Project-level changes (pre-merge)** - -- Current working state ("What semantics exist in my feature branch RIGHT NOW?") -- Pre-commit, uncommitted, unmerged code changes -- Developer's local RSS query results (live graph of their changes) -- File-to-element mappings in current project state -- Reference relationships within the project -- All slice files derived from **local source code** -- **The changes RECON is suggesting** (before merge) - -**Key principle:** RECON is authoritative for project-level semantic state. It extracts from the developer's current source code (which IS the truth for that project at that moment). - -### ste-runtime RECON is NOT Authoritative For: - -**Scope: Organization-level, merged/deployed state** - -- Merged/deployed semantic state (ADF's responsibility) -- Cross-project semantic index (ADF publishes after merge) -- Organization-wide documentation (generated from ADF) -- Compliance artifacts (sourced from ADF) -- Other developers' feature branches - -**Key principle:** Project-level changes DO NOT appear in ADF until promoted (merged/deployed). This is correct—feature branches are invisible to the organization until merged. - -### ADF (Authoritative Derived Facts) IS Authoritative For: - -**Scope: Organization-level, post-merge/deploy** - -- Merged semantic state (main/master branch) -- Deployed semantic state (production, staging) -- Cross-project semantic relationships -- Organization-wide semantic search/discovery -- Published documentation -- Compliance and audit artifacts - -**Triggered by:** Merge to main, deployment to production, CI/CD pipeline completion - -**Visibility:** All projects can query ADF to "get oriented" to merged changes - -### Authority Handoff - -``` -Developer working on feature/add-angular-components: - ├─ ste-runtime RECON: Authoritative for this branch - ├─ Extracts Angular components from local source - ├─ Developer queries RSS: "What components exist?" - ├─ Answer: Based on current feature branch (pre-merge) - └─ Changes NOT visible to other projects (correct) - ↓ - [git merge to main] - ↓ - CI/CD triggers ADF update: - ├─ ADF extracts from merged code - ├─ Publishes organization-wide semantic index - ├─ Other projects can now discover new Angular components - └─ ADF: Now authoritative for merged state -``` - -### Optional: RECON Pulling From ADF - -**Use case:** Developer wants broader context while working locally - -``` -Developer working locally: - ├─ ste-runtime RECON extracts from local source (authoritative) - ├─ Optionally: RECON queries ADF for organization context - │ └─ "What API endpoints exist in deployed backend?" - │ └─ "What design tokens are in main branch?" - ├─ RECON enriches local extraction with ADF context - └─ BUT: Local source is still authority for project-level changes -``` - -**Key:** Even with ADF context, ste-runtime RECON remains authoritative for **the changes it's suggesting** based on local source code. - ---- - -**Boundary Summary:** - -| Aspect | ste-runtime RECON (Project) | ADF (Organization) | -|--------|----------------------------|-------------------| -| **Authority** | Local source code (feature branch) | Merged/deployed code (main) | -| **Scope** | Pre-merge, single project | Post-merge, organization-wide | -| **Visibility** | Developer only | All projects | -| **Triggered by** | Developer runs `npm run recon` | Merge to main, deployment | -| **Purpose** | Understand current changes | Cross-project semantic index | -| **Changes visible** | Uncommitted, unmerged | Merged, deployed | - ---- - -## Specification - -### §1 Confidence-Based Authority - -| Confidence | Action | Authority | Example | -|------------|--------|-----------|---------| -| **1.0** (Certain) | Auto-resolve immediately | **Watchdog** | File moved, content unchanged | -| **0.95-0.99** (Very High) | Auto-resolve, log decision | **Watchdog** | Same class name, selector, 95% content match | -| **0.80-0.94** (High) | Surface as high-confidence candidate | **Human** | Similar structure, different name | -| **0.50-0.79** (Medium) | Surface as possible match | **Human** | Some overlap, unclear intent | -| **< 0.50** (Low) | Treat as unrelated changes | **Watchdog** | Different types, no similarity | - -### §2 Self-Healing Property - -**Watchdog monitors ALL files, including slice files.** - -When slice file changes: -1. Check: Was this watchdog's own write? (ignore if yes) -2. Check: Does content match recent write? (ignore if yes) -3. External modification detected → **Heal from source** -4. Regenerate slice from source code (authoritative) -5. Overwrite manually edited slice - -**Result:** Slice files always reflect current source code. Manual edits don't persist. - -**Developer guidance:** -- Edit source code (watchdog updates slices automatically) -- Don't edit slices directly (they'll be overwritten) - -### §3 Watchdog Architecture - -``` -┌─────────────────────────────────────────────────────────┐ -│ ste-runtime (Self-Contained) │ -│ │ -│ ┌────────────────┐ │ -│ │ Watchdog │ ← Long-running process │ -│ │ Process │ │ -│ └────────────────┘ │ -│ │ │ -│ ├──► File System Watcher (chokidar) │ -│ │ - Monitors parent project │ -│ │ - Debounces changes (wait 500ms) │ -│ │ - Filters by language relevance │ -│ │ │ -│ ├──► Incremental RECON Trigger │ -│ │ - Runs extraction on changed files only │ -│ │ - Applies migrations automatically │ -│ │ - Surfaces conflicts (non-blocking) │ -│ │ │ -│ └──► RSS Graph Reloader │ -│ - Notifies RSS server (IPC or HTTP) │ -│ - RSS reloads slices from disk │ -│ - Graph is now fresh │ -│ │ -│ ┌────────────────┐ │ -│ │ RSS Server │ ← HTTP API or Unix socket │ -│ │ (optional) │ │ -│ └────────────────┘ │ -└─────────────────────────────────────────────────────────┘ - │ - │ Monitors (read-only) - ▼ -┌─────────────────────────────────────────────────────────┐ -│ Parent Project (your-project) │ -│ - frontend/src/**/*.ts │ -│ - backend/lambda/**/*.py │ -│ - backend/cloudformation/**/*.yaml │ -│ (Source code - never modified by ste-runtime) │ -└─────────────────────────────────────────────────────────┘ -``` - -### §4 Resilience Mechanisms - -#### §4.1 Write Tracking (Prevent Infinite Loops) - -**Problem:** Watchdog writes slice → file change event → watchdog detects change → infinite loop - -**Solution:** Content-hash based write tracking - -```typescript -// Record write with content hash -writeTracker.recordWrite(filepath, content); - -// On file change: -const currentContent = await fs.readFile(filepath); -const currentHash = hash(currentContent); - -if (currentHash === recordedHash) { - return; // Ignore - this is our own write -} - -// External modification - proceed with healing -``` - -**Key properties:** -- Content-based, not timestamp-based (no race conditions) -- Path normalization (handles relative/absolute/symlinks) -- Longer retention window (30 seconds, tolerates event delays) - -#### §4.2 Update Coordination (Prevent Cascading Loops) - -**Problem:** Source change triggers RECON → updates slice A → inference updates slices B, C, D → triggers healing for B, C, D → cascading updates - -**Solution:** Generation-based update tracking - -```typescript -// Start update batch -const generation = updateCoordinator.startUpdate([sourceFile]); - -// Run RECON, record all affected slices -const results = await runIncrementalRECON([sourceFile]); -for (const slice of results.written) { - updateCoordinator.recordSliceWrite(generation, slice.filepath); -} - -// Complete batch -updateCoordinator.completeUpdate(generation); - -// On file change: -if (updateCoordinator.isFromActiveUpdate(sliceFilepath)) { - return; // Ignore - part of active update batch -} -``` - -**Key properties:** -- Tracks entire update batch (not just individual writes) -- Ignores transitive updates (inference-driven slice changes) -- Short retention window (clears after update completes) - -#### §4.3 Periodic Full Reconciliation (Recover from Event Loss) - -**Problem:** File system watchers have buffer limits. During high activity (git checkout, npm install), events can be lost. - -**Solution:** Periodic full reconciliation (every 5 minutes) - -```typescript -// Background task: -setInterval(async () => { - // Compute source file checksums - const sourceChecksums = await computeAllSourceChecksums(); - - // Compare to slice provenance checksums - const staleSlices = findStaleSlices(sourceChecksums); - - if (staleSlices.length > 0) { - console.warn(`Found ${staleSlices.length} stale slices, regenerating...`); - await runIncrementalRECON(staleSlices.map(s => s.sourceFile)); - } -}, 5 * 60 * 1000); // 5 minutes -``` - -**Key properties:** -- Detects missed file system events -- Self-correcting (automatically heals stale state) -- Low frequency (acceptable overhead) -- Non-blocking (runs in background) - -**Prerequisite:** Store source checksum in slice provenance: - -```yaml -_slice: - id: "component:angular:app-user-panel" - source_files: ["frontend/.../user-panel.component.ts"] -provenance: - extracted_at: "2026-01-07T20:00:00Z" - source_checksum: "a7f3e9d2b8c1..." # SHA-256 of source file - extractor_version: "0.2.0" -``` - -#### §4.4 Update Queue with Version Tracking (Handle Rapid Changes) - -**Problem:** Developer saves file multiple times rapidly while RECON is processing. Cursor AI may generate code with streaming edits (10+ saves during generation). - -**Solution:** Multi-layer debouncing with syntax validation and transaction detection - -```typescript -class EditQueueManager { - private pendingEdits: Map = new Map(); - private transactionDetector = new TransactionDetector(); - - async handleFileChange(filePath: string) { - // 1. Record the edit for transaction detection - this.transactionDetector.recordEdit(filePath); - - // 2. Update or create edit record - const existing = this.pendingEdits.get(filePath); - if (existing) { - existing.version++; - existing.lastChange = Date.now(); - } else { - this.pendingEdits.set(filePath, { - path: filePath, - version: 1, - lastChange: Date.now(), - source: 'unknown' - }); - } - - // 3. Schedule processing (will be debounced) - this.scheduleProcessing(filePath); - } - - async scheduleProcessing(filePath: string) { - const record = this.pendingEdits.get(filePath); - if (!record) return; - - // 4. Detect edit source (AI vs manual) - record.source = this.detectEditSource(filePath); - const debounce = this.getDebounceTimeout(record.source); - - // 5. Wait for debounce period - await sleep(debounce); - - // 6. Check if newer version exists (coalesce) - const current = this.pendingEdits.get(filePath); - if (!current || current.version !== record.version) { - return; // Newer version exists, skip this one - } - - // 7. Check for multi-file transaction - if (this.transactionDetector.isPartOfTransaction()) { - console.log('[Watchdog] Multi-file edit detected, waiting...'); - await this.transactionDetector.waitForComplete(); - } - - // 8. Verify file stability - if (!await this.isFileStable(filePath)) { - console.log('[Watchdog] File still changing, re-queuing...'); - this.scheduleProcessing(filePath); // Try again later - return; - } - - // 9. Validate syntax (skip broken code) - if (!await this.validateSyntax(filePath)) { - console.log('[Watchdog] Syntax error, skipping RECON'); - this.pendingEdits.delete(filePath); - return; - } - - // 10. NOW trigger RECON - this.pendingEdits.delete(filePath); - await runIncrementalRECON([filePath]); - } - - detectEditSource(filePath: string): 'cursor' | 'manual' | 'unknown' { - const recentChanges = this.getRecentChanges(filePath); - - // Cursor pattern: Multiple rapid large changes - if (recentChanges.length > 5 && recentChanges.timespan < 3000) { - return 'cursor'; - } - - return 'manual'; - } - - getDebounceTimeout(source: string): number { - return source === 'cursor' ? 2000 : 500; - } - - async isFileStable(filePath: string): Promise { - try { - // Check mtime stability (file not being written) - const mtime1 = (await fs.stat(filePath)).mtimeMs; - await sleep(100); - const mtime2 = (await fs.stat(filePath)).mtimeMs; - - return mtime1 === mtime2; - } catch { - return false; - } - } - - async validateSyntax(filePath: string): Promise { - const ext = path.extname(filePath); - const content = await fs.readFile(filePath, 'utf-8'); - - try { - switch (ext) { - case '.py': - // Python syntax check (parse only, don't execute) - const { exec } = await import('child_process'); - await new Promise((resolve, reject) => { - exec(`python -m py_compile "${filePath}"`, (error) => { - error ? reject(error) : resolve(null); - }); - }); - return true; - - case '.ts': - case '.tsx': - case '.js': - case '.jsx': - // TypeScript/JavaScript syntax check - const ts = await import('typescript'); - const result = ts.transpileModule(content, { - compilerOptions: { noEmit: true, allowJs: true } - }); - return !result.diagnostics || result.diagnostics.length === 0; - - default: - // No validator available, assume valid - return true; - } - } catch (error) { - // Syntax error - skip this change - return false; - } - } -} - -class TransactionDetector { - private recentEdits: Map = new Map(); - - recordEdit(filePath: string) { - this.recentEdits.set(filePath, Date.now()); - - // Cleanup old entries (>10 seconds) - const cutoff = Date.now() - 10000; - for (const [path, timestamp] of this.recentEdits.entries()) { - if (timestamp < cutoff) { - this.recentEdits.delete(path); - } - } - } - - isPartOfTransaction(): boolean { - // If 2+ files edited within 5 seconds, it's likely a transaction - const now = Date.now(); - const recentFiles = Array.from(this.recentEdits.values()) - .filter(timestamp => now - timestamp < 5000); - - return recentFiles.length > 1; - } - - async waitForComplete(): Promise { - // Wait until no edits for 2 seconds - let lastEdit = Math.max(...this.recentEdits.values()); - - while (Date.now() - lastEdit < 2000) { - await sleep(500); - const mostRecent = Math.max(...this.recentEdits.values()); - if (mostRecent > lastEdit) { - lastEdit = mostRecent; - } - } - } -} -``` - -**Key properties:** -- **Syntax validation** - Skips files with parse errors (mid-edit) -- **Edit source detection** - Longer debounce for AI-generated edits (2s vs 500ms) -- **Transaction detection** - Waits for multi-file edits to complete -- **File stability** - Ensures file is no longer being written -- **Version coalescing** - Only processes latest version -- **Adaptive debouncing** - Adjusts timeout based on edit pattern - -#### §4.5 Atomic Writes with Cleanup (Prevent Partial Writes) - -**Problem:** Write fails mid-operation, leaving temp files or corrupted slices. - -**Solution:** Atomic write with temp file cleanup - -```typescript -async function atomicWrite(filepath: string, content: string): Promise { - const tempFile = `${filepath}.tmp.${Date.now()}.${randomId()}`; - - try { - await fs.writeFile(tempFile, content); - await fs.rename(tempFile, filepath); // Atomic on POSIX, mostly atomic on Windows - } catch (error) { - await fs.unlink(tempFile).catch(() => {}); // Cleanup on failure - throw error; - } -} - -// Periodic cleanup of orphaned temp files (every 1 minute) -setInterval(async () => { - const tempFiles = await glob('**/*.tmp.*', { cwd: stateDir }); - for (const tempFile of tempFiles) { - const age = Date.now() - (await fs.stat(tempFile)).mtimeMs; - if (age > 60_000) { // Older than 1 minute - await fs.unlink(tempFile); - } - } -}, 60_000); -``` - -#### §4.6 Bounded Memory (LRU Cache) - -**Problem:** Write tracker and update coordinator store data indefinitely, causing memory leaks. - -**Solution:** LRU cache with TTL - -```typescript -import { LRUCache } from 'lru-cache'; - -const writeTracker = new LRUCache({ - max: 10000, // Maximum 10k entries - ttl: 30_000, // Auto-expire after 30 seconds - updateAgeOnGet: false -}); -``` - -**Key properties:** -- Bounded size (max 10k entries, typical project < 1000 files) -- Auto-expiration (old entries removed automatically) -- LRU eviction (removes least recently used if max exceeded) - -### §5 Developer Experience - -#### §5.1 Starting Watchdog - -```bash -cd ste-runtime -npm run recon:watch - -[RECON Watchdog] Monitoring: /your-project -[RECON Watchdog] Authority mode: AUTOMATIC (confidence ≥ 0.95) -[RECON Watchdog] Self-healing enabled -[RECON Watchdog] RSS server started on http://localhost:3000 -``` - -#### §5.2 Cursor AI Edit Example - -```bash -# User asks Cursor: "Add error handling to this function" - -# Cursor generates code with streaming edits: -[Watchdog] Change detected: handler.py (edit 1/12) -[Watchdog] Change detected: handler.py (edit 2/12) -[Watchdog] Change detected: handler.py (edit 3/12) -... (Cursor streaming, multiple partial saves) -[Watchdog] AI edit pattern detected, debouncing 2000ms... -[Watchdog] Change detected: handler.py (edit 12/12) -[Watchdog] File stable, checking syntax... -[Watchdog] Syntax valid, triggering incremental RECON -[Watchdog] RECON complete (87ms), 1 module updated -[Watchdog] RSS graph reloaded - -# Result: Only 1 RECON run (not 12!) -``` - -#### §5.3 Multi-File Transaction Example - -```bash -# User asks Cursor: "Refactor authentication across backend" - -# Cursor edits multiple files: -[Watchdog] Change detected: auth/handler.py -[Watchdog] Change detected: auth/middleware.py -[Watchdog] Change detected: auth/utils.py -[Watchdog] Multi-file transaction detected (3 files) -[Watchdog] Waiting for transaction to complete... -[Watchdog] No edits for 2s, transaction complete -[Watchdog] Validating syntax for 3 files... -[Watchdog] All files valid, triggering incremental RECON -[Watchdog] RECON complete (142ms), 3 modules updated - -# Result: Only 1 RECON run for entire transaction! -``` - -#### §5.4 Syntax Error Handling Example - -```bash -# Cursor generates code with temporary syntax error: -[Watchdog] Change detected: handler.py -[Watchdog] AI edit pattern detected, debouncing 2000ms... -[Watchdog] File stable, checking syntax... -[Watchdog] Syntax error detected (likely mid-edit), skipping RECON - -# Cursor finishes edit, fixes syntax: -[Watchdog] Change detected: handler.py -[Watchdog] File stable, checking syntax... -[Watchdog] Syntax valid, triggering incremental RECON -[Watchdog] RECON complete (91ms) - -# Result: RECON only runs on syntactically valid code -``` - -#### §5.5 Automatic Resolution Example - -```bash -# Developer moves file: -mv frontend/src/app/features/user-panel/user-panel.component.ts \ - frontend/src/app/components/shared/user-panel.component.ts - -# Watchdog responds: -[RECON Watchdog] Change detected: user-panel.component.ts MOVED -[RECON Watchdog] Migration detected (confidence: 1.0) -[RECON Watchdog] AUTO-RESOLVED: Path migration - - Slice ID unchanged: component:angular:app-user-panel - - Updated source_files metadata - - No references broken -[RECON Watchdog] RSS graph reloaded (120ms) -``` - -#### §5.6 Low-Confidence Conflict Example - -```bash -# Developer renames file and changes content: -mv utils.service.ts helpers.service.ts -# ... also changes class name ... - -# Watchdog responds: -[RECON Watchdog] Change detected: - - DELETED: utils.service.ts - - CREATED: helpers.service.ts -[RECON Watchdog] Migration candidate detected (confidence: 0.82) -[RECON Watchdog] LOW CONFIDENCE - Requires review - - Conflict written to: .ste/state/conflicts/2026-01-07-20-15-33.yaml - - Action: Run `npm run recon:resolve-conflict 2026-01-07-20-15-33` -[RECON Watchdog] Continuing... (1 conflict pending review) -``` - -#### §5.7 Self-Healing Example - -```bash -# Developer (confused) edits slice directly: -vim .ste/state/frontend/component/component-abc123.yaml -# Makes some change, saves - -# Watchdog responds: -[RECON Watchdog] 🏥 External slice modification detected: component-abc123.yaml -[RECON Watchdog] 🏥 Healing from source: user-panel.component.ts -[RECON Watchdog] Slice healed successfully (45ms) -[RECON Watchdog] Tip: Edit source files, not slices (slices are auto-generated) - -# Developer's manual edit is gone (overwritten with correct data from source) -``` - -### §6 Configuration - -```json -{ - "watchdog": { - "enabled": false, - "authorityMode": "automatic", - "confidenceThresholds": { - "autoResolve": 0.95, - "surface": 0.80, - "ignore": 0.50 - }, - "debounceMs": 500, - "aiEditDebounceMs": 2000, - "syntaxValidation": true, - "transactionDetection": true, - "stabilityCheckMs": 100, - "batchSize": 10, - "autoReloadRSS": true, - "fullReconciliationInterval": 300000, - "enableSelfHealing": true, - "fallbackPolling": false, - "pollingInterval": 5000 - } -} -``` - -**New Field Descriptions:** - -- `aiEditDebounceMs` - Debounce timeout for AI-generated edits (default: 2000ms). Used when multiple rapid changes detected (Cursor streaming pattern). -- `syntaxValidation` - Skip RECON for files with syntax errors (default: true). Prevents processing mid-edit files. -- `transactionDetection` - Wait for multi-file edits to complete (default: true). Detects when Cursor edits multiple files together. -- `stabilityCheckMs` - Time to wait for file mtime stability check (default: 100ms). Ensures file is no longer being written. - -### §7 Safeguards - -#### §7.1 Watchdog Health Monitoring - -```typescript -class WatchdogHealth { - lastEventTime: number; - lastRECONTime: number; - lastFullReconciliation: number; - - checkHealth(): HealthStatus { - const now = Date.now(); - - if (now - this.lastEventTime > 10 * 60 * 1000) { - return { healthy: false, reason: 'No file system events received' }; - } - - if (now - this.lastFullReconciliation > 10 * 60 * 1000) { - return { healthy: false, reason: 'Full reconciliation overdue' }; - } - - return { healthy: true }; - } -} -``` - -#### §7.2 Graceful Degradation - -```typescript -let consecutiveFailures = 0; - -try { - await processUpdate(file); - consecutiveFailures = 0; -} catch (error) { - consecutiveFailures++; - - if (consecutiveFailures > 10) { - console.error(`[RECON Watchdog] Too many failures, disabling automatic mode.`); - console.error(`Please run manual RECON to recover: npm run recon:full`); - watchdog.disable(); - } -} -``` - -#### §7.3 Network/Cloud File System Detection - -```typescript -const fsType = await detectFileSystemType(projectRoot); - -if (fsType !== 'local') { - console.warn(` - WARNING: Non-Local File System Detected (${fsType}) - -Watchdog may experience: -- Delayed or duplicate file system events -- Event loss during high activity -- Conflicts with sync software - -Recommendation: -- Use local file system for active development -- Fallback to manual RECON if issues occur - `); - - // Enable fallback polling mode - config.watchdog.fallbackPolling = true; - config.watchdog.fullReconciliationInterval = 60_000; // 1 minute -} -``` - -#### §7.4 Audit Log - -All automatic decisions are logged: - -```yaml -# .ste/state/watchdog/2026-01-07-session.yaml -session_start: "2026-01-07T19:00:00Z" -session_end: "2026-01-07T22:30:00Z" -migrations: - - type: PATH_CHANGE - sliceId: "component:angular:app-user-panel" - oldPath: "frontend/.../features/user-panel/..." - newPath: "frontend/.../components/shared/..." - confidence: 1.0 - applied: true - timestamp: "2026-01-07T19:15:00Z" - - type: IDENTITY_UPGRADE - oldId: "service:frontend/.../data.service.ts:DataService" - newId: "service:angular:app.features.data.DataService" - confidence: 0.95 - applied: true - referencesUpdated: 12 - timestamp: "2026-01-07T20:00:00Z" -conflicts: - - type: LOW_CONFIDENCE_MIGRATION - candidateOldId: "service:...utils.service.ts:UtilsService" - candidateNewId: "service:...helpers.service.ts:HelpersService" - confidence: 0.82 - surfaced: true - resolved: false - timestamp: "2026-01-07T21:30:00Z" -stats: - filesChanged: 47 - slicesUpdated: 52 - migrationsApplied: 2 - conflictsSurfaced: 1 - selfHealingEvents: 0 - fullReconciliations: 3 -``` - ---- - -## Prerequisites - -Before implementing watchdog, these foundational pieces must be stable: - -1. **Incremental RECON** - Must be fast (<100ms for 1-5 file changes) -2. **Migration detection** - Must be accurate (>95% correct classifications) -3. **Stable semantic IDs** - Must survive file moves (path-independent IDs) -4. **RSS hot reloading** - Must reload graph without full restart -5. **Resource efficiency** - File watching with acceptable CPU/memory usage - ---- - -## Non-Goals - -- Not a replacement for manual RECON (both modes coexist) -- Not automatic publication to canonical state (ADF's responsibility) -- Not cross-project synchronization -- Not CI/CD integration (watchdog is for local development only) -- Not automatic conflict resolution for low-confidence cases - ---- - -## Implementation Phases - -### Phase 1: Critical Safeguards (Must Have) -1. Content-hash based write tracking -2. Update coordinator (prevent cascading loops) -3. Periodic full reconciliation -4. Source checksum in slice provenance - -### Phase 2: Important Features (Should Have) -5. Update queue with version tracking -6. LRU cache for trackers -7. Atomic write with cleanup -8. Self-healing on slice edits - -### Phase 3: Nice-to-Have (Could Have) -9. File system type detection -10. Health monitoring -11. State consistency verification -12. RSS integration (hot reload notification) - ---- - -## Success Criteria - -### Functional Requirements - -- Watchdog detects file changes within 500ms -- Incremental RECON completes in <100ms for 1-5 files -- High-confidence migrations (≥0.95) auto-resolve correctly -- Low-confidence migrations (<0.95) surface to human -- Self-healing restores correct state from manual slice edits -- No infinite loops under any scenario -- Periodic reconciliation catches missed events -- RSS graph stays fresh (reloads after updates) - -### Non-Functional Requirements - -- Memory usage: <100MB while idle, <500MB under load -- CPU usage: <1% while idle, <10% during updates -- Disk I/O: <10 writes/second average -- Event buffer: Handles 1000+ file changes without event loss -- Reliability: <1 failure per 1000 updates -- Developer experience: "Just works" without configuration - ---- - -## Risks and Mitigations - -| Risk | Impact | Mitigation | -|------|--------|------------| -| File system event loss | Stale state | Periodic full reconciliation (every 5 min) | -| Infinite loops | System unusable | Content-hash tracking + update coordinator | -| False positive migrations | Broken references | Confidence thresholds, human review for <0.95 | -| Memory leaks | Watchdog crashes | LRU cache with TTL, bounded data structures | -| Network file systems | Unreliable events | Detect and warn, fallback to polling | -| Partial writes | Corrupted slices | Atomic writes with temp file cleanup | -| Too many failures | Developer frustration | Graceful degradation, auto-disable after 10 failures | - ---- - -## Future Work - -### RSS Integration - -When RSS is implemented, watchdog will notify RSS to reload graph: - -```typescript -// After RECON completes: -await notifyRSS('graph-updated', { - slicesUpdated: results.updated.length, - slicesCreated: results.created.length, - generation: currentGeneration -}); - -// RSS responds: -rss.reloadGraph(); // Reload from disk -console.log('[RSS] Graph reloaded, queries now reflect latest state'); -``` - -### Language Server Protocol (LSP) - -Future integration with VS Code, IntelliJ: -- Real-time semantic hints -- Jump-to-definition across languages -- Inline dependency visualization -- Conflict notifications in IDE - -### Real-Time Query API - -WebSocket or SSE for live updates: -```typescript -const ws = new WebSocket('ws://localhost:3000/rss/live'); - -ws.on('message', (event) => { - if (event.type === 'slice-updated') { - // UI refreshes automatically - } -}); -``` - ---- - -## Learning Log - -### Open Questions - -1. **Migration confidence calibration:** What is the empirical accuracy of 0.95 threshold? -2. **RSS reload performance:** How fast can RSS reload 10,000+ slices? -3. **Windows performance:** Is file watching reliable on Windows network drives? -4. **False positive rate:** How often do high-confidence migrations incorrectly resolve? - -### Hypotheses to Test - -1. **H1:** Content-hash tracking prevents 99%+ of infinite loops -2. **H2:** Periodic reconciliation catches all missed events within 5 minutes -3. **H3:** Self-healing reduces manual slice edits by 100% (developers learn quickly) -4. **H4:** Watchdog reduces RECON invocations by 90% (automatic maintenance) -5. **H5:** Syntax validation reduces unnecessary RECON runs by 80% during AI editing -6. **H6:** Transaction detection prevents 95% of redundant multi-file RECON runs -7. **H7:** AI edit detection with longer debounce reduces RECON runs by 90% during Cursor generation - -### Metrics to Collect - -- Watchdog uptime vs. crashes -- Migrations auto-resolved vs. surfaced -- False positives (incorrect auto-resolutions) -- Event loss rate (detected by periodic reconciliation) -- Memory/CPU usage over 8-hour development session -- Developer satisfaction (survey) -- **Edit pattern metrics:** - - File changes detected vs. RECON runs triggered (should be 10:1 or better) - - Syntax validation skips (files with errors) - - Transaction coalescing rate (multi-file edits → single RECON) - - AI edit detection accuracy (true positives vs false positives) - - Debounce effectiveness (rapid changes → single RECON) - ---- - -## References - -- **E-ADR-001:** Provisional Execution (Manual RECON mode) -- **E-ADR-002:** RECON Self-Validation -- **E-ADR-006:** Angular and CSS/SCSS Semantic Extraction -- **Git rename detection:** `git log --follow` (heuristic similarity scoring) -- **LRU Cache:** npm package `lru-cache` -- **File watching:** npm package `chokidar` - ---- - -## Revision History - -| Date | Version | Changes | -|------|---------|---------| -| 2026-01-07 | 0.1 | Initial proposal | - ---- - -**Remember:** Watchdog exists to maintain live project state automatically, not to replace human judgment on ambiguous cases. When in doubt, surface to human. - diff --git a/documentation/e-adr-archived/E-ADR-008-Extractor-Development-Guide.md b/documentation/e-adr-archived/E-ADR-008-Extractor-Development-Guide.md deleted file mode 100644 index bd7f4ce..0000000 --- a/documentation/e-adr-archived/E-ADR-008-Extractor-Development-Guide.md +++ /dev/null @@ -1,922 +0,0 @@ -# E-ADR-008: Extractor Development Guide - -**Status:** Accepted -**Implementation:** N/A (Documentation Guide) -**Date:** 2026-01-07 -**Author:** Erik Gallmann -**Authority:** Exploratory ADR (Living Document) - -> **Next Step:** Keep updated as extractor patterns evolve. No spec validation needed (guide, not implementation). - ---- - -## Purpose - -Enable developers to create custom semantic extractors for languages, frameworks, and file types not included in the ste-runtime distribution. This guide provides patterns, interfaces, and examples to lower the barrier to entry for extractor development. - -**Target Audience:** -- Users extending ste-runtime for their tech stack -- Contributors adding new extractors to ste-runtime -- Teams building domain-specific extractors (internal tooling, DSLs) - ---- - -## Philosophy: What to Extract - -### Core Principle - -**Extract semantics, not syntax.** - -AI-DOC slices should capture **what the code does and how it relates to other code**, not how it's implemented. - -### Good Extraction (Semantic) - -```typescript -// Extract this: -{ - type: 'function', - name: 'getUserById', - signature: 'function getUserById(id: string): Promise', - calls: ['database.query', 'logger.info'], - http_endpoint: '/api/users/:id' -} - -// NOT this: -{ - type: 'function', - implementation: 'const getUserById = async (id) => { const result = await database.query(...); ... }' -} -``` - -### Extraction Decision Matrix - -| Pattern | Extract? | Rationale | -|---------|----------|-----------| -| Function signatures | Yes | Public API surface | -| Class names and methods | Yes | Component structure | -| Import/export relationships | Yes | Dependency graph | -| HTTP endpoints (routes) | Yes | API contracts | -| Database queries (SQL, ORM) | Yes | Data access patterns | -| Configuration (env vars, settings) | Yes | Runtime dependencies | -| Function bodies | No | Implementation detail | -| Variable assignments | No | Implementation detail | -| Loop constructs | No | Implementation detail | -| Comments (usually) | Selective | Extract semantic annotations only | - -### Examples by Language - -**TypeScript/JavaScript:** -- Extract: Functions, classes, exports, imports, decorators -- Skip: Variable declarations, loops, conditionals - -**Python:** -- Extract: Functions, classes, decorators (`@app.route`), imports -- Skip: Variable assignments, comprehensions, loops - -**CloudFormation:** -- Extract: Resources, parameters, outputs, conditions -- Skip: Intrinsic function internals, metadata - -**Angular:** -- Extract: Components, services, routes, decorators, selectors -- Skip: Template implementation, lifecycle method bodies - -**CSS/SCSS:** -- Extract: Design tokens (variables), breakpoints, animations, class names -- Skip: Property values, vendor prefixes - ---- - -## Extractor Architecture - -### Extractor Lifecycle - -``` -┌─────────────────────────────────────────────────────────────┐ -│ RECON Execution Flow │ -└─────────────────────────────────────────────────────────────┘ - -Phase 1: DISCOVERY - ├─ User config specifies languages: ["typescript", "python", "myextractor"] - ├─ Discovery phase maps file extensions to languages - └─ Returns: Map (language → filepaths) - -Phase 2: EXTRACTION (Your Extractor Runs Here) - ├─ For each file in your language: - │ ├─ extract(filepath, content) → Assertion[] - │ ├─ Each assertion captures ONE semantic element - │ └─ Assertions include provenance (file, line, language) - └─ Returns: Assertion[] - -Phase 3: NORMALIZATION - ├─ Converts Assertion[] to NormalizedAssertion[] - ├─ Adds IDs, domains, types - └─ Returns: NormalizedAssertion[] - -Phase 4: INFERENCE - ├─ Analyzes references between assertions - ├─ Adds forward/reverse references - └─ Returns: NormalizedAssertion[] (with references) - -Phase 5: POPULATION - ├─ Writes slices to .ste/state/graph/ - └─ Your extracted semantics are now in AI-DOC -``` - ---- - -## Required Interface - -### Minimal Extractor - -Every extractor must export a function matching this signature: - -```typescript -export async function extract( - filepath: string, - content: string, - projectRoot: string -): Promise { - // 1. Parse the file (AST, regex, line-by-line) - // 2. Identify semantic elements - // 3. Return assertions - return assertions; -} -``` - -### Assertion Schema - -```typescript -interface Assertion { - // Core identification - domain: string; // "backend", "frontend", "infrastructure", "data" - type: string; // "function", "class", "component", "route", "resource" - - // Element details - element: { - name: string; // Element name - [key: string]: unknown; // Type-specific fields - }; - - // Provenance (required) - provenance: { - file: string; // Relative path from project root - line: number; // Line number in source file - language: string; // Your extractor's language name - }; - - // Relationships (optional, but recommended) - references?: { - imports?: string[]; // Modules/files imported - calls?: string[]; // Functions/methods called - uses?: string[]; // General dependencies - }; -} -``` - ---- - -## Implementation Patterns - -### Pattern 1: AST-Based Extraction (TypeScript, Python) - -**When to use:** Language has a mature parser (tree-sitter, @babel/parser, etc.) - -**Example: TypeScript Extractor** - -```typescript -import ts from 'typescript'; - -export async function extract( - filepath: string, - content: string, - projectRoot: string -): Promise { - const assertions: Assertion[] = []; - - // Parse to AST - const sourceFile = ts.createSourceFile( - filepath, - content, - ts.ScriptTarget.Latest, - true - ); - - // Walk the AST - function visit(node: ts.Node) { - // Extract functions - if (ts.isFunctionDeclaration(node) && node.name) { - assertions.push({ - domain: 'backend', - type: 'function', - element: { - name: node.name.getText(), - signature: node.getText().split('{')[0].trim(), - async: node.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword), - }, - provenance: { - file: path.relative(projectRoot, filepath), - line: sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1, - language: 'typescript', - }, - }); - } - - ts.forEachChild(node, visit); - } - - visit(sourceFile); - return assertions; -} -``` - -**Pros:** -- Accurate (respects language grammar) -- Handles complex syntax -- Provides line numbers - -**Cons:** -- Requires parser dependency -- Must handle parser errors - ---- - -### Pattern 2: Subprocess Delegation (Python, Go, Ruby) - -**When to use:** Language has no JavaScript parser, or you prefer native tooling - -**Example: Python Extractor (Subprocess)** - -```typescript -import { spawn } from 'child_process'; -import path from 'path'; - -export async function extract( - filepath: string, - content: string, - projectRoot: string -): Promise { - // Delegate to Python script - const pythonScript = path.join(__dirname, '../../python-scripts/extract_python.py'); - - return new Promise((resolve, reject) => { - const proc = spawn('python3', [pythonScript, filepath]); - let stdout = ''; - let stderr = ''; - - proc.stdout.on('data', (data) => stdout += data); - proc.stderr.on('data', (data) => stderr += data); - - proc.on('close', (code) => { - if (code !== 0) { - reject(new Error(`Python extraction failed: ${stderr}`)); - return; - } - - const assertions = JSON.parse(stdout); - resolve(assertions); - }); - }); -} -``` - -**Python script (`extract_python.py`):** - -```python -import ast -import json -import sys - -def extract_functions(filepath): - with open(filepath, 'r') as f: - tree = ast.parse(f.read()) - - assertions = [] - for node in ast.walk(tree): - if isinstance(node, ast.FunctionDef): - assertions.append({ - 'domain': 'backend', - 'type': 'function', - 'element': { - 'name': node.name, - 'signature': f"def {node.name}({', '.join(arg.arg for arg in node.args.args)})", - }, - 'provenance': { - 'file': filepath, - 'line': node.lineno, - 'language': 'python', - }, - }) - - return assertions - -if __name__ == '__main__': - assertions = extract_functions(sys.argv[1]) - print(json.dumps(assertions)) -``` - -**Pros:** -- Uses native language tooling -- No JavaScript parser dependency -- Easy to maintain (language-native code) - -**Cons:** -- Subprocess overhead -- Requires language runtime installed - ---- - -### Pattern 3: Regex/Line-Based Extraction (Simple Formats) - -**When to use:** File format is line-oriented and has simple patterns - -**Example: Environment File Extractor** - -```typescript -export async function extract( - filepath: string, - content: string, - projectRoot: string -): Promise { - const assertions: Assertion[] = []; - const lines = content.split('\n'); - - lines.forEach((line, index) => { - // Match: KEY=value - const match = line.match(/^([A-Z_]+)=(.*)$/); - if (match) { - const [, name, value] = match; - assertions.push({ - domain: 'infrastructure', - type: 'environment-variable', - element: { - name, - has_default: value.length > 0, - }, - provenance: { - file: path.relative(projectRoot, filepath), - line: index + 1, - language: 'env', - }, - }); - } - }); - - return assertions; -} -``` - -**Pros:** -- Extremely fast -- No dependencies -- Simple to implement - -**Cons:** -- Fragile (breaks with complex syntax) -- No semantic understanding -- Best for very simple formats only - ---- - -### Pattern 4: YAML/JSON Schema-Based (CloudFormation, Kubernetes) - -**When to use:** Structured data with known schema - -**Example: CloudFormation Extractor (Simplified)** - -```typescript -import yaml from 'js-yaml'; - -export async function extract( - filepath: string, - content: string, - projectRoot: string -): Promise { - const assertions: Assertion[] = []; - - try { - const template = yaml.load(content) as any; - - // Extract resources - const resources = template.Resources || {}; - for (const [logicalId, resource] of Object.entries(resources)) { - assertions.push({ - domain: 'infrastructure', - type: 'cloudformation-resource', - element: { - name: logicalId, - resource_type: (resource as any).Type, - properties: Object.keys((resource as any).Properties || {}), - }, - provenance: { - file: path.relative(projectRoot, filepath), - line: 1, // YAML doesn't provide line numbers easily - language: 'cloudformation', - }, - }); - } - } catch (error) { - console.warn(`Failed to parse ${filepath}:`, error); - } - - return assertions; -} -``` - -**Pros:** -- Leverages existing parsers -- Structured data is easy to navigate -- Schema validation possible - -**Cons:** -- Line numbers require extra work -- Parser errors abort extraction - ---- - -## Registering Your Extractor - -### Step 1: Add Language Support - -**File:** `src/recon/discovery.ts` - -```typescript -const LANGUAGE_EXTENSIONS: Record = { - typescript: ['.ts', '.tsx'], - python: ['.py'], - cloudformation: ['.yaml', '.yml', '.json'], - myextractor: ['.myext', '.custom'], // ← Add your extensions -}; - -export type SupportedLanguage = - | 'typescript' - | 'python' - | 'cloudformation' - | 'myextractor'; // ← Add your language -``` - -### Step 2: Create Extractor File - -**File:** `src/extractors/myextractor/myextractor-extractor.ts` - -```typescript -export async function extract( - filepath: string, - content: string, - projectRoot: string -): Promise { - // Your implementation here - return []; -} -``` - -### Step 3: Register in Extraction Phase - -**File:** `src/recon/phases/extraction.ts` - -```typescript -import { extract as extractMyExtractor } from '../../extractors/myextractor/myextractor-extractor.js'; - -async function extractByLanguage( - language: SupportedLanguage, - files: string[], - projectRoot: string -): Promise { - switch (language) { - case 'typescript': - return extractTypeScript(files, projectRoot); - case 'python': - return extractPython(files, projectRoot); - case 'myextractor': // ← Add your case - return extractMyExtractor(files, projectRoot); - default: - return []; - } -} -``` - -### Step 4: Update Configuration Schema - -**File:** `src/config/types.ts` - -```typescript -export type SupportedLanguage = - | 'typescript' - | 'python' - | 'cloudformation' - | 'json' - | 'angular' - | 'css' - | 'myextractor'; // ← Add your language -``` - ---- - -## Testing Your Extractor - -### Test File Structure - -``` -src/extractors/myextractor/ -├── myextractor-extractor.ts # Your extractor -├── myextractor-extractor.test.ts # Tests -└── fixtures/ # Test files - ├── simple.myext - ├── complex.myext - └── edge-cases.myext -``` - -### Example Test - -```typescript -import { extract } from './myextractor-extractor.js'; -import fs from 'fs/promises'; -import path from 'path'; - -describe('MyExtractor', () => { - it('should extract simple elements', async () => { - const filepath = path.join(__dirname, 'fixtures', 'simple.myext'); - const content = await fs.readFile(filepath, 'utf-8'); - - const assertions = await extract(filepath, content, '/project/root'); - - expect(assertions).toHaveLength(3); - expect(assertions[0]).toMatchObject({ - domain: 'backend', - type: 'function', - element: { - name: 'myFunction', - }, - provenance: { - file: expect.stringContaining('simple.myext'), - line: 5, - language: 'myextractor', - }, - }); - }); - - it('should handle parse errors gracefully', async () => { - const content = 'INVALID SYNTAX !!!'; - const assertions = await extract('/test.myext', content, '/project/root'); - - // Should return empty array, not throw - expect(assertions).toEqual([]); - }); -}); -``` - ---- - -## Reference Extraction - -### Why References Matter - -References enable the **RSS graph queries**: - -```typescript -// Find all functions that call getUserById -rss.query('function', { calls: 'getUserById' }); - -// Find all components that import AuthService -rss.query('component', { imports: 'AuthService' }); -``` - -### Common Reference Types - -```typescript -interface References { - imports?: string[]; // Modules/files imported - calls?: string[]; // Functions/methods called - uses?: string[]; // Generic dependencies - extends?: string[]; // Class inheritance - implements?: string[]; // Interface implementation - http_calls?: string[]; // HTTP endpoints called - db_queries?: string[]; // Database tables accessed -} -``` - -### Example: Extracting Imports - -```typescript -// TypeScript: import { UserService } from './services/user-service'; -references: { - imports: ['./services/user-service', 'UserService'] -} - -// Python: from app.services.user import UserService -references: { - imports: ['app.services.user', 'UserService'] -} - -// CloudFormation: DependsOn: [DatabaseStack, VPCStack] -references: { - depends_on: ['DatabaseStack', 'VPCStack'] -} -``` - ---- - -## Performance Considerations - -### Benchmarks to Target - -| Operation | Target | Good | Acceptable | -|-----------|--------|------|------------| -| Parse single file | <10ms | <50ms | <200ms | -| Extract 100 files | <1s | <5s | <30s | -| Full project (1000 files) | <10s | <60s | <5min | - -### Optimization Strategies - -**1. Parallel Processing** -```typescript -const assertions = await Promise.all( - files.map(f => extractFile(f)) -); -``` - -**2. Caching** -```typescript -const cache = new Map(); -if (cache.has(fileHash)) { - return cache.get(fileHash); -} -``` - -**3. Incremental Extraction** -```typescript -// Only extract changed files -const changedFiles = files.filter(f => isModified(f)); -``` - -**4. Streaming for Large Files** -```typescript -// Process line-by-line for huge files -const stream = fs.createReadStream(filepath); -``` - ---- - -## Example Extractors - -### Included with ste-runtime - -| Extractor | Complexity | Pattern | Files | -|-----------|------------|---------|-------| -| **JSON** | Simple | Schema-based | `src/extractors/json/` | -| **TypeScript** | Moderate | AST-based | `src/extractors/typescript/` | -| **Python** | Moderate | Subprocess | `src/extractors/python/` | -| **CloudFormation** | Complex | Schema + spec | `src/extractors/cloudformation/` | -| **Angular** | Very Complex | Decorator-based | `src/extractors/angular/` | -| **CSS/SCSS** | Moderate | Regex + parsing | `src/extractors/css/` | - -### Recommended Study Order - -1. **Start with JSON extractor** - Simplest possible extractor -2. **Study TypeScript extractor** - AST pattern, good comments -3. **Review Python extractor** - Subprocess delegation -4. **Examine Angular extractor** - Complex decorators, cross-file references - ---- - -## Common Pitfalls - -### Pitfall 1: Extracting Too Much - -**Bad:** -```typescript -// Extracting every variable -{ type: 'variable', name: 'i', value: 0 } -{ type: 'variable', name: 'temp', value: 'hello' } -``` - -**Good:** -```typescript -// Extracting only semantic elements -{ type: 'function', name: 'processUsers', signature: '...' } -``` - -### Pitfall 2: Not Handling Errors - -**Bad:** -```typescript -const ast = parser.parse(content); // Throws on syntax error -``` - -**Good:** -```typescript -try { - const ast = parser.parse(content); -} catch (error) { - console.warn(`Parse error in ${filepath}:`, error); - return []; // Return empty, don't crash RECON -} -``` - -### Pitfall 3: Absolute Paths in Provenance - -**Bad:** -```typescript -provenance: { - file: '/Users/me/project/src/app.ts' // Absolute -} -``` - -**Good:** -```typescript -provenance: { - file: path.relative(projectRoot, filepath) // 'src/app.ts' -} -``` - -### Pitfall 4: Missing Line Numbers - -**Bad:** -```typescript -provenance: { - file: 'src/app.ts', - line: 0 // Invalid -} -``` - -**Good:** -```typescript -provenance: { - file: 'src/app.ts', - line: node.getLineNumber() // Actual line -} -``` - ---- - -## Distribution - -### Bundled Extractor (Part of ste-runtime) - -**Location:** `src/extractors/myextractor/` - -**Requirements:** -- TypeScript source -- Test suite -- Fixtures -- Update discovery.ts, extraction.ts, types.ts - -**Benefits:** -- Official support -- Included in releases -- Community maintained - -### Third-Party Extractor (User-provided) - -**Not yet supported.** Future E-ADR will define: -- Plugin system -- npm package format -- Configuration registration - ---- - -## Future Enhancements - -### Phase 1: Plugin System -- Load extractors from npm packages -- Configuration: `extractors: ['@myorg/rust-extractor']` -- Dynamic registration - -### Phase 2: Extractor Marketplace -- Registry of community extractors -- Versioning and compatibility -- Quality metrics - -### Phase 3: Code Generation -- CLI: `ste generate-extractor --language rust` -- Scaffold with tests and fixtures -- Best practices template - ---- - -## Questions and Support - -### Where to Get Help - -1. **Read E-ADR-001** - Understand RECON philosophy -2. **Study existing extractors** - JSON, TypeScript, Python -3. **Review test suites** - See expected behavior -4. **Open GitHub issues** - For questions and bugs - -### Contributing Your Extractor - -1. Implement extractor in `src/extractors/yourlang/` -2. Add comprehensive tests -3. Update this E-ADR with lessons learned -4. Submit pull request with examples - ---- - -## Living Document Notice - -**This E-ADR will be updated as we implement new extractors.** - -When building E-ADR-006 (Angular + CSS), E-ADR-009 (React), or any future extractor, we will: -- Document new patterns discovered -- Add real-world examples -- Update pitfalls and best practices -- Refine interfaces as needed - -**Last Updated:** 2026-01-07 -**Updates Planned:** After E-ADR-006 implementation (Angular + CSS extractors) - ---- - -## Appendix A: Full Extractor Checklist - -- [ ] Implements `extract(filepath, content, projectRoot): Promise` -- [ ] Returns assertions matching schema (domain, type, element, provenance) -- [ ] Includes relative file paths in provenance -- [ ] Provides accurate line numbers -- [ ] Handles parse errors gracefully (returns empty, doesn't throw) -- [ ] Extracts semantic elements (not implementation details) -- [ ] Includes references (imports, calls, dependencies) -- [ ] Has test suite with fixtures -- [ ] Registered in discovery.ts -- [ ] Registered in extraction.ts -- [ ] Added to SupportedLanguage type -- [ ] Performance: <200ms per file (acceptable) -- [ ] Documentation: Updated this E-ADR with learnings - ---- - -## Appendix B: Assertion Schema Reference - -```typescript -interface Assertion { - domain: 'backend' | 'frontend' | 'infrastructure' | 'data'; - type: string; // Extractor-specific - element: { - name: string; - [key: string]: unknown; - }; - provenance: { - file: string; // Relative path - line: number; // 1-indexed - language: string; // Extractor name - }; - references?: { - imports?: string[]; - calls?: string[]; - uses?: string[]; - extends?: string[]; - implements?: string[]; - [key: string]: string[] | undefined; - }; -} -``` - ---- - -## Appendix C: Quick Start Template - -```typescript -// src/extractors/myextractor/myextractor-extractor.ts - -import path from 'path'; -import type { Assertion } from '../../recon/phases/extraction.js'; - -export async function extract( - filepath: string, - content: string, - projectRoot: string -): Promise { - const assertions: Assertion[] = []; - - try { - // TODO: Parse the file - // TODO: Walk the structure - // TODO: Extract semantic elements - - // Example assertion: - assertions.push({ - domain: 'backend', - type: 'function', - element: { - name: 'exampleFunction', - }, - provenance: { - file: path.relative(projectRoot, filepath), - line: 1, - language: 'myextractor', - }, - }); - } catch (error) { - console.warn(`[MyExtractor] Failed to extract ${filepath}:`, error); - } - - return assertions; -} -``` - ---- - -**End of E-ADR-008** - - - diff --git a/documentation/e-adr-archived/E-ADR-009-Self-Configuring-Domain-Discovery.md b/documentation/e-adr-archived/E-ADR-009-Self-Configuring-Domain-Discovery.md deleted file mode 100644 index d8e01e4..0000000 --- a/documentation/e-adr-archived/E-ADR-009-Self-Configuring-Domain-Discovery.md +++ /dev/null @@ -1,629 +0,0 @@ -# E-ADR-009: Self-Configuring Domain Discovery - -**Status:** Proposed -**Implementation:** Complete -**Date:** 2026-01-07 -**Author:** Erik Gallmann -**Priority:** P0 - Critical for Adoption -**Supersedes:** None -**Related:** E-ADR-001 (RECON), E-ADR-006 (Angular Extraction) - -> **Next Step:** Validate discovery heuristics against ste-spec portability requirements for ADR graduation. - ---- - -## Context and Problem Statement - -The ste-runtime is designed to be a portable, reusable framework for semantic extraction that can be dropped into any project. However, requiring users to manually configure domain names and paths creates a significant adoption barrier. - -**The Challenge:** Different projects use different naming conventions: -- Some use `frontend` and `backend` -- Others use `client` and `server` -- Some use `web` and `api` -- Others have `app`, `ui`, `services`, etc. - -**Current Limitation:** The runtime would require manual configuration to understand these different structures, creating friction at every installation. - -**Desired State:** A self-configuring runtime that automatically understands any project structure, requiring zero configuration from users. - ---- - -## Decision Drivers - -### Primary Driver: Zero-Configuration Adoption - -Manual configuration creates multiple friction points: -- Users must learn configuration schema -- Every project requires setup time -- Mistakes in configuration cause failures -- Reduces "just works" experience - -**Goal:** Enable users to drop ste-runtime into any project and run immediately with zero setup. - -### Secondary Driver: Universal Compatibility - -Projects vary widely in structure: -- Monorepos with multiple packages -- Single-page applications -- Full-stack applications -- Microservices architectures -- Various naming conventions - -**Goal:** Work with any project structure automatically, without requiring users to understand or describe their architecture. - -### Constraint: Framework Independence - -The runtime should discover and adapt to: -- Any frontend framework (Angular, React, Vue, Svelte, etc.) -- Any backend framework (Express, FastAPI, Lambda, Flask, etc.) -- Any infrastructure tooling (CloudFormation, Terraform, Kubernetes, etc.) - ---- - -## Considered Options - -### Option 1: Manual Configuration - -**Approach:** Require users to configure domains explicitly. - -```json -{ - "domains": { - "client": { - "type": "client", - "paths": ["src/client"], - "framework": "react" - }, - "server": { - "type": "server", - "paths": ["src/server"], - "framework": "express" - } - } -} -``` - -**Pros:** -- Explicit control for power users -- Clear documentation of project structure -- Faster to implement (2 weeks) - -**Cons:** -- High adoption barrier (requires learning configuration) -- Setup required for every project -- Users must understand domain concepts before use -- Configuration errors cause failures -- Maintenance burden as projects evolve - -**Adoption Impact:** Every new user must spend 10-30 minutes configuring before first use. - ---- - -### Option 2: Self-Configuring Domain Discovery CHOSEN - -**Approach:** Automatically discover project structure on startup, adapt to whatever naming conventions the project uses. - -```typescript -// No configuration required -// Runtime automatically discovers: -// - Project A: uses "frontend" + "backend" -// - Project B: uses "client" + "server" -// - Project C: uses "web" + "api" -``` - -**Pros:** -- Zero configuration required - drop in and run -- Universal compatibility (works with any structure) -- Better adoption UX ("just works") -- Intelligent behavior (understands project context) -- Framework-agnostic (detects any framework) -- Self-documenting (discovery output shows what was found) - -**Cons:** -- Longer implementation time (4 weeks vs 2 weeks) -- More complex implementation -- Discovery heuristics require careful design - -**Adoption Impact:** Users can run `recon` immediately after installation - zero setup time. - ---- - -## Decision Outcome - -**Chosen Option:** **Option 2 - Self-Configuring Domain Discovery** - -### Rationale - -Despite the longer implementation timeline, self-configuration transforms the adoption experience: - -1. **Eliminates Adoption Barrier** - - Download and run immediately - - No learning curve - - No configuration errors - - "Just works" with any project - -2. **Universal Compatibility** - - Works with any naming convention - - Adapts to any framework - - Handles any project structure - - Scales to monorepos, microservices, etc. - -3. **Better User Experience** - - Immediate value delivery - - No manual setup overhead - - Self-documenting behavior - - Reduces support burden - -4. **Future-Proof Architecture** - - Adapts to new frameworks automatically - - No breaking changes as projects evolve - - Enables ecosystem growth - -### Key Insight - -> "ste-runtime should orient itself to the project it was added to. It should understand the project structure and ensure that it can execute without humans configuring the ste-runtime. This is big for adoption and we must solve for this." - -The investment in self-configuration pays dividends in adoption velocity and user satisfaction. - ---- - -## Technical Design - -### Phase 0: Project Structure Discovery - -Add automatic discovery phase before extraction: - -```typescript -interface DiscoveredDomain { - name: string; // Discovered from project directories - type: DomainType; // CLIENT | SERVER | INFRASTRUCTURE | DATA - rootPaths: string[]; // Where domain files are located - indicators: string[]; // What led to identification - confidence: number; // 0-1, how confident discovery is - framework?: string; // Detected framework (e.g., "angular", "react") -} - -interface ProjectStructure { - rootDir: string; - domains: DiscoveredDomain[]; - architecture: 'monorepo' | 'multi-repo' | 'single'; -} -``` - -### Discovery Heuristics - -**CLIENT Domain Detection:** -- Directory names: `frontend`, `client`, `web`, `ui`, `app`, `src/app`, `www` -- File patterns: `*.component.ts`, `*.tsx`, `*.jsx`, `*.vue`, `*.svelte` -- Framework indicators: `angular.json`, `package.json` with React/Vue/Angular -- UI patterns: Presence of `components/`, `views/`, `pages/` directories -- Style files: CSS, SCSS, styled-components - -**SERVER Domain Detection:** -- Directory names: `backend`, `server`, `api`, `services`, `src/server`, `lambda` -- File patterns: `*.handler.py`, `*.controller.ts`, `*.route.js`, `*.service.ts` -- Framework indicators: Express, FastAPI, Lambda, Flask, NestJS -- API patterns: Presence of `routes/`, `handlers/`, `controllers/`, `endpoints/` - -**INFRASTRUCTURE Domain Detection:** -- Directory names: `infrastructure`, `iac`, `terraform`, `cloudformation`, `k8s`, `helm` -- File patterns: `*.yaml` (CloudFormation), `*.tf`, `*.tfvars`, `*.k8s.yaml` -- IaC indicators: Terraform modules, CloudFormation templates, Kubernetes manifests - -**DATA Domain Detection:** -- Directory names: `data`, `models`, `schemas`, `entities`, `database` -- File patterns: JSON schemas, database migrations, seed data -- ORM indicators: Sequelize models, SQLAlchemy models, Prisma schemas - -### Discovery Algorithm - -```typescript -async function discoverProjectStructure(rootDir: string): Promise { - // 1. Scan directory structure - const fileTree = await scanFileSystem(rootDir); - - // 2. Analyze directories for naming patterns - const directorySignals = analyzeDirectories(fileTree); - - // 3. Analyze file types and patterns - const fileSignals = analyzeFilePatterns(fileTree); - - // 4. Detect frameworks from config files - const frameworkSignals = await detectFrameworks(rootDir); - - // 5. Combine signals with confidence scoring - const domains = identifyDomains({ - directorySignals, - fileSignals, - frameworkSignals - }); - - // 6. Determine architecture type - const architecture = inferArchitecture(domains); - - return { rootDir, domains, architecture }; -} -``` - -### Confidence Scoring - -Each discovery signal contributes to confidence: - -```typescript -function calculateDomainConfidence(signals: Signal[]): number { - let score = 0; - - // Directory name match: 30% - if (hasRecognizedDirectoryName(signals)) score += 0.3; - - // File patterns match: 30% - if (hasRecognizedFilePatterns(signals)) score += 0.3; - - // Framework detected: 40% - if (hasFrameworkIndicators(signals)) score += 0.4; - - return Math.min(score, 1.0); -} -``` - -### Integration with Extraction - -#### Normalization Phase - -Replace static domain assignment with discovered domains: - -```typescript -// Dynamically assign domain based on file location -domain: projectDiscovery.getDomainForFile(assertion.source.file) || 'unknown', -``` - -#### Inference Phase - -Use domain types instead of specific names: - -```typescript -const domainType = projectDiscovery.getDomainType(slice.domain); -if (slice.type === 'component' && domainType === DomainType.CLIENT) { - const framework = projectDiscovery.getFramework(slice.domain); - tags.push(`${slice.domain}:${framework}`); -} -``` - ---- - -## Implementation Examples - -### Example 1: Angular + Python Monorepo - -Project structure: -``` -my-app/ - frontend/src/ - app/components/ - backend/lambda/ - handlers/ -``` - -Discovery result: -```typescript -{ - domains: [ - { - name: "frontend", - type: "CLIENT", - framework: "angular", - confidence: 0.95 - }, - { - name: "backend", - type: "SERVER", - framework: "aws-lambda", - confidence: 0.90 - } - ] -} -``` - -### Example 2: React + Express - -Project structure: -``` -my-app/ - src/ - client/ - server/ -``` - -Discovery result: -```typescript -{ - domains: [ - { - name: "client", - type: "CLIENT", - framework: "react", - confidence: 0.90 - }, - { - name: "server", - type: "SERVER", - framework: "express", - confidence: 0.90 - } - ] -} -``` - -### Example 3: Next.js (Hybrid) - -Project structure: -``` -my-app/ - pages/ - pages/api/ -``` - -Discovery result: -```typescript -{ - domains: [ - { - name: "pages", - type: "CLIENT", - framework: "next", - confidence: 0.95 - }, - { - name: "api", - type: "SERVER", - framework: "next", - confidence: 0.95 - } - ] -} -``` - ---- - -## Consequences - -### Positive Consequences - -1. **Zero-Configuration Experience** - - Drop into any project and run immediately - - No setup time, no learning curve - - Immediate value delivery - -2. **Universal Compatibility** - - Works with any project structure - - Works with any naming convention - - Works with any framework combination - -3. **Intelligent Behavior** - - Understands project context automatically - - Tags and relationships use actual project names - - Output reflects real architecture - -4. **Better Adoption** - - Reduces barrier to entry dramatically - - Eliminates configuration errors - - Enables rapid experimentation - -5. **Self-Documenting** - - Discovery output shows what was found - - Users understand what runtime sees - - Transparent behavior - -### Negative Consequences - -1. **Implementation Complexity** - - Discovery engine requires careful design - - Edge cases need handling - - More code to maintain - -2. **Longer Timeline** - - 4 weeks vs 2 weeks for manual config - - Delays other features - - Higher upfront investment - -3. **Discovery Accuracy** - - Heuristics may fail for unusual structures - - Need robust fallback mechanisms - - Requires extensive testing - -### Mitigation Strategies - -**For Complexity:** -- Clear abstractions and interfaces -- Comprehensive unit test coverage -- Well-documented heuristics - -**For Timeline:** -- Investment justified by adoption gains -- Phased implementation with validation gates -- Early user testing - -**For Accuracy:** -- Confidence scoring system -- Graceful fallback to safe defaults -- Optional configuration override for edge cases -- Clear discovery debugging output - ---- - -## Validation and Testing - -### Success Criteria - -- [ ] Discovery completes in <100ms for typical projects -- [ ] Works with 15+ different project structures without configuration -- [ ] Domain names in output match actual project naming -- [ ] Framework detection accuracy >90% -- [ ] Confidence scoring correctly identifies ambiguous cases -- [ ] Discovery output is clear and actionable - -### Test Projects Matrix - -| Project Type | Framework | Structure | Expected Domains | -|-------------|-----------|-----------|------------------| -| Create React App | React | Single | `src` (CLIENT) | -| Angular CLI | Angular | Single | `src/app` (CLIENT) | -| Express API | Express | Single | `src` (SERVER) | -| Next.js | Next.js | Hybrid | `pages` (CLIENT), `api` (SERVER) | -| Monorepo (Nx) | Multi | Complex | Multiple domains | -| Serverless | Lambda | Functions | `functions` (SERVER) | -| Full Stack | Multiple | Monorepo | CLIENT + SERVER + INFRA | -| Microservices | Multiple | Multi-repo | Per-service domains | - -### Validation Process - -1. **Unit Tests**: Test each discovery heuristic independently -2. **Integration Tests**: Test full discovery on sample projects -3. **Real-World Tests**: Test on actual open-source projects -4. **Performance Tests**: Ensure discovery is fast (<100ms) -5. **Accuracy Tests**: Verify confidence scoring is calibrated - ---- - -## Implementation Timeline - -| Week | Phase | Deliverables | Validation Gate | -|------|-------|--------------|-----------------| -| 1 | Discovery Engine | Structure scanning, domain identification, confidence scoring | Discovery works on 5+ project types | -| 2 | Integration | Normalization and inference use discovery | All existing tests passing | -| 3 | Testing | Validate with 15+ project types, edge cases | Universal compatibility demonstrated | -| 4 | Polish | Performance optimization, documentation, debugging tools | <100ms discovery, all metrics met | - -**Key Milestones:** -- End of Week 1: Core discovery algorithm functional -- End of Week 2: Full integration complete -- End of Week 3: Edge cases handled, ready for release -- End of Week 4: Performance validated, documentation complete - ---- - -## Risks and Contingencies - -### Risk 1: Discovery Heuristics Insufficient -**Probability:** Medium -**Impact:** High -**Mitigation:** -- Implement confidence scoring to flag low-confidence cases -- Provide optional configuration override -- Include discovery debugging output -- Gather user feedback early - -### Risk 2: Performance Concerns -**Probability:** Low -**Impact:** Medium -**Mitigation:** -- Cache discovery results for watch mode -- Optimize file scanning (ignore node_modules, etc.) -- Target: <100ms discovery time -- Profile and optimize hot paths - -### Risk 3: Ambiguous Project Structures -**Probability:** Medium -**Impact:** Medium -**Mitigation:** -- Use confidence scoring to detect ambiguity -- Provide clear messaging when confidence is low -- Allow optional manual override -- Log discovery reasoning for debugging - -### Risk 4: Timeline Overrun -**Probability:** Medium -**Impact:** Medium -**Mitigation:** -- Weekly validation gates with clear criteria -- Phased implementation -- Option to ship with fallback to manual config if needed - ---- - -## Success Metrics - -### Technical Metrics -- **Discovery Performance:** <100ms (target: <50ms) -- **Accuracy:** >90% correct domain identification -- **Coverage:** Works with 15+ project types -- **Performance:** No regression in extraction speed - -### Adoption Metrics -- **Time to First RECON:** <2 minutes (vs 10+ with manual config) -- **Configuration Required:** 0% of projects -- **User Satisfaction:** Measured via feedback surveys - -### Quality Metrics -- **Test Coverage:** >90% for discovery engine -- **False Positives:** <5% incorrect domain identification -- **User-Reported Issues:** Track and address rapidly - ---- - -## References - -### Related E-ADRs -- E-ADR-001: RECON Provisional Execution -- E-ADR-006: Angular Semantic Extraction -- E-ADR-007: Watchdog Authoritative Mode - -### Related Concepts -- Convention over Configuration -- Zero-Configuration Tools (Vite, Create React App, Next.js) -- Automatic Code Discovery (Language servers, linters) - ---- - -## Decision Record - -**Date:** 2026-01-07 -**Status:** Proposed (pending implementation) -**Priority:** P0 - Critical for adoption - -**Architectural Principle Established:** - -> The ste-runtime shall be a self-configuring framework that automatically adapts to any project structure, requiring zero configuration from users while maintaining universal compatibility across frameworks and architectures. - -**Design Philosophy:** - -The best tools are invisible. By eliminating configuration requirements, we enable users to focus on extracting value rather than understanding setup. Self-configuration transforms ste-runtime from a tool that requires investment to a tool that delivers immediate results. - ---- - -## Next Steps - -1. **Stakeholder Review and Approval** - - Review this E-ADR - - Approve 4-week timeline - - Confirm success criteria - -2. **Week 1: Discovery Engine** - - Implement `ProjectDiscovery` interface - - Build structure scanning logic - - Create domain identification heuristics - - **Gate:** Works with 5+ diverse project types - -3. **Week 2: Integration** - - Refactor normalization to use discovery - - Refactor inference to use discovery - - **Gate:** All existing tests passing - -4. **Week 3: Validation** - - Test with 15+ project types - - Handle edge cases and ambiguous structures - - Optimize performance - - **Gate:** Universal compatibility demonstrated - -5. **Week 4: Release Preparation** - - Final optimization and polish - - Documentation and examples - - Discovery debugging tools - - Release ste-runtime v0.3.0 - - **Gate:** All success criteria met - ---- - -**Status:** **READY FOR REVIEW** -**Next Action:** Obtain stakeholder approval to begin implementation -**Expected Impact:** Dramatic improvement in adoption velocity and user experience diff --git a/documentation/e-adr-archived/E-ADR-010-Conversational-Query-Interface.md b/documentation/e-adr-archived/E-ADR-010-Conversational-Query-Interface.md deleted file mode 100644 index da1581e..0000000 --- a/documentation/e-adr-archived/E-ADR-010-Conversational-Query-Interface.md +++ /dev/null @@ -1,384 +0,0 @@ -# E-ADR-010: Conversational Query Interface for Human-AI Seamless Context Discovery - -**Status:** Proposed -**Implementation:** Complete -**Date:** 2026-01-09 -**Author:** Erik Gallmann -**Authority:** Exploratory ADR (Reversible) - -> **Next Step:** Validate against ste-spec Section 4.6 (RSS) for ADR graduation. CQI extends RSS with conversational semantics. - ---- - -## Context - -E-ADR-004 established the RSS CLI and TypeScript API as the foundation for graph traversal and context assembly. However, a gap exists between: - -1. **Raw RSS operations** (search, dependencies, blast-radius) - require knowing the API -2. **Natural language queries** ("Tell me about X") - how humans and AI agents actually communicate - -The challenge: **How do we make RSS consumption as seamless as natural conversation?** - -Observations from usage patterns: - -| Pattern | Example Query | Current RSS Approach | -|---------|---------------|---------------------| -| Describe | "Tell me about X" | `search X` → `blast-radius` → manual assembly | -| Explain | "How does X work?" | Same as above | -| Impact | "What would change affect?" | `blast-radius X --depth=3` | -| List | "Show all Lambda handlers" | `by-tag handler:lambda` | -| Locate | "Where is X?" | `search X` | - -Each pattern requires the caller to: -1. Know which RSS operation to use -2. Compose operations correctly -3. Parse unstructured output -4. Generate follow-up queries - -This friction degrades both human UX and AI agent efficiency. - ---- - -## Decision - -**Implement a Conversational Query Interface (CQI) as a layer above RSS that:** - -1. **Classifies intent** from natural language queries -2. **Routes to optimal RSS operations** automatically -3. **Caches results** for sub-millisecond repeated queries -4. **Returns structured responses** with summary, nodes, files, and suggested follow-ups -5. **Provides dual output formats** for humans (terminal) and agents (JSON) - ---- - -## Specification - -### §10.1 Intent Classification - -CQI recognizes the following intents via pattern matching: - -| Intent | Trigger Patterns | RSS Operations Used | -|--------|------------------|---------------------| -| `describe` | "Tell me about", "What is", "Describe" | findEntryPoints → blastRadius | -| `explain` | "How does X work", "Explain" | findEntryPoints → blastRadius | -| `list` | "List all", "Show all", "What are the" | byTag or search | -| `impact` | "What would be affected", "Blast radius" | blastRadius (depth=3) | -| `dependencies` | "What does X depend on" | dependencies | -| `dependents` | "What depends on X" | dependents | -| `relationship` | "How are X and Y related" | blastRadius (both) → intersection | -| `locate` | "Where is", "Find" | search | -| `unknown` | Fallback | findEntryPoints → assembleContext | - -### §10.2 Response Schema - -```typescript -interface ConversationalResponse { - // Original query - query: string; - - // Detected intent - intent: QueryIntent; - - // Processing time in milliseconds - timeMs: number; - - // Quick summary suitable for immediate display - summary: string; - - // Primary node(s) found - primaryNodes: NodeSummary[]; - - // Related nodes (via traversal) - relatedNodes: NodeSummary[]; - - // File paths in scope (deterministic) - filePaths: string[]; - - // Suggested follow-up queries - suggestedQueries: string[]; - - // Performance metrics - metrics: { - searchTimeMs: number; - traversalTimeMs: number; - totalNodes: number; - fromCache: boolean; - }; -} -``` - -### §10.3 Caching - -CQI implements LRU caching with: - -| Parameter | Value | Rationale | -|-----------|-------|-----------| -| Max entries | 100 | Typical session variety | -| TTL | 5 minutes | Balance freshness vs performance | -| Cache key | Normalized lowercase query | Ignore case/whitespace variations | - -Cached query response time: **<0.3ms** (vs 2-4ms uncached). - -### §10.4 Output Formats - -**Human format** (terminal): -``` -════════════════════════════════════════════════════════════ -Query: "Tell me about the user service" -Intent: describe | Time: 2.3ms -════════════════════════════════════════════════════════════ - -📋 UserService is a class in the graph domain. - It has 12 connections to other components. - -Primary Results: - • UserService (graph/class) - └─ src/services/user-service.ts - -Files in scope (4): - 📄 src/services/user-service.ts - 📄 src/models/user.ts - ... - -Suggested follow-ups: - → What does UserService depend on? - → What depends on UserService? -``` - -**Agent format** (JSON): -```json -{ - "query": "Tell me about the user service", - "intent": "describe", - "summary": "UserService is a class...", - "primaryNodes": [...], - "filePaths": ["src/services/user-service.ts", ...], - "suggestedQueries": ["What does UserService depend on?", ...] -} -``` - -### §10.5 API - -```typescript -// Engine-based (reuse context across queries) -const engine = new ConversationalQueryEngine('.ste/state'); -await engine.initialize(); -const response = await engine.query("Tell me about X"); - -// Convenience function (one-off queries) -import { ask, formatForHuman, formatForAgent } from 'ste-runtime'; -const response = await ask("Tell me about X"); -console.log(formatForHuman(response)); // Human terminal -console.log(formatForAgent(response)); // AI agent JSON -``` - -### §10.6 Fuzzy Matching - -CQI uses tiered search with fuzzy matching as fallback for typo tolerance: - -**Tier 1 - Exact Matching (fast path):** -| Match Type | Score | -|------------|-------| -| Exact ID match | 100 | -| ID contains query | 80 | -| Path contains query | 60 | -| Key contains query | 40 | - -**Tier 2 - Fuzzy Matching (fallback):** -When Tier 1 returns no results, CQI falls back to Levenshtein distance-based matching: - -| Parameter | Default | Description | -|-----------|---------|-------------| -| `fuzzy` | `true` | Enable fuzzy fallback | -| `fuzzyThreshold` | `0.6` | Minimum similarity (0.0-1.0) | - -Fuzzy matches score in the 0-39 range, ensuring exact matches always rank higher. - -**Examples:** -```typescript -// Typo handled gracefully -search(ctx, 'UserServce') // → finds "UserService" (91% similar) -search(ctx, 'lamda_handler') // → finds "lambda_handler" (93% similar) - -// Disable fuzzy for strict matching -search(ctx, 'UserServce', { fuzzy: false }) // → no results -``` - -**Performance:** Fuzzy fallback adds ~1ms when exact search returns empty. Cached queries remain <0.3ms. - ---- - -## Rationale - -### 1. Reduces Cognitive Load for Both Humans and AI - -Without CQI: -``` -Human: "What would be affected by changing the auth service?" -→ Human must know: use blast-radius, specify key format, parse output -→ AI must know: compose RSS calls, format results, generate follow-ups -``` - -With CQI: -``` -Human: "What would be affected by changing the auth service?" -→ CQI: intent=impact, blastRadius(depth=3), structured response with files -``` - -### 2. Intent Classification Enables Optimization - -Different intents have different optimal strategies: - -| Intent | Optimization | -|--------|-------------| -| `list` | Use tag query if applicable (O(n) scan vs O(1) tag lookup) | -| `impact` | Increase depth, cap nodes | -| `relationship` | Traverse both, compute intersection | -| `describe` | Get context + suggested follow-ups | - -### 3. Caching Amortizes Graph Load Cost - -Benchmark results: - -| Metric | Value | -|--------|-------| -| Graph load (cold) | ~300-400ms | -| Uncached query | ~2-4ms | -| Cached query | **~0.2-0.3ms** | - -For interactive sessions, caching provides ~10x speedup on repeated patterns. - -### 4. Suggested Queries Enable Exploration - -CQI generates contextual follow-ups: - -``` -Query: "Tell me about the auth service" -Suggested: - → What does AuthService depend on? - → What depends on AuthService? - → Impact of changing AuthService -``` - -This guides both humans and AI agents toward productive exploration. - ---- - -## Performance Benchmark - -| Query Type | Time (ms) | Nodes Found | -|------------|-----------|-------------| -| Describe | 2-4 | 10-30 | -| List (by tag) | 0.9-1.3 | 20-50 | -| Impact | 3-4 | 40-50 | -| Dependencies | 1-2 | 1-10 | -| Fuzzy fallback | 3-5 | 1-10 | -| Cached (any) | **0.2-0.3** | — | - -All queries complete in **<5ms** after graph load. Fuzzy matching adds ~1ms when exact search returns empty. - ---- - -## Implementation - -### Files - -| File | Purpose | -|------|---------| -| `src/rss/conversational-query.ts` | CQI engine and formatters | -| `src/rss/rss-operations.ts` | Tiered search with fuzzy matching | -| `dist/rss/conversational-query.js` | Compiled module | - -### Dependencies - -- `lru-cache` - LRU caching for query results -- `rss-operations.ts` - Core RSS API with fuzzy search (E-ADR-004) - -### Fuzzy Matching Algorithm - -Uses Levenshtein (edit) distance with O(n) space optimization: -- Calculates minimum single-character edits (insert, delete, substitute) -- Normalizes to similarity ratio: `1 - (distance / maxLength)` -- Threshold of 0.6 catches 1-2 character typos in typical identifiers - ---- - -## Constraints - -1. **Intent classification is pattern-based**: Complex or ambiguous queries may misclassify. Fallback to `unknown` triggers generic assembly. - -2. **Cache invalidation is manual**: After RECON updates the graph, call `engine.invalidateCache()`. Future: Watchdog integration (E-ADR-007). - -3. **English only**: Intent patterns are English. Internationalization is out of scope. - ---- - -## Consequences - -### Positive - -- **Seamless UX**: Both humans and AI agents use natural language -- **Performance**: Sub-5ms queries, <0.3ms cached -- **Discoverability**: Suggested queries guide exploration -- **Dual output**: Same engine serves terminal and programmatic use -- **Foundation for MCP**: CQI becomes the MCP tool interface - -### Negative - -- **Pattern maintenance**: New intent patterns require code changes -- **Cache staleness**: Risk of stale results if cache not invalidated -- **Abstraction cost**: Hides RSS complexity (may hinder advanced use) - -### Mitigation - -- Expose raw RSS API for power users -- Document intent patterns explicitly -- Integrate with Watchdog for automatic cache invalidation - ---- - -## Relationship to Other Decisions - -| E-ADR | Relationship | -|-------|--------------| -| E-ADR-004 (RSS CLI) | CQI consumes RSS API; CLI remains for power users | -| E-ADR-007 (Watchdog) | Future: Watchdog triggers cache invalidation | -| E-ADR-003 (CEM Deferral) | CQI is integration point when CEM arrives | - -### Dependency Direction - -``` -RECON → AI-DOC → RSS API → CQI → [ Human, AI Agent, MCP Server ] - ↓ - RSS CLI (power users) -``` - -CQI is the **preferred interface** for conversational access. RSS CLI remains for advanced/debugging use. - ---- - -## Future Considerations - -1. **Alias system**: Map nicknames to canonical entities -2. **Session context**: Remember prior queries for refinement -3. **Streaming responses**: Return summary first, details progressively -4. **MCP integration**: Expose CQI as MCP tool for AI assistants - ---- - -## Review Trigger - -This decision should be revisited when: - -1. Intent classification accuracy drops below acceptable threshold -2. New query patterns emerge that don't fit existing intents -3. MCP integration requires protocol changes -4. Multi-turn conversation support is needed - ---- - -## References - -- E-ADR-004: RSS CLI Implementation for Developer-Invoked Graph Traversal -- STE Architecture Specification, Section 4.6: Runtime Components (RSS) -- Benchmark: `benchmark-conversational.js` diff --git a/documentation/e-adr-archived/E-ADR-011-ste-runtime-MCP-Server.md b/documentation/e-adr-archived/E-ADR-011-ste-runtime-MCP-Server.md deleted file mode 100644 index b709d82..0000000 --- a/documentation/e-adr-archived/E-ADR-011-ste-runtime-MCP-Server.md +++ /dev/null @@ -1,1099 +0,0 @@ -# E-ADR-011: ste-runtime MCP Server Implementation - -**Status:** Accepted -**Implementation:** Planned -**Date:** 2026-01-11 -**Author:** Erik Gallmann -**Authority:** Exploratory ADR (Reversible) - -> **Purpose:** Define comprehensive architecture for ste-runtime as a unified MCP server with file watching capabilities, enabling governed cognition in the Workspace Development Boundary. - -> **Implementation Note (2026-02-08):** The current MCP server exposes 8 AI-optimized tools (`find`, `show`, `usages`, `impact`, `similar`, `overview`, `diagnose`, `refresh`). The detailed tool specifications below reflect the original layered design and serve as historical/roadmap context. - ---- - -## Context - -Per STE Architecture Section 3.1, the Workspace Development Boundary requires: -- **Provisional state** maintenance (pre-merge, feature branches) -- **Soft + hard enforcement** (LLM instruction-following + validation tools) -- **Post-reasoning validation** (catch violations after generation) -- **Context assembly via RSS** (CEM Stage 2: State Loading) - -Currently, ste-runtime provides: -- ✅ Incremental RECON (maintains fresh AI-DOC) -- ✅ RSS operations (semantic graph traversal) -- ✅ CLI interface (human-friendly commands) -- ❌ No long-running process (graph reloaded on every query) -- ❌ No MCP interface (Cursor can't discover tools automatically) -- ❌ No automatic file watching (manual RECON invocation required) - -**Gap:** Cursor (and other AI assistants) need: -1. **Always-fresh semantic state** (automatic updates on file changes) -2. **Fast queries** (in-memory graph, <100ms response) -3. **Tool auto-discovery** (MCP protocol for semantic operations) -4. **Deterministic context** (RSS graph traversal, not probabilistic search) - ---- - -## Decision - -**Implement ste-runtime as a unified MCP server that combines:** - -1. **File Watcher** - Monitors project files, triggers incremental RECON on changes -2. **Incremental RECON Engine** - Maintains fresh AI-DOC state (O(changed files)) -3. **In-Memory RSS Context** - Fast semantic graph queries (<100ms) -4. **MCP Server** - Exposes RSS operations as tools for Cursor integration - -### Architecture - -``` -┌─────────────────────────────────────────────────────────────┐ -│ Workspace Development Boundary │ -│ │ -│ ┌──────────────┐ │ -│ │ Cursor IDE │ │ -│ └──────┬───────┘ │ -│ │ MCP Protocol (stdio) │ -│ ▼ │ -│ ┌─────────────────────────────────────────────────────┐ │ -│ │ ste-runtime Process │ │ -│ │ │ │ -│ │ ┌──────────────┐ ┌──────────────────┐ │ │ -│ │ │ MCP Server │◄─────┤ In-Memory RSS │ │ │ -│ │ │ (stdio) │ │ Context (Graph) │ │ │ -│ │ └──────────────┘ └────────▲─────────┘ │ │ -│ │ │ │ │ -│ │ ┌──────────────┐ ┌────────┴─────────┐ │ │ -│ │ │ File Watcher │──────► Incremental │ │ │ -│ │ │ (chokidar) │ │ RECON Engine │ │ │ -│ │ └──────────────┘ └────────┬─────────┘ │ │ -│ │ │ │ │ -│ └─────────────────────────────────┼──────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌─────────────────────┐ │ -│ │ .ste/state/ │ │ -│ │ (AI-DOC YAML files) │ │ -│ └─────────────────────┘ │ -└─────────────────────────────────────────────────────────────┘ -``` - -### Two-Layer Innovation: RSS + Context Assembly - -**Potentially Novel Architectural Pattern:** Separate fast structural queries from rich context loading. We have not found prior work that combines these elements, but welcome references to similar systems. - -``` -┌────────────────────────────────────────────────────────────────┐ -│ LAYER 2: CONTEXT ASSEMBLY │ -│ (Semantic Graph + Source Code + Invariants) │ -│ │ -│ What it does: Combines RSS queries with filesystem access │ -│ What it returns: Slices + source code + invariants │ -│ Performance: Slower (disk I/O), but targeted │ -│ │ -│ MCP Tools: │ -│ • assemble_context(query, includeSource=true) │ -│ → Returns: Relevant slices with full source code │ -│ │ -│ • get_implementation_context(key, depth=2) │ -│ → Returns: Slice + dependencies with implementations │ -│ │ -│ • get_related_implementations(key, maxResults=10) │ -│ → Returns: Similar code patterns from codebase │ -│ │ -│ Strategy: │ -│ 1. Query RSS for relevant slice keys (fast, structural) │ -│ 2. Load source code ONLY for those slices (targeted I/O) │ -│ 3. Inject applicable invariants from .ste/invariants/ │ -│ 4. Optimize for LLM context budget (only send what's needed) │ -└────────────────────────────────────────────────────────────────┘ - ↓ uses -┌────────────────────────────────────────────────────────────────┐ -│ LAYER 1: RSS (Pure Semantic Graph) │ -│ │ -│ What it does: Graph traversal and structural queries │ -│ What it returns: Slice metadata only (no source code) │ -│ Performance: Fast (<100ms, in-memory) │ -│ │ -│ MCP Tools: │ -│ • search(query) → Find relevant slice keys │ -│ • get_dependencies(key) → What this component uses │ -│ • get_dependents(key) → What uses this component │ -│ • get_blast_radius(key) → Full impact analysis │ -│ • lookup(key) / by_tag(tag) → Direct queries │ -│ │ -│ Storage: .ste/state/*.aidoc (YAML) │ -│ Maintained by: Incremental RECON + File Watcher │ -└────────────────────────────────────────────────────────────────┘ -``` - -**Why This Is Novel:** - -1. **Token Efficiency:** Most semantic tools return either metadata OR source. We do structural search first (cheap), then targeted source loading (expensive but precise). - -2. **Composable Queries:** LLMs can chain operations: - - "Search for auth handlers" → get 10 slice keys (RSS layer) - - "Show implementations for top 3 results" → load source for 3 files (Context Assembly) - - Result: 3 files loaded instead of entire codebase - -3. **CEM Stage Mapping:** - - **Stage 2 (State Loading):** RSS layer identifies WHAT is relevant - - **Stage 3 (Analysis):** Context Assembly loads HOW it works (source + invariants) - - **Stage 4-9:** LLM reasons over assembled context - -4. **Performance:** RSS queries are <100ms (in-memory graph). Context Assembly only pays filesystem I/O cost for slices that matter. - -5. **Separation of Concerns:** - - RSS stays pure (graph operations, no I/O side effects) - - Context Assembly handles integration (filesystem, invariants, formatting) - -**Example: Two Ways to Answer "What calls authenticate()?"** - -```typescript -// Fast (RSS Layer): Get structural information -search("calls to authenticate function") -→ Returns: ["api/function/login-handler", "api/function/refresh-token"] -→ Time: 45ms - -// Rich (Context Assembly): Get implementations -assemble_context("show implementations that call authenticate", includeSource=true) -→ Returns: Slice metadata + full source code + invariants for auth domain -→ Time: 380ms (but only loads 2 relevant files, not entire codebase) -``` - -### Key Design Decisions - -#### 1. Unified Process Architecture -**Decision:** Single process combines MCP server + file watcher -**Rationale:** Shared in-memory graph, no IPC overhead, simpler deployment -**Alternative rejected:** Separate processes (complexity, synchronization issues) - -#### 2. MCP Over HTTP -**Decision:** Primary interface is MCP (stdio), not HTTP REST API -**Rationale:** -- Native Cursor integration (stdio transport) -- Tool auto-discovery (Cursor sees available tools automatically) -- Schema validation (MCP enforces input/output schemas) -- Standardized protocol (works with any MCP-compatible AI assistant) - -#### 3. Workspace Boundary Only -**Decision:** ste-runtime is local, per-project, pre-merge state -**Rationale:** Different from ADF (org-wide, post-merge canonical state) -**Boundary:** Source code is truth → RECON extracts → MCP serves - -#### 4. Configuration-Driven -**Decision:** Configure via `ste.config.json` with sensible defaults -**Rationale:** Balance flexibility with zero-config experience - ---- - -## Specification - -### §1 MCP Tools Specification - -#### Layer 1: RSS Operations (Pure Semantic Graph) - -**Characteristics:** -- Fast (<100ms), in-memory queries -- Returns slice metadata only (no source code) -- Pure graph traversal operations - -```typescript -{ - name: "search_semantic_graph", - description: "Search the semantic graph for components, functions, entities", - inputSchema: { - type: "object", - properties: { - query: { type: "string", description: "Search query (natural language)" }, - maxResults: { type: "number", default: 50 } - }, - required: ["query"] - } -} - -{ - name: "get_dependencies", - description: "Find what a component depends on (forward traversal)", - inputSchema: { - type: "object", - properties: { - key: { type: "string", description: "Component key (domain/type/id)" }, - depth: { type: "number", default: 2, description: "Traversal depth" } - }, - required: ["key"] - } -} - -{ - name: "get_dependents", - description: "Find what depends on this component (backward traversal)", - inputSchema: { - type: "object", - properties: { - key: { type: "string", description: "Component key (domain/type/id)" }, - depth: { type: "number", default: 2 } - }, - required: ["key"] - } -} - -{ - name: "get_blast_radius", - description: "Analyze full impact surface of changing this component", - inputSchema: { - type: "object", - properties: { - key: { type: "string", description: "Component key (domain/type/id)" }, - depth: { type: "number", default: 2 } - }, - required: ["key"] - } -} - -{ - name: "lookup_by_key", - description: "Direct retrieval of component by full key", - inputSchema: { - type: "object", - properties: { - key: { type: "string", description: "Full key (domain/type/id)" } - }, - required: ["key"] - } -} - -{ - name: "lookup", - description: "Direct retrieval of component by domain and id", - inputSchema: { - type: "object", - properties: { - domain: { type: "string", description: "AI-DOC domain (api, data, graph, etc.)" }, - id: { type: "string", description: "Component ID" } - }, - required: ["domain", "id"] - } -} - -{ - name: "by_tag", - description: "Find all components with a specific tag", - inputSchema: { - type: "object", - properties: { - tag: { type: "string", description: "Tag to search for" }, - maxResults: { type: "number", default: 50 } - }, - required: ["tag"] - } -} - -{ - name: "get_graph_stats", - description: "Get statistics about the semantic graph", - inputSchema: { - type: "object", - properties: {} - } -} -``` - -#### Layer 2: Context Assembly Operations (Semantic + Source + Invariants) - -**Characteristics:** -- Slower (disk I/O), but targeted -- Returns slice metadata + source code + invariants -- Optimized for LLM context budget - -```typescript -{ - name: "assemble_context", - description: "Assemble task-relevant context for LLM reasoning (CEM Stage 2→3)", - inputSchema: { - type: "object", - properties: { - query: { type: "string", description: "Task description (natural language)" }, - includeSource: { type: "boolean", default: true, description: "Include source code" }, - includeInvariants: { type: "boolean", default: true, description: "Include domain invariants" }, - depth: { type: "number", default: 2, description: "Dependency traversal depth" }, - maxNodes: { type: "number", default: 50, description: "Max components to return" }, - maxSourceLines: { type: "number", default: 100, description: "Max lines per file" } - }, - required: ["query"] - } -} - -{ - name: "get_implementation_context", - description: "Get full implementation context for a specific component", - inputSchema: { - type: "object", - properties: { - key: { type: "string", description: "Component key (domain/type/id)" }, - includeSource: { type: "boolean", default: true }, - includeDependencies: { type: "boolean", default: true }, - depth: { type: "number", default: 1 } - }, - required: ["key"] - } -} - -{ - name: "get_related_implementations", - description: "Find similar code patterns in the codebase", - inputSchema: { - type: "object", - properties: { - key: { type: "string", description: "Component key (domain/type/id)" }, - includeSource: { type: "boolean", default: true }, - maxResults: { type: "number", default: 10 } - }, - required: ["key"] - } -} -``` - -**Operational Tools:** - -```typescript -{ - name: "detect_missing_extractors", - description: "Analyze project and identify missing language/framework extractors", - inputSchema: { - type: "object", - properties: {} - } -} - -{ - name: "get_graph_health", - description: "Get validation status and health metrics", - inputSchema: { - type: "object", - properties: {} - } -} - -{ - name: "trigger_full_recon", - description: "Manually trigger full RECON (fallback for errors)", - inputSchema: { - type: "object", - properties: {} - } -} -``` - -### §2 Cross-Platform Considerations - -#### Windows-Specific - -**Path Normalization:** -- Normalize backslashes to forward slashes for consistency -- Use `path.posix` for AI-DOC paths (always forward slash) -- Use `path.resolve` for file system operations (platform-specific) - -**NTFS Characteristics:** -- Case-insensitive but case-preserving -- Normalize paths for comparison: `path.toLowerCase()` on Windows -- Handle long paths (>260 characters) with `\\?\` prefix - -**Network Drives:** -- Detect network drives: `path.startsWith('\\\\')` or drive letter check -- Warn user: "Network drives may have delayed/unreliable file system events" -- Recommend: Use local file system for active development -- Fallback: Enable polling mode (`watchdog.fallbackPolling: true`) - -**Cloud Sync (OneDrive, Dropbox):** -- Detect cloud sync directories (check for `.onedrive`, `.dropbox` markers) -- Warn user: "Cloud sync may conflict with file watching" -- Recommend: Exclude `.ste/state/` from cloud sync - -#### macOS/Linux-Specific - -**Case-Sensitive File Systems:** -- Preserve exact case in paths -- No normalization needed for comparison - -**Symlink Handling:** -- Follow symlinks by default (`followSymlinks: true` in chokidar) -- Detect circular symlinks (prevent infinite loops) -- Normalize resolved paths - -**inotify Limits (Linux):** -- Check system limit: `cat /proc/sys/fs/inotify/max_user_watches` -- Warn if project has more files than limit -- Recommend: Increase limit or use polling mode - -#### All Platforms - -**`.gitignore` Respect:** -- Use `globby` with `gitignore: true` option -- Automatically exclude `.git/`, `node_modules/`, `.venv/`, `.ste/` - -**Large File Handling:** -- Skip files >100MB (unlikely to be source code) -- Binary file detection (check for null bytes in first 8KB) -- Warn on large projects (>10,000 files) - -**File System Event Buffer Limits:** -- chokidar has internal buffer (default 10ms) -- Debounce changes (500ms default, configurable) -- Coalesce rapid changes to same file - -### §3 Adaptive Tool Parameters - -**Problem:** Static defaults for traversal depth are always wrong for some queries. A microservices architecture might need `depth=4`, while a layered monolith works best with `depth=2`. - -**Solution:** Analyze graph topology at runtime and dynamically adjust tool parameter defaults. - -#### Graph Topology Analysis - -```typescript -interface GraphMetrics { - // Basic stats - totalComponents: number; - componentsByDomain: Record; - componentsByType: Record; - - // Depth analysis - avgDependencyDepth: number; // Average forward traversal depth - maxDependencyDepth: number; // Deepest dependency chain - p95DependencyDepth: number; // 95th percentile - - avgDependentDepth: number; // Average backward traversal depth - maxDependentDepth: number; // Deepest dependent chain - - // Width analysis - avgDependenciesPerComponent: number; - avgDependentsPerComponent: number; - - // Architecture patterns - detectedPattern: 'layered' | 'microservices' | 'component-tree' | 'flat' | 'mixed'; - hasDeepTrees: boolean; // maxDepth > 5 - hasWideNetwork: boolean; // avgFanOut > 10 - - // Recommended defaults - recommendedDepth: number; - lastAnalyzed: string; // ISO timestamp -} -``` - -#### Analysis Algorithm - -```typescript -async function analyzeGraphTopology(graph: AIDocGraph): Promise { - const metrics: GraphMetrics = { - totalComponents: graph.nodes.length, - componentsByDomain: {}, - componentsByType: {}, - avgDependencyDepth: 0, - maxDependencyDepth: 0, - p95DependencyDepth: 0, - avgDependentDepth: 0, - maxDependentDepth: 0, - avgDependenciesPerComponent: 0, - avgDependentsPerComponent: 0, - detectedPattern: 'mixed', - hasDeepTrees: false, - hasWideNetwork: false, - recommendedDepth: 2, - lastAnalyzed: new Date().toISOString() - }; - - // 1. Count components by domain/type - for (const node of graph.nodes) { - metrics.componentsByDomain[node.domain] = - (metrics.componentsByDomain[node.domain] || 0) + 1; - metrics.componentsByType[node.type] = - (metrics.componentsByType[node.type] || 0) + 1; - } - - // 2. Calculate depth statistics - const forwardDepths: number[] = []; - const backwardDepths: number[] = []; - const dependencyCounts: number[] = []; - const dependentCounts: number[] = []; - - for (const node of graph.nodes) { - // Measure forward depth (dependencies) - const forwardDepth = measureDepth(graph, node.key, 'forward'); - forwardDepths.push(forwardDepth); - dependencyCounts.push(node.dependencies?.length || 0); - - // Measure backward depth (dependents) - const backwardDepth = measureDepth(graph, node.key, 'backward'); - backwardDepths.push(backwardDepth); - dependentCounts.push(node.dependents?.length || 0); - } - - metrics.avgDependencyDepth = mean(forwardDepths); - metrics.maxDependencyDepth = Math.max(...forwardDepths); - metrics.p95DependencyDepth = percentile(forwardDepths, 0.95); - - metrics.avgDependentDepth = mean(backwardDepths); - metrics.maxDependentDepth = Math.max(...backwardDepths); - - metrics.avgDependenciesPerComponent = mean(dependencyCounts); - metrics.avgDependentsPerComponent = mean(dependentCounts); - - // 3. Detect architecture pattern - metrics.hasDeepTrees = metrics.maxDependencyDepth > 5; - metrics.hasWideNetwork = metrics.avgDependenciesPerComponent > 10; - metrics.detectedPattern = detectPattern(metrics); - - // 4. Calculate recommended depth - metrics.recommendedDepth = calculateOptimalDepth(metrics); - - return metrics; -} - -function detectPattern(metrics: GraphMetrics): ArchitecturePattern { - const { avgDependencyDepth, avgDependenciesPerComponent, hasDeepTrees, hasWideNetwork } = metrics; - - // React/Vue component trees: deep but narrow - if (hasDeepTrees && !hasWideNetwork && avgDependenciesPerComponent < 5) { - return 'component-tree'; - } - - // Microservices: shallow but wide - if (!hasDeepTrees && hasWideNetwork && avgDependencyDepth < 3) { - return 'microservices'; - } - - // Layered architecture: moderate depth, clear boundaries - if (avgDependencyDepth >= 2 && avgDependencyDepth <= 4 && !hasWideNetwork) { - return 'layered'; - } - - // Flat utilities: minimal dependencies - if (avgDependencyDepth <= 2 && avgDependenciesPerComponent <= 3) { - return 'flat'; - } - - return 'mixed'; -} - -function calculateOptimalDepth(metrics: GraphMetrics): number { - const { detectedPattern, avgDependencyDepth, p95DependencyDepth } = metrics; - - // Pattern-specific recommendations - const baseDepth = { - 'component-tree': 4, // Deep component hierarchies - 'microservices': 3, // Peer services with shared deps - 'layered': 2, // Clear layer boundaries - 'flat': 2, // Simple utility libraries - 'mixed': 3 // Conservative default - }[detectedPattern]; - - // Adjust based on actual graph characteristics - // Use P95 instead of average (avoid outliers) - const dataDepth = Math.ceil(p95DependencyDepth * 0.6); - - // Take max of pattern-based and data-driven, cap at 5 - return Math.min(Math.max(baseDepth, dataDepth), 5); -} -``` - -#### Dynamic Tool Schema Updates - -```typescript -class AdaptiveMCPServer { - private graphMetrics: GraphMetrics; - private toolSchemas: Map; - - async initialize() { - // Load graph and analyze - const graph = await this.loadGraph(); - this.graphMetrics = await analyzeGraphTopology(graph); - - // Update tool schemas with calculated defaults - this.updateToolDefaults(); - - // Log recommendations - console.log(`[MCP Server] Graph analysis complete:`); - console.log(` - Pattern: ${this.graphMetrics.detectedPattern}`); - console.log(` - Components: ${this.graphMetrics.totalComponents}`); - console.log(` - Avg depth: ${this.graphMetrics.avgDependencyDepth.toFixed(1)}`); - console.log(` - Recommended traversal depth: ${this.graphMetrics.recommendedDepth}`); - } - - updateToolDefaults() { - const depth = this.graphMetrics.recommendedDepth; - - // Update all traversal tools - const traversalTools = [ - 'get_dependencies', - 'get_dependents', - 'get_blast_radius', - 'assemble_context' - ]; - - for (const toolName of traversalTools) { - const tool = this.toolSchemas.get(toolName); - if (tool?.inputSchema.properties.depth) { - tool.inputSchema.properties.depth.default = depth; - tool.inputSchema.properties.depth.description = - `Traversal depth (default: ${depth}, based on graph topology)`; - } - } - } - - // Recalculate after significant graph changes - async onReconComplete() { - const graph = await this.loadGraph(); - const newMetrics = await analyzeGraphTopology(graph); - - // Only update if significant change (20% difference) - const depthChange = Math.abs( - newMetrics.recommendedDepth - this.graphMetrics.recommendedDepth - ); - - if (depthChange >= 1) { - console.log(`[MCP Server] Graph structure changed significantly`); - console.log(` - Old recommended depth: ${this.graphMetrics.recommendedDepth}`); - console.log(` - New recommended depth: ${newMetrics.recommendedDepth}`); - - this.graphMetrics = newMetrics; - this.updateToolDefaults(); - - // Persist metrics - await this.saveGraphMetrics(newMetrics); - } - } -} -``` - -#### Metrics Persistence - -**File:** `.ste/state/graph-metrics.json` - -```json -{ - "totalComponents": 450, - "componentsByDomain": { - "api": 120, - "data": 80, - "graph": 150, - "ui": 100 - }, - "avgDependencyDepth": 3.2, - "maxDependencyDepth": 8, - "p95DependencyDepth": 5, - "detectedPattern": "component-tree", - "hasDeepTrees": true, - "hasWideNetwork": false, - "recommendedDepth": 4, - "lastAnalyzed": "2026-01-11T10:30:00.000Z", - "reasoning": "Deep component hierarchies detected (React), using depth=4" -} -``` - -#### Benefits - -1. **Automatic Optimization:** Defaults adjust to your codebase structure -2. **Transparent:** Logs explain why a depth was chosen -3. **Self-Improving:** Updates as codebase evolves -4. **No User Tuning:** Works well out-of-the-box -5. **Pattern Detection:** Identifies architecture style automatically - -#### Example Behavior - -```bash -# React frontend (deep component trees) -[MCP Server] Graph analysis complete: - - Pattern: component-tree - - Components: 450 - - Avg depth: 4.7 - - Recommended traversal depth: 4 - -# Python backend (layered architecture) -[MCP Server] Graph analysis complete: - - Pattern: layered - - Components: 120 - - Avg depth: 2.3 - - Recommended traversal depth: 2 - -# Microservices (wide, shallow) -[MCP Server] Graph analysis complete: - - Pattern: microservices - - Components: 85 - - Avg depth: 2.8 - - Recommended traversal depth: 3 -``` - -### §4 Configuration Schema - -**File:** `ste.config.json` - -```json -{ - "watchdog": { - "enabled": false, - "debounceMs": 500, - "aiEditDebounceMs": 2000, - "syntaxValidation": true, - "transactionDetection": true, - "stabilityCheckMs": 100, - "patterns": ["**/*.py", "**/*.ts", "**/*.js", "**/*.tsx", "**/*.jsx"], - "ignore": [".git", "node_modules", ".venv", "__pycache__", "dist", "build"], - "fullReconciliationInterval": 300000, - "fallbackPolling": false, - "pollingInterval": 5000 - }, - "mcp": { - "transport": "stdio", - "logLevel": "info" - }, - "rss": { - "stateRoot": ".ste/state", - "defaultDepth": 2, - "maxResults": 50 - } -} -``` - -**Field Descriptions:** - -- `watchdog.enabled` - Enable file watching (default: false, opt-in) -- `watchdog.debounceMs` - Wait time after last change before triggering RECON (manual edits) -- `watchdog.aiEditDebounceMs` - Debounce for AI-generated edits (Cursor streaming pattern, default: 2000ms) -- `watchdog.syntaxValidation` - Skip RECON for files with syntax errors (default: true) -- `watchdog.transactionDetection` - Wait for multi-file edits to complete (default: true) -- `watchdog.stabilityCheckMs` - Time to wait for file mtime stability check (default: 100ms) -- `watchdog.patterns` - Glob patterns for files to watch -- `watchdog.ignore` - Directories/patterns to ignore -- `watchdog.fullReconciliationInterval` - Periodic full RECON (ms, 0 = disabled) -- `watchdog.fallbackPolling` - Use polling instead of native events (for network drives) -- `watchdog.pollingInterval` - Polling interval if fallbackPolling enabled -- `mcp.transport` - MCP transport type (stdio only for now) -- `mcp.logLevel` - Logging level (error, warn, info, debug) -- `rss.stateRoot` - Path to AI-DOC state directory -- `rss.defaultDepth` - Default traversal depth for dependencies/dependents -- `rss.maxResults` - Default maximum results for search operations - -### §4 CLI Integration - -```bash -# Start MCP server with file watching -ste watch [options] - --mcp # Explicitly enable MCP mode (default when run by Cursor) - --no-watch # Disable file watching (MCP server only) - --config PATH # Custom config file path - -# One-shot RECON (no server) -ste recon [options] - --incremental # Use incremental RECON (default if manifest exists) - --full # Force full RECON - -# Query operations (hits running server if available, else reads from disk) -ste query [args] - search - dependencies [--depth N] - dependents [--depth N] - blast-radius [--depth N] - lookup - stats -``` - -**Cursor MCP Configuration:** - -```json -// ~/.cursor/mcp.json -{ - "mcpServers": { - "ste-runtime": { - "command": "ste", - "args": ["watch", "--mcp"], - "cwd": "${workspaceFolder}" - } - } -} -``` - -### §5 Governance Confidence Framework - -**Theoretical Estimates (Subject to Empirical Validation):** - -#### Layer 1: Explicit State (vs Hallucinated) -- **Target:** ~84% confidence state is correct -- **Components:** - - AI-DOC extraction accuracy: 95% (deterministic extractors, tested) - - RSS traversal completeness: 98% (explicit graph, bounded) - - State freshness: 90% (watchdog + periodic reconciliation) -- **Baseline ungoverned:** ~30% (LLM hallucinates context) - -#### Layer 2: Instruction Following (CEM + Invariants) -- **Estimated:** ~44% adherence to process -- Based on known LLM instruction-following rates for complex multi-stage instructions -- **Baseline ungoverned:** ~70-80% for simple instructions - -#### Layer 3: Output Validation (Hard Enforcement) -- **Estimated:** ~54% of violations caught -- Depends on validator coverage (static analysis, tests, MCP validators) -- **Critical:** This catches violations even when Layer 2 fails - -#### Layer 4: Human Review (Ultimate Enforcement) -- **Estimated:** ~65% of remaining violations caught -- Based on human cognitive limitations, alert fatigue -- **Critical:** Final safety net - -**Overall Theoretical Estimate:** -- Compliant path: 84% × 44% = ~37% perfect compliance -- Caught violations: 84% × 56% × 54% = ~25% violations blocked by validation -- Human catch: 84% × 56% × 46% × 65% = ~14% violations caught by human -- **Total governed: ~68-76%** (vs ~25% ungoverned) - -**Important Caveats:** -- These are **theoretical estimates** based on enforcement layer analysis -- Actual governance confidence requires **empirical measurement** -- Metrics will vary by: - - Project complexity - - Language support and extractor quality - - Validation coverage - - Human reviewer expertise -- Baseline ungoverned LLM confidence (~25%) is also an estimate -- **We must validate these claims through empirical testing** - -**Measurement Strategy (To Validate Estimates):** -1. Establish baseline (ungoverned LLM on test tasks) -2. Track AI-DOC extraction accuracy against ground truth -3. Monitor RSS traversal completeness (coverage metrics) -4. Log validation pass/fail rates over time -5. Record human approval/rejection rates -6. Compare governed vs ungoverned outputs on same tasks -7. Publish validation methodology and results -8. Iterate on weak enforcement layers - ---- - -## Implementation Notes - -### Existing Code Reuse - -- **RECON:** Use existing `src/recon/incremental-recon.ts` -- **RSS:** Use existing `src/rss/rss-operations.ts` -- **Change Detection:** Use existing `src/watch/change-detector.ts` -- **Safeguards:** Use existing `src/watch/write-tracker.ts`, `src/watch/update-coordinator.ts` - -### New Components Required - -- **MCP Server:** `src/mcp/mcp-server.ts` (uses `@modelcontextprotocol/sdk`) -- **Watchdog Loop:** `src/watch/watchdog.ts` (orchestrates watcher + RECON) -- **Edit Queue Manager:** `src/watch/edit-queue-manager.ts` (handles debouncing, syntax validation, transaction detection) -- **Transaction Detector:** `src/watch/transaction-detector.ts` (detects multi-file edits) -- **CLI Entry Point:** `src/cli/watch-cli.ts` (handles `ste watch`) - -### Dependencies - -```json -{ - "dependencies": { - "@modelcontextprotocol/sdk": "^0.5.0" - }, - "devDependencies": { - "@types/node": "^20.0.0" - } -} -``` - -**Note:** `chokidar`, `globby`, `js-yaml` already exist in dependencies. - -### Integration Testing Strategy - -**Test Scenarios:** -1. File change → incremental RECON → graph update → MCP query returns new state -2. **Cursor streaming edits** → multiple rapid saves → single RECON run (not 10+) -3. **Multi-file transaction** → Cursor edits 5 files → wait for completion → single RECON -4. **Syntax error** → invalid code mid-edit → skip RECON → valid code → trigger RECON -5. **AI edit detection** → rapid large changes → 2s debounce (not 500ms) -6. Missing extractor detection → warning to user -7. Concurrent file changes → debouncing → single RECON run -8. Graph corruption → fallback to full RECON -9. Platform-specific path handling (Windows vs Unix) - -**Test Implementation:** -- Use temporary project fixtures (`fixtures/` directory) -- Mock file system watcher for determinism -- Verify MCP protocol compliance -- Measure governance improvement over baseline - ---- - -## Future Work - -### Phase 1 Extensions - -#### 1. Invariant Injection -- Load invariants from `.ste/invariants/` -- Add `get_invariants_for_scope(scope)` MCP tool -- Return context + invariants together -- **Goal:** Raise Layer 2 confidence (instruction following) - -#### 2. Divergence Detection -- Currency validation (source vs extracted timestamps) -- Conflict detection in AI-DOC -- Staleness warnings -- **Goal:** Raise Layer 1 confidence (state freshness) - -### Phase 2: CEM Integration - -#### 3. CEM Orchestration Layer -- Enforce 9-stage execution model -- Structured output validation (require CEM trace) -- Execution trace logging -- **Goal:** Raise Layer 2 confidence (process adherence) - -#### 4. Self-Bootstrapping Extractors -- Detect missing language support -- Generate extractor implementation plans using RSS context of existing extractors -- Governed generation with human approval -- **Goal:** 85-90% governance confidence for meta-operations -- **Benefit:** Expand coverage automatically - -**Self-Bootstrapping Flow:** -``` -1. ste-runtime detects missing extractor (e.g., Java) -2. Cursor queries RSS for existing extractor patterns (Python, Angular) -3. Cursor proposes implementation plan -4. Human reviews and approves -5. Cursor generates: java-extractor.ts + tests -6. Run tests → iterate if needed -7. New extractor ready, coverage expanded -``` - -### Phase 3: Runtime Boundary - -#### 5. ADF Integration -- Remote MCP for org-wide semantic state -- Post-merge canonical state authority -- Multi-environment isolation -- **Goal:** 95-99% governance confidence (cryptographic enforcement) - ---- - -## Success Criteria - -### Functional -- ✅ Cursor can discover and call ste-runtime MCP tools -- ✅ File changes trigger incremental RECON within 1 second -- ✅ RSS queries return fresh state (<100ms) -- ✅ Windows/macOS/Linux support with platform-specific optimizations -- ✅ Graceful degradation (fallback to full RECON on errors) - -### Non-Functional -- ✅ Memory usage <100MB idle, <500MB under load -- ✅ CPU usage <1% idle, <10% during RECON -- ✅ No infinite loops (WriteTracker + UpdateCoordinator prevent) -- ✅ **Measurable governance improvement** over ungoverned LLM (establish baseline, collect metrics, validate estimates) - -### Developer Experience -- ✅ Zero-config startup (`ste watch`) -- ✅ Clear error messages and recovery paths -- ✅ Visible progress indicators -- ✅ Documentation with examples - ---- - -## Why This Matters - -### Potentially Novel: Two-Layer Context Architecture - -**The Problem:** Existing semantic code tools face a dilemma: -- Return only metadata → LLM lacks implementation details -- Return full source → Token budget explodes, irrelevant code floods context - -**Our Solution:** Layered context assembly with query composition - -``` -Traditional Approach: -User: "Fix the auth bug" -Tool: [Returns entire auth module: 50 files, 15,000 lines, 80,000 tokens] -LLM: [Struggles to find relevant code in noise] - -STE Two-Layer Approach: -User: "Fix the auth bug" - -Step 1 (RSS Layer): search("authentication bugs") -→ Returns: 12 slice keys in 45ms - -Step 2 (LLM narrows): "Show me login-related handlers" -→ get_dependents("api/function/authenticate") -→ Returns: 3 slice keys in 23ms - -Step 3 (Context Assembly): assemble_context("login handlers with auth calls") -→ Loads source for 3 files (240 lines, 1,200 tokens) -→ Includes applicable invariants from auth domain -→ Returns in 180ms - -LLM: [Works with precise, relevant context] -``` - -**Why This Matters:** -1. **Token Efficiency:** 98% reduction in context size (80K → 1.2K tokens) -2. **Composability:** LLM can iteratively refine queries (narrow → specific) -3. **Speed:** Fast RSS queries enable conversational narrowing -4. **Precision:** Only load source for slices that matter - -**Prior Art Analysis (Preliminary):** - -Systems we've examined: -- **GitHub Copilot:** Sends entire files (no semantic graph) -- **OpenAI Code Interpreter:** Executes code, no structural understanding -- **Sourcegraph:** Semantic search, but returns full files -- **LSP (Language Servers):** Local semantic analysis, no graph traversal -- **CodeQL:** Query language for code, but no LLM integration - -**What appears to be different:** -- Real-time semantic graph maintenance (file watching + incremental RECON) -- Two-layer context assembly (structural search → targeted source loading) -- Native MCP integration (AI assistants can query directly) -- Governed cognition framework (CEM + invariant injection) - -**We have not yet:** -- Conducted exhaustive academic literature review -- Searched patent databases comprehensively -- Reviewed all industry research labs (Google, Microsoft, Meta) -- Received peer review feedback - -**We welcome:** References to similar work, corrections, and feedback from the community. - -### Self-Expanding Semantic Understanding -- Detect missing extractors → Generate implementation → Validate → Expand coverage -- Each new extractor becomes reference for future extractors -- Knowledge compounds over time -- **Two-layer enables this:** Query existing extractors (RSS) → load implementations (Context Assembly) → generate new extractor - -### Measurable Governance -- Quantifiable confidence metrics (pending validation) -- Transparent enforcement layers -- Empirical validation strategy - -### OS for AI Cognition -- Not just a tool, but an operating system for governed LLM reasoning -- Explicit state instead of hallucination -- Deterministic traversal instead of probabilistic search -- Layered enforcement instead of best-effort compliance -- **Two-layer enables:** Semantic routing (RSS) → context assembly (rich state) → governed execution (CEM) - ---- - -## References - -- [STE Architecture](../../spec/ste-spec/architecture/STE-Architecture.md) - Sections 3.1, 4.6, 5.3 -- [E-ADR-007](E-ADR-007-Watchdog-Authoritative-Mode.md) - Workspace Boundary operation -- [E-ADR-004](E-ADR-004-RSS-CLI-Implementation.md) - RSS operations -- [Incremental RECON](../../instructions/recon-incremental.md) - Implementation guide -- [RSS Programmatic API](../../instructions/RSS-PROGRAMMATIC-API.md) - API documentation - ---- - -## Revision History - -| Date | Version | Changes | -|------|---------|---------| -| 2026-01-11 | 0.1 | Initial design document | -| 2026-01-11 | 0.2 | Added two-layer architecture (RSS + Context Assembly), identified as potentially novel innovation | - diff --git a/documentation/e-adr-archived/E-ADR-013-Extractor-Validation-Requirements.md b/documentation/e-adr-archived/E-ADR-013-Extractor-Validation-Requirements.md deleted file mode 100644 index deb58c9..0000000 --- a/documentation/e-adr-archived/E-ADR-013-Extractor-Validation-Requirements.md +++ /dev/null @@ -1,624 +0,0 @@ -# E-ADR-013: Extractor Validation Requirements - -**Status:** Accepted -**Implementation:** In Progress -**Date:** 2026-01-11 -**Author:** System -**Authority:** Exploratory ADR (Compliance Required) - -> **Context:** Bug surfaced where module import relationships weren't being converted to graph edges, crippling RSS traversal. This E-ADR defines mandatory validation requirements for all extractors to prevent regression. - ---- - -## Problem Statement - -**Symptom:** `rss-context` returned 30 nodes instead of 100+ because module imports weren't creating graph edges. - -**Root Cause:** Inference phase had a bug in `resolveImportToModuleId()` that prevented relative import resolution. - -**Systemic Issue:** No validation tests caught this bug, even though we worked on it yesterday. If this can happen to built-in extractors, **automated extractors will be unreliable**. - ---- - -## Requirements - -### 1. Graph Edge Creation (MANDATORY) - -Every extractor that emits relationship metadata (imports, calls, uses, etc.) **MUST** ensure that the inference phase converts this metadata to graph edges. - -#### Test Requirement - -```typescript -it('should create graph edges from relationship metadata', async () => { - // Given: Extractor emits imports - const assertions = await extract(filePath, content, projectRoot); - - // When: Inference runs - const result = inferRelationships(assertions, rawAssertions); - - // Then: Graph edges must exist - const node = result.find(a => a._slice.id === 'target-id'); - expect(node._slice.references).toBeDefined(); - expect(node._slice.references.length).toBeGreaterThan(0); -}); -``` - -#### Specific Tests Required - -**Test 1: Module Import Edges** -```typescript -describe('Module Import Graph Edges', () => { - it('should create module->module references from imports', () => { - // Given: Module A imports Module B - const moduleA = createModule('src/a.ts', { - imports: [{ module: './b.js', names: ['foo'] }] - }); - const moduleB = createModule('src/b.ts', {}); - - // When: Inference runs - const result = inferRelationships([moduleA, moduleB], rawImports); - - // Then: A.references should include B - const a = result.find(n => n._slice.id === 'module-src-a'); - expect(a._slice.references).toContainEqual({ - domain: 'graph', - type: 'module', - id: 'module-src-b' - }); - }); -}); -``` - -**Test 2: Bidirectional Edges** -```typescript -it('should create bidirectional edges (referenced_by)', () => { - // Given: Module A imports Module B - const moduleA = createModule('src/a.ts', { imports: ['./b.js'] }); - const moduleB = createModule('src/b.ts', {}); - - // When: Inference runs - const result = inferRelationships([moduleA, moduleB], rawImports); - - // Then: B.referenced_by should include A - const b = result.find(n => n._slice.id === 'module-src-b'); - expect(b._slice.referenced_by).toContainEqual({ - domain: 'graph', - type: 'module', - id: 'module-src-a' - }); -}); -``` - -**Test 3: Relative Import Resolution** -```typescript -it('should resolve relative imports correctly', () => { - // Given: Complex relative imports - const tests = [ - { from: 'src/mcp/mcp-server.ts', import: './tools-optimized.js', expect: 'module-src-mcp-tools-optimized' }, - { from: 'src/mcp/mcp-server.ts', import: '../rss/rss-operations.js', expect: 'module-src-rss-rss-operations' }, - { from: 'src/a/b/c.ts', import: '../../x/y.js', expect: 'module-src-x-y' }, - ]; - - for (const test of tests) { - const resolved = resolveImportToModuleId(test.import, test.from); - expect(resolved).toBe(test.expect); - } -}); -``` - ---- - -### 2. Import Metadata Format (MANDATORY) - -All extractors that process imports **MUST** emit raw assertions in this format: - -```typescript -{ - elementId: 'import-{index}', - elementType: 'import', - file: 'relative/path/to/file.ext', - metadata: { - module: 'relative/or/absolute/import/path', - names: ['namedImport1', 'namedImport2'], - default: 'defaultImportName' // optional - } -} -``` - -#### Example: TypeScript Extractor - -```typescript -// For: import { foo, bar } from './utils'; -{ - elementId: 'import-0', - elementType: 'import', - file: 'src/app.ts', - metadata: { - module: './utils', - names: ['foo', 'bar'] - } -} - -// For: import Utils from '../utils'; -{ - elementId: 'import-1', - elementType: 'import', - file: 'src/app.ts', - metadata: { - module: '../utils', - default: 'Utils', - names: [] - } -} -``` - -#### Validation Test - -```typescript -it('should emit import metadata in correct format', async () => { - const content = `import { foo } from './bar';`; - const assertions = await extract('src/test.ts', content, '/project'); - - const imports = assertions.filter(a => a.elementType === 'import'); - expect(imports[0]).toMatchObject({ - elementId: expect.stringMatching(/^import-\d+$/), - elementType: 'import', - file: 'src/test.ts', - metadata: { - module: './bar', - names: ['foo'] - } - }); -}); -``` - ---- - -### 3. Inference Phase Validation (SYSTEM) - -The inference phase **MUST** validate that it correctly processes extractor output. - -#### Test Suite: `src/recon/phases/inference.test.ts` - -```typescript -describe('Inference Phase - Graph Edge Creation', () => { - it('should convert import metadata to graph edges', () => { - // Test that imports become references - }); - - it('should create bidirectional edges', () => { - // Test that A->B creates B.referenced_by = [A] - }); - - it('should resolve relative imports correctly', () => { - // Test ../path, ./path, ../../path - }); - - it('should handle circular dependencies', () => { - // Test A->B->A doesn't infinite loop - }); - - it('should skip external imports', () => { - // Test that 'react', 'lodash', etc. don't create edges - }); -}); -``` - ---- - -### 4. End-to-End Validation (INTEGRATION) - -After full RECON, the graph **MUST** be traversable. - -#### Validation Test - -```typescript -describe('Graph Traversal Post-RECON', () => { - it('should traverse module dependencies via blast radius', async () => { - // Given: Full RECON has run - await runFullRecon(projectRoot); - - // When: Query blast radius - const ctx = await initRssContext(stateRoot); - const result = blastRadius(ctx, 'module-src-mcp-mcp-server', 3); - - // Then: Should find all dependencies - expect(result.nodes.length).toBeGreaterThan(10); - expect(result.nodes).toContainEqual( - expect.objectContaining({ key: 'module-src-mcp-tools-optimized' }) - ); - }); - - it('should assemble context from natural language query', async () => { - // Given: Full RECON has run - await runFullRecon(projectRoot); - - // When: Query context - const ctx = await initRssContext(stateRoot); - const { entryPoints } = findEntryPoints(ctx, 'mcp server'); - const context = assembleContext(ctx, entryPoints, { maxDepth: 3 }); - - // Then: Should find comprehensive context - expect(context.nodes.length).toBeGreaterThan(50); - }); -}); -``` - ---- - -### 5. Self-Validation (RECON Phase 7) - -RECON Phase 7 **MUST** validate graph integrity after inference. - -#### Checks Required - -**Check 1: Orphaned References** -```typescript -// Find references to non-existent nodes -const orphans = findOrphanedReferences(graph); -if (orphans.length > 0) { - reportError('Orphaned references detected', { orphans }); -} -``` - -**Check 2: Bidirectional Consistency** -```typescript -// Verify A->B implies B.referenced_by includes A -const inconsistencies = findBidirectionalInconsistencies(graph); -if (inconsistencies.length > 0) { - reportWarning('Bidirectional edge inconsistencies', { inconsistencies }); -} -``` - -**Check 3: Import Coverage** -```typescript -// Verify all extracted imports created edges -const importsWithoutEdges = findImportsWithoutEdges(rawAssertions, graph); -if (importsWithoutEdges.length > 0) { - reportError('Imports did not create graph edges', { importsWithoutEdges }); -} -``` - -#### Implementation - -**File:** `src/recon/phases/validation.ts` - -```typescript -export interface GraphHealthCheck { - name: string; - severity: 'error' | 'warning' | 'info'; - passed: boolean; - message: string; - details?: unknown; -} - -export function validateGraphEdges( - graph: Map, - rawAssertions: RawAssertion[] -): GraphHealthCheck[] { - const checks: GraphHealthCheck[] = []; - - // Check 1: Orphaned References - const orphans = findOrphanedReferences(graph); - checks.push({ - name: 'orphaned-references', - severity: 'error', - passed: orphans.length === 0, - message: `Found ${orphans.length} orphaned references`, - details: { orphans }, - }); - - // Check 2: Bidirectional Consistency - const inconsistencies = findBidirectionalInconsistencies(graph); - checks.push({ - name: 'bidirectional-edges', - severity: 'warning', - passed: inconsistencies.length === 0, - message: `Found ${inconsistencies.length} bidirectional inconsistencies`, - details: { inconsistencies }, - }); - - // Check 3: Import Coverage - const importsWithoutEdges = findImportsWithoutEdges(rawAssertions, graph); - checks.push({ - name: 'import-edge-coverage', - severity: 'error', - passed: importsWithoutEdges.length === 0, - message: `${importsWithoutEdges.length} imports did not create edges`, - details: { importsWithoutEdges }, - }); - - return checks; -} -``` - ---- - -### 6. Continuous Validation (CI/CD) - -All extractor tests **MUST** run in CI before merge. - -#### GitHub Actions Workflow - -```yaml -name: Extractor Validation - -on: [push, pull_request] - -jobs: - validate-extractors: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - - run: npm ci - - run: npm test -- src/extractors/ - - run: npm test -- src/recon/phases/inference.test.ts - - run: npm run build - - run: npm run test:integration -- graph-edges -``` - ---- - -## Extractor Checklist (Updated from E-ADR-008) - -All extractors **MUST** pass these checks: - -### Code Requirements -- [ ] Implements `extract(filepath, content, projectRoot): Promise` -- [ ] Emits import metadata as raw assertions (if applicable) -- [ ] Import metadata follows required format -- [ ] Handles parse errors gracefully (returns empty, doesn't throw) -- [ ] Relative file paths in provenance -- [ ] Accurate line numbers (1-indexed) - -### Test Requirements -- [ ] Unit tests for extraction logic -- [ ] Test: Graph edges created from imports -- [ ] Test: Bidirectional edges exist -- [ ] Test: Relative import resolution -- [ ] Test: Handles circular dependencies -- [ ] Test: Skips external imports -- [ ] Integration test: Blast radius works -- [ ] Integration test: Context assembly works - -### Validation Requirements -- [ ] Passes RECON Phase 7 validation -- [ ] No orphaned references -- [ ] Bidirectional edges consistent -- [ ] All imports create edges (or explicitly skip) -- [ ] CI tests pass - -### Documentation -- [ ] Added to E-ADR-008 (Extractor Development Guide) -- [ ] Test fixtures included -- [ ] Known limitations documented - ---- - -## Enforcement - -### For Built-in Extractors - -**Immediate:** All existing extractors must be retrofitted with these tests by 2026-01-15. - -**Status:** -- ✅ TypeScript: Fixed (2026-01-11) -- ⏳ Python: Pending -- ⏳ CloudFormation: Pending -- ⏳ JSON: N/A (no imports) -- ⏳ Angular: Pending -- ⏳ CSS: N/A (no imports) - -### For Future Extractors - -**Blocker:** Cannot merge without: -1. All tests passing -2. CI validation passing -3. RECON Phase 7 reporting 0 errors - -### For Third-Party Extractors - -**Plugin System:** When E-ADR-014 (Extractor Plugin System) is implemented: -- Plugins must declare conformance level: "validated" or "experimental" -- Non-validated plugins show warning during RECON -- Validated plugins must pass test suite - ---- - -## Rationale - -### Why This Matters - -**Without validation:** -- Graph traversal is unreliable -- Context assembly returns incomplete results -- RSS queries miss relevant code -- AI assistants get insufficient context -- Bugs recur even after fixes - -**With validation:** -- Extractors are self-documenting (tests show expected behavior) -- Bugs caught before merge -- Regression impossible (tests prevent it) -- Confidence in automated extraction -- Plugin ecosystem becomes viable - ---- - -## Impact - -### On Existing Code - -**Low Impact:** Most extractors already emit correct metadata. This E-ADR: -- Formalizes existing implicit requirements -- Adds test coverage for edge cases -- Provides validation hooks - -### On New Extractors - -**Medium Impact:** Developers must write 5-10 additional tests per extractor. However: -- Template tests can be copy-pasted -- Test utilities reduce boilerplate -- Confidence in correctness is worth effort - -### On Performance - -**Negligible:** Validation runs only in Phase 7 (after population), doesn't block writes. - ---- - -## Future Work - -### Phase 1: Test Utilities (Immediate) - -Create helper functions to reduce test boilerplate: - -```typescript -// src/test/extractor-test-utils.ts - -export function expectGraphEdges( - result: NormalizedAssertion[], - from: string, - to: string[] -) { - const node = result.find(a => a._slice.id === from); - expect(node).toBeDefined(); - - for (const target of to) { - expect(node!._slice.references).toContainEqual( - expect.objectContaining({ id: target }) - ); - } -} - -export function expectBidirectionalEdges( - result: NormalizedAssertion[], - nodeA: string, - nodeB: string -) { - expectGraphEdges(result, nodeA, [nodeB]); - expectGraphEdges(result, nodeB, [nodeA]); // via referenced_by -} -``` - -### Phase 2: Visual Validation (Future) - -Graph visualization tool to inspect edges: - -```bash -ste validate-graph --visualize -# Opens browser with interactive graph explorer -``` - -### Phase 3: Fuzzing (Future) - -Automated generation of edge-case test files: - -```bash -ste fuzz-extractor --language typescript --iterations 1000 -``` - ---- - -## Appendix A: Bug Postmortem (2026-01-11) - -### What Went Wrong - -1. **Inference bug:** `resolveImportToModuleId()` used `generateModuleId(importPath)` directly instead of resolving relative paths first -2. **Result:** Import `./tools-optimized.js` from `src/mcp/mcp-server.ts` generated ID `module-.-tools` instead of `module-src-mcp-tools-optimized` -3. **Impact:** Graph lookups failed, no edges created, traversal crippled - -### Why Tests Didn't Catch It - -**Root cause:** No tests validated that imports create graph edges. - -**Tests that existed:** -- Extractor emits correct metadata ✅ -- Inference runs without error ✅ - -**Tests that were missing:** -- Graph edges actually created ❌ -- Relative imports resolved correctly ❌ -- Blast radius traverses imported modules ❌ - -### Fix Applied - -1. **Fixed `resolveImportToModuleId()`** to resolve relative paths before generating module ID -2. **Added comprehensive tests** in `src/recon/phases/inference.test.ts` -3. **Verified with integration test:** `ste rss-context` now returns 98 nodes (was 30) - -### Lessons Learned - -**Insight:** Extractor validation must test **end-to-end behavior** (graph traversal), not just intermediate outputs. - -**Principle:** If a feature is critical to the system, it must have a test that would fail if that feature breaks. - ---- - -## Appendix B: Test Template - -```typescript -// src/extractors/YOURLANG/YOURLANG-extractor.test.ts - -import { describe, it, expect } from 'vitest'; -import { extract } from './YOURLANG-extractor.js'; -import { inferRelationships } from '../../recon/phases/inference.js'; - -describe('YOURLANG Extractor - Graph Edges', () => { - it('should create graph edges from imports', async () => { - // Given: File with imports - const content = `/* your language syntax */`; - const assertions = await extract('test.ext', content, '/project'); - - // When: Inference runs - const rawAssertions = buildRawImportAssertions(assertions); - const result = inferRelationships(assertions, rawAssertions); - - // Then: Graph edges exist - const node = result.find(a => a._slice.id === 'expected-id'); - expect(node._slice.references).toContainEqual({ - domain: 'graph', - type: 'module', - id: 'expected-import-id', - }); - }); - - it('should create bidirectional edges', async () => { - // Test that A->B creates B.referenced_by = [A] - }); - - it('should resolve relative imports', async () => { - // Test that ../path and ./path work correctly - }); -}); - -describe('YOURLANG Extractor - Integration', () => { - it('should enable blast radius traversal', async () => { - // Full RECON + blast radius query - }); -}); -``` - ---- - -**Status Summary:** -- ✅ Requirements defined -- ✅ TypeScript extractor validated -- ⏳ Test utilities needed -- ⏳ Other extractors need retrofitting -- ⏳ CI enforcement pending - -**Next Steps:** -1. Create test utilities (2026-01-11) -2. Retrofit Python extractor (2026-01-12) -3. Add CI validation (2026-01-13) -4. Document in E-ADR-008 (2026-01-14) - ---- - -**End of E-ADR-013** - - - - diff --git a/documentation/e-adr-archived/README.md b/documentation/e-adr-archived/README.md deleted file mode 100644 index c962a78..0000000 --- a/documentation/e-adr-archived/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# Archived E-ADRs (Exploratory ADRs) - -**Status:** DEPRECATED -**Archived Date:** 2026-03-08 -**Reason:** Migrated to ADR Kit format - -## Notice - -These E-ADRs have been **migrated to ADR Kit format** and are now located in `adrs/`. - -**Please use the new ADR Kit versions instead:** - -| Original E-ADR | New ADR Kit ID | Type | Location | -|----------------|----------------|------|----------| -| E-ADR-001 | ADR-L-0001 | Logical | `adrs/logical/ADR-L-0001-*.yaml` | -| E-ADR-002 | ADR-L-0002 | Logical | `adrs/logical/ADR-L-0002-*.yaml` | -| E-ADR-003 | ADR-L-0003 | Logical | `adrs/logical/ADR-L-0003-*.yaml` | -| E-ADR-004 | ADR-P-0001 | Physical | `adrs/physical/ADR-P-0001-*.yaml` | -| E-ADR-005 | ADR-P-0002 | Physical | `adrs/physical/ADR-P-0002-*.yaml` | -| E-ADR-006 | ADR-P-0003 | Physical | `adrs/physical/ADR-P-0003-*.yaml` | -| E-ADR-007 | ADR-L-0004 | Logical | `adrs/logical/ADR-L-0004-*.yaml` | -| E-ADR-008 | N/A | Documentation | Kept as guide (not a decision) | -| E-ADR-009 | ADR-L-0005 | Logical | `adrs/logical/ADR-L-0005-*.yaml` | -| E-ADR-010 | ADR-L-0006 | Logical | `adrs/logical/ADR-L-0006-*.yaml` | -| E-ADR-011 | ADR-P-0004 | Physical | `adrs/physical/ADR-P-0004-*.yaml` | -| E-ADR-013 | ADR-P-0005 | Physical | `adrs/physical/ADR-P-0005-*.yaml` | - -## Why Migrate? - -E-ADRs were an exploratory format that served their purpose during initial development. However, they had limitations: - -- **Not machine-verifiable**: No schema validation -- **Poor AI readability**: Free-form narrative requires parsing -- **No discovery mechanism**: Must scan all files -- **Not STE-compliant**: Doesn't follow STE principles - -ADR Kit addresses all these limitations with: -- JSON Schema + Pydantic validation -- YAML frontmatter + embedded Markdown -- Auto-generated manifest for discovery -- Full STE compliance (PRIME-1, PRIME-2, SYS-14) - -## What Changed? - -### Format -- **Before**: Markdown with bold metadata (`**Status:** Accepted`) -- **After**: YAML frontmatter with strict schema - -### Structure -- **Before**: Free-form sections (Context, Decision, Rationale, Specification, Consequences) -- **After**: Structured fields (context, decisions[], invariants[], component_specifications[]) - -### Discovery -- **Before**: Grep through markdown files -- **After**: Query manifest.yaml by domain, status, technology - -### Validation -- **Before**: Manual review only -- **After**: Automated JSON Schema + Pydantic validation - -## What Was Preserved? - -**Everything.** All narrative content, metadata, and decisions were migrated: - -- Context sections → `context` field -- Decision sections → `decisions[].summary` -- Rationale sections → `decisions[].rationale` -- Specification sections → `invariants[]` or `component_specifications[]` -- Consequences sections → `decisions[].consequences` - -Original E-ADRs are preserved in this archive for historical reference. - -## Migration Tooling - -The migration was performed using [adr-architecture-kit](https://github.com/egallmann/adr-architecture-kit) migration tooling: - -```bash -python scripts/migrate_e_adrs.py \ - --input-dir ste-runtime/documentation/e-adr \ - --output-dir ste-runtime/adrs \ - --ste-runtime-root ste-runtime -``` - -This tooling is reusable for other projects migrating from Markdown ADRs to ADR Kit format. - -## References - -- [New ADRs](../../adrs/) -- [ADR Kit Documentation](https://github.com/egallmann/adr-architecture-kit) -- [Migration Details](../../adrs/MIGRATION.md) diff --git a/documentation/guides/README.md b/documentation/guides/README.md new file mode 100644 index 0000000..9e509af --- /dev/null +++ b/documentation/guides/README.md @@ -0,0 +1,23 @@ +# Guides + +This directory is intentionally small. + +Keep only guides that are current, operational, and specific to using `ste-runtime` today. + +## Current Guides + +- [Configuration Reference](./configuration-reference.md) - Runtime configuration and `ste.config.json` behavior. +- [MCP Setup Guide](./mcp-setup.md) - MCP integration and editor setup. +- [Troubleshooting Guide](./troubleshooting.md) - Operational debugging and common failure modes. + +## Generated Architecture Docs + +Architecture authority now lives under [`adrs/`](../../adrs/) and the generated [`SYSTEM-OVERVIEW.md`](../../SYSTEM-OVERVIEW.md). + +- Source ADRs: [`../../adrs/`](../../adrs/) +- Generated ADR markdown: [`../../adrs/rendered/`](../../adrs/rendered/) +- Generated repo overview: [`../../SYSTEM-OVERVIEW.md`](../../SYSTEM-OVERVIEW.md) + +## Removed Material + +Legacy onboarding, FAQ, glossary, and project-history guide documents were removed from the active guide shelf because they had drifted from the ADR Kit source of truth and were adding navigation noise. diff --git a/documentation/guides/configuration-reference.md b/documentation/guides/configuration-reference.md index f8eb9a2..acb2250 100644 --- a/documentation/guides/configuration-reference.md +++ b/documentation/guides/configuration-reference.md @@ -680,5 +680,6 @@ Some settings can be overridden via environment variables: - [RECON README](../instructions/RECON-README.md) - RECON usage and configuration - [MCP Setup Guide](./mcp-setup.md) - MCP server configuration -- [E-ADR-011](../e-adr/E-ADR-011-ste-runtime-MCP-Server.md) - MCP Server architecture +- [ADR-P-0004](../../adrs/rendered/ADR-P-0004.md) - MCP server architecture + diff --git a/documentation/guides/dual-repo-workflow.md b/documentation/guides/dual-repo-workflow.md deleted file mode 100644 index dcbf58f..0000000 --- a/documentation/guides/dual-repo-workflow.md +++ /dev/null @@ -1,359 +0,0 @@ -# Dual-Repo Workflow Guide - -## Strategy Overview - -You have two repositories with different purposes: - -1. **`ste-runtime` (public)** — Stable releases, showcasing, public documentation -2. **`ste-runtime-private` (private)** — Active development, experimental features, work-in-progress - -This allows you to: -- Develop privately without exposing incomplete work -- Release stable versions publicly when ready -- Maintain a clean public history while working messily in private -- Keep sensitive experiments/prototypes private indefinitely - ---- - -## Initial Setup (One-Time) - -### 1. Rename GitHub Repository - -On GitHub: -1. Go to https://github.com/egallmann/ste-runtime/settings -2. Scroll to "Repository name" -3. Change to: `ste-runtime-private` -4. Click "Rename" - -GitHub automatically redirects old URLs, but we'll update local config to be explicit. - -### 2. Update Local Remote - -```bash -cd /path/to/ste-runtime -git remote set-url origin https://github.com/egallmann/ste-runtime-private.git -git remote -v # Verify -``` - -Output should show: -``` -origin https://github.com/egallmann/ste-runtime-private.git (fetch) -origin https://github.com/egallmann/ste-runtime-private.git (push) -``` - -### 3. Create New Public Repository - -On GitHub: -1. Go to https://github.com/new -2. Repository name: `ste-runtime` -3. Visibility: **Public** -4. Do NOT initialize with README/license/gitignore -5. Click "Create repository" - -### 4. Add Public Repo as Remote - -```bash -git remote add public https://github.com/egallmann/ste-runtime.git -git remote -v # Should now show both 'origin' and 'public' -``` - -### 5. Initial Push to Public - -```bash -# Push your current develop branch to the public repo -git push public develop:main - -# Or if you want develop branch on public too: -git push public develop - -# Or push main if that's your stable branch: -git push public main -``` - ---- - -## Daily Workflow - -### Development (Private Repository) - -```bash -# Normal development work -git checkout develop -# ... make changes ... -git add . -git commit -m "Add experimental feature X" -git push origin develop # → Goes to ste-runtime-private -``` - -**This stays private.** Your WIP commits, experiments, and private features never leave `ste-runtime-private`. - -### Release to Public - -When a feature/version is ready for public release: - -```bash -# 1. Ensure your develop/main branch is clean and tested -git checkout develop -npm test # Make sure everything passes - -# 2. Update version in package.json (if releasing a new version) -# Edit package.json, then commit: -git add ste-runtime/package.json -git commit -m "Bump version to 1.1.0" -git push origin develop - -# 3. Push to public repository -git push public develop:main # Push develop → public main -# OR -git push public develop # Push develop → public develop -# OR -git push public main # If you use main for releases - -# 4. Tag the release (optional but recommended) -git tag v1.1.0 -git push public v1.1.0 -``` - -**What gets published:** -- All commits from the branch you push -- All files tracked in git (respecting .gitignore) - -**What stays private:** -- Commits/branches you don't push -- Anything in private-only branches -- Work-in-progress features - ---- - -## Advanced: Selective Syncing - -### Cherry-Pick Specific Commits - -If you want to publish only specific commits (not the full branch): - -```bash -# Create a public-release branch -git checkout -b public-release origin/main # Start from current public state - -# Cherry-pick specific commits from develop -git cherry-pick -git cherry-pick - -# Push to public -git push public public-release:main -``` - -### Merge Specific Features - -```bash -# Create a clean branch for public release -git checkout -b feature-for-public develop - -# Remove or clean up anything you don't want public -# ... make edits ... - -# Commit and push -git commit -am "Clean version of feature X for public release" -git push public feature-for-public:main -``` - ---- - -## Git Submodule Workflow - -Since your private project will use `ste-runtime` as a submodule: - -### In Your Private Project - -```bash -cd /path/to/my-private-project - -# Add the PUBLIC ste-runtime as a submodule -git submodule add https://github.com/egallmann/ste-runtime.git ste-runtime - -# This pulls from the public repo -# You get stable, released versions -``` - -### Updating the Submodule - -When you push new versions to public: - -```bash -# In your private project -cd ste-runtime -git pull origin main # Pull latest from public repo - -cd .. # Back to private project root -git add ste-runtime -git commit -m "Update ste-runtime submodule to v1.1.0" -git push -``` - -### Development in Both Repos - -**Option A: Develop in ste-runtime-private, release to ste-runtime public, pull into your project** - -```bash -# 1. Work in ste-runtime-private -cd /path/to/ste-runtime -# ... develop features ... -git push origin develop - -# 2. When stable, push to public -git push public develop:main - -# 3. Update submodule in private project -cd /path/to/my-private-project/ste-runtime -git pull origin main -cd .. -git add ste-runtime -git commit -m "Update ste-runtime" -``` - -**Option B: Develop directly in the submodule (for quick fixes)** - -```bash -# In your private project's ste-runtime submodule -cd /path/to/my-private-project/ste-runtime - -# Make changes -# ... edit files ... - -# Commit locally -git add . -git commit -m "Fix bug X" - -# Push to PUBLIC repo (since submodule points to public) -git push origin main - -# Or push to private repo instead: -git remote add private https://github.com/egallmann/ste-runtime-private.git -git push private develop -``` - ---- - -## Best Practices - -### 1. Branch Strategy - -**Private repo (`ste-runtime-private`):** -- `develop` — Active development (bleeding edge) -- `feature/*` — Experimental features -- `main` — Stable releases (synced with public) - -**Public repo (`ste-runtime`):** -- `main` — Stable releases only -- Optional: `develop` for "next" version preview - -### 2. Commit Hygiene - -**Private commits can be messy:** -```bash -git commit -m "WIP: trying something" -git commit -m "debugging" -git commit -m "fix typo" -``` - -**Public commits should be clean:** -```bash -# Before pushing to public, squash/rebase if needed -git rebase -i HEAD~5 # Clean up last 5 commits -git push public develop:main -``` - -### 3. Secrets and Sensitive Data - -**Never commit to private repo:** -- Production credentials -- API keys -- Internal infrastructure references - -Even in private repos, avoid hardcoding secrets. Use environment variables and `.env` files (gitignored). - -### 4. Documentation - -**Private repo:** -- Can have internal notes, TODOs, architecture explorations - -**Public repo:** -- Only polished, user-facing documentation - -### 5. Versioning - -**Use semantic versioning:** -- `1.0.0` — Stable public release -- `1.1.0` — New features -- `1.1.1` — Bug fixes -- `2.0.0` — Breaking changes - -Update `package.json` version before each public release. - ---- - -## Quick Reference - -```bash -# Check current remotes -git remote -v - -# Normal private development -git push origin develop # → ste-runtime-private - -# Push to public repo -git push public main # → ste-runtime (public) - -# Push specific branch to public -git push public develop:main # develop → public main - -# Tag a release -git tag v1.1.0 -git push public v1.1.0 - -# Pull public changes back to private -git fetch public -git merge public/main -``` - ---- - -## Prompt for Cursor (Other Project) - -When working in your other Cursor project that uses `ste-runtime` as a submodule: - -``` -I'm using ste-runtime as a git submodule in this project. -- The submodule is located at: ste-runtime/ -- It points to the public repo: https://github.com/egallmann/ste-runtime.git -- I develop ste-runtime separately in a separate repository -- That repo has two remotes: - - origin: ste-runtime-private (my development repo) - - public: ste-runtime (public releases) - -When I need to: -1. Use ste-runtime → Use the submodule as-is -2. Update ste-runtime → cd ste-runtime && git pull origin main -3. Develop ste-runtime → Switch to my development repository -4. Release updates → Push from private to public, then update submodule - -Please respect this workflow and don't modify the submodule directly unless it's a small fix I want to push to public immediately. -``` - ---- - -## Summary - -| Action | Command | Goes To | -|--------|---------|---------| -| Normal development | `git push origin develop` | Private repo | -| Public release | `git push public main` | Public repo | -| Update submodule | `cd submodule && git pull origin main` | Pull from public | -| Check remotes | `git remote -v` | Show all remotes | - -**Your workflow is:** Develop in private → Test thoroughly → Push stable code to public → Update submodules - -This gives you **full control** over what becomes public while maintaining **clean separation** between development and releases. - - - diff --git a/documentation/guides/extractor-validation-quickstart.md b/documentation/guides/extractor-validation-quickstart.md deleted file mode 100644 index 8f20931..0000000 --- a/documentation/guides/extractor-validation-quickstart.md +++ /dev/null @@ -1,314 +0,0 @@ -# Extractor Validation Quick Start - -**Authority:** E-ADR-013 (Extractor Validation Requirements) - -This guide shows how to validate that your extractor properly creates graph edges. - ---- - -## The Problem We're Solving - -**Bug:** Module imports weren't creating graph edges, breaking RSS traversal. - -**Solution:** Every extractor must validate that relationship metadata (imports, calls, uses) becomes graph edges. - ---- - -## Quick Example - -```typescript -import { describe, it } from 'vitest'; -import { - createModuleAssertion, - createRawImportAssertion, - assertInferenceCreatesEdges, - assertNoOrphanedReferences, - assertBidirectionalConsistency -} from '../../test/extractor-test-utils.js'; - -describe('MyExtractor - Graph Edges', () => { - it('should create edges from imports', () => { - // Given: Two modules where A imports B - const moduleA = createModuleAssertion('src/a.ext', 'module-src-a'); - const moduleB = createModuleAssertion('src/b.ext', 'module-src-b'); - - const rawImport = createRawImportAssertion( - 'src/a.ext', - './b', - ['foo', 'bar'] - ); - - // When: Inference runs (validates edges created) - const result = assertInferenceCreatesEdges( - [moduleA, moduleB], - [rawImport], - 'module-src-a', // from - ['module-src-b'] // to - ); - - // Then: Validate graph integrity - assertNoOrphanedReferences(result); - assertBidirectionalConsistency(result); - }); -}); -``` - ---- - -## Test Utilities - -### `createModuleAssertion(filePath, moduleId)` - -Creates a minimal module for testing. - -```typescript -const module = createModuleAssertion('src/app.ts', 'module-src-app'); -``` - -### `createRawImportAssertion(file, module, names)` - -Creates a raw import assertion that inference will process. - -```typescript -const rawImport = createRawImportAssertion( - 'src/app.ts', - './utils.js', - ['foo', 'bar'] -); -``` - -### `assertInferenceCreatesEdges(normalized, rawAssertions, fromId, toIds)` - -**Core validation.** Runs inference and asserts that edges are created correctly. - -```typescript -const result = assertInferenceCreatesEdges( - [moduleA, moduleB], - [rawImport], - 'module-src-a', - ['module-src-b'] -); -``` - -### `assertNoOrphanedReferences(result)` - -Validates that all references point to real nodes. - -```typescript -assertNoOrphanedReferences(result); -``` - -### `assertBidirectionalConsistency(result)` - -Validates that A→B implies B is referenced by A. - -```typescript -assertBidirectionalConsistency(result); -``` - -### `expectGraphEdges(result, fromId, toIds)` - -Low-level assertion for specific edges. - -```typescript -expectGraphEdges(result, 'module-src-a', ['module-src-b', 'module-src-c']); -``` - -### `expectBidirectionalEdges(result, nodeA, nodeB)` - -Low-level assertion for bidirectional edges. - -```typescript -expectBidirectionalEdges(result, 'module-src-a', 'module-src-b'); -``` - ---- - -## Required Tests (Checklist) - -Every extractor that emits relationship metadata **MUST** have these tests: - -- [ ] **Graph edges created** - `assertInferenceCreatesEdges()` passes -- [ ] **Bidirectional edges** - `assertBidirectionalConsistency()` passes -- [ ] **No orphans** - `assertNoOrphanedReferences()` passes -- [ ] **Relative imports** - Tests for `./`, `../`, `../../` paths -- [ ] **Circular dependencies** - A→B→A doesn't break -- [ ] **External imports skipped** - 'react', 'lodash', etc. don't create edges - ---- - -## Example: Full Test Suite - -```typescript -import { describe, it } from 'vitest'; -import { extract } from './myextractor.js'; -import { - createModuleAssertion, - createRawImportAssertion, - assertInferenceCreatesEdges, - assertNoOrphanedReferences, - assertBidirectionalConsistency -} from '../../test/extractor-test-utils.js'; - -describe('MyExtractor - Graph Edge Validation', () => { - it('should create module->module edges from imports', () => { - const moduleA = createModuleAssertion('src/a.ext', 'module-src-a'); - const moduleB = createModuleAssertion('src/b.ext', 'module-src-b'); - const rawImport = createRawImportAssertion('src/a.ext', './b', ['foo']); - - const result = assertInferenceCreatesEdges( - [moduleA, moduleB], - [rawImport], - 'module-src-a', - ['module-src-b'] - ); - - assertNoOrphanedReferences(result); - assertBidirectionalConsistency(result); - }); - - it('should resolve relative imports correctly', () => { - // Test ./path - const a1 = createModuleAssertion('src/mcp/mcp-server.ts', 'module-src-mcp-mcp-server'); - const b1 = createModuleAssertion('src/mcp/tools-optimized.ts', 'module-src-mcp-tools-optimized'); - const raw1 = createRawImportAssertion('src/mcp/mcp-server.ts', './tools-optimized', []); - - const result1 = assertInferenceCreatesEdges( - [a1, b1], - [raw1], - 'module-src-mcp-mcp-server', - ['module-src-mcp-tools-optimized'] - ); - - // Test ../path - const a2 = createModuleAssertion('src/mcp/mcp-server.ts', 'module-src-mcp-mcp-server'); - const b2 = createModuleAssertion('src/rss/rss-operations.ts', 'module-src-rss-rss-operations'); - const raw2 = createRawImportAssertion('src/mcp/mcp-server.ts', '../rss/rss-operations', []); - - const result2 = assertInferenceCreatesEdges( - [a2, b2], - [raw2], - 'module-src-mcp-mcp-server', - ['module-src-rss-rss-operations'] - ); - }); - - it('should handle circular dependencies', () => { - const moduleA = createModuleAssertion('src/a.ext', 'module-src-a'); - const moduleB = createModuleAssertion('src/b.ext', 'module-src-b'); - - const rawImportAB = createRawImportAssertion('src/a.ext', './b', []); - const rawImportBA = createRawImportAssertion('src/b.ext', './a', []); - - const result = assertInferenceCreatesEdges( - [moduleA, moduleB], - [rawImportAB, rawImportBA], - 'module-src-a', - ['module-src-b'] - ); - - // Also check reverse edge - expectGraphEdges(result, 'module-src-b', ['module-src-a']); - - assertNoOrphanedReferences(result); - assertBidirectionalConsistency(result); - }); - - it('should skip external imports', () => { - const moduleA = createModuleAssertion('src/a.ext', 'module-src-a'); - - const rawExternal = createRawImportAssertion('src/a.ext', 'react', []); - - const result = inferRelationships([moduleA], [rawExternal]); - - // Should not create edge to 'react' - const a = result.find(n => n._slice.id === 'module-src-a'); - const refs = a!._slice.references || []; - - expect(refs.filter(r => r.id.includes('react'))).toHaveLength(0); - }); -}); -``` - ---- - -## Integration Test (Recommended) - -After unit tests pass, validate end-to-end: - -```typescript -describe('MyExtractor - Integration', () => { - it('should enable blast radius traversal', async () => { - // Full RECON - await runFullRecon(projectRoot); - - // Load graph - const ctx = await initRssContext(stateRoot); - - // Query blast radius - const result = blastRadius(ctx, 'module-src-entry', 3); - - // Should traverse import edges - expect(result.nodes.length).toBeGreaterThan(5); - expect(result.nodes).toContainEqual( - expect.objectContaining({ key: 'module-src-dependency' }) - ); - }); -}); -``` - ---- - -## What Gets Validated - -### ✅ Extractor Output -- Emits correct import metadata format -- Provenance includes relative paths -- Line numbers are accurate - -### ✅ Inference Processing -- Import metadata → graph edges -- Relative paths resolved correctly -- Bidirectional edges created - -### ✅ Graph Integrity -- No orphaned references -- Bidirectional consistency -- Traversal works end-to-end - ---- - -## CI/CD Integration - -Add to your CI workflow: - -```yaml -- name: Validate Extractors - run: | - npm test -- src/extractors/ - npm test -- src/recon/phases/inference.test.ts -``` - ---- - -## References - -- **E-ADR-013:** Extractor Validation Requirements (full specification) -- **E-ADR-008:** Extractor Development Guide (how to build extractors) -- **Example:** `src/recon/phases/inference.test.ts` (working tests) -- **Utilities:** `src/test/extractor-test-utils.ts` (test helpers) - ---- - -## Getting Help - -1. Study `src/recon/phases/inference.test.ts` for working examples -2. Copy-paste the test template above -3. Run tests: `npm test -- src/extractors/your-extractor.test.ts` -4. Check RECON Phase 7 validation: `ste recon --mode=full` - ---- - -**Status:** ✅ Active requirement for all extractors (as of 2026-01-11) - - diff --git a/documentation/guides/faq.md b/documentation/guides/faq.md deleted file mode 100644 index ab29794..0000000 --- a/documentation/guides/faq.md +++ /dev/null @@ -1,676 +0,0 @@ -# Frequently Asked Questions (FAQ) - -Common questions about ste-runtime. - ---- - -## General Questions - -### What is ste-runtime? - -ste-runtime is a **component implementation** of the [System of Thought Engineering (STE) Specification](https://github.com/egallmann/ste-spec). This repository provides a subset of the components defined in the complete STE Runtime architecture. - -**Components implemented in this repository:** - -1. **RECON** (Reconciliation Protocol) - Extracts semantic state from source code into AI-DOC format -2. **RSS** (Runtime State Slicing) - Graph traversal protocol for deterministic context assembly - - Includes **MVC** (Minimally Viable Context) assembly via `assembleContext` function - - Basic entry point discovery (`findEntryPoints`) for natural language queries -3. **MCP Server** - Model Context Protocol integration for AI assistant tooling -4. **File Watching** - Incremental RECON triggering on file changes - -**Complete STE Runtime Architecture:** - -The complete STE Runtime system (per [STE Architecture Specification](https://github.com/egallmann/ste-spec)) includes additional components not implemented in this repository: -- AI-DOC Fabric (attestation authority) -- STE Gateway (enforcement service) -- Trust Registry (verification service) -- **CEM** (Cognitive Execution Model) - 9-stage execution lifecycle (deferred per [E-ADR-003](../e-adr/E-ADR-003-CEM-Deferral.md)) -- Task Analysis Protocol (full protocol not implemented; basic entry point discovery exists) -- Validation Stack (CEM validation, static analysis) - -**See also:** [README.md](../../README.md) and [STE Specification](https://github.com/egallmann/ste-spec) - ---- - -### Why use ste-runtime instead of grep/text search? - -**Traditional approach (grep):** -- Returns raw text matches -- No context or relationships -- O(n) linear scans -- No semantic understanding - -**ste-runtime approach:** -- Returns structured semantic entities -- Full relationship graph -- O(1) semantic lookups -- Complete subgraph assembly in one query - -**Example:** -```bash -# Grep: 47 text matches, no context -grep -r "validateUser" - -# ste-runtime: Complete subgraph (45 nodes) with relationships -ste rss context "validateUser" -``` - ---- - -### Is ste-runtime production-ready? - -**Status:** Yes, production-ready for core use cases. - -- ✅ Core features implemented and tested -- ✅ Multi-language support (TypeScript, Python, CloudFormation, JSON, Angular, CSS) -- ✅ MCP server integration -- ✅ File watching (optional) -- ✅ Comprehensive test coverage - -**See:** [Implementation Status](../plan/e-adr-implementation-status.md) - ---- - -### What languages are supported? - -**Currently supported:** -- TypeScript/JavaScript -- Python -- CloudFormation -- JSON (configurable patterns) -- Angular (components, services, templates) -- CSS/SCSS (design tokens, styles) - -**See:** [Extractor Development Guide](../e-adr/E-ADR-008-Extractor-Development-Guide.md) for adding new languages. - ---- - -## Installation & Setup - -### Do I need to configure anything? - -**No configuration required** - ste-runtime works zero-configuration by default. - -It auto-detects: -- Project structure -- Languages used -- Source directories -- File patterns - -**Optional:** Create `ste.config.json` for customization. - -**See:** [Configuration Reference](./configuration-reference.md) - ---- - -### How do I install ste-runtime? - -**Option 1: Clone repository** -```bash -git clone https://github.com/egallmann/ste-runtime.git -cd ste-runtime -npm install -npm run build -``` - -**Option 2: Global install** -```bash -cd ste-runtime -npm install -g . -``` - -**See:** [README.md](../../README.md) for full installation instructions. - ---- - -### Where does ste-runtime store state? - -**Default location:** `.ste/state/` in your project root - -**Contains:** -- `graph/` - Semantic graph slices (YAML files) -- `validation/` - Validation reports -- `graph-metrics.json` - Graph topology analysis - -**Note:** Add `.ste/` to `.gitignore` (generated content). - ---- - -## RECON Questions - -### What is RECON? - -**RECON** (Reconciliation Engine) extracts semantic state from source code. - -**Process:** -1. Discovers source files -2. Extracts semantic assertions -3. Infers relationships -4. Normalizes into AI-DOC slices -5. Writes to `.ste/state/` - -**See:** [RECON README](../../instructions/RECON-README.md) - ---- - -### How long does RECON take? - -**Typical performance:** -- **256 files (864 slices):** ~9 seconds -- **49 files (TypeScript only):** ~2 seconds -- **Incremental:** ~200ms-2s (depends on files changed) - -**See:** [Performance Benchmarks](../reference/performance-benchmarks.md) - ---- - -### When should I run RECON? - -**Run RECON:** -- Before starting new features -- After pulling significant changes -- After refactoring modules -- When onboarding to a codebase -- Before planning architecture changes - -**With watchdog enabled:** RECON runs automatically on file changes. - ---- - -### What's the difference between incremental and full RECON? - -**Incremental RECON:** -- Processes only changed files -- Fast (200ms-2s) -- Use for regular updates - -**Full RECON:** -- Processes all files -- Slower (1-10s depending on size) -- Use for initial run or after major refactoring - -```bash -ste recon # Incremental (default) -ste recon --mode=full # Full reconciliation -``` - ---- - -### Why are slices content-addressable (hashed filenames)? - -**Benefits:** -- **Deterministic** - Same source → same filename -- **No collisions** - Long component names don't break filesystem -- **Performance** - 11-23% faster than descriptive names -- **Debugging** - Use RSS queries, not filenames - -**See:** [Content-Addressable Naming](../reference/content-addressable-naming.md) - ---- - -## RSS Questions - -### What is RSS? - -**RSS** (Runtime State Slicing) queries the semantic graph. RSS is a graph traversal protocol for deterministic context assembly. - -**Operations:** -- `search` - Find components by query -- `dependencies` - What does this depend on? -- `dependents` - What depends on this? -- `blast-radius` - Full impact analysis -- `context` - Assemble complete subgraph - -**See:** [RSS Usage Guide](../../instructions/RSS-USAGE-GUIDE.md) - ---- - -### How fast are RSS queries? - -**Performance:** -- **Structural queries:** <100ms (in-memory) -- **Context assembly:** 100-500ms (loads source files) -- **Graph stats:** <10ms (cached) - -**See:** [Performance Benchmarks](../reference/performance-benchmarks.md) - ---- - -### What's the difference between Layer 1 and Layer 2 queries? - -**Layer 1 (Structural):** -- Fast (<100ms) -- Returns metadata only (keys, relationships) -- No source code -- Use for: Entry point discovery, graph traversal - -**Layer 2 (Context Assembly):** -- Slower (100-500ms) -- Returns metadata + source code -- Loads files from filesystem -- Use for: LLM reasoning, implementation context - -**See:** [Two-Layer Context Assembly](../innovations/Two-Layer-Context-Assembly.md) - ---- - -### Why does blast-radius return empty results? - -**Possible causes:** -1. Component has no relationships -2. Graph edges not created (extractor issue) -3. Invalid component key - -**Solutions:** -```bash -# Verify component exists -ste rss lookup graph/function/myFunction - -# Check dependencies -ste rss dependencies graph/function/myFunction - -# Run RECON to update graph -ste recon -``` - ---- - -## MCP Server Questions - -### What is the MCP server? - -**MCP** (Model Context Protocol) server exposes ste-runtime tools to Cursor IDE. - -**Features:** -- 8 tools available -- Auto-discovery in Cursor -- File watching (optional) -- Always-fresh semantic state - -**See:** [MCP Setup Guide](./mcp-setup.md) - ---- - -### How do I set up MCP in Cursor? - -1. **Install ste-runtime globally:** - ```bash - npm install -g . - ``` - -2. **Configure Cursor:** - Edit `~/.cursor/mcp.json`: - ```json - { - "mcpServers": { - "ste-runtime": { - "command": "ste", - "args": ["watch", "--mcp"], - "cwd": "${workspaceFolder}" - } - } - } - ``` - -3. **Restart Cursor** - -**See:** [MCP Setup Guide](./mcp-setup.md) for detailed instructions. - ---- - -### Why aren't tools appearing in Cursor? - -**Common causes:** -1. Cursor not restarted (fully quit application) -2. MCP configuration error -3. `ste` not in PATH -4. State directory missing - -**Solutions:** -- See [MCP Setup Troubleshooting](./mcp-setup.md#troubleshooting) -- See [General Troubleshooting](./troubleshooting.md#mcp-server-issues) - ---- - -## Watchdog Questions - -### What is Watchdog? - -**Watchdog** monitors file changes and automatically triggers incremental RECON. - -**Features:** -- File watching (chokidar) -- Debouncing (500ms manual, 2s AI edits) -- Transaction detection (batches multi-file edits) -- Syntax validation - -**See:** [E-ADR-007](../e-adr/E-ADR-007-Watchdog-Authoritative-Mode.md) - ---- - -### Should I enable Watchdog? - -**Enable if:** -- You want automatic graph updates -- You're using MCP server -- You make frequent code changes - -**Disable if:** -- You prefer manual RECON -- You have performance concerns -- You're on a slow system - -**Default:** Disabled (opt-in) - ---- - -### Why is Watchdog triggering too many RECON runs? - -**Causes:** -- Debounce too short -- AI edit detection not working -- Transaction detection disabled - -**Solutions:** -```json -{ - "watchdog": { - "debounceMs": 1000, - "aiEditDebounceMs": 3000, - "transactionDetection": true - } -} -``` - ---- - -## Configuration Questions - -### Do I need ste.config.json? - -**No** - ste-runtime works zero-configuration by default. - -**Auto-generation:** -- `ste.config.json` is automatically generated on initialization -- You can modify it afterwards to customize behavior - -**When to customize:** -- You want to customize behavior -- You need specific file patterns -- You want to enable watchdog -- You have non-standard project structure - -**See:** [Configuration Reference](./configuration-reference.md) - ---- - -### How do I configure which files to extract? - -**Option 1: Source directories** -```json -{ - "sourceDirs": ["src", "lib"] -} -``` - -**Option 2: Ignore patterns** -```json -{ - "ignorePatterns": ["**/test/**", "**/spec/**"] -} -``` - -**See:** [Configuration Reference](./configuration-reference.md) - ---- - -### How do I configure JSON extraction? - -**Configure patterns:** -```json -{ - "jsonPatterns": { - "controls": "**/controls/**/*.json", - "schemas": "**/schemas/**/*.json", - "parameters": "**/parameters/**/*.json" - } -} -``` - -**See:** [E-ADR-005](../e-adr/E-ADR-005-JSON-Data-Extraction.md) - ---- - -## Extractor Questions - -### How do I add support for a new language? - -1. **Study existing extractors:** - - See [Extractor Development Guide](../e-adr/E-ADR-008-Extractor-Development-Guide.md) - -2. **Create extractor:** - - Implement extraction logic - - Emit semantic assertions - - Handle errors gracefully - -3. **Add validation tests:** - - See [Extractor Validation Quickstart](./extractor-validation-quickstart.md) - -4. **Register extractor:** - - Update discovery logic - - Add to `SupportedLanguage` enum - -**See:** [Contributing Guide](../../CONTRIBUTING.md#extractor-development) - ---- - -### Why aren't graph edges being created? - -**Causes:** -1. Extractor not emitting relationship assertions -2. Inference phase not processing relationships -3. Validation tests failing - -**Solutions:** -1. Run extractor validation tests -2. Check [Inference Phase Enhancements](../implementation/inference-phase-enhancements.md) -3. Verify extractor emits `elementType: 'import'` or `'dependency'` - -**See:** [Extractor Validation Status](../implementation/extractor-validation-status.md) - ---- - -## Performance Questions - -### RECON is slow. How can I speed it up? - -**Optimizations:** -1. Use incremental mode (default) -2. Reduce source directories -3. Add ignore patterns -4. Disable watchdog if not needed - -**See:** [Troubleshooting Guide](./troubleshooting.md#performance-issues) - ---- - -### RSS queries are slow. What can I do? - -**Optimizations:** -1. Reduce `rss.maxResults` in config -2. Reduce `rss.defaultDepth` -3. Use more specific queries -4. Check graph size (`ste rss stats`) - -**See:** [Troubleshooting Guide](./troubleshooting.md#performance-issues) - ---- - -## State & Data Questions - -### What is AI-DOC state? - -**AI-DOC** (AI-Documentation) is the semantic graph format. - -**Structure:** -- `graph/modules/` - Source file metadata -- `graph/functions/` - Function signatures -- `graph/classes/` - Class definitions -- `api/endpoints/` - REST/GraphQL endpoints -- `data/entities/` - Database schemas - -**Format:** YAML files with content-addressable naming - -**See:** [E-ADR-001](../e-adr/E-ADR-001-RECON-Provisional-Execution.md) - ---- - -### Can I edit AI-DOC slices manually? - -**No** - Slices are derived artifacts, always regenerated from source. - -**If you edit manually:** -- RECON will detect the change -- Phase 6 will self-heal (overwrite your edit) -- This is correct behavior - -**To change semantics:** Edit source code, then run RECON. - -**See:** [Authoritative Semantics Correction](../reference/authoritative-semantics-correction.md) - ---- - -### What are "orphaned slices"? - -**Orphaned slices** are slices whose source files have been deleted. - -**Behavior:** -- Automatically detected by RECON Phase 6 -- Automatically removed -- Logged as informational message - -**This is normal** - No action needed. - ---- - -## Security Questions - -### Is it safe to run RECON on my codebase? - -**Yes** - ste-runtime enforces strict boundaries: - -- Never scans outside project root -- Never scans parent directories -- Never scans home directories -- Validates all file paths - -**See:** [Boundary Enforcement](../security/boundary-enforcement.md) - ---- - -### What permissions does ste-runtime need? - -**Read-only access:** -- Read source files -- Read configuration -- Read project structure - -**Write access:** -- Write to `.ste/state/` directory only -- Write to `.ste/cache/` directory (for CloudFormation spec cache) - -**Network access:** -- CloudFormation spec fetching (optional, only when analyzing CloudFormation templates) -- **Cached:** Once fetched, the spec is cached for 7 days at `.ste/cache/cfn-spec.json` -- Falls back to expired cache if network is unavailable -- **Note:** The `.ste/cache/` directory is only created when CloudFormation files are detected and processed. If you don't see it, CloudFormation wasn't detected in your project. - ---- - -## Integration Questions - -### Can I use ste-runtime with other AI assistants? - -**Currently:** Cursor IDE via MCP - -**Future:** Other MCP-compatible assistants - -**Programmatic API:** Available for custom integrations - -**See:** [RSS Programmatic API](../../instructions/RSS-PROGRAMMATIC-API.md) - ---- - -### How do I integrate ste-runtime into my workflow? - -**Option 1: CLI** -```bash -ste recon -ste rss search "your query" -``` - -**Option 2: Programmatic API** -```typescript -import { initRssContext, search } from 'ste-runtime'; -const ctx = await initRssContext('.ste/state'); -const results = search(ctx, 'your query'); -``` - -**Option 3: MCP Server** -- Configure in Cursor -- Tools available automatically - ---- - -## Troubleshooting Questions - -### Where can I find help? - -1. **Documentation:** - - [Troubleshooting Guide](./troubleshooting.md) - - [Configuration Reference](./configuration-reference.md) - - [MCP Setup Guide](./mcp-setup.md) - -2. **Check logs:** - ```bash - ste recon --verbose - ste watch --mcp # For MCP issues - ``` - -3. **Report issues:** - - Include full error messages - - Include configuration (sanitized) - - Include version: `ste --version` - ---- - -### Common error messages? - -**"CRITICAL BOUNDARY VIOLATION"** -- RECON attempted to scan outside project root -- See [Boundary Enforcement](../security/boundary-enforcement.md) - -**"Failed to load current AI-DOC graph"** -- Incremental RECON failed, falling back to full recon -- This is automatic recovery - -**"Extractor failure: [language]"** -- Language extractor encountered error -- Check source files for syntax errors - -**See:** [Troubleshooting Guide](./troubleshooting.md#common-error-messages) - ---- - -## Still Have Questions? - -- **Documentation:** Check `documentation/` directory -- **E-ADRs:** See `documentation/e-adr/` for design decisions -- **Troubleshooting:** See [Troubleshooting Guide](./troubleshooting.md) -- **Contributing:** See [Contributing Guide](../../CONTRIBUTING.md) - ---- - -**Last Updated:** 2026-01-11 - diff --git a/documentation/guides/getting-started.md b/documentation/guides/getting-started.md deleted file mode 100644 index 3324923..0000000 --- a/documentation/guides/getting-started.md +++ /dev/null @@ -1,409 +0,0 @@ -# Getting Started with ste-runtime - -A step-by-step tutorial to get you up and running with ste-runtime, a component implementation of the [STE Specification](https://github.com/egallmann/ste-spec). - ---- - -## Prerequisites - -- **Node.js** 18.0.0 or higher -- **npm** or **yarn** -- A codebase to analyze (or use ste-runtime itself) - ---- - -## Step 1: Installation - -### Option A: Clone and Build - -```bash -# Clone the repository -git clone https://github.com/egallmann/ste-runtime.git -cd ste-runtime - -# Install dependencies -npm install - -# Build the project -npm run build -``` - -### Option B: Global Install - -```bash -cd ste-runtime -npm install -g . -``` - -**Verify installation:** -```bash -ste --version -# Should show: 1.0.0 -``` - ---- - -## Step 2: Run Your First RECON - -### Self-Documentation (Recommended First Step) - -Analyze ste-runtime itself to see how it works: - -```bash -cd ste-runtime -npm run recon:self -``` - -**What happens:** -1. RECON discovers TypeScript files -2. Extracts semantic assertions (functions, classes, imports) -3. Infers relationships (imports → graph edges) -4. Creates AI-DOC slices in `.ste-self/state/` -5. Reports completion - -**Expected output:** -``` -[RECON] Discovery: 256 files -[RECON] Extraction: 864 assertions -[RECON] Inference: 1,243 relationships -[RECON] Normalization: 864 slices -[RECON] Population: 864 slices written -[RECON] Validation: 0 errors, 3 warnings, 15 info -[RECON] Complete -``` - ---- - -## Step 3: Query the Graph - -### Check Graph Statistics - -```bash -npm run rss:stats -``` - -**Output:** -``` -Graph Statistics: - Components: 864 - Domains: 5 - Types: 12 - Relationships: 1,243 - Pattern: hierarchical - Recommended depth: 2 -``` - -### Search for Components - -```bash -# Search for authentication-related code -npm run rss -- search "authentication" - -# Search for MCP server -npm run rss -- search "mcp server" -``` - -**Output:** -``` -Found 3 components: - 1. graph/function/src/mcp/mcp-server.ts:initialize - 2. graph/module/src/mcp/mcp-server.ts - 3. graph/function/src/mcp/mcp-server.ts:start -``` - -### Get Dependencies - -```bash -# Find what a component depends on -npm run rss -- dependencies graph/function/src/mcp/mcp-server.ts:initialize -``` - -**Output:** -``` -Dependencies (12): - - graph/module/src/config/index.ts - - graph/module/src/rss/graph-loader.ts - - graph/function/src/rss/graph-loader.ts:loadGraph - ... -``` - -### Impact Analysis - -```bash -# See what would break if you change this component -npm run rss -- blast-radius graph/function/src/mcp/mcp-server.ts:initialize -``` - -**Output:** -``` -Blast Radius (45 components): - Direct dependencies: 12 - Transitive dependencies: 18 - Dependents: 15 - Total impact: 45 components -``` - ---- - -## Step 4: Use Your Own Project - -### Analyze Your Codebase - -```bash -# Navigate to your project -cd /path/to/your-project - -# Run RECON -ste recon --mode=full -``` - -**What happens:** -1. RECON auto-detects your project structure -2. Discovers source files -3. Extracts semantics based on detected languages -4. Creates `.ste/state/` directory - -**Note:** First run may take 5-15 seconds depending on project size. - -### Query Your Codebase - -```bash -# Search for components -ste rss search "user authentication" - -# Get context for a task -ste rss context "implement rate limiting" -``` - ---- - -## Step 5: Configure (Optional) - -### Generate Configuration File - -```bash -ste recon --init -``` - -This creates `ste.config.json` with defaults. - -### Customize Configuration - -Edit `ste.config.json`: - -```json -{ - "languages": ["typescript", "python"], - "sourceDirs": ["src", "lib"], - "ignorePatterns": ["**/test/**"], - "watchdog": { - "enabled": true, - "debounceMs": 500 - } -} -``` - -**See:** [Configuration Reference](./configuration-reference.md) for all options. - ---- - -## Step 6: Set Up MCP Server (Optional) - -### Install Globally - -```bash -cd ste-runtime -npm install -g . -``` - -### Configure Cursor - -Edit `~/.cursor/mcp.json` (or `C:\Users\YourName\.cursor\mcp.json` on Windows): - -```json -{ - "mcpServers": { - "ste-runtime": { - "command": "ste", - "args": ["watch", "--mcp"], - "cwd": "${workspaceFolder}" - } - } -} -``` - -### Restart Cursor - -Fully quit and restart Cursor. Tools should appear automatically. - -**See:** [MCP Setup Guide](./mcp-setup.md) for detailed instructions. - ---- - -## Step 7: Enable File Watching (Optional) - -### Enable Watchdog - -Edit `ste.config.json`: - -```json -{ - "watchdog": { - "enabled": true, - "debounceMs": 500, - "aiEditDebounceMs": 2000 - } -} -``` - -**What happens:** -- Watchdog monitors file changes -- Automatically triggers incremental RECON -- Keeps semantic graph always fresh - -**Note:** Watchdog is opt-in and disabled by default. - ---- - -## Common Workflows - -### Workflow 1: Understanding a Feature - -```bash -# 1. Search for the feature -ste rss search "authentication" - -# 2. Get full context -ste rss context "authentication flow" - -# 3. Check dependencies -ste rss dependencies graph/function/src/auth/authenticate.ts:authenticate - -# 4. See impact -ste rss blast-radius graph/function/src/auth/authenticate.ts:authenticate -``` - -### Workflow 2: Impact Analysis Before Changes - -```bash -# 1. Find the component -ste rss search "User entity" - -# 2. Check blast radius -ste rss blast-radius data/entity/User - -# 3. Review affected components -# 4. Make changes -# 5. Run RECON to update graph -ste recon -``` - -### Workflow 3: Finding Similar Code - -```bash -# 1. Find a component -ste rss search "UserService" - -# 2. Find similar implementations -ste rss -- get-related-implementations graph/module/src/services/user-service.ts -``` - ---- - -## Next Steps - -### Learn More - -- **Configuration:** [Configuration Reference](./configuration-reference.md) -- **Troubleshooting:** [Troubleshooting Guide](./troubleshooting.md) -- **FAQ:** [Frequently Asked Questions](./faq.md) -- **Glossary:** [Terminology](./glossary.md) - -### Advanced Topics - -- **Extractor Development:** [Extractor Development Guide](../e-adr/E-ADR-008-Extractor-Development-Guide.md) -- **Architecture:** [E-ADRs](../e-adr/) -- **Performance:** [Performance Benchmarks](../reference/performance-benchmarks.md) - -### Integration - -- **MCP Setup:** [MCP Setup Guide](./mcp-setup.md) -- **Programmatic API:** [RSS Programmatic API](../../instructions/RSS-PROGRAMMATIC-API.md) -- **CLI Usage:** [RSS Usage Guide](../../instructions/RSS-USAGE-GUIDE.md) - ---- - -## Troubleshooting - -### RECON finds no files - -**Check:** -- Files are in `sourceDirs` or project root -- Not in ignored directories -- Language is supported - -**See:** [Troubleshooting Guide](./troubleshooting.md#recon-issues) - -### RSS queries return empty - -**Check:** -- RECON has been run -- State directory exists (`.ste/state/`) -- Query is not too specific - -**See:** [Troubleshooting Guide](./troubleshooting.md#rss-query-issues) - -### MCP server not starting - -**Check:** -- `ste` is in PATH -- Configuration is correct -- Cursor is fully restarted - -**See:** [MCP Setup Guide](./mcp-setup.md#troubleshooting) - ---- - -## Example: Complete Workflow - -```bash -# 1. Install -cd ste-runtime -npm install -npm run build - -# 2. Test self-documentation -npm run recon:self - -# 3. Check stats -npm run rss:stats - -# 4. Search -npm run rss -- search "mcp" - -# 5. Get context -npm run rss -- context "MCP server implementation" - -# 6. Use in your project -cd /path/to/your-project -ste recon --mode=full -ste rss search "your feature" -``` - ---- - -## Getting Help - -- **Documentation:** Check `documentation/` directory -- **Troubleshooting:** [Troubleshooting Guide](./troubleshooting.md) -- **FAQ:** [Frequently Asked Questions](./faq.md) -- **Contributing:** [Contributing Guide](../../CONTRIBUTING.md) - ---- - -**Congratulations!** You're now ready to use ste-runtime. Start with self-documentation, then apply it to your own projects. - ---- - -**Last Updated:** 2026-01-11 - diff --git a/documentation/guides/glossary.md b/documentation/guides/glossary.md deleted file mode 100644 index f2c64ad..0000000 --- a/documentation/guides/glossary.md +++ /dev/null @@ -1,398 +0,0 @@ -# Glossary - -Definitions of terms and concepts used in ste-runtime, a component implementation of the [System of Thought Engineering (STE) Specification](https://github.com/egallmann/ste-spec). - -**Note:** This glossary is aligned with the [STE Specification Glossary](../../spec/ste-spec/glossary.md). For authoritative definitions, refer to the specification. - -**Important:** ste-runtime implements a subset of STE Runtime components (RECON and RSS). The complete STE Runtime architecture includes additional services (AI-DOC Fabric, STE Gateway, Trust Registry) not implemented in this repository. - ---- - -## A - -### AI-DOC - -**AI-Documentation** - The semantic graph format used by ste-runtime and the complete STE Runtime system. AI-DOC represents code as structured semantic entities (functions, classes, modules, etc.) stored as YAML files. - -**See:** [E-ADR-001](../e-adr/E-ADR-001-RECON-Provisional-Execution.md) - ---- - -### Assertion - -A semantic claim about source code. Assertions are extracted from source files and represent elements like functions, classes, imports, etc. - -**Types:** -- **Raw Assertion** - Initial extraction from source -- **Normalized Assertion** - Processed into AI-DOC format - ---- - -## B - -### Blast Radius - -The complete impact surface of changing a component. Includes all dependencies, dependents, and transitive relationships. - -**Usage:** -```bash -ste rss blast-radius graph/function/myFunction -``` - -**See:** [RSS Usage Guide](../../instructions/RSS-USAGE-GUIDE.md) - ---- - -### Boundary Enforcement - -Security mechanism that prevents RECON from scanning outside the allowed project scope. Ensures RECON never accesses parent directories, home directories, or system directories. - -**See:** [Boundary Enforcement](../security/boundary-enforcement.md) - ---- - -## C - -### CEM (Cognitive Execution Model) - -**Cognitive Execution Model** - The 9-stage execution lifecycle defined in the STE Specification that orchestrates governed AI cognition. Stages: Initialization → State Loading → Pre-Task Validation → Divergence Detection → Divergence Communication → Correction and Reconvergence → Reasoning Execution → Post-Task Validation → Final Convergence. - -**Status in ste-runtime:** Not implemented (deferred per [E-ADR-003](../e-adr/E-ADR-003-CEM-Deferral.md)). Human-in-loop provides implicit CEM governance during development. - -**See:** [STE Cognitive Execution Model](../../spec/ste-spec/execution/STE-Cognitive-Execution-Model.md) in the STE Specification - ---- - -### Context Assembly - -The process of bundling relevant semantic entities and source code for a specific task. Layer 2 operation that combines graph metadata with actual source files. - -**Usage:** -```bash -ste rss context "add rate limiting to auth endpoints" -``` - -**See:** [Two-Layer Context Assembly](../innovations/Two-Layer-Context-Assembly.md) - ---- - -### MVC (Minimally Viable Context) - -**Minimally Viable Context** - The bounded, task-relevant context assembled by RSS for LLM reasoning. MVC prevents context window overflow by including only the semantic entities and source code necessary for a specific task. - -**Implementation:** Implemented in ste-runtime via the `assembleContext` function in RSS operations. Takes entry points and traverses the graph to assemble minimal viable context with configurable depth and node limits. - -**See:** [RSS Operations](../../src/rss/rss-operations.ts), [STE Architecture Specification](../../spec/ste-spec/architecture/STE-Architecture.md) Section 4.6 - ---- - -### Content-Addressable Naming - -Naming scheme where slice filenames are SHA-256 hashes of their content. Provides deterministic, collision-free naming. - -**Benefits:** -- Deterministic (same content → same filename) -- No filesystem limits -- Performance improvement (11-23%) - -**See:** [Content-Addressable Naming](../reference/content-addressable-naming.md) - ---- - -## D - -### Dependency - -A relationship where one component depends on another. Examples: imports, function calls, resource references. - -**Types:** -- **Import** - Module-to-module dependency -- **Dependency** - Generic dependency (DependsOn, injection, etc.) - -**See:** [Inference Phase Enhancements](../implementation/inference-phase-enhancements.md) - ---- - -### Domain - -A category of semantic entities. Examples: `graph` (code structure), `api` (endpoints), `data` (entities), `infrastructure` (resources). - -**13-Domain Model:** -- `graph` - Code structure (modules, functions, classes) -- `api` - API endpoints -- `data` - Data entities -- `infrastructure` - Cloud resources -- `frontend` - UI components -- `backend` - Server-side code -- And 7 more... - ---- - -## E - -### E-ADR - -**Exploratory Architectural Decision Record** - Documents architectural decisions made during development. E-ADRs are exploratory (reversible) and may graduate to formal ADRs. - -**See:** [E-ADR Directory](../e-adr/) - ---- - -### Extractor - -A language-specific module that extracts semantic assertions from source code. Each supported language has an extractor. - -**Examples:** -- TypeScript Extractor - AST-based extraction -- Python Extractor - Subprocess-based extraction -- CloudFormation Extractor - Template parsing - -**See:** [Extractor Development Guide](../e-adr/E-ADR-008-Extractor-Development-Guide.md) - ---- - -## G - -### Graph Edge - -A relationship between two semantic entities in the graph. Edges represent dependencies, imports, calls, etc. - -**Creation:** -- Extracted from source code (imports, dependencies) -- Inferred by inference phase -- Stored in slice `references` field - -**See:** [Extractor Validation Status](../implementation/extractor-validation-status.md) - ---- - -### Graph Metrics - -Analysis of graph topology (structure, depth, patterns). Used to optimize query parameters like traversal depth. - -**Metrics:** -- Component count -- Average depth -- Graph pattern (flat, hierarchical, etc.) -- Recommended depth - -**See:** [Graph Topology Analyzer](../../src/mcp/graph-topology-analyzer.ts) - ---- - -## I - -### Incremental RECON - -RECON mode that processes only changed files. Faster than full RECON, used for regular updates. - -**Usage:** -```bash -ste recon # Incremental (default) -``` - -**See:** [RECON README](../../instructions/RECON-README.md) - ---- - -### Inference Phase - -RECON Phase 3 that infers relationships from raw assertions. Converts import/dependency metadata into graph edges. - -**Process:** -1. Collects relationship assertions -2. Resolves module/dependency references -3. Creates graph edges -4. Establishes bidirectional relationships - -**See:** [Inference Phase Enhancements](../implementation/inference-phase-enhancements.md) - ---- - -## M - -### MCP - -**Model Context Protocol** - Standardized protocol for AI assistants to discover and use tools. ste-runtime implements MCP to expose RSS operations to Cursor IDE. - -**See:** [MCP Setup Guide](./mcp-setup.md) - ---- - -### Module - -A source file represented in the semantic graph. Contains metadata about exports, imports, and file-level information. - -**ID Format:** `module-src-path-to-file` - ---- - -## N - -### Normalization - -RECON Phase 4 that converts raw assertions into normalized AI-DOC slices. Ensures consistent structure and content-addressable naming. - -**Process:** -1. Validates assertions -2. Generates slice IDs -3. Creates content-addressable filenames -4. Writes YAML files - ---- - -## O - -### Orphaned Slice - -A slice whose source file has been deleted. Detected by RECON Phase 6 and automatically removed. - -**Behavior:** -- Informational message (not an error) -- Automatically cleaned up -- No action needed - ---- - -## R - -### RECON - -**Reconciliation Engine** - The semantic extraction pipeline that generates AI-DOC state from source code. - -**Phases:** -1. Discovery - Find source files -2. Extraction - Extract semantic assertions -3. Inference - Infer relationships -4. Normalization - Create slices -5. Population - Write to disk -6. Validation - Self-healing -7. Self-Validation - Generate reports - -**See:** [RECON README](../../instructions/RECON-README.md) - ---- - -### RSS - -**Runtime State Slicing** - Graph traversal protocol for deterministic context assembly. Starts at entry points, traverses explicit references with depth bounds, assembles Minimally Viable Context. Includes convergence validation for multi-entry traversals. Deterministic: same entry points → same traversal → same context. - -**Operations:** -- `search` - Find components -- `dependencies` - Forward traversal -- `dependents` - Backward traversal -- `blast-radius` - Impact analysis -- `context` - Context assembly - -**Authority:** [STE Specification Glossary (ste-spec)](../../spec/ste-spec/glossary.md) - -**See:** [RSS Usage Guide](../../instructions/RSS-USAGE-GUIDE.md) - ---- - -## S - -### Self-Healing - -RECON Phase 6 mechanism that automatically fixes corrupted or manually-edited slices. Regenerates slices from source when they don't match. - -**Behavior:** -- Detects slice-source mismatches -- Regenerates from source -- No conflicts (slices are derived artifacts) - -**See:** [Self-Healing Implementation](../reference/phase-6-self-healing-implementation.md) - ---- - -### Slice - -A single semantic entity in AI-DOC format. Stored as a YAML file with content-addressable naming. - -**Structure:** -- `_slice` - Metadata (ID, domain, type) -- `element` - Semantic element data -- `provenance` - Source information - -**Properties:** -- Derived artifact (always regenerated from source) -- Content-addressable filename -- Self-healing (corruption automatically fixed) - -**See:** [E-ADR-001](../e-adr/E-ADR-001-RECON-Provisional-Execution.md) - ---- - -### Source of Truth - -**Source code is the only source of truth.** AI-DOC slices are derived artifacts that always reflect source code. Manual edits to slices are considered corruption and are automatically overwritten. - -**See:** [Authoritative Semantics Correction](../reference/authoritative-semantics-correction.md) - ---- - -## T - -### Transaction Detection - -Watchdog feature that detects multi-file edits and batches them into a single RECON run. Prevents excessive RECON triggers during refactoring. - -**Window:** 3 seconds (default) - -**See:** [E-ADR-007](../e-adr/E-ADR-007-Watchdog-Authoritative-Mode.md) - ---- - -### Two-Layer Architecture - -Design pattern that separates fast structural queries (Layer 1) from rich context assembly (Layer 2). - -**Layer 1:** Metadata only, <100ms -**Layer 2:** Metadata + source code, 100-500ms - -**See:** [Two-Layer Context Assembly](../innovations/Two-Layer-Context-Assembly.md) - ---- - -## V - -### Validation - -RECON Phase 7 that generates validation reports. Non-blocking, report-only validation that surfaces observations without halting execution. - -**Categories:** -- ERROR - Critical issues -- WARNING - Potential issues -- INFO - Informational findings - -**See:** [E-ADR-002](../e-adr/E-ADR-002-RECON-Self-Validation.md) - ---- - -## W - -### Watchdog - -File watching system that monitors project files and automatically triggers incremental RECON on changes. - -**Features:** -- Debouncing (500ms manual, 2s AI edits) -- Transaction detection -- Syntax validation -- Opt-in (disabled by default) - -**See:** [E-ADR-007](../e-adr/E-ADR-007-Watchdog-Authoritative-Mode.md) - ---- - -## Related Documentation - -- [Configuration Reference](./configuration-reference.md) -- [Troubleshooting Guide](./troubleshooting.md) -- [FAQ](./faq.md) -- [E-ADRs](../e-adr/) - ---- - -**Last Updated:** 2026-01-11 - diff --git a/documentation/guides/mcp-setup.md b/documentation/guides/mcp-setup.md index c87ec42..a2f1a2c 100644 --- a/documentation/guides/mcp-setup.md +++ b/documentation/guides/mcp-setup.md @@ -471,7 +471,7 @@ This design minimizes token usage while providing rich context. ## See Also -- [E-ADR-011: MCP Server Implementation](../e-adr/E-ADR-011-ste-runtime-MCP-Server.md) +- [ADR-P-0004: ste-runtime MCP Server Implementation](../../adrs/rendered/ADR-P-0004.md) - [RSS Usage Guide](../instructions/RSS-USAGE-GUIDE.md) - [RECON README](../instructions/RECON-README.md) @@ -479,3 +479,4 @@ This design minimizes token usage while providing rich context. + diff --git a/documentation/guides/pre-commit-hook-setup.md b/documentation/guides/pre-commit-hook-setup.md deleted file mode 100644 index c357c75..0000000 --- a/documentation/guides/pre-commit-hook-setup.md +++ /dev/null @@ -1,131 +0,0 @@ -# Pre-Commit Hook Implementation - -## Summary - -A pre-commit git hook has been successfully implemented to enforce code quality and stability. The hook ensures that only stable, tested code can ever be committed to the repository. - -## What Gets Checked - -The hook runs five checks before allowing a commit: - -1. **Build** - `npm run build` - - Ensures TypeScript compilation succeeds - - Prevents syntax and type errors from being committed - -2. **RECON Self-Check** - `npm run recon:self` - - Validates RECON functionality - - Ensures documentation generation works correctly - -3. **Tests** - `npm test` - - Runs all test suites - - Prevents commits if any tests fail - -4. **RSS Stats** - `npm run rss:stats` - - Validates RSS functionality - - Ensures semantic search capabilities are intact - -5. **Test Coverage** - `npm run test:coverage` - - Verifies test coverage meets minimum threshold - - Current setting: **50%** statement coverage (your current level: 51.42%) - -## Files Created - -- `.husky/pre-commit` - Pre-commit hook (tracked in git) -- `package.json` - Added `husky` dev dependency and `prepare` script - -**Note:** Hooks are managed by [husky](https://typicode.github.io/husky/) and automatically installed when you run `npm install`. - -## Configuration - -### Adjusting Coverage Threshold - -The current minimum coverage is set to **50%** to prevent regression. To change it: - -Edit `.husky/pre-commit`: -```bash -MIN_COVERAGE=50 # Change this value -``` - -### Recommended Coverage Levels - -- **50%** - Current setting, prevents regression -- **60%** - Moderate improvement target -- **70%** - Good coverage standard -- **80%+** - Excellent coverage (industry best practice) - -## Usage - -The hook runs automatically on every `git commit`. If any check fails, the commit will be blocked with a clear error message indicating what needs to be fixed. - -### Example Output - -``` -[1/5] Building project... -[OK] Build successful - -[2/5] Running RECON self-check... -[OK] RECON self-check passed - -[3/5] Running tests... -[OK] All tests passed - -[4/5] Running RSS stats... -[OK] RSS stats check passed - -[5/5] Checking test coverage... -[OK] Test coverage is 51.42% (minimum: 50%) - -======================================== -All pre-commit checks passed! -======================================== -``` - -## Bypassing the Hook - -In exceptional circumstances only: - -```bash -git commit --no-verify -``` - -**Warning:** Only use this in emergencies. The hook exists to maintain code quality. - -## Installation - -Hooks are automatically installed when you run: -```bash -npm install -``` - -The `prepare` script in `package.json` runs `husky` to set up the hooks. - -**Manual installation (if needed):** -```bash -npx husky install -``` - -## Testing - -The hook has been tested and confirmed working: -- All checks execute successfully -- Current coverage (51.42%) exceeds minimum threshold (50%) -- Proper error handling and clear output messages - -## Philosophy - -This implementation embodies your requirement: **"Only stable code can ever be committed"** - -By enforcing these checks at commit time, the hook creates a safety net that: -- Catches build errors before they enter the repository -- Ensures all tests pass consistently -- Validates that RECON and RSS functionality remain intact -- Prevents test coverage regression -- Makes the codebase more reliable and maintainable - -## Next Steps - -1. The hook is ready to use immediately -2. Consider gradually increasing the coverage threshold as you add more tests -3. All contributors will automatically get the hooks when they run `npm install` -4. The hook is tracked in git (`.husky/pre-commit`) so it's version-controlled - diff --git a/documentation/guides/troubleshooting.md b/documentation/guides/troubleshooting.md index 2f74083..d987651 100644 --- a/documentation/guides/troubleshooting.md +++ b/documentation/guides/troubleshooting.md @@ -386,8 +386,8 @@ $ ste rss blast-radius graph/function/myFunction ``` 3. **Verify extractor created edges:** - - See [Extractor Validation Guide](./extractor-validation-quickstart.md) - - Run validation tests + - Review extractor tests + - See [PROJECT metadata](../../PROJECT.yaml) 4. **Check inference phase:** - Ensure imports/dependencies are extracted @@ -940,7 +940,8 @@ Components exist but no relationships/edges - See [Inference Phase Enhancements](../implementation/inference-phase-enhancements.md) 3. **Verify extractor emits relationships:** - - See [Extractor Development Guide](../e-adr/E-ADR-008-Extractor-Development-Guide.md) + - See [Inference Phase Enhancements](../implementation/inference-phase-enhancements.md) + - See [PROJECT metadata](../../PROJECT.yaml) --- @@ -1018,8 +1019,9 @@ If you encounter an issue not covered here: - [MCP Setup Guide](./mcp-setup.md) - [RECON README](../instructions/RECON-README.md) -3. **Check E-ADRs:** - - [E-ADR Directory](../e-adr/) +3. **Check ADRs:** + - [ADR Directory](../../adrs/) + - [Rendered ADR Docs](../../adrs/rendered/) 4. **Report issues:** - Include full error messages @@ -1056,3 +1058,4 @@ If you encounter an issue not covered here: **Last Updated:** 2026-01-11 + diff --git a/documentation/implementation/extractor-validation-status.md b/documentation/implementation/extractor-validation-status.md index dd2757e..95adac6 100644 --- a/documentation/implementation/extractor-validation-status.md +++ b/documentation/implementation/extractor-validation-status.md @@ -206,10 +206,10 @@ Validation tests have been created for all extractors per E-ADR-013. These tests ## References -- **E-ADR-013:** Extractor Validation Requirements (specification) -- **E-ADR-008:** Extractor Development Guide (how to build extractors) +- **ADR-P-0005:** Extractor Validation Requirements (specification) +- **PROJECT Metadata:** `PROJECT.yaml` - **Test Utilities:** `src/test/extractor-test-utils.ts` -- **Quick Start:** `documentation/guides/extractor-validation-quickstart.md` +- **System Overview:** `SYSTEM-OVERVIEW.md` --- diff --git a/documentation/implementation/inference-phase-enhancements.md b/documentation/implementation/inference-phase-enhancements.md index ff00d3b..33b9562 100644 --- a/documentation/implementation/inference-phase-enhancements.md +++ b/documentation/implementation/inference-phase-enhancements.md @@ -303,9 +303,9 @@ ste rss-context "mcp server implementation" --depth 3 --max 100 ## Documentation Updates -1. **E-ADR-013:** Extractor Validation Requirements (created) +1. **ADR-P-0005:** Extractor Validation Requirements (created) 2. **extractor-validation-status.md:** Updated with all tests passing -3. **extractor-validation-quickstart.md:** Developer guide (created) +3. **PROJECT.yaml / SYSTEM-OVERVIEW.md:** Current contributor orientation and repo metadata 4. **inference-phase-enhancements.md:** This document (created) --- diff --git a/documentation/innovations/Two-Layer-Context-Assembly.md b/documentation/innovations/Two-Layer-Context-Assembly.md deleted file mode 100644 index 0ffc486..0000000 --- a/documentation/innovations/Two-Layer-Context-Assembly.md +++ /dev/null @@ -1,487 +0,0 @@ -# Potentially Novel: Two-Layer Context Assembly for AI Code Understanding - -**Date:** 2026-01-11 -**Status:** Exploratory Research - Seeking Validation -**Related:** E-ADR-011 - ---- - -## Summary - -We've designed a two-layer architectural pattern for AI-assisted code understanding that addresses the fundamental token efficiency vs. precision tradeoff in semantic code analysis. - -**Novelty Status:** We believe this approach may be novel based on our preliminary research, but we have not yet conducted exhaustive prior art review or received peer feedback. We actively welcome corrections and references to similar work. - -> **Important:** The purpose of this document is to articulate our design thinking and identify what *might* be innovative, not to make definitive claims. Validation comes from building it, community feedback, and peer review—not from our own assessment. - -### The Core Problem - -Existing semantic code tools face a dilemma: - -| Approach | Problem | -|----------|---------| -| **Metadata Only** (LSP, Sourcegraph schema) | LLM lacks implementation details, can't reason about behavior | -| **Full Source** (Copilot, file-based retrieval) | Token budget explodes, irrelevant code floods context | -| **RAG on Code** (embeddings + similarity) | No structural understanding, misses dependencies | - -### Our Two-Layer Solution - -**Layer 1: RSS (Semantic Graph Engine)** -- Fast structural queries (<100ms) -- Returns component keys and relationships -- In-memory graph traversal -- No source code in responses - -**Layer 2: Context Assembly** -- Uses RSS queries to identify relevant slices -- Loads source code ONLY for identified components -- Injects applicable domain invariants -- Optimized for LLM token budget - -## Validation Status - -### What We've Checked -- ✅ GitHub repositories (semantic code analysis, AI coding tools) -- ✅ Major products: Sourcegraph, GitHub Copilot, CodeQL, LSP implementations -- ✅ Recent blog posts and technical articles (2024-2026) -- ✅ MCP ecosystem documentation and example servers - -### What We Haven't Checked Yet -- ❌ Full academic literature review (ACM Digital Library, IEEE Xplore, Google Scholar) -- ❌ Patent databases (USPTO, Google Patents, WIPO) -- ❌ Research lab publications (Google Research, Microsoft Research, Meta AI) -- ❌ Unpublished work (arXiv preprints, technical reports) -- ❌ Industry whitepapers and internal research - -### How You Can Help -If you know of prior work that combines: -1. Real-time semantic graph maintenance -2. Two-layer context assembly (structural → source) -3. Token budget optimization for LLMs -4. Native AI assistant integration - -**Please let us know!** We'd love to learn from it and cite it properly. - ---- - -### Why This Approach Is Useful (Regardless of Novelty) - -#### Composable Queries -LLMs can iteratively refine context: - -``` -Step 1: search("authentication") → 50 components -Step 2: get_dependents("api/function/login") → 8 components -Step 3: assemble_context("login error handling") → source for 3 files -``` - -Each step narrows scope using cheap graph queries, only loading source at the end. - -#### Token Efficiency - -**Traditional approach:** -``` -Query: "Fix auth bug" -Response: [Entire auth module: 50 files, 15K lines, 80K tokens] -Result: 95% irrelevant code in context -``` - -**Two-layer approach:** -``` -Query: "Fix auth bug" -RSS queries: 3 steps, 150ms, 200 tokens of metadata -Context assembly: 3 files, 240 lines, 1.2K tokens of source -Result: 98% reduction in tokens, 100% relevant -``` - -#### Real-Time Maintenance - -Unlike static analysis tools: -- File watcher + incremental RECON keeps graph fresh -- Queries always against current state -- No stale indexes or rebuild delays - -#### Native AI Integration - -Via MCP protocol: -- AI assistants can discover tools automatically -- No custom integration per IDE -- Composable tool chains (search → filter → assemble) - ---- - -## Prior Art Analysis (Preliminary) - -**Disclaimer:** This is a preliminary analysis based on our current knowledge. We have not conducted exhaustive research and may have missed relevant work. - -### Systems We've Examined - -| System | Semantic Graph | Source Loading | Real-Time | AI-Native | -|--------|---------------|----------------|-----------|-----------| -| **Sourcegraph** | ✅ | Full files | ❌ | ❌ | -| **GitHub Copilot** | ❌ | Full files | ❌ | ✅ | -| **CodeQL** | ✅ | Query results | ❌ | ❌ | -| **LSP** | ✅ | On-demand | ✅ | ❌ | -| **STE (ours)** | ✅ | Targeted slices | ✅ | ✅ | - -### What Appears to Be Different (Based on Our Research) - -1. **Two-layer context assembly:** We haven't found systems that separate fast structural queries from targeted source loading -2. **Real-time semantic graph:** LSP is real-time but per-file; we maintain cross-project graph -3. **MCP-native:** We haven't seen semantic code tools designed specifically for AI assistant integration -4. **Token-optimized:** Explicitly designed for LLM context budget constraints -5. **Adaptive tool parameters:** Dynamically adjusts traversal defaults based on graph topology analysis - -**Note:** These observations are based on publicly available information. Similar approaches may exist in: -- Proprietary systems (Google internal tools, etc.) -- Academic prototypes not widely publicized -- Recent work we haven't discovered yet - ---- - -## Performance Characteristics - -### Layer 1 (RSS) Benchmarks - -| Operation | Typical Time | Returns | -|-----------|--------------|---------| -| `search(query)` | 30-80ms | Slice keys | -| `get_dependencies(key)` | 15-40ms | Slice keys | -| `get_blast_radius(key)` | 50-120ms | Slice keys | - -### Layer 2 (Context Assembly) Benchmarks - -| Operation | Typical Time | Returns | -|-----------|--------------|---------| -| `assemble_context(query)` | 200-500ms | Slices + source | -| 3 files, 300 lines | 250ms | ~1.5K tokens | -| 10 files, 1000 lines | 600ms | ~5K tokens | - -### Comparison: Traditional Full-File Loading - -| Scope | Traditional | Two-Layer | Savings | -|-------|-------------|-----------|---------| -| "Auth module" | 50 files, 80K tokens | 3 files, 1.2K tokens | 98.5% | -| "API handlers" | 120 files, 200K tokens | 8 files, 4K tokens | 98% | -| "Database layer" | 35 files, 60K tokens | 5 files, 2.5K tokens | 95.8% | - ---- - -## Adaptive Tool Parameters - -A complementary innovation: **Tool parameters that adapt to codebase structure**. - -### The Problem -Static defaults for traversal depth are always wrong: -- `depth=2` works for layered monoliths -- `depth=4` needed for deep React component trees -- `depth=3` appropriate for microservices - -Developers shouldn't need to guess or configure this. - -### Our Solution -Analyze graph topology at runtime and automatically adjust defaults: - -```typescript -// Server startup -const metrics = await analyzeGraphTopology(graph); -// Pattern: component-tree, Avg depth: 4.7 -// → Set default depth=4 - -// Update tool schemas -tools.get_dependencies.default.depth = 4; -tools.get_dependents.default.depth = 4; -``` - -### Architecture Pattern Detection - -| Pattern | Detection Criteria | Default Depth | -|---------|-------------------|---------------| -| **component-tree** | Deep (>5 levels), narrow (<5 deps) | 4 | -| **microservices** | Wide (>10 deps), shallow (<3 levels) | 3 | -| **layered** | Moderate (2-4 levels), boundaries | 2 | -| **flat** | Minimal (<2 levels, <3 deps) | 2 | -| **mixed** | No clear pattern | 3 | - -### Self-Adjusting Behavior - -```bash -# React frontend added to Python backend -[MCP Server] Graph structure changed significantly - - Old: layered, depth=2 - - New: mixed, depth=3 -[MCP Server] Tool defaults updated -``` - -The system **learns your architecture** and adjusts automatically. - -### Why This Matters - -1. **Zero configuration** - Works optimally out-of-the-box -2. **Transparent** - Logs explain why a depth was chosen -3. **Self-improving** - Adapts as codebase evolves -4. **Prevents errors** - Too-shallow depth misses context, too-deep explodes token budget - -**To our knowledge**, no semantic code tool dynamically adjusts query parameters based on analyzed graph topology. - ---- - -## CEM Integration - -The two-layer architecture maps naturally to CEM execution stages: - -``` -CEM Stage 1: Task Understanding -└─> No context needed (just user query) - -CEM Stage 2: State Loading -└─> RSS Layer: Identify relevant components (structural) - • search(task_keywords) → candidate slices - • get_dependencies/dependents → expand scope - • Output: List of relevant slice keys - -CEM Stage 3: Analysis -└─> Context Assembly Layer: Load implementations - • assemble_context(refined_query, includeSource=true) - • Load source for ONLY the slices identified in Stage 2 - • Inject domain invariants for relevant components - • Output: Rich context (semantic + source + constraints) - -CEM Stage 4-9: Execution -└─> LLM reasons over assembled context with invariants -``` - -**Key insight:** Don't load source until you know what's relevant (Stage 2 → Stage 3). - ---- - -## Potential Applications Beyond Code - -This pattern could apply to any domain with: -1. Large corpora requiring semantic understanding -2. Token budget constraints (LLM context limits) -3. Structural relationships between entities -4. Need for real-time updates - -**Examples:** -- **Legal documents:** Graph of citations → targeted clause retrieval -- **Medical records:** Patient relationship graph → specific record loading -- **Research papers:** Citation graph → relevant section extraction -- **Enterprise knowledge bases:** Ontology graph → document retrieval - ---- - -## Future Research Directions - -### 1. Adaptive Layer Selection -Could the system automatically decide which layer to use based on query complexity? - -```typescript -// Simple query: Layer 1 only -"What depends on UserAuth?" → RSS layer sufficient - -// Complex query: Auto-escalate to Layer 2 -"How is UserAuth implemented?" → Context Assembly needed -``` - -### 2. Multi-Hop Context Assembly -Can we compose multiple context assembly operations? - -```typescript -// Find pattern A -const patternA = await assembleContext("error handling pattern"); - -// Find similar to pattern A -const similar = await getRelatedImplementations(patternA.slices[0].key); - -// Contrast implementations -const comparison = await assembleContext(`compare ${patternA.key} and ${similar[0].key}`); -``` - -### 3. Incremental Context Loading -Can Layer 2 return partial results for very large queries? - -```typescript -// Stream results as they're assembled -for await (const slice of assembleContextStream(query)) { - // LLM can start reasoning before full context loaded - yield slice; -} -``` - -### 4. Context Budget Optimization -Can we use RL to learn optimal query chains for given token budgets? - -``` -Given: Task T, Budget B (tokens), Time Limit L (ms) -Learn: Optimal sequence of RSS + Context Assembly queries -Maximize: Task success rate -``` - ---- - -## Validation Strategy - -### Hypothesis 1: Token Efficiency -**Claim:** Two-layer approach reduces context tokens by 90%+ vs. full-file loading - -**Test:** -1. Collect 100 real developer tasks -2. Measure tokens with traditional full-file retrieval -3. Measure tokens with two-layer approach -4. Compare task success rates - -**Expected Result:** 90%+ token reduction, no accuracy loss - -### Hypothesis 2: Composability Value -**Claim:** Multi-step queries (RSS → narrow → assemble) produce better context than single-step - -**Test:** -1. Compare single `assemble_context(query)` vs. guided 3-step refinement -2. Measure precision (% relevant code) and recall (% needed code included) -3. User study: developers rate context quality - -**Expected Result:** 3-step > single-step for complex tasks - -### Hypothesis 3: Real-Time Advantage -**Claim:** Real-time graph maintenance provides fresher state than index-rebuild systems - -**Test:** -1. Measure staleness: time between file change and query seeing update -2. Compare: STE (incremental) vs. Sourcegraph (index rebuild) -3. Track developer frustration incidents (querying stale state) - -**Expected Result:** STE: <1s staleness, Sourcegraph: 5-30s - ---- - -## Publication Potential (If Novel) - -**Important:** Only pursue publication AFTER validating novelty through community feedback and literature review. - -### Possible Venues (If Validated) - -**Systems/Software Engineering:** -- ICSE (International Conference on Software Engineering) - Top tier, ~20% acceptance -- FSE (Foundations of Software Engineering) - Top tier -- ASE (Automated Software Engineering) - Competitive - -**AI/ML (if we develop optimizations):** -- NeurIPS (if learning-based optimizations) - Very competitive -- ICLR (context optimization as RL problem) - Very competitive -- AAAI (AI for software engineering track) - Competitive - -**Industry/Systems:** -- OSDI (Operating Systems Design) - "OS for AI cognition" angle - Very competitive -- Strange Loop (Industry talk) - More accessible -- Blog post series - Immediate feedback - -### Realistic Timeline - -**Before considering publication:** -1. Build working implementation (2-3 months) -2. Validate token efficiency claims with real users (1-2 months) -3. Comprehensive literature review (1-2 weeks) -4. Community feedback (HN, Reddit, Twitter) (1 month) -5. IF still appears novel → draft paper - -**Publication timeline:** -- Workshop paper (easier): 2-3 months after submission -- Conference paper: 6-12 months (multiple revision cycles likely) -- Industry blog: Immediate - -### Potential Paper Title (If We Get There) -"Two-Layer Context Assembly: Efficient Semantic Code Understanding for Large Language Models" - -### What Would Need to Be Contributions -1. Architectural pattern (if validated as novel) -2. Real-time semantic graph maintenance -3. Empirical validation of token reduction -4. Open-source implementation (ste-runtime) -5. Case studies with real developers - -**Reality check:** Most papers get rejected on first submission. This is normal. Community feedback and iteration are part of the process. - ---- - -## IP Considerations - -**Disclaimer:** This is not legal advice. Consult a patent attorney before making IP decisions. - -### Preliminary Patentability Thoughts - -**Could potentially be patentable IF novel:** -1. Two-layer architecture (structural queries → targeted source loading) -2. Incremental RECON algorithm for graph maintenance -3. Token budget optimization via semantic routing -4. CEM integration with layered context assembly - -**Known prior art to consider:** -- LSP provides real-time semantic analysis (but not cross-file graph) -- Sourcegraph provides semantic search (but returns full files) -- RAG systems provide targeted retrieval (but not structurally aware) - -**Unknown factors:** -- Proprietary systems at large companies (Google, Microsoft, etc.) -- Existing patents we haven't searched yet -- Academic prototypes that may have published similar ideas - -**Realistic assessment:** -- We don't know if this is patentable without comprehensive prior art search -- Even if novel, patent process is expensive ($10K-30K) and time-consuming (2-4 years) -- Open-source strategy may be more valuable than patents for this domain - -**Recommendation:** -- Focus on building and open-sourcing first -- Document prior art searches as you go -- Consider provisional patent later IF validation confirms novelty AND commercial value warrants it -- Community adoption may be more valuable than IP protection - ---- - -## Next Steps - -### Phase 1: Build It (Immediate Priority) -- [ ] Implement Layer 1 (RSS) MCP tools -- [ ] Implement Layer 2 (Context Assembly) MCP tools -- [ ] Build benchmarking harness for token efficiency claims -- [ ] Document example query chains -- [ ] Get it working end-to-end - -### Phase 2: Validate Novelty (Before Any Claims) -- [ ] Do comprehensive literature search (dedicate 2-4 hours) -- [ ] Search patent databases (Google Patents, USPTO) -- [ ] Post "Show HN" or similar for community feedback -- [ ] Email researchers in code understanding space -- [ ] Update this document with findings - -### Phase 3: Validate Utility (Even If Not Novel) -- [ ] Collect real-world usage data (token savings, query patterns) -- [ ] User study with developers -- [ ] Measure actual performance vs. claims -- [ ] Document what works and what doesn't - -### Phase 4: Share (Only After Validation) -- [ ] Publish blog post explaining architecture -- [ ] Open-source announcement -- [ ] Conference talk submission (if validated) -- [ ] Paper submission (if novel AND validated) - -### Decision Points -- **After Phase 2:** Is this actually novel? (Update claims accordingly) -- **After Phase 3:** Is this actually useful? (Might matter more than novelty) -- **After Phase 4:** Community response? (Let them tell us what's interesting) - ---- - -## References - -- [E-ADR-011: ste-runtime MCP Server Implementation](../e-adr/E-ADR-011-ste-runtime-MCP-Server.md) -- [E-ADR-007: Watchdog Authoritative Mode](../e-adr/E-ADR-007-Watchdog-Authoritative-Mode.md) -- [STE Architecture Specification](../../spec/ste-spec/architecture/STE-Architecture.md) - ---- - -**Contributors:** Erik Gallmann, Claude (Anthropic) -**License:** MIT (documentation), same as ste-runtime project - diff --git a/documentation/innovations/prior-art-research.md b/documentation/innovations/prior-art-research.md deleted file mode 100644 index bf56e0a..0000000 --- a/documentation/innovations/prior-art-research.md +++ /dev/null @@ -1,477 +0,0 @@ -# Prior Art Research: Semantic Code Graphs & LLM Context Assembly - -**Research Date:** January 11, 2026 -**Topics:** Semantic code graphs, LLM context assembly, code intelligence, software engineering + ML - ---- - -## Executive Summary - -This document compiles research on semantic code analysis, context assembly for LLMs, and related technologies across academic papers, patents, and industry developments. The field is rapidly evolving with significant contributions from both academia and major tech companies. - ---- - -## 1. Academic Papers - -### 1.1 Code Analysis & Machine Learning - -#### **"A Systematic Literature Review on the Use of Machine Learning in Software Engineering"** -- **Source:** arXiv (2024) -- **Link:** https://arxiv.org/abs/2406.13877 -- **Key Topics:** Software quality assurance, maintenance, comprehension, documentation -- **Techniques:** Supervised learning, unsupervised learning, deep learning -- **Relevance:** Comprehensive overview of ML applications in software engineering domains - -#### **"A Large-Scale Study of Model Integration in ML-Enabled Software Systems"** -- **Source:** arXiv (2024) -- **Link:** https://arxiv.org/abs/2408.06226 -- **Scope:** Analysis of 2,900+ open-source systems -- **Focus:** ML model integration practices, bridging data science and software engineering -- **Key Insights:** Characteristics and practices of embedding ML models into traditional software - -#### **"A Software Engineering Perspective on Engineering Machine Learning Systems"** -- **Source:** arXiv (2020) -- **Link:** https://arxiv.org/abs/2012.07919 -- **Author:** Görkem Giray -- **Key Points:** - - Challenges of non-deterministic ML systems - - Need for new tools and testing methodologies - - Software engineering complexities in ML systems - -#### **"Software Engineering for AI and Machine Learning Software: Systematic Literature Review"** -- **Source:** arXiv (2020) -- **Link:** https://arxiv.org/abs/2011.03751 -- **Focus:** SE practices in AI/ML development -- **Contributions:** Challenges identification and proposed solutions - -### 1.2 Code Vulnerability & Security - -#### **"Ensemble Multi-Label Machine Learning Solidity Smart Contract Vulnerability Detection Model"** -- **Source:** Springer (2025) -- **Link:** https://link.springer.com/article/10.1007/s10586-025-05725-y -- **Innovation:** Transforms bytecode emphasizing control and data flow patterns -- **Method:** Retains opcode mnemonics, discards operand values for better generalization -- **Application:** Smart contract vulnerability detection - -#### **"MalBERTv2: Code Aware BERT-Based Model for Malware Identification"** -- **Source:** MDPI (2024) -- **Link:** https://www.mdpi.com/2504-2289/7/2/60 -- **Approach:** BERT-based model for code analysis -- **Features:** Custom tokenizer, Byte-Pair Encoding (BPE) -- **Application:** Malware detection through code semantics - -### 1.3 Code Understanding & RAG Limitations - -#### **"Why RAG Retrieval Fails for Microservices Code Review at Scale"** -- **Source:** CodeAnt.ai Blog (2025) -- **Link:** https://www.codeant.ai/blogs/rag-retrieval-fails-microservices-code-review -- **Key Findings:** - - RAG struggles with distributed systems - - Complex queries across service boundaries - - Data inconsistencies - - Hallucinations in code analysis - - Need for LLMs with deep architectural understanding - -### 1.4 Compiler & Language Theory - -#### **"BurTorch: Revisiting Training from First Principles"** -- **Source:** KAUST Repository -- **Link:** https://repository.kaust.edu.sa/bitstreams/0997f91f-441a-4f16-9003-3e33e729134e/download -- **Focus:** Compiler-based approaches in ML -- **Topics:** Semantic analysis, code optimization - -#### **"Development, Assessment, and Reengineering of Language Descriptions"** -- **Source:** VU Amsterdam -- **Link:** https://www.cs.vu.nl/~x/cale/cale.html -- **Method:** BNF parsers for language description analysis -- **Goal:** Identify and correct semantic errors in language definitions - ---- - -## 2. Patents & Proprietary Technologies - -### 2.1 Graph-Based Systems - -#### **"Graph-Augmented RAG for Telecom"** (Ericsson) -- **Source:** Ericsson Initiative -- **Link:** https://fr.linkedin.com/jobs/view/graph-augmented-rag-for-telecom-at-ericsson-4344930017 -- **Innovation:** Incorporates graph structures into RAG -- **Benefits:** - - Preserves document hierarchies - - Handles inter-referenced documentation - - Improves factual accuracy - - Enhanced reasoning depth - -### 2.2 Security Systems - -#### **"HOLMES: A System for Detecting Advanced and Persistent Threats"** -- **Source:** IEEE Security & Privacy 2019 -- **Link:** https://www.ieee-security.org/TC/SP2019/program-papers.html -- **Approach:** Correlates suspicious information flows -- **Features:** - - High-level graph generation - - Real-time attacker action summarization - - APT campaign detection - -### 2.3 Patent Search Recommendations -- **Google Patents:** Search for "semantic code analysis" and "context assembly" -- **USPTO:** Combine keywords: software + semantic + graph - ---- - -## 3. Industry Implementations - -### 3.1 Cody AI (Sourcegraph) - -#### **"Deep Codebase Understanding, Real-World Applications, and Strategic Market Positioning"** -- **Source:** MGX.dev Insights -- **Link:** https://mgx.dev/insights/c4dc216669bf47a4b91e6e1e103a57cd -- **Key Technology:** Repo-level Semantic Graph (RSG) -- **Features:** - - Sophisticated context engine - - Maintains deep codebase understanding - - Graph expansion algorithms - - Link prediction on RSG - - Multi-source context retrieval (local code, docs, etc.) - - Token usage optimization - - Prevents truncated responses - -**System Architecture:** -1. **Retrieval Phase:** Gather context from multiple sources -2. **Ranking Phase:** Prioritize most relevant context -3. **Graph Operations:** Expansion and link prediction - -### 3.2 Microsoft Research - -#### **"Software Engineering for Machine Learning: A Case Study"** -- **Source:** Microsoft Research -- **Link:** https://www.microsoft.com/en-us/research/publication/software-engineering-for-machine-learning-a-case-study/ -- **Contribution:** Nine-stage workflow for AI-based applications -- **Focus:** Evolution of development processes for AI capabilities -- **Insights:** Practical approaches to integrating ML into software - -### 3.3 Snyk - -#### **"Context Engineering: Building Intelligent AI Systems Through Strategic Information Management"** -- **Source:** Snyk Blog -- **Link:** https://snyk.io/articles/context-engineering/ -- **Principles:** - - **Semantic similarity** optimization - - **Information density** optimization - - **Temporal relationship** preservation - - **Context relevance** maximization -- **Implementation Methods:** - - Adaptive retrieval systems - - Bayesian inference frameworks - - Strategic context selection - -### 3.4 Practical Implementation - -#### **"Building my first AI project: From Zero to 'Production' ready RAG"** -- **Source:** Medium (2025) -- **Author:** Sandeep G -- **Link:** https://medium.com/@sandeepg2890/building-my-first-ai-service-from-zero-to-production-rag-in-2025-08d1b370640b -- **Focus:** Custom RAG pipeline for code analysis -- **Challenges:** Legacy codebase complexity -- **Solutions:** Context engineering, specialized parsing - ---- - -## 4. Research Institutions & Educational Resources - -### 4.1 Carnegie Mellon University - SEI - -#### **"Applied Machine Learning in Software Engineering"** -- **Source:** Software Engineering Institute -- **Link:** https://insights.sei.cmu.edu/library/applied-machine-learning-in-software-engineering/ -- **Topics:** Immediate benefits and considerations for ML in SE -- **Focus:** Alignment of data scientists, software engineers, and operations - -#### **"Software Engineering for Machine Learning" (Podcast)** -- **Source:** SEI -- **Link:** https://www.sei.cmu.edu/library/software-engineering-for-machine-learning/ -- **Content:** Integration of ML into SE practices - -### 4.2 Cornell University - -#### **"Software Engineering in the Era of Machine Learning"** -- **Source:** CS 6158 Course -- **Link:** https://www.cs.cornell.edu/courses/cs6158/2024fa/ -- **Topics:** - - Testing and debugging ML systems - - Program analysis for ML - - Using ML to improve SE - - Research at SE/ML intersection - -### 4.3 Imperial College London - -#### **"Software Engineering for Machine Learning Systems"** -- **Source:** Course by Andrew Eland -- **Link:** https://www.andreweland.org/swemls/ -- **Content:** - - Building robust ML systems - - Practical projects (medical prediction models, clinical alerts) - - Engineering concepts for ML operations - ---- - -## 5. Tools & Frameworks - -### 5.1 Apache SystemDS -- **Status:** Open-source ML system -- **Former Name:** Apache SystemML -- **Features:** - - End-to-end data science lifecycle support - - R-like and Python-like languages - - Multiple execution modes (standalone, distributed) - - Algorithm customizability -- **Link:** https://en.wikipedia.org/wiki/Apache_SystemDS - -### 5.2 MLIR (Multi-Level Intermediate Representation) -- **Developer:** Google -- **Purpose:** Compiler infrastructure for ML -- **Benefits:** - - Improved modularity - - Better maintainability - - Multi-level IR support - - Gradual lowering through transformations - - Custom operations and type systems -- **Link:** https://en.wikipedia.org/wiki/MLIR_(software) - ---- - -## 6. Key Concepts & Methodologies - -### 6.1 MLOps -- **Definition:** Combination of ML + DevOps -- **Scope:** Entire ML lifecycle -- **Components:** - - Integration - - Deployment - - Monitoring - - Governance -- **Goal:** Robust, scalable, efficient ML systems -- **Link:** https://en.wikipedia.org/wiki/MLOps - -### 6.2 Context Engineering Principles - -From multiple sources, key principles include: - -1. **Semantic Similarity** - - Match query intent to code semantics - - Use embeddings for similarity matching - -2. **Information Density Optimization** - - Maximize relevant information per token - - Minimize noise in context - -3. **Temporal Relationship Preservation** - - Maintain code evolution history - - Track dependency changes over time - -4. **Adaptive Retrieval** - - Dynamic context selection - - Query-specific retrieval strategies - -5. **Graph-Based Relationships** - - Leverage code structure - - Use dependency graphs - - Enable graph traversal for context - ---- - -## 7. Challenges Identified - -### 7.1 RAG Limitations in Code Analysis -- **Complex queries** across service boundaries -- **Inconsistent data** in distributed systems -- **Hallucinations** when context is incomplete -- **Microservices architecture** breaks RAG assumptions -- **Token limitations** with large codebases - -### 7.2 ML/SE Integration Challenges -- **Non-determinism** in ML systems -- **Testing difficulties** for ML components -- **Versioning** of ML models and data -- **Reproducibility** concerns -- **Cross-team alignment** (data scientists, engineers, ops) - -### 7.3 Semantic Code Analysis Challenges -- **Scale** - handling large codebases -- **Multi-language** support -- **Cross-file dependencies** -- **Dynamic behavior** vs static analysis -- **Context window limitations** - ---- - -## 8. Recommended Conference Sources - -### 8.1 Strange Loop -- Focus: Software engineering practices -- Topics: Programming languages, distributed systems, security - -### 8.2 QCon -- Focus: Enterprise software development -- Topics: Architecture, ML/AI, DevOps, cloud - -### 8.3 Other Relevant Conferences -- **ICSE** (International Conference on Software Engineering) -- **FSE** (Foundations of Software Engineering) -- **ASE** (Automated Software Engineering) -- **ISSTA** (International Symposium on Software Testing and Analysis) - ---- - -## 9. Search Queries for Further Research - -### 9.1 Google Scholar -``` -"semantic code graph" "LLM context assembly" -"code intelligence" "graph-based code analysis" -"repository semantic graph" -"code embedding" "semantic search" -"program dependence graph" "LLM" -``` - -### 9.2 arXiv (cs.SE) -``` -semantic code analysis -code graph neural networks -program analysis machine learning -code context retrieval -``` - -### 9.3 ACM Digital Library -``` -software engineering AND machine learning -code comprehension AND deep learning -semantic code search -program analysis AND transformers -``` - -### 9.4 Google Patents / USPTO -``` -semantic code analysis -context assembly software -code graph analysis -program dependence graph -code intelligence system -``` - ---- - -## 10. Related Technologies & Terms - -### 10.1 Static Analysis -- **AST** (Abstract Syntax Tree) -- **CFG** (Control Flow Graph) -- **PDG** (Program Dependence Graph) -- **Call graphs** -- **Data flow analysis** - -### 10.2 Code Intelligence -- **Code2Vec** - code embeddings -- **GraphCodeBERT** - graph-enhanced code understanding -- **CodeBERT** - pre-trained models for code -- **UniXcoder** - unified cross-modal code representation - -### 10.3 Retrieval & Search -- **RAG** (Retrieval-Augmented Generation) -- **Semantic search** -- **Vector databases** -- **Embedding models** -- **Hybrid search** (keyword + semantic) - ---- - -## 11. Industry Players - -### 11.1 Major Companies -- **GitHub** (Copilot, CodeQL) -- **Microsoft** (IntelliCode, Pylance) -- **Google** (Code Search, AI assistance) -- **JetBrains** (AI Assistant) -- **Amazon** (CodeWhisperer) - -### 11.2 Startups & Specialized Tools -- **Sourcegraph** (Cody AI, code search) -- **Tabnine** (AI code completion) -- **Codeium** (AI-powered toolkit) -- **CodeAnt.ai** (Code review) -- **Snyk** (Security with AI) - ---- - -## 12. Key Takeaways for STE Runtime - -### 12.1 Differentiation Opportunities -1. **Multi-language semantic graph** - comprehensive language support -2. **Incremental reconciliation** - efficient updates vs full rebuilds -3. **Hybrid approach** - combining static analysis + semantic understanding -4. **Change detection** - sophisticated file watching and delta analysis -5. **Validation framework** - ensuring graph consistency - -### 12.2 Alignment with Industry -- **Semantic graph approach** aligns with Cody AI's RSG -- **Context assembly** similar to retrieval/ranking pipelines -- **Graph traversal** for context gathering is industry standard -- **Incremental updates** address scalability concerns - -### 12.3 Novel Contributions -- **Change-aware reconciliation** (incremental recon approach) -- **Multi-phase recon** (discovery → parse → resolve → link → finalize) -- **STE format specification** (standardized interchange format) -- **Language-agnostic framework** with extensible extractors - -### 12.4 Research Gaps to Explore -1. How others handle **partial graph updates** -2. **Validation strategies** for graph consistency -3. **Performance benchmarks** for large-scale codebases -4. **Context selection algorithms** for LLM consumption - ---- - -## 13. Next Steps - -### 13.1 Deep Dives Needed -- [ ] Read full papers on code embeddings (code2vec, CodeBERT) -- [ ] Study graph neural networks for code -- [ ] Analyze Sourcegraph's RSG architecture (if public docs available) -- [ ] Research program dependence graphs in detail - -### 13.2 Patent Research -- [ ] Conduct USPTO search for specific patents -- [ ] Review Google Patents for code graph technologies -- [ ] Identify potential IP conflicts or prior art - -### 13.3 Conference Proceedings -- [ ] Search QCon 2024-2026 for relevant talks -- [ ] Look for Strange Loop presentations on code analysis -- [ ] Review ICSE/FSE proceedings for semantic analysis papers - -### 13.4 Industry Engagement -- [ ] Subscribe to GitHub Engineering blog -- [ ] Follow JetBrains Research publications -- [ ] Monitor Microsoft Research for code intelligence papers -- [ ] Track Sourcegraph's technical blog updates - ---- - -## References - -All links and sources are embedded throughout this document. For the most current information, regularly search: -- arXiv cs.SE: https://arxiv.org/list/cs.SE/recent -- ACM Digital Library: https://dl.acm.org/ -- Google Scholar: https://scholar.google.com/ -- Google Patents: https://patents.google.com/ -- USPTO: https://www.uspto.gov/ - ---- - -**Document Maintained By:** STE Runtime Project -**Last Updated:** January 11, 2026 -**Status:** Living document - update as new research emerges - - - diff --git a/documentation/plan/e-adr-implementation-status.md b/documentation/plan/e-adr-implementation-status.md deleted file mode 100644 index 29ea31d..0000000 --- a/documentation/plan/e-adr-implementation-status.md +++ /dev/null @@ -1,439 +0,0 @@ -# E-ADR Implementation Status Report - -**Generated:** 2026-01-11 -**ADRs Reviewed:** E-ADR-007 (Watchdog), E-ADR-011 (MCP Server) - ---- - -## Executive Summary - -Both E-ADR-007 and E-ADR-011 are **SUBSTANTIALLY COMPLETE** with all core components implemented and tested. The implementation follows the specifications closely and includes sophisticated features beyond the baseline requirements. - -**Overall Status:** ✅ 95% Complete (Production-Ready) - ---- - -## E-ADR-007: Watchdog Authoritative Mode - -**Status:** ✅ **IMPLEMENTED** -**Test Coverage:** ✅ Passing (21 tests in `safeguards.test.ts`) - -### Implemented Components - -#### ✅ Core Safeguards (Phase 1 - Critical) -- **Write Tracker** (`src/watch/write-tracker.ts`) - - Content-hash based write tracking - - Prevents infinite loops - - LRU cache with TTL (30s retention) - -- **Update Coordinator** (`src/watch/update-coordinator.ts`) - - Generation-based update tracking - - Prevents cascading loops - - Transitive update detection - -- **Full Reconciliation** (`src/watch/full-reconciliation.ts`) - - Periodic consistency checks - - Detects missed file system events - - Recovers from event loss - -#### ✅ Advanced Features (Phase 2 - Important) -- **Edit Queue Manager** (`src/watch/edit-queue-manager.ts`) - - **AI Edit Detection** - Detects Cursor streaming patterns - - **Adaptive Debouncing** - 2s for AI, 500ms for manual - - **Version Tracking** - Coalesces rapid changes - - **Stability Checks** - Waits for file to settle - -- **Transaction Detector** (`src/watch/transaction-detector.ts`) - - Multi-file edit detection - - Batch processing (single RECON for multiple files) - - Transaction window (3s default) - -- **Watchdog Orchestrator** (`src/watch/watchdog.ts`) - - Unified process coordination - - File watcher integration (chokidar) - - Stats tracking and health monitoring - -#### ✅ Integration (Phase 3 - Nice-to-Have) -- **Change Detector** (`src/watch/change-detector.ts`) - - File change classification - - Manifest-based tracking - -- **File Watcher** (`src/watch/file-watcher.ts`) - - Cross-platform support (Windows, macOS, Linux) - - `.gitignore` respect - - Polling fallback for network drives - -### Implementation Highlights - -**Beyond Specification:** -1. **Sophisticated AI Edit Detection** - The implementation goes beyond simple debouncing: - - Tracks edit velocity (bytes/second) - - Detects streaming patterns (multiple rapid changes) - - Adjusts debounce timing dynamically - -2. **Comprehensive Safeguards** - Multiple layers prevent edge cases: - - Content-hash tracking (not just timestamps) - - Path normalization (handles symlinks, relative paths) - - LRU cache prevents memory leaks - -3. **Transaction Intelligence** - Detects multi-file refactorings: - - Groups related changes automatically - - Single RECON for entire transaction - - Reduces overhead by 90%+ for AI-generated multi-file edits - -### Test Results - -``` -✓ src/watch/safeguards.test.ts (21 tests) 5319ms - ✓ WriteTracker - ✓ UpdateCoordinator - ✓ Integration scenarios -``` - -**Key Test Scenarios Covered:** -- Infinite loop prevention -- Cascading update prevention -- Content hash collision handling -- Path normalization (Windows vs Unix) -- LRU cache eviction -- Concurrent write tracking - -### What's Working - -1. **File Changes → RECON** - Automatic triggering works reliably -2. **AI Edit Handling** - Cursor streaming edits coalesce correctly (10+ saves → 1 RECON) -3. **Multi-File Transactions** - Detects and batches related changes -4. **No Infinite Loops** - Safeguards prevent all tested edge cases -5. **Cross-Platform** - Works on Windows (your dev environment) - -### Configuration Status - -**File:** `ste.config.json` - -```json -{ - "watchdog": { - "enabled": false, // ← CURRENTLY DISABLED (opt-in) - "debounceMs": 500, - "aiEditDebounceMs": 2000, - "syntaxValidation": true, - "transactionDetection": true, - "stabilityCheckMs": 100, - "patterns": ["**/*.py", "**/*.ts", "**/*.js", "**/*.tsx", "**/*.jsx"], - "ignore": [".git", "node_modules", ".venv", "__pycache__", "dist", "build"], - "fullReconciliationInterval": 300000, - "fallbackPolling": false, - "pollingInterval": 5000 - } -} -``` - -**Note:** Watchdog is disabled by default. Enable by setting `watchdog.enabled: true`. - ---- - -## E-ADR-011: ste-runtime MCP Server - -**Status:** ✅ **IMPLEMENTED** -**Test Coverage:** ✅ Passing (9 tests in `mcp-server.test.ts`) - -### Implemented Components - -#### ✅ MCP Server Core -- **MCP Server** (`src/mcp/mcp-server.ts`) - - Stdio transport for Cursor integration - - Tool registration and discovery - - Context initialization and hot-reloading - - Graceful shutdown handling - -#### ✅ AI-Optimized MCP Tools (8) -**File:** `src/mcp/tools-optimized.ts` - -Implemented Tools: -- `find` - Semantic search by meaning/name -- `show` - Full implementation with dependencies -- `usages` - Usage sites with snippets -- `impact` - Change impact analysis -- `similar` - Similar code patterns -- `overview` - Codebase structure overview -- `diagnose` - Graph health/coverage checks -- `refresh` - Trigger graph refresh (reloads context) - -**Operational Helpers (internal):** -- `src/mcp/tools-operational.ts` (recon triggers, health utilities) - -#### ✅ Adaptive Tool Parameters (§3 of E-ADR-011) (§3 of E-ADR-011) -**File:** `src/mcp/graph-topology-analyzer.ts` - -**Implemented:** -- Graph metrics calculation -- Architecture pattern detection (layered, microservices, component-tree, flat, mixed) -- Dynamic depth recommendation based on graph structure -- Metrics persistence (`.ste/state/graph-metrics.json`) -- Automatic recalculation on significant graph changes - -**Pattern Detection Logic:** -```typescript -// React component tree → depth=4 -// Layered backend → depth=2 -// Microservices → depth=3 -// Adapts to YOUR codebase automatically -``` - -### Integration with Watchdog - -**File:** `src/cli/watch-cli.ts` and `src/cli/index.ts` - -**Flow:** -1. User runs `ste watch` (or Cursor starts it via MCP config) -2. Loads configuration from `ste.config.json` -3. Runs initial RECON if needed -4. Starts MCP server (stdio transport) -5. Optionally starts Watchdog (if `watchdog.enabled: true`) -6. File changes → Incremental RECON → MCP server reloads context -7. Cursor queries MCP tools → Gets fresh state - -### Test Results - -``` -✓ src/mcp/mcp-server.test.ts (9 tests) 271ms - ✓ MCP Server Integration - ✓ Initialization - ✓ Tool Registration - ✓ Context Reload - ✓ Watchdog Integration - ✓ File Watching - ✓ RECON Triggering -``` - -**Key Scenarios Tested:** -- MCP server starts and registers tools -- RSS context loads correctly -- Graph topology analysis runs -- Context reload after RECON -- Watchdog integration (start/stop) - -### What's Working - -1. **Cursor Integration Ready** - MCP protocol implemented correctly -2. **Tool Discovery** - Cursor can see all 8 MCP tools automatically -3. **Fast Queries** - RSS operations <100ms (in-memory) -4. **Rich Context** - Source code loading for targeted files only -5. **Adaptive Defaults** - Graph analysis tunes depth automatically -6. **Hot Reload** - Context refreshes after file changes (when watchdog enabled) - -### Cursor Configuration - -**File:** `~/.cursor/mcp.json` - -```json -{ - "mcpServers": { - "ste-runtime": { - "command": "ste", - "args": ["watch", "--mcp"], - "cwd": "${workspaceFolder}" - } - } -} -``` - -**Status:** ⚠️ NOT YET CONFIGURED (requires manual setup) - ---- - -## Two-Layer Architecture Implementation - -**Per E-ADR-011 §2 - Potentially Novel Innovation** - -### Implementation Status: ✅ COMPLETE - -**Layer 1: RSS (Structural)** - ✅ Fully implemented -- Fast graph queries (<100ms) -- Returns metadata only (keys, relationships) -- No disk I/O during queries - -**Layer 2: Context Assembly (Rich)** - ✅ Fully implemented -- Targeted source code loading -- Only reads files for relevant slices -- Token budget optimization -- LLM-friendly formatting - -**Integration Pattern:** -```typescript -// Step 1: Fast structural query (RSS Layer) -find({ query: "authentication handlers" }) -→ Returns 12 slice keys in 45ms - -// Step 2: LLM narrows down -usages({ target: "api/function/authenticate" }) -→ Returns 3 slice keys in 23ms - -// Step 3: Rich context (Context Assembly Layer) -show({ target: "api/function/authenticate" }) -→ Loads source for 3 files (240 lines) in 180ms -→ Total: 248ms, precise context -``` - -**Token Efficiency Example:** -- Traditional: 50 files, 15,000 lines, 80,000 tokens -- Two-Layer: 3 files, 240 lines, 1,200 tokens -- **Reduction:** 98.5% - ---- - -## Missing/Incomplete Features - -### E-ADR-007 Missing Items - -#### ⚠️ Not Implemented (Optional): -1. **Self-Healing on Manual Slice Edits** (§2 of E-ADR-007) - - Detection: Partially implemented in change-detector - - Automatic healing: NOT implemented - - Impact: Low (users don't typically edit slices directly) - -2. **Conflict Resolution UI** (§5.6 of E-ADR-007) - - Low-confidence migration surfacing: NOT implemented - - CLI command for conflict resolution: NOT implemented - - Impact: Medium (would improve UX for file renames with low confidence) - -3. **Migration Detection** (E-ADR-007 §1) - - File move detection: NOT implemented - - Confidence scoring: NOT implemented - - Auto-resolution: NOT implemented - - Impact: Medium (helpful for refactorings, but incremental RECON handles changes) - -4. **Audit Log** (§7.4 of E-ADR-007) - - Session logging: NOT implemented - - Impact: Low (nice-to-have for debugging) - -### E-ADR-011 Missing Items - -#### ⚠️ Not Implemented (Future Work): -1. **Invariant Injection** (Phase 1 Extensions) - - Load from `.ste/invariants/`: NOT implemented - - `get_invariants_for_scope()` tool: NOT implemented - - Impact: Medium (needed for full CEM integration) - -2. **Divergence Detection** (Phase 1 Extensions) - - Currency validation: NOT implemented - - Staleness warnings: NOT implemented - - Impact: Low (periodic reconciliation provides basic coverage) - -3. **CEM Orchestration Layer** (Phase 2) - - 9-stage execution enforcement: NOT implemented - - Structured output validation: NOT implemented - - Execution trace logging: NOT implemented - - Impact: High (core governed cognition feature, but out of scope for v1.0) - -4. **Self-Bootstrapping Extractors** (Phase 2) - - Automatic extractor generation: NOT implemented - - Impact: Low (manual extractor development works fine) - ---- - -## Testing Coverage Summary - -### Automated Tests -- **Watch/Safeguards:** 21 tests passing -- **MCP Server:** 9 tests passing -- **Overall:** 469 tests passing across entire codebase - -### Manual Testing Needed -1. **Cursor Integration End-to-End** - - Configure `~/.cursor/mcp.json` - - Start `ste watch` - - Verify Cursor can discover tools - - Test actual queries from Cursor - -2. **Windows File Watching** - - Enable watchdog (`watchdog.enabled: true`) - - Make file changes - - Verify RECON triggers - - Test AI edit detection (Cursor streaming) - -3. **Network Drive Handling** - - Test on network drive (if applicable) - - Verify fallback polling works - ---- - -## Production Readiness Assessment - -### Ready for Use: ✅ -- MCP server implementation (stable, tested) -- RSS operations (fast, reliable) -- Graph topology analysis (adaptive parameters) -- Context assembly (token-efficient) -- CLI integration (`ste watch` command) - -### Needs Testing: ⚠️ -- Cursor MCP integration (end-to-end) -- Watchdog in real development workflow -- AI edit detection under heavy use - -### Optional Enhancements: 💡 -- Migration detection (file renames) -- Conflict resolution UI -- Invariant injection (for full CEM) -- Self-healing slice edits - ---- - -## Recommendations - -### Immediate Next Steps - -1. **Test Cursor Integration** - - Add MCP config to `~/.cursor/mcp.json` - - Start `ste watch` in a test project - - Verify tool discovery and basic queries - -2. **Enable Watchdog** (Optional) - - Set `watchdog.enabled: true` in `ste.config.json` - - Test file changes trigger RECON - - Validate AI edit detection during Cursor code generation - -3. **Document Setup** - - Create user guide for Cursor MCP configuration - - Add troubleshooting section - - Document expected behavior - -### Future Enhancements (Post-v1.0) - -1. **Migration Detection** - Would improve file rename handling -2. **Invariant System** - Needed for full CEM Stage 3 integration -3. **Conflict Resolution** - Better UX for ambiguous changes -4. **Audit Logging** - Helpful for debugging watchdog decisions - ---- - -## Conclusion - -**Both E-ADR-007 and E-ADR-011 are substantially complete** with all core features implemented and tested. The implementation includes sophisticated features beyond the baseline specification: - -✅ **Strengths:** -- Comprehensive safeguards prevent edge cases -- AI edit detection handles Cursor streaming patterns -- Two-layer architecture enables token-efficient context assembly -- Adaptive parameter tuning based on graph topology -- Cross-platform support (Windows, macOS, Linux) - -⚠️ **Gaps:** -- Migration detection not implemented (optional feature) -- Invariant injection not implemented (future CEM integration) -- End-to-end Cursor integration not yet tested - -**Overall Status:** Production-ready for core use cases (MCP queries, optional file watching). Advanced features (migration detection, invariants) can be added incrementally. - -**Recommended Action:** Proceed with Cursor integration testing and real-world validation. - ---- - -**Last Updated:** 2026-01-11 -**Next Review:** After Cursor integration testing - - - - - diff --git a/documentation/plan/e-adr-spec-validation-assessment.md b/documentation/plan/e-adr-spec-validation-assessment.md deleted file mode 100644 index 88731b7..0000000 --- a/documentation/plan/e-adr-spec-validation-assessment.md +++ /dev/null @@ -1,333 +0,0 @@ -# E-ADR Specification Validation Assessment - -**Date:** 2026-01-09 -**Assessor:** AI Assistant -**Spec Reference:** [https://github.com/egallmann/ste-spec/tree/main/ste-spec](https://github.com/egallmann/ste-spec/tree/main/ste-spec) -**Purpose:** Evaluate each E-ADR against relevant ste-spec sections for ADR graduation - ---- - -## Executive Summary - -| E-ADR | Implementation | Spec Alignment | Validation Status | Graduation Readiness | -|-------|---------------|----------------|-------------------|---------------------| -| E-ADR-001 | Complete | 🟢 Strong | Awaiting Formal Review | Ready | -| E-ADR-002 | Complete | 🟢 Strong | Awaiting Formal Review | Ready | -| E-ADR-003 | N/A (Deferral) | 🟢 Compliant | Awaiting Formal Review | Ready | -| E-ADR-004 | Complete | 🟢 Strong | Awaiting Formal Review | Ready | -| E-ADR-005 | Complete | 🟡 Moderate | Awaiting Formal Review | Ready with Notes | -| E-ADR-006 | Complete | 🟡 Moderate | Awaiting Formal Review | Ready with Notes | -| E-ADR-007 | Partial | 🟡 Moderate | Needs Work | Not Ready | -| E-ADR-008 | N/A (Guide) | 🟢 Compliant | No Validation Needed | N/A | -| E-ADR-009 | Complete | 🟡 Moderate | Awaiting Formal Review | Ready with Notes | -| E-ADR-010 | Complete | 🟢 Strong | Awaiting Formal Review | Ready | - ---- - -## Detailed Assessments - -### E-ADR-001: Provisional Execution of RECON for Project-Level Semantic State Pressure - -**Relevant Spec Sections:** -- STE-Architecture.md §4.5: State Components (RECON) -- STE-Architecture.md §5.1: Bootstrap Flow (RECON 6-phase) -- STE-Cognitive-Execution-Model.md §3: Stage 1 - Initialization -- STE-Invariant-Hierarchy.md §3: RECON and the Invariant Hierarchy - -**Alignment Assessment:** - -| Spec Requirement | E-ADR Compliance | Notes | -|-----------------|------------------|-------| -| RECON extracts semantic state from source | Compliant | E-ADR defines extraction as authoritative for project-level state | -| 6-phase execution pipeline | Compliant | E-ADR extends to 7 phases (adds self-validation) - additive extension | -| Slices are derived artifacts | Compliant | §5.4 explicitly states slices are derived, self-healing | -| RECON operates on canonical state | Compliant | E-ADR clarifies project-level vs org-level authority boundary | -| SYS-6: RECON Completion Prerequisite | Compliant | Validation phase ensures state completeness | - -**Gaps Identified:** -- None significant. E-ADR extends spec with practical implementation details. - -**Graduation Recommendation:** **Ready for ADR graduation** - ---- - -### E-ADR-002: RECON Self-Validation, Non-Blocking - -**Relevant Spec Sections:** -- STE-Architecture.md §4.4: Validation Components -- STE-Cognitive-Execution-Model.md §5: Stage 3 - Pre-Task Validation -- STE-Artifact-Specifications.md §7: Validator Artifact Requirements - -**Alignment Assessment:** - -| Spec Requirement | E-ADR Compliance | Notes | -|-----------------|------------------|-------| -| Validators enforce rules deterministically | Compliant | E-ADR defines deterministic validation with categories | -| Validators do not introduce new rules | Compliant | Validators are read-only observers | -| Documentation Validator exists | Compliant | Schema, Graph, Identity, Coverage validators defined | -| Non-blocking for provisional execution | Compliant | Explicitly non-blocking during exploratory phase | - -**Gaps Identified:** -- Spec mentions AI-DOC Currency Validator (DOC-16) - E-ADR could add currency validation - -**Graduation Recommendation:** **Ready for ADR graduation** - ---- - -### E-ADR-003: CEM Implementation Deferral - -**Relevant Spec Sections:** -- STE-Cognitive-Execution-Model.md (entire document) -- STE-Architecture.md §4.7: Runtime Execution Services - -**Alignment Assessment:** - -| Spec Requirement | E-ADR Compliance | Notes | -|-----------------|------------------|-------| -| CEM defines 9-stage execution lifecycle | 🟡 Acknowledged | E-ADR explicitly defers CEM implementation | -| Human-in-loop acceptable per §4.7 | Compliant | E-ADR correctly cites spec allowance for human oversight | -| Foundations must exist before CEM | Compliant | Build order is correct (RECON, AI-DOC, RSS, then CEM) | - -**Gaps Identified:** -- None. Deferral is architecturally sound and spec-compliant. - -**Graduation Recommendation:** **Ready for ADR graduation** (as deferral decision) - ---- - -### E-ADR-004: RSS CLI Implementation for Developer-Invoked Graph Traversal - -**Relevant Spec Sections:** -- STE-Architecture.md §4.6: Runtime Components (RSS) -- STE-Cognitive-Execution-Model.md §4.3: RSS Graph Traversal -- STE-Architecture.md §4.5: State Components (AI-DOC) - -**Alignment Assessment:** - -| Spec Requirement | E-ADR Compliance | Notes | -|-----------------|------------------|-------| -| RSS operations: lookup, dependencies, dependents, blast_radius, by_tag, assemble_context | Compliant | All 6 spec operations implemented | -| RSS traverses `_slice` metadata | Compliant | Graph loader reads YAML slices | -| RSS ensures AI-DOC size and context size are decoupled | Compliant | Bounded context assembly implemented | -| Task Analysis feeds entry points to RSS | Compliant | findEntryPoints implemented | -| SYS-12: AI-DOC Sliceability | Compliant | Slices include required metadata | - -**Extensions Beyond Spec:** -- `search` operation (entry point discovery) -- `stats` operation (debugging) - -**Gaps Identified:** -- None significant. Extensions are additive and useful. - -**Graduation Recommendation:** **Ready for ADR graduation** - ---- - -### E-ADR-005: JSON Data Model and Configuration Extraction - -**Relevant Spec Sections:** -- STE-Architecture.md §4.5: AI-DOC 13-Domain Structure -- STE-Architecture.md §5.1: RECON 6-phase pipeline -- STE-Artifact-Specifications.md §2.1: AI-DOC characteristics - -**Alignment Assessment:** - -| Spec Requirement | E-ADR Compliance | Notes | -|-----------------|------------------|-------| -| AI-DOC is explicit, non-narrative, declarative | Compliant | JSON extraction produces structured slices | -| 13-domain structure | 🟡 Partial | `data` domain used but not all domains covered | -| Extraction is deterministic | Compliant | JSON parsing is deterministic | -| Configuration patterns defined | Compliant | Controls, schemas, parameters extracted | - -**Gaps Identified:** -- Spec defines 13 domains; E-ADR focuses on `data` and `infrastructure` - acceptable for initial scope - -**Graduation Recommendation:** **Ready with note:** Aligns with subset of 13-domain model - ---- - -### E-ADR-006: Angular and CSS/SCSS Semantic Extraction - -**Relevant Spec Sections:** -- STE-Architecture.md §4.5: AI-DOC 13-Domain Structure -- STE-Architecture.md §5.1: RECON Extraction phase -- STE-Artifact-Specifications.md §3: Structural Requirements - -**Alignment Assessment:** - -| Spec Requirement | E-ADR Compliance | Notes | -|-----------------|------------------|-------| -| AI-DOC is machine-interpretable | Compliant | Component, service, route slices are structured | -| Provenance metadata required | Compliant | source_files, line info included | -| References enable graph traversal | Compliant | Component → template → styles relationships | -| Cross-cutting extractor pattern | Compliant | CSS extractor is framework-agnostic | - -**Gaps Identified:** -- Spec doesn't explicitly define frontend domain structure - E-ADR pioneers this - -**Graduation Recommendation:** **Ready with note:** Extends spec for frontend semantics - ---- - -### E-ADR-007: Automatic Semantic Maintenance (Watchdog Authoritative Mode) - -**Relevant Spec Sections:** -- STE-Architecture.md §5.3: Operational AI-DOC Maintenance Flow -- STE-Architecture.md: Incremental RECON Protocol -- STE-Architecture.md: Lazy Population Protocol - -**Alignment Assessment:** - -| Spec Requirement | E-ADR Compliance | Notes | -|-----------------|------------------|-------| -| Incremental RECON for O(changed files) | Partial | Watchdog concept exists but not fully integrated | -| Staleness detection (DOC-16) | Partial | Periodic reconciliation planned but not complete | -| Source is single source of truth | Compliant | E-ADR explicitly states RECON is always authoritative | -| Self-healing property | Partial | Designed but not fully implemented | - -**Gaps Identified:** -- Implementation marked as "Partial" - core watchdog features not complete -- Incremental RECON integration pending -- RSS hot-reload not implemented - -**Graduation Recommendation:** ⛔ **Not ready** - Complete implementation first - ---- - -### E-ADR-008: Extractor Development Guide - -**Relevant Spec Sections:** -- N/A (Documentation guide, not implementation) - -**Alignment Assessment:** - -This is a developer guide, not an implementation decision. It does not require spec validation. - -| Aspect | Assessment | -|--------|------------| -| Provides patterns for new extractors | Documented | -| Follows spec philosophy | Semantics over syntax | -| Living document | Acknowledged | - -**Graduation Recommendation:** N/A - Not an implementation ADR, remains as guide - ---- - -### E-ADR-009: Self-Configuring Domain Discovery - -**Relevant Spec Sections:** -- STE-Architecture.md §4.5: AI-DOC 13-Domain Structure -- STE-Architecture.md §5.1: RECON Discovery phase -- Portability requirements (implicit in spec) - -**Alignment Assessment:** - -| Spec Requirement | E-ADR Compliance | Notes | -|-----------------|------------------|-------| -| RECON Discovery phase enumerates files | Compliant | Discovery includes domain detection | -| Domain classification | Compliant | CLIENT, SERVER, INFRASTRUCTURE, DATA types | -| Zero-configuration experience | Compliant | Spec implies portability | -| Confidence scoring | Compliant | Graceful degradation for ambiguous cases | - -**Gaps Identified:** -- Spec doesn't explicitly require auto-discovery, but E-ADR enhances portability -- 13-domain structure partially mapped (CLIENT, SERVER, INFRASTRUCTURE, DATA) - -**Graduation Recommendation:** **Ready with note:** Extends spec for portability - ---- - -### E-ADR-010: Conversational Query Interface for Human-AI Seamless Context Discovery - -**Relevant Spec Sections:** -- STE-Architecture.md §4.6: Runtime Components (RSS) -- STE-Cognitive-Execution-Model.md §4.1: Task Analysis -- STE-Cognitive-Execution-Model.md §4.2: Entry Point Discovery - -**Alignment Assessment:** - -| Spec Requirement | E-ADR Compliance | Notes | -|-----------------|------------------|-------| -| Task Analysis parses natural language | Compliant | Intent classification implements this | -| Entry Point Discovery via scoring | Compliant | findEntryPoints with confidence scoring | -| RSS operations for context assembly | Compliant | CQI routes to appropriate RSS operations | -| Bounded probabilism at entry, determinism at traversal | Compliant | Intent classification is bounded; graph traversal is deterministic | - -**Spec Alignment Highlights:** -- CQI implements Task Analysis Protocol concepts -- Intent classification maps to "Task Decomposition" in spec -- Suggested queries align with "Candidate Discovery" in spec -- Fuzzy matching provides graceful degradation (Tier 2/3 fallback) - -**Gaps Identified:** -- None significant. CQI is a natural extension of RSS for conversational access. - -**Graduation Recommendation:** **Ready for ADR graduation** - ---- - -## Graduation Priority Order - -Based on implementation completeness and spec alignment: - -### Tier 1: Ready for Immediate Graduation -1. **E-ADR-001** (RECON Provisional Execution) - Foundation decision, fully compliant -2. **E-ADR-004** (RSS CLI) - Core component, fully compliant -3. **E-ADR-010** (CQI) - RSS extension, fully compliant - -### Tier 2: Ready with Notes -4. **E-ADR-002** (Self-Validation) - Fully compliant -5. **E-ADR-003** (CEM Deferral) - Architecturally sound deferral -6. **E-ADR-005** (JSON Extraction) - Extends spec for data domain -7. **E-ADR-006** (Angular Extraction) - Pioneers frontend domain -8. **E-ADR-009** (Self-Configuring Discovery) - Enhances portability - -### Tier 3: Not Ready -9. **E-ADR-007** (Watchdog) - Implementation incomplete - -### N/A: Documentation Only -10. **E-ADR-008** (Extractor Guide) - Not an implementation decision - ---- - -## Next Steps for Graduation - -### For Each E-ADR in Tier 1/Tier 2: -1. Formal review against ste-spec by human stakeholder -2. Document any spec clarifications needed -3. Create corresponding ADR in ste-spec/adr/ format -4. Update E-ADR status from "Proposed" to "Accepted" -5. Archive E-ADR as historical record - -### For E-ADR-007 (Watchdog): -1. Complete incremental RECON integration -2. Complete RSS hot-reload mechanism -3. Implement self-healing from slice edits -4. Validate against spec requirements -5. Update Implementation status to Complete -6. Re-assess for graduation - ---- - -## Spec Coverage Analysis - -| Spec Section | E-ADR Coverage | -|--------------|----------------| -| §4.5 RECON | E-ADR-001, E-ADR-005, E-ADR-006, E-ADR-009 | -| §4.6 RSS | E-ADR-004, E-ADR-010 | -| §4.7 CEM | E-ADR-003 (deferred) | -| §4.4 Validation | E-ADR-002 | -| §5.1 Bootstrap Flow | E-ADR-001 | -| §5.3 Maintenance Flow | E-ADR-007 (partial) | -| Portability | E-ADR-009 | -| Frontend Semantics | E-ADR-006 | -| Data Semantics | E-ADR-005 | - -**Coverage Summary:** Core spec sections (RECON, RSS, Validation) are well-covered. CEM is intentionally deferred. Maintenance flow (Watchdog) needs completion. - ---- - -**Assessment Complete** - -*This document should be reviewed by a human stakeholder to confirm spec interpretation and authorize E-ADR → ADR graduation.* - diff --git a/documentation/reference/alternatives-comparison.md b/documentation/reference/alternatives-comparison.md index 905a216..1a19925 100644 --- a/documentation/reference/alternatives-comparison.md +++ b/documentation/reference/alternatives-comparison.md @@ -298,4 +298,5 @@ ste-runtime is **complementary** to existing tools, not competitive: **Related Documentation:** - [Architecture](../architecture.md) — ste-runtime technical architecture - [MATURITY.md](../../MATURITY.md) — Production readiness assessment -- [E-ADR-001](../e-adr/E-ADR-001-RECON-Provisional-Execution.md) — RECON design decisions +- [ADR-L-0001](../../adrs/rendered/ADR-L-0001.md) — RECON design decisions + diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..ec93347 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,53 @@ +import js from '@eslint/js'; +import globals from 'globals'; +import tseslint from 'typescript-eslint'; + +export default tseslint.config( + { + ignores: [ + 'coverage/**', + 'dist/**', + 'fixtures/**', + 'node_modules/**', + '.ste/**', + '.ste-self/**', + ], + linterOptions: { + reportUnusedDisableDirectives: 'off', + }, + }, + js.configs.recommended, + ...tseslint.configs.recommended, + { + files: ['src/**/*.ts', 'vitest.config.ts'], + languageOptions: { + ecmaVersion: 2022, + sourceType: 'module', + globals: { + ...globals.es2022, + ...globals.node, + afterAll: 'readonly', + afterEach: 'readonly', + beforeAll: 'readonly', + beforeEach: 'readonly', + describe: 'readonly', + expect: 'readonly', + it: 'readonly', + vi: 'readonly', + }, + }, + rules: { + 'no-duplicate-imports': 'warn', + 'prefer-const': 'warn', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-unused-vars': [ + 'warn', + { + argsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + varsIgnorePattern: '^_', + }, + ], + }, + }, +); diff --git a/fixtures/python-sample/.ste-self/state/graph-metrics.json b/fixtures/python-sample/.ste-self/state/graph-metrics.json new file mode 100644 index 0000000..436b2ba --- /dev/null +++ b/fixtures/python-sample/.ste-self/state/graph-metrics.json @@ -0,0 +1,18 @@ +{ + "totalComponents": 0, + "componentsByDomain": {}, + "componentsByType": {}, + "avgDependencyDepth": 0, + "maxDependencyDepth": 0, + "p95DependencyDepth": 0, + "avgDependentDepth": 0, + "maxDependentDepth": 0, + "avgDependenciesPerComponent": 0, + "avgDependentsPerComponent": 0, + "detectedPattern": "mixed", + "hasDeepTrees": false, + "hasWideNetwork": false, + "recommendedDepth": 2, + "reasoning": "Empty graph, using default depth=2", + "lastAnalyzed": "2026-03-12T05:50:06.662Z" +} \ No newline at end of file diff --git a/fixtures/python-sample/.ste/state/api/endpoints/api-GET-api-greet-name.yaml b/fixtures/python-sample/.ste/state/api/endpoints/api-GET-api-greet-name.yaml index 83552a6..834daa3 100644 --- a/fixtures/python-sample/.ste/state/api/endpoints/api-GET-api-greet-name.yaml +++ b/fixtures/python-sample/.ste/state/api/endpoints/api-GET-api-greet-name.yaml @@ -15,7 +15,7 @@ _slice: extraction: method: static confidence: high - timestamp: '2026-01-12T02:14:45.530Z' + timestamp: '2026-03-12T05:50:05.236Z' endpoint: id: api-GET-api-greet-name method: GET diff --git a/fixtures/python-sample/.ste/state/api/endpoints/api-GET-api-users-user-id.yaml b/fixtures/python-sample/.ste/state/api/endpoints/api-GET-api-users-user-id.yaml index 83d42c8..bed63f0 100644 --- a/fixtures/python-sample/.ste/state/api/endpoints/api-GET-api-users-user-id.yaml +++ b/fixtures/python-sample/.ste/state/api/endpoints/api-GET-api-users-user-id.yaml @@ -15,7 +15,7 @@ _slice: extraction: method: static confidence: high - timestamp: '2026-01-12T02:14:45.530Z' + timestamp: '2026-03-12T05:50:05.236Z' endpoint: id: api-GET-api-users-user-id method: GET diff --git a/fixtures/python-sample/.ste/state/api/endpoints/api-GET-api-users.yaml b/fixtures/python-sample/.ste/state/api/endpoints/api-GET-api-users.yaml index cd4d4d7..7d28356 100644 --- a/fixtures/python-sample/.ste/state/api/endpoints/api-GET-api-users.yaml +++ b/fixtures/python-sample/.ste/state/api/endpoints/api-GET-api-users.yaml @@ -15,7 +15,7 @@ _slice: extraction: method: static confidence: high - timestamp: '2026-01-12T02:14:45.530Z' + timestamp: '2026-03-12T05:50:05.236Z' endpoint: id: api-GET-api-users method: GET diff --git a/fixtures/python-sample/.ste/state/api/endpoints/api-POST-api-users.yaml b/fixtures/python-sample/.ste/state/api/endpoints/api-POST-api-users.yaml index e7d1ac0..21c0a2e 100644 --- a/fixtures/python-sample/.ste/state/api/endpoints/api-POST-api-users.yaml +++ b/fixtures/python-sample/.ste/state/api/endpoints/api-POST-api-users.yaml @@ -15,7 +15,7 @@ _slice: extraction: method: static confidence: high - timestamp: '2026-01-12T02:14:45.530Z' + timestamp: '2026-03-12T05:50:05.236Z' endpoint: id: api-POST-api-users method: POST diff --git a/fixtures/python-sample/.ste/state/api/index.yaml b/fixtures/python-sample/.ste/state/api/index.yaml index ca6f9ce..1535883 100644 --- a/fixtures/python-sample/.ste/state/api/index.yaml +++ b/fixtures/python-sample/.ste/state/api/index.yaml @@ -10,7 +10,7 @@ _slice: extraction: method: static confidence: high - timestamp: '2026-01-12T02:14:45.530Z' + timestamp: '2026-03-12T05:50:05.236Z' endpoints: - id: api-GET-api-greet-name method: GET diff --git a/fixtures/python-sample/.ste/state/data/entities/data-GreetingConfig.yaml b/fixtures/python-sample/.ste/state/data/entities/data-GreetingConfig.yaml index a85dc9d..f6758ca 100644 --- a/fixtures/python-sample/.ste/state/data/entities/data-GreetingConfig.yaml +++ b/fixtures/python-sample/.ste/state/data/entities/data-GreetingConfig.yaml @@ -15,7 +15,7 @@ _slice: extraction: method: static confidence: high - timestamp: '2026-01-12T02:14:45.530Z' + timestamp: '2026-03-12T05:50:05.236Z' entity: id: data-GreetingConfig name: GreetingConfig diff --git a/fixtures/python-sample/.ste/state/data/entities/data-User.yaml b/fixtures/python-sample/.ste/state/data/entities/data-User.yaml index 5926346..f885380 100644 --- a/fixtures/python-sample/.ste/state/data/entities/data-User.yaml +++ b/fixtures/python-sample/.ste/state/data/entities/data-User.yaml @@ -15,7 +15,7 @@ _slice: extraction: method: static confidence: high - timestamp: '2026-01-12T02:14:45.530Z' + timestamp: '2026-03-12T05:50:05.236Z' entity: id: data-User name: User diff --git a/fixtures/python-sample/.ste/state/data/index.yaml b/fixtures/python-sample/.ste/state/data/index.yaml index 2e180f2..9868906 100644 --- a/fixtures/python-sample/.ste/state/data/index.yaml +++ b/fixtures/python-sample/.ste/state/data/index.yaml @@ -10,7 +10,7 @@ _slice: extraction: method: static confidence: high - timestamp: '2026-01-12T02:14:45.530Z' + timestamp: '2026-03-12T05:50:05.236Z' entities: - id: data-GreetingConfig name: GreetingConfig diff --git a/fixtures/python-sample/.ste/state/graph-metrics.json b/fixtures/python-sample/.ste/state/graph-metrics.json index 0f6f069..988cba5 100644 --- a/fixtures/python-sample/.ste/state/graph-metrics.json +++ b/fixtures/python-sample/.ste/state/graph-metrics.json @@ -24,5 +24,5 @@ "hasWideNetwork": false, "recommendedDepth": 2, "reasoning": "Detected flat architecture. Avg depth: 0.8, P95 depth: 2.0, Max depth: 2. Recommended depth: 2.", - "lastAnalyzed": "2026-01-12T02:14:45.841Z" + "lastAnalyzed": "2026-03-12T05:50:06.647Z" } \ No newline at end of file diff --git a/fixtures/python-sample/.ste/state/graph/internal/index.yaml b/fixtures/python-sample/.ste/state/graph/internal/index.yaml index b3f39cb..77c41cd 100644 --- a/fixtures/python-sample/.ste/state/graph/internal/index.yaml +++ b/fixtures/python-sample/.ste/state/graph/internal/index.yaml @@ -11,7 +11,7 @@ _slice: extraction: method: static confidence: high - timestamp: '2026-01-12T02:14:45.530Z' + timestamp: '2026-03-12T05:50:05.236Z' modules: - id: module-app-__init__ path: app/__init__.py diff --git a/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-__init__.yaml b/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-__init__.yaml index 91a09f1..f3dffa2 100644 --- a/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-__init__.yaml +++ b/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-__init__.yaml @@ -13,7 +13,7 @@ _slice: extraction: method: static confidence: high - timestamp: '2026-01-12T02:14:45.530Z' + timestamp: '2026-03-12T05:50:05.236Z' module: id: module-app-__init__ path: app/__init__.py diff --git a/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-api.yaml b/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-api.yaml index c96c993..d430126 100644 --- a/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-api.yaml +++ b/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-api.yaml @@ -31,7 +31,7 @@ _slice: extraction: method: static confidence: high - timestamp: '2026-01-12T02:14:45.530Z' + timestamp: '2026-03-12T05:50:05.236Z' module: id: module-app-api path: app/api.py diff --git a/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-services-__init__.yaml b/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-services-__init__.yaml index 3343b31..21b05ef 100644 --- a/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-services-__init__.yaml +++ b/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-services-__init__.yaml @@ -13,7 +13,7 @@ _slice: extraction: method: static confidence: high - timestamp: '2026-01-12T02:14:45.530Z' + timestamp: '2026-03-12T05:50:05.236Z' module: id: module-app-services-__init__ path: app/services/__init__.py diff --git a/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-services-greeting.yaml b/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-services-greeting.yaml index ab9a116..894401f 100644 --- a/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-services-greeting.yaml +++ b/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-services-greeting.yaml @@ -19,7 +19,7 @@ _slice: extraction: method: static confidence: high - timestamp: '2026-01-12T02:14:45.530Z' + timestamp: '2026-03-12T05:50:05.236Z' module: id: module-app-services-greeting path: app/services/greeting.py diff --git a/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-services-user_service.yaml b/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-services-user_service.yaml index 5f6887f..bbfbc90 100644 --- a/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-services-user_service.yaml +++ b/fixtures/python-sample/.ste/state/graph/internal/modules/module-app-services-user_service.yaml @@ -19,7 +19,7 @@ _slice: extraction: method: static confidence: high - timestamp: '2026-01-12T02:14:45.530Z' + timestamp: '2026-03-12T05:50:05.236Z' module: id: module-app-services-user_service path: app/services/user_service.py diff --git a/fixtures/python-sample/.ste/state/manifest/recon-manifest.json b/fixtures/python-sample/.ste/state/manifest/recon-manifest.json index f3f07f2..dcbc4ee 100644 --- a/fixtures/python-sample/.ste/state/manifest/recon-manifest.json +++ b/fixtures/python-sample/.ste/state/manifest/recon-manifest.json @@ -1,34 +1,34 @@ { "version": 1, - "generatedAt": "2026-01-12T02:14:45.799Z", + "generatedAt": "2026-03-12T05:50:06.214Z", "files": { "app/api.py": { "path": "app/api.py", - "mtimeMs": 1768161171728.0117, + "mtimeMs": 1768013953694.0403, "size": 1421, "hash": "b5e175ca50dcd6712422e6ea18130e40ac1a9c6ccb519ca724945092ae4dbfc0" }, "app/__init__.py": { "path": "app/__init__.py", - "mtimeMs": 1768161171727.421, + "mtimeMs": 1768013953694.0403, "size": 49, "hash": "c71784319958aed60cd445890c62b7946832fc781b44c73c058b30da390ec31d" }, "app/services/greeting.py": { "path": "app/services/greeting.py", - "mtimeMs": 1768161171728.9526, + "mtimeMs": 1768013953709.6902, "size": 1010, "hash": "6d30729c2393d770edb880effc872f534f88cf95d2bd68945f84d9599fef8665" }, "app/services/user_service.py": { "path": "app/services/user_service.py", - "mtimeMs": 1768161171730.1372, + "mtimeMs": 1768013953712.8206, "size": 1159, "hash": "a670c703d9f2769fa2f7f9f6370e6792a8c01373649fc1259ed2464c81cdb07e" }, "app/services/__init__.py": { "path": "app/services/__init__.py", - "mtimeMs": 1768161171728.9526, + "mtimeMs": 1768013953716.829, "size": 23, "hash": "35e97f8b497a8eb82f0c8f40e86919e1896f8e35cf30a1c1e0491d39356c0793" } diff --git a/instructions/adaptive-tool-parameters.md b/instructions/adaptive-tool-parameters.md index 88b5f4b..2ef9234 100644 --- a/instructions/adaptive-tool-parameters.md +++ b/instructions/adaptive-tool-parameters.md @@ -461,9 +461,10 @@ if (usageStats.get('get_dependencies').avgDepth > recommendedDepth) { ## References -- [E-ADR-011 §3: Adaptive Tool Parameters](documentation/e-adr/E-ADR-011-ste-runtime-MCP-Server.md) +- [ADR-P-0004 §3: Adaptive Tool Parameters](../adrs/rendered/ADR-P-0004.md) - [Graph Topology Analyzer Implementation](../src/rss/graph-topology-analyzer.ts) - [RSS Programmatic API](./RSS-PROGRAMMATIC-API.md) + diff --git a/package-lock.json b/package-lock.json index 8f33e43..b0a932e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.9.0-experimental", "license": "Apache-2.0", "dependencies": { - "@modelcontextprotocol/sdk": "1.25.3", + "@modelcontextprotocol/sdk": "^1.27.1", "chokidar": "^3.5.3", "commander": "^14.0.2", "execa": "^8.0.1", @@ -25,11 +25,15 @@ "ste": "dist/cli/index.js" }, "devDependencies": { + "@eslint/js": "^9.22.0", "@mermaid-js/mermaid-cli": "^11.4.0", "@types/js-yaml": "^4.0.9", "@types/node": "^20.0.0", "@vitest/coverage-v8": "^3.2.0", + "eslint": "^9.22.0", + "globals": "^16.0.0", "husky": "9.1.7", + "typescript-eslint": "^8.26.1", "vitest": "^3.2.0" }, "engines": { @@ -169,60 +173,46 @@ "license": "MIT" }, "node_modules/@chevrotain/cst-dts-gen": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", - "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.1.2.tgz", + "integrity": "sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@chevrotain/gast": "11.0.3", - "@chevrotain/types": "11.0.3", - "lodash-es": "4.17.21" + "@chevrotain/gast": "11.1.2", + "@chevrotain/types": "11.1.2", + "lodash-es": "4.17.23" } }, - "node_modules/@chevrotain/cst-dts-gen/node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "dev": true, - "license": "MIT" - }, "node_modules/@chevrotain/gast": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz", - "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.1.2.tgz", + "integrity": "sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@chevrotain/types": "11.0.3", - "lodash-es": "4.17.21" + "@chevrotain/types": "11.1.2", + "lodash-es": "4.17.23" } }, - "node_modules/@chevrotain/gast/node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "dev": true, - "license": "MIT" - }, "node_modules/@chevrotain/regexp-to-ast": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", - "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.1.2.tgz", + "integrity": "sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw==", "dev": true, "license": "Apache-2.0" }, "node_modules/@chevrotain/types": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz", - "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.1.2.tgz", + "integrity": "sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==", "dev": true, "license": "Apache-2.0" }, "node_modules/@chevrotain/utils": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz", - "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.1.2.tgz", + "integrity": "sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA==", "dev": true, "license": "Apache-2.0" }, @@ -668,6 +658,235 @@ "node": ">=18" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@floating-ui/core": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.4.tgz", @@ -777,9 +996,9 @@ } }, "node_modules/@hono/node-server": { - "version": "1.19.9", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.9.tgz", - "integrity": "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==", + "version": "1.19.11", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz", + "integrity": "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==", "license": "MIT", "engines": { "node": ">=18.14.1" @@ -788,6 +1007,58 @@ "hono": "^4" } }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@iconify/types": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", @@ -911,19 +1182,19 @@ } }, "node_modules/@mermaid-js/parser": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.6.3.tgz", - "integrity": "sha512-lnjOhe7zyHjc+If7yT4zoedx2vo4sHaTmtkl1+or8BRTnCtDmcTpAjpzDSfCZrshM5bCoz0GyidzadJAH1xobA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-1.0.1.tgz", + "integrity": "sha512-opmV19kN1JsK0T6HhhokHpcVkqKpF+x2pPDKKM2ThHtZAB5F4PROopk0amuVYK5qMrIA4erzpNm8gmPNJgMDxQ==", "dev": true, "license": "MIT", "dependencies": { - "langium": "3.3.1" + "langium": "^4.0.0" } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.25.3", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.25.3.tgz", - "integrity": "sha512-vsAMBMERybvYgKbg/l4L1rhS7VXV1c0CtyJg72vwxONVX0l4ZfKVAnZEWTQixJGTzKnELjQ59e4NbdFDALRiAQ==", + "version": "1.27.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.27.1.tgz", + "integrity": "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==", "license": "MIT", "dependencies": { "@hono/node-server": "^1.19.9", @@ -934,14 +1205,15 @@ "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", - "express": "^5.0.1", - "express-rate-limit": "^7.5.0", - "jose": "^6.1.1", + "express": "^5.2.1", + "express-rate-limit": "^8.2.1", + "hono": "^4.11.4", + "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", - "zod-to-json-schema": "^3.25.0" + "zod-to-json-schema": "^3.25.1" }, "engines": { "node": ">=18" @@ -1134,9 +1406,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.0.tgz", - "integrity": "sha512-tPgXB6cDTndIe1ah7u6amCI1T0SsnlOuKgg10Xh3uizJk4e5M1JGaUMk7J4ciuAUcFpbOiNhm2XIjP9ON0dUqA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", "cpu": [ "arm" ], @@ -1148,9 +1420,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.0.tgz", - "integrity": "sha512-sa4LyseLLXr1onr97StkU1Nb7fWcg6niokTwEVNOO7awaKaoRObQ54+V/hrF/BP1noMEaaAW6Fg2d/CfLiq3Mg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", "cpu": [ "arm64" ], @@ -1162,9 +1434,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.57.0.tgz", - "integrity": "sha512-/NNIj9A7yLjKdmkx5dC2XQ9DmjIECpGpwHoGmA5E1AhU0fuICSqSWScPhN1yLCkEdkCwJIDu2xIeLPs60MNIVg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", "cpu": [ "arm64" ], @@ -1176,9 +1448,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.0.tgz", - "integrity": "sha512-xoh8abqgPrPYPr7pTYipqnUi1V3em56JzE/HgDgitTqZBZ3yKCWI+7KUkceM6tNweyUKYru1UMi7FC060RyKwA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", "cpu": [ "x64" ], @@ -1190,9 +1462,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.0.tgz", - "integrity": "sha512-PCkMh7fNahWSbA0OTUQ2OpYHpjZZr0hPr8lId8twD7a7SeWrvT3xJVyza+dQwXSSq4yEQTMoXgNOfMCsn8584g==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", "cpu": [ "arm64" ], @@ -1204,9 +1476,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.0.tgz", - "integrity": "sha512-1j3stGx+qbhXql4OCDZhnK7b01s6rBKNybfsX+TNrEe9JNq4DLi1yGiR1xW+nL+FNVvI4D02PUnl6gJ/2y6WJA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", "cpu": [ "x64" ], @@ -1218,9 +1490,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.0.tgz", - "integrity": "sha512-eyrr5W08Ms9uM0mLcKfM/Uzx7hjhz2bcjv8P2uynfj0yU8GGPdz8iYrBPhiLOZqahoAMB8ZiolRZPbbU2MAi6Q==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", "cpu": [ "arm" ], @@ -1232,9 +1504,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.0.tgz", - "integrity": "sha512-Xds90ITXJCNyX9pDhqf85MKWUI4lqjiPAipJ8OLp8xqI2Ehk+TCVhF9rvOoN8xTbcafow3QOThkNnrM33uCFQA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", "cpu": [ "arm" ], @@ -1246,9 +1518,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.0.tgz", - "integrity": "sha512-Xws2KA4CLvZmXjy46SQaXSejuKPhwVdaNinldoYfqruZBaJHqVo6hnRa8SDo9z7PBW5x84SH64+izmldCgbezw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", "cpu": [ "arm64" ], @@ -1260,9 +1532,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.0.tgz", - "integrity": "sha512-hrKXKbX5FdaRJj7lTMusmvKbhMJSGWJ+w++4KmjiDhpTgNlhYobMvKfDoIWecy4O60K6yA4SnztGuNTQF+Lplw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", "cpu": [ "arm64" ], @@ -1274,9 +1546,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.0.tgz", - "integrity": "sha512-6A+nccfSDGKsPm00d3xKcrsBcbqzCTAukjwWK6rbuAnB2bHaL3r9720HBVZ/no7+FhZLz/U3GwwZZEh6tOSI8Q==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", "cpu": [ "loong64" ], @@ -1288,9 +1560,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.0.tgz", - "integrity": "sha512-4P1VyYUe6XAJtQH1Hh99THxr0GKMMwIXsRNOceLrJnaHTDgk1FTcTimDgneRJPvB3LqDQxUmroBclQ1S0cIJwQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", "cpu": [ "loong64" ], @@ -1302,9 +1574,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.0.tgz", - "integrity": "sha512-8Vv6pLuIZCMcgXre6c3nOPhE0gjz1+nZP6T+hwWjr7sVH8k0jRkH+XnfjjOTglyMBdSKBPPz54/y1gToSKwrSQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", "cpu": [ "ppc64" ], @@ -1316,9 +1588,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.0.tgz", - "integrity": "sha512-r1te1M0Sm2TBVD/RxBPC6RZVwNqUTwJTA7w+C/IW5v9Ssu6xmxWEi+iJQlpBhtUiT1raJ5b48pI8tBvEjEFnFA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", "cpu": [ "ppc64" ], @@ -1330,9 +1602,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.0.tgz", - "integrity": "sha512-say0uMU/RaPm3CDQLxUUTF2oNWL8ysvHkAjcCzV2znxBr23kFfaxocS9qJm+NdkRhF8wtdEEAJuYcLPhSPbjuQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", "cpu": [ "riscv64" ], @@ -1344,9 +1616,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.0.tgz", - "integrity": "sha512-/MU7/HizQGsnBREtRpcSbSV1zfkoxSTR7wLsRmBPQ8FwUj5sykrP1MyJTvsxP5KBq9SyE6kH8UQQQwa0ASeoQQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", "cpu": [ "riscv64" ], @@ -1358,9 +1630,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.0.tgz", - "integrity": "sha512-Q9eh+gUGILIHEaJf66aF6a414jQbDnn29zeu0eX3dHMuysnhTvsUvZTCAyZ6tJhUjnvzBKE4FtuaYxutxRZpOg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", "cpu": [ "s390x" ], @@ -1372,9 +1644,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.57.0.tgz", - "integrity": "sha512-OR5p5yG5OKSxHReWmwvM0P+VTPMwoBS45PXTMYaskKQqybkS3Kmugq1W+YbNWArF8/s7jQScgzXUhArzEQ7x0A==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", "cpu": [ "x64" ], @@ -1386,9 +1658,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.0.tgz", - "integrity": "sha512-XeatKzo4lHDsVEbm1XDHZlhYZZSQYym6dg2X/Ko0kSFgio+KXLsxwJQprnR48GvdIKDOpqWqssC3iBCjoMcMpw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", "cpu": [ "x64" ], @@ -1400,9 +1672,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.0.tgz", - "integrity": "sha512-Lu71y78F5qOfYmubYLHPcJm74GZLU6UJ4THkf/a1K7Tz2ycwC2VUbsqbJAXaR6Bx70SRdlVrt2+n5l7F0agTUw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", "cpu": [ "x64" ], @@ -1414,9 +1686,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.0.tgz", - "integrity": "sha512-v5xwKDWcu7qhAEcsUubiav7r+48Uk/ENWdr82MBZZRIm7zThSxCIVDfb3ZeRRq9yqk+oIzMdDo6fCcA5DHfMyA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", "cpu": [ "arm64" ], @@ -1428,9 +1700,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.0.tgz", - "integrity": "sha512-XnaaaSMGSI6Wk8F4KK3QP7GfuuhjGchElsVerCplUuxRIzdvZ7hRBpLR0omCmw+kI2RFJB80nenhOoGXlJ5TfQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", "cpu": [ "arm64" ], @@ -1442,9 +1714,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.0.tgz", - "integrity": "sha512-3K1lP+3BXY4t4VihLw5MEg6IZD3ojSYzqzBG571W3kNQe4G4CcFpSUQVgurYgib5d+YaCjeFow8QivWp8vuSvA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", "cpu": [ "ia32" ], @@ -1456,9 +1728,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.0.tgz", - "integrity": "sha512-MDk610P/vJGc5L5ImE4k5s+GZT3en0KoK1MKPXCRgzmksAMk79j4h3k1IerxTNqwDLxsGxStEZVBqG0gIqZqoA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", "cpu": [ "x64" ], @@ -1470,9 +1742,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.0.tgz", - "integrity": "sha512-Zv7v6q6aV+VslnpwzqKAmrk5JdVkLUzok2208ZXGipjb+msxBr/fJPZyeEXiFgH7k62Ak0SLIfxQRZQvTuf7rQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", "cpu": [ "x64" ], @@ -1853,6 +2125,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "20.19.30", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", @@ -1883,6 +2162,299 @@ "@types/node": "*" } }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.0.tgz", + "integrity": "sha512-qeu4rTHR3/IaFORbD16gmjq9+rEs9fGKdX0kF6BKSfi+gCuG3RCKLlSBYzn/bGsY9Tj7KE/DAQStbp8AHJGHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.57.0", + "@typescript-eslint/type-utils": "8.57.0", + "@typescript-eslint/utils": "8.57.0", + "@typescript-eslint/visitor-keys": "8.57.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.57.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.0.tgz", + "integrity": "sha512-XZzOmihLIr8AD1b9hL9ccNMzEMWt/dE2u7NyTY9jJG6YNiNthaD5XtUHVF2uCXZ15ng+z2hT3MVuxnUYhq6k1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.57.0", + "@typescript-eslint/types": "8.57.0", + "@typescript-eslint/typescript-estree": "8.57.0", + "@typescript-eslint/visitor-keys": "8.57.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.0.tgz", + "integrity": "sha512-pR+dK0BlxCLxtWfaKQWtYr7MhKmzqZxuii+ZjuFlZlIGRZm22HnXFqa2eY+90MUz8/i80YJmzFGDUsi8dMOV5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.57.0", + "@typescript-eslint/types": "^8.57.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.0.tgz", + "integrity": "sha512-nvExQqAHF01lUM66MskSaZulpPL5pgy5hI5RfrxviLgzZVffB5yYzw27uK/ft8QnKXI2X0LBrHJFr1TaZtAibw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.57.0", + "@typescript-eslint/visitor-keys": "8.57.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.0.tgz", + "integrity": "sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.0.tgz", + "integrity": "sha512-yjgh7gmDcJ1+TcEg8x3uWQmn8ifvSupnPfjP21twPKrDP/pTHlEQgmKcitzF/rzPSmv7QjJ90vRpN4U+zoUjwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.57.0", + "@typescript-eslint/typescript-estree": "8.57.0", + "@typescript-eslint/utils": "8.57.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.0.tgz", + "integrity": "sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.0.tgz", + "integrity": "sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.57.0", + "@typescript-eslint/tsconfig-utils": "8.57.0", + "@typescript-eslint/types": "8.57.0", + "@typescript-eslint/visitor-keys": "8.57.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.0.tgz", + "integrity": "sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.57.0", + "@typescript-eslint/types": "8.57.0", + "@typescript-eslint/typescript-estree": "8.57.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.0.tgz", + "integrity": "sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.57.0", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@upsetjs/venn.js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@upsetjs/venn.js/-/venn.js-2.0.0.tgz", + "integrity": "sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "d3-selection": "^3.0.0", + "d3-transition": "^3.0.1" + } + }, "node_modules/@vitest/coverage-v8": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz", @@ -2105,6 +2677,16 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -2117,9 +2699,9 @@ } }, "node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -2412,9 +2994,9 @@ "license": "MIT" }, "node_modules/basic-ftp": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.1.0.tgz", - "integrity": "sha512-RkaJzeJKDbaDWTIPiJwubyljaEPwpVWkm9Rt5h9Nd6h7tEXTJ3VB4qxdZBioV7JO5yLUaOKwz7vDOzlncUsegw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.0.tgz", + "integrity": "sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==", "dev": true, "license": "MIT", "peer": true, @@ -2570,7 +3152,6 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" } @@ -2626,18 +3207,18 @@ } }, "node_modules/chevrotain": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", - "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.1.2.tgz", + "integrity": "sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@chevrotain/cst-dts-gen": "11.0.3", - "@chevrotain/gast": "11.0.3", - "@chevrotain/regexp-to-ast": "11.0.3", - "@chevrotain/types": "11.0.3", - "@chevrotain/utils": "11.0.3", - "lodash-es": "4.17.21" + "@chevrotain/cst-dts-gen": "11.1.2", + "@chevrotain/gast": "11.1.2", + "@chevrotain/regexp-to-ast": "11.1.2", + "@chevrotain/types": "11.1.2", + "@chevrotain/utils": "11.1.2", + "lodash-es": "4.17.23" } }, "node_modules/chevrotain-allstar": { @@ -2653,13 +3234,6 @@ "chevrotain": "^11.0.0" } }, - "node_modules/chevrotain/node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "dev": true, - "license": "MIT" - }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -2886,6 +3460,13 @@ "node": ">=20" } }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, "node_modules/confbox": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", @@ -3569,9 +4150,9 @@ } }, "node_modules/dagre-d3-es": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.13.tgz", - "integrity": "sha512-efEhnxpSuwpYOKRm/L5KbqoZmNNukHa/Flty4Wp62JRvgH2ojwVgPgdYyr4twpieZnyRDdIH7PY2mopX26+j2Q==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.14.tgz", + "integrity": "sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==", "dev": true, "license": "MIT", "dependencies": { @@ -3624,6 +4205,13 @@ "node": ">=6" } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, "node_modules/degenerator": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", @@ -3694,9 +4282,9 @@ "license": "MIT" }, "node_modules/dompurify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.1.tgz", - "integrity": "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.3.tgz", + "integrity": "sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==", "dev": true, "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { @@ -3875,27 +4463,242 @@ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/eslint": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": ">=6.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "optionalDependencies": { - "source-map": "~0.6.1" + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -3913,13 +4716,38 @@ "node": ">=4" } }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "engines": { "node": ">=4.0" } @@ -3940,7 +4768,6 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -4083,10 +4910,13 @@ } }, "node_modules/express-rate-limit": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", - "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz", + "integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==", "license": "MIT", + "dependencies": { + "ip-address": "10.1.0" + }, "engines": { "node": ">= 16" }, @@ -4166,6 +4996,20 @@ "node": ">=8.6.0" } }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-redact": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", @@ -4212,6 +5056,19 @@ "pend": "~1.2.0" } }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -4245,6 +5102,44 @@ "url": "https://opencollective.com/express" } }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.1.tgz", + "integrity": "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==", + "dev": true, + "license": "ISC" + }, "node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", @@ -4412,6 +5307,19 @@ "node": ">= 6" } }, + "node_modules/globals": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", + "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globby": { "version": "13.2.2", "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", @@ -4495,11 +5403,10 @@ } }, "node_modules/hono": { - "version": "4.11.7", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.11.7.tgz", - "integrity": "sha512-l7qMiNee7t82bH3SeyUCt9UF15EVmaBvsppY2zQtrbIhl/yzBTny+YUxsVjSjQ6gaqaeVtZmGocom8TzBlA4Yw==", + "version": "4.12.7", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.7.tgz", + "integrity": "sha512-jq9l1DM0zVIvsm3lv9Nw9nlJnMNPOcAtsbsgiUhWcFzPE99Gvo6yRTlszSLLYacMeQ6quHD6hMfId8crVHvexw==", "license": "MIT", - "peer": true, "engines": { "node": ">=16.9.0" } @@ -4656,7 +5563,6 @@ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -4679,6 +5585,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -4699,9 +5615,7 @@ "version": "10.1.0", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 12" } @@ -4953,6 +5867,13 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -4973,6 +5894,13 @@ "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", "license": "BSD-2-Clause" }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/katex": { "version": "0.16.28", "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.28.tgz", @@ -5000,6 +5928,16 @@ "node": ">= 12" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/khroma": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", @@ -5007,20 +5945,21 @@ "dev": true }, "node_modules/langium": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/langium/-/langium-3.3.1.tgz", - "integrity": "sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/langium/-/langium-4.2.1.tgz", + "integrity": "sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ==", "dev": true, "license": "MIT", "dependencies": { - "chevrotain": "~11.0.3", - "chevrotain-allstar": "~0.3.0", + "chevrotain": "~11.1.1", + "chevrotain-allstar": "~0.3.1", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", - "vscode-uri": "~3.0.8" + "vscode-uri": "~3.1.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.10.0", + "npm": ">=10.2.3" } }, "node_modules/layout-base": { @@ -5030,6 +5969,20 @@ "dev": true, "license": "MIT" }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/lilconfig": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", @@ -5050,6 +6003,22 @@ "dev": true, "license": "MIT" }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lodash": { "version": "4.17.23", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", @@ -5064,6 +6033,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, "node_modules/loupe": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", @@ -5174,28 +6150,29 @@ } }, "node_modules/mermaid": { - "version": "11.12.2", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.12.2.tgz", - "integrity": "sha512-n34QPDPEKmaeCG4WDMGy0OT6PSyxKCfy2pJgShP+Qow2KLrvWjclwbc3yXfSIf4BanqWEhQEpngWwNp/XhZt6w==", + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.13.0.tgz", + "integrity": "sha512-fEnci+Immw6lKMFI8sqzjlATTyjLkRa6axrEgLV2yHTfv8r+h1wjFbV6xeRtd4rUV1cS4EpR9rwp3Rci7TRWDw==", "dev": true, "license": "MIT", "dependencies": { "@braintree/sanitize-url": "^7.1.1", - "@iconify/utils": "^3.0.1", - "@mermaid-js/parser": "^0.6.3", + "@iconify/utils": "^3.0.2", + "@mermaid-js/parser": "^1.0.1", "@types/d3": "^7.4.3", - "cytoscape": "^3.29.3", + "@upsetjs/venn.js": "^2.0.0", + "cytoscape": "^3.33.1", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", - "dagre-d3-es": "7.0.13", - "dayjs": "^1.11.18", - "dompurify": "^3.2.5", - "katex": "^0.16.22", + "dagre-d3-es": "7.0.14", + "dayjs": "^1.11.19", + "dompurify": "^3.3.1", + "katex": "^0.16.25", "khroma": "^2.1.0", - "lodash-es": "^4.17.21", - "marked": "^16.2.1", + "lodash-es": "^4.17.23", + "marked": "^16.3.0", "roughjs": "^4.6.6", "stylis": "^4.3.6", "ts-dedent": "^2.2.0", @@ -5266,13 +6243,13 @@ } }, "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -5349,6 +6326,13 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, "node_modules/negotiator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", @@ -5482,6 +6466,56 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pac-proxy-agent": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", @@ -5545,7 +6579,6 @@ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "callsites": "^3.0.0" }, @@ -5589,6 +6622,16 @@ "dev": true, "license": "MIT" }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -5948,6 +6991,16 @@ "dev": true, "license": "MIT" }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -6041,6 +7094,16 @@ "once": "^1.3.1" } }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/puppeteer": { "version": "23.11.1", "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-23.11.1.tgz", @@ -6085,9 +7148,9 @@ } }, "node_modules/qs": { - "version": "6.14.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", - "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -6290,7 +7353,6 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=4" } @@ -6313,9 +7375,9 @@ "license": "Unlicense" }, "node_modules/rollup": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.0.tgz", - "integrity": "sha512-e5lPJi/aui4TO1LpAXIRLySmwXSE8k3b9zoGfd42p67wzxog4WHjiZF3M2uheQih4DGyc25QEV4yRBbpueNiUA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", "dev": true, "license": "MIT", "dependencies": { @@ -6329,31 +7391,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.57.0", - "@rollup/rollup-android-arm64": "4.57.0", - "@rollup/rollup-darwin-arm64": "4.57.0", - "@rollup/rollup-darwin-x64": "4.57.0", - "@rollup/rollup-freebsd-arm64": "4.57.0", - "@rollup/rollup-freebsd-x64": "4.57.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.57.0", - "@rollup/rollup-linux-arm-musleabihf": "4.57.0", - "@rollup/rollup-linux-arm64-gnu": "4.57.0", - "@rollup/rollup-linux-arm64-musl": "4.57.0", - "@rollup/rollup-linux-loong64-gnu": "4.57.0", - "@rollup/rollup-linux-loong64-musl": "4.57.0", - "@rollup/rollup-linux-ppc64-gnu": "4.57.0", - "@rollup/rollup-linux-ppc64-musl": "4.57.0", - "@rollup/rollup-linux-riscv64-gnu": "4.57.0", - "@rollup/rollup-linux-riscv64-musl": "4.57.0", - "@rollup/rollup-linux-s390x-gnu": "4.57.0", - "@rollup/rollup-linux-x64-gnu": "4.57.0", - "@rollup/rollup-linux-x64-musl": "4.57.0", - "@rollup/rollup-openbsd-x64": "4.57.0", - "@rollup/rollup-openharmony-arm64": "4.57.0", - "@rollup/rollup-win32-arm64-msvc": "4.57.0", - "@rollup/rollup-win32-ia32-msvc": "4.57.0", - "@rollup/rollup-win32-x64-gnu": "4.57.0", - "@rollup/rollup-win32-x64-msvc": "4.57.0", + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" } }, @@ -6896,6 +7958,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-literal": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", @@ -7256,6 +8331,19 @@ "node": ">=0.6" } }, + "node_modules/ts-api-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, "node_modules/ts-dedent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", @@ -7280,6 +8368,19 @@ "dev": true, "license": "0BSD" }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/type-is": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", @@ -7315,6 +8416,30 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.57.0.tgz", + "integrity": "sha512-W8GcigEMEeB07xEZol8oJ26rigm3+bfPHxHvwbYUlu1fUDsGuQ7Hiskx5xGW/xM4USc9Ephe3jtv7ZYPQntHeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.57.0", + "@typescript-eslint/parser": "8.57.0", + "@typescript-eslint/typescript-estree": "8.57.0", + "@typescript-eslint/utils": "8.57.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, "node_modules/ufo": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz", @@ -7376,6 +8501,16 @@ "node": ">= 0.8" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/use-sync-external-store": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", @@ -7687,9 +8822,9 @@ "license": "MIT" }, "node_modules/vscode-uri": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", - "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", "dev": true, "license": "MIT" }, @@ -7725,6 +8860,16 @@ "node": ">=8" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", @@ -7955,6 +9100,19 @@ "fd-slicer": "~1.1.0" } }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zod": { "version": "3.25.76", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", diff --git a/package.json b/package.json index 2ef7c5a..d0634eb 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,12 @@ "description": "STE Runtime [EXPERIMENTAL] - Component implementation of RECON and RSS for AI-assisted development. NOT production-ready.", "type": "module", "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist", + "README.md", + "LICENSE" + ], "bin": { "ste": "dist/cli/index.js", "recon": "dist/cli/recon-cli.js", @@ -17,9 +23,11 @@ "build": "tsc", "test": "vitest run", "test:watch": "vitest", - "test:unit": "vitest run --testPathPattern='\\.(test|spec)\\.ts$' --exclude='**/integration/**'", - "test:integration": "vitest run --testPathPattern='integration'", + "test:unit": "vitest run", + "test:integration": "node -e \"console.log('No integration tests are currently defined for ste-runtime.')\"", "test:coverage": "vitest run --coverage", + "lint": "eslint src vitest.config.ts", + "lint:fix": "eslint src vitest.config.ts --fix", "recon": "node dist/cli/recon-cli.js", "recon:full": "node dist/cli/recon-cli.js --mode=full", "recon:self": "node dist/cli/recon-cli.js --self", @@ -33,7 +41,7 @@ "prepare": "husky" }, "dependencies": { - "@modelcontextprotocol/sdk": "1.25.3", + "@modelcontextprotocol/sdk": "^1.27.1", "chokidar": "^3.5.3", "commander": "^14.0.2", "execa": "^8.0.1", @@ -48,12 +56,17 @@ "@types/js-yaml": "^4.0.9", "@types/node": "^20.0.0", "@vitest/coverage-v8": "^3.2.0", + "@eslint/js": "^9.22.0", + "eslint": "^9.22.0", + "globals": "^16.0.0", "husky": "9.1.7", + "typescript-eslint": "^8.26.1", "vitest": "^3.2.0" }, "engines": { "node": ">=18.0.0" }, + "packageManager": "npm@10.9.4", "keywords": [ "ste", "recon", @@ -63,5 +76,13 @@ "context-assembly", "ai-agent" ], - "license": "Apache-2.0" + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "git+https://github.com/egallmann/ste-runtime.git" + }, + "bugs": { + "url": "https://github.com/egallmann/ste-runtime/issues" + }, + "homepage": "https://github.com/egallmann/ste-runtime#readme" } diff --git a/src/aidoc/python-aidoc-generator.ts b/src/aidoc/python-aidoc-generator.ts deleted file mode 100644 index ebf9fd3..0000000 --- a/src/aidoc/python-aidoc-generator.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { ExtractedStructure } from '../extractors/base-extractor.js'; - -export function generatePythonAidoc(structures: ExtractedStructure[]): string { - // Placeholder AIDoc generator - const count = structures.length; - return `Generated placeholder AIDoc for ${count} Python artifact(s).`; -} - diff --git a/src/cli/discovery-cli.ts b/src/cli/discovery-cli.ts deleted file mode 100644 index dfeaf8d..0000000 --- a/src/cli/discovery-cli.ts +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env node -/** - * Discovery CLI - Test and debug project structure discovery - * - * Usage: - * node dist/cli/discovery-cli.js - * node dist/cli/discovery-cli.js /path/to/project - */ - -import { ProjectDiscovery, DomainType } from '../discovery/index.js'; -import path from 'path'; - -function formatDomainType(type: DomainType): string { - const colors = { - [DomainType.CLIENT]: '\x1b[36m', // Cyan - [DomainType.SERVER]: '\x1b[33m', // Yellow - [DomainType.INFRASTRUCTURE]: '\x1b[35m', // Magenta - [DomainType.DATA]: '\x1b[32m', // Green - [DomainType.SHARED]: '\x1b[37m', // White - [DomainType.UNKNOWN]: '\x1b[90m' // Gray - }; - - const reset = '\x1b[0m'; - const color = colors[type] || reset; - - return `${color}${type}${reset}`; -} - -function formatConfidence(confidence: number): string { - if (confidence >= 0.8) return '\x1b[32m' + confidence.toFixed(2) + '\x1b[0m'; // Green - if (confidence >= 0.5) return '\x1b[33m' + confidence.toFixed(2) + '\x1b[0m'; // Yellow - return '\x1b[31m' + confidence.toFixed(2) + '\x1b[0m'; // Red -} - -async function main() { - const targetDir = process.argv[2] || process.cwd(); - const absolutePath = path.resolve(targetDir); - - console.log('='.repeat(80)); - console.log('PROJECT STRUCTURE DISCOVERY'); - console.log('='.repeat(80)); - console.log(); - console.log(`Target: ${absolutePath}`); - console.log(); - - const discovery = new ProjectDiscovery(absolutePath); - - console.log('Discovering project structure...'); - console.log(); - - const startTime = Date.now(); - const structure = await discovery.discover(); - const duration = Date.now() - startTime; - - console.log('='.repeat(80)); - console.log('DISCOVERY RESULTS'); - console.log('='.repeat(80)); - console.log(); - console.log(`Architecture: ${structure.architecture}`); - console.log(`Domains Found: ${structure.domains.length}`); - console.log(`Discovery Time: ${duration}ms`); - console.log(); - - if (structure.domains.length === 0) { - console.log('\x1b[33mNo domains discovered. Project may have unusual structure.\x1b[0m'); - console.log(); - return; - } - - console.log('='.repeat(80)); - console.log('DOMAINS'); - console.log('='.repeat(80)); - console.log(); - - for (const domain of structure.domains) { - console.log(`Domain: \x1b[1m${domain.name}\x1b[0m`); - console.log(` Type: ${formatDomainType(domain.type)}`); - console.log(` Confidence: ${formatConfidence(domain.confidence)}`); - console.log(` Framework: ${domain.framework || 'unknown'}`); - console.log(` Root Paths:`); - domain.rootPaths.forEach(p => console.log(` - ${p}`)); - console.log(` Indicators:`); - domain.indicators.slice(0, 5).forEach(i => console.log(` - ${i}`)); - if (domain.indicators.length > 5) { - console.log(` ... and ${domain.indicators.length - 5} more`); - } - console.log(); - } - - console.log('='.repeat(80)); - console.log('FILE DOMAIN MAPPING (Sample)'); - console.log('='.repeat(80)); - console.log(); - - // Test file mapping with some example paths - const testPaths = structure.domains.flatMap(d => - d.rootPaths.flatMap((root: string) => [ - `${root}/test.ts`, - `${root}/components/example.ts`, - `${root}/handlers/example.py` - ]) - ); - - for (const testPath of testPaths.slice(0, 10)) { - const domain = discovery.getDomainForFile(testPath); - const domainType = domain ? discovery.getDomainType(domain) : null; - - if (domain && domainType) { - console.log(`${testPath}`); - console.log(` → Domain: ${domain} (${formatDomainType(domainType)})`); - } - } - - console.log(); - console.log('='.repeat(80)); - console.log('\x1b[32m✓ Discovery Complete\x1b[0m'); - console.log('='.repeat(80)); -} - -main().catch(error => { - console.error('\x1b[31mError during discovery:\x1b[0m', error); - process.exit(1); -}); - diff --git a/src/cli/index.ts b/src/cli/index.ts index 09b3bd1..aa4235c 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -18,7 +18,6 @@ import { assembleContext } from '../rss/rss-operations.js'; import { runTaskAnalyze } from '../task/task-analysis.js'; -import { startWatch } from '../watch/file-watcher.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); diff --git a/src/cli/recon-cli.ts b/src/cli/recon-cli.ts index 6cf2173..b88463b 100644 --- a/src/cli/recon-cli.ts +++ b/src/cli/recon-cli.ts @@ -9,14 +9,13 @@ * node dist/cli/recon-cli.js # Auto-detect project, incremental mode * node dist/cli/recon-cli.js --mode=full # Full reconciliation * node dist/cli/recon-cli.js --init # Create ste.config.json - * node dist/cli/recon-cli.js --self # Self-documentation mode (legacy) + * node dist/cli/recon-cli.js --self # Self-documentation mode */ import path from 'node:path'; import { fileURLToPath } from 'node:url'; -import fs from 'node:fs/promises'; import { executeRecon } from '../recon/index.js'; -import { loadConfig, loadConfigFromFile, initConfig, type ResolvedConfig } from '../config/index.js'; +import { loadConfig, loadConfigFromFile, initConfig } from '../config/index.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -99,43 +98,18 @@ async function main() { process.exit(0); } - // Handle --self (legacy self-documentation mode) - if (args.self) { - console.log('='.repeat(60)); - console.log('RECON - Self-Documentation Mode (Legacy)'); - console.log('='.repeat(60)); - console.log(''); - - const projectRoot = path.resolve(runtimeDir, '..'); - const sourceRoot = 'ste-runtime/src'; - const stateRoot = 'ste-runtime/.ste/state'; - - console.log(` Project Root: ${projectRoot}`); - console.log(` Source Root: ${sourceRoot}`); - console.log(` State Root: ${stateRoot}`); - console.log(''); - - const result = await executeRecon({ - projectRoot, - sourceRoot, - stateRoot, - mode: args.mode, - }); - - printResult(result, projectRoot, stateRoot); - process.exit(result.success ? 0 : 1); - } - // Normal operation: auto-detect project and use config console.log('='.repeat(60)); - console.log('RECON - Reconciliation Engine (E-ADR-001, E-ADR-002)'); + console.log(args.self + ? 'RECON - Self-Documentation Mode (E-ADR-001, E-ADR-002)' + : 'RECON - Reconciliation Engine (E-ADR-001, E-ADR-002)'); console.log('='.repeat(60)); console.log(''); // Load configuration (use specific file if --config provided) const config = args.config ? await loadConfigFromFile(path.resolve(runtimeDir, args.config), runtimeDir) - : await loadConfig(runtimeDir); + : await loadConfig(runtimeDir, { selfMode: args.self }); const isSelfAnalysis = config.projectRoot === config.runtimeDir; @@ -145,135 +119,19 @@ async function main() { console.log(` Languages: ${config.languages.join(', ')}`); console.log(` Self-Analysis: ${isSelfAnalysis}`); - // Declare variables for both reconciliations - let externalResult: Awaited> | null = null; - - // For full recon in self-analysis mode: clean up .ste/state since there's no external project - if (args.mode === 'full' && isSelfAnalysis) { - const steStateDir = path.resolve(runtimeDir, '.ste', 'state'); - try { - const stats = await fs.stat(steStateDir); - if (stats.isDirectory()) { - console.log(''); - console.log('='.repeat(60)); - console.log('Cleaning up orphaned .ste/state (no external project detected)...'); - console.log('='.repeat(60)); - console.log(''); - - // Directly remove all slice files in .ste/state since there's no external project - // Keep the directory structure but remove all slice content - const subdirs = ['graph', 'api', 'data', 'infrastructure', 'behavior']; - let deletedCount = 0; - - for (const subdir of subdirs) { - const subdirPath = path.join(steStateDir, subdir); - try { - const entries = await fs.readdir(subdirPath, { recursive: true, withFileTypes: true }); - for (const entry of entries) { - if (entry.isFile() && (entry.name.endsWith('.yaml') || entry.name.endsWith('.yml')) && entry.name !== 'index.yaml') { - // Use parentPath if available (Node 20.1+), otherwise construct from subdirPath - const entryPath = 'parentPath' in entry && entry.parentPath - ? path.join(entry.parentPath, entry.name) - : path.join(subdirPath, entry.name); - await fs.unlink(entryPath); - deletedCount++; - } - } - } catch { - // Subdirectory doesn't exist, skip - } - } - - // Also clean up manifest and validation directories - try { - await fs.rm(path.join(steStateDir, 'manifest'), { recursive: true, force: true }); - } catch {} - try { - await fs.rm(path.join(steStateDir, 'validation'), { recursive: true, force: true }); - } catch {} - - // Remove graph-metrics.json if it exists - try { - await fs.unlink(path.join(steStateDir, 'graph-metrics.json')); - } catch {} - - console.log(`[RECON] Cleaned up orphaned .ste/state: ${deletedCount} slice files deleted`); - console.log(''); - } - } catch (error) { - // .ste/state doesn't exist, which is fine - nothing to clean up - } - } - - // For full recon, run BOTH external project (if exists) AND self-analysis - if (args.mode === 'full' && !isSelfAnalysis) { - console.log(''); - console.log('='.repeat(60)); - console.log('Step 1: Reconciling external project...'); - console.log('='.repeat(60)); - console.log(''); - - // Run RECON for external project - externalResult = await executeRecon({ - projectRoot: config.projectRoot, - sourceRoot: config.sourceDirs[0] || '.', - stateRoot: config.stateDir, // This will be .ste/state for external projects - mode: 'full', - config, - }); - - printResult(externalResult, config.projectRoot, config.stateDir); - - console.log(''); - console.log('='.repeat(60)); - console.log('Step 2: Reconciling ste-runtime (self-analysis)...'); - console.log('='.repeat(60)); - console.log(''); - } - - // Always run self-analysis (even if we just did external project) - // Load self-analysis config - const selfConfigPath = path.join(runtimeDir, 'ste-self.config.json'); - let selfConfig: ResolvedConfig; - - try { - selfConfig = await loadConfigFromFile(selfConfigPath, runtimeDir); - } catch { - // No ste-self.config.json, create a default self-analysis config - selfConfig = { - ...config, - projectRoot: runtimeDir, - runtimeDir: runtimeDir, - stateDir: '.ste-self/state', - sourceDirs: ['src'], - languages: ['typescript' as const], - }; - } - - // Run RECON for ste-runtime self-analysis - const selfResult = await executeRecon({ - projectRoot: selfConfig.projectRoot, - sourceRoot: selfConfig.sourceDirs[0] ?? 'src', - stateRoot: selfConfig.stateDir, // .ste-self/state + const result = await executeRecon({ + projectRoot: config.projectRoot, + sourceRoot: config.sourceDirs[0] ?? '.', + stateRoot: config.stateDir, mode: args.mode, - config: selfConfig, + config, }); - - if (args.mode === 'full' && !isSelfAnalysis && externalResult) { - printResult(selfResult, selfConfig.projectRoot, selfConfig.stateDir); - console.log(''); - console.log('='.repeat(60)); - console.log('Full RECON Complete: Both external project and self-analysis'); - console.log('='.repeat(60)); - process.exit(externalResult.success && selfResult.success ? 0 : 1); - } else { - // Single recon (incremental or self-analysis only) - printResult(selfResult, selfConfig.projectRoot, selfConfig.stateDir); - process.exit(selfResult.success ? 0 : 1); - } + + printResult(result, config.projectRoot, config.stateDir); + process.exit(result.success ? 0 : 1); } -function printResult(result: Awaited>, projectRoot: string, stateRoot: string) { +function printResult(result: Awaited>, _projectRoot: string, _stateRoot: string) { console.log(''); console.log('='.repeat(60)); console.log('RECON EXECUTION COMPLETE'); diff --git a/src/cli/watch-cli.ts b/src/cli/watch-cli.ts deleted file mode 100644 index b801953..0000000 --- a/src/cli/watch-cli.ts +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env node -/** - * Watch CLI - * - * CLI entry point for `ste watch` command. - * Per E-ADR-011: Starts MCP server with optional file watching. - */ - -import { Command } from 'commander'; -import { loadConfig } from '../config/index.js'; -import { McpServer } from '../mcp/mcp-server.js'; -import { Watchdog } from '../watch/watchdog.js'; -import { executeRecon } from '../recon/index.js'; -import { loadReconManifest } from '../watch/change-detector.js'; -import path from 'node:path'; -import { fileURLToPath } from 'node:url'; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); - -export async function main() { - const program = new Command(); - - program - .name('ste watch') - .description('Start MCP server with optional file watching') - .option('--mcp', 'Enable MCP mode (default when run by Cursor)', true) - .option('--no-watch', 'Disable file watching (MCP server only)') - .option('--self', 'Self-analysis mode: analyze ste-runtime itself instead of parent project') - .option('--config ', 'Custom config file path') - .parse(process.argv); - - const options = program.opts(); - try { - // Load configuration - const runtimeDir = path.resolve(__dirname, '../..'); - const config = await loadConfig(runtimeDir, { selfMode: options.self }); - - console.log(`[ste watch] Project root: ${config.projectRoot}`); - console.log(`[ste watch] State directory: ${config.stateDir}`); - - // CRITICAL: Resolve stateDir to absolute path for manifest operations - // The stateDir from config is relative to projectRoot, so resolve it properly - const resolvedStateDir = path.resolve(config.projectRoot, config.stateDir); - console.log(`[ste watch] Resolved state directory: ${resolvedStateDir}`); - - // Check if manifest exists, run full RECON if not - // CRITICAL: Use resolvedStateDir, NOT projectRoot - manifest lives INSIDE stateDir - const manifest = await loadReconManifest(resolvedStateDir); - if (!manifest) { - console.log('[ste watch] No manifest found, running initial RECON...'); - // Use executeRecon with proper config - this writes to config.stateDir (inside ste-runtime) - await executeRecon({ - projectRoot: config.projectRoot, - sourceRoot: config.sourceDirs[0] ?? '.', - stateRoot: config.stateDir, - mode: 'full', - config: config, - }); - console.log('[ste watch] Initial RECON complete'); - } - - // Create MCP server - const mcpServer = new McpServer({ - config, - projectRoot: config.projectRoot, - }); - - // Create watchdog if file watching is enabled - let watchdog: Watchdog | null = null; - - if (options.watch && config.watchdog.enabled) { - watchdog = new Watchdog({ - projectRoot: config.projectRoot, - config, - onReconComplete: async () => { - // Reload MCP server context after RECON - await mcpServer.reloadContext(); - }, - onError: (error) => { - console.error('[ste watch] Watchdog error:', error); - }, - }); - - // Start watchdog - await watchdog.start(); - console.log('[ste watch] File watching enabled'); - } else if (options.watch && !config.watchdog.enabled) { - console.log('[ste watch] File watching disabled in config (set watchdog.enabled: true to enable)'); - } else { - console.log('[ste watch] File watching disabled (--no-watch)'); - } - - // Start MCP server - await mcpServer.start(); - - // Handle shutdown - const shutdown = async () => { - console.log('\n[ste watch] Shutting down...'); - - if (watchdog) { - await watchdog.stop(); - } - - await mcpServer.stop(); - - process.exit(0); - }; - - process.on('SIGINT', shutdown); - process.on('SIGTERM', shutdown); - - // Keep process alive - console.log('[ste watch] Ready (press Ctrl+C to stop)'); - - } catch (error) { - console.error('[ste watch] Fatal error:', error); - process.exit(1); - } -} - -// Run if called directly -if (import.meta.url === `file://${process.argv[1]}`) { - main(); -} - diff --git a/src/config/boundary-validation.test.ts b/src/config/boundary-validation.test.ts index 42416e7..8231554 100644 --- a/src/config/boundary-validation.test.ts +++ b/src/config/boundary-validation.test.ts @@ -13,7 +13,6 @@ import path from 'node:path'; const runtimeDir = path.resolve('C:/Users/Erik.Gallmann/Documents/PycharmProjects/ste-runtime'); const parentDir = path.resolve('C:/Users/Erik.Gallmann/Documents/PycharmProjects'); const homeDir = path.resolve('C:/Users/Erik.Gallmann'); -const allowedScope = runtimeDir; describe('Boundary Validation Logic', () => { describe('Project Root Validation', () => { @@ -43,8 +42,6 @@ describe('Boundary Validation Logic', () => { const runtimeDir = path.resolve(homeDir, 'Documents/PycharmProjects/ste-runtime'); const runtimeParent = path.dirname(runtimeDir); - const projectParent = path.dirname(projectRoot); - // Check if project root is higher up the tree const relativePath = path.relative(runtimeParent, projectRoot); const isTooHigh = relativePath.startsWith('..') && relativePath.split(path.sep).filter(p => p === '..').length > 1; diff --git a/src/config/index.ts b/src/config/index.ts index 108a5e5..41a5240 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -268,61 +268,6 @@ const BUILTIN_IGNORE_PATTERNS = [ * * Strategy: * 1. Start from ste-runtime's PARENT directory (not ste-runtime itself) - * 2. FIRST: Look for ste.config.json - this is the authoritative project marker - * 3. THEN: Look for standard project markers (package.json, pyproject.toml, .git, etc.) - * 4. Stop at the FIRST match - do not traverse further up - * - * This ensures that if a project has ste.config.json at its root, we use that - * as the definitive project boundary, even if parent directories also have markers. - */ -async function findProjectRoot(startDir: string): Promise { - // Start from parent of ste-runtime, not ste-runtime itself - let currentDir = path.resolve(startDir, '..'); - const root = path.parse(currentDir).root; - - // Priority 1: ste.config.json is the authoritative project marker - // Check immediate parent first before traversing - const steConfigPath = path.join(currentDir, 'ste.config.json'); - try { - await fs.access(steConfigPath); - return currentDir; // Found ste.config.json in immediate parent - } catch { - // Continue with standard marker search - } - - // Priority 2: Look for standard project markers - // But STOP at the first directory that has ANY marker - const markers = [ - 'ste.config.json', // Check again in case it's higher up - 'pyproject.toml', - 'requirements.txt', - 'setup.py', - 'package.json', - '.git', - ]; - - let searchDir = currentDir; - while (searchDir !== root) { - for (const marker of markers) { - const markerPath = path.join(searchDir, marker); - try { - await fs.access(markerPath); - return searchDir; - } catch { - // Continue searching - } - } - - const parentDir = path.dirname(searchDir); - if (parentDir === searchDir) break; - searchDir = parentDir; - } - - // Fallback: use startDir's parent (assuming ste-runtime is in project) - return currentDir; -} - -/** * Auto-detect languages based on file presence in project */ async function detectLanguages(projectRoot: string): Promise { @@ -335,7 +280,7 @@ async function detectLanguages(projectRoot: string): Promise } } -/** - * Load configuration from ste.config.json if present. - * - * Search order: - * 1. Project root (parent directory) - authoritative project config - * 2. Inside ste-runtime/ - self-contained config for portability - * - * This allows projects to have their own ste.config.json at the root, - * while still supporting self-contained configs inside ste-runtime/. - */ -async function loadConfigFile(runtimeDir: string, projectRoot: string): Promise { - // Priority 1: Check project root for ste.config.json - const projectConfigPath = path.join(projectRoot, 'ste.config.json'); - const projectConfig = await loadConfigFromPath(projectConfigPath); - if (projectConfig) { - return projectConfig; - } - - // Priority 2: Check inside ste-runtime for self-contained config - const runtimeConfigPath = path.join(runtimeDir, 'ste.config.json'); - return loadConfigFromPath(runtimeConfigPath); -} - /** * Validate that sourceDirs exist relative to project root. * Returns only the valid directories, or ['.'] if none are valid. @@ -498,121 +420,6 @@ async function validateSourceDirs( return { validDirs, invalidDirs }; } -/** - * Detect if ste-runtime is analyzing itself (self-analysis mode) - */ -/** - * Check if the parent directory has a ste.config.json file. - * This is the AUTHORITATIVE signal that ste-runtime is embedded in a parent project. - * When present, this OVERRIDES internal self-analysis heuristics. - */ -async function hasParentProjectConfig(runtimeDir: string): Promise { - const resolvedRuntimeDir = path.resolve(runtimeDir); - const parentDir = path.dirname(resolvedRuntimeDir); - const parentConfigPath = path.join(parentDir, 'ste.config.json'); - - try { - await fs.access(parentConfigPath); - return true; - } catch { - return false; - } -} - -/** - * Check if the parent directory has standard project markers. - * These indicate ste-runtime is embedded in a real project, not standalone. - */ -async function hasParentProjectMarkers(runtimeDir: string): Promise { - const resolvedRuntimeDir = path.resolve(runtimeDir); - const parentDir = path.dirname(resolvedRuntimeDir); - - // Standard project markers (excluding ste-runtime's own markers) - const projectMarkers = [ - 'pyproject.toml', // Python project - 'requirements.txt', // Python project - 'setup.py', // Python project - 'Cargo.toml', // Rust project - 'go.mod', // Go project - 'pom.xml', // Java/Maven project - 'build.gradle', // Java/Gradle project - ]; - - // Check for package.json but ensure it's NOT another ste-runtime - const parentPackageJson = path.join(parentDir, 'package.json'); - try { - const content = await fs.readFile(parentPackageJson, 'utf-8'); - const pkg = JSON.parse(content); - if (pkg.name && pkg.name !== 'ste-runtime') { - return true; - } - } catch { - // No package.json or can't read it - } - - // Check for other markers - for (const marker of projectMarkers) { - const markerPath = path.join(parentDir, marker); - try { - await fs.access(markerPath); - return true; - } catch { - // Continue checking - } - } - - return false; -} - -async function detectSelfAnalysis(runtimeDir: string): Promise { - const resolvedRuntimeDir = path.resolve(runtimeDir); - - // PRIORITY 1: If parent has ste.config.json, this is ALWAYS external project mode - // This is the authoritative signal that overrides all other heuristics - if (await hasParentProjectConfig(resolvedRuntimeDir)) { - console.error('[STE Config] Parent project config found - external project mode'); - return false; - } - - // PRIORITY 2: If parent has standard project markers, treat as external project - if (await hasParentProjectMarkers(resolvedRuntimeDir)) { - console.error('[STE Config] Parent project markers found - external project mode'); - return false; - } - - // FALLBACK: Check if this looks like ste-runtime for self-analysis - - // Heuristic 1: Check package.json for name "ste-runtime" - try { - const packageJsonPath = path.join(resolvedRuntimeDir, 'package.json'); - const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8'); - const packageJson = JSON.parse(packageJsonContent); - if (packageJson.name === 'ste-runtime') { - return true; - } - } catch { - // Ignore error, continue to next heuristic - } - - // Heuristic 2: Check if directory name is "ste-runtime" - if (path.basename(resolvedRuntimeDir) === 'ste-runtime') { - return true; - } - - // Heuristic 3: Check for ste-runtime specific structure (e.g., src/cli/index.ts, dist/) - const cliIndexPath = path.join(resolvedRuntimeDir, 'src', 'cli', 'index.ts'); - const distDirPath = path.join(resolvedRuntimeDir, 'dist'); - try { - await fs.access(cliIndexPath); - await fs.access(distDirPath); - return true; - } catch { - // Ignore error - } - - return false; -} - /** * Check if a directory appears to be a user home directory or system directory. */ @@ -636,69 +443,6 @@ function isSystemOrHomeDirectory(dirPath: string): boolean { return systemRoots.some(root => normalized.startsWith(root)); } -/** - * Validate that project root is within the allowed scope. - * For ste-runtime self-analysis, the project root MUST be exactly the runtime directory. - * - * @param projectRoot - The detected project root - * @param runtimeDir - The ste-runtime directory - * @param isSelfAnalysis - Whether we're in self-analysis mode - * @throws Error if project root is outside allowed scope - */ -function validateProjectScope( - projectRoot: string, - runtimeDir: string, - isSelfAnalysis: boolean -): void { - const resolvedProjectRoot = path.resolve(projectRoot); - const resolvedRuntimeDir = path.resolve(runtimeDir); - - if (isSelfAnalysis) { - // For self-analysis: project root MUST be exactly the runtime directory - if (resolvedProjectRoot !== resolvedRuntimeDir) { - throw new Error( - `CRITICAL BOUNDARY VIOLATION: For self-analysis, project root must equal runtime directory.\n` + - ` Project root: ${resolvedProjectRoot}\n` + - ` Runtime dir: ${resolvedRuntimeDir}\n` + - ` This would allow scanning outside the ste-runtime directory, which is FORBIDDEN.\n` + - ` Allowed scope: ${resolvedRuntimeDir}` - ); - } - } else { - // For external projects: project root should be the immediate parent of runtime dir - // This is the intended use case: ste-runtime dropped into a project folder - const runtimeParent = path.dirname(resolvedRuntimeDir); - - // ALLOWED: Project root is the immediate parent of ste-runtime - // This is the PRIMARY use case - ste-runtime embedded in a project - if (resolvedProjectRoot === runtimeParent) { - // This is the expected case - validation passes - return; - } - - // ALLOWED: Project root is a subdirectory of runtime's parent (sibling or deeper) - if (resolvedProjectRoot.startsWith(runtimeParent + path.sep)) { - // This is also valid - project is a sibling or child directory - return; - } - - // REJECT: Project root is higher than the immediate parent (grandparent or beyond) - const relativePath = path.relative(runtimeParent, resolvedProjectRoot); - if (relativePath.startsWith('..')) { - const upLevels = relativePath.split(path.sep).filter(p => p === '..').length; - if (upLevels >= 1) { - throw new Error( - `CRITICAL BOUNDARY VIOLATION: Project root is outside the allowed scope.\n` + - ` Project root: ${resolvedProjectRoot}\n` + - ` Runtime dir: ${resolvedRuntimeDir}\n` + - ` Expected: Project root should be the immediate parent of ste-runtime.\n` + - ` This would scan outside the intended project scope.` - ); - } - } - } -} - /** * Validate that project root is within reasonable bounds from runtime directory. */ @@ -733,32 +477,6 @@ async function validateProjectRootBounds( } } -/** - * Enforce hard boundary that project root never exceeds the runtime directory for self-analysis. - */ -async function enforceProjectBoundary( - projectRoot: string, - runtimeDir: string, - isSelfAnalysis: boolean -): Promise { - const resolvedProjectRoot = path.resolve(projectRoot); - const resolvedRuntimeDir = path.resolve(runtimeDir); - - if (isSelfAnalysis) { - // For self-analysis: project root MUST equal runtime directory - if (resolvedProjectRoot !== resolvedRuntimeDir) { - throw new Error( - `CRITICAL: For self-analysis, project root must equal runtime directory. ` + - `Project root: ${resolvedProjectRoot}, Runtime dir: ${resolvedRuntimeDir}. ` + - `This would allow scanning outside the ste-runtime directory, which is forbidden.` - ); - } - } else { - // For external projects: validate bounds - await validateProjectRootBounds(projectRoot, runtimeDir); - } -} - /** * Load and resolve STE configuration. * diff --git a/src/discovery/project-discovery.ts b/src/discovery/project-discovery.ts index 9aac815..c392aa8 100644 --- a/src/discovery/project-discovery.ts +++ b/src/discovery/project-discovery.ts @@ -125,21 +125,6 @@ const INFRA_FILE_PATTERNS = [ /\.k8s\.yaml$/ ]; -/** Framework detection patterns */ -const FRAMEWORK_INDICATORS = { - angular: ['angular.json', 'src/app/app.module.ts', '.component.ts'], - react: ['package.json', '.jsx', '.tsx'], - vue: ['vue.config.js', '.vue'], - svelte: ['svelte.config.js', '.svelte'], - next: ['next.config.js', 'pages/'], - express: ['package.json', '.route.js', '.controller.js'], - fastapi: ['requirements.txt', 'main.py', '@app.'], - flask: ['requirements.txt', 'app.py', '@app.route'], - lambda: ['handler.py', 'lambda_handler', 'handler.js'], - cloudformation: ['.yaml', 'Resources:', 'AWSTemplateFormatVersion'], - terraform: ['.tf', 'provider "aws"', 'resource "aws_'] -}; - // ============================================================================ // Discovery Engine // ============================================================================ @@ -291,7 +276,7 @@ export class ProjectDiscovery { directories.push(...subdirs); } } - } catch (error) { + } catch { // Ignore permission errors or invalid directories } @@ -410,7 +395,7 @@ export class ProjectDiscovery { }); } } - } catch (error) { + } catch { // Ignore errors } } @@ -525,7 +510,7 @@ export class ProjectDiscovery { weight: 0.4 }); } - } catch (error) { + } catch { // Ignore JSON parse errors } } @@ -559,7 +544,7 @@ export class ProjectDiscovery { weight: 0.4 }); } - } catch (error) { + } catch { // Ignore read errors } } @@ -576,7 +561,7 @@ export class ProjectDiscovery { weight: 0.4 }); } - } catch (error) { + } catch { // Ignore errors } } diff --git a/src/extractors/angular/angular-extractor.ts b/src/extractors/angular/angular-extractor.ts index 6a9ccc4..2493881 100644 --- a/src/extractors/angular/angular-extractor.ts +++ b/src/extractors/angular/angular-extractor.ts @@ -188,8 +188,6 @@ function extractSignalInputsOutputs( if (!member.initializer) continue; const propName = member.name.text; - const initText = member.initializer.getText(sourceFile); - // Check for input() or input.required() pattern if (ts.isCallExpression(member.initializer)) { const callExpr = member.initializer; @@ -519,7 +517,7 @@ function extractInjectableDecorator( */ function extractPipeDecorator( node: ts.ClassDeclaration, - sourceFile: ts.SourceFile + _sourceFile: ts.SourceFile ): AngularPipe | null { const decorators = ts.getDecorators(node); if (!decorators) return null; @@ -624,7 +622,7 @@ async function extractComponent(file: DiscoveredFile, projectRoot?: string): Pro let content: string; try { content = await fs.readFile(file.path, 'utf-8'); - } catch (error) { + } catch { return assertions; } @@ -707,7 +705,7 @@ async function extractComponent(file: DiscoveredFile, projectRoot?: string): Pro }, }); } - } catch (error) { + } catch { // Style file doesn't exist or can't be read - that's ok continue; } @@ -727,7 +725,7 @@ async function extractService(file: DiscoveredFile): Promise { let content: string; try { content = await fs.readFile(file.path, 'utf-8'); - } catch (error) { + } catch { return assertions; } @@ -771,7 +769,7 @@ async function extractPipe(file: DiscoveredFile): Promise { let content: string; try { content = await fs.readFile(file.path, 'utf-8'); - } catch (error) { + } catch { return assertions; } @@ -815,7 +813,7 @@ async function extractDirective(file: DiscoveredFile): Promise { let content: string; try { content = await fs.readFile(file.path, 'utf-8'); - } catch (error) { + } catch { return assertions; } @@ -859,7 +857,7 @@ async function extractGuard(file: DiscoveredFile): Promise { let content: string; try { content = await fs.readFile(file.path, 'utf-8'); - } catch (error) { + } catch { return assertions; } @@ -918,7 +916,7 @@ async function extractRoutes(file: DiscoveredFile): Promise { let content: string; try { content = await fs.readFile(file.path, 'utf-8'); - } catch (error) { + } catch { return assertions; } @@ -974,7 +972,7 @@ async function extractTemplate(file: DiscoveredFile): Promise { let content: string; try { content = await fs.readFile(file.path, 'utf-8'); - } catch (error) { + } catch { return assertions; } @@ -1055,7 +1053,7 @@ async function extractTemplate(file: DiscoveredFile): Promise { export async function extractFromAngular( file: DiscoveredFile, projectRoot?: string, - patterns?: AngularPatterns + _patterns?: AngularPatterns ): Promise { const fileType = getAngularFileType(file.relativePath); @@ -1100,4 +1098,3 @@ export async function extract( return allAssertions; } - diff --git a/src/extractors/python/python-extractor-validation.test.ts b/src/extractors/python/python-extractor-validation.test.ts index 3a5db46..54a1d4a 100644 --- a/src/extractors/python/python-extractor-validation.test.ts +++ b/src/extractors/python/python-extractor-validation.test.ts @@ -86,7 +86,6 @@ describe('Python Extractor - Graph Edge Validation', () => { expect(app).toBeDefined(); // For now, we verify the import was processed (even if edge creation needs work) - const refs = app!._slice.references || []; // This test documents current behavior - may need enhancement }); @@ -168,7 +167,6 @@ describe('Python Extractor - Graph Edge Validation', () => { // Note: Relative Python imports (. and ..) require special resolution logic // This test documents expected behavior for future implementation - const refs = auth!._slice.references || []; // May need enhancement in inference phase to handle Python relative imports }); diff --git a/src/mcp/context-source-loader.test.ts b/src/mcp/context-source-loader.test.ts index 8f6e8c9..d539d52 100644 --- a/src/mcp/context-source-loader.test.ts +++ b/src/mcp/context-source-loader.test.ts @@ -13,7 +13,6 @@ import { loadSourceForSlices, loadSourceGroupedByFile, formatSourceForLLM, - type LoadSourceOptions, } from './context-source-loader.js'; import type { AidocNode } from '../rss/graph-loader.js'; diff --git a/src/mcp/context-source-loader.ts b/src/mcp/context-source-loader.ts index 6b2c8b1..7e8855c 100644 --- a/src/mcp/context-source-loader.ts +++ b/src/mcp/context-source-loader.ts @@ -87,7 +87,7 @@ export async function loadSourceForSlice( lines, truncated, }; - } catch (error) { + } catch (_error) { // File might not exist or not readable return null; } @@ -147,7 +147,7 @@ export async function loadSourceGroupedByFile( contexts.push(ctx); } } - } catch (error) { + } catch (_error) { // Skip file if not readable continue; } diff --git a/src/mcp/graph-topology-analyzer.test.ts b/src/mcp/graph-topology-analyzer.test.ts index a390556..8c10832 100644 --- a/src/mcp/graph-topology-analyzer.test.ts +++ b/src/mcp/graph-topology-analyzer.test.ts @@ -13,7 +13,6 @@ import { saveGraphMetrics, loadGraphMetrics, type GraphMetrics, - type ArchitecturePattern, } from './graph-topology-analyzer.js'; import type { AidocGraph, AidocNode } from '../rss/graph-loader.js'; diff --git a/src/mcp/graph-topology-analyzer.ts b/src/mcp/graph-topology-analyzer.ts index d8b82b6..3212dbe 100644 --- a/src/mcp/graph-topology-analyzer.ts +++ b/src/mcp/graph-topology-analyzer.ts @@ -261,8 +261,7 @@ export async function loadGraphMetrics( try { const content = await fs.readFile(metricsPath, 'utf-8'); return JSON.parse(content) as GraphMetrics; - } catch (error) { + } catch (_error) { return null; } } - diff --git a/src/mcp/mcp-server.test.ts b/src/mcp/mcp-server.test.ts index 60de52a..950e6da 100644 --- a/src/mcp/mcp-server.test.ts +++ b/src/mcp/mcp-server.test.ts @@ -123,7 +123,6 @@ describe('MCP Server Integration', () => { describe('Watchdog Integration', () => { let watchdog: Watchdog; let config: ResolvedConfig; - let reconCompleted = false; beforeAll(async () => { // Create mock config for test project @@ -137,9 +136,7 @@ describe('Watchdog Integration', () => { watchdog = new Watchdog({ projectRoot: TEST_PROJECT, config, - onReconComplete: async () => { - reconCompleted = true; - }, + onReconComplete: async () => {}, onError: (error) => { console.error('Watchdog error:', error); }, diff --git a/src/mcp/obligation-projector.ts b/src/mcp/obligation-projector.ts index 12465ff..795ed63 100644 --- a/src/mcp/obligation-projector.ts +++ b/src/mcp/obligation-projector.ts @@ -10,24 +10,20 @@ */ import type { AidocNode } from '../rss/graph-loader.js'; -import type { RssContext } from '../rss/rss-operations.js'; import { - blastRadius, + type RssContext, dependencies, dependents, lookupByKey, - search, } from '../rss/rss-operations.js'; import type { ChangeIntent, ChangeIntentType, Obligation, ObligationType, - ObligationStatus, SliceReference, InvalidatedValidation, SliceValidation, - ValidationClaim, Advisory, } from '../rss/schema.js'; import { resolveIntentScope, type ScopeResolutionResult } from './preflight.js'; @@ -370,8 +366,6 @@ function generateAdvisory( // Generate review recommendation const dependentCount = impactedSlices.dependents.length; - const dependencyCount = impactedSlices.dependencies.length; - let reviewRecommendation = ''; if (intentType === 'delete') { reviewRecommendation = `Deletion of ${targetNode.id}. Ensure ${dependentCount} dependent(s) are updated.`; diff --git a/src/mcp/preflight.ts b/src/mcp/preflight.ts index b862262..b85ff1d 100644 --- a/src/mcp/preflight.ts +++ b/src/mcp/preflight.ts @@ -12,17 +12,13 @@ import { createHash } from 'node:crypto'; import fs from 'node:fs/promises'; import path from 'node:path'; -import type { RssContext } from '../rss/rss-operations.js'; -import { blastRadius, search, lookupByKey } from '../rss/rss-operations.js'; -import { loadReconManifest, type ReconManifest, type FileFingerprint } from '../watch/change-detector.js'; +import { type RssContext, blastRadius, search, lookupByKey } from '../rss/rss-operations.js'; +import { loadReconManifest, type ReconManifest } from '../watch/change-detector.js'; import { runIncrementalRecon } from '../recon/incremental-recon.js'; -import { initRssContext } from '../rss/rss-operations.js'; import type { FreshnessIndicator, FreshnessStatus, ChangeIntent, - ChangeIntentType, - ChangeTargetType, } from '../rss/schema.js'; // ───────────────────────────────────────────────────────────────── diff --git a/src/mcp/tools-context.test.ts b/src/mcp/tools-context.test.ts index ad366e1..0c3649a 100644 --- a/src/mcp/tools-context.test.ts +++ b/src/mcp/tools-context.test.ts @@ -4,7 +4,7 @@ * Tests Layer 2 operations that combine graph metadata with source code. */ -import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import fs from 'node:fs/promises'; import path from 'node:path'; import os from 'node:os'; diff --git a/src/mcp/tools-context.ts b/src/mcp/tools-context.ts index 0a801d4..730e4e6 100644 --- a/src/mcp/tools-context.ts +++ b/src/mcp/tools-context.ts @@ -5,8 +5,8 @@ * Per E-ADR-011: Context Assembly operations that combine graph metadata with source code. */ -import type { RssContext } from '../rss/rss-operations.js'; import { + type RssContext, findEntryPoints, assembleContext, blastRadius, @@ -51,7 +51,6 @@ export async function assembleContextTool( const { query, includeSource = true, - includeInvariants = true, depth = 2, maxNodes = 50, maxSourceLines = 100, diff --git a/src/mcp/tools-obligation.test.ts b/src/mcp/tools-obligation.test.ts index 9a92462..e449fcd 100644 --- a/src/mcp/tools-obligation.test.ts +++ b/src/mcp/tools-obligation.test.ts @@ -263,11 +263,6 @@ describe('MCP Tools - Obligation Projection', () => { const result = await projectChangeObligationsTool(ctx, args, config); // Should be bounded by maxSlices - const totalSlices = - result.impactedSlices.direct.length + - result.impactedSlices.dependents.length + - result.impactedSlices.dependencies.length; - // Note: The implementation may still return the direct target plus some dependents // The exact behavior depends on implementation details expect(result.meta.slicesAnalyzed).toBeDefined(); diff --git a/src/mcp/tools-obligation.ts b/src/mcp/tools-obligation.ts index d5a1c8f..5fab121 100644 --- a/src/mcp/tools-obligation.ts +++ b/src/mcp/tools-obligation.ts @@ -7,7 +7,6 @@ */ import type { RssContext } from '../rss/rss-operations.js'; -import { initRssContext } from '../rss/rss-operations.js'; import { preflightReconciliation, checkFreshness, @@ -17,13 +16,11 @@ import { import { projectObligations, countObligations, - type ObligationProjectionOptions, } from './obligation-projector.js'; import type { ChangeIntent, ChangeIntentType, ChangeTargetType, - ObligationProjectionResponse, FreshnessIndicator, } from '../rss/schema.js'; diff --git a/src/mcp/tools-operational.ts b/src/mcp/tools-operational.ts index 9bacf0c..f5cb7d1 100644 --- a/src/mcp/tools-operational.ts +++ b/src/mcp/tools-operational.ts @@ -5,14 +5,13 @@ * Per E-ADR-011: Operational tools for graph health and extractor detection. */ -import type { RssContext } from '../rss/rss-operations.js'; import { + type RssContext, validateGraphHealth, findOrphanedNodes, findAllBrokenEdges, validateBidirectionalEdges, } from '../rss/rss-operations.js'; -import { runFullRecon } from '../recon/full-recon.js'; import { executeRecon } from '../recon/index.js'; import { loadConfig, loadConfigFromFile, type ResolvedConfig } from '../config/index.js'; import { globby } from 'globby'; @@ -271,15 +270,21 @@ export async function triggerFullRecon( // Also clean up manifest and validation directories try { await fs.rm(path.join(steStateDir, 'manifest'), { recursive: true, force: true }); - } catch {} + } catch { + // Best-effort cleanup: process may have already exited. + } try { await fs.rm(path.join(steStateDir, 'validation'), { recursive: true, force: true }); - } catch {} + } catch { + // Best-effort cleanup: process may have already exited. + } // Remove graph-metrics.json if it exists try { await fs.unlink(path.join(steStateDir, 'graph-metrics.json')); - } catch {} + } catch { + // Best-effort cleanup: process may have already exited. + } } } catch { // .ste/state doesn't exist, which is fine - nothing to clean up diff --git a/src/mcp/tools-optimized.ts b/src/mcp/tools-optimized.ts index c472aa2..43ec837 100644 --- a/src/mcp/tools-optimized.ts +++ b/src/mcp/tools-optimized.ts @@ -16,9 +16,9 @@ * - refresh: Force re-extraction */ -import type { RssContext, RssQueryResult } from '../rss/rss-operations.js'; import type { AidocNode } from '../rss/graph-loader.js'; import { + type RssContext, search, lookupByKey, dependencies, @@ -797,7 +797,6 @@ export async function refresh( triggerRecon: () => Promise<{ success: boolean; message: string }> ): Promise { const startTime = performance.now(); - const { scope = 'full' } = args; try { const result = await triggerRecon(); diff --git a/src/mcp/tools-structural.ts b/src/mcp/tools-structural.ts index a420351..16f0242 100644 --- a/src/mcp/tools-structural.ts +++ b/src/mcp/tools-structural.ts @@ -5,8 +5,8 @@ * Per E-ADR-011: RSS Pure Semantic Graph operations (<100ms, metadata only) */ -import type { RssContext } from '../rss/rss-operations.js'; import { + type RssContext, search, lookupByKey, lookup, diff --git a/src/recon/incremental-recon.ts b/src/recon/incremental-recon.ts index 05bfd06..cc8c756 100644 --- a/src/recon/incremental-recon.ts +++ b/src/recon/incremental-recon.ts @@ -26,7 +26,6 @@ import { import { runFullRecon } from './full-recon.js'; import { ChangeSet, - ReconManifest, buildFullManifest, detectFileChanges, loadReconManifest, diff --git a/src/recon/index.ts b/src/recon/index.ts index ab3ddd2..5b0c180 100644 --- a/src/recon/index.ts +++ b/src/recon/index.ts @@ -12,8 +12,6 @@ import type { ResolvedConfig } from '../config/index.js'; import { runReconPhases } from './phases/index.js'; -import path from 'node:path'; -import fs from 'node:fs/promises'; import { log, error as logError } from '../utils/logger.js'; export interface ReconOptions { diff --git a/src/recon/phases/discovery.ts b/src/recon/phases/discovery.ts index 46ae5df..f9e8e12 100644 --- a/src/recon/phases/discovery.ts +++ b/src/recon/phases/discovery.ts @@ -96,7 +96,7 @@ const LANGUAGE_IGNORES: Record = { /** * Get file extension to language mapping */ -function getLanguageForFile(filePath: string, content?: string): SupportedLanguage | null { +function getLanguageForFile(filePath: string, _content?: string): SupportedLanguage | null { const ext = path.extname(filePath).toLowerCase(); const posixPath = toPosixPath(filePath); diff --git a/src/recon/phases/divergence.test.ts b/src/recon/phases/divergence.test.ts index 7b7e0bb..841a059 100644 --- a/src/recon/phases/divergence.test.ts +++ b/src/recon/phases/divergence.test.ts @@ -4,7 +4,7 @@ */ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; -import { detectDivergence, type ValidationResult, type SemanticEnrichment } from './divergence.js'; +import { detectDivergence } from './divergence.js'; import type { NormalizedAssertion } from './index.js'; import * as fs from 'node:fs/promises'; diff --git a/src/recon/phases/divergence.ts b/src/recon/phases/divergence.ts index 130a997..5fe6dcd 100644 --- a/src/recon/phases/divergence.ts +++ b/src/recon/phases/divergence.ts @@ -22,7 +22,6 @@ import fs from 'node:fs/promises'; import path from 'node:path'; -import yaml from 'js-yaml'; import type { NormalizedAssertion } from './index.js'; export interface ValidationResult { @@ -75,7 +74,7 @@ export async function detectDivergence( // Identify orphaned slices (source file deleted or element removed) const newIds = new Set(newAssertions.map(a => a._slice.id)); - for (const [id, priorAssertion] of priorState.entries()) { + for (const [id] of priorState.entries()) { if (!newIds.has(id)) { orphanedSlices.push(id); } diff --git a/src/recon/phases/extraction-cloudformation.ts b/src/recon/phases/extraction-cloudformation.ts index 685eedf..fb21668 100644 --- a/src/recon/phases/extraction-cloudformation.ts +++ b/src/recon/phases/extraction-cloudformation.ts @@ -29,7 +29,7 @@ import { getReferenceProperties, type CloudFormationSpec } from '../../extractors/cfn/cfn-spec-loader.js'; -import { parseResourceType, getCategoryForService } from '../../extractors/cfn/cfn-types.js'; +import { parseResourceType } from '../../extractors/cfn/cfn-types.js'; // Cached spec (loaded once per RECON run) let cachedSpec: CloudFormationSpec | null = null; @@ -1212,4 +1212,3 @@ function extractRefFromIntrinsic(value: unknown): string | undefined { return undefined; } - diff --git a/src/recon/phases/extraction.ts b/src/recon/phases/extraction.ts index 16b4e0c..18faf53 100644 --- a/src/recon/phases/extraction.ts +++ b/src/recon/phases/extraction.ts @@ -17,7 +17,7 @@ import { fileURLToPath } from 'node:url'; import * as ts from 'typescript'; import { execa } from 'execa'; import type { DiscoveredFile, RawAssertion } from './index.js'; -import type { SupportedLanguage, JsonPatterns } from '../../config/index.js'; +import type { SupportedLanguage } from '../../config/index.js'; import { generateSliceId, toPosixPath } from '../../utils/paths.js'; import { extractFromCloudFormation } from './extraction-cloudformation.js'; import { extractFromJson } from '../../extractors/json/index.js'; @@ -1018,7 +1018,7 @@ function extractClassProperties(node: ts.ClassDeclaration, sourceFile: ts.Source return properties; } -function extractImportedNames(node: ts.ImportDeclaration, sourceFile: ts.SourceFile): string[] { +function extractImportedNames(node: ts.ImportDeclaration, _sourceFile: ts.SourceFile): string[] { const names: string[] = []; if (node.importClause) { diff --git a/src/recon/phases/index.ts b/src/recon/phases/index.ts index 3139ae4..88849ed 100644 --- a/src/recon/phases/index.ts +++ b/src/recon/phases/index.ts @@ -19,7 +19,7 @@ import { extractAssertions } from './extraction.js'; import { inferRelationships } from './inference.js'; import { normalizeAssertions } from './normalization.js'; import { populateAiDoc } from './population.js'; -import { detectDivergence, type ValidationResult } from './divergence.js'; +import { detectDivergence } from './divergence.js'; import { runSelfValidation } from './self-validation.js'; import { updateCoordinator } from '../../watch/update-coordinator.js'; import { buildFullManifest, writeReconManifest, type ManifestLanguage } from '../../watch/change-detector.js'; diff --git a/src/recon/phases/inference.test.ts b/src/recon/phases/inference.test.ts index be48524..ffa4bcf 100644 --- a/src/recon/phases/inference.test.ts +++ b/src/recon/phases/inference.test.ts @@ -2,8 +2,6 @@ import { describe, it, expect } from 'vitest'; import { inferRelationships } from './inference.js'; import type { NormalizedAssertion, RawAssertion } from './index.js'; import { - expectGraphEdges, - expectBidirectionalEdges, createRawImportAssertion, createModuleAssertion, assertInferenceCreatesEdges, diff --git a/src/recon/phases/inference.ts b/src/recon/phases/inference.ts index 8938f77..427e433 100644 --- a/src/recon/phases/inference.ts +++ b/src/recon/phases/inference.ts @@ -13,7 +13,6 @@ */ import type { RawAssertion, NormalizedAssertion } from './index.js'; -import type { SupportedLanguage } from '../../config/index.js'; import { generateModuleId } from '../../utils/paths.js'; /** @@ -431,7 +430,7 @@ export function inferRelationships( for (const methodName of calledMethods) { // Find methods with this name // First: same file - let targetMethods = byFile.get(file)?.filter(a => + const targetMethods = byFile.get(file)?.filter(a => a._slice.type === 'function' && a.element.isMethod === true && a.element.name === methodName @@ -1347,7 +1346,7 @@ function buildRelationshipMap(rawAssertions: RawAssertion[]): Map, - fileByModuleId: Map + _fileByModuleId: Map ): Map> { const result = new Map>(); @@ -1376,30 +1375,6 @@ function buildImportedNamesMap( return result; } -/** - * Legacy function for backward compatibility - * Converts relationship map to old import map format - */ -function buildImportMap(rawAssertions: RawAssertion[]): Map> { - const relationshipMap = buildRelationshipMap(rawAssertions); - const result = new Map>(); - - for (const [file, relationships] of relationshipMap.entries()) { - const imports = relationships - .filter((r) => r.type === 'import' && r.module) - .map((r) => ({ - module: r.module!, - names: r.names ?? [], - })); - - if (imports.length > 0) { - result.set(file, imports); - } - } - - return result; -} - /** * Resolve a module reference to a module ID based on language */ @@ -1517,7 +1492,7 @@ function resolveAngularDependency( byFile: Map ): string | null { // Search for the target component or service across all files - for (const [file, assertions] of byFile.entries()) { + for (const [, assertions] of byFile.entries()) { for (const assertion of assertions) { const element = assertion.element; diff --git a/src/recon/phases/normalization.test.ts b/src/recon/phases/normalization.test.ts index fb92003..3c148f2 100644 --- a/src/recon/phases/normalization.test.ts +++ b/src/recon/phases/normalization.test.ts @@ -8,7 +8,6 @@ import type { RawAssertion } from './index.js'; describe('normalizeAssertions', () => { const projectRoot = '/test/project'; - const timestamp = new Date('2024-01-01T00:00:00Z').toISOString(); describe('Function normalization', () => { it('should normalize TypeScript functions', async () => { @@ -616,4 +615,3 @@ describe('normalizeAssertions', () => { }); }); }); - diff --git a/src/recon/phases/normalization.ts b/src/recon/phases/normalization.ts index afd5818..b83373c 100644 --- a/src/recon/phases/normalization.ts +++ b/src/recon/phases/normalization.ts @@ -14,7 +14,7 @@ import path from 'node:path'; import type { RawAssertion, NormalizedAssertion } from './index.js'; import type { SupportedLanguage } from '../../config/index.js'; -import { generateModuleId, toPosixPath } from '../../utils/paths.js'; +import { generateModuleId } from '../../utils/paths.js'; /** * Get extractor name for a language @@ -72,7 +72,7 @@ function getFileExtension(language: SupportedLanguage): string { */ export async function normalizeAssertions( rawAssertions: RawAssertion[], - projectRoot: string + _projectRoot: string ): Promise { const normalized: NormalizedAssertion[] = []; const timestamp = new Date().toISOString(); diff --git a/src/recon/phases/population.ts b/src/recon/phases/population.ts index cb37a51..ba91dc2 100644 --- a/src/recon/phases/population.ts +++ b/src/recon/phases/population.ts @@ -87,7 +87,7 @@ export async function populateAiDoc( await fs.unlink(targetPath); deleted++; log(`[RECON Population] Deleted orphan: ${priorId}`); - } catch (error) { + } catch (_error) { // File might not exist, ignore } } @@ -133,7 +133,7 @@ export async function populateAiDoc( await fs.unlink(targetPath); deleted++; log(`[RECON Population] Deleted orphan: ${priorId}`); - } catch (error) { + } catch (_error) { // File might not exist (already deleted or misnamed), log but continue console.warn(`[RECON Population] Could not delete orphan ${priorId}: file not found`); } @@ -308,7 +308,7 @@ async function loadPriorState(stateDir: string): Promise { }); }); }); - diff --git a/src/recon/validation/report-generator.test.ts b/src/recon/validation/report-generator.test.ts index a5923bb..9162af0 100644 --- a/src/recon/validation/report-generator.test.ts +++ b/src/recon/validation/report-generator.test.ts @@ -9,7 +9,7 @@ import fs from 'node:fs/promises'; import path from 'node:path'; import os from 'node:os'; import yaml from 'js-yaml'; -import { generateReport, type ReportVerbosity } from './report-generator.js'; +import { generateReport } from './report-generator.js'; import type { ValidationFinding, ValidationReport } from './types.js'; describe('Report Generator', () => { diff --git a/src/recon/validation/schema-validator.ts b/src/recon/validation/schema-validator.ts index 4bebd4e..14a0b67 100644 --- a/src/recon/validation/schema-validator.ts +++ b/src/recon/validation/schema-validator.ts @@ -7,7 +7,6 @@ * Avoids brittle markdown parsing becoming fake pressure. */ -import type { NormalizedAssertion } from '../phases/index.js'; import type { ValidationFinding, ValidatorContext } from './types.js'; // Minimal required fields based on current AI-DOC structure @@ -153,4 +152,3 @@ export async function validateSchema( return findings; } - diff --git a/src/rss/conversational-query.test.ts b/src/rss/conversational-query.test.ts index 36932de..73adbd4 100644 --- a/src/rss/conversational-query.test.ts +++ b/src/rss/conversational-query.test.ts @@ -5,7 +5,7 @@ */ import { describe, it, expect } from 'vitest'; -import { ConversationalQueryEngine, type QueryIntent } from './conversational-query.js'; +import { ConversationalQueryEngine } from './conversational-query.js'; describe('Conversational Query Engine', () => { describe('initialization', () => { diff --git a/src/rss/conversational-query.ts b/src/rss/conversational-query.ts index e828d3d..2549574 100644 --- a/src/rss/conversational-query.ts +++ b/src/rss/conversational-query.ts @@ -17,17 +17,15 @@ */ import { - RssContext, + type RssContext, initRssContext, search, - lookupByKey, dependencies, dependents, blastRadius, byTag, findEntryPoints, assembleContext, - getGraphStats, extractFilePaths, type RssQueryResult, } from './rss-operations.js'; @@ -302,7 +300,7 @@ export class ConversationalQueryEngine { startTime: number ): Promise { const searchStart = performance.now(); - const { entryPoints, searchTerms } = findEntryPoints(this.ctx, query, 5); + const { entryPoints } = findEntryPoints(this.ctx, query, 5); const searchTime = performance.now() - searchStart; if (entryPoints.length === 0) { @@ -316,7 +314,7 @@ export class ConversationalQueryEngine { const filePaths = extractFilePaths([primary, ...impact.nodes]); - const summary = this.buildDescriptionSummary(primary, impact.nodes, searchTerms); + const summary = this.buildDescriptionSummary(primary, impact.nodes); return { query, @@ -597,7 +595,7 @@ export class ConversationalQueryEngine { startTime: number ): Promise { const searchStart = performance.now(); - const { entryPoints, searchTerms } = findEntryPoints(this.ctx, query, 10); + const { entryPoints } = findEntryPoints(this.ctx, query, 10); const searchTime = performance.now() - searchStart; if (entryPoints.length === 0) { @@ -677,8 +675,7 @@ export class ConversationalQueryEngine { private buildDescriptionSummary( primary: AidocNode, - related: AidocNode[], - searchTerms: string[] + related: AidocNode[] ): string { const typeLabel = primary.type.replace(/_/g, ' '); const connectionCount = primary.references.length + primary.referencedBy.length; diff --git a/src/rss/graph-loader.test.ts b/src/rss/graph-loader.test.ts index 0511433..da74dcb 100644 --- a/src/rss/graph-loader.test.ts +++ b/src/rss/graph-loader.test.ts @@ -8,7 +8,7 @@ import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { mkdir, mkdtemp, writeFile, rm } from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; -import { loadAidocGraph, type AidocNode, type AidocEdge } from './graph-loader.js'; +import { loadAidocGraph } from './graph-loader.js'; let tempDir: string; diff --git a/src/rss/rss-operations.test.ts b/src/rss/rss-operations.test.ts index 96c1216..bfb0cf5 100644 --- a/src/rss/rss-operations.test.ts +++ b/src/rss/rss-operations.test.ts @@ -25,8 +25,6 @@ import { findAllBrokenEdges, validateGraphHealth, type RssContext, - type BrokenEdge, - type BidirectionalInconsistency, } from './rss-operations.js'; let tempDir: string; diff --git a/src/rss/rss-operations.ts b/src/rss/rss-operations.ts index 2e201c8..61cb80d 100644 --- a/src/rss/rss-operations.ts +++ b/src/rss/rss-operations.ts @@ -12,7 +12,7 @@ * - assemble_context(task) — Main context assembly function */ -import { loadAidocGraph, AidocNode, AidocGraph, AidocEdge } from './graph-loader.js'; +import { loadAidocGraph, AidocNode, AidocGraph } from './graph-loader.js'; import path from 'node:path'; /** @@ -70,7 +70,7 @@ export async function initRssContext(stateRoot: string = '.ste/state'): Promise< */ export function lookup(ctx: RssContext, domain: string, id: string): AidocNode | null { // Try direct lookup - for (const [key, node] of ctx.graph.entries()) { + for (const [, node] of ctx.graph.entries()) { if (node.domain === domain && node.id === id) { return node; } diff --git a/src/watch/change-detector.test.ts b/src/watch/change-detector.test.ts index 343cc63..5a23ec8 100644 --- a/src/watch/change-detector.test.ts +++ b/src/watch/change-detector.test.ts @@ -19,7 +19,6 @@ import { detectFileChanges, manifestPath, type ReconManifest, - type FileFingerprint, } from './change-detector.js'; let tempDir: string; diff --git a/src/watch/edit-queue-manager.test.ts b/src/watch/edit-queue-manager.test.ts index 3d4243b..68db92b 100644 --- a/src/watch/edit-queue-manager.test.ts +++ b/src/watch/edit-queue-manager.test.ts @@ -5,7 +5,7 @@ */ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; -import { EditQueueManager, type FileChange } from './edit-queue-manager.js'; +import { EditQueueManager } from './edit-queue-manager.js'; describe('EditQueueManager', () => { let manager: EditQueueManager; diff --git a/src/watch/full-reconciliation.test.ts b/src/watch/full-reconciliation.test.ts index 8389445..940d1f2 100644 --- a/src/watch/full-reconciliation.test.ts +++ b/src/watch/full-reconciliation.test.ts @@ -8,7 +8,6 @@ import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import fs from 'node:fs/promises'; import path from 'node:path'; import os from 'node:os'; -import yaml from 'js-yaml'; import { computeFileChecksum, } from './full-reconciliation.js'; diff --git a/src/watch/full-reconciliation.ts b/src/watch/full-reconciliation.ts index 8f9833d..8a81e31 100644 --- a/src/watch/full-reconciliation.ts +++ b/src/watch/full-reconciliation.ts @@ -41,7 +41,7 @@ export async function computeFileChecksum(filepath: string): Promise { try { const content = await fs.readFile(filepath, 'utf-8'); return createHash('sha256').update(content, 'utf-8').digest('hex'); - } catch (error) { + } catch { // File doesn't exist or can't be read return ''; } @@ -225,4 +225,3 @@ export function scheduleFullReconciliation( console.log('[Full Reconciliation] Stopped'); }; } - diff --git a/src/watch/write-tracker.ts b/src/watch/write-tracker.ts index b58783c..b220fc7 100644 --- a/src/watch/write-tracker.ts +++ b/src/watch/write-tracker.ts @@ -69,7 +69,7 @@ export class WriteTracker { // If content matches our recorded write, it's our write return currentHash === record.contentHash; - } catch (error) { + } catch { // File read error - assume not our write return false; } @@ -103,4 +103,3 @@ export class WriteTracker { // Singleton instance export const writeTracker = new WriteTracker(); -