diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index a6e442c..9ab0945 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -14,43 +14,5 @@ "knowledge-management", "persistent-memory", "ontology" - ], - "commands": [ - "./commands/capture.md", - "./commands/discover.md", - "./commands/gc.md", - "./commands/init.md", - "./commands/integrate.md", - "./commands/list.md", - "./commands/query.md", - "./commands/recall.md", - "./commands/search.md", - "./commands/search-enhanced.md", - "./commands/setup.md", - "./commands/status.md", - "./commands/validate.md", - "./commands/custodian.md" - ], - "skills": [ - "./skills/mnemonic-agent-coordination/SKILL.md", - "./skills/mnemonic-blackboard/SKILL.md", - "./skills/mnemonic-core/SKILL.md", - "./skills/mnemonic-format/SKILL.md", - "./skills/mnemonic-organization/SKILL.md", - "./skills/mnemonic-progressive-disclosure/SKILL.md", - "./skills/mnemonic-search/SKILL.md", - "./skills/mnemonic-search-enhanced/SKILL.md", - "./skills/mnemonic-setup/SKILL.md", - "./skills/integrate/SKILL.md", - "./skills/ontology/SKILL.md", - "./skills/custodian/SKILL.md", - "./skills/qmd-setup/SKILL.md", - "./skills/qmd-reindex/SKILL.md" - ], - "agents": [ - "./agents/memory-curator.md", - "./agents/mnemonic-search-subcall.md", - "./agents/compression-worker.md", - "./agents/ontology-discovery.md" ] -} +} \ No newline at end of file diff --git a/.github/readme-infographic-g.jpeg b/.github/readme-infographic-g.jpeg deleted file mode 100644 index 2926f70..0000000 Binary files a/.github/readme-infographic-g.jpeg and /dev/null differ diff --git a/.github/readme-infographic.svg b/.github/readme-infographic.svg deleted file mode 100644 index 1c90018..0000000 --- a/.github/readme-infographic.svg +++ /dev/null @@ -1,165 +0,0 @@ - - - - - - - - - - - - - Mnemonic: Cognitive Memory Architecture - - - - - - Claude Code - - - - - - - - - Mnemonic Plugin - - - - - Commands - - - - Skills - - - - Hooks - - - - Ont - - - - - - - - - - Filesystem + Git - .memory.md (MIF Level 3) - - - - - Cognitive Namespaces - - - - - semantic/ - decisions/ knowledge/ entities/ - Facts, concepts, relationships - - - - - - episodic/ - incidents/ sessions/ blockers/ - Events, experiences, timelines - - - - - - procedural/ - runbooks/ patterns/ migrations/ - Steps, workflows, procedures - - - - - - Extensible Ontologies - - - - Custom entity types - - - - Entity relationships - - - - Discovery patterns - - - - MIF + JSON-LD export - - - - - - Features - - - - MIF Level 3 Format - - - - Git Versioning - - - - Proactive Hooks - - - - Cross-Session Sync - - - - No Dependencies - - - - Multi-Tool Support - - - - - - Integrations - Claude Code | GitHub Copilot - Cursor | Windsurf | Aider - Codex CLI | Gemini CLI - - - - - Quick Commands - /mnemonic:capture - /mnemonic:recall - /mnemonic:search - /mnemonic:discover - /mnemonic:validate - /mnemonic:gc - - - - - - Powered by MIF - Memory Interchange Format - - diff --git a/.github/social-preview-g.jpeg b/.github/social-preview-g.jpeg deleted file mode 100644 index 5d0c637..0000000 Binary files a/.github/social-preview-g.jpeg and /dev/null differ diff --git a/.github/social-preview.svg b/.github/social-preview.svg deleted file mode 100644 index 242dbe2..0000000 --- a/.github/social-preview.svg +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SEMANTIC - Facts & Knowledge - decisions/ knowledge/ entities/ - - - - - - - EPISODIC - Events & Experiences - incidents/ sessions/ blockers/ - - - - - - - PROCEDURAL - Workflows & Steps - runbooks/ patterns/ migrations/ - - - - - - EXTENSIBLE - Ontologies - - - - mnemonic - - - Cognitive Memory System for Claude Code - - - - - MIF Level 3 - - - - Git Versioned - - - - Filesystem - - - - No Dependencies - - - - - - - - - - diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml deleted file mode 100644 index 202dbf2..0000000 --- a/.github/workflows/ci-doctor.lock.yml +++ /dev/null @@ -1,1173 +0,0 @@ -# -# ___ _ _ -# / _ \ | | (_) -# | |_| | __ _ ___ _ __ | |_ _ ___ -# | _ |/ _` |/ _ \ '_ \| __| |/ __| -# | | | | (_| | __/ | | | |_| | (__ -# \_| |_/\__, |\___|_| |_|\__|_|\___| -# __/ | -# _ _ |___/ -# | | | | / _| | -# | | | | ___ _ __ _ __| |_| | _____ ____ -# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___| -# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ -# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ -# -# This file was automatically generated by gh-aw (v0.45.0). DO NOT EDIT. -# -# To update this file, edit githubnext/agentics/workflows/ci-doctor.md@eb7950f37d350af6fa09d19827c4883e72947221 and run: -# gh aw compile -# Not all edits will cause changes to this file. -# -# For more information: https://github.github.com/gh-aw/introduction/overview/ -# -# This workflow is an automated CI failure investigator that triggers when monitored workflows fail. -# Performs deep analysis of GitHub Actions workflow failures to identify root causes, -# patterns, and provide actionable remediation steps. Analyzes logs, error messages, -# and workflow configuration to help diagnose and resolve CI issues efficiently. -# -# Source: githubnext/agentics/workflows/ci-doctor.md@eb7950f37d350af6fa09d19827c4883e72947221 -# -# frontmatter-hash: 2cb21e1f83777de19c0137fc0a4ac2c3a3441a38e8d13c72756fedf132379622 - -name: "CI Failure Doctor" -"on": - workflow_run: - # zizmor: ignore[dangerous-triggers] - workflow_run trigger is secured with role and fork validation - branches: - - main - types: - - completed - workflows: - - Daily Perf Improver - - Daily Test Coverage Improver - -permissions: {} - -concurrency: - group: "gh-aw-${{ github.workflow }}" - -run-name: "CI Failure Doctor" - -jobs: - activation: - needs: pre_activation - # zizmor: ignore[dangerous-triggers] - workflow_run trigger is secured with role and fork validation - if: > - ((needs.pre_activation.outputs.activated == 'true') && (github.event.workflow_run.conclusion == 'failure')) && - ((github.event_name != 'workflow_run') || ((github.event.workflow_run.repository.id == github.repository_id) && - (!(github.event.workflow_run.repository.fork)))) - runs-on: ubuntu-slim - permissions: - contents: read - outputs: - comment_id: "" - comment_repo: "" - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Check workflow file timestamps - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_WORKFLOW_FILE: "ci-doctor.lock.yml" - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/check_workflow_timestamp_api.cjs'); - await main(); - - agent: - needs: activation - runs-on: ubuntu-latest - permissions: read-all - env: - DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} - GH_AW_ASSETS_ALLOWED_EXTS: "" - GH_AW_ASSETS_BRANCH: "" - GH_AW_ASSETS_MAX_SIZE_KB: 0 - GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs - GH_AW_SAFE_OUTPUTS: /opt/gh-aw/safeoutputs/outputs.jsonl - GH_AW_SAFE_OUTPUTS_CONFIG_PATH: /opt/gh-aw/safeoutputs/config.json - GH_AW_SAFE_OUTPUTS_TOOLS_PATH: /opt/gh-aw/safeoutputs/tools.json - GH_AW_WORKFLOW_ID_SANITIZED: cidoctor - outputs: - checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }} - has_patch: ${{ steps.collect_output.outputs.has_patch }} - model: ${{ steps.generate_aw_info.outputs.model }} - output: ${{ steps.collect_output.outputs.output }} - output_types: ${{ steps.collect_output.outputs.output_types }} - secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - name: Create gh-aw temp directory - run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - # Cache memory file share configuration from frontmatter processed below - - name: Create cache-memory directory - run: bash /opt/gh-aw/actions/create_cache_memory_dir.sh - - name: Restore cache-memory file share data - uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 - with: - key: memory-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }} - path: /tmp/gh-aw/cache-memory - restore-keys: | - memory-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}- - - name: Configure Git credentials - env: - REPO_NAME: ${{ github.repository }} - SERVER_URL: ${{ github.server_url }} - run: | - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - # Re-authenticate git with GitHub token - SERVER_URL_STRIPPED="${SERVER_URL#https://}" - git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" - echo "Git configured with standard GitHub Actions identity" - - name: Checkout PR branch - id: checkout-pr - if: | - github.event.pull_request - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - with: - github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/checkout_pr_branch.cjs'); - await main(); - - name: Generate agentic run info - id: generate_aw_info - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const fs = require('fs'); - - const awInfo = { - engine_id: "copilot", - engine_name: "GitHub Copilot CLI", - model: process.env.GH_AW_MODEL_AGENT_COPILOT || "", - version: "", - agent_version: "0.0.410", - cli_version: "v0.45.0", - workflow_name: "CI Failure Doctor", - experimental: false, - supports_tools_allowlist: true, - supports_http_transport: true, - run_id: context.runId, - run_number: context.runNumber, - run_attempt: process.env.GITHUB_RUN_ATTEMPT, - repository: context.repo.owner + '/' + context.repo.repo, - ref: context.ref, - sha: context.sha, - actor: context.actor, - event_name: context.eventName, - staged: false, - allowed_domains: ["defaults"], - firewall_enabled: true, - awf_version: "v0.18.0", - awmg_version: "v0.1.4", - steps: { - firewall: "squid" - }, - created_at: new Date().toISOString() - }; - - // Write to /tmp/gh-aw directory to avoid inclusion in PR - const tmpPath = '/tmp/gh-aw/aw_info.json'; - fs.writeFileSync(tmpPath, JSON.stringify(awInfo, null, 2)); - console.log('Generated aw_info.json at:', tmpPath); - console.log(JSON.stringify(awInfo, null, 2)); - - // Set model as output for reuse in other steps/jobs - core.setOutput('model', awInfo.model); - - name: Validate COPILOT_GITHUB_TOKEN secret - id: validate-secret - run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default - env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - - name: Install GitHub Copilot CLI - run: /opt/gh-aw/actions/install_copilot_cli.sh 0.0.410 - - name: Install awf binary - run: bash /opt/gh-aw/actions/install_awf_binary.sh v0.18.0 - - name: Determine automatic lockdown mode for GitHub MCP Server - id: determine-automatic-lockdown - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} - GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - with: - script: | - const determineAutomaticLockdown = require('/opt/gh-aw/actions/determine_automatic_lockdown.cjs'); - await determineAutomaticLockdown(github, context, core); - - name: Download container images - run: bash /opt/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.18.0 ghcr.io/github/gh-aw-firewall/squid:0.18.0 ghcr.io/github/gh-aw-mcpg:v0.1.4 ghcr.io/github/github-mcp-server:v0.30.3 node:lts-alpine - - name: Write Safe Outputs Config - run: | - mkdir -p /opt/gh-aw/safeoutputs - mkdir -p /tmp/gh-aw/safeoutputs - mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF' - {"add_comment":{"max":1},"create_issue":{"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}} - GH_AW_SAFE_OUTPUTS_CONFIG_EOF - cat > /opt/gh-aw/safeoutputs/tools.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_EOF' - [ - { - "description": "Create a new GitHub issue for tracking bugs, feature requests, or tasks. Use this for actionable work items that need assignment, labeling, and status tracking. For reports, announcements, or status updates that don't require task tracking, use create_discussion instead. CONSTRAINTS: Maximum 1 issue(s) can be created. Title will be prefixed with \"${{ github.workflow }}\". Labels [automation ci] will be automatically added.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "body": { - "description": "Detailed issue description in Markdown. Do NOT repeat the title as a heading since it already appears as the issue's h1. Include context, reproduction steps, or acceptance criteria as appropriate.", - "type": "string" - }, - "labels": { - "description": "Labels to categorize the issue (e.g., 'bug', 'enhancement'). Labels must exist in the repository.", - "items": { - "type": "string" - }, - "type": "array" - }, - "parent": { - "description": "Parent issue number for creating sub-issues. This is the numeric ID from the GitHub URL (e.g., 42 in github.com/owner/repo/issues/42). Can also be a temporary_id (e.g., 'aw_abc123', 'aw_Test123') from a previously created issue in the same workflow run.", - "type": [ - "number", - "string" - ] - }, - "temporary_id": { - "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", - "type": "string" - }, - "title": { - "description": "Concise issue title summarizing the bug, feature, or task. The title appears as the main heading, so keep it brief and descriptive.", - "type": "string" - } - }, - "required": [ - "title", - "body" - ], - "type": "object" - }, - "name": "create_issue" - }, - { - "description": "Add a comment to an existing GitHub issue, pull request, or discussion. Use this to provide feedback, answer questions, or add information to an existing conversation. For creating new items, use create_issue, create_discussion, or create_pull_request instead. IMPORTANT: Comments are subject to validation constraints enforced by the MCP server - maximum 65536 characters for the complete comment (including footer which is added automatically), 10 mentions (@username), and 50 links. Exceeding these limits will result in an immediate error with specific guidance. CONSTRAINTS: Maximum 1 comment(s) can be added.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "body": { - "description": "The comment text in Markdown format. This is the 'body' field - do not use 'comment_body' or other variations. Provide helpful, relevant information that adds value to the conversation. CONSTRAINTS: The complete comment (your body text + automatically added footer) must not exceed 65536 characters total. Maximum 10 mentions (@username), maximum 50 links (http/https URLs). A footer (~200-500 characters) is automatically appended with workflow attribution, so leave adequate space. If these limits are exceeded, the tool call will fail with a detailed error message indicating which constraint was violated.", - "type": "string" - }, - "item_number": { - "description": "The issue, pull request, or discussion number to comment on. This is the numeric ID from the GitHub URL (e.g., 123 in github.com/owner/repo/issues/123). If omitted, the tool will attempt to resolve the target from the current workflow context (triggering issue, PR, or discussion).", - "type": "number" - } - }, - "required": [ - "body" - ], - "type": "object" - }, - "name": "add_comment" - }, - { - "description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "alternatives": { - "description": "Any workarounds, manual steps, or alternative approaches the user could take (max 256 characters).", - "type": "string" - }, - "reason": { - "description": "Explanation of why this tool is needed or what information you want to share about the limitation (max 256 characters).", - "type": "string" - }, - "tool": { - "description": "Optional: Name or description of the missing tool or capability (max 128 characters). Be specific about what functionality is needed.", - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - }, - "name": "missing_tool" - }, - { - "description": "Log a transparency message when no significant actions are needed. Use this to confirm workflow completion and provide visibility when analysis is complete but no changes or outputs are required (e.g., 'No issues found', 'All checks passed'). This ensures the workflow produces human-visible output even when no other actions are taken.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "message": { - "description": "Status or completion message to log. Should explain what was analyzed and the outcome (e.g., 'Code review complete - no issues found', 'Analysis complete - all tests passing').", - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - }, - "name": "noop" - }, - { - "description": "Report that data or information needed to complete the task is not available. Use this when you cannot accomplish what was requested because required data, context, or information is missing.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "alternatives": { - "description": "Any workarounds, manual steps, or alternative approaches the user could take (max 256 characters).", - "type": "string" - }, - "context": { - "description": "Additional context about the missing data or where it should come from (max 256 characters).", - "type": "string" - }, - "data_type": { - "description": "Type or description of the missing data or information (max 128 characters). Be specific about what data is needed.", - "type": "string" - }, - "reason": { - "description": "Explanation of why this data is needed to complete the task (max 256 characters).", - "type": "string" - } - }, - "required": [], - "type": "object" - }, - "name": "missing_data" - } - ] - GH_AW_SAFE_OUTPUTS_TOOLS_EOF - cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF' - { - "add_comment": { - "defaultMax": 1, - "fields": { - "body": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "item_number": { - "issueOrPRNumber": true - } - } - }, - "create_issue": { - "defaultMax": 1, - "fields": { - "body": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "labels": { - "type": "array", - "itemType": "string", - "itemSanitize": true, - "itemMaxLength": 128 - }, - "parent": { - "issueOrPRNumber": true - }, - "repo": { - "type": "string", - "maxLength": 256 - }, - "temporary_id": { - "type": "string" - }, - "title": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 128 - } - } - }, - "missing_tool": { - "defaultMax": 20, - "fields": { - "alternatives": { - "type": "string", - "sanitize": true, - "maxLength": 512 - }, - "reason": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 256 - }, - "tool": { - "type": "string", - "sanitize": true, - "maxLength": 128 - } - } - }, - "noop": { - "defaultMax": 1, - "fields": { - "message": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - } - } - } - } - GH_AW_SAFE_OUTPUTS_VALIDATION_EOF - - name: Generate Safe Outputs MCP Server Config - id: safe-outputs-config - run: | - # Generate a secure random API key (360 bits of entropy, 40+ chars) - # Mask immediately to prevent timing vulnerabilities - API_KEY=$(openssl rand -base64 45 | tr -d '/+=') - echo "::add-mask::${API_KEY}" - - PORT=3001 - - # Set outputs for next steps - { - echo "safe_outputs_api_key=${API_KEY}" - echo "safe_outputs_port=${PORT}" - } >> "$GITHUB_OUTPUT" - - echo "Safe Outputs MCP server will run on port ${PORT}" - - - name: Start Safe Outputs MCP HTTP Server - id: safe-outputs-start - env: - DEBUG: '*' - GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }} - GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }} - GH_AW_SAFE_OUTPUTS_TOOLS_PATH: /opt/gh-aw/safeoutputs/tools.json - GH_AW_SAFE_OUTPUTS_CONFIG_PATH: /opt/gh-aw/safeoutputs/config.json - GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs - run: | - # Environment variables are set above to prevent template injection - export DEBUG - export GH_AW_SAFE_OUTPUTS_PORT - export GH_AW_SAFE_OUTPUTS_API_KEY - export GH_AW_SAFE_OUTPUTS_TOOLS_PATH - export GH_AW_SAFE_OUTPUTS_CONFIG_PATH - export GH_AW_MCP_LOG_DIR - - bash /opt/gh-aw/actions/start_safe_outputs_server.sh - - - name: Start MCP Gateway - id: start-mcp-gateway - env: - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }} - GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }} - GITHUB_MCP_LOCKDOWN: ${{ steps.determine-automatic-lockdown.outputs.lockdown == 'true' && '1' || '0' }} - GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - run: | - set -eo pipefail - mkdir -p /tmp/gh-aw/mcp-config - - # Export gateway environment variables for MCP config and gateway script - export MCP_GATEWAY_PORT="80" - export MCP_GATEWAY_DOMAIN="host.docker.internal" - MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=') - echo "::add-mask::${MCP_GATEWAY_API_KEY}" - export MCP_GATEWAY_API_KEY - export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" - mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" - export DEBUG="*" - - export GH_AW_ENGINE="copilot" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_LOCKDOWN -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.1.4' - - mkdir -p /home/runner/.copilot - cat << GH_AW_MCP_CONFIG_EOF | bash /opt/gh-aw/actions/start_mcp_gateway.sh - { - "mcpServers": { - "github": { - "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v0.30.3", - "env": { - "GITHUB_LOCKDOWN_MODE": "$GITHUB_MCP_LOCKDOWN", - "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}", - "GITHUB_READ_ONLY": "1", - "GITHUB_TOOLSETS": "context,repos,issues,pull_requests" - } - }, - "safeoutputs": { - "type": "http", - "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT", - "headers": { - "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}" - } - } - }, - "gateway": { - "port": $MCP_GATEWAY_PORT, - "domain": "${MCP_GATEWAY_DOMAIN}", - "apiKey": "${MCP_GATEWAY_API_KEY}", - "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" - } - } - GH_AW_MCP_CONFIG_EOF - - name: Generate workflow overview - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { generateWorkflowOverview } = require('/opt/gh-aw/actions/generate_workflow_overview.cjs'); - await generateWorkflowOverview(core); - - name: Create prompt with built-in context - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GH_AW_GITHUB_ACTOR: ${{ github.actor }} - GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_CONCLUSION: ${{ github.event.workflow_run.conclusion }} - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_EVENT: ${{ github.event.workflow_run.event }} - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_HEAD_SHA: ${{ github.event.workflow_run.head_sha }} - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_HTML_URL: ${{ github.event.workflow_run.html_url }} - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_ID: ${{ github.event.workflow_run.id }} - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_RUN_NUMBER: ${{ github.event.workflow_run.run_number }} - GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} - GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} - GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - run: | - bash /opt/gh-aw/actions/create_prompt_first.sh - cat << 'GH_AW_PROMPT_EOF' > "$GH_AW_PROMPT" - - GH_AW_PROMPT_EOF - cat "/opt/gh-aw/prompts/xpia.md" >> "$GH_AW_PROMPT" - cat "/opt/gh-aw/prompts/temp_folder_prompt.md" >> "$GH_AW_PROMPT" - cat "/opt/gh-aw/prompts/markdown.md" >> "$GH_AW_PROMPT" - cat "/opt/gh-aw/prompts/cache_memory_prompt.md" >> "$GH_AW_PROMPT" - cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT" - - GitHub API Access Instructions - - The gh CLI is NOT authenticated. Do NOT use gh commands for GitHub operations. - - - To create or modify GitHub resources (issues, discussions, pull requests, etc.), you MUST call the appropriate safe output tool. Simply writing content will NOT work - the workflow requires actual tool calls. - - Temporary IDs: Some safe output tools support a temporary ID field (usually named temporary_id) so you can reference newly-created items elsewhere in the SAME agent output (for example, using #aw_abc1 in a later body). - - **IMPORTANT - temporary_id format rules:** - - If you DON'T need to reference the item later, OMIT the temporary_id field entirely (it will be auto-generated if needed) - - If you DO need cross-references/chaining, you MUST match this EXACT validation regex: /^aw_[A-Za-z0-9]{3,8}$/i - - Format: aw_ prefix followed by 3 to 8 alphanumeric characters (A-Z, a-z, 0-9, case-insensitive) - - Valid alphanumeric characters: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 - - INVALID examples: aw_ab (too short), aw_123456789 (too long), aw_test-id (contains hyphen), aw_id_123 (contains underscore) - - VALID examples: aw_abc, aw_abc1, aw_Test123, aw_A1B2C3D4, aw_12345678 - - To generate valid IDs: use 3-8 random alphanumeric characters or omit the field to let the system auto-generate - - Do NOT invent other aw_* formats — downstream steps will reject them with validation errors matching against /^aw_[A-Za-z0-9]{3,8}$/i. - - Discover available tools from the safeoutputs MCP server. - - **Critical**: Tool calls write structured data that downstream jobs process. Without tool calls, follow-up actions will be skipped. - - **Note**: If you made no other safe output tool calls during this workflow execution, call the "noop" tool to provide a status message indicating completion or that no actions were needed. - - - - The following GitHub context information is available for this workflow: - {{#if __GH_AW_GITHUB_ACTOR__ }} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if __GH_AW_GITHUB_REPOSITORY__ }} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if __GH_AW_GITHUB_WORKSPACE__ }} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ }} - - **issue-number**: #__GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ }} - - **discussion-number**: #__GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ }} - - **pull-request-number**: #__GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_COMMENT_ID__ }} - - **comment-id**: __GH_AW_GITHUB_EVENT_COMMENT_ID__ - {{/if}} - {{#if __GH_AW_GITHUB_RUN_ID__ }} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - - GH_AW_PROMPT_EOF - cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT" - - GH_AW_PROMPT_EOF - cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT" - {{#runtime-import .github/workflows/ci-doctor.md}} - GH_AW_PROMPT_EOF - - name: Substitute placeholders - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_ALLOWED_EXTENSIONS: '' - GH_AW_CACHE_DESCRIPTION: '' - GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' - GH_AW_GITHUB_ACTOR: ${{ github.actor }} - GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_CONCLUSION: ${{ github.event.workflow_run.conclusion }} - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_EVENT: ${{ github.event.workflow_run.event }} - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_HEAD_SHA: ${{ github.event.workflow_run.head_sha }} - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_HTML_URL: ${{ github.event.workflow_run.html_url }} - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_ID: ${{ github.event.workflow_run.id }} - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_RUN_NUMBER: ${{ github.event.workflow_run.run_number }} - GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} - GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} - GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - with: - script: | - const substitutePlaceholders = require('/opt/gh-aw/actions/substitute_placeholders.cjs'); - - // Call the substitution function - return await substitutePlaceholders({ - file: process.env.GH_AW_PROMPT, - substitutions: { - GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, - GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, - GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, - GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, - GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID, - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER, - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: process.env.GH_AW_GITHUB_EVENT_ISSUE_NUMBER, - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER, - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_CONCLUSION: process.env.GH_AW_GITHUB_EVENT_WORKFLOW_RUN_CONCLUSION, - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_EVENT: process.env.GH_AW_GITHUB_EVENT_WORKFLOW_RUN_EVENT, - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_HEAD_SHA: process.env.GH_AW_GITHUB_EVENT_WORKFLOW_RUN_HEAD_SHA, - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_HTML_URL: process.env.GH_AW_GITHUB_EVENT_WORKFLOW_RUN_HTML_URL, - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_ID: process.env.GH_AW_GITHUB_EVENT_WORKFLOW_RUN_ID, - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_RUN_NUMBER: process.env.GH_AW_GITHUB_EVENT_WORKFLOW_RUN_RUN_NUMBER, - GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, - GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, - GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE - } - }); - - name: Interpolate variables and render templates - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_CONCLUSION: ${{ github.event.workflow_run.conclusion }} - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_EVENT: ${{ github.event.workflow_run.event }} - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_HEAD_SHA: ${{ github.event.workflow_run.head_sha }} - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_HTML_URL: ${{ github.event.workflow_run.html_url }} - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_ID: ${{ github.event.workflow_run.id }} - GH_AW_GITHUB_EVENT_WORKFLOW_RUN_RUN_NUMBER: ${{ github.event.workflow_run.run_number }} - GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/interpolate_prompt.cjs'); - await main(); - - name: Validate prompt placeholders - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - run: bash /opt/gh-aw/actions/validate_prompt_placeholders.sh - - name: Print prompt - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - run: bash /opt/gh-aw/actions/print_prompt_summary.sh - - name: Clean git credentials - run: bash /opt/gh-aw/actions/clean_git_credentials.sh - - name: Execute GitHub Copilot CLI - id: agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 10 - run: | - set -o pipefail - sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.18.0 --skip-pull \ - -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_COPILOT:+ --model "$GH_AW_MODEL_AGENT_COPILOT"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log - env: - COPILOT_AGENT_RUNNER_TYPE: STANDALONE - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json - GH_AW_MODEL_AGENT_COPILOT: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }} - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GITHUB_HEAD_REF: ${{ github.head_ref }} - GITHUB_REF_NAME: ${{ github.ref_name }} - GITHUB_STEP_SUMMARY: ${{ env.GITHUB_STEP_SUMMARY }} - GITHUB_WORKSPACE: ${{ github.workspace }} - XDG_CONFIG_HOME: /home/runner - - name: Configure Git credentials - env: - REPO_NAME: ${{ github.repository }} - SERVER_URL: ${{ github.server_url }} - run: | - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - # Re-authenticate git with GitHub token - SERVER_URL_STRIPPED="${SERVER_URL#https://}" - git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" - echo "Git configured with standard GitHub Actions identity" - - name: Copy Copilot session state files to logs - if: always() - continue-on-error: true - run: | - # Copy Copilot session state files to logs folder for artifact collection - # This ensures they are in /tmp/gh-aw/ where secret redaction can scan them - SESSION_STATE_DIR="$HOME/.copilot/session-state" - LOGS_DIR="/tmp/gh-aw/sandbox/agent/logs" - - if [ -d "$SESSION_STATE_DIR" ]; then - echo "Copying Copilot session state files from $SESSION_STATE_DIR to $LOGS_DIR" - mkdir -p "$LOGS_DIR" - cp -v "$SESSION_STATE_DIR"/*.jsonl "$LOGS_DIR/" 2>/dev/null || true - echo "Session state files copied successfully" - else - echo "No session-state directory found at $SESSION_STATE_DIR" - fi - - name: Stop MCP Gateway - if: always() - continue-on-error: true - env: - MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }} - MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }} - GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }} - run: | - bash /opt/gh-aw/actions/stop_mcp_gateway.sh "$GATEWAY_PID" - - name: Redact secrets in logs - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/redact_secrets.cjs'); - await main(); - env: - GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN' - SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} - SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Upload Safe Outputs - if: always() - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: safe-output - path: ${{ env.GH_AW_SAFE_OUTPUTS }} - if-no-files-found: warn - - name: Ingest agent output - id: collect_output - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com" - GITHUB_SERVER_URL: ${{ github.server_url }} - GITHUB_API_URL: ${{ github.api_url }} - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/collect_ndjson_output.cjs'); - await main(); - - name: Upload sanitized agent output - if: always() && env.GH_AW_AGENT_OUTPUT - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: agent-output - path: ${{ env.GH_AW_AGENT_OUTPUT }} - if-no-files-found: warn - - name: Upload engine output files - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: agent_outputs - path: | - /tmp/gh-aw/sandbox/agent/logs/ - /tmp/gh-aw/redacted-urls.log - if-no-files-found: ignore - - name: Parse agent logs for step summary - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/ - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/parse_copilot_log.cjs'); - await main(); - - name: Parse MCP Gateway logs for step summary - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/parse_mcp_gateway_log.cjs'); - await main(); - - name: Print firewall logs - if: always() - continue-on-error: true - env: - AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs - run: | - # Fix permissions on firewall logs so they can be uploaded as artifacts - # AWF runs with sudo, creating files owned by root - sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true - # Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step) - if command -v awf &> /dev/null; then - awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" - else - echo 'AWF binary not installed, skipping firewall log summary' - fi - - name: Upload cache-memory data as artifact - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - if: always() - with: - name: cache-memory - path: /tmp/gh-aw/cache-memory - - name: Upload agent artifacts - if: always() - continue-on-error: true - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: agent-artifacts - path: | - /tmp/gh-aw/aw-prompts/prompt.txt - /tmp/gh-aw/aw_info.json - /tmp/gh-aw/mcp-logs/ - /tmp/gh-aw/sandbox/firewall/logs/ - /tmp/gh-aw/agent-stdio.log - /tmp/gh-aw/agent/ - if-no-files-found: ignore - - conclusion: - needs: - - activation - - agent - - detection - - safe_outputs - - update_cache_memory - if: (always()) && (needs.agent.result != 'skipped') - runs-on: ubuntu-slim - permissions: - contents: read - discussions: write - issues: write - pull-requests: write - outputs: - noop_message: ${{ steps.noop.outputs.noop_message }} - tools_reported: ${{ steps.missing_tool.outputs.tools_reported }} - total_count: ${{ steps.missing_tool.outputs.total_count }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Download agent output artifact - continue-on-error: true - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: agent-output - path: /tmp/gh-aw/safeoutputs/ - - name: Setup agent output environment variable - run: | - mkdir -p /tmp/gh-aw/safeoutputs/ - find "/tmp/gh-aw/safeoutputs/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/safeoutputs/agent_output.json" >> "$GITHUB_ENV" - - name: Process No-Op Messages - id: noop - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_NOOP_MAX: 1 - GH_AW_WORKFLOW_NAME: "CI Failure Doctor" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/ci-doctor.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/ci-doctor.md" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/noop.cjs'); - await main(); - - name: Record Missing Tool - id: missing_tool - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "CI Failure Doctor" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/ci-doctor.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/ci-doctor.md" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/missing_tool.cjs'); - await main(); - - name: Handle Agent Failure - id: handle_agent_failure - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "CI Failure Doctor" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/ci-doctor.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/ci-doctor.md" - GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_WORKFLOW_ID: "ci-doctor" - GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.agent.outputs.secret_verification_result }} - GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/handle_agent_failure.cjs'); - await main(); - - name: Handle No-Op Message - id: handle_noop_message - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "CI Failure Doctor" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/ci-doctor.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/ci-doctor.md" - GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_MESSAGE: ${{ steps.noop.outputs.noop_message }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/handle_noop_message.cjs'); - await main(); - - detection: - needs: agent - if: needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true' - runs-on: ubuntu-latest - permissions: {} - timeout-minutes: 10 - outputs: - success: ${{ steps.parse_results.outputs.success }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Download agent artifacts - continue-on-error: true - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: agent-artifacts - path: /tmp/gh-aw/threat-detection/ - - name: Download agent output artifact - continue-on-error: true - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: agent-output - path: /tmp/gh-aw/threat-detection/ - - name: Echo agent output types - env: - AGENT_OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }} - run: | - echo "Agent output-types: $AGENT_OUTPUT_TYPES" - - name: Setup threat detection - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - WORKFLOW_NAME: "CI Failure Doctor" - WORKFLOW_DESCRIPTION: "This workflow is an automated CI failure investigator that triggers when monitored workflows fail.\nPerforms deep analysis of GitHub Actions workflow failures to identify root causes,\npatterns, and provide actionable remediation steps. Analyzes logs, error messages,\nand workflow configuration to help diagnose and resolve CI issues efficiently." - HAS_PATCH: ${{ needs.agent.outputs.has_patch }} - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/setup_threat_detection.cjs'); - await main(); - - name: Ensure threat-detection directory and log - run: | - mkdir -p /tmp/gh-aw/threat-detection - touch /tmp/gh-aw/threat-detection/detection.log - - name: Validate COPILOT_GITHUB_TOKEN secret - id: validate-secret - run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default - env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - - name: Install GitHub Copilot CLI - run: /opt/gh-aw/actions/install_copilot_cli.sh 0.0.410 - - name: Execute GitHub Copilot CLI - id: agentic_execution - # Copilot CLI tool arguments (sorted): - # --allow-tool shell(cat) - # --allow-tool shell(grep) - # --allow-tool shell(head) - # --allow-tool shell(jq) - # --allow-tool shell(ls) - # --allow-tool shell(tail) - # --allow-tool shell(wc) - timeout-minutes: 20 - run: | - set -o pipefail - COPILOT_CLI_INSTRUCTION="$(cat /tmp/gh-aw/aw-prompts/prompt.txt)" - mkdir -p /tmp/ - mkdir -p /tmp/gh-aw/ - mkdir -p /tmp/gh-aw/agent/ - mkdir -p /tmp/gh-aw/sandbox/agent/logs/ - copilot --add-dir /tmp/ --add-dir /tmp/gh-aw/ --add-dir /tmp/gh-aw/agent/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-tool 'shell(cat)' --allow-tool 'shell(grep)' --allow-tool 'shell(head)' --allow-tool 'shell(jq)' --allow-tool 'shell(ls)' --allow-tool 'shell(tail)' --allow-tool 'shell(wc)' --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$COPILOT_CLI_INSTRUCTION"${GH_AW_MODEL_DETECTION_COPILOT:+ --model "$GH_AW_MODEL_DETECTION_COPILOT"} 2>&1 | tee /tmp/gh-aw/threat-detection/detection.log - env: - COPILOT_AGENT_RUNNER_TYPE: STANDALONE - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - GH_AW_MODEL_DETECTION_COPILOT: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }} - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GITHUB_HEAD_REF: ${{ github.head_ref }} - GITHUB_REF_NAME: ${{ github.ref_name }} - GITHUB_STEP_SUMMARY: ${{ env.GITHUB_STEP_SUMMARY }} - GITHUB_WORKSPACE: ${{ github.workspace }} - XDG_CONFIG_HOME: /home/runner - - name: Parse threat detection results - id: parse_results - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - - name: Upload threat detection log - if: always() - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: threat-detection.log - path: /tmp/gh-aw/threat-detection/detection.log - if-no-files-found: ignore - - pre_activation: - if: ${{ github.event.workflow_run.conclusion == 'failure' }} - runs-on: ubuntu-slim - outputs: - activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Check team membership for workflow - id: check_membership - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_REQUIRED_ROLES: admin,maintainer,write - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/check_membership.cjs'); - await main(); - - safe_outputs: - needs: - - agent - - detection - if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (needs.detection.outputs.success == 'true') - runs-on: ubuntu-slim - permissions: - contents: read - discussions: write - issues: write - pull-requests: write - timeout-minutes: 15 - env: - GH_AW_WORKFLOW_ID: "ci-doctor" - GH_AW_WORKFLOW_NAME: "CI Failure Doctor" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/ci-doctor.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/ci-doctor.md" - outputs: - create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }} - create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} - process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} - process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Download agent output artifact - continue-on-error: true - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: agent-output - path: /tmp/gh-aw/safeoutputs/ - - name: Setup agent output environment variable - run: | - mkdir -p /tmp/gh-aw/safeoutputs/ - find "/tmp/gh-aw/safeoutputs/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/safeoutputs/agent_output.json" >> "$GITHUB_ENV" - - name: Process Safe Outputs - id: process_safe_outputs - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_issue\":{\"labels\":[\"automation\",\"ci\"],\"max\":1,\"title_prefix\":\"${{ github.workflow }}\"},\"missing_data\":{},\"missing_tool\":{}}" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/safe_output_handler_manager.cjs'); - await main(); - - update_cache_memory: - needs: - - agent - - detection - if: always() && needs.detection.outputs.success == 'true' - runs-on: ubuntu-latest - permissions: {} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Download cache-memory artifact (default) - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - continue-on-error: true - with: - name: cache-memory - path: /tmp/gh-aw/cache-memory - - name: Save cache-memory to cache (default) - uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 - with: - key: memory-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }} - path: /tmp/gh-aw/cache-memory - diff --git a/.github/workflows/ci-doctor.md b/.github/workflows/ci-doctor.md deleted file mode 100644 index 3bab6ad..0000000 --- a/.github/workflows/ci-doctor.md +++ /dev/null @@ -1,196 +0,0 @@ ---- -description: | - This workflow is an automated CI failure investigator that triggers when monitored workflows fail. - Performs deep analysis of GitHub Actions workflow failures to identify root causes, - patterns, and provide actionable remediation steps. Analyzes logs, error messages, - and workflow configuration to help diagnose and resolve CI issues efficiently. - -on: - workflow_run: - workflows: ["Daily Perf Improver", "Daily Test Coverage Improver"] # Monitor the CI workflow specifically - types: - - completed - branches: - - main - -# Only trigger for failures - check in the workflow body -if: ${{ github.event.workflow_run.conclusion == 'failure' }} - -permissions: read-all - -network: defaults - -safe-outputs: - create-issue: - title-prefix: "${{ github.workflow }}" - labels: [automation, ci] - add-comment: - -tools: - cache-memory: true - web-fetch: - -timeout-minutes: 10 - -source: githubnext/agentics/workflows/ci-doctor.md@eb7950f37d350af6fa09d19827c4883e72947221 ---- - -# CI Failure Doctor - -You are the CI Failure Doctor, an expert investigative agent that analyzes failed GitHub Actions workflows to identify root causes and patterns. Your goal is to conduct a deep investigation when the CI workflow fails. - -## Current Context - -- **Repository**: ${{ github.repository }} -- **Workflow Run**: ${{ github.event.workflow_run.id }} -- **Conclusion**: ${{ github.event.workflow_run.conclusion }} -- **Run URL**: ${{ github.event.workflow_run.html_url }} -- **Head SHA**: ${{ github.event.workflow_run.head_sha }} - -## Investigation Protocol - -**ONLY proceed if the workflow conclusion is 'failure' or 'cancelled'**. Exit immediately if the workflow was successful. - -### Phase 1: Initial Triage - -1. **Verify Failure**: Check that `${{ github.event.workflow_run.conclusion }}` is `failure` or `cancelled` -2. **Get Workflow Details**: Use `get_workflow_run` to get full details of the failed run -3. **List Jobs**: Use `list_workflow_jobs` to identify which specific jobs failed -4. **Quick Assessment**: Determine if this is a new type of failure or a recurring pattern - -### Phase 2: Deep Log Analysis - -1. **Retrieve Logs**: Use `get_job_logs` with `failed_only=true` to get logs from all failed jobs -2. **Pattern Recognition**: Analyze logs for: - - Error messages and stack traces - - Dependency installation failures - - Test failures with specific patterns - - Infrastructure or runner issues - - Timeout patterns - - Memory or resource constraints -3. **Extract Key Information**: - - Primary error messages - - File paths and line numbers where failures occurred - - Test names that failed - - Dependency versions involved - - Timing patterns - -### Phase 3: Historical Context Analysis - -1. **Search Investigation History**: Use file-based storage to search for similar failures: - - Read from cached investigation files in `/tmp/memory/investigations/` - - Parse previous failure patterns and solutions - - Look for recurring error signatures -2. **Issue History**: Search existing issues for related problems -3. **Commit Analysis**: Examine the commit that triggered the failure -4. **PR Context**: If triggered by a PR, analyze the changed files - -### Phase 4: Root Cause Investigation - -1. **Categorize Failure Type**: - - **Code Issues**: Syntax errors, logic bugs, test failures - - **Infrastructure**: Runner issues, network problems, resource constraints - - **Dependencies**: Version conflicts, missing packages, outdated libraries - - **Configuration**: Workflow configuration, environment variables - - **Flaky Tests**: Intermittent failures, timing issues - - **External Services**: Third-party API failures, downstream dependencies - -2. **Deep Dive Analysis**: - - For test failures: Identify specific test methods and assertions - - For build failures: Analyze compilation errors and missing dependencies - - For infrastructure issues: Check runner logs and resource usage - - For timeout issues: Identify slow operations and bottlenecks - -### Phase 5: Pattern Storage and Knowledge Building - -1. **Store Investigation**: Save structured investigation data to files: - - Write investigation report to `/tmp/memory/investigations/-.json` - - Store error patterns in `/tmp/memory/patterns/` - - Maintain an index file of all investigations for fast searching -2. **Update Pattern Database**: Enhance knowledge with new findings by updating pattern files -3. **Save Artifacts**: Store detailed logs and analysis in the cached directories - -### Phase 6: Looking for existing issues - -1. **Convert the report to a search query** - - Use any advanced search features in GitHub Issues to find related issues - - Look for keywords, error messages, and patterns in existing issues -2. **Judge each match issues for relevance** - - Analyze the content of the issues found by the search and judge if they are similar to this issue. -3. **Add issue comment to duplicate issue and finish** - - If you find a duplicate issue, add a comment with your findings and close the investigation. - - Do NOT open a new issue since you found a duplicate already (skip next phases). - -### Phase 6: Reporting and Recommendations - -1. **Create Investigation Report**: Generate a comprehensive analysis including: - - **Executive Summary**: Quick overview of the failure - - **Root Cause**: Detailed explanation of what went wrong - - **Reproduction Steps**: How to reproduce the issue locally - - **Recommended Actions**: Specific steps to fix the issue - - **Prevention Strategies**: How to avoid similar failures - - **AI Team Self-Improvement**: Give a short set of additional prompting instructions to copy-and-paste into instructions.md for AI coding agents to help prevent this type of failure in future - - **Historical Context**: Similar past failures and their resolutions - -2. **Actionable Deliverables**: - - Create an issue with investigation results (if warranted) - - Comment on related PR with analysis (if PR-triggered) - - Provide specific file locations and line numbers for fixes - - Suggest code changes or configuration updates - -## Output Requirements - -### Investigation Issue Template - -When creating an investigation issue, use this structure: - -```markdown -# 🏥 CI Failure Investigation - Run #${{ github.event.workflow_run.run_number }} - -## Summary -[Brief description of the failure] - -## Failure Details -- **Run**: [${{ github.event.workflow_run.id }}](${{ github.event.workflow_run.html_url }}) -- **Commit**: ${{ github.event.workflow_run.head_sha }} -- **Trigger**: ${{ github.event.workflow_run.event }} - -## Root Cause Analysis -[Detailed analysis of what went wrong] - -## Failed Jobs and Errors -[List of failed jobs with key error messages] - -## Investigation Findings -[Deep analysis results] - -## Recommended Actions -- [ ] [Specific actionable steps] - -## Prevention Strategies -[How to prevent similar failures] - -## AI Team Self-Improvement -[Short set of additional prompting instructions to copy-and-paste into instructions.md for a AI coding agents to help prevent this type of failure in future] - -## Historical Context -[Similar past failures and patterns] -``` - -## Important Guidelines - -- **Be Thorough**: Don't just report the error - investigate the underlying cause -- **Use Memory**: Always check for similar past failures and learn from them -- **Be Specific**: Provide exact file paths, line numbers, and error messages -- **Action-Oriented**: Focus on actionable recommendations, not just analysis -- **Pattern Building**: Contribute to the knowledge base for future investigations -- **Resource Efficient**: Use caching to avoid re-downloading large logs -- **Security Conscious**: Never execute untrusted code from logs or external sources - -## Cache Usage Strategy - -- Store investigation database and knowledge patterns in `/tmp/memory/investigations/` and `/tmp/memory/patterns/` -- Cache detailed log analysis and artifacts in `/tmp/investigation/logs/` and `/tmp/investigation/reports/` -- Persist findings across workflow runs using GitHub Actions cache -- Build cumulative knowledge about failure patterns and solutions using structured JSON files -- Use file-based indexing for fast pattern matching and similarity detection diff --git a/.github/workflows/issue-triage.lock.yml b/.github/workflows/issue-triage.lock.yml deleted file mode 100644 index ff84d16..0000000 --- a/.github/workflows/issue-triage.lock.yml +++ /dev/null @@ -1,1062 +0,0 @@ -# -# ___ _ _ -# / _ \ | | (_) -# | |_| | __ _ ___ _ __ | |_ _ ___ -# | _ |/ _` |/ _ \ '_ \| __| |/ __| -# | | | | (_| | __/ | | | |_| | (__ -# \_| |_/\__, |\___|_| |_|\__|_|\___| -# __/ | -# _ _ |___/ -# | | | | / _| | -# | | | | ___ _ __ _ __| |_| | _____ ____ -# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___| -# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ -# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ -# -# This file was automatically generated by gh-aw (v0.45.0). DO NOT EDIT. -# -# To update this file, edit githubnext/agentics/workflows/issue-triage.md@eb7950f37d350af6fa09d19827c4883e72947221 and run: -# gh aw compile -# Not all edits will cause changes to this file. -# -# For more information: https://github.github.com/gh-aw/introduction/overview/ -# -# Intelligent issue triage assistant that processes new and reopened issues. -# Analyzes issue content, selects appropriate labels, detects spam, gathers context -# from similar issues, and provides analysis notes including debugging strategies, -# reproduction steps, and resource links. Helps maintainers quickly understand and -# prioritize incoming issues. -# -# Source: githubnext/agentics/workflows/issue-triage.md@eb7950f37d350af6fa09d19827c4883e72947221 -# -# frontmatter-hash: 9a6e7204ade267f685c491ee9911cd7527e7ed2736a51a1fbb104d897af68384 - -name: "Agentic Triage" -"on": - issues: - types: - - opened - - reopened - -permissions: {} - -concurrency: - group: "gh-aw-${{ github.workflow }}-${{ github.event.issue.number }}" - -run-name: "Agentic Triage" - -jobs: - activation: - needs: pre_activation - if: needs.pre_activation.outputs.activated == 'true' - runs-on: ubuntu-slim - permissions: - contents: read - discussions: write - issues: write - pull-requests: write - outputs: - comment_id: "" - comment_repo: "" - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Check workflow file timestamps - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_WORKFLOW_FILE: "issue-triage.lock.yml" - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/check_workflow_timestamp_api.cjs'); - await main(); - - agent: - needs: activation - runs-on: ubuntu-latest - permissions: read-all - env: - DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} - GH_AW_ASSETS_ALLOWED_EXTS: "" - GH_AW_ASSETS_BRANCH: "" - GH_AW_ASSETS_MAX_SIZE_KB: 0 - GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs - GH_AW_SAFE_OUTPUTS: /opt/gh-aw/safeoutputs/outputs.jsonl - GH_AW_SAFE_OUTPUTS_CONFIG_PATH: /opt/gh-aw/safeoutputs/config.json - GH_AW_SAFE_OUTPUTS_TOOLS_PATH: /opt/gh-aw/safeoutputs/tools.json - GH_AW_WORKFLOW_ID_SANITIZED: issuetriage - outputs: - checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }} - has_patch: ${{ steps.collect_output.outputs.has_patch }} - model: ${{ steps.generate_aw_info.outputs.model }} - output: ${{ steps.collect_output.outputs.output }} - output_types: ${{ steps.collect_output.outputs.output_types }} - secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - name: Create gh-aw temp directory - run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - - name: Configure Git credentials - env: - REPO_NAME: ${{ github.repository }} - SERVER_URL: ${{ github.server_url }} - run: | - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - # Re-authenticate git with GitHub token - SERVER_URL_STRIPPED="${SERVER_URL#https://}" - git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" - echo "Git configured with standard GitHub Actions identity" - - name: Checkout PR branch - id: checkout-pr - if: | - github.event.pull_request - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - with: - github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/checkout_pr_branch.cjs'); - await main(); - - name: Generate agentic run info - id: generate_aw_info - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const fs = require('fs'); - - const awInfo = { - engine_id: "copilot", - engine_name: "GitHub Copilot CLI", - model: process.env.GH_AW_MODEL_AGENT_COPILOT || "", - version: "", - agent_version: "0.0.410", - cli_version: "v0.45.0", - workflow_name: "Agentic Triage", - experimental: false, - supports_tools_allowlist: true, - supports_http_transport: true, - run_id: context.runId, - run_number: context.runNumber, - run_attempt: process.env.GITHUB_RUN_ATTEMPT, - repository: context.repo.owner + '/' + context.repo.repo, - ref: context.ref, - sha: context.sha, - actor: context.actor, - event_name: context.eventName, - staged: false, - allowed_domains: ["defaults"], - firewall_enabled: true, - awf_version: "v0.18.0", - awmg_version: "v0.1.4", - steps: { - firewall: "squid" - }, - created_at: new Date().toISOString() - }; - - // Write to /tmp/gh-aw directory to avoid inclusion in PR - const tmpPath = '/tmp/gh-aw/aw_info.json'; - fs.writeFileSync(tmpPath, JSON.stringify(awInfo, null, 2)); - console.log('Generated aw_info.json at:', tmpPath); - console.log(JSON.stringify(awInfo, null, 2)); - - // Set model as output for reuse in other steps/jobs - core.setOutput('model', awInfo.model); - - name: Validate COPILOT_GITHUB_TOKEN secret - id: validate-secret - run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default - env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - - name: Install GitHub Copilot CLI - run: /opt/gh-aw/actions/install_copilot_cli.sh 0.0.410 - - name: Install awf binary - run: bash /opt/gh-aw/actions/install_awf_binary.sh v0.18.0 - - name: Download container images - run: bash /opt/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.18.0 ghcr.io/github/gh-aw-firewall/squid:0.18.0 ghcr.io/github/gh-aw-mcpg:v0.1.4 ghcr.io/github/github-mcp-server:v0.30.3 node:lts-alpine - - name: Write Safe Outputs Config - run: | - mkdir -p /opt/gh-aw/safeoutputs - mkdir -p /tmp/gh-aw/safeoutputs - mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF' - {"add_comment":{"max":1},"add_labels":{"max":5},"missing_data":{},"missing_tool":{},"noop":{"max":1}} - GH_AW_SAFE_OUTPUTS_CONFIG_EOF - cat > /opt/gh-aw/safeoutputs/tools.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_EOF' - [ - { - "description": "Add a comment to an existing GitHub issue, pull request, or discussion. Use this to provide feedback, answer questions, or add information to an existing conversation. For creating new items, use create_issue, create_discussion, or create_pull_request instead. IMPORTANT: Comments are subject to validation constraints enforced by the MCP server - maximum 65536 characters for the complete comment (including footer which is added automatically), 10 mentions (@username), and 50 links. Exceeding these limits will result in an immediate error with specific guidance. CONSTRAINTS: Maximum 1 comment(s) can be added.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "body": { - "description": "The comment text in Markdown format. This is the 'body' field - do not use 'comment_body' or other variations. Provide helpful, relevant information that adds value to the conversation. CONSTRAINTS: The complete comment (your body text + automatically added footer) must not exceed 65536 characters total. Maximum 10 mentions (@username), maximum 50 links (http/https URLs). A footer (~200-500 characters) is automatically appended with workflow attribution, so leave adequate space. If these limits are exceeded, the tool call will fail with a detailed error message indicating which constraint was violated.", - "type": "string" - }, - "item_number": { - "description": "The issue, pull request, or discussion number to comment on. This is the numeric ID from the GitHub URL (e.g., 123 in github.com/owner/repo/issues/123). If omitted, the tool will attempt to resolve the target from the current workflow context (triggering issue, PR, or discussion).", - "type": "number" - } - }, - "required": [ - "body" - ], - "type": "object" - }, - "name": "add_comment" - }, - { - "description": "Add labels to an existing GitHub issue or pull request for categorization and filtering. Labels must already exist in the repository. For creating new issues with labels, use create_issue with the labels property instead. CONSTRAINTS: Maximum 5 label(s) can be added.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "item_number": { - "description": "Issue or PR number to add labels to. This is the numeric ID from the GitHub URL (e.g., 456 in github.com/owner/repo/issues/456). If omitted, adds labels to the item that triggered this workflow.", - "type": "number" - }, - "labels": { - "description": "Label names to add (e.g., ['bug', 'priority-high']). Labels must exist in the repository.", - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - }, - "name": "add_labels" - }, - { - "description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "alternatives": { - "description": "Any workarounds, manual steps, or alternative approaches the user could take (max 256 characters).", - "type": "string" - }, - "reason": { - "description": "Explanation of why this tool is needed or what information you want to share about the limitation (max 256 characters).", - "type": "string" - }, - "tool": { - "description": "Optional: Name or description of the missing tool or capability (max 128 characters). Be specific about what functionality is needed.", - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - }, - "name": "missing_tool" - }, - { - "description": "Log a transparency message when no significant actions are needed. Use this to confirm workflow completion and provide visibility when analysis is complete but no changes or outputs are required (e.g., 'No issues found', 'All checks passed'). This ensures the workflow produces human-visible output even when no other actions are taken.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "message": { - "description": "Status or completion message to log. Should explain what was analyzed and the outcome (e.g., 'Code review complete - no issues found', 'Analysis complete - all tests passing').", - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - }, - "name": "noop" - }, - { - "description": "Report that data or information needed to complete the task is not available. Use this when you cannot accomplish what was requested because required data, context, or information is missing.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "alternatives": { - "description": "Any workarounds, manual steps, or alternative approaches the user could take (max 256 characters).", - "type": "string" - }, - "context": { - "description": "Additional context about the missing data or where it should come from (max 256 characters).", - "type": "string" - }, - "data_type": { - "description": "Type or description of the missing data or information (max 128 characters). Be specific about what data is needed.", - "type": "string" - }, - "reason": { - "description": "Explanation of why this data is needed to complete the task (max 256 characters).", - "type": "string" - } - }, - "required": [], - "type": "object" - }, - "name": "missing_data" - } - ] - GH_AW_SAFE_OUTPUTS_TOOLS_EOF - cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF' - { - "add_comment": { - "defaultMax": 1, - "fields": { - "body": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "item_number": { - "issueOrPRNumber": true - } - } - }, - "add_labels": { - "defaultMax": 5, - "fields": { - "item_number": { - "issueOrPRNumber": true - }, - "labels": { - "required": true, - "type": "array", - "itemType": "string", - "itemSanitize": true, - "itemMaxLength": 128 - } - } - }, - "missing_tool": { - "defaultMax": 20, - "fields": { - "alternatives": { - "type": "string", - "sanitize": true, - "maxLength": 512 - }, - "reason": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 256 - }, - "tool": { - "type": "string", - "sanitize": true, - "maxLength": 128 - } - } - }, - "noop": { - "defaultMax": 1, - "fields": { - "message": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - } - } - } - } - GH_AW_SAFE_OUTPUTS_VALIDATION_EOF - - name: Generate Safe Outputs MCP Server Config - id: safe-outputs-config - run: | - # Generate a secure random API key (360 bits of entropy, 40+ chars) - # Mask immediately to prevent timing vulnerabilities - API_KEY=$(openssl rand -base64 45 | tr -d '/+=') - echo "::add-mask::${API_KEY}" - - PORT=3001 - - # Set outputs for next steps - { - echo "safe_outputs_api_key=${API_KEY}" - echo "safe_outputs_port=${PORT}" - } >> "$GITHUB_OUTPUT" - - echo "Safe Outputs MCP server will run on port ${PORT}" - - - name: Start Safe Outputs MCP HTTP Server - id: safe-outputs-start - env: - DEBUG: '*' - GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }} - GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }} - GH_AW_SAFE_OUTPUTS_TOOLS_PATH: /opt/gh-aw/safeoutputs/tools.json - GH_AW_SAFE_OUTPUTS_CONFIG_PATH: /opt/gh-aw/safeoutputs/config.json - GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs - run: | - # Environment variables are set above to prevent template injection - export DEBUG - export GH_AW_SAFE_OUTPUTS_PORT - export GH_AW_SAFE_OUTPUTS_API_KEY - export GH_AW_SAFE_OUTPUTS_TOOLS_PATH - export GH_AW_SAFE_OUTPUTS_CONFIG_PATH - export GH_AW_MCP_LOG_DIR - - bash /opt/gh-aw/actions/start_safe_outputs_server.sh - - - name: Start MCP Gateway - id: start-mcp-gateway - env: - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }} - GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }} - GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - run: | - set -eo pipefail - mkdir -p /tmp/gh-aw/mcp-config - - # Export gateway environment variables for MCP config and gateway script - export MCP_GATEWAY_PORT="80" - export MCP_GATEWAY_DOMAIN="host.docker.internal" - MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=') - echo "::add-mask::${MCP_GATEWAY_API_KEY}" - export MCP_GATEWAY_API_KEY - export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" - mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" - export DEBUG="*" - - export GH_AW_ENGINE="copilot" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_LOCKDOWN -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.1.4' - - mkdir -p /home/runner/.copilot - cat << GH_AW_MCP_CONFIG_EOF | bash /opt/gh-aw/actions/start_mcp_gateway.sh - { - "mcpServers": { - "github": { - "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v0.30.3", - "env": { - "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}", - "GITHUB_READ_ONLY": "1", - "GITHUB_TOOLSETS": "issues" - } - }, - "safeoutputs": { - "type": "http", - "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT", - "headers": { - "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}" - } - } - }, - "gateway": { - "port": $MCP_GATEWAY_PORT, - "domain": "${MCP_GATEWAY_DOMAIN}", - "apiKey": "${MCP_GATEWAY_API_KEY}", - "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" - } - } - GH_AW_MCP_CONFIG_EOF - - name: Generate workflow overview - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { generateWorkflowOverview } = require('/opt/gh-aw/actions/generate_workflow_overview.cjs'); - await generateWorkflowOverview(core); - - name: Create prompt with built-in context - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GH_AW_GITHUB_ACTOR: ${{ github.actor }} - GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} - GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} - GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} - GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - run: | - bash /opt/gh-aw/actions/create_prompt_first.sh - cat << 'GH_AW_PROMPT_EOF' > "$GH_AW_PROMPT" - - GH_AW_PROMPT_EOF - cat "/opt/gh-aw/prompts/xpia.md" >> "$GH_AW_PROMPT" - cat "/opt/gh-aw/prompts/temp_folder_prompt.md" >> "$GH_AW_PROMPT" - cat "/opt/gh-aw/prompts/markdown.md" >> "$GH_AW_PROMPT" - cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT" - - GitHub API Access Instructions - - The gh CLI is NOT authenticated. Do NOT use gh commands for GitHub operations. - - - To create or modify GitHub resources (issues, discussions, pull requests, etc.), you MUST call the appropriate safe output tool. Simply writing content will NOT work - the workflow requires actual tool calls. - - Temporary IDs: Some safe output tools support a temporary ID field (usually named temporary_id) so you can reference newly-created items elsewhere in the SAME agent output (for example, using #aw_abc1 in a later body). - - **IMPORTANT - temporary_id format rules:** - - If you DON'T need to reference the item later, OMIT the temporary_id field entirely (it will be auto-generated if needed) - - If you DO need cross-references/chaining, you MUST match this EXACT validation regex: /^aw_[A-Za-z0-9]{3,8}$/i - - Format: aw_ prefix followed by 3 to 8 alphanumeric characters (A-Z, a-z, 0-9, case-insensitive) - - Valid alphanumeric characters: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 - - INVALID examples: aw_ab (too short), aw_123456789 (too long), aw_test-id (contains hyphen), aw_id_123 (contains underscore) - - VALID examples: aw_abc, aw_abc1, aw_Test123, aw_A1B2C3D4, aw_12345678 - - To generate valid IDs: use 3-8 random alphanumeric characters or omit the field to let the system auto-generate - - Do NOT invent other aw_* formats — downstream steps will reject them with validation errors matching against /^aw_[A-Za-z0-9]{3,8}$/i. - - Discover available tools from the safeoutputs MCP server. - - **Critical**: Tool calls write structured data that downstream jobs process. Without tool calls, follow-up actions will be skipped. - - **Note**: If you made no other safe output tool calls during this workflow execution, call the "noop" tool to provide a status message indicating completion or that no actions were needed. - - - - The following GitHub context information is available for this workflow: - {{#if __GH_AW_GITHUB_ACTOR__ }} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if __GH_AW_GITHUB_REPOSITORY__ }} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if __GH_AW_GITHUB_WORKSPACE__ }} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ }} - - **issue-number**: #__GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ }} - - **discussion-number**: #__GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ }} - - **pull-request-number**: #__GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_COMMENT_ID__ }} - - **comment-id**: __GH_AW_GITHUB_EVENT_COMMENT_ID__ - {{/if}} - {{#if __GH_AW_GITHUB_RUN_ID__ }} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - - GH_AW_PROMPT_EOF - cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT" - - GH_AW_PROMPT_EOF - cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT" - {{#runtime-import .github/workflows/issue-triage.md}} - GH_AW_PROMPT_EOF - - name: Substitute placeholders - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_GITHUB_ACTOR: ${{ github.actor }} - GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} - GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} - GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} - GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - with: - script: | - const substitutePlaceholders = require('/opt/gh-aw/actions/substitute_placeholders.cjs'); - - // Call the substitution function - return await substitutePlaceholders({ - file: process.env.GH_AW_PROMPT, - substitutions: { - GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, - GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID, - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER, - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: process.env.GH_AW_GITHUB_EVENT_ISSUE_NUMBER, - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER, - GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, - GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, - GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE - } - }); - - name: Interpolate variables and render templates - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/interpolate_prompt.cjs'); - await main(); - - name: Validate prompt placeholders - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - run: bash /opt/gh-aw/actions/validate_prompt_placeholders.sh - - name: Print prompt - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - run: bash /opt/gh-aw/actions/print_prompt_summary.sh - - name: Clean git credentials - run: bash /opt/gh-aw/actions/clean_git_credentials.sh - - name: Execute GitHub Copilot CLI - id: agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 10 - run: | - set -o pipefail - sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.18.0 --skip-pull \ - -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --allow-all-paths --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_COPILOT:+ --model "$GH_AW_MODEL_AGENT_COPILOT"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log - env: - COPILOT_AGENT_RUNNER_TYPE: STANDALONE - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json - GH_AW_MODEL_AGENT_COPILOT: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }} - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GITHUB_HEAD_REF: ${{ github.head_ref }} - GITHUB_REF_NAME: ${{ github.ref_name }} - GITHUB_STEP_SUMMARY: ${{ env.GITHUB_STEP_SUMMARY }} - GITHUB_WORKSPACE: ${{ github.workspace }} - XDG_CONFIG_HOME: /home/runner - - name: Configure Git credentials - env: - REPO_NAME: ${{ github.repository }} - SERVER_URL: ${{ github.server_url }} - run: | - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - # Re-authenticate git with GitHub token - SERVER_URL_STRIPPED="${SERVER_URL#https://}" - git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" - echo "Git configured with standard GitHub Actions identity" - - name: Copy Copilot session state files to logs - if: always() - continue-on-error: true - run: | - # Copy Copilot session state files to logs folder for artifact collection - # This ensures they are in /tmp/gh-aw/ where secret redaction can scan them - SESSION_STATE_DIR="$HOME/.copilot/session-state" - LOGS_DIR="/tmp/gh-aw/sandbox/agent/logs" - - if [ -d "$SESSION_STATE_DIR" ]; then - echo "Copying Copilot session state files from $SESSION_STATE_DIR to $LOGS_DIR" - mkdir -p "$LOGS_DIR" - cp -v "$SESSION_STATE_DIR"/*.jsonl "$LOGS_DIR/" 2>/dev/null || true - echo "Session state files copied successfully" - else - echo "No session-state directory found at $SESSION_STATE_DIR" - fi - - name: Stop MCP Gateway - if: always() - continue-on-error: true - env: - MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }} - MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }} - GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }} - run: | - bash /opt/gh-aw/actions/stop_mcp_gateway.sh "$GATEWAY_PID" - - name: Redact secrets in logs - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/redact_secrets.cjs'); - await main(); - env: - GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN' - SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} - SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Upload Safe Outputs - if: always() - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: safe-output - path: ${{ env.GH_AW_SAFE_OUTPUTS }} - if-no-files-found: warn - - name: Ingest agent output - id: collect_output - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com" - GITHUB_SERVER_URL: ${{ github.server_url }} - GITHUB_API_URL: ${{ github.api_url }} - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/collect_ndjson_output.cjs'); - await main(); - - name: Upload sanitized agent output - if: always() && env.GH_AW_AGENT_OUTPUT - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: agent-output - path: ${{ env.GH_AW_AGENT_OUTPUT }} - if-no-files-found: warn - - name: Upload engine output files - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: agent_outputs - path: | - /tmp/gh-aw/sandbox/agent/logs/ - /tmp/gh-aw/redacted-urls.log - if-no-files-found: ignore - - name: Parse agent logs for step summary - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/ - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/parse_copilot_log.cjs'); - await main(); - - name: Parse MCP Gateway logs for step summary - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/parse_mcp_gateway_log.cjs'); - await main(); - - name: Print firewall logs - if: always() - continue-on-error: true - env: - AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs - run: | - # Fix permissions on firewall logs so they can be uploaded as artifacts - # AWF runs with sudo, creating files owned by root - sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true - # Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step) - if command -v awf &> /dev/null; then - awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" - else - echo 'AWF binary not installed, skipping firewall log summary' - fi - - name: Upload agent artifacts - if: always() - continue-on-error: true - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: agent-artifacts - path: | - /tmp/gh-aw/aw-prompts/prompt.txt - /tmp/gh-aw/aw_info.json - /tmp/gh-aw/mcp-logs/ - /tmp/gh-aw/sandbox/firewall/logs/ - /tmp/gh-aw/agent-stdio.log - /tmp/gh-aw/agent/ - if-no-files-found: ignore - - conclusion: - needs: - - activation - - agent - - detection - - safe_outputs - if: (always()) && (needs.agent.result != 'skipped') - runs-on: ubuntu-slim - permissions: - contents: read - discussions: write - issues: write - pull-requests: write - outputs: - noop_message: ${{ steps.noop.outputs.noop_message }} - tools_reported: ${{ steps.missing_tool.outputs.tools_reported }} - total_count: ${{ steps.missing_tool.outputs.total_count }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Download agent output artifact - continue-on-error: true - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: agent-output - path: /tmp/gh-aw/safeoutputs/ - - name: Setup agent output environment variable - run: | - mkdir -p /tmp/gh-aw/safeoutputs/ - find "/tmp/gh-aw/safeoutputs/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/safeoutputs/agent_output.json" >> "$GITHUB_ENV" - - name: Process No-Op Messages - id: noop - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_NOOP_MAX: 1 - GH_AW_WORKFLOW_NAME: "Agentic Triage" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/issue-triage.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/issue-triage.md" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/noop.cjs'); - await main(); - - name: Record Missing Tool - id: missing_tool - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "Agentic Triage" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/issue-triage.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/issue-triage.md" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/missing_tool.cjs'); - await main(); - - name: Handle Agent Failure - id: handle_agent_failure - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "Agentic Triage" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/issue-triage.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/issue-triage.md" - GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_WORKFLOW_ID: "issue-triage" - GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.agent.outputs.secret_verification_result }} - GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/handle_agent_failure.cjs'); - await main(); - - name: Handle No-Op Message - id: handle_noop_message - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "Agentic Triage" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/issue-triage.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/issue-triage.md" - GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_MESSAGE: ${{ steps.noop.outputs.noop_message }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/handle_noop_message.cjs'); - await main(); - - detection: - needs: agent - if: needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true' - runs-on: ubuntu-latest - permissions: {} - timeout-minutes: 10 - outputs: - success: ${{ steps.parse_results.outputs.success }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Download agent artifacts - continue-on-error: true - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: agent-artifacts - path: /tmp/gh-aw/threat-detection/ - - name: Download agent output artifact - continue-on-error: true - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: agent-output - path: /tmp/gh-aw/threat-detection/ - - name: Echo agent output types - env: - AGENT_OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }} - run: | - echo "Agent output-types: $AGENT_OUTPUT_TYPES" - - name: Setup threat detection - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - WORKFLOW_NAME: "Agentic Triage" - WORKFLOW_DESCRIPTION: "Intelligent issue triage assistant that processes new and reopened issues.\nAnalyzes issue content, selects appropriate labels, detects spam, gathers context\nfrom similar issues, and provides analysis notes including debugging strategies,\nreproduction steps, and resource links. Helps maintainers quickly understand and\nprioritize incoming issues." - HAS_PATCH: ${{ needs.agent.outputs.has_patch }} - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/setup_threat_detection.cjs'); - await main(); - - name: Ensure threat-detection directory and log - run: | - mkdir -p /tmp/gh-aw/threat-detection - touch /tmp/gh-aw/threat-detection/detection.log - - name: Validate COPILOT_GITHUB_TOKEN secret - id: validate-secret - run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default - env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - - name: Install GitHub Copilot CLI - run: /opt/gh-aw/actions/install_copilot_cli.sh 0.0.410 - - name: Execute GitHub Copilot CLI - id: agentic_execution - # Copilot CLI tool arguments (sorted): - # --allow-tool shell(cat) - # --allow-tool shell(grep) - # --allow-tool shell(head) - # --allow-tool shell(jq) - # --allow-tool shell(ls) - # --allow-tool shell(tail) - # --allow-tool shell(wc) - timeout-minutes: 20 - run: | - set -o pipefail - COPILOT_CLI_INSTRUCTION="$(cat /tmp/gh-aw/aw-prompts/prompt.txt)" - mkdir -p /tmp/ - mkdir -p /tmp/gh-aw/ - mkdir -p /tmp/gh-aw/agent/ - mkdir -p /tmp/gh-aw/sandbox/agent/logs/ - copilot --add-dir /tmp/ --add-dir /tmp/gh-aw/ --add-dir /tmp/gh-aw/agent/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-tool 'shell(cat)' --allow-tool 'shell(grep)' --allow-tool 'shell(head)' --allow-tool 'shell(jq)' --allow-tool 'shell(ls)' --allow-tool 'shell(tail)' --allow-tool 'shell(wc)' --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$COPILOT_CLI_INSTRUCTION"${GH_AW_MODEL_DETECTION_COPILOT:+ --model "$GH_AW_MODEL_DETECTION_COPILOT"} 2>&1 | tee /tmp/gh-aw/threat-detection/detection.log - env: - COPILOT_AGENT_RUNNER_TYPE: STANDALONE - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - GH_AW_MODEL_DETECTION_COPILOT: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }} - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GITHUB_HEAD_REF: ${{ github.head_ref }} - GITHUB_REF_NAME: ${{ github.ref_name }} - GITHUB_STEP_SUMMARY: ${{ env.GITHUB_STEP_SUMMARY }} - GITHUB_WORKSPACE: ${{ github.workspace }} - XDG_CONFIG_HOME: /home/runner - - name: Parse threat detection results - id: parse_results - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - - name: Upload threat detection log - if: always() - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: threat-detection.log - path: /tmp/gh-aw/threat-detection/detection.log - if-no-files-found: ignore - - pre_activation: - runs-on: ubuntu-slim - permissions: - discussions: write - issues: write - pull-requests: write - outputs: - activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Add eyes reaction for immediate feedback - id: react - if: github.event_name == 'issues' || github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' || github.event_name == 'discussion_comment' || (github.event_name == 'pull_request') && (github.event.pull_request.head.repo.id == github.repository_id) - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_REACTION: "eyes" - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/add_reaction.cjs'); - await main(); - - name: Check team membership for workflow - id: check_membership - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_REQUIRED_ROLES: admin,maintainer,write - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/check_membership.cjs'); - await main(); - - safe_outputs: - needs: - - agent - - detection - if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (needs.detection.outputs.success == 'true') - runs-on: ubuntu-slim - permissions: - contents: read - discussions: write - issues: write - pull-requests: write - timeout-minutes: 15 - env: - GH_AW_WORKFLOW_ID: "issue-triage" - GH_AW_WORKFLOW_NAME: "Agentic Triage" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/issue-triage.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/issue-triage.md" - outputs: - create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }} - create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} - process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} - process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Download agent output artifact - continue-on-error: true - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: agent-output - path: /tmp/gh-aw/safeoutputs/ - - name: Setup agent output environment variable - run: | - mkdir -p /tmp/gh-aw/safeoutputs/ - find "/tmp/gh-aw/safeoutputs/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/safeoutputs/agent_output.json" >> "$GITHUB_ENV" - - name: Process Safe Outputs - id: process_safe_outputs - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"add_labels\":{\"max\":5},\"missing_data\":{},\"missing_tool\":{}}" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/safe_output_handler_manager.cjs'); - await main(); - diff --git a/.github/workflows/issue-triage.md b/.github/workflows/issue-triage.md deleted file mode 100644 index bd8ea85..0000000 --- a/.github/workflows/issue-triage.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -description: | - Intelligent issue triage assistant that processes new and reopened issues. - Analyzes issue content, selects appropriate labels, detects spam, gathers context - from similar issues, and provides analysis notes including debugging strategies, - reproduction steps, and resource links. Helps maintainers quickly understand and - prioritize incoming issues. - -on: - issues: - types: [opened, reopened] - reaction: eyes - -permissions: read-all - -network: defaults - -safe-outputs: - add-labels: - max: 5 - add-comment: - -tools: - web-fetch: - github: - toolsets: [issues] - # If in a public repo, setting `lockdown: false` allows - # reading issues, pull requests and comments from 3rd-parties - # If in a private repo this has no particular effect. - lockdown: false - -timeout-minutes: 10 -source: githubnext/agentics/workflows/issue-triage.md@eb7950f37d350af6fa09d19827c4883e72947221 ---- - -# Agentic Triage - - - -You're a triage assistant for GitHub issues. Your task is to analyze issue #${{ github.event.issue.number }} and perform some initial triage tasks related to that issue. - -1. Select appropriate labels for the issue from the provided list. - -2. Retrieve the issue content using the `get_issue` tool. If the issue is obviously spam, or generated by bot, or something else that is not an actual issue to be worked on, then add an issue comment to the issue with a one-sentence analysis and exit the workflow. - -3. Next, use the GitHub tools to gather additional context about the issue: - - - Fetch the list of labels available in this repository. Use 'gh label list' bash command to fetch the labels. This will give you the labels you can use for triaging issues. - - Fetch any comments on the issue using the `get_issue_comments` tool - - Find similar issues if needed using the `search_issues` tool - - List the issues to see other open issues in the repository using the `list_issues` tool - -4. Analyze the issue content, considering: - - - The issue title and description - - The type of issue (bug report, feature request, question, etc.) - - Technical areas mentioned - - Severity or priority indicators - - User impact - - Components affected - -5. Write notes, ideas, nudges, resource links, debugging strategies and/or reproduction steps for the team to consider relevant to the issue. - -6. Select appropriate labels from the available labels list provided above: - - - Choose labels that accurately reflect the issue's nature - - Be specific but comprehensive - - Select priority labels if you can determine urgency (high-priority, med-priority, or low-priority) - - Consider platform labels (android, ios) if applicable - - Search for similar issues, and if you find similar issues consider using a "duplicate" label if appropriate. Only do so if the issue is a duplicate of another OPEN issue. - - Only select labels from the provided list above - - It's okay to not add any labels if none are clearly applicable - -7. Apply the selected labels: - - - Use the `update_issue` tool to apply the labels to the issue - - DO NOT communicate directly with users - - If no labels are clearly applicable, do not apply any labels - -8. Add an issue comment to the issue with your analysis: - - Start with "🎯 Agentic Issue Triage" - - Provide a brief summary of the issue - - Mention any relevant details that might help the team understand the issue better - - Include any debugging strategies or reproduction steps if applicable - - Suggest resources or links that might be helpful for resolving the issue or learning skills related to the issue or the particular area of the codebase affected by it - - Mention any nudges or ideas that could help the team in addressing the issue - - If you have possible reproduction steps, include them in the comment - - If you have any debugging strategies, include them in the comment - - If appropriate break the issue down to sub-tasks and write a checklist of things to do. - - Use collapsed-by-default sections in the GitHub markdown to keep the comment tidy. Collapse all sections except the short main summary at the top. diff --git a/.github/workflows/plan.lock.yml b/.github/workflows/plan.lock.yml deleted file mode 100644 index 77e30bd..0000000 --- a/.github/workflows/plan.lock.yml +++ /dev/null @@ -1,1170 +0,0 @@ -# -# ___ _ _ -# / _ \ | | (_) -# | |_| | __ _ ___ _ __ | |_ _ ___ -# | _ |/ _` |/ _ \ '_ \| __| |/ __| -# | | | | (_| | __/ | | | |_| | (__ -# \_| |_/\__, |\___|_| |_|\__|_|\___| -# __/ | -# _ _ |___/ -# | | | | / _| | -# | | | | ___ _ __ _ __| |_| | _____ ____ -# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___| -# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ -# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ -# -# This file was automatically generated by gh-aw (v0.45.0). DO NOT EDIT. -# -# To update this file, edit githubnext/agentics/workflows/plan.md@eb7950f37d350af6fa09d19827c4883e72947221 and run: -# gh aw compile -# Not all edits will cause changes to this file. -# -# For more information: https://github.github.com/gh-aw/introduction/overview/ -# -# Generates project plans and task breakdowns when invoked with /plan command in issues or PRs -# -# Source: githubnext/agentics/workflows/plan.md@eb7950f37d350af6fa09d19827c4883e72947221 -# -# frontmatter-hash: dbdade82987b91f02e7f3e88f81d7403a70a8ff8882e51d118d5b590a575e882 - -name: "Plan Command" -"on": - discussion_comment: - types: - - created - - edited - issue_comment: - types: - - created - - edited - -permissions: {} - -concurrency: - group: "gh-aw-${{ github.workflow }}-${{ github.event.issue.number || github.event.pull_request.number }}" - -run-name: "Plan Command" - -jobs: - activation: - needs: pre_activation - if: > - (needs.pre_activation.outputs.activated == 'true') && ((github.event_name == 'issue_comment') && (((startsWith(github.event.comment.body, '/plan ')) || - (github.event.comment.body == '/plan')) && (github.event.issue.pull_request == null)) || (github.event_name == 'discussion_comment') && - ((startsWith(github.event.comment.body, '/plan ')) || (github.event.comment.body == '/plan'))) - runs-on: ubuntu-slim - permissions: - contents: read - discussions: write - issues: write - pull-requests: write - outputs: - body: ${{ steps.compute-text.outputs.body }} - comment_id: "" - comment_repo: "" - slash_command: ${{ needs.pre_activation.outputs.matched_command }} - text: ${{ steps.compute-text.outputs.text }} - title: ${{ steps.compute-text.outputs.title }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Check workflow file timestamps - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_WORKFLOW_FILE: "plan.lock.yml" - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/check_workflow_timestamp_api.cjs'); - await main(); - - name: Compute current body text - id: compute-text - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/compute_text.cjs'); - await main(); - - agent: - needs: activation - runs-on: ubuntu-latest - permissions: - contents: read - discussions: read - issues: read - pull-requests: read - env: - DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} - GH_AW_ASSETS_ALLOWED_EXTS: "" - GH_AW_ASSETS_BRANCH: "" - GH_AW_ASSETS_MAX_SIZE_KB: 0 - GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs - GH_AW_SAFE_OUTPUTS: /opt/gh-aw/safeoutputs/outputs.jsonl - GH_AW_SAFE_OUTPUTS_CONFIG_PATH: /opt/gh-aw/safeoutputs/config.json - GH_AW_SAFE_OUTPUTS_TOOLS_PATH: /opt/gh-aw/safeoutputs/tools.json - GH_AW_WORKFLOW_ID_SANITIZED: plan - outputs: - checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }} - has_patch: ${{ steps.collect_output.outputs.has_patch }} - model: ${{ steps.generate_aw_info.outputs.model }} - output: ${{ steps.collect_output.outputs.output }} - output_types: ${{ steps.collect_output.outputs.output_types }} - secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - name: Create gh-aw temp directory - run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - - name: Configure Git credentials - env: - REPO_NAME: ${{ github.repository }} - SERVER_URL: ${{ github.server_url }} - run: | - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - # Re-authenticate git with GitHub token - SERVER_URL_STRIPPED="${SERVER_URL#https://}" - git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" - echo "Git configured with standard GitHub Actions identity" - - name: Checkout PR branch - id: checkout-pr - if: | - github.event.pull_request - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - with: - github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/checkout_pr_branch.cjs'); - await main(); - - name: Generate agentic run info - id: generate_aw_info - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const fs = require('fs'); - - const awInfo = { - engine_id: "copilot", - engine_name: "GitHub Copilot CLI", - model: process.env.GH_AW_MODEL_AGENT_COPILOT || "", - version: "", - agent_version: "0.0.410", - cli_version: "v0.45.0", - workflow_name: "Plan Command", - experimental: false, - supports_tools_allowlist: true, - supports_http_transport: true, - run_id: context.runId, - run_number: context.runNumber, - run_attempt: process.env.GITHUB_RUN_ATTEMPT, - repository: context.repo.owner + '/' + context.repo.repo, - ref: context.ref, - sha: context.sha, - actor: context.actor, - event_name: context.eventName, - staged: false, - allowed_domains: ["defaults"], - firewall_enabled: true, - awf_version: "v0.18.0", - awmg_version: "v0.1.4", - steps: { - firewall: "squid" - }, - created_at: new Date().toISOString() - }; - - // Write to /tmp/gh-aw directory to avoid inclusion in PR - const tmpPath = '/tmp/gh-aw/aw_info.json'; - fs.writeFileSync(tmpPath, JSON.stringify(awInfo, null, 2)); - console.log('Generated aw_info.json at:', tmpPath); - console.log(JSON.stringify(awInfo, null, 2)); - - // Set model as output for reuse in other steps/jobs - core.setOutput('model', awInfo.model); - - name: Validate COPILOT_GITHUB_TOKEN secret - id: validate-secret - run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default - env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - - name: Install GitHub Copilot CLI - run: /opt/gh-aw/actions/install_copilot_cli.sh 0.0.410 - - name: Install awf binary - run: bash /opt/gh-aw/actions/install_awf_binary.sh v0.18.0 - - name: Download container images - run: bash /opt/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.18.0 ghcr.io/github/gh-aw-firewall/squid:0.18.0 ghcr.io/github/gh-aw-mcpg:v0.1.4 ghcr.io/github/github-mcp-server:v0.30.3 node:lts-alpine - - name: Write Safe Outputs Config - run: | - mkdir -p /opt/gh-aw/safeoutputs - mkdir -p /tmp/gh-aw/safeoutputs - mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF' - {"close_discussion":{"max":1,"required_category":"Ideas"},"create_issue":{"max":5},"missing_data":{},"missing_tool":{},"noop":{"max":1}} - GH_AW_SAFE_OUTPUTS_CONFIG_EOF - cat > /opt/gh-aw/safeoutputs/tools.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_EOF' - [ - { - "description": "Create a new GitHub issue for tracking bugs, feature requests, or tasks. Use this for actionable work items that need assignment, labeling, and status tracking. For reports, announcements, or status updates that don't require task tracking, use create_discussion instead. CONSTRAINTS: Maximum 5 issue(s) can be created. Title will be prefixed with \"[task] \". Labels [task ai-generated] will be automatically added.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "body": { - "description": "Detailed issue description in Markdown. Do NOT repeat the title as a heading since it already appears as the issue's h1. Include context, reproduction steps, or acceptance criteria as appropriate.", - "type": "string" - }, - "labels": { - "description": "Labels to categorize the issue (e.g., 'bug', 'enhancement'). Labels must exist in the repository.", - "items": { - "type": "string" - }, - "type": "array" - }, - "parent": { - "description": "Parent issue number for creating sub-issues. This is the numeric ID from the GitHub URL (e.g., 42 in github.com/owner/repo/issues/42). Can also be a temporary_id (e.g., 'aw_abc123', 'aw_Test123') from a previously created issue in the same workflow run.", - "type": [ - "number", - "string" - ] - }, - "temporary_id": { - "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.", - "pattern": "^aw_[A-Za-z0-9]{4,8}$", - "type": "string" - }, - "title": { - "description": "Concise issue title summarizing the bug, feature, or task. The title appears as the main heading, so keep it brief and descriptive.", - "type": "string" - } - }, - "required": [ - "title", - "body" - ], - "type": "object" - }, - "name": "create_issue" - }, - { - "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 1 discussion(s) can be closed.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "body": { - "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.", - "type": "string" - }, - "discussion_number": { - "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).", - "type": [ - "number", - "string" - ] - }, - "reason": { - "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).", - "enum": [ - "RESOLVED", - "DUPLICATE", - "OUTDATED", - "ANSWERED" - ], - "type": "string" - } - }, - "required": [ - "body" - ], - "type": "object" - }, - "name": "close_discussion" - }, - { - "description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "alternatives": { - "description": "Any workarounds, manual steps, or alternative approaches the user could take (max 256 characters).", - "type": "string" - }, - "reason": { - "description": "Explanation of why this tool is needed or what information you want to share about the limitation (max 256 characters).", - "type": "string" - }, - "tool": { - "description": "Optional: Name or description of the missing tool or capability (max 128 characters). Be specific about what functionality is needed.", - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - }, - "name": "missing_tool" - }, - { - "description": "Log a transparency message when no significant actions are needed. Use this to confirm workflow completion and provide visibility when analysis is complete but no changes or outputs are required (e.g., 'No issues found', 'All checks passed'). This ensures the workflow produces human-visible output even when no other actions are taken.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "message": { - "description": "Status or completion message to log. Should explain what was analyzed and the outcome (e.g., 'Code review complete - no issues found', 'Analysis complete - all tests passing').", - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - }, - "name": "noop" - }, - { - "description": "Report that data or information needed to complete the task is not available. Use this when you cannot accomplish what was requested because required data, context, or information is missing.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "alternatives": { - "description": "Any workarounds, manual steps, or alternative approaches the user could take (max 256 characters).", - "type": "string" - }, - "context": { - "description": "Additional context about the missing data or where it should come from (max 256 characters).", - "type": "string" - }, - "data_type": { - "description": "Type or description of the missing data or information (max 128 characters). Be specific about what data is needed.", - "type": "string" - }, - "reason": { - "description": "Explanation of why this data is needed to complete the task (max 256 characters).", - "type": "string" - } - }, - "required": [], - "type": "object" - }, - "name": "missing_data" - } - ] - GH_AW_SAFE_OUTPUTS_TOOLS_EOF - cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF' - { - "close_discussion": { - "defaultMax": 1, - "fields": { - "body": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "discussion_number": { - "optionalPositiveInteger": true - }, - "reason": { - "type": "string", - "enum": [ - "RESOLVED", - "DUPLICATE", - "OUTDATED", - "ANSWERED" - ] - } - } - }, - "create_issue": { - "defaultMax": 1, - "fields": { - "body": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "labels": { - "type": "array", - "itemType": "string", - "itemSanitize": true, - "itemMaxLength": 128 - }, - "parent": { - "issueOrPRNumber": true - }, - "repo": { - "type": "string", - "maxLength": 256 - }, - "temporary_id": { - "type": "string" - }, - "title": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 128 - } - } - }, - "missing_tool": { - "defaultMax": 20, - "fields": { - "alternatives": { - "type": "string", - "sanitize": true, - "maxLength": 512 - }, - "reason": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 256 - }, - "tool": { - "type": "string", - "sanitize": true, - "maxLength": 128 - } - } - }, - "noop": { - "defaultMax": 1, - "fields": { - "message": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - } - } - } - } - GH_AW_SAFE_OUTPUTS_VALIDATION_EOF - - name: Generate Safe Outputs MCP Server Config - id: safe-outputs-config - run: | - # Generate a secure random API key (360 bits of entropy, 40+ chars) - # Mask immediately to prevent timing vulnerabilities - API_KEY=$(openssl rand -base64 45 | tr -d '/+=') - echo "::add-mask::${API_KEY}" - - PORT=3001 - - # Set outputs for next steps - { - echo "safe_outputs_api_key=${API_KEY}" - echo "safe_outputs_port=${PORT}" - } >> "$GITHUB_OUTPUT" - - echo "Safe Outputs MCP server will run on port ${PORT}" - - - name: Start Safe Outputs MCP HTTP Server - id: safe-outputs-start - env: - DEBUG: '*' - GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }} - GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }} - GH_AW_SAFE_OUTPUTS_TOOLS_PATH: /opt/gh-aw/safeoutputs/tools.json - GH_AW_SAFE_OUTPUTS_CONFIG_PATH: /opt/gh-aw/safeoutputs/config.json - GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs - run: | - # Environment variables are set above to prevent template injection - export DEBUG - export GH_AW_SAFE_OUTPUTS_PORT - export GH_AW_SAFE_OUTPUTS_API_KEY - export GH_AW_SAFE_OUTPUTS_TOOLS_PATH - export GH_AW_SAFE_OUTPUTS_CONFIG_PATH - export GH_AW_MCP_LOG_DIR - - bash /opt/gh-aw/actions/start_safe_outputs_server.sh - - - name: Start MCP Gateway - id: start-mcp-gateway - env: - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }} - GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }} - GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - run: | - set -eo pipefail - mkdir -p /tmp/gh-aw/mcp-config - - # Export gateway environment variables for MCP config and gateway script - export MCP_GATEWAY_PORT="80" - export MCP_GATEWAY_DOMAIN="host.docker.internal" - MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=') - echo "::add-mask::${MCP_GATEWAY_API_KEY}" - export MCP_GATEWAY_API_KEY - export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" - mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" - export DEBUG="*" - - export GH_AW_ENGINE="copilot" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_LOCKDOWN -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.1.4' - - mkdir -p /home/runner/.copilot - cat << GH_AW_MCP_CONFIG_EOF | bash /opt/gh-aw/actions/start_mcp_gateway.sh - { - "mcpServers": { - "github": { - "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v0.30.3", - "env": { - "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}", - "GITHUB_READ_ONLY": "1", - "GITHUB_TOOLSETS": "context,repos,issues,pull_requests,discussions" - } - }, - "safeoutputs": { - "type": "http", - "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT", - "headers": { - "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}" - } - } - }, - "gateway": { - "port": $MCP_GATEWAY_PORT, - "domain": "${MCP_GATEWAY_DOMAIN}", - "apiKey": "${MCP_GATEWAY_API_KEY}", - "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" - } - } - GH_AW_MCP_CONFIG_EOF - - name: Generate workflow overview - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { generateWorkflowOverview } = require('/opt/gh-aw/actions/generate_workflow_overview.cjs'); - await generateWorkflowOverview(core); - - name: Create prompt with built-in context - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GH_AW_GITHUB_ACTOR: ${{ github.actor }} - GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} - GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} - GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} - GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - GH_AW_IS_PR_COMMENT: ${{ github.event.issue.pull_request && 'true' || '' }} - GH_AW_NEEDS_ACTIVATION_OUTPUTS_TEXT: ${{ needs.activation.outputs.text }} - run: | - bash /opt/gh-aw/actions/create_prompt_first.sh - cat << 'GH_AW_PROMPT_EOF' > "$GH_AW_PROMPT" - - GH_AW_PROMPT_EOF - cat "/opt/gh-aw/prompts/xpia.md" >> "$GH_AW_PROMPT" - cat "/opt/gh-aw/prompts/temp_folder_prompt.md" >> "$GH_AW_PROMPT" - cat "/opt/gh-aw/prompts/markdown.md" >> "$GH_AW_PROMPT" - cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT" - - GitHub API Access Instructions - - The gh CLI is NOT authenticated. Do NOT use gh commands for GitHub operations. - - - To create or modify GitHub resources (issues, discussions, pull requests, etc.), you MUST call the appropriate safe output tool. Simply writing content will NOT work - the workflow requires actual tool calls. - - Temporary IDs: Some safe output tools support a temporary ID field (usually named temporary_id) so you can reference newly-created items elsewhere in the SAME agent output (for example, using #aw_abc1 in a later body). - - **IMPORTANT - temporary_id format rules:** - - If you DON'T need to reference the item later, OMIT the temporary_id field entirely (it will be auto-generated if needed) - - If you DO need cross-references/chaining, you MUST match this EXACT validation regex: /^aw_[A-Za-z0-9]{3,8}$/i - - Format: aw_ prefix followed by 3 to 8 alphanumeric characters (A-Z, a-z, 0-9, case-insensitive) - - Valid alphanumeric characters: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 - - INVALID examples: aw_ab (too short), aw_123456789 (too long), aw_test-id (contains hyphen), aw_id_123 (contains underscore) - - VALID examples: aw_abc, aw_abc1, aw_Test123, aw_A1B2C3D4, aw_12345678 - - To generate valid IDs: use 3-8 random alphanumeric characters or omit the field to let the system auto-generate - - Do NOT invent other aw_* formats — downstream steps will reject them with validation errors matching against /^aw_[A-Za-z0-9]{3,8}$/i. - - Discover available tools from the safeoutputs MCP server. - - **Critical**: Tool calls write structured data that downstream jobs process. Without tool calls, follow-up actions will be skipped. - - **Note**: If you made no other safe output tool calls during this workflow execution, call the "noop" tool to provide a status message indicating completion or that no actions were needed. - - - - The following GitHub context information is available for this workflow: - {{#if __GH_AW_GITHUB_ACTOR__ }} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if __GH_AW_GITHUB_REPOSITORY__ }} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if __GH_AW_GITHUB_WORKSPACE__ }} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ }} - - **issue-number**: #__GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ }} - - **discussion-number**: #__GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ }} - - **pull-request-number**: #__GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_COMMENT_ID__ }} - - **comment-id**: __GH_AW_GITHUB_EVENT_COMMENT_ID__ - {{/if}} - {{#if __GH_AW_GITHUB_RUN_ID__ }} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - - GH_AW_PROMPT_EOF - if [ "$GITHUB_EVENT_NAME" = "issue_comment" ] && [ -n "$GH_AW_IS_PR_COMMENT" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review" ]; then - cat "/opt/gh-aw/prompts/pr_context_prompt.md" >> "$GH_AW_PROMPT" - fi - cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT" - - GH_AW_PROMPT_EOF - cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT" - {{#runtime-import .github/workflows/plan.md}} - GH_AW_PROMPT_EOF - - name: Substitute placeholders - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_GITHUB_ACTOR: ${{ github.actor }} - GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} - GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} - GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} - GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - GH_AW_IS_PR_COMMENT: ${{ github.event.issue.pull_request && 'true' || '' }} - GH_AW_NEEDS_ACTIVATION_OUTPUTS_TEXT: ${{ needs.activation.outputs.text }} - with: - script: | - const substitutePlaceholders = require('/opt/gh-aw/actions/substitute_placeholders.cjs'); - - // Call the substitution function - return await substitutePlaceholders({ - file: process.env.GH_AW_PROMPT, - substitutions: { - GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, - GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID, - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER, - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: process.env.GH_AW_GITHUB_EVENT_ISSUE_NUMBER, - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER, - GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, - GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, - GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, - GH_AW_IS_PR_COMMENT: process.env.GH_AW_IS_PR_COMMENT, - GH_AW_NEEDS_ACTIVATION_OUTPUTS_TEXT: process.env.GH_AW_NEEDS_ACTIVATION_OUTPUTS_TEXT - } - }); - - name: Interpolate variables and render templates - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} - GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} - GH_AW_NEEDS_ACTIVATION_OUTPUTS_TEXT: ${{ needs.activation.outputs.text }} - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/interpolate_prompt.cjs'); - await main(); - - name: Validate prompt placeholders - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - run: bash /opt/gh-aw/actions/validate_prompt_placeholders.sh - - name: Print prompt - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - run: bash /opt/gh-aw/actions/print_prompt_summary.sh - - name: Clean git credentials - run: bash /opt/gh-aw/actions/clean_git_credentials.sh - - name: Execute GitHub Copilot CLI - id: agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 10 - run: | - set -o pipefail - sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.18.0 --skip-pull \ - -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --allow-all-paths --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_COPILOT:+ --model "$GH_AW_MODEL_AGENT_COPILOT"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log - env: - COPILOT_AGENT_RUNNER_TYPE: STANDALONE - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json - GH_AW_MODEL_AGENT_COPILOT: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }} - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GITHUB_HEAD_REF: ${{ github.head_ref }} - GITHUB_REF_NAME: ${{ github.ref_name }} - GITHUB_STEP_SUMMARY: ${{ env.GITHUB_STEP_SUMMARY }} - GITHUB_WORKSPACE: ${{ github.workspace }} - XDG_CONFIG_HOME: /home/runner - - name: Configure Git credentials - env: - REPO_NAME: ${{ github.repository }} - SERVER_URL: ${{ github.server_url }} - run: | - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - # Re-authenticate git with GitHub token - SERVER_URL_STRIPPED="${SERVER_URL#https://}" - git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" - echo "Git configured with standard GitHub Actions identity" - - name: Copy Copilot session state files to logs - if: always() - continue-on-error: true - run: | - # Copy Copilot session state files to logs folder for artifact collection - # This ensures they are in /tmp/gh-aw/ where secret redaction can scan them - SESSION_STATE_DIR="$HOME/.copilot/session-state" - LOGS_DIR="/tmp/gh-aw/sandbox/agent/logs" - - if [ -d "$SESSION_STATE_DIR" ]; then - echo "Copying Copilot session state files from $SESSION_STATE_DIR to $LOGS_DIR" - mkdir -p "$LOGS_DIR" - cp -v "$SESSION_STATE_DIR"/*.jsonl "$LOGS_DIR/" 2>/dev/null || true - echo "Session state files copied successfully" - else - echo "No session-state directory found at $SESSION_STATE_DIR" - fi - - name: Stop MCP Gateway - if: always() - continue-on-error: true - env: - MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }} - MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }} - GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }} - run: | - bash /opt/gh-aw/actions/stop_mcp_gateway.sh "$GATEWAY_PID" - - name: Redact secrets in logs - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/redact_secrets.cjs'); - await main(); - env: - GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN' - SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} - SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Upload Safe Outputs - if: always() - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: safe-output - path: ${{ env.GH_AW_SAFE_OUTPUTS }} - if-no-files-found: warn - - name: Ingest agent output - id: collect_output - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com" - GITHUB_SERVER_URL: ${{ github.server_url }} - GITHUB_API_URL: ${{ github.api_url }} - GH_AW_COMMAND: plan - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/collect_ndjson_output.cjs'); - await main(); - - name: Upload sanitized agent output - if: always() && env.GH_AW_AGENT_OUTPUT - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: agent-output - path: ${{ env.GH_AW_AGENT_OUTPUT }} - if-no-files-found: warn - - name: Upload engine output files - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: agent_outputs - path: | - /tmp/gh-aw/sandbox/agent/logs/ - /tmp/gh-aw/redacted-urls.log - if-no-files-found: ignore - - name: Parse agent logs for step summary - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/ - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/parse_copilot_log.cjs'); - await main(); - - name: Parse MCP Gateway logs for step summary - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/parse_mcp_gateway_log.cjs'); - await main(); - - name: Print firewall logs - if: always() - continue-on-error: true - env: - AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs - run: | - # Fix permissions on firewall logs so they can be uploaded as artifacts - # AWF runs with sudo, creating files owned by root - sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true - # Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step) - if command -v awf &> /dev/null; then - awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" - else - echo 'AWF binary not installed, skipping firewall log summary' - fi - - name: Upload agent artifacts - if: always() - continue-on-error: true - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: agent-artifacts - path: | - /tmp/gh-aw/aw-prompts/prompt.txt - /tmp/gh-aw/aw_info.json - /tmp/gh-aw/mcp-logs/ - /tmp/gh-aw/sandbox/firewall/logs/ - /tmp/gh-aw/agent-stdio.log - /tmp/gh-aw/agent/ - if-no-files-found: ignore - - conclusion: - needs: - - activation - - agent - - detection - - safe_outputs - if: (always()) && (needs.agent.result != 'skipped') - runs-on: ubuntu-slim - permissions: - contents: read - discussions: write - issues: write - outputs: - noop_message: ${{ steps.noop.outputs.noop_message }} - tools_reported: ${{ steps.missing_tool.outputs.tools_reported }} - total_count: ${{ steps.missing_tool.outputs.total_count }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Download agent output artifact - continue-on-error: true - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: agent-output - path: /tmp/gh-aw/safeoutputs/ - - name: Setup agent output environment variable - run: | - mkdir -p /tmp/gh-aw/safeoutputs/ - find "/tmp/gh-aw/safeoutputs/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/safeoutputs/agent_output.json" >> "$GITHUB_ENV" - - name: Process No-Op Messages - id: noop - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_NOOP_MAX: 1 - GH_AW_WORKFLOW_NAME: "Plan Command" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/plan.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/plan.md" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/noop.cjs'); - await main(); - - name: Record Missing Tool - id: missing_tool - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "Plan Command" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/plan.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/plan.md" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/missing_tool.cjs'); - await main(); - - name: Handle Agent Failure - id: handle_agent_failure - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "Plan Command" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/plan.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/plan.md" - GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_WORKFLOW_ID: "plan" - GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.agent.outputs.secret_verification_result }} - GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/handle_agent_failure.cjs'); - await main(); - - name: Handle No-Op Message - id: handle_noop_message - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "Plan Command" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/plan.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/plan.md" - GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_MESSAGE: ${{ steps.noop.outputs.noop_message }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/handle_noop_message.cjs'); - await main(); - - detection: - needs: agent - if: needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true' - runs-on: ubuntu-latest - permissions: {} - timeout-minutes: 10 - outputs: - success: ${{ steps.parse_results.outputs.success }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Download agent artifacts - continue-on-error: true - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: agent-artifacts - path: /tmp/gh-aw/threat-detection/ - - name: Download agent output artifact - continue-on-error: true - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: agent-output - path: /tmp/gh-aw/threat-detection/ - - name: Echo agent output types - env: - AGENT_OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }} - run: | - echo "Agent output-types: $AGENT_OUTPUT_TYPES" - - name: Setup threat detection - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - WORKFLOW_NAME: "Plan Command" - WORKFLOW_DESCRIPTION: "Generates project plans and task breakdowns when invoked with /plan command in issues or PRs" - HAS_PATCH: ${{ needs.agent.outputs.has_patch }} - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/setup_threat_detection.cjs'); - await main(); - - name: Ensure threat-detection directory and log - run: | - mkdir -p /tmp/gh-aw/threat-detection - touch /tmp/gh-aw/threat-detection/detection.log - - name: Validate COPILOT_GITHUB_TOKEN secret - id: validate-secret - run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default - env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - - name: Install GitHub Copilot CLI - run: /opt/gh-aw/actions/install_copilot_cli.sh 0.0.410 - - name: Execute GitHub Copilot CLI - id: agentic_execution - # Copilot CLI tool arguments (sorted): - # --allow-tool shell(cat) - # --allow-tool shell(grep) - # --allow-tool shell(head) - # --allow-tool shell(jq) - # --allow-tool shell(ls) - # --allow-tool shell(tail) - # --allow-tool shell(wc) - timeout-minutes: 20 - run: | - set -o pipefail - COPILOT_CLI_INSTRUCTION="$(cat /tmp/gh-aw/aw-prompts/prompt.txt)" - mkdir -p /tmp/ - mkdir -p /tmp/gh-aw/ - mkdir -p /tmp/gh-aw/agent/ - mkdir -p /tmp/gh-aw/sandbox/agent/logs/ - copilot --add-dir /tmp/ --add-dir /tmp/gh-aw/ --add-dir /tmp/gh-aw/agent/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-tool 'shell(cat)' --allow-tool 'shell(grep)' --allow-tool 'shell(head)' --allow-tool 'shell(jq)' --allow-tool 'shell(ls)' --allow-tool 'shell(tail)' --allow-tool 'shell(wc)' --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$COPILOT_CLI_INSTRUCTION"${GH_AW_MODEL_DETECTION_COPILOT:+ --model "$GH_AW_MODEL_DETECTION_COPILOT"} 2>&1 | tee /tmp/gh-aw/threat-detection/detection.log - env: - COPILOT_AGENT_RUNNER_TYPE: STANDALONE - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - GH_AW_MODEL_DETECTION_COPILOT: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }} - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GITHUB_HEAD_REF: ${{ github.head_ref }} - GITHUB_REF_NAME: ${{ github.ref_name }} - GITHUB_STEP_SUMMARY: ${{ env.GITHUB_STEP_SUMMARY }} - GITHUB_WORKSPACE: ${{ github.workspace }} - XDG_CONFIG_HOME: /home/runner - - name: Parse threat detection results - id: parse_results - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - - name: Upload threat detection log - if: always() - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: threat-detection.log - path: /tmp/gh-aw/threat-detection/detection.log - if-no-files-found: ignore - - pre_activation: - if: > - (github.event_name == 'issue_comment') && (((startsWith(github.event.comment.body, '/plan ')) || (github.event.comment.body == '/plan')) && - (github.event.issue.pull_request == null)) || (github.event_name == 'discussion_comment') && ((startsWith(github.event.comment.body, '/plan ')) || - (github.event.comment.body == '/plan')) - runs-on: ubuntu-slim - permissions: - discussions: write - issues: write - pull-requests: write - outputs: - activated: ${{ (steps.check_membership.outputs.is_team_member == 'true') && (steps.check_command_position.outputs.command_position_ok == 'true') }} - matched_command: ${{ steps.check_command_position.outputs.matched_command }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Add eyes reaction for immediate feedback - id: react - if: github.event_name == 'issues' || github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' || github.event_name == 'discussion_comment' || (github.event_name == 'pull_request') && (github.event.pull_request.head.repo.id == github.repository_id) - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_REACTION: "eyes" - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/add_reaction.cjs'); - await main(); - - name: Check team membership for command workflow - id: check_membership - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_REQUIRED_ROLES: admin,maintainer,write - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/check_membership.cjs'); - await main(); - - name: Check command position - id: check_command_position - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_COMMANDS: "[\"plan\"]" - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/check_command_position.cjs'); - await main(); - - safe_outputs: - needs: - - agent - - detection - if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (needs.detection.outputs.success == 'true') - runs-on: ubuntu-slim - permissions: - contents: read - discussions: write - issues: write - timeout-minutes: 15 - env: - GH_AW_ENGINE_ID: "copilot" - GH_AW_WORKFLOW_ID: "plan" - GH_AW_WORKFLOW_NAME: "Plan Command" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/plan.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/plan.md" - outputs: - create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }} - create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} - process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} - process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Download agent output artifact - continue-on-error: true - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: agent-output - path: /tmp/gh-aw/safeoutputs/ - - name: Setup agent output environment variable - run: | - mkdir -p /tmp/gh-aw/safeoutputs/ - find "/tmp/gh-aw/safeoutputs/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/safeoutputs/agent_output.json" >> "$GITHUB_ENV" - - name: Process Safe Outputs - id: process_safe_outputs - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":1},\"create_issue\":{\"labels\":[\"task\",\"ai-generated\"],\"max\":5,\"title_prefix\":\"[task] \"},\"missing_data\":{},\"missing_tool\":{}}" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/safe_output_handler_manager.cjs'); - await main(); - diff --git a/.github/workflows/plan.md b/.github/workflows/plan.md deleted file mode 100644 index 6cc24cd..0000000 --- a/.github/workflows/plan.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -name: Plan Command -description: Generates project plans and task breakdowns when invoked with /plan command in issues or PRs - -on: - slash_command: - name: plan - events: [issue_comment, discussion_comment] - -permissions: - contents: read - discussions: read - issues: read - pull-requests: read - -engine: copilot - -tools: - github: - toolsets: [default, discussions] - # If in a public repo, setting `lockdown: false` allows - # reading issues, pull requests and comments from 3rd-parties - # If in a private repo this has no particular effect. - # - # This allows the maintainer to use /plan in discussions and issues created - # by 3rd parties, and to read the content of those discussions and issues - # turning the content into actionable tasks. - lockdown: false - -safe-outputs: - create-issue: - title-prefix: "[task] " - labels: [task, ai-generated] - max: 5 - close-discussion: - required-category: "Ideas" -timeout-minutes: 10 -source: githubnext/agentics/workflows/plan.md@eb7950f37d350af6fa09d19827c4883e72947221 ---- - -# Planning Assistant - -You are an expert planning assistant for GitHub Copilot agents. Your task is to analyze an issue or discussion and break it down into a sequence of actionable work items that can be assigned to GitHub Copilot agents. - -## Current Context - -- **Repository**: ${{ github.repository }} -- **Issue Number**: ${{ github.event.issue.number }} -- **Discussion Number**: ${{ github.event.discussion.number }} -- **Content**: - - -${{ needs.activation.outputs.text }} - - -## Your Mission - -Analyze the issue or discussion and its comments, then create a sequence of clear, actionable sub-issues (at most 5) that break down the work into manageable tasks for GitHub Copilot agents. - -## Guidelines for Creating Sub-Issues - -### 1. Clarity and Specificity -Each sub-issue should: -- Have a clear, specific objective that can be completed independently -- Use concrete language that a SWE agent can understand and execute -- Include specific files, functions, or components when relevant -- Avoid ambiguity and vague requirements - -### 2. Proper Sequencing -Order the tasks logically: -- Start with foundational work (setup, infrastructure, dependencies) -- Follow with implementation tasks -- End with validation and documentation -- Consider dependencies between tasks - -### 3. Right Level of Granularity -Each task should: -- Be completable in a single PR -- Not be too large (avoid epic-sized tasks) -- With a single focus or goal. Keep them extremely small and focused even if it means more tasks. -- Have clear acceptance criteria - -### 4. SWE Agent Formulation -Write tasks as if instructing a software engineer: -- Use imperative language: "Implement X", "Add Y", "Update Z" -- Provide context: "In file X, add function Y to handle Z" -- Include relevant technical details -- Specify expected outcomes - -## Task Breakdown Process - -1. **Analyze the Content**: Read the issue or discussion title, description, and comments carefully -2. **Identify Scope**: Determine the overall scope and complexity -3. **Break Down Work**: Identify 3-5 logical work items -4. **Formulate Tasks**: Write clear, actionable descriptions for each task -5. **Create Sub-Issues**: Use safe-outputs to create the sub-issues - -## Output Format - -For each sub-issue you create: -- **Title**: Brief, descriptive title (e.g., "Implement authentication middleware") -- **Body**: Clear description with: - - Objective: What needs to be done - - Context: Why this is needed - - Approach: Suggested implementation approach (if applicable) - - Files: Specific files to modify or create - - Acceptance Criteria: How to verify completion - -## Example Sub-Issue - -**Title**: Add user authentication middleware - -**Body**: -``` -## Objective -Implement JWT-based authentication middleware for API routes. - -## Context -This is needed to secure API endpoints before implementing user-specific features. Part of issue or discussion #123. - -## Approach -1. Create middleware function in `src/middleware/auth.js` -2. Add JWT verification using the existing auth library -3. Attach user info to request object -4. Handle token expiration and invalid tokens - -## Files to Modify -- Create: `src/middleware/auth.js` -- Update: `src/routes/api.js` (to use the middleware) -- Update: `tests/middleware/auth.test.js` (add tests) - -## Acceptance Criteria -- [ ] Middleware validates JWT tokens -- [ ] Invalid tokens return 401 status -- [ ] User info is accessible in route handlers -- [ ] Tests cover success and error cases -``` - -## Important Notes - -- **Maximum 5 sub-issues**: Don't create more than 5 sub-issues (as configured in safe-outputs) -- **Parent Reference**: You must specify the current issue (#${{ github.event.issue.number }}) or discussion (#${{ github.event.discussion.number }}) as the parent when creating sub-issues. The system will automatically link them with "Related to #N" in the issue body. -- **Clear Steps**: Each sub-issue should have clear, actionable steps -- **No Duplication**: Don't create sub-issues for work that's already done -- **Prioritize Clarity**: SWE agents need unambiguous instructions - -## Instructions - -Review instructions in `.github/instructions/*.instructions.md` if you need guidance. - -## Begin Planning - -Analyze the issue or discussion and create the sub-issues now. Remember to use the safe-outputs mechanism to create each issue. Each sub-issue you create will be automatically linked to the parent (issue #${{ github.event.issue.number }} or discussion #${{ github.event.discussion.number }}). - -After creating all the sub-issues successfully, if this was triggered from a discussion in the "Ideas" category, close the discussion with a comment summarizing the plan and resolution reason "RESOLVED". diff --git a/.github/workflows/update-docs.lock.yml b/.github/workflows/update-docs.lock.yml deleted file mode 100644 index 9d6be41..0000000 --- a/.github/workflows/update-docs.lock.yml +++ /dev/null @@ -1,1091 +0,0 @@ -# -# ___ _ _ -# / _ \ | | (_) -# | |_| | __ _ ___ _ __ | |_ _ ___ -# | _ |/ _` |/ _ \ '_ \| __| |/ __| -# | | | | (_| | __/ | | | |_| | (__ -# \_| |_/\__, |\___|_| |_|\__|_|\___| -# __/ | -# _ _ |___/ -# | | | | / _| | -# | | | | ___ _ __ _ __| |_| | _____ ____ -# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___| -# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ -# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ -# -# This file was automatically generated by gh-aw (v0.45.0). DO NOT EDIT. -# -# To update this file, edit githubnext/agentics/workflows/update-docs.md@eb7950f37d350af6fa09d19827c4883e72947221 and run: -# gh aw compile -# Not all edits will cause changes to this file. -# -# For more information: https://github.github.com/gh-aw/introduction/overview/ -# -# This workflow keeps docs synchronized with code changes. -# Triggered on every push to main, it analyzes diffs to identify changed entities and -# updates corresponding documentation. Maintains consistent style (precise, active voice, -# plain English), ensures single source of truth, and creates draft PRs with documentation -# updates. Supports documentation-as-code philosophy. -# -# Source: githubnext/agentics/workflows/update-docs.md@eb7950f37d350af6fa09d19827c4883e72947221 -# -# frontmatter-hash: 304dbbcfd8e4a85bff10b8ee2e884ff7029229a677fe5d8d893a8cf320cda0f7 - -name: "Update Docs" -"on": - push: - branches: - - main - workflow_dispatch: - -permissions: {} - -concurrency: - group: "gh-aw-${{ github.workflow }}-${{ github.ref }}" - -run-name: "Update Docs" - -jobs: - activation: - needs: pre_activation - if: needs.pre_activation.outputs.activated == 'true' - runs-on: ubuntu-slim - permissions: - contents: read - outputs: - comment_id: "" - comment_repo: "" - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Check workflow file timestamps - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_WORKFLOW_FILE: "update-docs.lock.yml" - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/check_workflow_timestamp_api.cjs'); - await main(); - - agent: - needs: activation - runs-on: ubuntu-latest - permissions: read-all - env: - DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} - GH_AW_ASSETS_ALLOWED_EXTS: "" - GH_AW_ASSETS_BRANCH: "" - GH_AW_ASSETS_MAX_SIZE_KB: 0 - GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs - GH_AW_SAFE_OUTPUTS: /opt/gh-aw/safeoutputs/outputs.jsonl - GH_AW_SAFE_OUTPUTS_CONFIG_PATH: /opt/gh-aw/safeoutputs/config.json - GH_AW_SAFE_OUTPUTS_TOOLS_PATH: /opt/gh-aw/safeoutputs/tools.json - GH_AW_WORKFLOW_ID_SANITIZED: updatedocs - outputs: - checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }} - has_patch: ${{ steps.collect_output.outputs.has_patch }} - model: ${{ steps.generate_aw_info.outputs.model }} - output: ${{ steps.collect_output.outputs.output }} - output_types: ${{ steps.collect_output.outputs.output_types }} - secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - name: Create gh-aw temp directory - run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - - name: Configure Git credentials - env: - REPO_NAME: ${{ github.repository }} - SERVER_URL: ${{ github.server_url }} - run: | - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - # Re-authenticate git with GitHub token - SERVER_URL_STRIPPED="${SERVER_URL#https://}" - git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" - echo "Git configured with standard GitHub Actions identity" - - name: Checkout PR branch - id: checkout-pr - if: | - github.event.pull_request - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - with: - github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/checkout_pr_branch.cjs'); - await main(); - - name: Generate agentic run info - id: generate_aw_info - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const fs = require('fs'); - - const awInfo = { - engine_id: "copilot", - engine_name: "GitHub Copilot CLI", - model: process.env.GH_AW_MODEL_AGENT_COPILOT || "", - version: "", - agent_version: "0.0.410", - cli_version: "v0.45.0", - workflow_name: "Update Docs", - experimental: false, - supports_tools_allowlist: true, - supports_http_transport: true, - run_id: context.runId, - run_number: context.runNumber, - run_attempt: process.env.GITHUB_RUN_ATTEMPT, - repository: context.repo.owner + '/' + context.repo.repo, - ref: context.ref, - sha: context.sha, - actor: context.actor, - event_name: context.eventName, - staged: false, - allowed_domains: ["defaults"], - firewall_enabled: true, - awf_version: "v0.18.0", - awmg_version: "v0.1.4", - steps: { - firewall: "squid" - }, - created_at: new Date().toISOString() - }; - - // Write to /tmp/gh-aw directory to avoid inclusion in PR - const tmpPath = '/tmp/gh-aw/aw_info.json'; - fs.writeFileSync(tmpPath, JSON.stringify(awInfo, null, 2)); - console.log('Generated aw_info.json at:', tmpPath); - console.log(JSON.stringify(awInfo, null, 2)); - - // Set model as output for reuse in other steps/jobs - core.setOutput('model', awInfo.model); - - name: Validate COPILOT_GITHUB_TOKEN secret - id: validate-secret - run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default - env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - - name: Install GitHub Copilot CLI - run: /opt/gh-aw/actions/install_copilot_cli.sh 0.0.410 - - name: Install awf binary - run: bash /opt/gh-aw/actions/install_awf_binary.sh v0.18.0 - - name: Determine automatic lockdown mode for GitHub MCP Server - id: determine-automatic-lockdown - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} - GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - with: - script: | - const determineAutomaticLockdown = require('/opt/gh-aw/actions/determine_automatic_lockdown.cjs'); - await determineAutomaticLockdown(github, context, core); - - name: Download container images - run: bash /opt/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.18.0 ghcr.io/github/gh-aw-firewall/squid:0.18.0 ghcr.io/github/gh-aw-mcpg:v0.1.4 ghcr.io/github/github-mcp-server:v0.30.3 node:lts-alpine - - name: Write Safe Outputs Config - run: | - mkdir -p /opt/gh-aw/safeoutputs - mkdir -p /tmp/gh-aw/safeoutputs - mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF' - {"create_pull_request":{},"missing_data":{},"missing_tool":{},"noop":{"max":1}} - GH_AW_SAFE_OUTPUTS_CONFIG_EOF - cat > /opt/gh-aw/safeoutputs/tools.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_EOF' - [ - { - "description": "Create a new GitHub pull request to propose code changes. Use this after making file edits to submit them for review and merging. The PR will be created from the current branch with your committed changes. For code review comments on an existing PR, use create_pull_request_review_comment instead. CONSTRAINTS: Maximum 1 pull request(s) can be created. Labels [automation documentation] will be automatically added. PRs will be created as drafts.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "body": { - "description": "Detailed PR description in Markdown. Include what changes were made, why, testing notes, and any breaking changes. Do NOT repeat the title as a heading.", - "type": "string" - }, - "branch": { - "description": "Source branch name containing the changes. If omitted, uses the current working branch.", - "type": "string" - }, - "labels": { - "description": "Labels to categorize the PR (e.g., 'enhancement', 'bugfix'). Labels must exist in the repository.", - "items": { - "type": "string" - }, - "type": "array" - }, - "title": { - "description": "Concise PR title describing the changes. Follow repository conventions (e.g., conventional commits). The title appears as the main heading.", - "type": "string" - } - }, - "required": [ - "title", - "body" - ], - "type": "object" - }, - "name": "create_pull_request" - }, - { - "description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "alternatives": { - "description": "Any workarounds, manual steps, or alternative approaches the user could take (max 256 characters).", - "type": "string" - }, - "reason": { - "description": "Explanation of why this tool is needed or what information you want to share about the limitation (max 256 characters).", - "type": "string" - }, - "tool": { - "description": "Optional: Name or description of the missing tool or capability (max 128 characters). Be specific about what functionality is needed.", - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - }, - "name": "missing_tool" - }, - { - "description": "Log a transparency message when no significant actions are needed. Use this to confirm workflow completion and provide visibility when analysis is complete but no changes or outputs are required (e.g., 'No issues found', 'All checks passed'). This ensures the workflow produces human-visible output even when no other actions are taken.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "message": { - "description": "Status or completion message to log. Should explain what was analyzed and the outcome (e.g., 'Code review complete - no issues found', 'Analysis complete - all tests passing').", - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - }, - "name": "noop" - }, - { - "description": "Report that data or information needed to complete the task is not available. Use this when you cannot accomplish what was requested because required data, context, or information is missing.", - "inputSchema": { - "additionalProperties": false, - "properties": { - "alternatives": { - "description": "Any workarounds, manual steps, or alternative approaches the user could take (max 256 characters).", - "type": "string" - }, - "context": { - "description": "Additional context about the missing data or where it should come from (max 256 characters).", - "type": "string" - }, - "data_type": { - "description": "Type or description of the missing data or information (max 128 characters). Be specific about what data is needed.", - "type": "string" - }, - "reason": { - "description": "Explanation of why this data is needed to complete the task (max 256 characters).", - "type": "string" - } - }, - "required": [], - "type": "object" - }, - "name": "missing_data" - } - ] - GH_AW_SAFE_OUTPUTS_TOOLS_EOF - cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF' - { - "create_pull_request": { - "defaultMax": 1, - "fields": { - "body": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "branch": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 256 - }, - "labels": { - "type": "array", - "itemType": "string", - "itemSanitize": true, - "itemMaxLength": 128 - }, - "title": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 128 - } - } - }, - "missing_tool": { - "defaultMax": 20, - "fields": { - "alternatives": { - "type": "string", - "sanitize": true, - "maxLength": 512 - }, - "reason": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 256 - }, - "tool": { - "type": "string", - "sanitize": true, - "maxLength": 128 - } - } - }, - "noop": { - "defaultMax": 1, - "fields": { - "message": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - } - } - } - } - GH_AW_SAFE_OUTPUTS_VALIDATION_EOF - - name: Generate Safe Outputs MCP Server Config - id: safe-outputs-config - run: | - # Generate a secure random API key (360 bits of entropy, 40+ chars) - # Mask immediately to prevent timing vulnerabilities - API_KEY=$(openssl rand -base64 45 | tr -d '/+=') - echo "::add-mask::${API_KEY}" - - PORT=3001 - - # Set outputs for next steps - { - echo "safe_outputs_api_key=${API_KEY}" - echo "safe_outputs_port=${PORT}" - } >> "$GITHUB_OUTPUT" - - echo "Safe Outputs MCP server will run on port ${PORT}" - - - name: Start Safe Outputs MCP HTTP Server - id: safe-outputs-start - env: - DEBUG: '*' - GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }} - GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }} - GH_AW_SAFE_OUTPUTS_TOOLS_PATH: /opt/gh-aw/safeoutputs/tools.json - GH_AW_SAFE_OUTPUTS_CONFIG_PATH: /opt/gh-aw/safeoutputs/config.json - GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs - run: | - # Environment variables are set above to prevent template injection - export DEBUG - export GH_AW_SAFE_OUTPUTS_PORT - export GH_AW_SAFE_OUTPUTS_API_KEY - export GH_AW_SAFE_OUTPUTS_TOOLS_PATH - export GH_AW_SAFE_OUTPUTS_CONFIG_PATH - export GH_AW_MCP_LOG_DIR - - bash /opt/gh-aw/actions/start_safe_outputs_server.sh - - - name: Start MCP Gateway - id: start-mcp-gateway - env: - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }} - GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }} - GITHUB_MCP_LOCKDOWN: ${{ steps.determine-automatic-lockdown.outputs.lockdown == 'true' && '1' || '0' }} - GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - run: | - set -eo pipefail - mkdir -p /tmp/gh-aw/mcp-config - - # Export gateway environment variables for MCP config and gateway script - export MCP_GATEWAY_PORT="80" - export MCP_GATEWAY_DOMAIN="host.docker.internal" - MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=') - echo "::add-mask::${MCP_GATEWAY_API_KEY}" - export MCP_GATEWAY_API_KEY - export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" - mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" - export DEBUG="*" - - export GH_AW_ENGINE="copilot" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_LOCKDOWN -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.1.4' - - mkdir -p /home/runner/.copilot - cat << GH_AW_MCP_CONFIG_EOF | bash /opt/gh-aw/actions/start_mcp_gateway.sh - { - "mcpServers": { - "github": { - "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v0.30.3", - "env": { - "GITHUB_LOCKDOWN_MODE": "$GITHUB_MCP_LOCKDOWN", - "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}", - "GITHUB_READ_ONLY": "1", - "GITHUB_TOOLSETS": "all" - } - }, - "safeoutputs": { - "type": "http", - "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT", - "headers": { - "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}" - } - } - }, - "gateway": { - "port": $MCP_GATEWAY_PORT, - "domain": "${MCP_GATEWAY_DOMAIN}", - "apiKey": "${MCP_GATEWAY_API_KEY}", - "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" - } - } - GH_AW_MCP_CONFIG_EOF - - name: Generate workflow overview - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { generateWorkflowOverview } = require('/opt/gh-aw/actions/generate_workflow_overview.cjs'); - await generateWorkflowOverview(core); - - name: Create prompt with built-in context - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GH_AW_GITHUB_ACTOR: ${{ github.actor }} - GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} - GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} - GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} - GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} - GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - run: | - bash /opt/gh-aw/actions/create_prompt_first.sh - cat << 'GH_AW_PROMPT_EOF' > "$GH_AW_PROMPT" - - GH_AW_PROMPT_EOF - cat "/opt/gh-aw/prompts/xpia.md" >> "$GH_AW_PROMPT" - cat "/opt/gh-aw/prompts/temp_folder_prompt.md" >> "$GH_AW_PROMPT" - cat "/opt/gh-aw/prompts/markdown.md" >> "$GH_AW_PROMPT" - cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT" - - GitHub API Access Instructions - - The gh CLI is NOT authenticated. Do NOT use gh commands for GitHub operations. - - - To create or modify GitHub resources (issues, discussions, pull requests, etc.), you MUST call the appropriate safe output tool. Simply writing content will NOT work - the workflow requires actual tool calls. - - Temporary IDs: Some safe output tools support a temporary ID field (usually named temporary_id) so you can reference newly-created items elsewhere in the SAME agent output (for example, using #aw_abc1 in a later body). - - **IMPORTANT - temporary_id format rules:** - - If you DON'T need to reference the item later, OMIT the temporary_id field entirely (it will be auto-generated if needed) - - If you DO need cross-references/chaining, you MUST match this EXACT validation regex: /^aw_[A-Za-z0-9]{3,8}$/i - - Format: aw_ prefix followed by 3 to 8 alphanumeric characters (A-Z, a-z, 0-9, case-insensitive) - - Valid alphanumeric characters: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 - - INVALID examples: aw_ab (too short), aw_123456789 (too long), aw_test-id (contains hyphen), aw_id_123 (contains underscore) - - VALID examples: aw_abc, aw_abc1, aw_Test123, aw_A1B2C3D4, aw_12345678 - - To generate valid IDs: use 3-8 random alphanumeric characters or omit the field to let the system auto-generate - - Do NOT invent other aw_* formats — downstream steps will reject them with validation errors matching against /^aw_[A-Za-z0-9]{3,8}$/i. - - Discover available tools from the safeoutputs MCP server. - - **Critical**: Tool calls write structured data that downstream jobs process. Without tool calls, follow-up actions will be skipped. - - **Note**: If you made no other safe output tool calls during this workflow execution, call the "noop" tool to provide a status message indicating completion or that no actions were needed. - - - - The following GitHub context information is available for this workflow: - {{#if __GH_AW_GITHUB_ACTOR__ }} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if __GH_AW_GITHUB_REPOSITORY__ }} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if __GH_AW_GITHUB_WORKSPACE__ }} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ }} - - **issue-number**: #__GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ }} - - **discussion-number**: #__GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ }} - - **pull-request-number**: #__GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_COMMENT_ID__ }} - - **comment-id**: __GH_AW_GITHUB_EVENT_COMMENT_ID__ - {{/if}} - {{#if __GH_AW_GITHUB_RUN_ID__ }} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - - GH_AW_PROMPT_EOF - cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT" - - GH_AW_PROMPT_EOF - cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT" - {{#runtime-import .github/workflows/update-docs.md}} - GH_AW_PROMPT_EOF - - name: Substitute placeholders - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_GITHUB_ACTOR: ${{ github.actor }} - GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} - GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} - GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} - GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} - GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - with: - script: | - const substitutePlaceholders = require('/opt/gh-aw/actions/substitute_placeholders.cjs'); - - // Call the substitution function - return await substitutePlaceholders({ - file: process.env.GH_AW_PROMPT, - substitutions: { - GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, - GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID, - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER, - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: process.env.GH_AW_GITHUB_EVENT_ISSUE_NUMBER, - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER, - GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, - GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, - GH_AW_GITHUB_WORKFLOW: process.env.GH_AW_GITHUB_WORKFLOW, - GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE - } - }); - - name: Interpolate variables and render templates - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} - GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/interpolate_prompt.cjs'); - await main(); - - name: Validate prompt placeholders - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - run: bash /opt/gh-aw/actions/validate_prompt_placeholders.sh - - name: Print prompt - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - run: bash /opt/gh-aw/actions/print_prompt_summary.sh - - name: Clean git credentials - run: bash /opt/gh-aw/actions/clean_git_credentials.sh - - name: Execute GitHub Copilot CLI - id: agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 15 - run: | - set -o pipefail - sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.18.0 --skip-pull \ - -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --allow-all-paths --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_COPILOT:+ --model "$GH_AW_MODEL_AGENT_COPILOT"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log - env: - COPILOT_AGENT_RUNNER_TYPE: STANDALONE - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json - GH_AW_MODEL_AGENT_COPILOT: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }} - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GITHUB_HEAD_REF: ${{ github.head_ref }} - GITHUB_REF_NAME: ${{ github.ref_name }} - GITHUB_STEP_SUMMARY: ${{ env.GITHUB_STEP_SUMMARY }} - GITHUB_WORKSPACE: ${{ github.workspace }} - XDG_CONFIG_HOME: /home/runner - - name: Configure Git credentials - env: - REPO_NAME: ${{ github.repository }} - SERVER_URL: ${{ github.server_url }} - run: | - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - # Re-authenticate git with GitHub token - SERVER_URL_STRIPPED="${SERVER_URL#https://}" - git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" - echo "Git configured with standard GitHub Actions identity" - - name: Copy Copilot session state files to logs - if: always() - continue-on-error: true - run: | - # Copy Copilot session state files to logs folder for artifact collection - # This ensures they are in /tmp/gh-aw/ where secret redaction can scan them - SESSION_STATE_DIR="$HOME/.copilot/session-state" - LOGS_DIR="/tmp/gh-aw/sandbox/agent/logs" - - if [ -d "$SESSION_STATE_DIR" ]; then - echo "Copying Copilot session state files from $SESSION_STATE_DIR to $LOGS_DIR" - mkdir -p "$LOGS_DIR" - cp -v "$SESSION_STATE_DIR"/*.jsonl "$LOGS_DIR/" 2>/dev/null || true - echo "Session state files copied successfully" - else - echo "No session-state directory found at $SESSION_STATE_DIR" - fi - - name: Stop MCP Gateway - if: always() - continue-on-error: true - env: - MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }} - MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }} - GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }} - run: | - bash /opt/gh-aw/actions/stop_mcp_gateway.sh "$GATEWAY_PID" - - name: Redact secrets in logs - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/redact_secrets.cjs'); - await main(); - env: - GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN' - SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} - SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Upload Safe Outputs - if: always() - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: safe-output - path: ${{ env.GH_AW_SAFE_OUTPUTS }} - if-no-files-found: warn - - name: Ingest agent output - id: collect_output - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com" - GITHUB_SERVER_URL: ${{ github.server_url }} - GITHUB_API_URL: ${{ github.api_url }} - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/collect_ndjson_output.cjs'); - await main(); - - name: Upload sanitized agent output - if: always() && env.GH_AW_AGENT_OUTPUT - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: agent-output - path: ${{ env.GH_AW_AGENT_OUTPUT }} - if-no-files-found: warn - - name: Upload engine output files - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: agent_outputs - path: | - /tmp/gh-aw/sandbox/agent/logs/ - /tmp/gh-aw/redacted-urls.log - if-no-files-found: ignore - - name: Parse agent logs for step summary - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/ - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/parse_copilot_log.cjs'); - await main(); - - name: Parse MCP Gateway logs for step summary - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/parse_mcp_gateway_log.cjs'); - await main(); - - name: Print firewall logs - if: always() - continue-on-error: true - env: - AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs - run: | - # Fix permissions on firewall logs so they can be uploaded as artifacts - # AWF runs with sudo, creating files owned by root - sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true - # Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step) - if command -v awf &> /dev/null; then - awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" - else - echo 'AWF binary not installed, skipping firewall log summary' - fi - - name: Upload agent artifacts - if: always() - continue-on-error: true - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: agent-artifacts - path: | - /tmp/gh-aw/aw-prompts/prompt.txt - /tmp/gh-aw/aw_info.json - /tmp/gh-aw/mcp-logs/ - /tmp/gh-aw/sandbox/firewall/logs/ - /tmp/gh-aw/agent-stdio.log - /tmp/gh-aw/agent/ - /tmp/gh-aw/aw.patch - if-no-files-found: ignore - - conclusion: - needs: - - activation - - agent - - detection - - safe_outputs - if: (always()) && (needs.agent.result != 'skipped') - runs-on: ubuntu-slim - permissions: - contents: write - issues: write - pull-requests: write - outputs: - noop_message: ${{ steps.noop.outputs.noop_message }} - tools_reported: ${{ steps.missing_tool.outputs.tools_reported }} - total_count: ${{ steps.missing_tool.outputs.total_count }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Download agent output artifact - continue-on-error: true - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: agent-output - path: /tmp/gh-aw/safeoutputs/ - - name: Setup agent output environment variable - run: | - mkdir -p /tmp/gh-aw/safeoutputs/ - find "/tmp/gh-aw/safeoutputs/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/safeoutputs/agent_output.json" >> "$GITHUB_ENV" - - name: Process No-Op Messages - id: noop - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_NOOP_MAX: 1 - GH_AW_WORKFLOW_NAME: "Update Docs" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/update-docs.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/update-docs.md" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/noop.cjs'); - await main(); - - name: Record Missing Tool - id: missing_tool - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "Update Docs" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/update-docs.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/update-docs.md" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/missing_tool.cjs'); - await main(); - - name: Handle Agent Failure - id: handle_agent_failure - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "Update Docs" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/update-docs.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/update-docs.md" - GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_WORKFLOW_ID: "update-docs" - GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.agent.outputs.secret_verification_result }} - GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/handle_agent_failure.cjs'); - await main(); - - name: Handle No-Op Message - id: handle_noop_message - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "Update Docs" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/update-docs.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/update-docs.md" - GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_MESSAGE: ${{ steps.noop.outputs.noop_message }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/handle_noop_message.cjs'); - await main(); - - name: Handle Create Pull Request Error - id: handle_create_pr_error - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "Update Docs" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/update-docs.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/update-docs.md" - GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/handle_create_pr_error.cjs'); - await main(); - - detection: - needs: agent - if: needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true' - runs-on: ubuntu-latest - permissions: {} - timeout-minutes: 10 - outputs: - success: ${{ steps.parse_results.outputs.success }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Download agent artifacts - continue-on-error: true - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: agent-artifacts - path: /tmp/gh-aw/threat-detection/ - - name: Download agent output artifact - continue-on-error: true - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: agent-output - path: /tmp/gh-aw/threat-detection/ - - name: Echo agent output types - env: - AGENT_OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }} - run: | - echo "Agent output-types: $AGENT_OUTPUT_TYPES" - - name: Setup threat detection - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - WORKFLOW_NAME: "Update Docs" - WORKFLOW_DESCRIPTION: "This workflow keeps docs synchronized with code changes.\nTriggered on every push to main, it analyzes diffs to identify changed entities and\nupdates corresponding documentation. Maintains consistent style (precise, active voice,\nplain English), ensures single source of truth, and creates draft PRs with documentation\nupdates. Supports documentation-as-code philosophy." - HAS_PATCH: ${{ needs.agent.outputs.has_patch }} - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/setup_threat_detection.cjs'); - await main(); - - name: Ensure threat-detection directory and log - run: | - mkdir -p /tmp/gh-aw/threat-detection - touch /tmp/gh-aw/threat-detection/detection.log - - name: Validate COPILOT_GITHUB_TOKEN secret - id: validate-secret - run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default - env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - - name: Install GitHub Copilot CLI - run: /opt/gh-aw/actions/install_copilot_cli.sh 0.0.410 - - name: Execute GitHub Copilot CLI - id: agentic_execution - # Copilot CLI tool arguments (sorted): - # --allow-tool shell(cat) - # --allow-tool shell(grep) - # --allow-tool shell(head) - # --allow-tool shell(jq) - # --allow-tool shell(ls) - # --allow-tool shell(tail) - # --allow-tool shell(wc) - timeout-minutes: 20 - run: | - set -o pipefail - COPILOT_CLI_INSTRUCTION="$(cat /tmp/gh-aw/aw-prompts/prompt.txt)" - mkdir -p /tmp/ - mkdir -p /tmp/gh-aw/ - mkdir -p /tmp/gh-aw/agent/ - mkdir -p /tmp/gh-aw/sandbox/agent/logs/ - copilot --add-dir /tmp/ --add-dir /tmp/gh-aw/ --add-dir /tmp/gh-aw/agent/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-tool 'shell(cat)' --allow-tool 'shell(grep)' --allow-tool 'shell(head)' --allow-tool 'shell(jq)' --allow-tool 'shell(ls)' --allow-tool 'shell(tail)' --allow-tool 'shell(wc)' --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$COPILOT_CLI_INSTRUCTION"${GH_AW_MODEL_DETECTION_COPILOT:+ --model "$GH_AW_MODEL_DETECTION_COPILOT"} 2>&1 | tee /tmp/gh-aw/threat-detection/detection.log - env: - COPILOT_AGENT_RUNNER_TYPE: STANDALONE - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - GH_AW_MODEL_DETECTION_COPILOT: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }} - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GITHUB_HEAD_REF: ${{ github.head_ref }} - GITHUB_REF_NAME: ${{ github.ref_name }} - GITHUB_STEP_SUMMARY: ${{ env.GITHUB_STEP_SUMMARY }} - GITHUB_WORKSPACE: ${{ github.workspace }} - XDG_CONFIG_HOME: /home/runner - - name: Parse threat detection results - id: parse_results - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - - name: Upload threat detection log - if: always() - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: threat-detection.log - path: /tmp/gh-aw/threat-detection/detection.log - if-no-files-found: ignore - - pre_activation: - runs-on: ubuntu-slim - outputs: - activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Check team membership for workflow - id: check_membership - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_REQUIRED_ROLES: admin,maintainer,write - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/check_membership.cjs'); - await main(); - - safe_outputs: - needs: - - activation - - agent - - detection - if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (needs.detection.outputs.success == 'true') - runs-on: ubuntu-slim - permissions: - contents: write - issues: write - pull-requests: write - timeout-minutes: 15 - env: - GH_AW_WORKFLOW_ID: "update-docs" - GH_AW_WORKFLOW_NAME: "Update Docs" - GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/update-docs.md@eb7950f37d350af6fa09d19827c4883e72947221" - GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/tree/eb7950f37d350af6fa09d19827c4883e72947221/workflows/update-docs.md" - outputs: - create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }} - create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} - process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} - process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} - steps: - - name: Setup Scripts - uses: github/gh-aw/actions/setup@58d1d157fbac0f1204798500faefc4f7461ebe28 # v0.45.0 - with: - destination: /opt/gh-aw/actions - - name: Download agent output artifact - continue-on-error: true - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: agent-output - path: /tmp/gh-aw/safeoutputs/ - - name: Setup agent output environment variable - run: | - mkdir -p /tmp/gh-aw/safeoutputs/ - find "/tmp/gh-aw/safeoutputs/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/safeoutputs/agent_output.json" >> "$GITHUB_ENV" - - name: Download patch artifact - continue-on-error: true - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: agent-artifacts - path: /tmp/gh-aw/ - - name: Checkout repository - if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (contains(needs.agent.outputs.output_types, 'create_pull_request')) - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - token: ${{ github.token }} - persist-credentials: false - fetch-depth: 1 - - name: Configure Git credentials - if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (contains(needs.agent.outputs.output_types, 'create_pull_request')) - env: - REPO_NAME: ${{ github.repository }} - SERVER_URL: ${{ github.server_url }} - GIT_TOKEN: ${{ github.token }} - run: | - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - # Re-authenticate git with GitHub token - SERVER_URL_STRIPPED="${SERVER_URL#https://}" - git remote set-url origin "https://x-access-token:${GIT_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" - echo "Git configured with standard GitHub Actions identity" - - name: Process Safe Outputs - id: process_safe_outputs - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_pull_request\":{\"base_branch\":\"${{ github.ref_name }}\",\"draft\":true,\"labels\":[\"automation\",\"documentation\"],\"max\":1,\"max_patch_size\":1024},\"missing_data\":{},\"missing_tool\":{}}" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/safe_output_handler_manager.cjs'); - await main(); - diff --git a/.github/workflows/update-docs.md b/.github/workflows/update-docs.md deleted file mode 100644 index 597a6e2..0000000 --- a/.github/workflows/update-docs.md +++ /dev/null @@ -1,124 +0,0 @@ ---- -description: | - This workflow keeps docs synchronized with code changes. - Triggered on every push to main, it analyzes diffs to identify changed entities and - updates corresponding documentation. Maintains consistent style (precise, active voice, - plain English), ensures single source of truth, and creates draft PRs with documentation - updates. Supports documentation-as-code philosophy. - -on: - push: - branches: [main] - workflow_dispatch: - -permissions: read-all - -network: defaults - -safe-outputs: - create-pull-request: - draft: true - labels: [automation, documentation] - -tools: - github: - toolsets: [all] - web-fetch: - # By default this workflow allows all bash commands within the confine of Github Actions VM - bash: true - -timeout-minutes: 15 -source: githubnext/agentics/workflows/update-docs.md@eb7950f37d350af6fa09d19827c4883e72947221 ---- - -# Update Docs - -## Job Description - - - -Your name is ${{ github.workflow }}. You are an **Autonomous Technical Writer & Documentation Steward** for the GitHub repository `${{ github.repository }}`. - -### Mission -Ensure every code‑level change is mirrored by clear, accurate, and stylistically consistent documentation. - -### Voice & Tone -- Precise, concise, and developer‑friendly -- Active voice, plain English, progressive disclosure (high‑level first, drill‑down examples next) -- Empathetic toward both newcomers and power users - -### Key Values -Documentation‑as‑Code, transparency, single source of truth, continuous improvement, accessibility, internationalization‑readiness - -### Your Workflow - -1. **Analyze Repository Changes** - - - On every push to main branch, examine the diff to identify changed/added/removed entities - - Look for new APIs, functions, classes, configuration files, or significant code changes - - Check existing documentation for accuracy and completeness - - Identify documentation gaps like failing tests: a "red build" until fixed - -2. **Documentation Assessment** - - - Review existing documentation structure (look for docs/, documentation/, or similar directories) - - Assess documentation quality against style guidelines: - - Diátaxis framework (tutorials, how-to guides, technical reference, explanation) - - Google Developer Style Guide principles - - Inclusive naming conventions - - Microsoft Writing Style Guide standards - - Identify missing or outdated documentation - -3. **Create or Update Documentation** - - - Use Markdown (.md) format wherever possible - - Fall back to MDX only when interactive components are indispensable - - Follow progressive disclosure: high-level concepts first, detailed examples second - - Ensure content is accessible and internationalization-ready - - Create clear, actionable documentation that serves both newcomers and power users - -4. **Documentation Structure & Organization** - - - Organize content following Diátaxis methodology: - - **Tutorials**: Learning-oriented, hands-on lessons - - **How-to guides**: Problem-oriented, practical steps - - **Technical reference**: Information-oriented, precise descriptions - - **Explanation**: Understanding-oriented, clarification and discussion - - Maintain consistent navigation and cross-references - - Ensure searchability and discoverability - -5. **Quality Assurance** - - - Check for broken links, missing images, or formatting issues - - Ensure code examples are accurate and functional - - Verify accessibility standards are met - -6. **Continuous Improvement** - - - Perform nightly sanity sweeps for documentation drift - - Update documentation based on user feedback in issues and discussions - - Maintain and improve documentation toolchain and automation - -### Output Requirements - -- **Create Draft Pull Requests**: When documentation needs updates, create focused draft pull requests with clear descriptions - -### Technical Implementation - -- **Hosting**: Prepare documentation for GitHub Pages deployment with branch-based workflows -- **Automation**: Implement linting and style checking for documentation consistency - -### Error Handling - -- If documentation directories don't exist, suggest appropriate structure -- If build tools are missing, recommend necessary packages or configuration - -### Exit Conditions - -- Exit if the repository has no implementation code yet (empty repository) -- Exit if no code changes require documentation updates -- Exit if all documentation is already up-to-date and comprehensive - -> NOTE: Never make direct pushes to the main branch. Always create a pull request for documentation changes. - -> NOTE: Treat documentation gaps like failing tests. diff --git a/.gitignore b/.gitignore index 7eecc2e..ea77fd9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ # Mnemonic local data +refactor-result-* .claude/mnemonic/ .claude/.mnemonic-integration-manifest.json .fastembed_cache/ diff --git a/README.md b/README.md index 7487e96..47eb22e 100644 --- a/README.md +++ b/README.md @@ -201,31 +201,31 @@ See [docs/ontologies.md](docs/ontologies.md) for the full guide. | Command | Description | |---------|-------------| | `/mnemonic:setup` | Configure mnemonic with proactive behavior | -| `/mnemonic:init` | Initialize directory structure | | `/mnemonic:capture` | Capture a new memory | | `/mnemonic:recall` | Search and recall memories | -| `/mnemonic:search` | Full-text search | -| `/mnemonic:search-enhanced` | Agent-driven iterative search with synthesis | +| `/mnemonic:search` | Full-text search and enhanced iterative search | | `/mnemonic:query` | Structured frontmatter queries using yq | | `/mnemonic:status` | Show system status | | `/mnemonic:gc` | Garbage collect expired memories | | `/mnemonic:list` | List loaded ontologies and namespaces | | `/mnemonic:validate` | Validate ontology file | -| `/mnemonic:discover` | Discover entities in files based on ontology patterns | +| `/mnemonic:custodian` | Memory health checks and maintenance | +| `/mnemonic:integrate` | Wire mnemonic into other plugins | ## Skills Skills are fully self-contained and work without hooks or libraries: -- **mnemonic-setup**: Configure CLAUDE.md for proactive behavior -- **mnemonic-core**: Complete memory operations -- **mnemonic-search**: Advanced search patterns -- **mnemonic-search-enhanced**: Agent-driven iterative search with synthesis -- **mnemonic-format**: MIF Level 3 templates -- **mnemonic-organization**: Namespaces and maintenance -- **mnemonic-blackboard**: Cross-session coordination -- **mnemonic-agent-coordination**: Multi-agent coordination patterns +- **setup**: Configure CLAUDE.md for proactive behavior +- **core**: Complete memory operations +- **search**: Advanced search patterns and iterative synthesis +- **format**: MIF Level 3 templates +- **blackboard**: Cross-session coordination and agent patterns - **ontology**: Custom ontology support with entity types and discovery +- **custodian**: Memory maintenance, deduplication, and health checks +- **integrate**: CLAUDE.md integration for new projects +- **qmd-setup**: Semantic search setup via qmd +- **qmd-reindex**: Re-index memories for semantic search ## Agents @@ -241,17 +241,14 @@ Autonomous agents for specialized tasks: | Guide | Focus | |-------|-------| | [Getting Started](docs/tutorials/getting-started.md) | First project setup tutorial | -| [Tutorials](docs/tutorials/) | Step-by-step learning guides | -| [API Reference](docs/api-reference.md) | Python library documentation | | [CLI Usage](docs/cli-usage.md) | Command-line operations | | [Troubleshooting](docs/troubleshooting.md) | Common issues and solutions | | [Architecture](docs/architecture.md) | System architecture | +| [Semantic Search](docs/semantic-search.md) | QMD vector search setup | | [Library Reference](docs/library-reference.md) | Python library API reference | -| [Agent Coordination](docs/agent-coordination.md) | Multi-agent patterns | | [Ontologies](docs/ontologies.md) | Custom ontology guide | | [Validation](docs/validation.md) | Memory validation guide | | [ADRs](docs/adrs/) | Architecture decision records | -| [Enterprise](docs/enterprise/) | Deployment and compliance | ## Proactive Behavior @@ -359,19 +356,21 @@ mnemonic/ ├── .claude-plugin/ │ └── plugin.json # Plugin manifest ├── agents/ -│ ├── memory-curator.md # Maintenance agent +│ ├── memory-curator.md # Maintenance agent │ ├── mnemonic-search-subcall.md # Search iteration agent -│ └── compression-worker.md # Memory summarization agent +│ ├── compression-worker.md # Memory summarization agent +│ └── ontology-discovery.md # Entity discovery agent ├── commands/ │ └── *.md # Slash commands ├── docs/ │ ├── architecture.md # System architecture │ ├── semantic-search.md # QMD semantic search guide │ ├── validation.md # Memory validation guide -│ ├── agent-coordination.md # Multi-agent patterns │ ├── ontologies.md # Custom ontology guide -│ ├── adrs/ # Architecture decision records -│ └── enterprise/ # Enterprise adoption guides +│ ├── cli-usage.md # Command-line operations +│ ├── library-reference.md # Python library API +│ ├── troubleshooting.md # Common issues and solutions +│ └── adrs/ # Architecture decision records ├── hooks/ │ ├── hooks.json # Hook configuration │ └── *.py # Hook implementations @@ -381,7 +380,8 @@ mnemonic/ │ ├── ontology.py # Ontology loading │ ├── search.py # Memory search and scoring │ ├── memory_reader.py # Memory metadata extraction -│ └── relationships.py # Relationship writing +│ ├── relationships.py # Relationship writing +│ └── migrate_filenames.py # Filename migration utilities ├── skills/ │ ├── */SKILL.md # Self-contained skills │ └── ontology/ # Custom ontology support @@ -430,17 +430,6 @@ npm i -g @tobilu/qmd make check-deps ``` -## Documentation - -- **[Semantic Search Guide](docs/semantic-search.md)** - Setup and use QMD for vector search -- **[CLI Usage](docs/cli-usage.md)** - Command-line operations and search patterns -- **[Architecture](docs/architecture.md)** - System design and components -- **[Validation](docs/validation.md)** - Memory validation and MIF compliance -- **[Custom Ontologies](docs/ontologies.md)** - Extend with domain-specific types -- **[Agent Coordination](docs/agent-coordination.md)** - Multi-agent workflows -- **[ADRs](docs/adrs/)** - Architecture decision records -- **[Enterprise Guides](docs/enterprise/)** - Deployment and governance - ## Related Projects - **[MIF (Memory Interchange Format)](https://mif-spec.dev)** - The specification this plugin implements. An open standard for portable AI memory storage. Schemas: https://mif-spec.dev/schema/ diff --git a/commands/capture.md b/commands/capture.md index 835dc97..99fdb43 100644 --- a/commands/capture.md +++ b/commands/capture.md @@ -34,7 +34,7 @@ Capture a new memory to the mnemonic filesystem. - `--tags` - Comma-separated list of tags - `--scope` - project (default, current project) or org (shared across all projects in organization) - `--confidence` - Confidence score 0.0-1.0 (default: 0.95) -- `--citations` - JSON array of citation objects (see mnemonic-format skill for schema) +- `--citations` - JSON array of citation objects (see format skill for schema) - `--entity-type` - Entity type from ontology (e.g., technology, component, runbook) - `--entity-id` - Custom entity ID (auto-generated if not provided) diff --git a/commands/discover.md b/commands/discover.md deleted file mode 100644 index c7b7856..0000000 --- a/commands/discover.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -allowed-tools: -- Bash -- Read -- Grep -- Glob -- Write -description: Discover entities in content based on ontology patterns -name: discover ---- - -## Memory - -Search first: `/mnemonic:search {relevant_keywords}` -Capture after: `/mnemonic:capture {namespace} "{title}"` - -Run `/mnemonic:list --namespaces` to see available namespaces from loaded ontologies. - - -# Discover Entities - -Scans content or files for entity references and suggests entity types -based on discovery patterns defined in loaded ontologies. - -## Usage - -``` -/mnemonic:discover [] [--suggest] [--json] -``` - -## Arguments - -- `` - File or directory to scan (defaults to current directory) -- `--suggest` - Suggest entity types for unlinked mentions -- `--json` - Output as JSON - -## Procedure - -1. Load ontology from `$MNEMONIC_ROOT/ontology.yaml` -2. Extract discovery patterns -3. Scan content for pattern matches -4. Report found entities and suggestions - -```bash -# Resolve MNEMONIC_ROOT from config -if [ -f "$HOME/.config/mnemonic/config.json" ]; then - RAW_PATH=$(python3 -c "import json; print(json.load(open('$HOME/.config/mnemonic/config.json')).get('memory_store_path', '~/.claude/mnemonic'))") - MNEMONIC_ROOT="${RAW_PATH/#\~/$HOME}" -else - MNEMONIC_ROOT="$HOME/.claude/mnemonic" -fi -SCAN_PATH="${1:-.}" -ONTOLOGY_FILE="$MNEMONIC_ROOT/ontology.yaml" - -# Check for ontology -if [ ! -f "$ONTOLOGY_FILE" ]; then - echo "No ontology found at $ONTOLOGY_FILE" - echo "Copy an ontology to enable discovery:" - echo " cp skills/ontology/ontologies/examples/software-engineering.ontology.yaml $MNEMONIC_ROOT/ontology.yaml" - exit 1 -fi - -echo "Scanning $SCAN_PATH for entity patterns..." -echo "" - -# Extract and run discovery patterns from ontology -# Technology patterns -echo "## Technologies Found" -rg -i '\b(PostgreSQL|MySQL|MongoDB|Redis|Elasticsearch)\b' "$SCAN_PATH" --glob '*.{md,py,js,ts,yaml,yml}' -l 2>/dev/null | head -10 - -echo "" -echo "## Design Patterns Found" -rg -i '\b(Factory|Singleton|Observer|Repository|Adapter|Strategy)\s+Pattern\b' "$SCAN_PATH" --glob '*.{md,py,js,ts}' -l 2>/dev/null | head -10 - -echo "" -echo "## Incidents/Postmortems Found" -rg -i '\b(outage|incident|postmortem|RCA)\b' "$SCAN_PATH" --glob '*.md' -l 2>/dev/null | head -10 - -echo "" -echo "## Runbooks Found" -rg -i '\b(runbook|playbook|SOP|procedure)\b' "$SCAN_PATH" --glob '*.md' -l 2>/dev/null | head -10 -``` - -## Suggestions - -When patterns match, Claude will suggest: - -``` -I found mentions of these technologies that could be captured as entities: -- PostgreSQL (mentioned in src/database.py) -- Redis (mentioned in src/cache.py) - -Would you like me to create technology entities for these? -``` diff --git a/commands/init.md b/commands/init.md deleted file mode 100644 index 161098c..0000000 --- a/commands/init.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -name: init -allowed-tools: -- Bash -- Write -- Read -- Glob -- Grep -argument-hint: '[--org ]' -description: Initialize mnemonic directory structure ---- - -## Memory - -Search first: `/mnemonic:search {relevant_keywords}` -Capture after: `/mnemonic:capture {namespace} "{title}"` - -Run `/mnemonic:list --namespaces` to see available namespaces from loaded ontologies. - - -# /mnemonic:init - -Initialize the mnemonic memory system directory structure. - -## Arguments - -- `--org ` - Override auto-detected organization name - -## Procedure - -### Step 1: Detect or Override Organization - -```bash -# Use provided org or detect from git -if [ -n "$ORG_OVERRIDE" ]; then - ORG="$ORG_OVERRIDE" -else - ORG=$(git remote get-url origin 2>/dev/null | sed -E 's|.*[:/]([^/]+)/[^/]+\.git$|\1|' | sed 's|\.git$||') - [ -z "$ORG" ] && ORG="default" -fi - -PROJECT=$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null) -[ -z "$PROJECT" ] && PROJECT=$(basename "$PWD") -``` - -### Step 2: Create Unified Directory Structure - -All memories are stored under `${MNEMONIC_ROOT}/` with the V2 path structure: - -```bash -# Base directories -mkdir -p ${MNEMONIC_ROOT}/"$ORG"/"$PROJECT" -mkdir -p ${MNEMONIC_ROOT}/"$ORG" # For org-wide memories - -# Cognitive triad namespaces (project-specific, prefixed with _ for disambiguation) -for ns in _semantic/decisions _semantic/knowledge _semantic/entities \ - _episodic/incidents _episodic/sessions _episodic/blockers \ - _procedural/runbooks _procedural/patterns _procedural/migrations; do - mkdir -p ${MNEMONIC_ROOT}/"$ORG"/"$PROJECT"/"$ns" -done - -# Org-wide namespaces (shared across projects) -for ns in _semantic/decisions _semantic/knowledge _semantic/entities \ - _episodic/incidents _episodic/sessions _episodic/blockers \ - _procedural/runbooks _procedural/patterns _procedural/migrations; do - mkdir -p ${MNEMONIC_ROOT}/"$ORG"/"$ns" -done - -# Blackboard for session coordination (per-project) -mkdir -p ${MNEMONIC_ROOT}/"$ORG"/"$PROJECT"/.blackboard - -# Initialize standard blackboard topics -touch ${MNEMONIC_ROOT}/"$ORG"/"$PROJECT"/.blackboard/active-tasks.md -touch ${MNEMONIC_ROOT}/"$ORG"/"$PROJECT"/.blackboard/session-notes.md -touch ${MNEMONIC_ROOT}/"$ORG"/"$PROJECT"/.blackboard/shared-context.md -``` - -### Step 3: Initialize Git Repository - -```bash -if [ ! -d ${MNEMONIC_ROOT}/.git ]; then - cd ${MNEMONIC_ROOT} - git init - - cat > .gitignore << 'EOF' -# Lock files -*.lock - -# Temporary files -.blackboard/*.tmp -*.swp -*~ - -# OS files -.DS_Store -Thumbs.db -EOF - - git add . - git commit -m "Initialize mnemonic memory system" - cd - -fi -``` - -### Step 4: Verify Structure - -```bash -echo "=== Mnemonic Initialized ===" -echo "Organization: $ORG" -echo "Project: $PROJECT" -echo "" -echo "Memory path: ${MNEMONIC_ROOT}/$ORG/$PROJECT/" -echo "" -echo "Namespaces:" -echo " _semantic/decisions - Architectural choices" -echo " _semantic/knowledge - APIs, context, learnings" -echo " _semantic/entities - Entity definitions" -echo " _episodic/incidents - Production issues" -echo " _episodic/sessions - Debug sessions" -echo " _episodic/blockers - Impediments" -echo " _procedural/runbooks - Operational procedures" -echo " _procedural/patterns - Code conventions" -echo " _procedural/migrations - Migration steps" -``` - -## Output - -Display: -- Detected/configured organization -- Detected project name -- Memory path (unified under ${MNEMONIC_ROOT}/) -- Namespace list with descriptions -- Git status diff --git a/commands/search-enhanced.md b/commands/search-enhanced.md deleted file mode 100644 index 48d9fa1..0000000 --- a/commands/search-enhanced.md +++ /dev/null @@ -1,170 +0,0 @@ ---- -name: search-enhanced -allowed-tools: -- Task -- Bash -- Read -- Grep -- Glob -- Write -argument-hint: [--scope user|project|all] [--max-iterations 1-3] -description: Agent-driven iterative search with synthesis ---- - -## Memory - -Search first: `/mnemonic:search {relevant_keywords}` -Capture after: `/mnemonic:capture {namespace} "{title}"` - -Run `/mnemonic:list --namespaces` to see available namespaces from loaded ontologies. - - -# /mnemonic:search-enhanced - -Agent-driven iterative search across mnemonic memories with synthesis. Uses subcall agents for query refinement and produces comprehensive, synthesized answers. - -## Arguments - -- `` - Required. Search query or question -- `--scope` - Search scope: user, project, or all (default: all) -- `--max-iterations` - Maximum search iterations 1-3 (default: 3) - -## When to Use - -Use `/mnemonic:search-enhanced` instead of `/mnemonic:search` when: -- Query is complex or multi-faceted -- You want comprehensive coverage across namespaces -- You need a synthesized answer, not just file matches -- Topic may span multiple memory types - -For simple, fast searches use `/mnemonic:search` instead. - -## Procedure - -### Step 1: Parse Arguments - -```bash -QUERY="${1:?Error: Query required}" -SCOPE="${SCOPE:-all}" -MAX_ITERATIONS="${MAX_ITERATIONS:-3}" -``` - -### Step 2: Initialize - -```bash -echo "=== Enhanced Memory Search ===" -echo "Query: $QUERY" -echo "Scope: $SCOPE" -echo "Max iterations: $MAX_ITERATIONS" -echo "" -``` - -### Step 3: Invoke mnemonic-search-enhanced Skill - -The skill handles the full workflow: -1. Execute iterative search with subcall agents -2. Refine queries based on findings -3. Aggregate and deduplicate results -4. Synthesize comprehensive answer - -### Step 4: Display Results - -The skill produces structured markdown output: -- Summary answering the query -- Key findings by category -- Analysis connecting findings -- Source memory references -- Gaps and suggested follow-ups - -## Example Usage - -### Basic Enhanced Search - -``` -/mnemonic:search-enhanced "authentication security patterns" -``` - -### Project-Scoped Search - -``` -/mnemonic:search-enhanced "database performance" --scope project -``` - -### Quick Enhanced Search (1 iteration) - -``` -/mnemonic:search-enhanced "API endpoints" --max-iterations 1 -``` - -### Comprehensive Search - -``` -/mnemonic:search-enhanced "everything about our testing strategy" --max-iterations 3 -``` - -## Output Format - -```markdown -## Summary - -[2-3 sentence executive summary answering the query] - -## Key Findings - -### [Category] -- **[Memory Title]** (namespace, type) - - Key insight - - Evidence: "quote" - -## Analysis - -[Synthesis connecting findings] - -## Coverage - -- Iterations: 3 -- Memories examined: 45 -- Relevant memories: 12 -- Namespaces searched: _semantic/decisions, _semantic/knowledge, _procedural/patterns - -## Source Memories - -- [[uuid-1]] - Memory Title 1 -- [[uuid-2]] - Memory Title 2 - -## Gaps & Next Steps - -[Suggested follow-up searches] -``` - -## Performance - -| Metric | Typical Value | -|--------|---------------| -| Iterations | 2-3 | -| Runtime | 15-30 seconds | -| Memories examined | 20-50 | -| Context usage | 3-5k tokens | - -Enhanced search is slower than basic `/mnemonic:search` but provides: -- Comprehensive coverage across namespaces -- Synthesized answers (not just matches) -- Automatic query refinement -- Citation of source memories - -## Comparison - -| Feature | `/mnemonic:search` | `/mnemonic:search-enhanced` | -|---------|-------------------|----------------------------| -| Speed | Fast (~2s) | Slower (~20s) | -| Output | File matches | Synthesized answer | -| Refinement | None | Iterative | -| Coverage | Single pattern | Multi-pattern | -| Use case | Quick lookup | Comprehensive analysis | - -## Related - -- `/mnemonic:search` - Basic single-shot search -- `/mnemonic:recall` - Structured recall with filters -- `mnemonic-search` skill - Advanced search patterns -- `mnemonic-search-enhanced` skill - Full orchestration details diff --git a/commands/team-audit.md b/commands/team-audit.md deleted file mode 100644 index 27fdd80..0000000 --- a/commands/team-audit.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -name: team-audit -description: Comprehensive health audit with parallel agent remediation across all memory phases -allowed-tools: -- Bash -- Read -- Write -- Edit -- Glob -- Grep -- Task -argument-hint: '[--dry-run] [--phase 1|2|3|4|5|all]' ---- - -## Memory - -Search first: `/mnemonic:search {relevant_keywords}` -Capture after: `/mnemonic:capture {namespace} "{title}"` - -Run `/mnemonic:list --namespaces` to see available namespaces from loaded ontologies. - - -# /mnemonic:team-audit - -Comprehensive health audit of the mnemonic memory system with parallel agent remediation. - -## Arguments - -- `--dry-run` — Report issues without modifying files -- `--phase ` — Run a specific phase (1-5) or all phases (default: all) - -## Setup - -```bash -# Resolve MNEMONIC_ROOT from config -if [ -f "$HOME/.config/mnemonic/config.json" ]; then - RAW_PATH=$(python3 -c "import json; print(json.load(open('$HOME/.config/mnemonic/config.json')).get('memory_store_path', '~/.claude/mnemonic'))") - MNEMONIC_ROOT="${RAW_PATH/#\~/$HOME}" -else - MNEMONIC_ROOT="$HOME/.claude/mnemonic" -fi -``` - -## Phases - -Orchestrate a team of agents to execute phases in parallel where possible. - -### Phase 1: Duplicate Detection & Archival - -Scan all active memories (exclude `.archive/`) for duplicates across three vectors: - -1. **Same-topic duplicates within a namespace** — memories with similar titles/content about the same decision, pattern, or knowledge item. Use `lib.search.find_duplicates()` or Python fuzzy matching on titles. Read candidates to confirm. -2. **Cross-namespace duplicates** — identical memories in both `default/` and project-specific paths, or in both org-level and project-level paths. Keep project-specific, archive generic. -3. **Shared UUID duplicates** — memories with identical `id:` fields across different paths. Keep one, archive the other. - -For each confirmed duplicate cluster: keep the most complete/recent, archive the rest to `.archive/YYYY-MM/custodian-dedup/`. - -### Phase 2: Frontmatter Validation & Repair - -Validate all active memories against the MIF schema: - -- **Required fields**: `id` (valid UUID4), `type` (semantic|procedural|episodic), `title`, `created` (ISO 8601) -- **Placeholder detection**: Replace `PLACEHOLDER_UUID`, `MEMORY_ID_PLACEHOLDER`, `DATE_PLACEHOLDER`, `${UUID}`, `${DATE}` with real generated values -- **Type-path consistency**: `type:` must match directory path (`_semantic/` → semantic, `_procedural/` → procedural, `_episodic/` → episodic) -- **Namespace-path consistency**: `namespace:` must match cognitive triad path. Strip `/user`, `/project` suffixes. -- **Frontmatter delimiters**: Exactly 2 `---` per file. Replace extra `---` in body with `***`. -- **Broken merge templates**: Remove lines containing `> Merged from memory ${UUID}` or unresolved template variables. - -### Phase 3: Decay & Strength Management - -- **Add decay fields** to memories missing them: `strength: 1.0`, `half_life:` (per defaults), `last_accessed:` (file mtime), `decay_model: exponential` -- **Recalculate stale strengths**: `strength = 0.5^(days_since_access / half_life_days)` -- **Normalize schema**: Flatten nested `decay:` blocks to top-level fields - -**Half-life defaults:** - -| Namespace | Half-life | -|-----------|-----------| -| `_semantic/decisions` | P180D | -| `_semantic/knowledge` | P90D | -| `_procedural/patterns` | P180D | -| `_procedural/runbooks` | P180D | -| `_episodic/blockers` | P30D | -| `_episodic/sessions` | P30D | -| `_episodic/incidents` | P60D | - -### Phase 4: Link Validation - -- Find all `[[wiki-links]]` in memory bodies. Check if targets exist. Replace broken links with plain text. -- Validate frontmatter `relationships:` entries against the canonical MIF relationship registry (all supported types including inverse forms, both snake_case and PascalCase). Remove references to non-existent memories or invalid relationship types. - -### Phase 5: Prevention — Capture Workflow Audit - -Audit the mnemonic plugin source for correctness: - -1. **Capture template** (`skills/mnemonic-core/SKILL.md`): Verify minimal format includes `namespace`, `confidence`, `strength`, `half_life`, `last_accessed`, `decay_model`, `provenance`. -2. **Dedup check** (`skills/mnemonic-core/SKILL.md`, `references/capture.md`, `commands/capture.md`): Verify mandatory search-before-capture step exists. -3. **Namespace routing**: Verify memories route to `${ORG}/${PROJECT}/${NAMESPACE}`, not `default/` or bare org paths. - -## Deliverables - -After all phases, report: - -| Metric | Value | -|--------|-------| -| Active memories before/after | | -| Duplicates archived (by type) | | -| Frontmatter issues fixed (by category) | | -| Decay coverage % | | -| Broken links repaired | | -| Prevention measures verified | | diff --git a/docs/adrs/adr-001-filesystem-based-storage.md b/docs/adrs/adr-001-filesystem-based-storage.md index cfe385e..8211e11 100644 --- a/docs/adrs/adr-001-filesystem-based-storage.md +++ b/docs/adrs/adr-001-filesystem-based-storage.md @@ -250,8 +250,8 @@ This decision is supported by independent research: | Finding | Files | Lines | Assessment | |---------|-------|-------|------------| -| Memory files use .memory.md extension | `skills/mnemonic-core/SKILL.md` | L152-L176 | compliant | -| YAML frontmatter structure defined | `skills/mnemonic-format/SKILL.md` | L1-L50 | compliant | +| Memory files use .memory.md extension | `skills/core/SKILL.md` | L152-L176 | compliant | +| YAML frontmatter structure defined | `skills/format/SKILL.md` | L1-L50 | compliant | | Git integration in capture workflow | `commands/capture.md` | L131-L138 | compliant | | Namespace directory structure | `commands/setup.md` | L47-L58 | compliant | diff --git a/docs/adrs/adr-002-mif-level-3-format.md b/docs/adrs/adr-002-mif-level-3-format.md index f982b32..9fbf2dc 100644 --- a/docs/adrs/adr-002-mif-level-3-format.md +++ b/docs/adrs/adr-002-mif-level-3-format.md @@ -242,11 +242,11 @@ Mitigations for negative consequences: | Finding | Files | Lines | Assessment | |---------|-------|-------|------------| -| MIF Level 3 frontmatter template | `skills/mnemonic-core/SKILL.md` | L346-L394 | compliant | -| Cognitive type classification | `skills/mnemonic-core/SKILL.md` | L143-L149 | compliant | +| MIF Level 3 frontmatter template | `skills/core/SKILL.md` | L346-L394 | compliant | +| Cognitive type classification | `skills/core/SKILL.md` | L143-L149 | compliant | | Temporal fields in capture | `commands/capture.md` | L99-L116 | compliant | | Provenance tracking | `commands/capture.md` | L112-L115 | compliant | -| Decay model support | `skills/mnemonic-format/SKILL.md` | L1-L50 | compliant | +| Decay model support | `skills/format/SKILL.md` | L1-L50 | compliant | **Summary:** MIF Level 3 format implementation follows specification. diff --git a/docs/adrs/adr-004-mif-schema-validation.md b/docs/adrs/adr-004-mif-schema-validation.md index b1851bf..16f7149 100644 --- a/docs/adrs/adr-004-mif-schema-validation.md +++ b/docs/adrs/adr-004-mif-schema-validation.md @@ -1,6 +1,6 @@ --- title: "MIF Schema as Single Source of Truth for Validation" -description: "Validation tool parses MIF schema from mnemonic-format SKILL.md directly" +description: "Validation tool parses MIF schema from format SKILL.md directly" type: adr category: architecture tags: @@ -38,7 +38,7 @@ The mnemonic system needs a validation tool to ensure memory files conform to th ### Current State -The MIF Level 3 specification is documented in `skills/mnemonic-format/SKILL.md`, which includes: +The MIF Level 3 specification is documented in `skills/format/SKILL.md`, which includes: - Required fields and their types - Valid enum values for type, source_type, etc. - Validation rules section with specific checks @@ -109,7 +109,7 @@ The MIF Level 3 specification is documented in `skills/mnemonic-format/SKILL.md` ### Option 3: Parse Schema from SKILL.md (Selected) -**Description**: Validation tool parses rules directly from `mnemonic-format/SKILL.md`. +**Description**: Validation tool parses rules directly from `format/SKILL.md`. **Technical Characteristics**: - SKILL.md is authoritative source @@ -133,7 +133,7 @@ The MIF Level 3 specification is documented in `skills/mnemonic-format/SKILL.md` ## Decision -We will parse validation rules directly from `skills/mnemonic-format/SKILL.md`. +We will parse validation rules directly from `skills/format/SKILL.md`. ### Parsing Strategy @@ -149,7 +149,7 @@ The validation tool will extract: ```python def parse_mif_schema(skill_path: Path) -> MIFSchema: - """Parse MIF schema from mnemonic-format SKILL.md.""" + """Parse MIF schema from format SKILL.md.""" content = skill_path.read_text() schema = MIFSchema() diff --git a/docs/adrs/adr-008-custom-ontologies.md b/docs/adrs/adr-008-custom-ontologies.md index 5d190d8..faa20bd 100644 --- a/docs/adrs/adr-008-custom-ontologies.md +++ b/docs/adrs/adr-008-custom-ontologies.md @@ -318,7 +318,7 @@ mnemonic/ 1. `hooks/session_start.py` - Load ontologies 2. `commands/capture.md` - Ontology-aware capture 3. `tools/mnemonic-validate` - Ontology validation -4. `skills/mnemonic-format/SKILL.md` - Document ontology fields +4. `skills/format/SKILL.md` - Document ontology fields 5. `.claude-plugin/plugin.json` - Register new components ## Validation diff --git a/docs/adrs/adr-009-unified-path-resolution.md b/docs/adrs/adr-009-unified-path-resolution.md index cab6079..5273687 100644 --- a/docs/adrs/adr-009-unified-path-resolution.md +++ b/docs/adrs/adr-009-unified-path-resolution.md @@ -406,7 +406,6 @@ Convert Bash commands to Python: - [lib/paths.py](../../lib/paths.py) - Implementation - [tests/unit/test_paths.py](../../tests/unit/test_paths.py) - Tests -- [docs/architecture/path-resolution-integration.md](../architecture/path-resolution-integration.md) - Integration guide - [ADR-004: MIF Schema Validation](adr-004-mif-schema-validation.md) - Related MIF schema decision ## References diff --git a/docs/agent-coordination.md b/docs/agent-coordination.md deleted file mode 100644 index 683e548..0000000 --- a/docs/agent-coordination.md +++ /dev/null @@ -1,76 +0,0 @@ -# Multi-Agent Coordination - -This document describes how agents in the mnemonic system coordinate their work. - -## Coordination Model - -Agent coordination uses two distinct mechanisms based on scope: - -| Scope | Mechanism | When | -|-------|-----------|------| -| **In-session** | Claude Code native swarm | Agents working together in a single session | -| **Cross-session** | Mnemonic blackboard handoff | Passing context to the next session | - -### In-Session: Native Swarm - -For real-time coordination between agents within a single session, use Claude Code's built-in tools: - -- **TeamCreate**: Create a team with shared task list -- **TaskCreate / TaskUpdate / TaskList**: Track and assign work items -- **SendMessage**: Direct messages between agents -- **Task tool**: Spawn specialized subagents - -These tools handle registration, status tracking, task handoff, shared state, and progress reporting natively. The mnemonic blackboard is **not** used for in-session coordination. - -### Cross-Session: Blackboard Handoff - -For context that must survive between sessions, the blackboard provides automatic handoff: - -``` -${MNEMONIC_ROOT}/.blackboard/ -├── sessions/{session_id}/ # Session audit trail -│ ├── session-notes.md # Activity log -│ └── _meta.json # Lifecycle metadata -└── handoff/ - ├── latest-handoff.md # Active handoff (overwritten each session) - └── handoff-{session_id}.md # Archived handoffs -``` - -**Lifecycle:** -1. `hooks/session_start.py` reads `handoff/latest-handoff.md` at session start -2. `hooks/stop.py` writes handoff summary at session end - -This is fully automatic via hooks. - -## Agents - -| Agent | Purpose | -|-------|---------| -| `memory-curator` | Maintenance, conflict detection, deduplication | -| `mnemonic-search-subcall` | Individual search iterations | -| `compression-worker` | Memory summarization | -| `search-enhanced` (orchestrator) | Coordinates multi-round search | - -## Path Resolution - -Use `lib.paths.PathResolver` or the CLI tool: - -```bash -MNEMONIC_ROOT=$(tools/mnemonic-paths root) -BLACKBOARD=$(tools/mnemonic-paths blackboard) -HANDOFF_DIR=${BLACKBOARD}/handoff -``` - -## Best Practices - -1. **Use native swarm for in-session work** - TeamCreate, SendMessage, TaskCreate -2. **Let hooks handle cross-session handoff** - Automatic via session lifecycle -3. **Capture persistent knowledge as memories** - Insights that outlast the next session belong in `*.memory.md` -4. **Keep handoffs actionable** - Focus on what the next session needs - -## Related Documentation - -- [Blackboard Skill](../skills/mnemonic-blackboard/SKILL.md) - Blackboard patterns and handoff format -- [Agent Coordination Skill](../skills/mnemonic-agent-coordination/SKILL.md) - Coordination patterns -- [ADR-003](adrs/adr-003-agent-coordination-blackboard.md) - Original blackboard decision -- [ADR-011](adrs/adr-011-session-scoped-blackboard.md) - Session-scoped blackboard decision diff --git a/docs/api-reference.md b/docs/api-reference.md deleted file mode 100644 index 54735ea..0000000 --- a/docs/api-reference.md +++ /dev/null @@ -1,488 +0,0 @@ -# Python API Reference - -Complete reference for Mnemonic's Python libraries. - -## Overview - -Mnemonic provides Python libraries for path resolution, memory operations, search, ontology loading, and relationship management. These libraries power the hooks and can be used to extend the system. - -## lib.paths - -Centralized path resolution for all mnemonic memory operations. - -### Classes - -#### PathScheme - -Path scheme versions for migration support. - -````python -from lib.paths import PathScheme - -PathScheme.LEGACY # Current: dual location, flat namespace -PathScheme.V2 # Target: unified user-level, project hierarchy -```` - -#### Scope - -Memory scope for organization. - -````python -from lib.paths import Scope - -Scope.USER # Cross-project memories -Scope.PROJECT # Project-specific memories -Scope.ORG # Organization-wide memories (V2 only) -```` - -#### PathContext - -Context information for path resolution. - -````python -from lib.paths import PathContext - -# Auto-detect context -context = PathContext.detect() - -# Specify scheme -context = PathContext.detect(scheme=PathScheme.V2) - -# Fields -context.org # Organization name (from git remote) -context.project # Project name (from git remote) -context.home_dir # User home directory -context.project_dir # Current project directory -context.scheme # PathScheme to use -```` - -#### PathResolver - -Central path resolver for all mnemonic operations. - -````python -from lib.paths import PathResolver, Scope - -# Initialize with auto-detected context -resolver = PathResolver() - -# Initialize with custom context -resolver = PathResolver(context=custom_context) -```` - -**Methods:** - -- **`get_memory_dir(namespace: str, scope: Scope) -> Path`** - - Get directory for storing memories. - - ````python - memory_dir = resolver.get_memory_dir("_semantic/decisions", Scope.PROJECT) - # Returns: /path/to/project/.claude/mnemonic/_semantic/decisions - ```` - -- **`get_memory_path(namespace: str, filename: str, scope: Scope) -> Path`** - - Get full path for a memory file. - - ````python - path = resolver.get_memory_path("_semantic/decisions", "slug.memory.md", Scope.PROJECT) - ```` - -- **`get_search_paths(namespace: str, include_user: bool = True, include_project: bool = True, include_org: bool = False) -> list[Path]`** - - Get ordered list of paths to search for memories. - - ````python - paths = resolver.get_search_paths("_semantic/decisions") - # Returns: [project_path, user_path] (in priority order) - ```` - -- **`get_blackboard_dir(scope: Scope) -> Path`** - - Get blackboard directory for cross-session coordination. - - ````python - blackboard = resolver.get_blackboard_dir(Scope.PROJECT) - ```` - -- **`get_ontology_paths() -> list[Path]`** - - Get ordered list of ontology file paths to check (project > user/org levels). - Does not include the bundled MIF base ontology, which is resolved separately via `lib.ontology.get_ontology_file()`. - -- **`get_all_memory_roots() -> list[Path]`** - - Get all memory root directories. - -### Convenience Functions - -````python -from lib.paths import ( - get_memory_dir, - get_search_paths, - get_blackboard_dir, - get_all_memory_roots_with_legacy, -) - -# Get memory directory (string scope) -memory_dir = get_memory_dir("_semantic/decisions", scope="project") - -# Get full memory path -path = get_memory_path("_semantic/decisions", "slug.memory.md", scope="project") - -# Get search paths -paths = get_search_paths("_semantic/decisions", include_user=True) - -# Get blackboard -blackboard = get_blackboard_dir(scope="project") - -# Get all memory roots -roots = get_all_memory_roots() -```` - -## lib.config - -Configuration management. - -### Classes - -#### MnemonicConfig - -````python -from lib.config import MnemonicConfig - -# Load configuration -config = MnemonicConfig.load() - -# Access fields -config.memory_store_path # Path to memory root directory -```` - -### Functions - -- **`get_memory_root() -> Path`** - - Get configured memory root directory. - -## lib.memory_reader - -Memory file metadata extraction. - -### Functions - -- **`get_memory_summary(path: str, max_summary: int = 300) -> dict`** - - Extract summary from memory file. - - ````python - from lib.memory_reader import get_memory_summary - - summary = get_memory_summary("/path/to/memory.memory.md") - # Returns: {"path": "...", "title": "...", "summary": "...", ...} - ```` - -- **`get_memory_metadata(path: str, max_summary: int = 300) -> Optional[dict]`** - - Extract frontmatter metadata from memory file. - - ````python - from lib.memory_reader import get_memory_metadata - - metadata = get_memory_metadata("/path/to/memory.memory.md") - # Returns: {"id": "...", "type": "...", "title": "...", ...} - ```` - -## lib.search - -Memory search and scoring. - -### Functions - -- **`search_memories(topic: str, max_results: int = 3) -> list[str]`** - - Search mnemonic for memories matching topic. - - ````python - from lib.search import search_memories - - results = search_memories("authentication", max_results=5) - # Returns: ["/path/to/memory1.memory.md", "/path/to/memory2.memory.md", ...] - ```` - -- **`find_related_memories(context: str, max_results: int = 3) -> list[str]`** - - Find memories related to given context. - -- **`find_memories_for_context(context: dict) -> list[str]`** - - Find memories for file context dictionary. - - ````python - from lib.search import find_memories_for_context - - context = { - "file_path": "src/auth/login.py", - "namespace": "_semantic/decisions", - "keywords": "authentication login" - } - results = find_memories_for_context(context) - ```` - -- **`detect_file_context(file_path: str, file_patterns: list) -> Optional[dict]`** - - Detect namespace and keywords from file path using ontology patterns. - -- **`detect_namespace_for_file(file_path: str, file_patterns: list) -> str`** - - Detect namespace for a file path. - -- **`extract_keywords_from_path(file_path: str) -> str`** - - Extract keywords from file path. - -- **`extract_topic(prompt: str) -> str`** - - Extract topic keywords from user prompt. - -- **`find_related_memories_scored(context: str, max_results: int = 10, threshold: float = 0.3) -> list[tuple[str, float]]`** - - Find related memories with relevance scores. - - ````python - from lib.search import find_related_memories_scored - - results = find_related_memories_scored("database migration", max_results=10, threshold=0.5) - # Returns: [("/path/to/memory.memory.md", 0.85), ...] - ```` - -- **`find_duplicates(namespace: str = None, threshold: float = 0.8) -> list[tuple[str, str, float]]`** - - Find potential duplicate memories. - -## lib.relationships - -Memory relationship management. - -### Functions - -- **`to_pascal(snake: str) -> str`** - - Convert snake_case to PascalCase. - -- **`to_snake(pascal: str) -> str`** - - Convert PascalCase to snake_case. - -- **`get_inverse(rel_type: str) -> str`** - - Get inverse of a relationship type. - - ````python - from lib.relationships import get_inverse - - inverse = get_inverse("supersedes") # Returns: "SupersededBy" - ```` - -- **`is_valid_type(rel_type: str) -> bool`** - - Check if relationship type is valid. - -- **`is_symmetric(rel_type: str) -> bool`** - - Check if relationship type is symmetric. - -- **`get_all_valid_types() -> set[str]`** - - Get all valid relationship types. - -- **`add_relationship(memory_path: str, rel_type: str, target_id: str, label: str = None) -> bool`** - - Add a relationship to a memory file. - - ````python - from lib.relationships import add_relationship - - success = add_relationship( - memory_path="/path/to/source.memory.md", - rel_type="relates_to", - target_id="550e8400-e29b-41d4-a716-446655440000", - label="Related decision" - ) - ```` - -- **`add_bidirectional_relationship(source_path: str, target_path: str, rel_type: str, label: str = None) -> tuple[bool, bool]`** - - Add bidirectional relationship between two memories. - -## lib.ontology - -Ontology loading and management for the bundled MIF base ontology and any project/user ontologies. - -### Functions - -- **`get_ontology_file() -> Optional[Path]`** - - Get the path to the bundled MIF base ontology used as the fallback ontology. - This does not return project or user custom ontology paths; those are - discovered via `PathResolver.get_ontology_paths()`. - -- **`load_ontology_data() -> dict`** - - Load ontology data starting from the bundled base ontology, and then apply - any project/user ontologies discovered via `PathResolver.get_ontology_paths()`. - -- **`load_file_patterns() -> list`** - - Load file discovery patterns from the effective ontology (base plus any - discovered custom ontologies). - -- **`load_content_patterns() -> dict`** - - Load content discovery patterns from the effective ontology. - -- **`load_ontology_namespaces() -> list`** - - Load namespace hierarchy from the effective ontology. - -- **`get_fallback_file_patterns() -> list`** - - Get default file patterns if no ontology exists. - -- **`get_fallback_content_patterns() -> dict`** - - Get default content patterns if no ontology exists. - -## Usage Examples - -### Complete Memory Capture Workflow - -````python -from lib.paths import PathResolver, Scope -from lib.ontology import load_ontology_data -from lib.relationships import add_relationship -import uuid -from datetime import datetime - -# Initialize resolver -resolver = PathResolver() - -# Generate memory metadata -memory_id = str(uuid.uuid4()) -timestamp = datetime.utcnow().isoformat() + "Z" - -# Get memory directory -namespace = "_semantic/decisions" -memory_dir = resolver.get_memory_dir(namespace, Scope.PROJECT) -memory_dir.mkdir(parents=True, exist_ok=True) - -# Create memory file -filename = f"{memory_id[:8]}-use-postgresql.memory.md" -memory_path = resolver.get_memory_path(namespace, filename, Scope.PROJECT) - -# Write memory with frontmatter -content = f"""--- -id: {memory_id} -type: semantic -namespace: {namespace} -created: {timestamp} -modified: {timestamp} -title: "Use PostgreSQL for storage" -tags: - - database - - architecture -provenance: - source_type: conversation - agent: claude-opus-4 - confidence: 0.95 ---- - -# Use PostgreSQL for Storage - -We decided to use PostgreSQL for our data storage needs. - -## Rationale -- Strong ACID compliance -- Excellent JSON support -- Mature ecosystem -""" - -memory_path.write_text(content) - -# Add relationship to another memory -add_relationship( - source_path=str(memory_path), - target_id="a5e46807-6883-4fb2-be45-09872ae1a994", - rel_type="relates_to", - label="Related caching decision" -) -```` - -### Search and Retrieve Memories - -````python -from lib.search import search_memories, find_related_memories_scored -from lib.memory_reader import get_memory_metadata - -# Search for memories -results = search_memories("database", max_results=5) - -# Get scored results -scored_results = find_related_memories_scored("authentication security", threshold=0.5) - -# Read metadata -for path, score in scored_results[:3]: - metadata = get_memory_metadata(path) - if metadata: - print(f"Title: {metadata['title']} (Score: {score:.2f})") - print(f"Tags: {', '.join(metadata.get('tags', []))}") -```` - -### Custom Ontology Integration - -````python -from lib.ontology import load_ontology_data, load_file_patterns -from lib.search import detect_file_context - -# Load ontology -ontology = load_ontology_data() -file_patterns = load_file_patterns() - -# Detect context for a file -context = detect_file_context("src/auth/login.py", file_patterns) -if context: - print(f"Namespace: {context['namespace']}") - print(f"Keywords: {context['keywords']}") -```` - -## Testing - -All libraries support dependency injection for testing: - -````python -from lib.paths import PathResolver, PathContext, PathScheme -from pathlib import Path - -# Create test context -test_context = PathContext( - org="test-org", - project="test-project", - home_dir=Path("/tmp/test-home"), - project_dir=Path("/tmp/test-project"), - scheme=PathScheme.V2 -) - -# Create resolver with test context -resolver = PathResolver(context=test_context) - -# Now all paths use test context -memory_dir = resolver.get_memory_dir("_semantic/decisions", Scope.PROJECT) -# Returns: /tmp/test-project/.claude/mnemonic/_semantic/decisions -```` - -## See Also - -- [Architecture](architecture.md) - System architecture overview -- [CLI Usage](cli-usage.md) - Command-line operations -- [lib/README.md](../lib/README.md) - Path resolution library details -- [Validation](validation.md) - Memory validation guide diff --git a/docs/architecture.md b/docs/architecture.md index 93148eb..3566fc9 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -64,24 +64,24 @@ Simple slash commands for direct user interaction: | `/mnemonic:setup` | Initialize and configure mnemonic | | `/mnemonic:capture` | Create a new memory | | `/mnemonic:recall` | Retrieve memories | -| `/mnemonic:search` | Full-text search | -| `/mnemonic:search-enhanced` | Agent-driven iterative search with synthesis | +| `/mnemonic:search` | Full-text search and iterative synthesis | | `/mnemonic:status` | System status | | `/mnemonic:gc` | Garbage collection | -| `/mnemonic:init` | Initialize directories | ### Skills Self-contained instruction sets that work without external dependencies: -- **mnemonic-core**: Complete memory operations -- **mnemonic-setup**: CLAUDE.md configuration -- **mnemonic-search**: Advanced search patterns -- **mnemonic-search-enhanced**: Agent-driven iterative search with synthesis -- **mnemonic-format**: MIF Level 3 templates and schema -- **mnemonic-organization**: Namespace management -- **mnemonic-blackboard**: Cross-session coordination -- **mnemonic-agent-coordination**: Multi-agent coordination patterns +- **core**: Complete memory operations +- **setup**: CLAUDE.md configuration +- **search**: Advanced search patterns and iterative synthesis +- **format**: MIF Level 3 templates and schema +- **blackboard**: Cross-session coordination and agent patterns +- **ontology**: Custom ontology support with entity types and discovery +- **custodian**: Memory health checks and maintenance +- **integrate**: Plugin integration via sentinel markers +- **qmd-setup**: Semantic search bootstrap +- **qmd-reindex**: Memory re-indexing for semantic search ### Hooks @@ -114,7 +114,7 @@ Autonomous background operations: - **mnemonic-search-subcall**: Efficient search agent for iterative query refinement (Haiku model) - **compression-worker**: Memory summarization for gc --compress (Haiku model) -Agents coordinate through the blackboard pattern. See [Agent Coordination](agent-coordination.md) for details. +Agents coordinate through the blackboard pattern. See the [blackboard skill](../skills/blackboard/SKILL.md) for details. ### Tools @@ -321,11 +321,11 @@ Agents coordinate using the blackboard pattern (ADR-003): ▲ ▲ ▲ │ │ │ ┌────────┴─────┐ ┌────────┴─────┐ ┌────────┴─────┐ -│memory-curator│ │search-subcall│ │search-enhanced│ +│memory-curator│ │search-subcall│ │compress-worker│ └──────────────┘ └──────────────┘ └───────────────┘ ``` -See [Agent Coordination](agent-coordination.md) for patterns. +See the [blackboard skill](../skills/blackboard/SKILL.md) for patterns. ## Performance Considerations @@ -338,16 +338,5 @@ See [Agent Coordination](agent-coordination.md) for patterns. ## Related Documentation -### Technical - [Validation](validation.md) - MIF schema validation -- [Agent Coordination](agent-coordination.md) - Multi-agent patterns - [ADRs](adrs/README.md) - Architectural decisions - -### Enterprise -- [Research Validation](enterprise/research-validation.md) - Academic foundations (Letta LoCoMo benchmark, Unix philosophy) -- [Compliance & Governance](enterprise/compliance-governance.md) - Audit trails, data sovereignty -- [Deployment Guide](enterprise/deployment-guide.md) - Installation and team sharing - -### Community -- [Migration from Memory Bank](archive/community/migration-from-memory-bank.md) - For existing Memory Bank users -- [Comparison](archive/community/mnemonic-vs-memory-bank.md) - Mnemonic vs Memory Bank features diff --git a/docs/architecture/CLEAN-ARCHITECTURE-BLUEPRINT.md b/docs/architecture/CLEAN-ARCHITECTURE-BLUEPRINT.md deleted file mode 100644 index 2ee4f0f..0000000 --- a/docs/architecture/CLEAN-ARCHITECTURE-BLUEPRINT.md +++ /dev/null @@ -1,752 +0,0 @@ -# Clean Architecture Blueprint: Unified Memory Path Resolution - -**Status**: Phase 1 Complete ✓ - -**Created**: 2026-01-26 - -**Goal**: Consolidate mnemonic memory storage to unified user-level storage with clean abstractions that make future changes easy. - ---- - -## Executive Summary - -This blueprint implements a **centralized path resolution system** that: - -1. Eliminates scattered path construction logic across 30+ files -2. Provides clean abstractions with a single source of truth -3. Supports migration from current (LEGACY) to target (V2) path structure -4. Makes all path logic testable and mockable -5. Enables smooth transition without breaking existing installations - -**Architecture Pattern**: Dependency Injection + Strategy Pattern + Pure Functions - ---- - -## Current State → Target State - -### Current (LEGACY Scheme) - -**User-level** (cross-project): -``` -${MNEMONIC_ROOT}/{org}/{namespace}/ -${MNEMONIC_ROOT}/default/{namespace}/ -``` - -**Project-level** (codebase-specific): -``` -./.claude/mnemonic/{namespace}/ -``` - -**Pain Points**: -- Path logic scattered in 18 Python files + 16 command files -- Each component reimplements org/project detection -- Difficult to test (hardcoded paths) -- Hard to migrate to new structure -- Dual locations create confusion - -### Target (V2 Scheme) - -**Unified user-level** (everything in home): -``` -${MNEMONIC_ROOT}/{org}/{project}/{semantic,episodic,procedural}/{sub-namespace}/ -${MNEMONIC_ROOT}/{org}/{semantic,episodic,procedural}/{sub-namespace}/ -${MNEMONIC_ROOT}/{org}/{project}/.blackboard/ -``` - -**Benefits**: -- Single location for all memories -- Clear project isolation -- Org-wide shared knowledge -- Simpler search (one root) -- Better Git versioning - ---- - -## Architecture Design - -### Component Diagram - -``` -┌─────────────────────────────────────────────────────────────┐ -│ Mnemonic System │ -├─────────────────────────────────────────────────────────────┤ -│ │ -│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ -│ │ Hooks │ │ Commands │ │ Scripts │ │ -│ │ │ │ │ │ │ │ -│ │ session_start│ │ capture │ │ migrate │ │ -│ │ user_prompt │ │ search │ │ cleanup │ │ -│ │ pre_tool_use │ │ recall │ │ │ │ -│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ -│ │ │ │ │ -│ └─────────────────┼─────────────────┘ │ -│ │ │ -│ ┌────────▼─────────┐ │ -│ │ PathResolver │ ◄───────────┐ │ -│ │ │ │ │ -│ │ - get_memory_dir │ │ │ -│ │ - get_search_paths│ │ │ -│ │ - get_blackboard │ │ │ -│ └────────┬─────────┘ │ │ -│ │ │ │ -│ ┌────────▼─────────┐ ┌────────┴──────┐ │ -│ │ PathContext │ │ PathScheme │ │ -│ │ │ │ │ │ -│ │ - org │ │ - LEGACY │ │ -│ │ - project │ │ - V2 │ │ -│ │ - home_dir │ └───────────────┘ │ -│ │ - project_dir │ │ -│ │ - scheme │ │ -│ └──────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────┘ -``` - -### Core Module: `lib/paths.py` - -**Purpose**: Single source of truth for all path construction - -**Key Classes**: - -1. **PathResolver** - Central path resolution logic - - Computes paths based on context and scheme - - No I/O operations (pure functions) - - Supports multiple schemes (LEGACY, V2) - -2. **PathContext** - Environment context - - Organization (from git remote) - - Project name (from git remote) - - Directories and scheme - - Auto-detection or explicit creation - -3. **PathScheme** - Strategy enum - - LEGACY: Current dual-location - - V2: Target unified structure - -4. **Scope** - Memory scope enum - - USER: Cross-project - - PROJECT: Project-specific - - ORG: Organization-wide (V2) - -**Design Principles**: - -1. **Pure Functions**: Path computation only, no I/O -2. **Dependency Injection**: Accept context for testing -3. **Strategy Pattern**: Switch behavior via PathScheme -4. **Fail Fast**: Type system catches errors early -5. **Explicit Over Implicit**: Clear parameter names - ---- - -## Implementation Map - -### Phase 1: Core Library ✓ (COMPLETE) - -**Files Created**: -- `/Users/AllenR1_1/Projects/zircote/mnemonic/lib/__init__.py` - Package initialization -- `/Users/AllenR1_1/Projects/zircote/mnemonic/lib/paths.py` - Core implementation (500 lines) -- `/Users/AllenR1_1/Projects/zircote/mnemonic/lib/README.md` - Library documentation -- `/Users/AllenR1_1/Projects/zircote/mnemonic/tests/unit/test_paths.py` - Unit tests (26 tests, all passing) -- `/Users/AllenR1_1/Projects/zircote/mnemonic/scripts/migrate_to_v2_paths.py` - Migration script -- `/Users/AllenR1_1/Projects/zircote/mnemonic/docs/adrs/adr-009-unified-path-resolution.md` - Architecture decision -- `/Users/AllenR1_1/Projects/zircote/mnemonic/docs/architecture/path-resolution-integration.md` - Integration guide -- `/Users/AllenR1_1/Projects/zircote/mnemonic/docs/architecture/CLEAN-ARCHITECTURE-BLUEPRINT.md` - This document - -**Test Results**: -``` -26 passed in 0.03s -- 8 tests for LEGACY scheme -- 9 tests for V2 scheme -- 9 tests for edge cases and convenience functions -``` - -**Status**: Ready for integration - -### Phase 2: Python Components Integration (Week 2) - -**Priority 1: Migration Scripts** (Low risk, not user-facing) - -Files to modify: -- `/Users/AllenR1_1/Projects/zircote/mnemonic/scripts/migrate_scope_paths.py` - - Replace hardcoded paths with `resolver.get_all_memory_roots()` - - Use `PathResolver` for computing new paths - -- `/Users/AllenR1_1/Projects/zircote/mnemonic/scripts/migrate_namespaces.py` - - Use `resolver.get_memory_dir()` for namespace paths - - Simplify org/project detection - -- `/Users/AllenR1_1/Projects/zircote/mnemonic/scripts/cleanup_memory_paths.py` - - Use `resolver.get_all_memory_roots()` for discovery - - Remove duplicated path logic - -**Priority 2: Ontology System** (Medium risk) - -Files to modify: -- `/Users/AllenR1_1/Projects/zircote/mnemonic/skills/ontology/lib/ontology_registry.py` - - Add `__init__(self, resolver: PathResolver = None)` - - Use `resolver.get_ontology_paths()` - - Remove hardcoded path construction - -- `/Users/AllenR1_1/Projects/zircote/mnemonic/skills/ontology/lib/ontology_loader.py` - - Accept resolver in constructor - - Use resolver for loading paths - -- `/Users/AllenR1_1/Projects/zircote/mnemonic/skills/ontology/lib/entity_resolver.py` - - Use resolver for entity path resolution - -**Priority 3: Hooks** (Higher risk, frequently executed) - -Files to modify: -- `/Users/AllenR1_1/Projects/zircote/mnemonic/hooks/session_start.py` - ```python - # OLD (lines 180-209): - def count_memories_by_namespace(home: Path, org: str) -> dict: - paths = [ - home / ".claude" / "mnemonic" / org, - home / ".claude" / "mnemonic" / "default", - Path.cwd() / ".claude" / "mnemonic", - ] - # Manual iteration... - - # NEW: - from lib.paths import PathResolver - - def count_memories_by_namespace(resolver: PathResolver) -> dict: - counts = {} - for root in resolver.get_all_memory_roots(): - for memory_file in root.rglob("*.memory.md"): - # Count logic... - return counts - ``` - -- `/Users/AllenR1_1/Projects/zircote/mnemonic/hooks/user_prompt_submit.py` - ```python - # OLD (line 137): - mnemonic_dir = Path.home() / ".claude" / "mnemonic" - - # NEW: - from lib.paths import PathResolver - resolver = PathResolver() - search_paths = resolver.get_search_paths(include_user=True, include_project=True) - ``` - -- `/Users/AllenR1_1/Projects/zircote/mnemonic/hooks/pre_tool_use.py` -- `/Users/AllenR1_1/Projects/zircote/mnemonic/hooks/post_tool_use.py` -- `/Users/AllenR1_1/Projects/zircote/mnemonic/hooks/stop.py` - -**Priority 4: Tests** (Refactor for testability) - -Files to modify: -- `/Users/AllenR1_1/Projects/zircote/mnemonic/.claude/tests/conftest.py` - ```python - # Add resolver fixtures - @pytest.fixture - def test_resolver(tmp_path): - """Resolver with isolated paths.""" - context = PathContext( - org="testorg", - project="testproject", - home_dir=tmp_path / "home", - project_dir=tmp_path / "project", - scheme=PathScheme.LEGACY, - ) - return PathResolver(context) - ``` - -- Update all test files to use `test_resolver` fixture -- Remove hardcoded paths from tests - -### Phase 3: Command Migration (Week 3) - -Convert Bash commands to Python for better path handling: - -**New Python Commands**: - -1. `commands/capture.py` (convert from capture.md) - ```python - from lib.paths import PathResolver, Scope - - def capture_memory(namespace: str, title: str, scope: str = "project"): - resolver = PathResolver() - scope_enum = Scope.PROJECT if scope == "project" else Scope.USER - - memory_dir = resolver.get_memory_dir(namespace, scope_enum) - memory_dir.mkdir(parents=True, exist_ok=True) - - memory_path = resolver.get_memory_path( - namespace, - f"{slug}.memory.md", - scope_enum - ) - # Write memory... - ``` - -2. `commands/search.py` (convert from search.md) - ```python - def search_memories(pattern: str, namespace: str = None): - resolver = PathResolver() - search_paths = resolver.get_search_paths(namespace) - - for path in search_paths: - subprocess.run(["rg", pattern, str(path), "--glob", "*.memory.md"]) - ``` - -3. `commands/init.py` (convert from init.md) -4. `commands/recall.py` (convert from recall.md) - -**Benefits**: -- Better error handling -- Consistent path resolution -- Easier to test -- Type safety - -### Phase 4: V2 Scheme Enablement (Week 4) - -**Configuration File** (`${MNEMONIC_ROOT}/config.yaml`): -```yaml -# Path scheme configuration -paths: - scheme: legacy # or "v2" - custom_home: null # optional override - -# Migration settings -migration: - auto_migrate: false - backup_before_migrate: true -``` - -**Migration Command**: `/mnemonic:migrate` -```bash -# Preview migration -/mnemonic:migrate --to-v2 --dry-run - -# Execute migration with backup -/mnemonic:migrate --to-v2 - -# Rollback if needed -/mnemonic:migrate --rollback /path/to/backup -``` - -**Documentation Updates**: -- Migration guide for users -- Updated architecture diagrams -- New path structure in README - -### Phase 5: Legacy Deprecation (Future - v2.0.0) - -- Set V2 as default for new installations -- Auto-migrate on first run (with user confirmation) -- Remove legacy scheme support -- Major version bump - ---- - -## Data Flow - -### Memory Capture Flow - -``` -User Request - │ - ▼ -Command/Hook - │ - ├─► PathResolver.get_memory_dir(namespace, scope) - │ │ - │ ├─► PathContext (org, project, scheme) - │ │ - │ └─► Compute path based on scheme - │ │ - │ ├─► LEGACY: ./.claude/mnemonic/{namespace} - │ └─► V2: ${MNEMONIC_ROOT}/{org}/{project}/{namespace} - │ - ├─► Create directory (mkdir -p) - │ - ├─► PathResolver.get_memory_path(namespace, filename, scope) - │ - ├─► Write memory file - │ - └─► Git commit -``` - -### Memory Search Flow - -``` -User Search - │ - ▼ -Command/Hook - │ - ├─► PathResolver.get_search_paths(namespace, filters) - │ │ - │ ├─► PathContext (org, project, scheme) - │ │ - │ └─► Compute paths based on scheme - │ │ - │ ├─► LEGACY: [project, org, default] - │ └─► V2: [project, org, default] - │ - ├─► Filter existing paths - │ - ├─► For each path: - │ └─► rg -i {pattern} {path} --glob "*.memory.md" - │ - └─► Aggregate results -``` - -### Migration Flow - -``` -Migration Command - │ - ├─► Create MigrationManager(scheme=V2) - │ - ├─► Analyze current structure - │ │ - │ ├─► Legacy resolver gets all roots - │ ├─► For each memory file: - │ │ ├─► Extract namespace - │ │ ├─► Determine scope - │ │ └─► Compute V2 destination - │ │ - │ └─► Create MigrationPlan - │ - ├─► Create backup (with rollback info) - │ - ├─► Execute migration - │ │ - │ └─► For each file: - │ ├─► Copy to V2 location - │ └─► Track success/failure - │ - ├─► Cleanup legacy directories (optional) - │ - └─► Git commit changes -``` - ---- - -## Critical Implementation Details - -### 1. Error Handling - -**PathResolver never throws** - returns computed paths even if they don't exist: - -```python -# Resolver just computes - always succeeds -path = resolver.get_memory_dir("_semantic/decisions") - -# Caller handles existence -if not path.exists(): - path.mkdir(parents=True, exist_ok=True) -``` - -**Why**: Separation of concerns - path computation vs. file operations - -### 2. State Management - -**Resolvers are stateless** - can be created/discarded freely: - -```python -# OK to create multiple times -resolver1 = PathResolver() -resolver2 = PathResolver() - -# OK to cache if needed -class Manager: - def __init__(self): - self._resolver = PathResolver() -``` - -**Why**: Simpler reasoning, thread-safe, easier to test - -### 3. Testing Strategy - -**Unit tests** - Use mocked context: -```python -def test_path_resolution(): - context = PathContext( - org="testorg", - project="testproject", - home_dir=Path("/tmp/home"), - project_dir=Path("/tmp/project"), - scheme=PathScheme.LEGACY, - ) - resolver = PathResolver(context) - # Test pure logic without file system -``` - -**Integration tests** - Use tmp_path: -```python -def test_memory_capture(tmp_path): - context = PathContext(..., home_dir=tmp_path) - resolver = PathResolver(context) - # Test with real file operations in isolation -``` - -### 4. Performance Considerations - -**Lazy evaluation** - Don't create resolvers at module level: -```python -# BAD -_resolver = PathResolver() # Created on import - -# GOOD -def get_resolver(): - return PathResolver() # Created when needed -``` - -**Caching** - Add if profiling shows benefit: -```python -from functools import lru_cache - -class PathResolver: - @lru_cache(maxsize=128) - def get_memory_dir(self, namespace: str, scope: Scope) -> Path: - # Implementation... -``` - -### 5. Security Considerations - -**Path validation** - Prevent directory traversal: -```python -def get_memory_path(self, namespace: str, filename: str, scope: Scope) -> Path: - # Ensure filename doesn't contain path separators - if "/" in filename or "\\" in filename: - raise ValueError(f"Invalid filename: {filename}") - - directory = self.get_memory_dir(namespace, scope) - return directory / filename -``` - -**Git safety** - Never auto-commit without user awareness: -```python -def commit_changes(self, dry_run: bool = False): - if dry_run: - print("[DRY RUN] Would commit changes") - return - - # Require explicit user action - # ... -``` - ---- - -## Build Sequence - -### ✓ Phase 1: Foundation (Complete) - -- [x] Design architecture and interfaces -- [x] Create `lib/paths.py` with full implementation -- [x] Create comprehensive unit tests (26 tests) -- [x] Write library documentation -- [x] Create migration script -- [x] Document architecture decisions (ADR-009) -- [x] Write integration guide - -**Deliverables**: -- Fully functional path resolution library -- 100% test coverage -- Complete documentation -- Ready for integration - -### Phase 2: Integration Checklist - -Migration Scripts: -- [ ] Update `migrate_scope_paths.py` -- [ ] Update `migrate_namespaces.py` -- [ ] Update `cleanup_memory_paths.py` -- [ ] Test migration scripts - -Ontology System: -- [ ] Update `ontology_registry.py` -- [ ] Update `ontology_loader.py` -- [ ] Update `entity_resolver.py` -- [ ] Test ontology integration - -Hooks: -- [ ] Update `session_start.py` -- [ ] Update `user_prompt_submit.py` -- [ ] Update `pre_tool_use.py` -- [ ] Update `post_tool_use.py` -- [ ] Update `stop.py` -- [ ] Test all hooks - -Tests: -- [ ] Add resolver fixtures to `conftest.py` -- [ ] Update all test files -- [ ] Verify 100% pass rate - -### Phase 3: Commands Checklist - -- [ ] Convert `capture.md` to `capture.py` -- [ ] Convert `search.md` to `search.py` -- [ ] Convert `init.md` to `init.py` -- [ ] Convert `recall.md` to `recall.py` -- [ ] Update command manifests -- [ ] Test all commands - -### Phase 4: V2 Enablement Checklist - -- [ ] Add config file support -- [ ] Create `/mnemonic:migrate` command -- [ ] Update all documentation -- [ ] Create migration guide -- [ ] Add rollback capability -- [ ] Beta test with real data - ---- - -## Trade-offs Analysis - -### Complexity vs Flexibility - -**Trade-off**: More upfront code for long-term flexibility - -**Accepted**: -- 500 lines of library code + tests -- Learning curve for new abstraction -- Migration work across 30+ files - -**Benefit**: -- Future path changes trivial (1 file vs 30+) -- Testable path logic -- Support multiple schemes -- Clear upgrade path - -**Verdict**: Worth it for maintainability - -### Purity vs Pragmatism - -**Trade-off**: Pure path computation vs convenience with I/O - -**Accepted**: Keep resolver pure -- No file system checks in core methods -- No automatic directory creation -- Caller handles I/O - -**Benefit**: -- Easier to test (no mocking file system) -- Clear separation of concerns -- No hidden side effects - -**Verdict**: Pure functions easier to reason about - -### Python vs Bash - -**Trade-off**: Convert commands to Python vs keep Bash - -**Accepted**: Convert to Python in Phase 3 -- Commands become Python modules -- Bash retained for simple operations - -**Benefit**: -- Better error handling -- Type safety -- Testability -- Consistent with library - -**Verdict**: Python better for complex logic - ---- - -## Success Metrics - -### Code Quality Metrics - -- [x] Path resolution centralized in single module -- [x] 26 unit tests with 100% pass rate -- [x] Type hints on all public methods -- [x] Comprehensive docstrings -- [ ] Zero hardcoded paths in new code (after Phase 2-3) -- [ ] All Python components use resolver (after Phase 2) - -### Testing Metrics - -- [x] Unit tests use isolated paths (test_paths.py) -- [x] No file system dependencies in unit tests -- [ ] Integration tests cover both schemes (Phase 2) -- [ ] Migration tests verify data integrity (Phase 4) - -### Documentation Metrics - -- [x] ADR documenting architecture decision -- [x] Integration guide for each component type -- [x] Library API documentation -- [x] Migration script documentation -- [ ] User migration guide (Phase 4) -- [ ] Video walkthrough (Phase 5) - -### User Experience Metrics - -- [ ] Zero breaking changes during migration -- [ ] Migration completes successfully (Phase 4) -- [ ] Rollback works if migration fails (Phase 4) -- [ ] Performance same or better (Phase 5) - ---- - -## Related Documents - -### Core Implementation -- [lib/paths.py](../../lib/paths.py) - Path resolution library -- [tests/unit/test_paths.py](../../tests/unit/test_paths.py) - Unit tests -- [lib/README.md](../../lib/README.md) - Library documentation - -### Architecture & Planning -- [ADR-009](../adrs/adr-009-unified-path-resolution.md) - Architecture decision record -- [Integration Guide](./path-resolution-integration.md) - Component integration guide - -### Migration -- [migrate_to_v2_paths.py](../../scripts/migrate_to_v2_paths.py) - Migration script - ---- - -## Next Steps - -### Immediate (Phase 1 Complete ✓) - -This phase is COMPLETE. All deliverables created and tested. - -### Week 2 (Phase 2) - -1. Start with migration scripts (lowest risk) -2. Update ontology system -3. Integrate hooks one by one -4. Update tests continuously - -### Week 3 (Phase 3) - -1. Convert capture command -2. Convert search command -3. Convert remaining commands -4. Update command manifests - -### Week 4 (Phase 4) - -1. Add config file support -2. Create migration command -3. Document migration process -4. Beta test with volunteers - ---- - -## Conclusion - -Phase 1 delivers a **production-ready path resolution library** with: - -- ✓ Clean architecture with dependency injection -- ✓ Support for both LEGACY and V2 schemes -- ✓ Comprehensive test coverage (26 tests) -- ✓ Complete documentation -- ✓ Migration tooling ready - -The library provides a **single source of truth** for all path operations and enables **smooth migration** to the unified V2 structure. - -**Next**: Begin Phase 2 integration, starting with low-risk migration scripts. - ---- - -**Blueprint Version**: 1.0 -**Last Updated**: 2026-01-26 -**Status**: Phase 1 Complete ✓ diff --git a/docs/architecture/path-resolution-integration.md b/docs/architecture/path-resolution-integration.md deleted file mode 100644 index 66cad8d..0000000 --- a/docs/architecture/path-resolution-integration.md +++ /dev/null @@ -1,465 +0,0 @@ -# Path Resolution Integration Guide - -This guide shows how each component integrates with the centralized path resolution library (`lib/paths.py`). - -## Integration Pattern - -All components that work with file paths should: - -1. Import the path resolution library -2. Create a resolver (or use convenience functions) -3. Use resolver methods instead of manual path construction -4. Never hardcode path patterns - -## Component Integration Examples - -### 1. Hooks Integration - -#### Before (session_start.py) - -```python -# OLD: Manual path construction scattered throughout -def count_memories_by_namespace(home: Path, org: str) -> dict: - paths = [ - home / ".claude" / "mnemonic" / org, - home / ".claude" / "mnemonic" / "default", - Path.cwd() / ".claude" / "mnemonic", - ] - # ... -``` - -#### After (session_start.py) - -```python -from lib.paths import PathResolver, Scope - -def count_memories_by_namespace(resolver: PathResolver) -> dict: - """Count memories using centralized path resolution.""" - counts = {} - - # Get all memory roots automatically - for root in resolver.get_all_memory_roots(): - for memory_file in root.rglob("*.memory.md"): - # Count logic... - pass - - return counts - -def main(): - resolver = PathResolver() - counts = count_memories_by_namespace(resolver) - # ... -``` - -### 2. Commands Integration - -#### Before (capture.md) - -```bash -# OLD: Bash-based path construction -if [ "$SCOPE" = "project" ]; then - MEMORY_DIR="$MNEMONIC_ROOT/${NAMESPACE}" -else - MEMORY_DIR="$MNEMONIC_ROOT/${ORG}/${NAMESPACE}" -fi -``` - -#### After (capture.md) - -Commands can call a Python helper that uses the library: - -```bash -# NEW: Use Python helper with centralized paths -MEMORY_DIR=$(python3 -c " -from lib.paths import get_memory_dir -print(get_memory_dir('$NAMESPACE', '$SCOPE')) -") -``` - -Or better yet, convert capture to a Python command: - -```python -# commands/capture.py -from lib.paths import PathResolver, Scope - -def capture_memory(namespace: str, title: str, scope: str = "project"): - resolver = PathResolver() - scope_enum = Scope.PROJECT if scope == "project" else Scope.USER - - memory_dir = resolver.get_memory_dir(namespace, scope_enum) - memory_dir.mkdir(parents=True, exist_ok=True) - - memory_path = resolver.get_memory_path( - namespace, - f"{slug}.memory.md", - scope_enum - ) - - # Write memory file... -``` - -### 3. Search Integration - -#### Before (search.md) - -```bash -# OLD: Manual path construction -SEARCH_PATHS="$MNEMONIC_ROOT/$ORG $MNEMONIC_ROOT" -``` - -#### After (search.md) - -```bash -# NEW: Use Python helper for search paths -SEARCH_PATHS=$(python3 -c " -from lib.paths import get_search_paths -paths = get_search_paths(namespace='$NAMESPACE', include_user=True, include_project=True) -print(' '.join(str(p) for p in paths)) -") - -rg -i "$PATTERN" $SEARCH_PATHS --glob '*.memory.md' -``` - -### 4. Ontology Registry Integration - -#### Before (ontology_registry.py) - -```python -# OLD: Hardcoded paths -def get_ontology_paths(): - return [ - Path.cwd() / ".claude" / "mnemonic" / "ontology.yaml", - Path.home() / ".claude" / "mnemonic" / "ontology.yaml", - ] -``` - -#### After (ontology_registry.py) - -```python -from lib.paths import PathResolver - -class OntologyRegistry: - def __init__(self, resolver: PathResolver = None): - self.resolver = resolver or PathResolver() - - def load_ontologies(self): - """Load ontologies from all configured paths.""" - for ontology_path in self.resolver.get_ontology_paths(): - if ontology_path.exists(): - yield self._load_ontology_file(ontology_path) -``` - -### 5. Migration Scripts Integration - -#### Before (migrate_scope_paths.py) - -```python -# OLD: Hardcoded paths -paths = [ - Path.home() / ".claude" / "mnemonic", - Path.cwd() / ".claude" / "mnemonic", -] -``` - -#### After (migrate_scope_paths.py) - -```python -from lib.paths import PathResolver - -def migrate_to_v2_scheme(): - """Migrate from legacy to V2 path scheme.""" - # Use legacy resolver to find old paths - legacy_resolver = PathResolver() # defaults to LEGACY scheme - - # Get all memory roots from legacy scheme - for root in legacy_resolver.get_all_memory_roots(): - # Process memories... - pass - - # Use V2 resolver to compute new paths - from lib.paths import PathContext, PathScheme - context = PathContext.detect(scheme=PathScheme.V2) - v2_resolver = PathResolver(context) - - # Move files to new locations - # ... -``` - -### 6. Test Integration - -#### Test Setup - -```python -# tests/conftest.py -import pytest -from pathlib import Path -from lib.paths import PathResolver, PathContext, PathScheme - -@pytest.fixture -def test_resolver(tmp_path): - """Create a test resolver with isolated paths.""" - context = PathContext( - org="testorg", - project="testproject", - home_dir=tmp_path / "home", - project_dir=tmp_path / "project", - scheme=PathScheme.LEGACY, - ) - return PathResolver(context) - -@pytest.fixture -def v2_test_resolver(tmp_path): - """Create a V2 test resolver.""" - context = PathContext( - org="testorg", - project="testproject", - home_dir=tmp_path / "home", - project_dir=tmp_path / "project", - scheme=PathScheme.V2, - ) - return PathResolver(context) -``` - -#### Using Test Resolver - -```python -def test_memory_capture(test_resolver): - """Test memory capture with isolated paths.""" - memory_dir = test_resolver.get_memory_dir("_semantic/decisions", Scope.PROJECT) - memory_dir.mkdir(parents=True) - - memory_path = test_resolver.get_memory_path( - "_semantic/decisions", - "test.memory.md", - Scope.PROJECT - ) - - # Test memory creation... - assert memory_path.exists() -``` - -## Dependency Injection Pattern - -For better testability, components should accept a resolver as a parameter: - -```python -from lib.paths import PathResolver - -class MemoryManager: - def __init__(self, resolver: PathResolver = None): - """Initialize with optional resolver for testing.""" - self.resolver = resolver or PathResolver() - - def save_memory(self, namespace: str, content: str): - memory_dir = self.resolver.get_memory_dir(namespace) - # Save logic... -``` - -This enables easy testing: - -```python -def test_memory_manager(test_resolver): - manager = MemoryManager(resolver=test_resolver) - manager.save_memory("_semantic/decisions", "test content") - # Assertions... -``` - -## Migration Strategy - -### Phase 1: Add Library (Week 1) - -1. Create `lib/paths.py` with full implementation -2. Create comprehensive unit tests -3. Add integration documentation -4. No breaking changes - library is additive - -**Status**: Complete (this commit) - -### Phase 2: Integrate Python Components (Week 2) - -Priority order (least risk to most): - -1. **Migration scripts** (low risk, not user-facing) - - `scripts/migrate_scope_paths.py` - - `scripts/migrate_namespaces.py` - - `scripts/cleanup_memory_paths.py` - -2. **New components** (medium risk, limited usage) - - `skills/ontology/lib/ontology_registry.py` - - `skills/ontology/lib/ontology_loader.py` - -3. **Hooks** (higher risk, frequently executed) - - `hooks/session_start.py` - - `hooks/user_prompt_submit.py` - - `hooks/pre_tool_use.py` - - `hooks/post_tool_use.py` - - `hooks/stop.py` - -4. **Tests** (refactor to use test resolvers) - - `.claude/tests/conftest.py` - - All test files - -### Phase 3: Convert Commands to Python (Week 3) - -Convert Bash commands to Python for better path handling: - -1. `commands/capture.py` (convert from capture.md) -2. `commands/search.py` (convert from search.md) -3. `commands/init.py` (convert from init.md) -4. `commands/recall.py` (convert from recall.md) - -### Phase 4: Enable V2 Scheme (Week 4) - -1. Add configuration option for path scheme -2. Create migration command: `/mnemonic:migrate --to-v2` -3. Update documentation -4. Provide rollback capability - -### Phase 5: Deprecate Legacy (Future) - -1. Set V2 as default for new installations -2. Auto-migrate on first run (with user confirmation) -3. Remove legacy scheme support (major version bump) - -## Configuration - -Add path scheme configuration to `.claude/mnemonic/config.yaml`: - -```yaml -# Path scheme configuration -paths: - scheme: legacy # or "v2" - custom_home: null # optional override for testing - -# Migration settings -migration: - auto_migrate: false - backup_before_migrate: true -``` - -Load config in PathContext: - -```python -@classmethod -def detect(cls, config_path: Optional[Path] = None) -> "PathContext": - """Detect context from environment and config.""" - scheme = PathScheme.LEGACY # default - - if config_path and config_path.exists(): - with open(config_path) as f: - config = yaml.safe_load(f) - scheme_str = config.get("paths", {}).get("scheme", "legacy") - scheme = PathScheme.V2 if scheme_str == "v2" else PathScheme.LEGACY - - return cls( - org=_detect_org(), - project=_detect_project(), - home_dir=Path.home(), - project_dir=Path.cwd(), - scheme=scheme - ) -``` - -## Benefits Summary - -### Developer Experience - -- **Single source of truth**: All path logic in one place -- **Type safety**: Python type hints catch errors early -- **Easy testing**: Dependency injection enables isolated tests -- **Clear interfaces**: Explicit methods for each use case - -### Maintenance - -- **Easier refactoring**: Change paths once, affects all components -- **Migration support**: Support multiple schemes during transition -- **Documentation**: Self-documenting code with clear method names -- **Debugging**: Centralized logging and error handling - -### Future-Proofing - -- **Extensible**: Easy to add new path schemes or configurations -- **Configurable**: Support user preferences and environment overrides -- **Backward compatible**: Legacy scheme support during migration -- **Clean abstractions**: Future changes isolated to one module - -## Performance Considerations - -### Caching - -For frequently accessed paths, consider caching: - -```python -from functools import lru_cache - -class PathResolver: - @lru_cache(maxsize=128) - def get_memory_dir(self, namespace: str, scope: Scope) -> Path: - # Implementation... -``` - -### Lazy Evaluation - -Don't create resolvers unnecessarily: - -```python -# BAD: Creates resolver on module import -_resolver = PathResolver() - -# GOOD: Create resolver when needed -def get_resolver() -> PathResolver: - return PathResolver() -``` - -### File System Operations - -The resolver only computes paths - it doesn't check existence by default. Use `get_search_paths()` which filters non-existent paths only when needed for search operations. - -## Troubleshooting - -### Common Integration Issues - -1. **Import errors**: Ensure `lib/` is in Python path -2. **Test isolation**: Always use fixtures with tmp_path -3. **Circular imports**: Import paths in functions, not at module level if needed -4. **Path scheme confusion**: Explicitly pass scheme in tests - -### Debugging - -Add logging to resolver: - -```python -import logging - -logger = logging.getLogger(__name__) - -class PathResolver: - def get_memory_dir(self, namespace: str, scope: Scope) -> Path: - path = self._get_memory_dir_impl(namespace, scope) - logger.debug(f"Resolved {namespace}/{scope} -> {path}") - return path -``` - -## Questions & Decisions - -### Q: Should we support custom path schemes? - -**Decision**: Not in v1. Keep it simple with LEGACY and V2. Custom schemes can be added later if needed. - -### Q: How do we handle Windows paths? - -**Decision**: Python's `pathlib.Path` handles cross-platform paths automatically. No special handling needed. - -### Q: What about symlinks? - -**Decision**: Follow symlinks by default. Use `Path.resolve()` if absolute resolution needed. - -### Q: Should paths be validated? - -**Decision**: No validation in resolver - keep it pure path computation. Validation happens at usage sites (create directory, open file, etc). - -## Related Documents - -- [lib/paths.py](../../lib/paths.py) - Core implementation -- [tests/unit/test_paths.py](../../tests/unit/test_paths.py) - Unit tests -- [ADR-009: Unified Path Resolution](../adrs/adr-009-unified-path-resolution.md) - Architecture decision record diff --git a/docs/archive/community/CONTRIBUTING-COMMUNITY.md b/docs/archive/community/CONTRIBUTING-COMMUNITY.md deleted file mode 100644 index 57345ab..0000000 --- a/docs/archive/community/CONTRIBUTING-COMMUNITY.md +++ /dev/null @@ -1,229 +0,0 @@ -# Contributing to the Mnemonic Community - -How to share your experience, stories, and improvements with the community. - ---- - -## Ways to Contribute - -### Share Your Story - -Help others by sharing your experience: - -1. **Adoption stories** - How you're using mnemonic -2. **Migration guides** - Specific setups you've migrated from -3. **Tips and tricks** - Patterns you've discovered -4. **Integration guides** - Tool-specific configurations - -### Improve Documentation - -Found something unclear? Help us improve: - -1. **Fix typos and errors** - Small improvements matter -2. **Add examples** - Real-world usage examples -3. **Clarify explanations** - If something confused you, others may struggle too -4. **Translate** - Help make mnemonic accessible globally - -### Report Issues - -Encountered a problem? Let us know: - -1. **Bug reports** - Something not working as expected -2. **Feature requests** - Ideas for improvement -3. **Compatibility issues** - Problems with specific tools or setups - ---- - -## Submitting an Adoption Story - -### Option 1: Pull Request - -1. Fork the repository -2. Create a new branch: - ```bash - git checkout -b story/your-story-name - ``` -3. Add your story to `docs/community/adoption-stories.md`: - ```markdown - ### [Your Title] - - **Author:** Your Name / Anonymous - **Setup:** [Tool(s) used, team size, context] - **Migrated from:** [Memory Bank / Other / None] - - #### Challenge - [What problem were you trying to solve?] - - #### Solution - [How did mnemonic help?] - - #### Results - [What changed? Be specific where possible.] - - #### Tips - [What would you tell others adopting mnemonic?] - ``` -4. Commit and push: - ```bash - git commit -m "Add adoption story: [Your Title]" - git push origin story/your-story-name - ``` -5. Open a Pull Request - -### Option 2: GitHub Discussion - -Don't want to open a PR? Share your story in [GitHub Discussions](https://github.com/zircote/mnemonic/discussions). - -1. Go to the Discussions tab -2. Create a new discussion in the "Show and tell" category -3. Share your experience - -We may reach out to feature your story in the docs (with permission). - -### Option 3: Issue - -Open an [issue](https://github.com/zircote/mnemonic/issues) with the "story" label. - ---- - -## Documentation Improvements - -### Style Guide - -When contributing documentation: - -- **Be concise** - Developers appreciate brevity -- **Show, don't tell** - Use code examples -- **Test your examples** - Make sure they work -- **Use consistent formatting** - Follow existing patterns - -### File Structure - -``` -docs/ -├── community/ # Community-focused docs (you are here) -│ ├── README.md -│ ├── quickstart-memory-bank.md -│ ├── migration-from-memory-bank.md -│ ├── mnemonic-vs-memory-bank.md -│ ├── adoption-stories.md -│ └── CONTRIBUTING-COMMUNITY.md -├── enterprise/ # Enterprise-focused docs -├── integrations/ # Tool-specific guides -└── ... -``` - -### Pull Request Process - -1. Fork the repository -2. Create a feature branch: - ```bash - git checkout -b docs/your-improvement - ``` -3. Make your changes -4. Test locally (if applicable) -5. Commit with clear message: - ```bash - git commit -m "docs: clarify migration process for Cursor users" - ``` -6. Push and open PR - ---- - -## Bug Reports and Feature Requests - -### Bug Reports - -Use the [issue tracker](https://github.com/zircote/mnemonic/issues) with this template: - -```markdown -**Description** -A clear description of the bug. - -**Steps to Reproduce** -1. Run this command... -2. Then do this... -3. See error - -**Expected Behavior** -What should have happened. - -**Actual Behavior** -What actually happened. - -**Environment** -- OS: [e.g., macOS 14.2] -- Claude Code version: [e.g., 1.0.0] -- Mnemonic version: [e.g., 1.0.0] - -**Additional Context** -Any other relevant information. -``` - -### Feature Requests - -```markdown -**Problem Statement** -What problem does this feature solve? - -**Proposed Solution** -What would you like to happen? - -**Alternatives Considered** -Any alternative solutions you've considered? - -**Additional Context** -Any other relevant information. -``` - ---- - -## Community Guidelines - -### Be Respectful - -- Treat everyone with respect -- Be patient with newcomers -- Give constructive feedback - -### Be Helpful - -- Share your knowledge -- Answer questions when you can -- Point to relevant resources - -### Be Honest - -- Share both successes and failures -- Acknowledge limitations -- Credit others' contributions - ---- - -## Recognition - -We appreciate all contributions! Contributors are recognized in: - -- **CONTRIBUTORS.md** - All contributors -- **Release notes** - Significant contributions -- **Adoption stories** - Featured community members - ---- - -## Questions? - -- **GitHub Issues**: [Ask questions](https://github.com/zircote/mnemonic/issues) -- **Discussions**: [Community forum](https://github.com/zircote/mnemonic/discussions) - ---- - -## Quick Links - -| Resource | Description | -|----------|-------------| -| [Issues](https://github.com/zircote/mnemonic/issues) | Report bugs, request features | -| [Discussions](https://github.com/zircote/mnemonic/discussions) | Ask questions, share ideas | -| [Pull Requests](https://github.com/zircote/mnemonic/pulls) | Contribute code and docs | -| [Main CONTRIBUTING](../../CONTRIBUTING.md) | Full contribution guide | - -[← Back to Community](./README.md) diff --git a/docs/archive/community/README.md b/docs/archive/community/README.md deleted file mode 100644 index 774aa2b..0000000 --- a/docs/archive/community/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# Mnemonic Community - -Welcome to the mnemonic community! Whether you're migrating from a Memory Bank setup, exploring mnemonic for the first time, or looking to share your experience, you're in the right place. - ---- - -## For Memory Bank Users - -Already using markdown files for AI memory? You discovered what research confirms: filesystem-based memory works. - -Mnemonic formalizes your approach with: -- **Standardized format** (MIF Level 3) for cross-tool compatibility -- **Schema validation** to catch errors early -- **Multi-tool support** (9+ AI coding assistants) -- **Research validation** (74% accuracy benchmark) - -Get started: -- [Quick Start for Memory Bank Users](./quickstart-memory-bank.md) - 5-minute conversion -- [Full Migration Guide](./migration-from-memory-bank.md) - Complete walkthrough -- [Comparison](./mnemonic-vs-memory-bank.md) - Side-by-side differences - ---- - -## Community Resources - -### Adoption Stories - -See how others are using mnemonic: - -[→ Read Adoption Stories](./adoption-stories.md) - -Want to share your experience? We'd love to hear from you! - -[→ How to Contribute](./CONTRIBUTING-COMMUNITY.md) - ---- - -## Getting Help - -- **GitHub Issues**: [Report bugs or request features](https://github.com/zircote/mnemonic/issues) -- **Discussions**: [Ask questions and share ideas](https://github.com/zircote/mnemonic/discussions) -- **Documentation**: [Full reference](../../README.md) - ---- - -## Quick Links - -| Resource | Description | -|----------|-------------| -| [Quick Start](./quickstart-memory-bank.md) | 5-minute setup for Memory Bank users | -| [Migration Guide](./migration-from-memory-bank.md) | Complete migration walkthrough | -| [Comparison](./mnemonic-vs-memory-bank.md) | Feature comparison | -| [Adoption Stories](./adoption-stories.md) | Community experiences | -| [Contributing](./CONTRIBUTING-COMMUNITY.md) | How to contribute | - ---- - -## Why Community Matters - -Mnemonic exists because the community showed the need. Memory Bank projects in Cursor and Windsurf forums validated that: - -1. Developers want persistent AI memory -2. Filesystem-based approaches work well -3. Markdown is the right format -4. Cross-tool compatibility matters - -Mnemonic builds on this foundation with standardization, validation, and multi-tool support. - ---- - -## Navigation - -[← Back to Main Documentation](../../README.md) diff --git a/docs/archive/community/adoption-stories.md b/docs/archive/community/adoption-stories.md deleted file mode 100644 index 22c04d6..0000000 --- a/docs/archive/community/adoption-stories.md +++ /dev/null @@ -1,119 +0,0 @@ -# Adoption Stories - -Real-world experiences from developers and teams using mnemonic. - ---- - -## Share Your Story - -We'd love to hear how you're using mnemonic! See [How to Contribute](./CONTRIBUTING-COMMUNITY.md) to add your story. - ---- - -## Stories - -### Coming Soon - -This section will feature stories from early adopters. Check back soon or [submit your story](./CONTRIBUTING-COMMUNITY.md). - ---- - -## Template - -Here's the format we use for adoption stories: - -```markdown -### [Your Title] - -**Author:** Your Name / Anonymous -**Setup:** [Tool(s) used, team size, context] -**Migrated from:** [Memory Bank / Other / None] - -#### Challenge - -What problem were you trying to solve? - -#### Solution - -How did mnemonic help? - -#### Results - -What changed? Be specific where possible. - -#### Tips - -What would you tell others adopting mnemonic? -``` - ---- - -## Example Story - -### From Cursor Memory Bank to Multi-Tool Workflow - -**Author:** Anonymous -**Setup:** Solo developer, Cursor + Claude Code, web development -**Migrated from:** Cursor Memory Bank - -#### Challenge - -I had built up a great Memory Bank setup in Cursor over 6 months. Hundreds of patterns, decisions, and learnings. But I wanted to try Claude Code for some tasks, and starting from scratch felt wasteful. - -#### Solution - -Used the migration tool to convert my Memory Bank files to MIF format. Now the same memories work in both tools. I use Cursor for frontend work and Claude Code for backend—same context everywhere. - -#### Results - -- Migration took about 20 minutes -- Zero memory loss -- Now using 3 different AI tools with the same knowledge base -- Validation caught 2 malformed memories I hadn't noticed - -#### Tips - -- Don't try to migrate everything at once—start with your most-used decisions -- The validation tool is your friend—run it after migration -- Keep your old Memory Bank files around for a few weeks, just in case - ---- - -## Why Stories Matter - -Adoption stories help the community understand: -- Real-world use cases -- Migration challenges and solutions -- Team coordination patterns -- Unexpected benefits - -Your experience could help someone facing the same challenges. - ---- - -## Categories - -We're looking for stories in these areas: - -### Migration Stories -How did you move from Memory Bank or another system? - -### Team Adoption -How did your team roll out mnemonic? What worked? - -### Cross-Tool Workflows -How do you use mnemonic across multiple AI tools? - -### Enterprise Use -How does mnemonic fit into larger organizational contexts? - -### Creative Uses -Unexpected or creative applications of the memory system? - ---- - -## Submit Your Story - -Ready to share? See [How to Contribute](./CONTRIBUTING-COMMUNITY.md). - -[← Back to Community](./README.md) diff --git a/docs/archive/community/migration-from-memory-bank.md b/docs/archive/community/migration-from-memory-bank.md deleted file mode 100644 index 76b6f83..0000000 --- a/docs/archive/community/migration-from-memory-bank.md +++ /dev/null @@ -1,365 +0,0 @@ -# Migration Guide: Memory Bank to Mnemonic - -Complete walkthrough for converting your Memory Bank setup to mnemonic. - ---- - -## Overview - -This guide helps you migrate from a Memory Bank-style markdown memory setup to mnemonic's MIF Level 3 format. The migration preserves your content while adding structure and validation. - -**Estimated time**: 15-30 minutes depending on memory volume. - ---- - -## Before You Start - -### Prerequisites - -- Existing Memory Bank files (markdown) -- Claude Code installed -- Git (recommended for backup) - -### Backup Your Data - -```bash -# Create backup of existing memories -tar -czf memory-bank-backup-$(date +%Y%m%d).tar.gz ~/your-memory-bank/ - -# Or commit to git -cd ~/your-memory-bank -git add -A && git commit -m "Backup before mnemonic migration" -``` - ---- - -## Migration Methods - -### Method 1: Automated Migration Tool - -The fastest approach for bulk conversion. - -```bash -# Install mnemonic first -git clone https://github.com/zircote/mnemonic.git ~/tools/mnemonic -claude settings plugins add ~/tools/mnemonic - -# Run migration tool -./tools/migrate-memory-bank \ - --source ~/your-memory-bank \ - --target ${MNEMONIC_ROOT}/default \ - --namespace learnings -``` - -**Options:** -- `--source`: Path to existing Memory Bank -- `--target`: Mnemonic directory (usually `${MNEMONIC_ROOT}/default`) -- `--namespace`: Default namespace for migrated files -- `--dry-run`: Preview without changes -- `--preserve-dates`: Use file modification dates for timestamps - -### Method 2: Manual Conversion - -For careful, selective migration. - -#### Step 1: Analyze Your Existing Structure - -```bash -# See what you have -find ~/your-memory-bank -name "*.md" -type f - -# Count by directory -find ~/your-memory-bank -name "*.md" | \ - sed 's|/[^/]*$||' | sort | uniq -c -``` - -#### Step 2: Map to Namespaces - -| Your Category | Mnemonic Namespace | -|---------------|-------------------| -| Decisions, ADRs | `decisions/user` | -| Learnings, TILs | `learnings/user` | -| Patterns, conventions | `patterns/user` | -| Bugs, issues, blockers | `blockers/user` | -| Project context | `context/user` | -| API notes | `apis/user` | -| Security notes | `security/user` | -| Testing notes | `testing/user` | -| Session logs, events | `episodic/user` | - -#### Step 3: Convert Each File - -For each memory file: - -1. **Generate UUID and timestamps**: -```bash -UUID=$(uuidgen | tr '[:upper:]' '[:lower:]') -DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") -``` - -2. **Determine memory type**: - - `semantic` - Facts, decisions, specifications - - `episodic` - Events, debugging sessions, incidents - - `procedural` - Workflows, patterns, how-tos - -3. **Create MIF-compliant file**: - -```bash -# Example: Converting a decision -cat > ${MNEMONIC_ROOT}/default/decisions/user/${UUID}-use-jwt.memory.md << 'EOF' ---- -id: YOUR-UUID-HERE -type: semantic -namespace: decisions/user -created: 2026-01-23T10:30:00Z -modified: 2026-01-23T10:30:00Z -title: "Use JWT for Authentication" -tags: - - authentication - - security -temporal: - valid_from: 2026-01-23T10:30:00Z - recorded_at: 2026-01-23T10:30:00Z -provenance: - source_type: migration - agent: manual - confidence: 0.9 ---- - -# Use JWT for Authentication - -[Your original content here] -EOF -``` - -### Method 3: Incremental Migration - -Migrate files as you use them. - -1. **Keep both systems running**: -```bash -# Mnemonic for new memories -${MNEMONIC_ROOT}/ - -# Original for reference -~/your-memory-bank/ -``` - -2. **When you reference an old memory, migrate it**: -```bash -# Read old memory -cat ~/your-memory-bank/auth-decision.md - -# Create new mnemonic version -/mnemonic:capture decisions "Use JWT for Authentication" - -# Add your content to the new file -``` - -3. **Mark migrated files**: -```bash -# Add "MIGRATED" prefix to migrated files -mv ~/your-memory-bank/auth-decision.md \ - ~/your-memory-bank/MIGRATED-auth-decision.md -``` - ---- - -## Handling Common Patterns - -### Pattern: Single Large Context File - -**Before**: One `memory-bank.md` or `context.md` with everything - -**Migration approach**: - -1. Read the file and identify sections -2. Create separate memories for each logical unit -3. Use appropriate namespaces - -```bash -# Split by headers -grep -n "^## " ~/your-memory-bank/memory-bank.md - -# Create individual memories for each section -``` - -### Pattern: Cursor Rules/Memory Files - -**Before**: `.cursor/rules` or `.cursorrules` - -**Migration**: - -1. Keep Cursor files for Cursor-specific settings -2. Migrate reusable knowledge to mnemonic -3. Mnemonic can sync back to Cursor format - -```bash -# Patterns and decisions go to mnemonic -/mnemonic:capture patterns "Error handling convention" - -# IDE-specific settings stay in Cursor -# .cursor/rules (keep as-is) -``` - -### Pattern: Windsurf Memory/Rules - -**Before**: `.windsurf/memories/` or `.windsurfrules` - -**Migration**: - -1. Convert memories to MIF format -2. Keep Windsurf-specific rules -3. Link mnemonic to Windsurf via integration - -```bash -# See Windsurf integration guide -cat docs/integrations/windsurf.md -``` - -### Pattern: Date-Based Session Logs - -**Before**: `2025-01-15-session.md`, `2025-01-16-session.md` - -**Migration**: - -```bash -# These are episodic memories -for f in ~/your-memory-bank/20*-session.md; do - # Extract date from filename - DATE=$(basename "$f" .md | sed 's/-session//') - - # Migrate to episodic namespace - UUID=$(uuidgen | tr '[:upper:]' '[:lower:]') - ./tools/convert-to-mif "$f" \ - --namespace episodic/user \ - --type episodic \ - --valid-from "${DATE}T00:00:00Z" -done -``` - ---- - -## Post-Migration Validation - -### Validate All Memories - -```bash -# Run validation -./tools/mnemonic-validate - -# Check for errors -./tools/mnemonic-validate --format json | jq '.summary' -``` - -### Fix Common Issues - -**Missing required fields**: -```bash -# Find memories missing provenance -rg -L "provenance:" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# Add provenance to each -``` - -**Invalid timestamps**: -```bash -# Find non-ISO timestamps -rg "created:.*[^Z]$" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -``` - -**Duplicate UUIDs**: -```bash -# Check for duplicates -rg "^id:" ${MNEMONIC_ROOT}/ --glob "*.memory.md" | \ - cut -d: -f2 | sort | uniq -d -``` - ---- - -## Integration Setup - -After migration, set up integrations for other tools: - -### Claude Code (Native) - -Already configured by plugin installation. - -### Cursor - -```bash -# Generate Cursor rules from memories -./tools/mnemonic-export --format cursor > .cursor/rules -``` - -### Windsurf - -```bash -# Generate Windsurf memories -./tools/mnemonic-export --format windsurf > .windsurf/memories/mnemonic.md -``` - -### GitHub Copilot - -```bash -# Generate Copilot instructions -./tools/mnemonic-export --format copilot > .github/copilot-instructions.md -``` - -See [Integration Guides](../integrations/README.md) for complete setup. - ---- - -## Rollback - -If you need to revert: - -```bash -# Restore from backup -tar -xzf memory-bank-backup-*.tar.gz -C ~/ - -# Or git restore -cd ~/your-memory-bank -git checkout HEAD~1 -- . - -# Remove mnemonic memories -rm -rf ${MNEMONIC_ROOT}/ -``` - ---- - -## FAQ - -### Can I keep using both systems? - -Yes. Mnemonic doesn't require exclusive use. You can: -- Use mnemonic for new memories -- Keep old system for reference -- Gradually migrate - -### Will my old memories still work? - -Your original markdown files remain unchanged. Mnemonic creates new files in its own directory. - -### What about tool-specific features? - -Mnemonic focuses on portable memory. Tool-specific settings (Cursor rules, Windsurf configuration) should stay in their respective locations. - -### How do I sync changes back? - -Use the export tools to generate tool-specific formats: -```bash -# After adding memories in mnemonic -./tools/mnemonic-export --format cursor > .cursor/rules -``` - ---- - -## Next Steps - -- [Quick Start](./quickstart-memory-bank.md) - 5-minute overview -- [Comparison](./mnemonic-vs-memory-bank.md) - Feature differences -- [Integration Guides](../integrations/README.md) - Tool-specific setup -- [Main Documentation](../../README.md) - Complete reference - -[← Back to Community](./README.md) diff --git a/docs/archive/community/mnemonic-vs-memory-bank.md b/docs/archive/community/mnemonic-vs-memory-bank.md deleted file mode 100644 index a9dc919..0000000 --- a/docs/archive/community/mnemonic-vs-memory-bank.md +++ /dev/null @@ -1,428 +0,0 @@ -# Mnemonic vs Memory Bank: Comparison - -Side-by-side comparison of mnemonic with typical Memory Bank setups. - ---- - -## Overview - -Memory Bank is a community pattern—markdown files used to give AI coding assistants persistent memory. Mnemonic formalizes this approach with standards, validation, and multi-tool support. - -**Key insight**: Memory Bank proved filesystem-based memory works. Mnemonic adds structure without losing simplicity. - ---- - -## Feature Comparison - -| Feature | Memory Bank | Mnemonic | -|---------|-------------|----------| -| **Storage** | Markdown files | Markdown files | -| **Format** | Ad-hoc | MIF Level 3 standard | -| **Validation** | None | Schema validation tool | -| **Memory types** | Implicit | semantic/episodic/procedural | -| **Decay model** | None | Exponential decay | -| **Cross-tool** | Manual per tool | 9+ tools supported | -| **Research backing** | Community intuition | 74% benchmark accuracy | -| **Version control** | Optional | Git-native | -| **Metadata** | Varies | Structured YAML | -| **Provenance** | None | Full tracking | -| **Bi-temporal** | No | Yes (valid_from/recorded_at) | - ---- - -## Format Comparison - -### Memory Bank (Typical) - -```markdown -# Project Memory Bank - -## Context -We're building a REST API with Node.js. - -## Decisions -- Use PostgreSQL for storage -- JWT for authentication -- Rate limiting at API gateway - -## Patterns -- All errors return JSON with `error` key -- Use snake_case for API fields - -## Recent Sessions -### 2025-01-15 -Fixed the N+1 query bug in user dashboard. -``` - -### Mnemonic (MIF Level 3) - -**Decision memory** (`decisions/user/abc123-use-postgresql.memory.md`): -```yaml ---- -id: abc12345-1234-1234-1234-123456789abc -type: semantic -namespace: decisions/user -created: 2026-01-15T10:30:00Z -modified: 2026-01-15T10:30:00Z -title: "Use PostgreSQL for Storage" -tags: - - database - - architecture -temporal: - valid_from: 2026-01-15T10:30:00Z - recorded_at: 2026-01-15T10:30:00Z -provenance: - source_type: conversation - agent: claude-opus-4 - confidence: 0.95 ---- - -# Use PostgreSQL for Storage - -We decided to use PostgreSQL because: -- Strong ACID compliance for transaction integrity -- Excellent JSON support for flexible schemas -- Mature ecosystem with great tooling - -## Alternatives Considered -- MongoDB: Rejected due to consistency requirements -- MySQL: Less rich JSON support -``` - -**Episodic memory** (`episodic/user/def456-n1-query-fix.memory.md`): -```yaml ---- -id: def45678-5678-5678-5678-567890123def -type: episodic -namespace: episodic/user -created: 2026-01-15T14:00:00Z -title: "Fixed N+1 Query in User Dashboard" -tags: - - debugging - - performance -temporal: - valid_from: 2026-01-15T14:00:00Z - recorded_at: 2026-01-15T16:00:00Z - decay: - model: exponential - half_life: P7D -provenance: - source_type: observation - agent: claude-opus-4 - confidence: 0.9 ---- - -# Fixed N+1 Query in User Dashboard - -## Problem -Dashboard taking 5+ seconds to load. - -## Investigation -Found N+1 pattern in UserDashboard component. -Each user row triggered separate query for posts. - -## Solution -Added `.includes(:posts, :comments)` to ActiveRecord query. - -## Result -Load time: 5s → 200ms -``` - ---- - -## Structural Comparison - -### Memory Bank Organization - -``` -~/memory-bank/ -├── memory-bank.md # Everything in one file -├── decisions.md # Or split by topic -├── patterns.md -└── sessions/ - ├── 2025-01-15.md - └── 2025-01-16.md -``` - -### Mnemonic Organization - -``` -${MNEMONIC_ROOT}/ -├── default/ # Organization -│ ├── decisions/ -│ │ ├── user/ # Personal decisions -│ │ ├── project/ # Project-level -│ │ └── shared/ # Team-shared -│ ├── learnings/user/ -│ ├── patterns/user/ -│ ├── blockers/user/ -│ ├── context/user/ -│ ├── apis/user/ -│ ├── security/user/ -│ ├── testing/user/ -│ └── episodic/user/ -└── .blackboard/ # Session coordination - ├── active-tasks.md - ├── session-notes.md - └── shared-context.md -``` - ---- - -## Capability Comparison - -### Search - -**Memory Bank**: -```bash -# Basic grep -grep -r "authentication" ~/memory-bank/ -``` - -**Mnemonic**: -```bash -# Structured search -/mnemonic:search "authentication" - -# Namespace-specific -rg -i "authentication" ${MNEMONIC_ROOT}/*/decisions/ - -# By memory type -rg "^type: episodic" ${MNEMONIC_ROOT}/ -l -``` - -### Capture - -**Memory Bank**: -```bash -# Manual edit -vim ~/memory-bank/memory-bank.md -# Add to appropriate section -``` - -**Mnemonic**: -```bash -# Typed capture -/mnemonic:capture decisions "Use JWT for auth" -/mnemonic:capture learnings "PostgreSQL JSONB indexing" -/mnemonic:capture patterns "Error handling convention" -``` - -### Validation - -**Memory Bank**: -- No validation -- Format drift over time -- No schema enforcement - -**Mnemonic**: -```bash -# Full validation -./tools/mnemonic-validate - -# CI integration -./tools/mnemonic-validate --format json | jq '.summary' - -# Pre-commit hook -./tools/mnemonic-validate --changed --fast-fail -``` - -### Multi-Tool Support - -**Memory Bank**: -- Each tool needs manual configuration -- Different formats per tool -- No portability - -**Mnemonic**: -- 9+ tools supported natively -- Single format, multiple exports -- Switch tools without losing memory - -| Tool | Memory Bank Setup | Mnemonic Setup | -|------|------------------|----------------| -| Cursor | Custom .cursor/rules | Native + export | -| Windsurf | Custom .windsurfrules | Native + export | -| Copilot | Custom instructions | Native + export | -| Aider | CONVENTIONS.md | Native + export | -| Continue | config.yaml | Native + export | - ---- - -## Memory Types - -### Memory Bank Approach - -Typically implicit or section-based: -```markdown -## Decisions <- Type implied by header -## Learnings <- Type implied by header -## Sessions <- Type implied by header -``` - -### Mnemonic Approach - -Explicit typing with cognitive science foundation: - -| Type | Use Case | Decay Rate | Example | -|------|----------|------------|---------| -| `semantic` | Facts, decisions, specs | Slow (30d) | "We use PostgreSQL" | -| `episodic` | Events, sessions, incidents | Fast (7d) | "Fixed bug on Jan 15" | -| `procedural` | Patterns, workflows | Medium (14d) | "Deploy via GitHub Actions" | - ---- - -## Decay Model - -### Memory Bank - -No decay—all memories treated equally regardless of age or relevance. - -### Mnemonic - -Exponential decay based on memory type: - -```yaml -temporal: - decay: - model: exponential - half_life: P7D # Episodic: halves every 7 days - strength: 0.85 # Current relevance (0.0-1.0) -``` - -**Benefits**: -- Recent memories prioritized -- Old memories naturally fade -- Important memories can override decay -- Automatic relevance ranking - ---- - -## Provenance Tracking - -### Memory Bank - -No tracking—unknown origin for memories. - -### Mnemonic - -Full provenance for every memory: - -```yaml -provenance: - source_type: conversation # How it was captured - agent: claude-opus-4 # Which AI created it - confidence: 0.95 # How confident - references: # Supporting evidence - - type: documentation - url: https://docs.example.com -``` - -**Benefits**: -- Audit trail for compliance -- Confidence-weighted retrieval -- Source verification -- Citation support - ---- - -## Bi-Temporal Tracking - -### Memory Bank - -Single timestamp (if any). - -### Mnemonic - -Two time dimensions per SQL:2011 standard: - -```yaml -temporal: - valid_from: 2026-01-10T00:00:00Z # When this became true - recorded_at: 2026-01-15T10:30:00Z # When we recorded it -``` - -**Use cases**: -- "When was this decision made?" (valid_from) -- "When did we learn this?" (recorded_at) -- Backfilling historical decisions -- Compliance auditing - ---- - -## Research Validation - -### Memory Bank - -Community intuition—no formal benchmarks. - -### Mnemonic - -Research-validated approach: - -| Benchmark | Filesystem (Mnemonic) | Graph-Based (Mem0) | -|-----------|----------------------|-------------------| -| LoCoMo Accuracy | **74.0%** | 68.5% | - -**Academic foundation**: -- Unix philosophy (arXiv:2601.11672) -- Cognitive memory types (arXiv:2411.00489) -- Bi-temporal theory (SQL:2011) - ---- - -## Migration Path - -Memory Bank → Mnemonic is additive, not replacement: - -1. **Keep existing files** - No need to delete -2. **Install mnemonic** - Adds structure on top -3. **Migrate incrementally** - Convert as you use -4. **Validate** - Ensure format compliance - -See [Migration Guide](./migration-from-memory-bank.md) for details. - ---- - -## When to Use Each - -### Stick with Memory Bank if: - -- Simple, single-project setup -- No need for cross-tool support -- Minimal compliance requirements -- Prefer complete flexibility - -### Move to Mnemonic if: - -- Multiple AI tools in your workflow -- Team collaboration needed -- Compliance or audit requirements -- Want research-backed approach -- Value validation and structure - ---- - -## Summary - -| Aspect | Memory Bank | Mnemonic | -|--------|-------------|----------| -| Philosophy | DIY flexibility | Structured standards | -| Learning curve | Lower | Slightly higher | -| Validation | None | Built-in | -| Multi-tool | Manual | Native | -| Research backing | Community | Academic | -| Best for | Simple setups | Professional use | - -**Bottom line**: Mnemonic validates what Memory Bank proved while adding the structure needed for professional and team use. - ---- - -## Related Documentation - -- [Quick Start](./quickstart-memory-bank.md) - 5-minute setup -- [Migration Guide](./migration-from-memory-bank.md) - Full walkthrough -- [Research Validation](../enterprise/research-validation.md) - Academic backing -- [Main Documentation](../../README.md) - Complete reference - -[← Back to Community](./README.md) diff --git a/docs/archive/community/quickstart-memory-bank.md b/docs/archive/community/quickstart-memory-bank.md deleted file mode 100644 index b43edf9..0000000 --- a/docs/archive/community/quickstart-memory-bank.md +++ /dev/null @@ -1,237 +0,0 @@ -# Quick Start for Memory Bank Users - -Already using markdown files for AI memory? You're 5 minutes away from mnemonic. - ---- - -## What You Already Know - -If you've been using Memory Bank patterns, you've already discovered: - -- Markdown files work for AI memory -- Filesystem storage is reliable -- Your AI assistant can read and write context -- Version control with git is valuable - -**Mnemonic validates your approach** and adds standardization. - ---- - -## The 5-Minute Setup - -### Step 1: Install the Plugin - -```bash -# Clone mnemonic -git clone https://github.com/zircote/mnemonic.git ~/tools/mnemonic - -# Register with Claude Code -claude settings plugins add ~/tools/mnemonic -``` - -### Step 2: Initialize - -```bash -# Start Claude Code and run setup -/mnemonic:setup -``` - -This creates: -``` -${MNEMONIC_ROOT}/ -├── default/ -│ ├── decisions/user/ -│ ├── learnings/user/ -│ ├── patterns/user/ -│ ├── blockers/user/ -│ ├── context/user/ -│ ├── apis/user/ -│ ├── security/user/ -│ ├── testing/user/ -│ └── episodic/user/ -└── .blackboard/ -``` - -### Step 3: Migrate Your Existing Files - -```bash -# Quick migration - copy your existing memory files -cp ~/your-memory-bank/*.md ${MNEMONIC_ROOT}/default/context/user/ - -# Or use the migration tool for proper conversion -./tools/migrate-memory-bank \ - --source ~/your-memory-bank \ - --target ${MNEMONIC_ROOT}/default -``` - -### Step 4: Start Using It - -```bash -# Capture a new decision -/mnemonic:capture decisions "Use PostgreSQL for storage" - -# Search your memories -/mnemonic:search "authentication" - -# Check status -/mnemonic:status -``` - ---- - -## What Changes (And What Doesn't) - -### What Stays the Same - -| Your Approach | With Mnemonic | -|---------------|---------------| -| Plain markdown files | Still plain markdown | -| Stored on filesystem | Still on filesystem | -| Human-readable | Still human-readable | -| Git-versioned | Still git-versioned | -| Your editor works | Your editor still works | - -### What You Gain - -| Feature | Before | After | -|---------|--------|-------| -| **Structure** | Ad-hoc | Standardized (MIF Level 3) | -| **Validation** | None | Schema validation tool | -| **Cross-tool** | Manual setup per tool | Works with 9+ tools | -| **Decay model** | Static | Automatic relevance decay | -| **Research backing** | Your intuition | 74% benchmark accuracy | - ---- - -## Format Comparison - -### Your Current Format (Typical) - -```markdown -# Project Context - -We're building an API gateway. - -## Decisions -- Use JWT for auth -- PostgreSQL for storage - -## Notes -- Fixed the N+1 bug on 2025-01-15 -``` - -### Mnemonic Format (MIF Level 3) - -```yaml ---- -id: 550e8400-e29b-41d4-a716-446655440000 -type: semantic -namespace: decisions/user -created: 2026-01-23T10:30:00Z -title: "Use JWT for Authentication" -tags: - - authentication - - security -temporal: - valid_from: 2026-01-23T10:30:00Z - recorded_at: 2026-01-23T10:30:00Z -provenance: - source_type: conversation - agent: claude-opus-4 - confidence: 0.95 ---- - -# Use JWT for Authentication - -We decided to use JWT tokens because: -- Stateless authentication fits our microservices architecture -- Standard library support in all our languages -- Easy integration with API gateway -``` - -**Key difference**: Structured metadata in YAML frontmatter. - ---- - -## Common Migration Patterns - -### Pattern 1: Single Context File → Multiple Memories - -**Before**: One large `context.md` with everything - -**After**: Separate files by type -```bash -# Create separate memories for each decision -/mnemonic:capture decisions "Use JWT for auth" -/mnemonic:capture decisions "Use PostgreSQL for storage" -/mnemonic:capture patterns "Error handling pattern" -``` - -### Pattern 2: Project-Specific → Namespaced - -**Before**: `~/project-a/memory-bank/` - -**After**: `${MNEMONIC_ROOT}/project-a/decisions/user/` - -```bash -# Create project-specific namespace -mkdir -p ${MNEMONIC_ROOT}/project-a/{decisions,patterns,learnings}/user -``` - -### Pattern 3: Unstructured Notes → Typed Memories - -**Before**: Generic notes mixed together - -**After**: Typed by memory category -- `semantic` - Facts, decisions, specifications -- `episodic` - Events, debugging sessions -- `procedural` - Workflows, patterns - ---- - -## Keep Your Existing Setup - -You don't have to choose. Mnemonic can coexist with your current approach: - -``` -${MNEMONIC_ROOT}/ # Mnemonic memories -~/your-memory-bank/ # Keep your existing setup - -# Mnemonic reads both if you configure it -``` - -Or gradually migrate: -1. Start capturing new memories in mnemonic format -2. Migrate old memories when you touch them -3. Eventually consolidate - ---- - -## Validation - -Check your migrated memories: - -```bash -# Validate all memories -./tools/mnemonic-validate - -# See any format issues -./tools/mnemonic-validate --format json | jq '.errors' -``` - ---- - -## Next Steps - -- [Full Migration Guide](./migration-from-memory-bank.md) - Detailed walkthrough -- [Comparison](./mnemonic-vs-memory-bank.md) - Side-by-side differences -- [Main Documentation](../../README.md) - Complete reference - ---- - -## Questions? - -- **GitHub Issues**: [Report problems](https://github.com/zircote/mnemonic/issues) -- **Discussions**: [Ask questions](https://github.com/zircote/mnemonic/discussions) - -[← Back to Community](./README.md) diff --git a/docs/archive/integrations/README.md b/docs/archive/integrations/README.md deleted file mode 100644 index b9bf373..0000000 --- a/docs/archive/integrations/README.md +++ /dev/null @@ -1,122 +0,0 @@ -# Mnemonic Integrations - -Mnemonic integrates with popular AI coding assistants through their native configuration mechanisms. - -## Supported Tools - -| Tool | Integration Method | Guide | -|------|-------------------|-------| -| [Claude Code](https://claude.ai/code) | Native Plugin | Built-in | -| [GitHub Copilot](https://github.com/features/copilot) | `.github/copilot-instructions.md` | [Guide](./github-copilot.md) | -| [OpenAI Codex CLI](https://github.com/openai/codex) | `AGENTS.md` + Skills | [Guide](./codex-cli.md) | -| [Google Gemini CLI](https://github.com/google-gemini/gemini-cli) | MCP Server / Instructions | [Guide](./gemini-cli.md) | -| [OpenCode](https://opencode.ai) | Skills | [Guide](./opencode.md) | -| [Cursor](https://cursor.com) | Rules | [Guide](./cursor.md) | -| [Windsurf/Codeium](https://windsurf.ai) | Memories/Rules | [Guide](./windsurf.md) | -| [Aider](https://aider.chat) | `CONVENTIONS.md` | [Guide](./aider.md) | -| [Continue Dev](https://continue.dev) | `config.yaml` rules | [Guide](./continue.md) | - -## Quick Start - -### 1. Choose Your Tool - -Select the integration guide for your AI coding assistant from the table above. - -### 2. Copy Templates - -All integrations use templates from the [`templates/`](../../templates/) directory: - -```bash -# GitHub Copilot -cp templates/copilot-instructions.md .github/copilot-instructions.md - -# Codex CLI / OpenCode -cp -r templates/codex-skill ~/.codex/skills/mnemonic - -# Cursor -cp templates/cursor-rule.mdc .cursor/rules/mnemonic.mdc - -# Aider -cp templates/CONVENTIONS.md ./CONVENTIONS.md - -# Universal (many tools support this) -cp templates/AGENTS.md ./AGENTS.md -``` - -### 3. Verify - -Follow the verification steps in each integration guide to confirm the setup works. - -## Universal Memory Format - -All integrations use the same MIF Level 3 memory format: - -```yaml ---- -id: -type: semantic|episodic|procedural -namespace: {namespace}/user -created: -modified: -title: "Descriptive title" -tags: [tag1, tag2] -temporal: - valid_from: - recorded_at: -provenance: - source_type: conversation - agent: - confidence: 0.9 ---- - -# Title - -Content in markdown... -``` - -## Memory Storage - -All memories are stored at `${MNEMONIC_ROOT}/` with this structure: - -``` -${MNEMONIC_ROOT}/ -└── {org}/ # Organization from git remote (or "default") - ├── apis/user/ # API documentation - ├── blockers/user/ # Issues encountered - ├── context/user/ # General context - ├── decisions/user/ # Architectural choices - ├── learnings/user/ # Insights discovered - ├── patterns/user/ # Code conventions - ├── security/user/ # Security policies - ├── testing/user/ # Test strategies - └── episodic/user/ # Events, experiences -``` - -**Note:** The `{org}` directory is derived from your git remote (e.g., `zircote` for `github.com/zircote/repo`). Falls back to `default` if no git remote is configured. - -## Templates - -| Template | Purpose | Location | -|----------|---------|----------| -| `copilot-instructions.md` | GitHub Copilot | `.github/` | -| `codex-skill/SKILL.md` | Codex CLI, OpenCode | `~/.codex/skills/mnemonic/` | -| `cursor-rule.mdc` | Cursor | `.cursor/rules/` | -| `CONVENTIONS.md` | Aider | Project root | -| `AGENTS.md` | Multiple tools | Project root or `~/.codex/` | - -## Migrating from Memory Bank - -Already using a Memory Bank pattern in Cursor, Windsurf, or another tool? - -- [Quick Start for Memory Bank Users](../community/quickstart-memory-bank.md) - 5-minute setup -- [Full Migration Guide](../community/migration-from-memory-bank.md) - Complete walkthrough -- [Comparison](../community/mnemonic-vs-memory-bank.md) - Side-by-side differences - -## Contributing - -To add support for a new tool: - -1. Create a guide in `docs/integrations/.md` -2. Add templates to `templates/` if needed -3. Update this README with the new tool -4. Submit a pull request diff --git a/docs/archive/integrations/aider.md b/docs/archive/integrations/aider.md deleted file mode 100644 index 79bd401..0000000 --- a/docs/archive/integrations/aider.md +++ /dev/null @@ -1,119 +0,0 @@ -# Aider Integration - -Integrate Mnemonic with Aider using CONVENTIONS.md. - -## Overview - -Aider supports a CONVENTIONS.md file that provides project-specific instructions. This integration configures Aider to use Mnemonic for persistent memory. - -## Setup - -### Create CONVENTIONS.md - -Create `CONVENTIONS.md` in your project root: - -```bash -cp /path/to/mnemonic/templates/CONVENTIONS.md ./CONVENTIONS.md -``` - -### Configure Auto-Loading - -Add to `.aider.conf.yml`: - -```yaml -read: CONVENTIONS.md -``` - -Or pass explicitly: - -```bash -aider --read CONVENTIONS.md -``` - -## CONVENTIONS.md Content - -```markdown -# Mnemonic Memory Integration - -## Memory System -This project uses Mnemonic for persistent memories at `${MNEMONIC_ROOT}/`. - -## Before Implementing -Always search for relevant memories: -```bash -rg -i "" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -``` - -## Capture Requirements - -### When to Capture -- Decision made: Save to `decisions/user/` -- Lesson learned: Save to `learnings/user/` -- Pattern established: Save to `patterns/user/` -- Blocker found: Save to `blockers/user/` - -### Memory Format (MIF Level 3) -Files must have `.memory.md` extension with YAML frontmatter: - -```yaml ---- -id: -type: semantic|episodic|procedural -namespace: {namespace}/user -created: -title: "Descriptive title" -tags: [tag1, tag2] ---- - -# Title - -Content... -``` -``` - -## Usage - -### Start Aider with Conventions - -```bash -aider --read CONVENTIONS.md -``` - -### Commands During Session - -``` -/read CONVENTIONS.md # Re-read conventions -/add file.md # Add files to context -``` - -### Memory Operations - -Ask Aider naturally: -- "What decisions have been made about the API?" -- "Remember that we're using TypeScript strict mode" -- "Search for patterns related to error handling" - -## Best Practices - -1. Keep CONVENTIONS.md in version control -2. Update conventions as project evolves -3. Use `.aider.conf.yml` for consistent loading -4. Combine with `.aider.watch` for auto-context - -## Verification - -```bash -# Start aider with conventions -aider --read CONVENTIONS.md - -# Ask about memories -> What do we know about this project? - -# Create a memory -> Remember that we decided to use PostgreSQL -``` - -## Sources - -- [Aider CONVENTIONS.md](https://aider.chat/docs/usage/conventions.html) -- [Aider Configuration](https://aider.chat/docs/config.html) diff --git a/docs/archive/integrations/codex-cli.md b/docs/archive/integrations/codex-cli.md deleted file mode 100644 index 06f1e7e..0000000 --- a/docs/archive/integrations/codex-cli.md +++ /dev/null @@ -1,83 +0,0 @@ -# OpenAI Codex CLI Integration - -Integrate Mnemonic with OpenAI Codex CLI using AGENTS.md and Skills. - -## Overview - -Codex CLI supports two integration methods: -1. **AGENTS.md**: Global instructions for all sessions -2. **Skills**: Reusable commands invokable with `$mnemonic` - -## Setup - -### Method 1: AGENTS.md (Global Instructions) - -Create `~/.codex/AGENTS.md`: - -```bash -mkdir -p ~/.codex -cp /path/to/mnemonic/templates/AGENTS.md ~/.codex/ -``` - -### Method 2: Mnemonic Skill - -Create the skill directory and file: - -```bash -mkdir -p ~/.codex/skills/mnemonic -cp /path/to/mnemonic/templates/codex-skill/SKILL.md ~/.codex/skills/mnemonic/ -``` - -## Skill Usage - -Once installed, invoke the skill: - -``` -$mnemonic search authentication -$mnemonic capture decision "Use JWT for auth" -``` - -## AGENTS.md Content - -The AGENTS.md file instructs Codex to: - -1. Search memories before implementing features -2. Capture decisions, learnings, and patterns -3. Use MIF Level 3 format for all memories - -See [templates/AGENTS.md](../../templates/AGENTS.md) for the full template. - -## Skill Content - -The skill provides: - -1. `search` - Find relevant memories -2. `capture` - Create new memories -3. `list` - View memories by namespace - -See [templates/codex-skill/SKILL.md](../../templates/codex-skill/SKILL.md) for the full template. - -## Verification - -```bash -# Verify AGENTS.md is loaded -codex --show-agents - -# List available skills -codex /skills - -# Test skill invocation -$mnemonic search test -``` - -## Best Practices - -1. Use both AGENTS.md and Skills for complete integration -2. Place project-specific agents in repository root -3. Use global agents for cross-project memory access - -## Sources - -- [Codex AGENTS.md Guide](https://developers.openai.com/codex/guides/agents-md) -- [Codex Skills Documentation](https://developers.openai.com/codex/skills/) -- [Create Skills](https://developers.openai.com/codex/skills/create-skill/) diff --git a/docs/archive/integrations/continue.md b/docs/archive/integrations/continue.md deleted file mode 100644 index fa13335..0000000 --- a/docs/archive/integrations/continue.md +++ /dev/null @@ -1,120 +0,0 @@ -# Continue Dev Integration - -Integrate Mnemonic with Continue Dev using config.yaml rules and custom commands. - -## Overview - -Continue Dev supports system messages and custom commands. This integration adds mnemonic memory capabilities to your Continue configuration. - -## Setup - -### Edit Configuration - -Add to `~/.continue/config.yaml`: - -```yaml -models: - - provider: anthropic - name: claude-sonnet-4-20250514 - -chatOptions: - baseSystemMessage: | - You have access to a Mnemonic memory system at ${MNEMONIC_ROOT}/. - - BEFORE implementing anything: - - Search: rg -i "" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - - CAPTURE immediately when: - - Decision made → decisions/user/ - - Lesson learned → learnings/user/ - - Pattern established → patterns/user/ - - Memory format: .memory.md files with MIF Level 3 YAML frontmatter - (id, type, namespace, created, title, tags) - -customCommands: - - name: mnemonic-search - description: Search mnemonic memories - prompt: | - Search for memories related to: {{input}} - Use: rg -i "{{input}}" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - - - name: mnemonic-capture - description: Capture a new memory - prompt: | - Create a memory in ${MNEMONIC_ROOT}/default/{{namespace}}/user/ - with MIF Level 3 format for: {{input}} - - - name: mnemonic-list - description: List memories by namespace - prompt: | - List memories in namespace: {{input}} - Use: ls ${MNEMONIC_ROOT}/default/{{input}}/user/ -``` - -## Custom Commands - -### Search Memories - -``` -/mnemonic-search authentication -``` - -### Capture Memory - -``` -/mnemonic-capture decisions Use JWT for authentication -``` - -### List by Namespace - -``` -/mnemonic-list decisions -``` - -## Context Provider (Advanced) - -Add a custom context provider for deeper integration: - -```yaml -contextProviders: - - name: mnemonic - params: - path: ${MNEMONIC_ROOT} - pattern: "*.memory.md" -``` - -## Usage - -### In Chat - -``` -What memories exist about the database schema? -Remember that we decided to use PostgreSQL -Search for patterns related to API design -``` - -### With Commands - -``` -/mnemonic-search database -/mnemonic-capture patterns Always validate input at API boundaries -``` - -## Verification - -1. Open Continue in your IDE -2. Run `/mnemonic-search test` -3. Verify the search command is executed -4. Create a test memory with `/mnemonic-capture` - -## Best Practices - -1. Use `baseSystemMessage` for always-on instructions -2. Create custom commands for frequent operations -3. Consider context providers for large memory sets - -## Sources - -- [Continue Dev Documentation](https://docs.continue.dev/) -- [Continue Configuration](https://docs.continue.dev/reference/config) diff --git a/docs/archive/integrations/cursor.md b/docs/archive/integrations/cursor.md deleted file mode 100644 index 00848de..0000000 --- a/docs/archive/integrations/cursor.md +++ /dev/null @@ -1,295 +0,0 @@ -# Cursor Integration - -Integrate Mnemonic with Cursor using the Rules system. - -## Overview - -Cursor supports rules that apply to all AI interactions. The mnemonic rule configures Cursor to use the memory system. - -## Setup - -### Create Cursor Rule - -Create `.cursor/rules/mnemonic.mdc`: - -```bash -mkdir -p .cursor/rules -cp /path/to/mnemonic/templates/cursor-rule.mdc .cursor/rules/mnemonic.mdc -``` - -### Alternative: AGENTS.md - -Cursor also supports `AGENTS.md` in the project root: - -```bash -cp /path/to/mnemonic/templates/AGENTS.md ./AGENTS.md -``` - -## Rule Content - -```markdown ---- -description: "Mnemonic memory system for persistent context across sessions" -alwaysApply: true ---- - -# Mnemonic Memory System - -## Memory Storage -All memories stored at `${MNEMONIC_ROOT}/` as `.memory.md` files. - -## Required Behavior - -### Before Implementing -Search for relevant memories: -```bash -rg -i "" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -``` - -### Capture Triggers -- Decision made → Create in `decisions/user/` -- Lesson learned → Create in `learnings/user/` -- Pattern established → Create in `patterns/user/` -- Blocker encountered → Create in `blockers/user/` - -## Memory Types -- **semantic**: Facts, decisions, specifications -- **episodic**: Events, debug sessions, incidents -- **procedural**: Workflows, patterns, how-tos -``` - -## Usage - -Once the rule is in place: - -1. **Recall**: Ask Cursor "What do we know about X?" -2. **Capture**: Tell Cursor "Remember that we decided Y" -3. **Reference**: Use `@mnemonic` in Cursor Chat - -## Verification - -1. Open a file in Cursor -2. Check Settings > Features > Rules for the mnemonic rule -3. Ask in Composer: "Search for memories about this project" - -## Rule Options - -| Option | Description | -|--------|-------------| -| `alwaysApply: true` | Apply to all interactions | -| `alwaysApply: false` | Only apply when explicitly referenced | -| `description` | Shown in rule list | - ---- - -## Common Workflows - -### Daily Development - -``` -Morning: -1. Open project in Cursor -2. Ask: "What decisions have we made about this project?" -3. Continue where you left off - -During Development: -1. Before implementing: "Search memories for [feature]" -2. After decisions: "Remember that we're using [approach]" -3. After debugging: "Capture this fix as a learning" - -End of Day: -1. Review: "What did we learn today?" -2. Verify memories captured -``` - -### Feature Implementation - -``` -1. "What patterns do we use for [component type]?" - → Cursor searches patterns/user/ - -2. "What decisions affect [feature]?" - → Cursor searches decisions/user/ - -3. Implement feature following established patterns - -4. "Remember this pattern: [description]" - → Creates new pattern memory -``` - -### Debugging Session - -``` -1. Encounter bug -2. "Search memories for similar issues" -3. Investigate and fix -4. "Capture this debugging session as a learning" - → Creates episodic memory with: - - Problem description - - Investigation steps - - Solution -``` - ---- - -## Advanced Patterns - -### Memory-Aware Code Review - -Add to your Cursor rule: - -```markdown -When reviewing code: -1. Check patterns/user/ for established conventions -2. Reference decisions/user/ for architectural context -3. Flag violations of documented patterns -``` - -### Context Switching - -When switching between projects: - -```bash -# Each project can have its own namespace -${MNEMONIC_ROOT}/project-a/decisions/user/ -${MNEMONIC_ROOT}/project-b/decisions/user/ -``` - -Configure rule to use project-specific paths: - -```markdown -Memory path for this project: ${MNEMONIC_ROOT}/project-a/ -``` - -### Team Patterns - -Share patterns across team: - -```bash -# Clone shared patterns -git clone git@github.com:team/patterns.git ${MNEMONIC_ROOT}/shared - -# Rule references both personal and shared -Memory paths: -- Personal: ${MNEMONIC_ROOT}/default/ -- Shared: ${MNEMONIC_ROOT}/shared/ -``` - ---- - -## Migrating from Cursor Memory Bank - -If you've been using a Memory Bank pattern in Cursor: - -### Step 1: Export Current Memories - -Your Memory Bank files are typically in: -- `.cursor/memory-bank/` -- `.cursorrules` (memory section) -- Project-specific markdown files - -### Step 2: Convert to MIF Format - -```bash -# Use migration tool -./tools/migrate-memory-bank \ - --source .cursor/memory-bank \ - --target ${MNEMONIC_ROOT}/default \ - --namespace context -``` - -### Step 3: Update Cursor Rules - -Replace old memory references with mnemonic paths: - -**Before:** -```markdown -Check .cursor/memory-bank/ for context -``` - -**After:** -```markdown -Check ${MNEMONIC_ROOT}/default/ for context -Use MIF Level 3 format for new memories -``` - -### Step 4: Verify Migration - -```bash -# Validate converted memories -./tools/mnemonic-validate ${MNEMONIC_ROOT}/default/ - -# Test in Cursor -"What do we know about [topic from old memory bank]?" -``` - -See [Migration Guide](../community/migration-from-memory-bank.md) for complete details. - ---- - -## Troubleshooting - -### Rules Not Loading - -**Symptom**: Cursor doesn't follow mnemonic instructions - -**Solutions**: -1. Check rule location: `.cursor/rules/mnemonic.mdc` -2. Verify `alwaysApply: true` is set -3. Restart Cursor after adding rules -4. Check Settings > Features > Rules to confirm loading - -### Memory Files Not Found - -**Symptom**: "No memories found for [topic]" - -**Solutions**: -1. Verify memory directory exists: - ```bash - ls -la ${MNEMONIC_ROOT}/ - ``` -2. Check file permissions -3. Ensure `.memory.md` extension -4. Try explicit path in query - -### Format Errors - -**Symptom**: Cursor creates invalid memory files - -**Solutions**: -1. Add format examples to rule -2. Run validation after capture: - ```bash - ./tools/mnemonic-validate --changed - ``` -3. Include YAML template in rule - -### Search Not Working - -**Symptom**: ripgrep commands fail - -**Solutions**: -1. Verify ripgrep installed: - ```bash - which rg || brew install ripgrep - ``` -2. Check path in rule matches actual location -3. Try broader search pattern - -### Rule Conflicts - -**Symptom**: Multiple rules interfering - -**Solutions**: -1. Use unique description for mnemonic rule -2. Set priority with rule ordering -3. Check for conflicting `alwaysApply` rules - ---- - -## Sources - -- [Cursor Rules Documentation](https://cursor.com/docs/context/rules) -- [awesome-cursorrules](https://github.com/PatrickJS/awesome-cursorrules) -- [Memory Bank Migration](../community/migration-from-memory-bank.md) -- [MIF Level 3 Specification](../../skills/mnemonic-format/SKILL.md) diff --git a/docs/archive/integrations/gemini-cli.md b/docs/archive/integrations/gemini-cli.md deleted file mode 100644 index 6dfc26c..0000000 --- a/docs/archive/integrations/gemini-cli.md +++ /dev/null @@ -1,102 +0,0 @@ -# Google Gemini CLI Integration - -Integrate Mnemonic with Google Gemini CLI using instructions or MCP servers. - -## Overview - -Gemini CLI supports: -1. **Instructions file**: Simple text-based instructions -2. **MCP Servers**: Full tool integration (advanced) - -## Setup - -### Method 1: Instructions File (Recommended) - -Create `~/.gemini/instructions.md`: - -```bash -mkdir -p ~/.gemini -cat > ~/.gemini/instructions.md << 'EOF' -# Mnemonic Memory System - -## Memory Location -All memories are stored at `${MNEMONIC_ROOT}/` as `.memory.md` files. - -## Required Behavior -1. Search memories before implementing: `rg -i "" ${MNEMONIC_ROOT}/` -2. Capture decisions, learnings, patterns immediately -3. Use MIF Level 3 format with YAML frontmatter - -## Namespaces -- decisions/ - Architectural choices -- learnings/ - Insights and discoveries -- patterns/ - Code conventions -- blockers/ - Issues and impediments - -## Memory Format -```yaml ---- -id: -type: semantic|episodic|procedural -namespace: {namespace}/user -created: -title: "Title" -tags: [tag1, tag2] ---- - -# Title - -Content... -``` -EOF -``` - -### Method 2: MCP Server (Advanced) - -Add to `~/.gemini/settings.json`: - -```json -{ - "mcpServers": { - "mnemonic": { - "command": "/path/to/mnemonic-mcp-server", - "args": ["--memory-path", "${MNEMONIC_ROOT}"], - "timeout": 30000, - "trust": true - } - } -} -``` - -Note: MCP server implementation requires additional development. - -## Verification - -```bash -# Check MCP servers (if using Method 2) -gemini mcp list - -# Test memory search -gemini "search for memories about authentication" -``` - -## Usage Examples - -```bash -# Ask Gemini to recall -gemini "What decisions have been made about the database schema?" - -# Ask Gemini to capture -gemini "Remember that we decided to use PostgreSQL for the main database" -``` - -## Limitations - -- Instructions file is advisory only -- MCP server requires custom implementation -- Shell command execution depends on Gemini CLI configuration - -## Sources - -- [Gemini CLI MCP Servers](https://geminicli.com/docs/tools/mcp-server/) -- [GitHub - gemini-cli MCP docs](https://github.com/google-gemini/gemini-cli/blob/main/docs/tools/mcp-server.md) diff --git a/docs/archive/integrations/github-copilot.md b/docs/archive/integrations/github-copilot.md deleted file mode 100644 index dbc8f92..0000000 --- a/docs/archive/integrations/github-copilot.md +++ /dev/null @@ -1,306 +0,0 @@ -# GitHub Copilot Integration - -Integrate Mnemonic with GitHub Copilot to provide persistent memory context in your repositories. - -## Overview - -GitHub Copilot supports custom instructions through `.github/copilot-instructions.md` files. This integration configures Copilot to reference and create Mnemonic memories. - -## Setup - -### 1. Create Instructions File - -Create `.github/copilot-instructions.md` in your repository: - -```bash -mkdir -p .github -# From mnemonic repository root: -cp templates/copilot-instructions.md .github/ -``` - -Or copy from the [template](../../templates/copilot-instructions.md). - -### 2. Configure Path-Specific Instructions (Optional) - -For memory file editing support, create `.github/instructions/memory.instructions.md`: - -```markdown ---- -applyTo: ["**/*.memory.md"] ---- - -This is a Mnemonic memory file using MIF Level 3 format. -Preserve the YAML frontmatter structure when editing. -Required fields: id, type, namespace, created, title, tags. -``` - -## How It Works - -1. **Recall**: Copilot searches `${MNEMONIC_ROOT}/` before implementing features -2. **Capture**: Copilot creates memory files when decisions are made -3. **Format**: All memories use MIF Level 3 format with YAML frontmatter - -## Verification - -1. Open a file in your repository with Copilot enabled -2. Ask Copilot Chat: "What memories exist about this project?" -3. Verify it references the mnemonic search command - -## Limitations - -- GitHub Copilot cannot directly execute shell commands -- Instructions are advisory; Copilot may not always follow them -- Works best with Copilot Chat rather than inline completions - -## Template - -See [templates/copilot-instructions.md](../../templates/copilot-instructions.md) for the full template. - ---- - -## Common Workflows - -### Daily Development - -``` -Morning: -1. Open repository in VS Code/IDE -2. Copilot Chat: "What decisions have been made for this project?" -3. Review relevant memories before starting - -During Development: -1. Before implementing: "What patterns exist for [component]?" -2. After decisions: "Document this decision about [topic]" -3. After debugging: "Record this fix for future reference" - -Code Review: -1. "What patterns should I look for in this code?" -2. Reference memories in PR comments -``` - -### Feature Implementation - -``` -1. Copilot Chat: "Search for patterns related to [feature]" - -2. "What architectural decisions affect [area]?" - -3. Implement following established patterns - -4. "Create a memory documenting our approach to [feature]" -``` - -### Debugging Session - -``` -1. Encounter issue -2. "Have we seen similar issues before?" -3. Investigate and resolve -4. "Document this debugging session as a learning" -``` - ---- - -## Advanced Patterns - -### Repository-Level Context - -Add project context to instructions: - -```markdown -# .github/copilot-instructions.md - -## Project Context -This is a [type] project using [stack]. - -## Memory References -Before implementing features, check: -- ${MNEMONIC_ROOT}/this-project/decisions/ -- ${MNEMONIC_ROOT}/this-project/patterns/ - -## Capture Requirements -Document all: -- Architectural decisions -- API design choices -- Performance optimizations -``` - -### Path-Specific Memory Rules - -Create specialized rules for different file types: - -```markdown -# .github/instructions/api.instructions.md ---- -applyTo: ["**/api/**/*.ts"] ---- - -Check API decisions before implementing: -- ${MNEMONIC_ROOT}/default/apis/ - -Document new endpoints in apis/ namespace. -``` - -```markdown -# .github/instructions/tests.instructions.md ---- -applyTo: ["**/*.test.ts", "**/*.spec.ts"] ---- - -Reference testing patterns: -- ${MNEMONIC_ROOT}/default/testing/ - -Document testing strategies discovered. -``` - -### Multi-Repository Sharing - -Share memories across repositories: - -```markdown -# .github/copilot-instructions.md - -## Shared Memories (Organization-wide) -Also check: ~/shared-memories/org/ - -## Team Memories -Check: ~/shared-memories/team-platform/ - -## Project-Specific -Primary: ${MNEMONIC_ROOT}/this-project/ -``` - -### Copilot Workspace Integration - -For Copilot Workspace: - -```markdown -# .github/copilot-instructions.md - -## Workspace Context -When planning implementations: -1. Check decisions/ for architectural constraints -2. Reference patterns/ for code conventions -3. Review apis/ for integration points - -## Multi-file Changes -When modifying multiple files: -1. Verify consistency with patterns/ -2. Update affected memories if patterns change -``` - ---- - -## Migrating from Other Systems - -### From Copilot Memory (Cloud) - -If using GitHub Copilot's built-in memory features: - -1. **Export current context** from Copilot settings -2. **Convert to MIF format**: - ```bash - # Create memory file from exported content - ./tools/convert-to-mif exported-memory.txt \ - --namespace context/user \ - --type semantic - ``` -3. **Update instructions** to reference local files - -### From Repository Memory Files - -If you have existing markdown memory files: - -```bash -# Migrate existing files -./tools/migrate-memory-bank \ - --source ./docs/memory/ \ - --target ${MNEMONIC_ROOT}/default \ - --namespace context - -# Update copilot-instructions.md with new paths -``` - -### From Memory Bank Pattern - -See [Migration Guide](../community/migration-from-memory-bank.md) for detailed steps. - ---- - -## Troubleshooting - -### Instructions Not Loading - -**Symptom**: Copilot ignores custom instructions - -**Solutions**: -1. Verify file location: `.github/copilot-instructions.md` -2. Check repository settings enable custom instructions -3. Ensure file is committed to repository -4. Try refreshing Copilot Chat - -### Memory Commands Fail - -**Symptom**: Copilot can't execute shell commands - -**Note**: GitHub Copilot cannot directly execute shell commands. Instead: - -1. Ask Copilot to **show** the command: - ``` - "What command would search memories for authentication?" - ``` -2. Execute command manually in terminal -3. Share results with Copilot if needed - -### Chat vs Inline Completions - -**Best practices**: -- Use Copilot Chat for memory-related queries -- Inline completions work best for code generation -- Reference memories in Chat, apply in code - -### Path Issues - -**Symptom**: Wrong memory paths referenced - -**Solutions**: -1. Use absolute paths in instructions -2. Verify `~` expands correctly in your environment -3. Consider project-relative paths: - ```markdown - For this project: ./mnemonic/ - For personal: ${MNEMONIC_ROOT}/ - ``` - -### Format Inconsistencies - -**Symptom**: Created memories don't match MIF spec - -**Solutions**: -1. Include full template in path-specific instructions -2. Add validation reminder to instructions: - ```markdown - After creating memories, validate format matches MIF Level 3. - ``` -3. Run validation periodically: - ```bash - ./tools/mnemonic-validate - ``` - -### Stale Instructions - -**Symptom**: Old instructions still being used - -**Solutions**: -1. Refresh Copilot Chat session -2. Verify latest instructions are committed -3. Check for cached versions in IDE - ---- - -## Sources - -- [GitHub Docs - Custom Instructions](https://docs.github.com/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot) -- [Path-Specific Instructions](https://docs.github.com/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot#creating-a-file-to-define-path-specific-instructions) -- [Memory Bank Migration](../community/migration-from-memory-bank.md) -- [MIF Level 3 Specification](../../skills/mnemonic-format/SKILL.md) diff --git a/docs/archive/integrations/opencode.md b/docs/archive/integrations/opencode.md deleted file mode 100644 index a2c492a..0000000 --- a/docs/archive/integrations/opencode.md +++ /dev/null @@ -1,82 +0,0 @@ -# OpenCode Integration - -Integrate Mnemonic with OpenCode using the Skills system. - -## Overview - -OpenCode supports skills that can be invoked during coding sessions. The mnemonic skill provides memory capture and recall functionality. - -## Setup - -### Project-Level Skill - -Create `.opencode/skills/mnemonic/SKILL.md`: - -```bash -mkdir -p .opencode/skills/mnemonic -cp /path/to/mnemonic/templates/codex-skill/SKILL.md .opencode/skills/mnemonic/ -``` - -### Global Skill - -Create `~/.config/opencode/skills/mnemonic/SKILL.md`: - -```bash -mkdir -p ~/.config/opencode/skills/mnemonic -cp /path/to/mnemonic/templates/codex-skill/SKILL.md ~/.config/opencode/skills/mnemonic/ -``` - -## Skill Content - -```yaml ---- -name: mnemonic -description: Capture and recall memories using the MIF Level 3 filesystem memory system. ---- - -# Mnemonic Memory Skill - -## Memory Locations -- Global: `${MNEMONIC_ROOT}/{org}/{namespace}/` -- Project: `${MNEMONIC_ROOT}/{namespace}/` - -## Commands - -### Recall Memories -```bash -rg -i "" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -``` - -### Capture Memory -Write to `${MNEMONIC_ROOT}/default/{namespace}/user/{slug}.memory.md` - -## Capture Triggers -- "let's use X" → decisions/ -- "learned that" → learnings/ -- "the pattern is" → patterns/ -- "blocked by" → blockers/ -``` - -## Usage - -Once installed, the skill is automatically available: - -``` -@mnemonic search authentication -@mnemonic capture "Decided to use OAuth 2.0" -``` - -## Verification - -1. List available skills in OpenCode -2. Invoke `@mnemonic` to verify it's recognized -3. Test search and capture operations - -## Compatibility - -OpenCode also supports `.claude/skills/` paths, making it compatible with Claude Code skills. The same skill file works in both environments. - -## Sources - -- [OpenCode Agent Skills](https://opencode.ai/docs/skills) -- [GitHub - opencode-skills](https://github.com/malhashemi/opencode-skills) diff --git a/docs/archive/integrations/windsurf.md b/docs/archive/integrations/windsurf.md deleted file mode 100644 index 23473e6..0000000 --- a/docs/archive/integrations/windsurf.md +++ /dev/null @@ -1,311 +0,0 @@ -# Windsurf (Codeium) Integration - -Integrate Mnemonic with Windsurf's Cascade AI using Rules and Memories. - -## Overview - -Windsurf's Cascade has built-in memory capabilities. This integration configures it to use Mnemonic's filesystem-based memory format for portability across tools. - -## Setup - -### Configure Rules - -1. Open Windsurf -2. Navigate to **Settings > Cascade > Rules** -3. Add the following rules: - -``` -When I ask you to remember something, create a memory file at: -${MNEMONIC_ROOT}/default/{namespace}/user/ - -Use MIF Level 3 format with YAML frontmatter: -- id: UUID -- type: semantic|episodic|procedural -- namespace: {namespace}/user -- created: ISO8601 timestamp -- title: Descriptive title -- tags: array - -Before implementing features, search for relevant memories: -rg -i "" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -Capture decisions to decisions/, learnings to learnings/, patterns to patterns/. -``` - -### Memory Namespace Mapping - -Map Cascade's built-in memories to Mnemonic namespaces: - -| Cascade Memory Type | Mnemonic Namespace | -|--------------------|--------------------| -| Preferences | context/ | -| Decisions | decisions/ | -| Learnings | learnings/ | -| Patterns | patterns/ | - -## Usage - -### Natural Language - -``` -"Remember that we're using PostgreSQL for the database" -"What do we know about authentication?" -"Capture this as a pattern: always use dependency injection" -``` - -### Explicit Commands - -``` -"Create a mnemonic memory about using REST over GraphQL" -"Search mnemonic for database decisions" -``` - -## Syncing with Built-in Memories - -Windsurf Cascade generates memories automatically. To sync these with Mnemonic: - -1. Export Cascade memories periodically -2. Convert to MIF Level 3 format -3. Store in appropriate Mnemonic namespace - -## Verification - -1. Create a test memory: "Remember that this is a test" -2. Check `${MNEMONIC_ROOT}/default/context/user/` for the file -3. Ask Cascade: "What do you remember about tests?" - -## Limitations - -- UI-based configuration only -- No direct file system access in some modes -- Automatic memory sync requires manual intervention - ---- - -## Common Workflows - -### Daily Development - -``` -Morning: -1. Open project in Windsurf -2. Ask Cascade: "What context do we have about this project?" -3. Continue where you left off - -During Development: -1. Before implementing: "Check memories for [feature] patterns" -2. After decisions: "Remember we decided to use [approach]" -3. After debugging: "Store this fix as a learning" - -End of Day: -1. Review Cascade's memory panel -2. Export significant memories to mnemonic format -``` - -### Feature Implementation - -``` -1. "What patterns exist for [component type]?" - → Cascade references patterns/ - -2. "Any decisions about [feature]?" - → Searches decisions/ - -3. Implement following established patterns - -4. "Remember this pattern for future reference" - → Creates memory file -``` - -### Code Review with Memory - -``` -1. Review PR changes -2. "What patterns should this code follow?" -3. "Any prior decisions about this area?" -4. Reference memories in review comments -``` - ---- - -## Advanced Patterns - -### Bidirectional Sync - -Sync between Cascade's built-in memories and mnemonic files: - -```bash -# Export mnemonic to Cascade-readable format -./tools/mnemonic-export --format windsurf > .windsurf/memories/project.md - -# Import Cascade memories to mnemonic -./tools/import-cascade-memories \ - --source ~/.windsurf/memories/ \ - --target ${MNEMONIC_ROOT}/default/ -``` - -### Project-Specific Configuration - -Create project-level rules in `.windsurfrules`: - -```markdown -# Project Memory Configuration - -Memory storage: ${MNEMONIC_ROOT}/this-project/ - -## Namespaces -- decisions/ - Architectural decisions -- patterns/ - Code patterns and conventions -- apis/ - API documentation -- testing/ - Testing strategies - -## Capture Triggers -- "we decided" → decisions/ -- "use this pattern" → patterns/ -- "learned that" → learnings/ -``` - -### Team Collaboration - -Share memories via git: - -```bash -# Team patterns repository -git clone git@github.com:team/memories.git ${MNEMONIC_ROOT}/team - -# Reference in Windsurf rules -Also check ${MNEMONIC_ROOT}/team/ for shared patterns -``` - ---- - -## Migrating from Windsurf Memories - -If you're using Windsurf's built-in memory system: - -### Step 1: Export Current Memories - -Windsurf stores memories in: -- `.windsurf/memories/` -- Cascade's internal storage - -Export via: -1. Open Cascade settings -2. Navigate to Memory section -3. Export to markdown - -### Step 2: Convert to MIF Format - -```bash -# Manual conversion for each memory -UUID=$(uuidgen | tr '[:upper:]' '[:lower:]') -DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") - -cat > ${MNEMONIC_ROOT}/default/context/user/${UUID}-migrated.memory.md << EOF ---- -id: ${UUID} -type: semantic -namespace: context/user -created: ${DATE} -title: "Migrated from Windsurf" -tags: - - migrated - - windsurf -temporal: - valid_from: ${DATE} - recorded_at: ${DATE} -provenance: - source_type: migration - agent: windsurf-cascade - confidence: 0.9 ---- - -# [Title] - -[Your content here] -EOF -``` - -### Step 3: Update Windsurf Rules - -Add mnemonic paths to your rules: - -```markdown -Memory sources (in priority order): -1. ${MNEMONIC_ROOT}/default/ (mnemonic format) -2. .windsurf/memories/ (legacy) - -For new memories, always use mnemonic format. -``` - -### Step 4: Validate - -```bash -./tools/mnemonic-validate ${MNEMONIC_ROOT}/default/ -``` - -See [Migration Guide](../community/migration-from-memory-bank.md) for complete details. - ---- - -## Troubleshooting - -### Rules Not Applied - -**Symptom**: Cascade ignores mnemonic instructions - -**Solutions**: -1. Check Settings > Cascade > Rules -2. Ensure rules are enabled -3. Restart Windsurf after changes -4. Try explicit memory commands - -### Memory Files Not Created - -**Symptom**: "Remember X" doesn't create files - -**Solutions**: -1. Cascade may store internally first -2. Add explicit instruction: "Create a .memory.md file" -3. Check filesystem access permissions -4. Verify directory exists: - ```bash - mkdir -p ${MNEMONIC_ROOT}/default/context/user/ - ``` - -### Search Not Finding Memories - -**Symptom**: "What do we know about X?" returns nothing - -**Solutions**: -1. Verify memory path in rules -2. Check file permissions -3. Ensure `.memory.md` extension -4. Try: "Search files in ${MNEMONIC_ROOT}/ for X" - -### Sync Issues - -**Symptom**: Cascade memories don't match mnemonic files - -**Solutions**: -1. Export and convert regularly -2. Use explicit file-based storage -3. Set mnemonic as primary source in rules - -### Format Inconsistencies - -**Symptom**: Created memories don't match MIF spec - -**Solutions**: -1. Include full template in rules -2. Run validation after capture -3. Add format example to rules - ---- - -## Sources - -- [Windsurf Cascade Documentation](https://docs.windsurf.com/windsurf/cascade/cascade) -- [Codeium Documentation](https://codeium.com/documentation) -- [Memory Bank Migration](../community/migration-from-memory-bank.md) -- [MIF Level 3 Specification](../../skills/mnemonic-format/SKILL.md) diff --git a/docs/archive/templates/AGENTS.md b/docs/archive/templates/AGENTS.md deleted file mode 100644 index f1eba56..0000000 --- a/docs/archive/templates/AGENTS.md +++ /dev/null @@ -1,126 +0,0 @@ -# Global Agent Instructions - -## Mnemonic Memory System - -You have access to a persistent memory system at `${MNEMONIC_ROOT}/`. This system stores memories as `.memory.md` files with YAML frontmatter (MIF Level 3 format). - -## Required Behavior - -### Before Starting Any Task - -Search for relevant memories: - -```bash -# Search by topic -rg -i "" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# Check specific namespaces -rg -i "" ${MNEMONIC_ROOT}/*/decisions/ --glob "*.memory.md" -rg -i "" ${MNEMONIC_ROOT}/*/patterns/ --glob "*.memory.md" -``` - -### Capture Requirements - -Create memories immediately when: - -| Trigger | Namespace | Type | -|---------|-----------|------| -| Decision made ("let's use X") | decisions/ | semantic | -| Lesson learned ("turns out...") | learnings/ | semantic | -| Pattern established | patterns/ | procedural | -| Blocker encountered | blockers/ | episodic | -| Context to remember | context/ | semantic | - -### Memory Format - -Use MIF Level 3 format with YAML frontmatter: - -```yaml ---- -id: -type: semantic|episodic|procedural -namespace: {namespace}/user -created: -modified: -title: "Descriptive title" -tags: - - tag1 - - tag2 -temporal: - valid_from: - recorded_at: -provenance: - source_type: conversation - agent: - confidence: 0.9 ---- - -# Title - -Content here... -``` - -### Memory Types - -- **semantic**: Facts, decisions, specifications - things that ARE true -- **episodic**: Events, debug sessions, incidents - things that HAPPENED -- **procedural**: Workflows, patterns, how-tos - things you DO - -### Capture Script - -```bash -UUID=$(uuidgen | tr '[:upper:]' '[:lower:]') -DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") -NAMESPACE="decisions" # or: learnings, patterns, blockers, context -TITLE="Your descriptive title" -SLUG=$(echo "$TITLE" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | head -c 50) - -cat > ${MNEMONIC_ROOT}/default/${NAMESPACE}/user/${SLUG}.memory.md << EOF ---- -id: ${UUID} -type: semantic -namespace: ${NAMESPACE}/user -created: ${DATE} -modified: ${DATE} -title: "${TITLE}" -tags: [] -temporal: - valid_from: ${DATE} - recorded_at: ${DATE} -provenance: - source_type: conversation - agent: codex-cli - confidence: 0.9 ---- - -# ${TITLE} - -Content... -EOF -``` - -## Namespaces - -| Namespace | Purpose | -|-----------|---------| -| decisions/ | Architectural choices | -| learnings/ | Insights discovered | -| patterns/ | Code conventions | -| blockers/ | Issues encountered | -| context/ | General context | -| apis/ | API documentation | -| security/ | Security considerations | - -## Do Not - -- Skip searching before implementing -- Announce that you're capturing (just do it silently) -- Forget to capture decisions when made -- Create memories without proper frontmatter - -## Memory Locations - -- **Global**: `${MNEMONIC_ROOT}/{org}/{namespace}/` -- **Project**: `${MNEMONIC_ROOT}/{namespace}/` - -Use global for cross-project knowledge, project-local for project-specific context. diff --git a/docs/archive/templates/CONVENTIONS.md b/docs/archive/templates/CONVENTIONS.md deleted file mode 100644 index 5dd604e..0000000 --- a/docs/archive/templates/CONVENTIONS.md +++ /dev/null @@ -1,126 +0,0 @@ -# Mnemonic Memory Integration - -## Overview - -This project uses Mnemonic for persistent memories across coding sessions. Mnemonic stores memories as `.memory.md` files with YAML frontmatter at `${MNEMONIC_ROOT}/`. - -## Before Implementing - -Always search for relevant memories: - -```bash -# Search by topic -rg -i "" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# Check decisions -rg -i "" ${MNEMONIC_ROOT}/*/decisions/ --glob "*.memory.md" - -# Check patterns -rg -i "pattern" ${MNEMONIC_ROOT}/*/patterns/ --glob "*.memory.md" -``` - -## Capture Requirements - -### When to Capture - -| Trigger | Namespace | Memory Type | -|---------|-----------|-------------| -| Decision made ("let's use X") | decisions/user/ | semantic | -| Lesson learned ("turns out...") | learnings/user/ | semantic | -| Pattern established | patterns/user/ | procedural | -| Blocker encountered | blockers/user/ | episodic | -| Context to remember | context/user/ | semantic | - -### Memory File Location - -``` -${MNEMONIC_ROOT}/default/{namespace}/user/{slug}.memory.md -``` - -### Memory Format (MIF Level 3) - -All memory files must have `.memory.md` extension with YAML frontmatter: - -```yaml ---- -id: -type: semantic|episodic|procedural -namespace: {namespace}/user -created: -modified: -title: "Descriptive title" -tags: - - tag1 - - tag2 -temporal: - valid_from: - recorded_at: -provenance: - source_type: conversation - agent: aider - confidence: 0.9 ---- - -# Title - -Content in markdown format... - -## Context - -Why this decision was made or what was learned. - -## Details - -Specific implementation details or notes. -``` - -## Memory Types - -Choose the correct type for each memory: - -- **semantic**: Facts, decisions, specifications - things that ARE true - - Example: "We use PostgreSQL for the main database" - - Example: "API endpoints follow REST conventions" - -- **episodic**: Events, debug sessions, incidents - things that HAPPENED - - Example: "Fixed authentication bug by updating token validation" - - Example: "Deployed v2.0 to production on 2024-01-15" - -- **procedural**: Workflows, patterns, how-tos - things you DO - - Example: "To deploy: run tests, build, push to registry, apply k8s" - - Example: "Error handling pattern: wrap in try-catch, log, return Result" - -## Namespaces - -| Namespace | Purpose | -|-----------|---------| -| decisions/ | Architectural and design decisions | -| learnings/ | Insights and discoveries | -| patterns/ | Code conventions and patterns | -| blockers/ | Issues and impediments | -| context/ | General project context | -| apis/ | API documentation and contracts | -| security/ | Security considerations | - -## Best Practices - -1. **Search first**: Always check existing memories before implementing -2. **Capture immediately**: Don't wait - capture decisions when they're made -3. **Be descriptive**: Use clear titles that are easy to search -4. **Add context**: Include reasoning and background in the content -5. **Use tags**: Add relevant tags for categorization -6. **Update, don't duplicate**: If a memory exists, update it rather than creating a new one - -## Integration - -This conventions file is designed for use with Aider. Load it with: - -```bash -aider --read CONVENTIONS.md -``` - -Or configure in `.aider.conf.yml`: - -```yaml -read: CONVENTIONS.md -``` diff --git a/docs/archive/templates/codex-skill/SKILL.md b/docs/archive/templates/codex-skill/SKILL.md deleted file mode 100644 index e72da97..0000000 --- a/docs/archive/templates/codex-skill/SKILL.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -name: mnemonic -description: Capture and recall memories from the filesystem-based memory system at ${MNEMONIC_ROOT}. Use for decisions, learnings, patterns, and blockers. ---- - -# Mnemonic Memory Skill - -This skill provides access to the Mnemonic memory system for persistent context across coding sessions. - -## Memory Locations - -- **Global**: `${MNEMONIC_ROOT}/{org}/{namespace}/` -- **Project**: `${MNEMONIC_ROOT}/{namespace}/` - -## Commands - -### Search Memories - -```bash -# By topic -rg -i "" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# By namespace -ls ${MNEMONIC_ROOT}/default/{decisions,learnings,patterns}/user/ - -# By tag (in frontmatter) -rg "tags:.*" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# Recent memories -find ${MNEMONIC_ROOT} -name "*.memory.md" -mtime -7 -``` - -### Capture Memory - -Create a new memory file: - -```bash -UUID=$(uuidgen | tr '[:upper:]' '[:lower:]') -DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") -NAMESPACE="decisions" # or: learnings, patterns, blockers, context -TITLE="Your descriptive title" -SLUG=$(echo "$TITLE" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | head -c 50) - -cat > ${MNEMONIC_ROOT}/default/${NAMESPACE}/user/${SLUG}.memory.md << EOF ---- -id: ${UUID} -type: semantic -namespace: ${NAMESPACE}/user -created: ${DATE} -modified: ${DATE} -title: "${TITLE}" -tags: - - tag1 - - tag2 -temporal: - valid_from: ${DATE} - recorded_at: ${DATE} -provenance: - source_type: conversation - agent: codex-cli - confidence: 0.9 ---- - -# ${TITLE} - -Content here... -EOF -``` - -### List Memories - -```bash -# All memories -find ${MNEMONIC_ROOT} -name "*.memory.md" | head -20 - -# By namespace -ls ${MNEMONIC_ROOT}/default/decisions/user/ -ls ${MNEMONIC_ROOT}/default/learnings/user/ -ls ${MNEMONIC_ROOT}/default/patterns/user/ -``` - -## Memory Types - -| Type | Use For | Example | -|------|---------|---------| -| semantic | Facts, decisions, specs | "We use PostgreSQL" | -| episodic | Events, experiences | "Debug session on auth bug" | -| procedural | Workflows, patterns | "How to deploy to prod" | - -## Namespaces - -| Namespace | Purpose | -|-----------|---------| -| decisions/ | Architectural choices | -| learnings/ | Insights discovered | -| patterns/ | Code conventions | -| blockers/ | Issues encountered | -| context/ | General context | -| apis/ | API documentation | -| security/ | Security considerations | - -## Capture Triggers - -Automatically capture when: -- "let's use X" or "we'll go with X" → decisions/ -- "I learned" or "turns out" → learnings/ -- "the pattern is" or "convention" → patterns/ -- "blocked by" or "issue with" → blockers/ - -## Best Practices - -1. Search before implementing to check for existing decisions -2. Capture decisions immediately when made -3. Use descriptive titles for easy searching -4. Add relevant tags for categorization -5. Include context and reasoning in content diff --git a/docs/archive/templates/copilot-instructions.md b/docs/archive/templates/copilot-instructions.md deleted file mode 100644 index 3dc291d..0000000 --- a/docs/archive/templates/copilot-instructions.md +++ /dev/null @@ -1,86 +0,0 @@ -# Project Coding Instructions - -## Mnemonic Memory System - -This project uses Mnemonic for persistent memory across coding sessions. - -### Before Implementing Features - -Always search for existing memories: - -```bash -# Search by topic -rg -i "" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# Check patterns -rg -i "pattern" ${MNEMONIC_ROOT}/*/patterns/ - -# Check decisions -rg -i "" ${MNEMONIC_ROOT}/*/decisions/ -``` - -### Memory Capture Requirements - -When making decisions or learning something new, create a memory file: - -- **Location**: `${MNEMONIC_ROOT}/default/{namespace}/user/` -- **Format**: `.memory.md` with YAML frontmatter -- **Namespaces**: decisions, learnings, patterns, blockers, context - -### When to Capture - -| Trigger | Namespace | -|---------|-----------| -| Decision made ("let's use X") | decisions/ | -| Lesson learned ("turns out...") | learnings/ | -| Pattern established | patterns/ | -| Blocker encountered | blockers/ | -| Context to remember | context/ | - -### Memory File Format - -```yaml ---- -id: -type: semantic|episodic|procedural -namespace: decisions/user -created: -modified: -title: "Descriptive title" -tags: - - tag1 - - tag2 -temporal: - valid_from: - recorded_at: -provenance: - source_type: conversation - agent: github-copilot - confidence: 0.9 ---- - -# Title - -Content here in markdown format... - -## Context - -Why this decision was made or what was learned. - -## Details - -Specific implementation details or notes. -``` - -### Memory Types - -- **semantic**: Facts, decisions, specifications - things that ARE true -- **episodic**: Events, debug sessions, incidents - things that HAPPENED -- **procedural**: Workflows, patterns, how-tos - things you DO - -### Integration Notes - -- Search memories before making architectural decisions -- Capture decisions immediately when made -- Reference existing patterns when implementing new features -- Update memories when information changes (increment version) diff --git a/docs/archive/templates/cursor-rule.mdc b/docs/archive/templates/cursor-rule.mdc deleted file mode 100644 index 91f8a21..0000000 --- a/docs/archive/templates/cursor-rule.mdc +++ /dev/null @@ -1,112 +0,0 @@ ---- -description: "Mnemonic memory system for persistent context across sessions" -alwaysApply: true ---- - -# Mnemonic Memory System - -## Overview - -Mnemonic is a filesystem-based memory system that persists context across coding sessions. All memories are stored as `.memory.md` files with YAML frontmatter (MIF Level 3 format). - -## Memory Storage - -Location: `${MNEMONIC_ROOT}/` - -Structure: -``` -${MNEMONIC_ROOT}/ -└── default/ - ├── decisions/user/ - ├── learnings/user/ - ├── patterns/user/ - ├── blockers/user/ - └── context/user/ -``` - -## Required Behavior - -### Before Implementing - -Always search for relevant memories: - -```bash -rg -i "" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -``` - -### Capture Triggers - -Create memories when: - -| Trigger | Namespace | Type | -|---------|-----------|------| -| Decision made ("let's use X") | decisions/ | semantic | -| Lesson learned ("turns out...") | learnings/ | semantic | -| Pattern established | patterns/ | procedural | -| Blocker encountered | blockers/ | episodic | -| Context to remember | context/ | semantic | - -### Memory Format - -```yaml ---- -id: -type: semantic|episodic|procedural -namespace: {namespace}/user -created: -modified: -title: "Descriptive title" -tags: - - tag1 - - tag2 -temporal: - valid_from: - recorded_at: -provenance: - source_type: conversation - agent: cursor - confidence: 0.9 ---- - -# Title - -Content here... -``` - -## Memory Types - -- **semantic**: Facts, decisions, specifications - things that ARE true -- **episodic**: Events, debug sessions, incidents - things that HAPPENED -- **procedural**: Workflows, patterns, how-tos - things you DO - -## Capture Script - -```bash -UUID=$(uuidgen | tr '[:upper:]' '[:lower:]') -DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") -NAMESPACE="decisions" -TITLE="Your title" -SLUG=$(echo "$TITLE" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | head -c 50) - -cat > ${MNEMONIC_ROOT}/default/${NAMESPACE}/user/${SLUG}.memory.md << 'EOF' ---- -id: ${UUID} -type: semantic -namespace: ${NAMESPACE}/user -created: ${DATE} -title: "${TITLE}" -tags: [] ---- - -# ${TITLE} - -Content... -EOF -``` - -## Do Not - -- Skip searching before implementing -- Forget to capture decisions when made -- Create memories without proper frontmatter -- Use incorrect memory types diff --git a/docs/archive/templates/mnemonic-protocol.md b/docs/archive/templates/mnemonic-protocol.md deleted file mode 100644 index dcb273a..0000000 --- a/docs/archive/templates/mnemonic-protocol.md +++ /dev/null @@ -1,10 +0,0 @@ - -## Memory - -Search first: `/mnemonic:search {relevant_keywords}` -Capture after: `/mnemonic:capture {namespace} "{title}"` - -Run `/mnemonic:list --namespaces` to see available namespaces from loaded ontologies. - -Example: `/mnemonic:capture _semantic/decisions "Use PostgreSQL for data storage"` - diff --git a/docs/archive/templates/plugin-hooks/README.md b/docs/archive/templates/plugin-hooks/README.md deleted file mode 100644 index 319d377..0000000 --- a/docs/archive/templates/plugin-hooks/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# Plugin Hooks Templates - -Templates for integrating mnemonic memory operations into other Claude Code plugins. - -## Files - -### `mnemonic-suggest.py` - -A template Python hook that detects file creation events and suggests mnemonic memory capture. - -**To use:** - -1. Copy to target plugin's `hooks/` directory -2. Customize the `PLUGIN_PATTERNS` dict for your plugin's file patterns -3. Update `PLUGIN_NAME` constant -4. Create or update `hooks.json` to include this hook - -### `hooks.json.template` - -Example hooks.json configuration that triggers the mnemonic-suggest hook on Write tool use. - -**To use:** - -1. Copy as `hooks.json` to target plugin's `hooks/` directory -2. Merge with existing hooks.json if one exists - -## How It Works - -1. Claude uses the Write tool to create a file -2. PostToolUse hook runs `mnemonic-suggest.py` -3. Hook checks if file path matches any plugin patterns -4. If match found, injects `additionalContext` suggesting memory capture -5. Claude sees suggestion and captures memory with full conversation context - -## Customization - -The `PLUGIN_PATTERNS` dict maps regex patterns to capture configurations: - -```python -PLUGIN_PATTERNS = { - r"/adr/.*\.md$": { - "event": "ADR created", - "namespace": "decisions", - "capture_hint": "Capture decision rationale...", - "tags": ["architecture", "adr"], - }, -} -``` - -**Fields:** -- `event`: Human-readable description of what happened -- `namespace`: Target mnemonic namespace (decisions, learnings, patterns, etc.) -- `capture_hint`: Guidance for Claude on what to capture -- `tags`: Suggested tags for the memory - -## Integration with `/mnemonic:plugin-integration` - -The plugin-integration skill can automatically set up these templates for a target plugin. - -```bash -/mnemonic:plugin-integration ~/.claude/plugins/cache/your-org/your-plugin/ -``` - -This will: -1. Analyze the plugin structure -2. Copy and customize these templates -3. Add workflow sections to command/skill markdown files diff --git a/docs/archive/templates/plugin-hooks/hooks.json.template b/docs/archive/templates/plugin-hooks/hooks.json.template deleted file mode 100644 index 83007b5..0000000 --- a/docs/archive/templates/plugin-hooks/hooks.json.template +++ /dev/null @@ -1,15 +0,0 @@ -{ - "hooks": { - "PostToolUse": [ - { - "matcher": "Write", - "hooks": [ - { - "type": "command", - "command": "${CLAUDE_PLUGIN_ROOT}/hooks/mnemonic-suggest.py" - } - ] - } - ] - } -} diff --git a/docs/archive/templates/plugin-hooks/mnemonic-suggest.py b/docs/archive/templates/plugin-hooks/mnemonic-suggest.py deleted file mode 100644 index 3423955..0000000 --- a/docs/archive/templates/plugin-hooks/mnemonic-suggest.py +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env python3 -""" -Mnemonic Integration Hook Template - -This is a template for creating plugin-specific mnemonic integration hooks. -Copy this file to the target plugin's hooks directory and customize the -detection logic for that plugin's file patterns. - -Usage: -1. Copy to {plugin_path}/hooks/mnemonic-suggest.py -2. Add to hooks.json PostToolUse for Write matcher -3. Customize the PLUGIN_PATTERNS dict for your plugin - -Hook Contract: -- Receives CLAUDE_TOOL_INPUT with tool parameters as JSON -- Outputs JSON with continue: true and optional additionalContext -- additionalContext is shown to Claude as context for the current turn -""" - -import json -import os -import re -from pathlib import Path - -# ============================================================================= -# CUSTOMIZE THIS SECTION FOR YOUR PLUGIN -# ============================================================================= - -# Plugin name for context -PLUGIN_NAME = "your-plugin" - -# File pattern detection rules -# Each rule maps a file pattern to capture suggestions -PLUGIN_PATTERNS = { - # Example: ADR files - r"/adr/.*\.md$": { - "event": "ADR created", - "namespace": "decisions", - "capture_hint": "Capture decision rationale including: decision drivers, chosen option, alternatives considered, consequences", - "tags": ["architecture", "adr"], - }, - # Example: Documentation files - r"/docs/.*\.md$": { - "event": "Documentation created", - "namespace": "learnings", - "capture_hint": "Capture key documentation points for future reference", - "tags": ["documentation"], - }, - # Example: Config files - r"\.config\.(js|ts|json)$": { - "event": "Configuration created", - "namespace": "patterns", - "capture_hint": "Capture configuration pattern and rationale", - "tags": ["configuration", "patterns"], - }, - # Add more patterns as needed for your plugin -} - -# Namespaces and their typical content -NAMESPACE_HINTS = { - "decisions": "Architectural choices, technology selections, design decisions", - "learnings": "Insights, discoveries, documentation, TILs", - "patterns": "Coding conventions, best practices, workflows", - "blockers": "Issues, impediments, workarounds", - "context": "Background information, project state", -} - -# ============================================================================= -# HOOK IMPLEMENTATION (Usually no changes needed below) -# ============================================================================= - - -def match_pattern(file_path: str) -> dict | None: - """Match file path against plugin patterns.""" - for pattern, config in PLUGIN_PATTERNS.items(): - if re.search(pattern, file_path, re.IGNORECASE): - return config - return None - - -def get_project_context() -> str: - """Get current project context for the suggestion.""" - try: - cwd = os.getcwd() - project_name = Path(cwd).name - return f"Project: {project_name}" - except Exception: - return "Project: unknown" - - -def format_capture_suggestion(file_path: str, config: dict) -> str: - """Format the mnemonic capture suggestion for Claude.""" - namespace = config.get("namespace", "learnings") - namespace_hint = NAMESPACE_HINTS.get(namespace, "General knowledge") - tags = config.get("tags", []) - tags_str = ", ".join(tags) if tags else "relevant-tag" - - return f""" -**MNEMONIC CAPTURE SUGGESTED:** -- Event: {config.get('event', 'File created')} -- File: {file_path} -- Namespace: {namespace} ({namespace_hint}) -- Suggested tags: {tags_str} - -{config.get('capture_hint', 'Capture key details for future recall.')} - -Use progressive disclosure format: -- **Quick Answer:** 1-3 sentence summary -- **Context:** Why this was created, alternatives considered -- **Full Detail:** Implementation notes, related decisions - -Capture command template: -```bash -UUID=$(uuidgen | tr '[:upper:]' '[:lower:]') -DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") -# Write memory to ${MNEMONIC_ROOT}/default/{namespace}/user/${{UUID}}-slug.memory.md -``` -""" - - -def main(): - """Main hook entry point.""" - # Parse tool input from environment - tool_input_raw = os.environ.get("CLAUDE_TOOL_INPUT", "{}") - try: - tool_input = json.loads(tool_input_raw) - except json.JSONDecodeError: - tool_input = {} - - # Get file path from Write tool input - file_path = tool_input.get("file_path", "") - - if not file_path: - # No file path, nothing to suggest - print(json.dumps({"continue": True})) - return - - # Check if file matches any plugin patterns - config = match_pattern(file_path) - - if config: - # Generate capture suggestion - context = format_capture_suggestion(file_path, config) - project_ctx = get_project_context() - - output = { - "continue": True, - "hookSpecificOutput": { - "hookEventName": "PostToolUse", - "additionalContext": f"{project_ctx}\n{context}" - } - } - print(json.dumps(output)) - else: - # No matching pattern, continue without suggestion - print(json.dumps({"continue": True})) - - -if __name__ == "__main__": - main() diff --git a/docs/enterprise/README.md b/docs/enterprise/README.md deleted file mode 100644 index 21a12ff..0000000 --- a/docs/enterprise/README.md +++ /dev/null @@ -1,136 +0,0 @@ -# Mnemonic for Enterprise - -Enterprise-grade AI memory with complete audit trails, data sovereignty, and research-validated performance. - -## Quick Facts - -| Metric | Value | Source | -|--------|-------|--------| -| **Accuracy** | 74.0% vs 68.5% for competitors | [Letta LoCoMo Benchmark](https://www.letta.com/blog/benchmarking-ai-agent-memory) | -| **Audit Trail** | Complete git history | Every change tracked with who, when, what | -| **Data Sovereignty** | 100% local storage | No cloud, no third-party dependencies | -| **Integration** | Claude Code plugin | Native integration with Claude Code | -| **Format** | MIF Level 3 | Open standard, human-readable | - ---- - -## Research-Validated Performance - -Traditional AI memory systems use vector databases or knowledge graphs. Research shows this adds complexity without improving accuracy. - -**Letta's LoCoMo Benchmark Results:** - -``` -Filesystem approach: ████████████████████████ 74.0% -Mem0 (graph-based): ████████████████████ 68.5% - ───────────────────────────── - 0% 100% -``` - -The reason? LLMs are pretrained on filesystem operations. Simple tools are more reliable than specialized abstractions. - -Read more: ["From Everything is a File to Files Are All You Need"](https://arxiv.org/abs/2601.11672) (arXiv:2601.11672) - ---- - -## For Enterprise Architects - -**You need:** Compliance, governance, audit trails, data sovereignty - -**Mnemonic delivers:** -- Full git history of every memory change (who, when, what, why) -- Local-only storage—no cloud, no third-party dependencies -- Human-readable markdown format for audit reviews -- Bi-temporal tracking (valid time vs recorded time) per SQL:2011 standard -- MIF schema validation for data quality assurance - -[→ Read the Compliance & Governance Guide](./compliance-governance.md) - ---- - -## For Engineering Managers - -**You need:** Team productivity, knowledge retention, tool flexibility - -**Mnemonic delivers:** -- Cross-session memory reduces context switching overhead -- Open format prevents vendor lock-in -- Shared patterns namespace accelerates team onboarding -- Episodic memory reduces repeated debugging efforts -- Zero infrastructure costs—pure filesystem storage - -[→ Read the Productivity & ROI Guide](./productivity-roi.md) - ---- - -## For Individual Developers - -**You need:** Privacy, control, customization - -**Mnemonic delivers:** -- Zero telemetry—your memories stay on your machine -- Git-based, readable format you can edit directly -- Scriptable via standard Unix tools (grep, find, ripgrep) -- Portable MIF Level 3 format works across all tools -- Works offline—no network required - -[→ Read the Developer Experience Guide](./developer-experience.md) - ---- - -## Technical Deep Dive - -For technical decision-makers who need academic validation and competitive analysis: - -[→ Research Validation & Benchmarks](./research-validation.md) - ---- - -## Deployment - -For platform teams and DevOps planning enterprise rollout: - -[→ Enterprise Deployment Guide](./deployment-guide.md) - ---- - -## Enterprise Advantages Summary - -| Capability | Mnemonic | Cloud-Based Alternatives | -|------------|----------|-------------------------| -| **Audit Trail** | Full git history with diffs | Limited or API-only access | -| **Data Sovereignty** | 100% local storage | Data on third-party servers | -| **Offline Access** | Always available | Requires network | -| **Vendor Lock-in** | None (open format) | Proprietary formats | -| **Cost** | Zero (filesystem) | Per-seat or usage fees | -| **Compliance** | Self-hosted, auditable | Depends on vendor | -| **Research Validation** | 74% accuracy benchmark | Varies | - ---- - -## Getting Started - -```bash -# Install the plugin -claude settings plugins add /path/to/mnemonic - -# Initialize for your project -/mnemonic:setup - -# Capture your first memory -/mnemonic:capture decisions "Use PostgreSQL for storage" - -# Recall happens automatically—memories load when relevant -``` - ---- - -## Navigation - -- [Compliance & Governance](./compliance-governance.md) - For architects -- [Productivity & ROI](./productivity-roi.md) - For managers -- [Developer Experience](./developer-experience.md) - For developers -- [Research Validation](./research-validation.md) - Technical deep dive -- [Deployment Guide](./deployment-guide.md) - For operations - -[← Back to Main Documentation](../../README.md) diff --git a/docs/enterprise/compliance-governance.md b/docs/enterprise/compliance-governance.md deleted file mode 100644 index fda24f9..0000000 --- a/docs/enterprise/compliance-governance.md +++ /dev/null @@ -1,378 +0,0 @@ -# Compliance & Governance Guide - -For enterprise architects, compliance officers, and security teams. - -## Overview - -Mnemonic provides enterprise-grade AI memory with complete audit capabilities, data sovereignty, and governance controls—all without external dependencies. - ---- - -## Audit Trail Architecture - -### Git-Based Version Control - -Every memory change is tracked with full git history: - -```bash -# View memory change history -cd ${MNEMONIC_ROOT} -git log --oneline -20 - -# See who changed what -git log --pretty=format:"%h %an %ad %s" --date=short - -# View specific memory evolution -git log -p path/to/memory.memory.md - -# Compare versions -git diff HEAD~5 HEAD -- decisions/user/ -``` - -### What Gets Tracked - -| Event | Git Record | Details | -|-------|------------|---------| -| Memory created | New file commit | Author, timestamp, content | -| Memory modified | File change commit | Diff shows exact changes | -| Memory deleted | File removal commit | Preserved in history | -| Batch operations | Grouped commits | gc, compression, etc. | - -### Audit Query Examples - -```bash -# All changes by a specific user -git log --author="engineer@company.com" --oneline - -# Changes in date range -git log --after="2026-01-01" --before="2026-02-01" --oneline - -# Changes to decision memories -git log --oneline -- decisions/ - -# Search for changes mentioning "authentication" -git log -S "authentication" --oneline -``` - ---- - -## Data Sovereignty - -### Local-Only Storage - -All data stays on your infrastructure: - -``` -${MNEMONIC_ROOT}/ # User-level memories -${MNEMONIC_ROOT}/ # Project-level memories -``` - -**No external dependencies:** -- No cloud services -- No API calls -- No telemetry -- No account required -- No network access needed - -### Data Residency Compliance - -| Requirement | How Mnemonic Complies | -|-------------|----------------------| -| **Data stays in jurisdiction** | Filesystem storage only | -| **No cross-border transfers** | No network communication | -| **Right to deletion** | `rm` or git operations | -| **Data portability** | Standard markdown files | -| **Access control** | Filesystem permissions | - -### Encryption Options - -Mnemonic stores plain-text markdown for human readability. For encryption: - -```bash -# Encrypt at rest with filesystem encryption -# macOS: FileVault -# Linux: LUKS, eCryptfs -# Windows: BitLocker - -# Or use git-crypt for repository encryption -cd ${MNEMONIC_ROOT} -git-crypt init -echo "*.memory.md filter=git-crypt diff=git-crypt" >> .gitattributes -``` - ---- - -## Compliance Framework Alignment - -### SOC 2 - -| Trust Principle | Mnemonic Support | -|-----------------|------------------| -| **Security** | Filesystem permissions, no external access | -| **Availability** | Local storage, no network dependency | -| **Processing Integrity** | Git versioning, validation tool | -| **Confidentiality** | Local-only, encryption-ready | -| **Privacy** | No data collection, no telemetry | - -### ISO 27001 - -| Control Area | Implementation | -|--------------|----------------| -| **A.8 Asset Management** | Memory files are versioned assets | -| **A.9 Access Control** | Filesystem permissions | -| **A.12 Operations Security** | Validation tool, gc commands | -| **A.14 System Acquisition** | Open source, auditable code | -| **A.18 Compliance** | Local storage, audit logs | - -### GDPR Considerations - -| Right | Implementation | -|-------|----------------| -| **Right to Access** | `cat memory.md` - human readable | -| **Right to Rectification** | Direct file editing | -| **Right to Erasure** | `rm` or `git rm` | -| **Right to Portability** | Standard markdown export | -| **Data Minimization** | gc with TTL policies | - ---- - -## Retention & Lifecycle Policies - -### Garbage Collection - -```bash -# Clean up expired memories (TTL-based) -/mnemonic:gc --ttl 90d - -# Archive low-strength memories -/mnemonic:gc --min-strength 0.3 - -# Compress large old memories -/mnemonic:gc --compress - -# Dry run to preview changes -/mnemonic:gc --dry-run -``` - -### Policy Configuration - -Define retention policies in your organization's CLAUDE.md: - -```markdown -## Memory Retention Policy - -- **Decisions**: Retain indefinitely (semantic, slow decay) -- **Learnings**: 1 year retention -- **Episodic**: 90 days retention -- **Blockers**: Archive after resolution + 30 days -``` - -### Bi-Temporal Tracking - -Mnemonic implements SQL:2011 temporal patterns: - -```yaml -temporal: - valid_from: 2026-01-15T00:00:00Z # When this became true - recorded_at: 2026-01-20T10:30:00Z # When we recorded it -``` - -This supports: -- **Corrections**: Update valid_from without losing when you learned it -- **Audit**: Distinguish between truth time and knowledge time -- **Compliance**: Full temporal audit trail - ---- - -## Data Quality Assurance - -### Schema Validation - -```bash -# Validate all memories against MIF Level 3 schema -./tools/mnemonic-validate - -# CI-friendly JSON output -./tools/mnemonic-validate --format json - -# Validate only changed files -./tools/mnemonic-validate --changed -``` - -### Validation Checks - -| Check | Purpose | -|-------|---------| -| **Required fields** | Ensure complete metadata | -| **UUID format** | Unique identification | -| **ISO 8601 timestamps** | Standard date format | -| **Type enumeration** | semantic/episodic/procedural | -| **Provenance** | Track data origin | - -### Automated Validation - -Add to CI/CD pipeline: - -```yaml -# .github/workflows/validate-memories.yml -name: Validate Memories -on: - push: - paths: ['**/*.memory.md'] -jobs: - validate: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Validate memories - run: ./tools/mnemonic-validate --format json -``` - ---- - -## Security Model - -### Access Control - -```bash -# Restrict access to memory directory -chmod 700 ${MNEMONIC_ROOT} - -# Read-only for shared memories -chmod 444 ${MNEMONIC_ROOT}/shared/*.memory.md -``` - -### Threat Model - -| Threat | Mitigation | -|--------|------------| -| **Unauthorized access** | Filesystem permissions | -| **Data exfiltration** | No network access | -| **Tampering** | Git signatures (`git commit -S`) | -| **Data loss** | Git remote backup | -| **Injection attacks** | Markdown sanitization | - -### Git Signing - -For tamper-evident audit trails: - -```bash -cd ${MNEMONIC_ROOT} -git config commit.gpgsign true -git config user.signingkey YOUR_KEY_ID -``` - ---- - -## Enterprise Deployment Patterns - -### Centralized Memory Repository - -``` -Git Server (GitHub Enterprise / GitLab) - │ - ├── org/mnemonic-decisions (shared decisions) - ├── org/mnemonic-patterns (shared patterns) - └── user/* (individual memories) -``` - -### Team Memory Sharing - -```bash -# Clone shared memory repository -git clone git@github.com:org/shared-memories.git ${MNEMONIC_ROOT}/shared - -# Pull latest shared memories -cd ${MNEMONIC_ROOT}/shared && git pull - -# Contribute to shared memories -git add new-pattern.memory.md -git commit -m "Add authentication pattern" -git push -``` - -### Backup Strategy - -```bash -# Automated backup -0 2 * * * tar -czf ~/backups/mnemonic-$(date +%Y%m%d).tar.gz ${MNEMONIC_ROOT}/ - -# Git remote backup -cd ${MNEMONIC_ROOT} -git remote add backup git@backup-server:mnemonic.git -git push backup main -``` - ---- - -## Governance Controls - -### Memory Classification - -Use namespaces for access control: - -| Namespace | Classification | Access | -|-----------|---------------|--------| -| `security/` | Confidential | Security team only | -| `decisions/` | Internal | Engineering team | -| `patterns/` | Public | All developers | -| `personal/` | Private | Individual only | - -### Review Workflows - -Require PR review for shared memories: - -```yaml -# .github/CODEOWNERS -decisions/*.memory.md @engineering-leads -security/*.memory.md @security-team -patterns/*.memory.md @architects -``` - -### Provenance Tracking - -Every memory includes origin information: - -```yaml -provenance: - source_type: conversation # How it was captured - agent: claude-opus-4 # Which model - confidence: 0.95 # Confidence score -``` - ---- - -## Monitoring & Alerting - -### Memory System Health - -```bash -# Count memories by namespace -find ${MNEMONIC_ROOT} -name "*.memory.md" | \ - sed 's|.*/\([^/]*\)/[^/]*/[^/]*$|\1|' | sort | uniq -c - -# Check for validation errors -./tools/mnemonic-validate --format json | jq '.summary.errors' - -# Monitor memory growth -du -sh ${MNEMONIC_ROOT}/ -``` - -### Audit Log Export - -```bash -# Export audit log for compliance review -cd ${MNEMONIC_ROOT} -git log --pretty=format:'%H,%an,%ae,%ad,%s' --date=iso > audit-log.csv -``` - ---- - -## Related Documentation - -- [Research Validation](./research-validation.md) - Academic foundations -- [Deployment Guide](./deployment-guide.md) - Enterprise rollout -- [Validation Tool](../validation.md) - Schema validation details -- [ADR-001](../adrs/adr-001-filesystem-based-storage.md) - Storage architecture decision - -[← Back to Enterprise Overview](./README.md) diff --git a/docs/enterprise/deployment-guide.md b/docs/enterprise/deployment-guide.md deleted file mode 100644 index a78a55c..0000000 --- a/docs/enterprise/deployment-guide.md +++ /dev/null @@ -1,576 +0,0 @@ -# Enterprise Deployment Guide - -For platform teams, DevOps engineers, and IT administrators planning organization-wide rollout. - -## Overview - -Mnemonic is designed for zero-infrastructure deployment. This guide covers enterprise patterns for team coordination, backup, and governance. - ---- - -## Deployment Architectures - -### Individual Deployment (Default) - -Each developer has their own memory store: - -``` -Developer Workstation -└── ${MNEMONIC_ROOT}/ - └── {org}/ - ├── decisions/user/ - ├── learnings/user/ - ├── patterns/user/ - └── ... -``` - -**Pros**: Simple, private, no coordination needed -**Cons**: No team memory sharing - -### Team Shared Repository - -Centralized memories via git: - -``` -Git Server (GitHub Enterprise / GitLab) -└── team-memories.git - ├── decisions/team/ - ├── patterns/team/ - └── context/team/ - -Developer Workstation -└── ${MNEMONIC_ROOT}/ - ├── shared/ # Clone of team-memories.git - │ ├── decisions/team/ - │ └── patterns/team/ - └── {org}/ # Personal memories - └── learnings/user/ -``` - -**Setup:** -```bash -# Each developer -git clone git@github.com:org/team-memories.git ${MNEMONIC_ROOT}/shared - -# Sync daily -cd ${MNEMONIC_ROOT}/shared && git pull -``` - -### Organization Memory Hub - -Multi-team architecture: - -``` -Git Server -├── org-decisions.git # Company-wide decisions -├── security-policies.git # Security team memories -├── team-a-memories.git # Team A -├── team-b-memories.git # Team B -└── ... - -Developer Workstation -└── ${MNEMONIC_ROOT}/ - ├── org/ # Clone of org-decisions - ├── security/ # Clone of security-policies - ├── team/ # Clone of team-X-memories - └── personal/ # Local only -``` - ---- - -## Installation Methods - -### Manual Installation - -```bash -# Clone mnemonic plugin -git clone https://github.com/zircote/mnemonic.git ~/tools/mnemonic - -# Register with Claude Code -claude settings plugins add ~/tools/mnemonic - -# Initialize -/mnemonic:setup -``` - -### Scripted Installation - -```bash -#!/bin/bash -# install-mnemonic.sh - -MNEMONIC_VERSION="1.0.0" -INSTALL_DIR="$HOME/tools/mnemonic" - -# Download -git clone --branch v${MNEMONIC_VERSION} \ - https://github.com/zircote/mnemonic.git "$INSTALL_DIR" - -# Register -claude settings plugins add "$INSTALL_DIR" - -# Initialize directories -mkdir -p ${MNEMONIC_ROOT}/default/{decisions,learnings,patterns,blockers,context,apis,security,testing,episodic}/{user,project,shared} - -# Initialize git -cd ${MNEMONIC_ROOT} -git init -git add . -git commit -m "Initialize mnemonic" - -echo "Mnemonic installed successfully" -``` - -### Configuration Management - -**Ansible Example:** -```yaml -# roles/mnemonic/tasks/main.yml -- name: Clone mnemonic - git: - repo: https://github.com/zircote/mnemonic.git - dest: "{{ ansible_env.HOME }}/tools/mnemonic" - version: "v1.0.0" - -- name: Create memory directories - file: - path: "{{ ansible_env.HOME }}/.claude/mnemonic/default/{{ item }}/user" - state: directory - loop: - - decisions - - learnings - - patterns - - blockers - - context - -- name: Initialize git repository - command: git init - args: - chdir: "{{ ansible_env.HOME }}/.claude/mnemonic" - creates: "{{ ansible_env.HOME }}/.claude/mnemonic/.git" -``` - ---- - -## Git Server Integration - -### GitHub Enterprise - -```bash -# Create organization repository -gh repo create org/shared-memories --private - -# Clone to shared location -git clone git@github.com:org/shared-memories.git ${MNEMONIC_ROOT}/shared - -# Add branch protection -gh api repos/org/shared-memories/branches/main/protection \ - -X PUT \ - -f required_pull_request_reviews.required_approving_review_count=1 -``` - -### GitLab - -```bash -# Create project -glab project create shared-memories --group org --private - -# Clone -git clone git@gitlab.com:org/shared-memories.git ${MNEMONIC_ROOT}/shared - -# Configure merge request approvals -glab mr approval-rule create \ - --name "Memory Review" \ - --approvals-required 1 \ - --project org/shared-memories -``` - -### Self-Hosted Git - -```bash -# Gitea, Gogs, or bare git server -git clone git@git.internal:memories/shared.git ${MNEMONIC_ROOT}/shared -``` - ---- - -## Backup Strategies - -### Local Backup - -```bash -# Cron job for daily backup -# Add to crontab: crontab -e -0 2 * * * tar -czf ~/backups/mnemonic-$(date +\%Y\%m\%d).tar.gz ${MNEMONIC_ROOT}/ - -# Keep last 30 backups -find ~/backups -name "mnemonic-*.tar.gz" -mtime +30 -delete -``` - -### Git Remote Backup - -```bash -# Add backup remote -cd ${MNEMONIC_ROOT} -git remote add backup git@backup-server:mnemonic.git - -# Push to backup (cron job) -0 3 * * * cd ${MNEMONIC_ROOT} && git push backup main - -# Or push to multiple remotes -git remote set-url --add --push origin git@github.com:user/mnemonic.git -git remote set-url --add --push origin git@backup:mnemonic.git -``` - -### Cloud Sync (Optional) - -```bash -# Dropbox/iCloud/OneDrive -ln -s ${MNEMONIC_ROOT} ~/Dropbox/mnemonic-backup - -# Or rsync to cloud storage -rsync -avz ${MNEMONIC_ROOT}/ s3://bucket/mnemonic/ -``` - ---- - -## Disaster Recovery - -### Full Restore - -```bash -# From tar backup -tar -xzf ~/backups/mnemonic-20260124.tar.gz -C ~/ - -# From git remote -git clone git@backup-server:mnemonic.git ${MNEMONIC_ROOT} -``` - -### Point-in-Time Recovery - -```bash -cd ${MNEMONIC_ROOT} - -# Find commit from desired date -git log --before="2026-01-20" --oneline | head -1 - -# Restore to that point -git checkout abc123 -- . - -# Or create branch from that point -git checkout -b recovery-20260120 abc123 -``` - -### Corruption Recovery - -```bash -# If git is corrupted -rm -rf ${MNEMONIC_ROOT}/.git -git init -git add . -git commit -m "Recover from corruption" - -# Re-add remote -git remote add origin git@github.com:user/mnemonic.git -``` - ---- - -## Team Memory Sharing - -### Namespace Strategy - -``` -${MNEMONIC_ROOT}/ -├── org/ # Organization-wide (read-only for most) -│ ├── decisions/shared/ # Company architectural decisions -│ ├── patterns/shared/ # Standard code patterns -│ └── security/shared/ # Security policies -├── team/ # Team-specific (read-write for team) -│ ├── decisions/team/ # Team decisions -│ ├── patterns/team/ # Team patterns -│ └── context/team/ # Project context -└── personal/ # Individual (private) - ├── learnings/user/ # Personal learnings - └── episodic/user/ # Personal experiences -``` - -### Contribution Workflow - -```bash -# Developer wants to share a pattern -cd ${MNEMONIC_ROOT}/team - -# Create memory -cat > patterns/team/uuid-new-pattern.memory.md << 'EOF' ---- -id: uuid-here -type: procedural -namespace: patterns/team -... -EOF - -# Submit for review -git add patterns/team/uuid-new-pattern.memory.md -git commit -m "Add API pagination pattern" -git push origin feature/pagination-pattern - -# Create PR for review -gh pr create --title "Add pagination pattern" --body "..." -``` - -### Access Control - -**CODEOWNERS file:** -``` -# .github/CODEOWNERS -decisions/shared/*.memory.md @org/architects -security/shared/*.memory.md @org/security-team -patterns/shared/*.memory.md @org/tech-leads -``` - -**Branch protection:** -- Require PR reviews for shared memories -- Require specific team approval for security namespace -- Allow direct push for personal namespace - ---- - -## Migration Strategies - -### From Memory Bank - -```bash -# Use migration tool -./tools/migrate-memory-bank \ - --source ~/old-memory-bank \ - --target ${MNEMONIC_ROOT}/default \ - --namespace learnings -``` - -### From Other Systems - -```bash -# Generic markdown migration -for f in ~/old-memories/*.md; do - UUID=$(uuidgen | tr '[:upper:]' '[:lower:]') - DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") - TITLE=$(head -1 "$f" | sed 's/^# //') - - cat > ${MNEMONIC_ROOT}/default/context/user/${UUID}-migrated.memory.md << EOF ---- -id: ${UUID} -type: semantic -namespace: context/user -created: ${DATE} -title: "${TITLE}" -tags: [migrated] ---- - -$(cat "$f") -EOF -done -``` - -### Validation After Migration - -```bash -# Validate all migrated memories -./tools/mnemonic-validate ${MNEMONIC_ROOT}/ - -# Check for errors -./tools/mnemonic-validate --format json | jq '.summary' -``` - ---- - -## Monitoring - -### Memory System Health - -```bash -#!/bin/bash -# health-check.sh - -MEMORY_DIR="$MNEMONIC_ROOT" - -# Count by namespace -echo "=== Memory Counts ===" -find "$MEMORY_DIR" -name "*.memory.md" | \ - sed 's|.*/\([^/]*\)/[^/]*/.*|\1|' | sort | uniq -c - -# Total size -echo -e "\n=== Total Size ===" -du -sh "$MEMORY_DIR" - -# Recent activity -echo -e "\n=== Last 5 Changes ===" -cd "$MEMORY_DIR" && git log --oneline -5 - -# Validation status -echo -e "\n=== Validation ===" -./tools/mnemonic-validate --format json 2>/dev/null | \ - jq -r '"Valid: \(.summary.valid), Errors: \(.summary.errors)"' -``` - -### Alerting - -```bash -# Add to monitoring system -# Alert if validation errors > 0 -./tools/mnemonic-validate --format json | jq -e '.summary.errors == 0' -``` - ---- - -## Security Hardening - -### Filesystem Permissions - -```bash -# Restrict access -chmod 700 ${MNEMONIC_ROOT} -chmod 600 ${MNEMONIC_ROOT}/**/*.memory.md - -# Shared directories (read-only for team members) -chmod 750 ${MNEMONIC_ROOT}/shared -chmod 640 ${MNEMONIC_ROOT}/shared/**/*.memory.md -``` - -### Git Signing - -```bash -cd ${MNEMONIC_ROOT} - -# Configure signing -git config commit.gpgsign true -git config user.signingkey YOUR_GPG_KEY - -# Verify signatures -git log --show-signature -5 -``` - -### Sensitive Data - -```bash -# Add to .gitignore -echo "security/private/*" >> ${MNEMONIC_ROOT}/.gitignore - -# Or use git-crypt for encryption -git-crypt init -echo "security/**/*.memory.md filter=git-crypt" >> .gitattributes -``` - ---- - -## Performance Tuning - -### Large Memory Sets - -```bash -# Use indexed search for 10k+ memories -# Consider organizing by date -mkdir -p ${MNEMONIC_ROOT}/archive/2025 -mv ${MNEMONIC_ROOT}/default/episodic/user/2025-* ${MNEMONIC_ROOT}/archive/2025/ - -# Limit search scope -rg "pattern" ${MNEMONIC_ROOT}/default/ # Not archive -``` - -### Git Performance - -```bash -cd ${MNEMONIC_ROOT} - -# Pack repository -git gc --aggressive - -# Shallow clone for shared repos -git clone --depth 100 git@github.com:org/shared.git shared - -# Sparse checkout for large repos -git sparse-checkout init -git sparse-checkout set decisions patterns -``` - ---- - -## Rollout Checklist - -### Pre-Rollout - -- [ ] Choose deployment architecture (individual/team/org) -- [ ] Set up git server repository (if team/org) -- [ ] Create namespace structure -- [ ] Define access controls (CODEOWNERS) -- [ ] Prepare installation scripts -- [ ] Set up backup automation -- [ ] Create monitoring/alerting - -### Pilot (Week 1) - -- [ ] Install on 3-5 pilot users -- [ ] Capture initial memories -- [ ] Validate format compliance -- [ ] Gather feedback -- [ ] Refine namespace structure - -### Team Rollout (Week 2-3) - -- [ ] Roll out to full team -- [ ] Set up shared repository -- [ ] Establish contribution workflow -- [ ] Configure CI validation -- [ ] Train team on workflows - -### Organization Rollout (Month 2+) - -- [ ] Expand to additional teams -- [ ] Create org-wide decision repository -- [ ] Establish governance policies -- [ ] Set up cross-team sharing -- [ ] Document best practices - ---- - -## Troubleshooting - -### Common Issues - -**Git conflicts on shared memories:** -```bash -cd ${MNEMONIC_ROOT}/shared -git fetch origin -git rebase origin/main -# Resolve conflicts, then: -git rebase --continue -``` - -**Disk space issues:** -```bash -# Compress old memories -/mnemonic:gc --compress - -# Archive old episodic memories -mv ${MNEMONIC_ROOT}/default/episodic/user/old-* ~/archive/ -``` - -**Slow search:** -```bash -# Check ripgrep is installed -which rg || brew install ripgrep - -# Use namespace filtering -rg "pattern" ${MNEMONIC_ROOT}/default/decisions/ # Faster -``` - ---- - -## Related Documentation - -- [Compliance & Governance](./compliance-governance.md) - Security controls -- [Productivity & ROI](./productivity-roi.md) - Team benefits -- [Validation Tool](../validation.md) - Schema validation -- [Integrations](../integrations/README.md) - Tool setup - -[← Back to Enterprise Overview](./README.md) diff --git a/docs/enterprise/developer-experience.md b/docs/enterprise/developer-experience.md deleted file mode 100644 index 01e9696..0000000 --- a/docs/enterprise/developer-experience.md +++ /dev/null @@ -1,405 +0,0 @@ -# Developer Experience Guide - -For individual developers and senior engineers who value privacy, control, and customization. - -## Overview - -Mnemonic puts you in control. Your memories stay local, use standard formats, and work with your existing tools. No accounts, no telemetry, no cloud dependencies. - ---- - -## Privacy-First Design - -### Zero Telemetry - -Mnemonic collects nothing: - -- No usage analytics -- No memory content transmission -- No network calls -- No account required -- No API keys needed - -### Local Storage Only - -``` -${MNEMONIC_ROOT}/ # Your memories -${MNEMONIC_ROOT}/ # Project memories (optional) -``` - -That's it. Plain files on your filesystem. - -### You Own Your Data - -```bash -# See exactly what's stored -ls -la ${MNEMONIC_ROOT}/ - -# Read any memory with cat -cat ${MNEMONIC_ROOT}/default/decisions/user/*.memory.md - -# Delete anything -rm ${MNEMONIC_ROOT}/default/learnings/user/unwanted.memory.md - -# Export everything -tar -czf my-memories.tar.gz ${MNEMONIC_ROOT}/ -``` - ---- - -## Human-Readable Format - -### Standard Markdown - -Every memory is a `.memory.md` file you can read and edit: - -```yaml ---- -id: 550e8400-e29b-41d4-a716-446655440000 -type: semantic -namespace: decisions/user -created: 2026-01-23T10:30:00Z -title: "Use PostgreSQL for storage" -tags: - - database - - architecture ---- - -# Use PostgreSQL for Storage - -We decided to use PostgreSQL because: -- Strong ACID compliance -- Excellent JSON support -- Mature ecosystem with great tooling -``` - -### Version Control Built-in - -```bash -cd ${MNEMONIC_ROOT} -git log --oneline -10 # See recent changes -git diff HEAD~1 # What changed? -git checkout HEAD~1 -- file.md # Restore old version -git blame file.memory.md # Who changed what? -``` - ---- - -## Power User Features - -### Advanced Search - -```bash -# Full-text search with ripgrep -rg -i "authentication" ${MNEMONIC_ROOT}/ - -# Search by namespace -rg -i "pattern" ${MNEMONIC_ROOT}/*/decisions/ - -# Search by memory type -rg "^type: episodic" ${MNEMONIC_ROOT}/ -l - -# Search by tag -rg -l "^ - security" ${MNEMONIC_ROOT}/ - -# Recent memories (last 7 days) -find ${MNEMONIC_ROOT} -name "*.memory.md" -mtime -7 - -# Combine searches -rg -l "authentication" ${MNEMONIC_ROOT}/*/decisions/ | \ - xargs rg "JWT" -``` - -### Custom Scripts - -Create your own memory tools: - -```bash -#!/usr/bin/env bash -# quick-capture.sh - Fast memory capture - -NAMESPACE="${1:-learnings}" -TITLE="$2" -UUID=$(uuidgen | tr '[:upper:]' '[:lower:]') -DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") -SLUG=$(echo "$TITLE" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | head -c 50) - -cat > ${MNEMONIC_ROOT}/default/${NAMESPACE}/user/${SLUG}.memory.md << EOF ---- -id: ${UUID} -type: semantic -namespace: ${NAMESPACE}/user -created: ${DATE} -modified: ${DATE} -title: "${TITLE}" -tags: [] -temporal: - valid_from: ${DATE} - recorded_at: ${DATE} -provenance: - source_type: user_explicit - agent: custom-script - confidence: 1.0 ---- - -# ${TITLE} - -EOF - -echo "Created: ${MNEMONIC_ROOT}/default/${NAMESPACE}/user/${SLUG}.memory.md" -``` - -### Unix Tool Integration - -```bash -# Count memories by namespace -find ${MNEMONIC_ROOT} -name "*.memory.md" | \ - sed 's|.*/\([^/]*\)/[^/]*/.*|\1|' | sort | uniq -c - -# Find largest memories -find ${MNEMONIC_ROOT} -name "*.memory.md" -exec wc -l {} + | sort -n | tail -10 - -# Extract all titles -rg "^title:" ${MNEMONIC_ROOT}/ | sed 's/.*title: "//' | sed 's/"$//' - -# JSON export with yq -for f in ${MNEMONIC_ROOT}/**/*.memory.md; do - yq -f extract '.title, .type, .created' "$f" -done -``` - ---- - -## Offline Capability - -### No Network Required - -Mnemonic works completely offline: - -- No API calls to make -- No authentication to refresh -- No sync to wait for -- No rate limits - -### Travel Mode - -```bash -# On a plane? In a tunnel? Disconnected environment? -# Mnemonic works exactly the same. - -/mnemonic:capture decisions "Use event sourcing for audit log" -/mnemonic:recall authentication -/mnemonic:search "database" - -# All local, all instant -``` - ---- - -## Customization Options - -### Namespace Organization - -```bash -# Default namespaces -decisions/ patterns/ learnings/ blockers/ context/ -apis/ security/ testing/ episodic/ - -# Add your own -mkdir -p ${MNEMONIC_ROOT}/default/research/user -mkdir -p ${MNEMONIC_ROOT}/default/bookmarks/user -``` - -### Memory Types - -| Type | Use For | Decay Rate | -|------|---------|------------| -| **semantic** | Facts, decisions, specs | Slow (30 days) | -| **episodic** | Events, debugging sessions | Fast (7 days) | -| **procedural** | Workflows, how-tos | Medium (14 days) | - -### Decay Model - -Memories naturally fade based on age and access patterns: - -```yaml -temporal: - decay: - model: exponential - half_life: P7D # Halves every 7 days - strength: 0.85 # Current strength (0.0-1.0) -``` - -Override for important memories: - -```yaml -temporal: - decay: - model: none # Never decay -``` - ---- - -## Git Workflows - -### Personal Memory Repository - -```bash -# Initialize git (if not already) -cd ${MNEMONIC_ROOT} -git init - -# Daily backup -git add . -git commit -m "Daily backup $(date +%Y-%m-%d)" - -# Remote backup -git remote add origin git@github.com:yourname/memories.git -git push -u origin main -``` - -### Branch for Experiments - -```bash -cd ${MNEMONIC_ROOT} -git checkout -b experiment/new-architecture - -# Try new patterns, make decisions -# If it works, merge back -git checkout main -git merge experiment/new-architecture - -# If not, discard -git branch -D experiment/new-architecture -``` - -### Time Travel - -```bash -# What did I know last month? -git checkout HEAD~30 -- . - -# Restore specific memory -git checkout HEAD~5 -- decisions/user/important.memory.md - -# Compare memory evolution -git diff HEAD~10 -- patterns/user/auth.memory.md -``` - ---- - -## Performance Tips - -### Fast Search - -```bash -# Use ripgrep (10x faster than grep) -brew install ripgrep # macOS -apt install ripgrep # Ubuntu - -# Limit search scope -rg "pattern" ${MNEMONIC_ROOT}/*/decisions/ # Not all namespaces - -# Use file lists for large sets -rg -l "keyword" ${MNEMONIC_ROOT}/ | head -20 # Preview first -``` - -### Manage Memory Growth - -```bash -# Check size -du -sh ${MNEMONIC_ROOT}/ - -# Archive old memories -/mnemonic:gc --compress --compress-threshold 100 - -# Remove expired TTL memories -/mnemonic:gc --ttl 90d - -# Preview before cleanup -/mnemonic:gc --dry-run -``` - ---- - -## Validation & Quality - -### Schema Validation - -```bash -# Validate all memories -./tools/mnemonic-validate - -# Check specific namespace -./tools/mnemonic-validate ${MNEMONIC_ROOT}/default/decisions/ - -# Capture validation as memory -./tools/mnemonic-validate --capture -``` - -### Pre-commit Hook - -```bash -# .git/hooks/pre-commit -#!/bin/bash -./tools/mnemonic-validate --changed --fast-fail -``` - ---- - -## Comparison with Alternatives - -### vs. Cloud-Based Memory - -| Feature | Cloud Memory | Mnemonic | -|---------|-------------|----------| -| Privacy | Data on servers | 100% local | -| Offline | No | Yes | -| Telemetry | Usually yes | None | -| Lock-in | Vendor format | Open MIF | -| Cost | Subscription | Free | - -### vs. Plain Markdown Files - -| Feature | Plain Markdown | Mnemonic | -|---------|---------------|----------| -| Structure | Ad-hoc | Standardized | -| Validation | None | Schema validation | -| Integration | Manual | Claude Code plugin | -| Search | Basic grep | Intelligent recall | -| Metadata | None | Rich frontmatter | - ---- - -## Quick Reference - -```bash -# Capture -/mnemonic:capture decisions "Title here" - -# Search -rg -i "topic" ${MNEMONIC_ROOT}/ - -# Recall (automatic, but manual option) -/mnemonic:recall --namespace decisions - -# Status -/mnemonic:status - -# Validate -./tools/mnemonic-validate - -# Cleanup -/mnemonic:gc --compress -``` - ---- - -## Related Documentation - -- [Productivity & ROI](./productivity-roi.md) - Team benefits -- [Compliance & Governance](./compliance-governance.md) - Enterprise controls -- [Research Validation](./research-validation.md) - Why it works -- [Main Documentation](../../README.md) - Full reference - -[← Back to Enterprise Overview](./README.md) diff --git a/docs/enterprise/productivity-roi.md b/docs/enterprise/productivity-roi.md deleted file mode 100644 index abaced1..0000000 --- a/docs/enterprise/productivity-roi.md +++ /dev/null @@ -1,339 +0,0 @@ -# Productivity & ROI Guide - -For engineering managers, VPs of Engineering, and CTOs. - -## Overview - -Mnemonic eliminates context-switching overhead, accelerates onboarding, and reduces repeated debugging—all with zero infrastructure costs. - ---- - -## The Context Problem - -AI coding assistants are powerful but stateless. Every session starts fresh: - -``` -Session 1: "We decided to use JWT for auth" -Session 2: "What authentication approach should I use?" - └── Context lost, decision forgotten -``` - -**Impact:** -- Engineers re-explain decisions repeatedly -- New team members lack historical context -- Debugging sessions repeat past investigations -- Architectural knowledge scattered across Slack, docs, code comments - ---- - -## Mnemonic's Solution - -Persistent, cross-session memory that works across all AI coding tools: - -``` -Session 1: "We decided to use JWT for auth" - └── Captured to decisions/user/ - -Session 2: "What authentication approach should I use?" - └── Auto-recalls JWT decision - └── Implements with established pattern -``` - ---- - -## Productivity Metrics - -### Context Switching Reduction - -| Without Mnemonic | With Mnemonic | -|------------------|---------------| -| 5-10 min explaining prior decisions | Instant recall | -| Search Slack/docs for context | In-context memory | -| Re-investigate past bugs | Episodic memory available | -| Onboard new tool = start over | Same memories across tools | - -### Research-Validated Performance - -Filesystem-based memory achieves **74.0% accuracy** on the LoCoMo benchmark vs 68.5% for graph-based alternatives. This means: - -- Fewer incorrect recalls -- More relevant context surfaced -- Less time correcting AI mistakes - ---- - -## Team Benefits - -### Knowledge Retention - -``` -Developer leaves team - │ - └── Without mnemonic: Knowledge walks out the door - └── With mnemonic: Decisions, patterns, learnings preserved -``` - -**Captured knowledge types:** -- Architectural decisions with rationale -- Code patterns and conventions -- Debugging learnings -- API documentation -- Security policies - -### Accelerated Onboarding - -New team member workflow: - -```bash -# Day 1: Explore existing decisions -rg -l "." ${MNEMONIC_ROOT}/default/decisions/user/ | head -20 - -# Read architectural context -cat ${MNEMONIC_ROOT}/default/decisions/user/*postgresql*.memory.md - -# Understand patterns -rg -l "." ${MNEMONIC_ROOT}/default/patterns/user/ -``` - -**Estimated onboarding reduction:** 40-60% faster context acquisition - -### Reduced Debugging Time - -```yaml -# Episodic memory from past debugging session ---- -id: abc123 -type: episodic -namespace: learnings/user -title: "Fixed N+1 query in user dashboard" ---- - -# Investigation -Found N+1 query pattern in UserDashboard component. - -# Solution -Added .includes(:posts, :comments) to ActiveRecord query. - -# Time spent: 3 hours -``` - -Next time similar issue occurs: -- AI recalls past investigation -- Solution applied in minutes, not hours - ---- - -## Multi-Tool Flexibility - -### Open Format - -All memories are plain markdown with YAML frontmatter — no proprietary storage: - -**Benefits:** -- Human-readable and editable with any text editor -- Git-versioned with meaningful diffs -- No vendor lock-in — standard filesystem storage -- Portable MIF Level 3 format - -### Standardized Format (MIF Level 3) - -```yaml ---- -id: uuid -type: semantic|episodic|procedural -namespace: decisions/user -created: ISO-8601 -title: "Decision title" ---- - -Content in markdown... -``` - -All tools read the same format. All memories portable. - ---- - -## Cost Analysis - -### Zero Infrastructure Costs - -| Cost Category | Cloud Alternatives | Mnemonic | -|---------------|-------------------|----------| -| Monthly SaaS fee | $10-50/user/month | $0 | -| Storage costs | Usage-based | Filesystem (free) | -| API calls | Per-request fees | None | -| Integration work | Custom development | Templates provided | -| Maintenance | Vendor-dependent | Git + filesystem | - -### Total Cost of Ownership - -**Year 1 for 20-person team:** - -| Solution | Cost Estimate | -|----------|---------------| -| Cloud-based AI memory | $2,400-12,000/year | -| Mnemonic | $0 + 2 hours setup | - ---- - -## Implementation Effort - -### Quick Start (30 minutes) - -```bash -# Install plugin -claude settings plugins add /path/to/mnemonic - -# Initialize -/mnemonic:setup - -# Done - proactive memory starts working -``` - -### Team Rollout (1-2 days) - -1. **Day 1 Morning:** Install on pilot team (3-5 engineers) -2. **Day 1 Afternoon:** Capture first decisions and patterns -3. **Day 2:** Review captured memories, refine namespaces -4. **Week 1:** Roll out to full team - -### Adoption Strategy - -**Phase 1: Individual Adoption** -- Engineers install personally -- Build personal memory base -- Prove value with reduced context-switching - -**Phase 2: Team Patterns** -- Share common patterns via git -- Establish namespace conventions -- Document architectural decisions - -**Phase 3: Organization Knowledge Base** -- Centralized decision repository -- Onboarding memory packs -- Cross-team pattern sharing - ---- - -## Success Metrics - -### Track These KPIs - -| Metric | How to Measure | Target | -|--------|----------------|--------| -| Context re-explanation | Survey/time tracking | -50% | -| Onboarding time | New hire productivity ramp | -40% | -| Debugging repeat rate | Issue tracking tags | -30% | -| Tool switching friction | Developer feedback | Eliminated | - -### Measurement Commands - -```bash -# Memory usage over time -git log --oneline ${MNEMONIC_ROOT} | wc -l - -# Most accessed namespaces -find ${MNEMONIC_ROOT} -name "*.memory.md" | \ - sed 's|.*/\([^/]*\)/[^/]*/.*|\1|' | sort | uniq -c | sort -rn - -# Memory growth rate -du -sh ${MNEMONIC_ROOT} -``` - ---- - -## Risk Mitigation - -### Low Adoption Risk - -| Concern | Mitigation | -|---------|------------| -| Engineers won't use it | Automatic capture via hooks | -| Too much overhead | Proactive, silent operation | -| Learning curve | Familiar markdown format | -| Tool compatibility | 9+ integrations already | - -### Data Risk - -| Concern | Mitigation | -|---------|------------| -| Data loss | Git versioning, backups | -| Stale information | TTL policies, decay model | -| Incorrect memories | Validation tool, provenance tracking | -| Sensitive data exposure | Local storage, permissions | - ---- - -## Team Coordination Features - -### Shared Memory Patterns - -```bash -# Team shares a patterns repository -git clone git@github.com:team/shared-patterns ${MNEMONIC_ROOT}/shared - -# Individual contributions -cd ${MNEMONIC_ROOT}/shared -git add new-pattern.memory.md -git commit -m "Add API pagination pattern" -git push -``` - -### Namespace Strategy for Teams - -``` -${MNEMONIC_ROOT}/ -├── org/ # Organization-wide -│ ├── decisions/shared/ # Company architectural decisions -│ ├── patterns/shared/ # Standard code patterns -│ └── security/shared/ # Security policies -├── team/ # Team-specific -│ ├── decisions/team/ # Team decisions -│ └── context/team/ # Project context -└── default/ # Individual - ├── learnings/user/ # Personal learnings - └── episodic/user/ # Personal experiences -``` - ---- - -## Comparison with Alternatives - -### vs. Confluence/Notion - -| Aspect | Wiki Tools | Mnemonic | -|--------|-----------|----------| -| AI integration | Manual copy-paste | Automatic | -| Search context | Separate tool | In AI context | -| Update friction | High (manual) | Low (automatic) | -| Format | Proprietary | Standard markdown | - -### vs. Custom Solutions - -| Aspect | Build Your Own | Mnemonic | -|--------|---------------|----------| -| Development time | Weeks-months | Hours | -| Maintenance | Ongoing | Minimal | -| Multi-tool support | Custom per tool | Built-in | -| Research validation | Unknown | 74% accuracy benchmark | - -### vs. Cloud AI Memory - -| Aspect | Cloud Solutions | Mnemonic | -|--------|----------------|----------| -| Data sovereignty | Third-party servers | Local only | -| Offline access | Requires network | Always available | -| Cost | Per-user fees | Free | -| Lock-in | Vendor-specific | Open format | - ---- - -## Related Documentation - -- [Developer Experience](./developer-experience.md) - Individual benefits -- [Compliance & Governance](./compliance-governance.md) - Enterprise controls -- [Deployment Guide](./deployment-guide.md) - Rollout planning -- [Integrations](../integrations/README.md) - Tool-specific setup - -[← Back to Enterprise Overview](./README.md) diff --git a/docs/enterprise/research-validation.md b/docs/enterprise/research-validation.md deleted file mode 100644 index 5da6aa8..0000000 --- a/docs/enterprise/research-validation.md +++ /dev/null @@ -1,348 +0,0 @@ -# Research Validation - -Technical deep dive into the academic foundations and benchmark results that validate mnemonic's approach. - -## Overview - -Mnemonic's filesystem-based architecture is not just pragmatic—it's research-validated. This document presents the empirical evidence and theoretical foundations. - ---- - -## Letta LoCoMo Benchmark - -### Results Summary - -| Approach | Accuracy | Difference | -|----------|----------|------------| -| **Filesystem-based** | 74.0% | Baseline | -| Mem0 (graph-based) | 68.5% | -5.5% | - -Source: [Letta Research Blog](https://www.letta.com/blog/benchmarking-ai-agent-memory) - -### Why Filesystem Wins - -The benchmark reveals a counterintuitive finding: simpler approaches outperform complex ones. - -**Key Insight**: LLMs are extensively pretrained on filesystem operations. They understand: -- File paths and directory structures -- grep, find, cat command patterns -- Markdown and text processing -- Version control concepts - -This pretraining makes filesystem operations more reliable than specialized abstractions like: -- Vector databases -- Knowledge graphs -- Custom query languages - -### Methodology - -The LoCoMo (Long-Context Memory) benchmark measures: - -1. **Memory Recall Accuracy**: Can the system retrieve relevant information? -2. **Context Coherence**: Does retrieved context help the task? -3. **Temporal Reasoning**: Can the system reason about when things happened? - -Mnemonic's filesystem approach excels because: -- Direct file access = no abstraction overhead -- Human-readable format = debuggable -- Git history = temporal tracking built-in - ---- - -## Unix Philosophy Foundation - -### The Paper - -**Title**: "From Everything is a File to Files Are All You Need" -**Source**: [arXiv:2601.11672](https://arxiv.org/abs/2601.11672) - -### Core Argument - -The Unix philosophy of uniform interfaces (everything is a file) applies directly to AI agent design: - -> "Agents interacting with REST APIs, SQL databases, vector stores, and file systems benefit from file-like abstractions where complexity is encapsulated, not eliminated." - -### Application to Mnemonic - -| Unix Principle | Mnemonic Implementation | -|----------------|------------------------| -| Everything is a file | Memories are markdown files | -| Plain text | Human-readable content | -| Small tools, composable | grep, find, git integration | -| Simplicity | No databases, no cloud | - -### Why This Matters - -Vector databases and knowledge graphs add complexity that: -- Increases failure modes -- Reduces debuggability -- Requires specialized tooling -- Creates vendor dependencies - -File-based approaches: -- Use battle-tested filesystem semantics -- Work with any Unix tool -- Remain human-inspectable -- Scale with standard infrastructure - ---- - -## Cognitive Science Foundations - -### Memory Type Classification - -Mnemonic's type system derives from cognitive psychology: - -| Mnemonic Type | Cognitive Equivalent | Description | -|---------------|---------------------|-------------| -| **semantic** | Semantic Memory | Facts, concepts, general knowledge | -| **episodic** | Episodic Memory | Personal experiences, events | -| **procedural** | Procedural Memory | Skills, how-to knowledge | - -Source: [Human-inspired Perspectives: A Survey on AI Long-term Memory](https://arxiv.org/abs/2411.00489) - -### Why This Classification Works - -AI agent frameworks are adopting these cognitive patterns because they map naturally to: - -- **Semantic**: API documentation, architectural decisions, specifications -- **Episodic**: Debugging sessions, incidents, conversations -- **Procedural**: Deployment workflows, coding patterns, runbooks - -### Decay Model - -Human memory fades over time. Mnemonic implements exponential decay: - -``` -strength(t) = initial_strength × e^(-λt) -``` - -Where: -- `λ = ln(2) / half_life` -- Default half-lives: semantic (30d), episodic (7d), procedural (14d) - -This ensures: -- Recent memories are prioritized -- Old memories naturally fade -- Important memories can override decay - ---- - -## Bi-Temporal Database Theory - -### SQL:2011 Standard - -Mnemonic implements bi-temporal tracking per the SQL:2011 standard: - -```yaml -temporal: - valid_from: 2026-01-15T00:00:00Z # When this became true in reality - recorded_at: 2026-01-20T10:30:00Z # When we recorded this knowledge -``` - -### Two Time Dimensions - -| Dimension | Question Answered | Use Case | -|-----------|-------------------|----------| -| **valid_from** | When was this true? | Backfilling historical decisions | -| **recorded_at** | When did we learn this? | Audit trail, knowledge discovery | - -### Practical Benefits - -1. **Corrections**: Record that a decision was made last week, today -2. **Audit**: Distinguish between fact time and knowledge time -3. **Debugging**: "When did we know about this bug?" -4. **Compliance**: Full temporal provenance - -Reference: [Martin Fowler's Bitemporal History](https://martinfowler.com/articles/bitemporal-history.html) - ---- - -## Competitive Analysis - -### Market Positioning - -``` - Simple ◄─────────────────► Complex - │ │ - Private/Local [MNEMONIC] [Mem0] - │ │ │ - │ [Basic Memory] [Zep Cloud] - │ │ │ - Cloud/Hosted [Copilot Memory] [LangChain Memory] -``` - -### Feature Comparison - -| Feature | Mnemonic | Mem0 | Zep | LangChain | -|---------|----------|------|-----|-----------| -| Storage | Filesystem | Graph DB | Vector+Graph | Configurable | -| Dependencies | None | External DB | Cloud service | External DB | -| Accuracy (LoCoMo) | 74.0% | 68.5% | N/A | N/A | -| Human-readable | Yes | No | No | Varies | -| Offline | Yes | No | No | Depends | -| Git versioning | Yes | No | No | No | -| Cost | Free | Freemium | Paid | Depends | - -### Competitive Advantages - -1. **Research-validated accuracy**: 5.5% higher than leading alternative -2. **Zero dependencies**: No cloud, no databases, no accounts -3. **Human-readable**: Direct file inspection and editing -4. **Git integration**: Full version control with meaningful diffs -5. **Multi-tool support**: 9+ AI coding assistants -6. **Open format**: MIF Level 3 prevents lock-in - ---- - -## Performance Characteristics - -### Search Performance - -Mnemonic uses ripgrep for fast full-text search: - -| Memory Count | ripgrep Time | Traditional grep | -|--------------|--------------|------------------| -| 100 | 5ms | 50ms | -| 1,000 | 20ms | 400ms | -| 10,000 | 100ms | 4,000ms | - -Source: [ripgrep benchmarks](https://burntsushi.net/ripgrep/) - -### Scaling Considerations - -| Scale | Recommendation | -|-------|----------------| -| < 1,000 memories | Default configuration | -| 1,000 - 10,000 | Use namespace filtering | -| 10,000+ | Consider memory archival | - -### Memory Size - -Average memory file: 500 bytes - 5 KB -Typical installation: 100-1,000 memories = 0.5 - 5 MB - ---- - -## Validation Methodology - -### Schema Validation - -Mnemonic includes a validation tool that checks: - -| Check | Purpose | -|-------|---------| -| UUID format | Unique identification | -| ISO 8601 timestamps | Standard date format | -| Type enumeration | Valid memory types | -| Required fields | Complete metadata | -| Provenance | Track data origin | - -### Quality Assurance - -```bash -# Validate all memories -./tools/mnemonic-validate - -# CI integration -./tools/mnemonic-validate --format json - -# Capture validation as memory -./tools/mnemonic-validate --capture -``` - ---- - -## Comparison with Industry Trends - -### Context Engineering - -Anthropic's research on [Effective Context Engineering for AI Agents](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents) aligns with mnemonic's approach: - -- Structured context formats -- Relevant information retrieval -- Context window optimization - -### GitHub Copilot Memory - -GitHub Copilot's [Agentic Memory System](https://github.blog/ai-and-ml/github-copilot/building-an-agentic-memory-system-for-github-copilot/) uses citation-based validation—similar to mnemonic's provenance tracking: - -```yaml -provenance: - source_type: conversation - agent: claude-opus-4 - confidence: 0.95 -citations: - - type: documentation - title: "PostgreSQL Docs" - url: https://www.postgresql.org/docs/ - relevance: 0.90 -``` - -### MCP Ecosystem - -While mnemonic doesn't implement MCP (Model Context Protocol), its filesystem approach is compatible with MCP-style tool use: - -- Memories exposed as file resources -- Search as tool operations -- Standard Unix tools as primitives - ---- - -## Academic References - -### Primary Sources - -1. **Letta LoCoMo Benchmark** - - Source: [letta.com/blog/benchmarking-ai-agent-memory](https://www.letta.com/blog/benchmarking-ai-agent-memory) - - Finding: Filesystem 74.0% vs Graph 68.5% - -2. **Unix Philosophy for AI** - - Source: [arXiv:2601.11672](https://arxiv.org/abs/2601.11672) - - Finding: File abstractions work for agents - -3. **AI Long-term Memory Survey** - - Source: [arXiv:2411.00489](https://arxiv.org/abs/2411.00489) - - Finding: Cognitive memory types apply to AI - -### Supporting Sources - -4. **Martin Fowler - Bitemporal History** - - Source: [martinfowler.com/articles/bitemporal-history.html](https://martinfowler.com/articles/bitemporal-history.html) - - Application: Bi-temporal tracking design - -5. **ripgrep Benchmarks** - - Source: [burntsushi.net/ripgrep](https://burntsushi.net/ripgrep/) - - Finding: 5-10x faster than grep - -6. **Anthropic - Context Engineering** - - Source: [anthropic.com/engineering/effective-context-engineering](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents) - - Application: Context formatting patterns - -7. **GitHub Copilot Memory** - - Source: [github.blog/ai-and-ml/github-copilot/building-an-agentic-memory-system](https://github.blog/ai-and-ml/github-copilot/building-an-agentic-memory-system-for-github-copilot/) - - Application: Citation-based validation - ---- - -## Conclusion - -Mnemonic's design choices are not arbitrary—they're backed by: - -1. **Empirical evidence**: 74% accuracy in rigorous benchmarks -2. **Theoretical foundation**: Unix philosophy, cognitive science -3. **Industry alignment**: Matches trends from GitHub, Anthropic -4. **Practical benefits**: Zero dependencies, full auditability - -The research is clear: for AI memory systems, simplicity wins. - ---- - -## Related Documentation - -- [Compliance & Governance](./compliance-governance.md) - Enterprise controls -- [Developer Experience](./developer-experience.md) - User benefits -- [ADR-001](../adrs/adr-001-filesystem-based-storage.md) - Architecture decision -- [Original Research](../../reports/ai-memory-filesystem-research/2026-01-24-research.md) - Full market research - -[← Back to Enterprise Overview](./README.md) diff --git a/docs/library-reference.md b/docs/library-reference.md index aa83d76..f2c1af9 100644 --- a/docs/library-reference.md +++ b/docs/library-reference.md @@ -30,7 +30,7 @@ The `lib/` directory contains shared Python utilities used across mnemonic's hoo ### paths -**File**: `lib/paths.py` | **Documentation**: [lib/README.md](../lib/README.md) +**File**: `lib/paths.py` Centralized path resolution for all mnemonic memory operations. Provides single source of truth for memory directories, search paths, and blackboard locations. @@ -644,7 +644,7 @@ Validate memory conforms to loaded ontology. --- -**See Also**: +**See Also**: - [Ontologies Guide](ontologies.md) - [ADR-008: Custom Ontologies](adrs/adr-008-custom-ontologies.md) - [Ontology Skill](../skills/ontology/SKILL.md) diff --git a/docs/ontologies.md b/docs/ontologies.md index 5eaa875..002cac7 100644 --- a/docs/ontologies.md +++ b/docs/ontologies.md @@ -465,7 +465,6 @@ entity: |---------|-------------| | `/mnemonic:list` | List loaded ontologies and namespaces | | `/mnemonic:validate ` | Validate ontology file | -| `/mnemonic:discover ` | Discover entities in files | ### Library API diff --git a/docs/ontology-implementation-plan.md b/docs/ontology-implementation-plan.md deleted file mode 100644 index fabd201..0000000 --- a/docs/ontology-implementation-plan.md +++ /dev/null @@ -1,1008 +0,0 @@ -# Ontology Support Implementation Plan - -**Status**: Awaiting Approval -**Target**: Mnemonic v2.0 -**Timeline**: 5 weeks - -## Executive Summary - -This plan details the implementation of custom ontology support for mnemonic, enabling: -- Domain-specific knowledge management -- Entity types with mixin-based inheritance -- Agent-driven entity discovery -- URL-referenced shared ontologies -- Rich entity linking and relationships - -## Architecture Overview - -``` -┌─────────────────────────────────────────────────────────────┐ -│ Claude Code CLI │ -├─────────────────────────────────────────────────────────────┤ -│ Plugin Layer │ -│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐ │ -│ │ Commands │ │ Skills │ │ Agents │ │ -│ │ • capture │ │ • mnemonic- │ │ • ontology- │ │ -│ │ • ontology │ │ ontology │ │ discovery │ │ -│ └────────┬────────┘ └────────┬────────┘ └──────┬──────┘ │ -│ │ │ │ │ -│ └──────────────┬─────┴───────────────────┘ │ -│ │ │ -├──────────────────────────┼──────────────────────────────────┤ -│ Ontology Layer (NEW) │ │ -│ ┌───────────────────────▼───────────────────────────────┐ │ -│ │ OntologyRegistry │ │ -│ │ • Load ontology definitions │ │ -│ │ • Merge base + user + project ontologies │ │ -│ │ • Resolve namespace → ontology mappings │ │ -│ └─────────────────────┬─────────────────────────────────┘ │ -│ │ │ -│ ┌─────────────────────▼─────────────────────────────────┐ │ -│ │ OntologyValidator │ │ -│ │ • Validate ontology YAML against meta-schema │ │ -│ │ • Check entity type completeness │ │ -│ │ • Verify trait compatibility │ │ -│ └─────────────────────┬─────────────────────────────────┘ │ -│ │ │ -│ ┌─────────────────────▼─────────────────────────────────┐ │ -│ │ EntityResolver │ │ -│ │ • Link entities across memories │ │ -│ │ • Index entities for fast lookup │ │ -│ │ • Resolve @[[entity]] references │ │ -│ └───────────────────────────────────────────────────────┘ │ -│ │ -├────────────────────────────────────────────────────────────┤ -│ Storage Layer │ -│ ┌────────────────────────────────────────────────────────┐│ -│ │ Filesystem (.memory.md + .ontology.yaml) ││ -│ │ ┌─────────────────────┐ ┌─────────────────────────┐ ││ -│ │ │ ~/.claude/ │ │ $MNEMONIC_ROOT/ │ ││ -│ │ │ mnemonic/{org}/ │ │ │ ││ -│ │ │ ├── ontology.yaml │ │ ├── ontology.yaml │ ││ -│ │ │ └── {namespace}/ │ │ └── {namespace}/ │ ││ -│ │ └─────────────────────┘ └─────────────────────────┘ ││ -│ └────────────────────────────────────────────────────────┘│ -└────────────────────────────────────────────────────────────┘ -``` - -## Phase 1: Core Infrastructure (Week 1-2) - -### 1.1 Create Python Library Structure - -**Files to create:** - -``` -lib/ -├── __init__.py -├── ontology_registry.py -├── ontology_validator.py -└── entity_resolver.py -``` - -**lib/ontology_registry.py** (~400 lines): -```python -from dataclasses import dataclass, field -from pathlib import Path -from typing import Dict, List, Optional -import yaml - -@dataclass -class EntityType: - name: str - description: str - base: str # semantic | episodic | procedural - traits: List[str] = field(default_factory=list) - schema: Dict = field(default_factory=dict) - -@dataclass -class Trait: - name: str - fields: Dict - -@dataclass -class Namespace: - name: str - description: str - type_hint: str = "semantic" - replaces: Optional[str] = None - -@dataclass -class Ontology: - id: str - version: str - description: str - namespaces: Dict[str, Namespace] = field(default_factory=dict) - entity_types: List[EntityType] = field(default_factory=list) - traits: Dict[str, Trait] = field(default_factory=dict) - relationships: Dict = field(default_factory=dict) - discovery: Dict = field(default_factory=dict) - schema_url: Optional[str] = None - -class OntologyRegistry: - def __init__(self): - self._ontologies: Dict[str, Ontology] = {} - self._namespace_map: Dict[str, str] = {} # namespace -> ontology_id - self._base_namespaces = [ - "apis", "blockers", "context", "decisions", - "learnings", "patterns", "security", "testing", "episodic" - ] - - def load_ontologies(self, paths: List[Path]) -> None: - """Load ontologies from multiple paths with precedence.""" - for path in paths: - self._load_from_path(path) - - def get_ontology(self, ontology_id: str) -> Optional[Ontology]: - """Get ontology by ID.""" - return self._ontologies.get(ontology_id) - - def get_ontology_for_namespace(self, namespace: str) -> Optional[Ontology]: - """Get ontology that defines a namespace.""" - ontology_id = self._namespace_map.get(namespace) - return self._ontologies.get(ontology_id) if ontology_id else None - - def get_all_namespaces(self) -> List[str]: - """Get all valid namespaces (base + custom).""" - custom = list(self._namespace_map.keys()) - return list(set(self._base_namespaces + custom)) - - def get_entity_type(self, namespace: str, type_name: str) -> Optional[EntityType]: - """Get entity type definition.""" - ontology = self.get_ontology_for_namespace(namespace) - if ontology: - for et in ontology.entity_types: - if et.name == type_name: - return et - return None - - def is_custom_namespace(self, namespace: str) -> bool: - """Check if namespace is custom (not base).""" - return namespace not in self._base_namespaces - - def _load_from_path(self, path: Path) -> None: - """Load ontology from a path.""" - ontology_file = path / "ontology.yaml" - if ontology_file.exists(): - with open(ontology_file) as f: - data = yaml.safe_load(f) - ontology = self._parse_ontology(data) - self._register_ontology(ontology) - - def _parse_ontology(self, data: dict) -> Ontology: - """Parse ontology from YAML data.""" - # Implementation details... - pass - - def _register_ontology(self, ontology: Ontology) -> None: - """Register ontology and update mappings.""" - self._ontologies[ontology.id] = ontology - for ns_name in ontology.namespaces: - self._namespace_map[ns_name] = ontology.id -``` - -### 1.2 Create Ontology Meta-Schema - -**ontologies/schemas/ontology-meta-schema.json** (~200 lines): -```json -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://mnemonic.org/schemas/ontology/v1", - "title": "Mnemonic Ontology Schema", - "type": "object", - "required": ["ontology"], - "properties": { - "ontology": { - "type": "object", - "required": ["id", "version"], - "properties": { - "id": {"type": "string", "pattern": "^[a-z][a-z0-9-]*$"}, - "version": {"type": "string", "pattern": "^\\d+\\.\\d+\\.\\d+$"}, - "description": {"type": "string"}, - "schema_url": {"type": "string", "format": "uri"} - } - }, - "namespaces": { - "type": "object", - "additionalProperties": { - "type": "object", - "properties": { - "description": {"type": "string"}, - "type_hint": {"enum": ["semantic", "episodic", "procedural"]}, - "replaces": {"type": "string"} - } - } - }, - "entity_types": { - "type": "array", - "items": { - "type": "object", - "required": ["name", "base"], - "properties": { - "name": {"type": "string"}, - "description": {"type": "string"}, - "base": {"enum": ["semantic", "episodic", "procedural"]}, - "traits": {"type": "array", "items": {"type": "string"}}, - "schema": {"$ref": "#/$defs/entitySchema"} - } - } - }, - "traits": { - "type": "object", - "additionalProperties": { - "type": "object", - "required": ["fields"], - "properties": { - "fields": {"type": "object"} - } - } - }, - "relationships": { - "type": "object" - }, - "discovery": { - "type": "object", - "properties": { - "enabled": {"type": "boolean"}, - "patterns": {"type": "array"}, - "confidence_threshold": {"type": "number", "minimum": 0, "maximum": 1} - } - } - }, - "$defs": { - "entitySchema": { - "type": "object", - "properties": { - "required": {"type": "array", "items": {"type": "string"}}, - "properties": {"type": "object"} - } - } - } -} -``` - -### 1.3 Create Base Ontology - -**ontologies/base.ontology.yaml** (~100 lines): -```yaml -ontology: - id: mnemonic-base - version: "1.0.0" - description: "Base mnemonic namespaces (backward compatibility)" - -namespaces: - apis: - description: "API documentation, contracts, endpoints" - type_hint: semantic - - blockers: - description: "Issues, impediments, incidents" - type_hint: episodic - - context: - description: "Background information, environment state" - type_hint: semantic - - decisions: - description: "Architectural choices with rationale" - type_hint: semantic - - learnings: - description: "Insights, discoveries, TILs" - type_hint: semantic - - patterns: - description: "Code conventions, best practices" - type_hint: procedural - - security: - description: "Security policies, vulnerabilities" - type_hint: semantic - - testing: - description: "Test strategies, edge cases" - type_hint: procedural - - episodic: - description: "General events, experiences" - type_hint: episodic - -# No custom entity types in base ontology -# No traits in base ontology -# No discovery patterns in base ontology -``` - -### 1.4 Modify Session Start Hook - -**hooks/session_start.py** (add ~30 lines): -```python -# Add to imports -import sys -sys.path.insert(0, str(Path(__file__).parent.parent / "lib")) -from ontology_registry import OntologyRegistry - -# Add to startup -def load_ontologies() -> OntologyRegistry: - """Load ontologies from user and project directories.""" - registry = OntologyRegistry() - - # Load paths in precedence order (later overrides earlier) - paths = [ - Path(__file__).parent.parent / "ontologies", # Base ontologies - Path.home() / ".claude" / "mnemonic", # User ontologies - Path.cwd() / ".claude" / "mnemonic", # Project ontologies - ] - - registry.load_ontologies(paths) - return registry - -# Use in context generation -def get_ontology_context() -> str: - """Generate ontology context for additionalContext.""" - registry = load_ontologies() - namespaces = registry.get_all_namespaces() - custom = [ns for ns in namespaces if registry.is_custom_namespace(ns)] - - if custom: - return f"**Custom ontology namespaces:** {', '.join(custom)}" - return "" -``` - -### 1.5 Unit Tests - -**tests/test_ontology_registry.py** (~200 lines): -```python -import pytest -from pathlib import Path -from lib.ontology_registry import OntologyRegistry, Ontology, EntityType - -def test_load_base_ontology(): - """Test loading base ontology.""" - registry = OntologyRegistry() - registry.load_ontologies([Path("ontologies")]) - - assert "apis" in registry.get_all_namespaces() - assert "decisions" in registry.get_all_namespaces() - assert registry.is_custom_namespace("apis") == False - -def test_load_custom_ontology(tmp_path): - """Test loading custom ontology.""" - ontology_yaml = tmp_path / "ontology.yaml" - ontology_yaml.write_text(""" -ontology: - id: test-ontology - version: "1.0.0" - -namespaces: - custom-ns: - description: "Custom namespace" - type_hint: semantic -""") - - registry = OntologyRegistry() - registry.load_ontologies([tmp_path]) - - assert "custom-ns" in registry.get_all_namespaces() - assert registry.is_custom_namespace("custom-ns") == True - -def test_namespace_precedence(tmp_path): - """Test that project ontology overrides user ontology.""" - # Create user ontology - user_dir = tmp_path / "user" - user_dir.mkdir() - (user_dir / "ontology.yaml").write_text(""" -ontology: - id: user-ontology - version: "1.0.0" - -namespaces: - shared-ns: - description: "User version" -""") - - # Create project ontology - project_dir = tmp_path / "project" - project_dir.mkdir() - (project_dir / "ontology.yaml").write_text(""" -ontology: - id: project-ontology - version: "1.0.0" - -namespaces: - shared-ns: - description: "Project version" -""") - - registry = OntologyRegistry() - registry.load_ontologies([user_dir, project_dir]) - - ontology = registry.get_ontology_for_namespace("shared-ns") - assert ontology.id == "project-ontology" # Project wins - -def test_entity_type_lookup(): - """Test entity type lookup.""" - # Test implementation... - pass -``` - ---- - -## Phase 2: Entity Management (Week 2-3) - -### 2.1 Create Entity Resolver - -**lib/entity_resolver.py** (~300 lines): -```python -from dataclasses import dataclass -from pathlib import Path -from typing import Dict, List, Optional -import subprocess -import re - -@dataclass -class Entity: - id: str - type: str - name: str - memory_path: Path - ontology_id: str - -@dataclass -class EntityLink: - from_entity: str - to_entity: str - relationship: str - -class EntityResolver: - def __init__(self, registry: 'OntologyRegistry'): - self.registry = registry - self._index: Dict[str, Entity] = {} - self._links: List[EntityLink] = [] - - def resolve_entity(self, entity_ref: str) -> Optional[Entity]: - """Resolve @[[entity]] or [[type:id]] reference.""" - # Parse reference format - if entity_ref.startswith("@[["): - # Simple entity reference: @[[PostgreSQL]] - name = entity_ref[3:-2] - return self._find_by_name(name) - elif ":" in entity_ref: - # Typed reference: [[component:stripe-integration]] - type_name, entity_id = entity_ref.split(":", 1) - return self._find_by_type_and_id(type_name, entity_id) - return None - - def index_memory(self, memory_path: Path) -> List[Entity]: - """Index entities from a memory file.""" - # Parse frontmatter for entity fields - # Return list of discovered entities - pass - - def find_entities_by_type(self, entity_type: str) -> List[Entity]: - """Find all entities of a specific type.""" - return [e for e in self._index.values() if e.type == entity_type] - - def get_relationships(self, entity_id: str) -> List[EntityLink]: - """Get relationships for an entity.""" - return [l for l in self._links - if l.from_entity == entity_id or l.to_entity == entity_id] - - def search_entities(self, query: str) -> List[Entity]: - """Search entities using ripgrep.""" - try: - result = subprocess.run( - ["rg", "-i", "-l", f"entity_id:.*{query}", "--glob", "*.memory.md"], - capture_output=True, - text=True, - cwd=str(Path.home() / ".claude" / "mnemonic"), - timeout=5 - ) - # Parse results... - except Exception: - return [] - - def _find_by_name(self, name: str) -> Optional[Entity]: - """Find entity by name (case-insensitive).""" - for entity in self._index.values(): - if entity.name.lower() == name.lower(): - return entity - return None - - def _find_by_type_and_id(self, type_name: str, entity_id: str) -> Optional[Entity]: - """Find entity by type and ID.""" - key = f"{type_name}:{entity_id}" - return self._index.get(key) -``` - -### 2.2 Update Validator for Ontology - -**tools/mnemonic-validate** (add ~150 lines): -```python -# Add import -from lib.ontology_registry import OntologyRegistry - -# Modify validate_memory function -def validate_memory_with_ontology( - file_path: Path, - schema: MIFSchema, - registry: OntologyRegistry = None, - ... -) -> ValidationResult: - """Validate memory with ontology support.""" - result = ValidationResult(file_path=file_path) - - # ... existing validation ... - - # NEW: Ontology validation - if registry and "ontology" in frontmatter: - ontology_data = frontmatter["ontology"] - ontology_id = ontology_data.get("id") - entity_type = ontology_data.get("entity_type") - - ontology = registry.get_ontology(ontology_id) - if not ontology: - result.warnings.append(ValidationWarning( - field="ontology.id", - message=f"Unknown ontology: {ontology_id}" - )) - else: - # Validate entity type - et = registry.get_entity_type( - frontmatter.get("namespace", "").split("/")[0], - entity_type - ) - if et: - # Validate required fields from entity schema - entity_data = frontmatter.get("entity", {}) - for required in et.schema.get("required", []): - if required not in entity_data: - result.errors.append(ValidationError( - field=f"entity.{required}", - message=f"Required field missing for {entity_type}" - )) - - # Validate trait fields - for trait_name in et.traits: - trait = ontology.traits.get(trait_name) - if trait: - for field_name in trait.fields: - if field_name not in entity_data: - result.warnings.append(ValidationWarning( - field=f"entity.{field_name}", - message=f"Trait '{trait_name}' field missing" - )) - - return result -``` - ---- - -## Phase 3: Commands and Discovery (Week 3-4) - -### 3.1 Create Ontology Command - -**commands/ontology.md** (~200 lines): -```markdown ---- -description: Manage ontologies -argument-hint: " [options]" -allowed-tools: - - Bash - - Read - - Write ---- - -# /mnemonic:ontology - -Manage custom ontologies for mnemonic. - -## Subcommands - -### list -List active ontologies and their namespaces. - -```bash -python3 "$CLAUDE_PLUGIN_ROOT/lib/ontology_registry.py" --list -``` - -### validate -Validate an ontology definition file. - -```bash -python3 "$CLAUDE_PLUGIN_ROOT/lib/ontology_validator.py" \ - --file "${1:-$MNEMONIC_ROOT/ontology.yaml}" -``` - -### add -Add an ontology from a URL. - -```bash -URL="$1" -CACHE_DIR="$MNEMONIC_ROOT/.ontologies/.cache" -mkdir -p "$CACHE_DIR" -curl -sL "$URL" -o "$CACHE_DIR/$(basename $URL)" -echo "Ontology cached. Add to registry to activate." -``` - -### init -Initialize an ontology template. - -```bash -TEMPLATE="${1:-minimal}" -cp "$CLAUDE_PLUGIN_ROOT/ontologies/templates/${TEMPLATE}.yaml" \ - "$MNEMONIC_ROOT/ontology.yaml" -echo "Created $MNEMONIC_ROOT/ontology.yaml from $TEMPLATE template" -``` - -### namespaces -List all valid namespaces. - -```bash -python3 -c " -from lib.ontology_registry import OntologyRegistry -from pathlib import Path - -registry = OntologyRegistry() -registry.load_ontologies([ - Path('$CLAUDE_PLUGIN_ROOT/ontologies'), - Path.home() / '.claude' / 'mnemonic', - Path.cwd() / '.claude' / 'mnemonic' -]) - -for ns in sorted(registry.get_all_namespaces()): - custom = '(custom)' if registry.is_custom_namespace(ns) else '' - print(f' {ns} {custom}') -" -``` -``` - -### 3.2 Modify Capture Command - -**commands/capture.md** (modify ~50 lines): -```markdown -### Step 2: Validate Namespace (MODIFIED) - -```bash -# Load namespaces from ontology registry -VALID_NS=$(python3 -c " -import sys -sys.path.insert(0, '$CLAUDE_PLUGIN_ROOT/lib') -from ontology_registry import OntologyRegistry -from pathlib import Path - -registry = OntologyRegistry() -registry.load_ontologies([ - Path('$CLAUDE_PLUGIN_ROOT/ontologies'), - Path.home() / '.claude' / 'mnemonic', - Path.cwd() / '.claude' / 'mnemonic' -]) -print(' '.join(registry.get_all_namespaces())) -") - -if ! echo "$VALID_NS" | grep -qw "$NAMESPACE"; then - echo "Error: Invalid namespace '$NAMESPACE'" - echo "Valid namespaces: $VALID_NS" - echo "" - echo "To add custom namespaces, create $MNEMONIC_ROOT/ontology.yaml" - exit 1 -fi -``` - -### Step 6b: Entity Type Validation (NEW) - -```bash -# If namespace is custom, check for entity type -IS_CUSTOM=$(python3 -c " -from lib.ontology_registry import OntologyRegistry -# ... check if namespace is custom and requires entity type -") - -if [ "$IS_CUSTOM" = "true" ] && [ -n "$ENTITY_TYPE" ]; then - # Get entity schema and validate required fields - ENTITY_SCHEMA=$(python3 -c " -from lib.ontology_registry import OntologyRegistry -# ... get entity type schema -") - - # Prompt for required entity fields - for FIELD in $REQUIRED_FIELDS; do - read -p "$FIELD: " VALUE - ENTITY_FIELDS="$ENTITY_FIELDS - $FIELD: $VALUE" - done -fi -``` - -### Step 7: Create Memory File (MODIFIED) - -Add ontology section to frontmatter: - -```yaml ---- -id: {UUID} -type: {TYPE} -namespace: {NAMESPACE}/{SCOPE} -created: {DATE} -title: "{TITLE}" - -# NEW: Ontology metadata (if custom namespace) -ontology: - id: {ONTOLOGY_ID} - entity_type: {ENTITY_TYPE} - entity_id: {ENTITY_ID} - -# NEW: Entity-specific fields (if entity type) -entity: -{ENTITY_FIELDS} - -tags: -{TAGS_YAML} ---- -``` -``` - -### 3.3 Create Discovery Agent - -**agents/ontology-discovery.md** (~250 lines): -```markdown ---- -description: Discover and suggest entities from memory content -model: haiku -allowed-tools: - - Bash - - Grep - - Read - - Write ---- - -# Ontology Discovery Agent - -Autonomous agent for discovering and suggesting entities from memory content. - -## Purpose - -Analyze memory content to identify potential entities based on ontology patterns. -Suggest entities to user for confirmation. Create entity memories when confirmed. - -## Workflow - -### 1. Load Discovery Patterns - -```bash -# Get patterns from active ontologies -PATTERNS=$(python3 -c " -from lib.ontology_registry import OntologyRegistry -from pathlib import Path -import json - -registry = OntologyRegistry() -registry.load_ontologies([ - Path('$CLAUDE_PLUGIN_ROOT/ontologies'), - Path.home() / '.claude' / 'mnemonic', - Path.cwd() / '.claude' / 'mnemonic' -]) - -patterns = {} -for ontology_id, ontology in registry._ontologies.items(): - if ontology.discovery.get('enabled'): - for pattern in ontology.discovery.get('patterns', []): - patterns[pattern['suggest_entity']] = pattern['content_pattern'] - -print(json.dumps(patterns)) -") -``` - -### 2. Scan Memory Content - -```bash -# For each pattern, search memories -for ENTITY_TYPE in $(echo $PATTERNS | jq -r 'keys[]'); do - PATTERN=$(echo $PATTERNS | jq -r ".[\"$ENTITY_TYPE\"]") - - # Find matches using ripgrep - MATCHES=$(rg -i "$PATTERN" ${MNEMONIC_ROOT}/ $MNEMONIC_ROOT/ \ - --glob "*.memory.md" -o | sort | uniq -c | sort -rn | head -10) - - echo "Potential $ENTITY_TYPE entities:" - echo "$MATCHES" -done -``` - -### 3. Suggest to User - -For each discovered entity with confidence above threshold: - -```markdown -**Entity Discovery Results** - -I found the following potential entities: - -| Entity | Type | Mentions | Confidence | -|--------|------|----------|------------| -| PostgreSQL | technology | 12 | 0.95 | -| Repository Pattern | pattern | 8 | 0.88 | -| Redis | technology | 5 | 0.75 | - -Would you like me to create entity memories for any of these? -Reply with entity names to confirm (e.g., "PostgreSQL, Repository Pattern") -``` - -### 4. Create Entity Memories - -When user confirms: - -```bash -# Create entity memory -/mnemonic:capture apis "$ENTITY_NAME" \ - --type semantic \ - --tags entity,$ENTITY_TYPE \ - --scope user -``` - -### 5. Update Source Memories with Links - -```bash -# Find memories mentioning the entity -MEMORIES=$(rg -l "$ENTITY_NAME" ${MNEMONIC_ROOT}/ --glob "*.memory.md") - -for MEMORY in $MEMORIES; do - # Add entity_links to frontmatter - # This is done by reading and rewriting the memory -done -``` - -## Trigger Conditions - -- Manual: `/mnemonic:ontology discover` -- Automatic: After session with 5+ new captures -- Scheduled: Weekly curation via memory-curator agent - -## Output - -Reports discovered entities and actions taken: - -```json -{ - "discovered": [ - {"entity": "PostgreSQL", "type": "technology", "mentions": 12, "action": "created"}, - {"entity": "Repository Pattern", "type": "pattern", "mentions": 8, "action": "linked"}, - {"entity": "Redis", "type": "technology", "mentions": 5, "action": "skipped"} - ], - "memories_updated": 15, - "new_entities_created": 2 -} -``` -``` - ---- - -## Phase 4: Documentation (Week 4-5) - -### 4.1 User Guide - -**docs/ontologies.md** (~800 lines): -- Introduction to custom ontologies -- Ontology definition format reference -- Step-by-step guide for creating ontologies -- Entity types and traits explained -- Discovery configuration -- Example ontologies for common domains -- Migration from hardcoded namespaces -- Troubleshooting guide - -### 4.2 Ontology Skill - -**skills/mnemonic-ontology/SKILL.md** (~300 lines): -- Trigger phrases -- Available operations -- Ontology management workflow -- Entity linking syntax -- Best practices - -### 4.3 Example Ontologies - -**ontologies/examples/software-engineering.yaml** (~150 lines): -```yaml -ontology: - id: software-engineering - version: "1.0.0" - description: "Software engineering domain ontology" - -namespaces: - architecture: - description: "System architecture decisions" - type_hint: semantic - - components: - description: "Software components and modules" - type_hint: semantic - - incidents: - description: "Production incidents" - type_hint: episodic - -entity_types: - - name: component - base: semantic - traits: [versioned, documented] - schema: - required: [name, responsibility] - properties: - name: {type: string} - responsibility: {type: string} - dependencies: {type: array} - interfaces: {type: array} - - - name: architectural-decision - base: semantic - traits: [dated, cited] - schema: - required: [decision, rationale] - properties: - decision: {type: string} - rationale: {type: string} - alternatives: {type: array} - consequences: {type: object} - -traits: - versioned: - fields: - version: {type: string} - changelog: {type: array} - - documented: - fields: - documentation_url: {type: string, format: uri} - - dated: - fields: - decision_date: {type: string, format: date} - - cited: - requires: [citations] - -relationships: - depends_on: - from: [component] - to: [component] - implements: - from: [component] - to: [architectural-decision] - -discovery: - enabled: true - patterns: - - content_pattern: "\\b(PostgreSQL|MySQL|Redis|MongoDB|Elasticsearch)\\b" - suggest_entity: technology - - content_pattern: "\\b(Factory|Singleton|Observer|Repository|Adapter)\\s+Pattern\\b" - suggest_entity: pattern - confidence_threshold: 0.8 -``` - ---- - -## Success Criteria - -- [ ] Custom namespaces work in capture command -- [ ] Entity types with traits validate correctly -- [ ] Entity linking syntax (`@[[entity]]`) resolves -- [ ] Discovery agent suggests entities from code/docs -- [ ] URL-referenced ontologies load and cache -- [ ] Existing memories continue to validate -- [ ] Performance: <100ms ontology load, <50ms entity resolution - -## Testing Plan - -1. **Unit Tests**: Registry, validator, resolver -2. **Integration Tests**: Full capture flow with custom ontology -3. **Fixture Ontologies**: Test YAML files in CI/CD -4. **Backward Compatibility**: Existing memories still valid -5. **Performance**: Benchmark with 1000+ memories - -## Risks and Mitigations - -| Risk | Mitigation | -|------|------------| -| Ontology conflicts | Clear precedence rules (project > user > base) | -| Schema complexity | Start simple, progressive disclosure | -| Discovery false positives | User confirmation required, confidence threshold | -| Performance degradation | Lazy loading, caching, ripgrep | diff --git a/docs/semantic-search.md b/docs/semantic-search.md index 1fc6aa0..40d9bdd 100644 --- a/docs/semantic-search.md +++ b/docs/semantic-search.md @@ -255,12 +255,12 @@ qmd query "database schema patterns" /mnemonic:recall --id 550e8400-e29b-41d4-a716-446655440000 ``` -### Enhanced Search Skill +### Enhanced Search -The `/mnemonic:search-enhanced` skill can optionally use qmd for initial search: +The `/mnemonic:search` skill includes enhanced iterative search with synthesis, which can use qmd for initial search: ```bash -/mnemonic:search-enhanced "comprehensive guide to our authentication system" +/mnemonic:search "comprehensive guide to our authentication system" ``` ## Troubleshooting @@ -337,5 +337,4 @@ qmd search "term" -c mnemonic-project - [@tobilu/qmd Documentation](https://github.com/tobil4sk/qmd) - [BM25 Algorithm](https://en.wikipedia.org/wiki/Okapi_BM25) - [Vector Embeddings Explained](https://platform.openai.com/docs/guides/embeddings) -- [Mnemonic Search Skill](../skills/mnemonic-search/SKILL.md) -- [Enhanced Search Skill](../skills/mnemonic-search-enhanced/SKILL.md) +- [Mnemonic Search Skill](../skills/search/SKILL.md) diff --git a/docs/tutorials/README.md b/docs/tutorials/README.md deleted file mode 100644 index 1f7c15d..0000000 --- a/docs/tutorials/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# Tutorials - -Step-by-step guides for learning Mnemonic. - -## Getting Started - -New to Mnemonic? Start here: - -1. **[First Project Setup](getting-started.md)** - Set up Mnemonic in your first project (15 min) - -## Intermediate - -Build your skills with additional tutorials (coming soon): - -- Creating Your First Memory - Capture and recall memories -- Understanding Memory Types - Learn semantic, episodic, and procedural memories -- Building a Knowledge Base - Create a project knowledge base -- Custom Ontologies - Define domain-specific entities and relationships -- Multi-Project Workflows - Share memories across projects - -## Advanced - -Master Mnemonic with advanced tutorials (coming soon): - -- Agent Coordination - Use the blackboard for complex workflows -- Memory Maintenance - Curate and optimize your memory system -- Custom Skills - Extend Mnemonic with custom skills - -## Quick Reference - -- [CLI Cheat Sheet](../cli-usage.md) -- [API Reference](../api-reference.md) -- [Troubleshooting](../troubleshooting.md) - -## Learning Path - -### For Developers - -**Goal:** Build project documentation memory system - -1. First Project Setup -2. Additional tutorials coming soon - -**Time:** ~15 min (currently available) - -### For Teams - -**Goal:** Shared organizational memory across projects - -1. First Project Setup -2. Additional tutorials coming soon - -**Time:** ~15 min (currently available) - -### For Power Users - -**Goal:** Full system customization and extension - -1. First Project Setup + review architecture docs -2. Additional tutorials coming soon - -**Time:** ~30 min (currently available) - -## Tutorial Format - -Each tutorial follows this structure: - -1. **Learning Objectives** - What you'll learn -2. **Prerequisites** - What you need to know -3. **Time Required** - Estimated completion time -4. **Step-by-Step Instructions** - Hands-on exercises -5. **Verification** - Check your work -6. **Next Steps** - Where to go next - -## Contributing Tutorials - -See [CONTRIBUTING.md](../../CONTRIBUTING.md) for guidelines on adding tutorials. diff --git a/docs/validation.md b/docs/validation.md index 1675439..8471597 100644 --- a/docs/validation.md +++ b/docs/validation.md @@ -253,4 +253,4 @@ If frontmatter fails to parse: ## Schema Source -The validation rules are parsed from `skills/mnemonic-format/SKILL.md`, ensuring a single source of truth between documentation and validation (see ADR-004). +The validation rules are parsed from `skills/format/SKILL.md`, ensuring a single source of truth between documentation and validation (see ADR-004). diff --git a/lib/README.md b/lib/README.md deleted file mode 100644 index 7ea0129..0000000 --- a/lib/README.md +++ /dev/null @@ -1,572 +0,0 @@ -# Mnemonic Library Modules - -Shared Python utilities for the mnemonic memory system. - -## Overview - -The `lib/` directory contains core utilities used across mnemonic's hooks, commands, and tools. This README focuses on the **path resolution** module. For comprehensive documentation of all library modules, see: - -📚 **[Complete Library Reference](../docs/library-reference.md)** - -Includes detailed API documentation for: -- **paths.py** - Path resolution (this file) -- **config.py** - Configuration management -- **memory_reader.py** - Memory file parsing -- **search.py** - Memory search and ranking -- **relationships.py** - Relationship types and linking -- **ontology.py** - Custom ontology support - ---- - -# Path Resolution Library - -Centralized path resolution for all mnemonic memory operations. - -## Overview - -This library provides a single source of truth for path construction in the mnemonic memory system. It eliminates scattered path logic across 30+ files and enables smooth migration between different path schemes. - -## Key Features - -- **Single Source of Truth**: All path construction in one place -- **Multiple Scheme Support**: LEGACY and V2 path structures -- **Testable**: Dependency injection for isolated testing -- **Type Safe**: Full Python type hints -- **Well Documented**: Comprehensive docstrings and examples - -## Quick Start - -### Basic Usage - -```python -from lib.paths import PathResolver, Scope - -# Create resolver (auto-detects context) -resolver = PathResolver() - -# Get memory directory -memory_dir = resolver.get_memory_dir("_semantic/decisions", Scope.PROJECT) -# => /path/to/project/.claude/mnemonic/_semantic/decisions - -# Get full memory path -memory_path = resolver.get_memory_path( - "_semantic/decisions", - "slug.memory.md", - Scope.PROJECT -) - -# Get search paths (returns list in priority order) -search_paths = resolver.get_search_paths("_semantic/decisions") -# => [project_path, org_path, default_path] - -# Get blackboard directory -blackboard = resolver.get_blackboard_dir(Scope.PROJECT) -``` - -### Convenience Functions - -For simple use cases, use convenience functions: - -```python -from lib.paths import get_memory_dir, get_search_paths, get_blackboard_dir - -# Get memory directory (string scope) -memory_dir = get_memory_dir("_semantic/decisions", scope="project") - -# Get search paths -paths = get_search_paths("_semantic/decisions", include_user=True, include_project=True) - -# Get blackboard -blackboard = get_blackboard_dir(scope="project") -``` - -## Architecture - -### PathResolver - -Central class that computes paths based on context and scheme. - -**Key Methods:** - -- `get_memory_dir(namespace, scope)` - Directory for storing memories -- `get_memory_path(namespace, filename, scope)` - Full file path -- `get_search_paths(namespace, filters)` - Ordered search paths -- `get_blackboard_dir(scope)` - Blackboard directory -- `get_ontology_paths()` - Ontology files in precedence order -- `get_all_memory_roots()` - All memory root directories - -### PathContext - -Dataclass holding environment context: - -```python -@dataclass -class PathContext: - org: str # Organization (from git remote) - project: str # Project name (from git remote) - home_dir: Path # User home directory - project_dir: Path # Current project directory - scheme: PathScheme # Path scheme to use -``` - -Auto-detection: - -```python -# Auto-detect context -context = PathContext.detect() - -# Or specify scheme -context = PathContext.detect(scheme=PathScheme.V2) -``` - -### PathScheme - -Enum defining supported path schemes: - -- `LEGACY` - Current dual-location structure -- `V2` - Target unified structure - -### Scope - -Enum defining memory scope: - -- `USER` - Cross-project memories -- `PROJECT` - Project-specific memories -- `ORG` - Organization-wide memories (V2 only) - -## Path Schemes - -### LEGACY Scheme (Current) - -**User memories**: -``` -${MNEMONIC_ROOT}/{org}/{namespace}/ -``` - -**Project memories**: -``` -./.claude/mnemonic/{namespace}/ -``` - -**Example**: -``` -${MNEMONIC_ROOT}/myorg/_semantic/decisions/ -./.claude/mnemonic/_semantic/decisions/ -``` - -### V2 Scheme (Target) - -**Project memories**: -``` -${MNEMONIC_ROOT}/{org}/{project}/{namespace}/ -``` - -**Org-wide memories**: -``` -${MNEMONIC_ROOT}/{org}/{namespace}/ -``` - -**Example**: -``` -${MNEMONIC_ROOT}/myorg/myproject/_semantic/decisions/ -${MNEMONIC_ROOT}/myorg/_semantic/decisions/ -``` - -## Testing - -### Unit Tests - -Create isolated test contexts: - -```python -import pytest -from pathlib import Path -from lib.paths import PathResolver, PathContext, PathScheme, Scope - -@pytest.fixture -def test_resolver(tmp_path): - """Create test resolver with isolated paths.""" - context = PathContext( - org="testorg", - project="testproject", - home_dir=tmp_path / "home", - project_dir=tmp_path / "project", - scheme=PathScheme.LEGACY, - ) - return PathResolver(context) - -def test_memory_operations(test_resolver, tmp_path): - """Test with isolated file system.""" - memory_dir = test_resolver.get_memory_dir("_semantic/decisions", Scope.PROJECT) - memory_dir.mkdir(parents=True) - - # Test operations... - assert memory_dir.exists() -``` - -### Integration Tests - -Test with both schemes: - -```python -@pytest.fixture(params=[PathScheme.LEGACY, PathScheme.V2]) -def resolver_both_schemes(request, tmp_path): - """Test with both path schemes.""" - context = PathContext( - org="testorg", - project="testproject", - home_dir=tmp_path / "home", - project_dir=tmp_path / "project", - scheme=request.param, - ) - return PathResolver(context) - -def test_path_resolution(resolver_both_schemes): - """Test that works with both schemes.""" - memory_dir = resolver_both_schemes.get_memory_dir("semantic", Scope.PROJECT) - # Assertions... -``` - -## Integration Examples - -### Hooks - -```python -from lib.paths import PathResolver - -def count_memories(resolver: PathResolver) -> dict: - """Count memories using resolver.""" - counts = {} - - for root in resolver.get_all_memory_roots(): - for memory_file in root.rglob("*.memory.md"): - # Count logic... - pass - - return counts - -def main(): - resolver = PathResolver() - counts = count_memories(resolver) - print(f"Total: {sum(counts.values())}") -``` - -### Commands - -```python -from lib.paths import PathResolver, Scope - -def capture_memory(namespace: str, title: str, scope: str = "project"): - """Capture a new memory.""" - resolver = PathResolver() - scope_enum = Scope.PROJECT if scope == "project" else Scope.USER - - # Get memory directory - memory_dir = resolver.get_memory_dir(namespace, scope_enum) - memory_dir.mkdir(parents=True, exist_ok=True) - - # Create memory file - memory_path = resolver.get_memory_path( - namespace, - f"{slug}.memory.md", - scope_enum - ) - - # Write content... -``` - -### Ontology System - -```python -from lib.paths import PathResolver - -class OntologyRegistry: - def __init__(self, resolver: PathResolver = None): - self.resolver = resolver or PathResolver() - - def load_ontologies(self): - """Load all ontologies in precedence order.""" - for ontology_path in self.resolver.get_ontology_paths(): - if ontology_path.exists(): - yield self._load_ontology_file(ontology_path) -``` - -## Dependency Injection - -Components should accept resolver as optional parameter: - -```python -from lib.paths import PathResolver - -class MemoryManager: - def __init__(self, resolver: PathResolver = None): - """Initialize with optional resolver (for testing).""" - self.resolver = resolver or PathResolver() - - def save_memory(self, namespace: str, content: str): - memory_dir = self.resolver.get_memory_dir(namespace) - # Save logic... -``` - -This enables easy testing: - -```python -def test_memory_manager(test_resolver): - """Test with isolated paths.""" - manager = MemoryManager(resolver=test_resolver) - manager.save_memory("_semantic/decisions", "test") - # Assertions... -``` - -## Migration - -### Analyzing Current Structure - -```python -from lib.paths import PathResolver, PathScheme, PathContext - -# Get legacy paths -legacy_resolver = PathResolver() # defaults to LEGACY -legacy_roots = legacy_resolver.get_all_memory_roots() - -# Get V2 paths -v2_context = PathContext.detect(scheme=PathScheme.V2) -v2_resolver = PathResolver(v2_context) -v2_root = v2_resolver.get_all_memory_roots()[0] - -print(f"Migrating from {len(legacy_roots)} roots to {v2_root}") -``` - -### Migration Script - -See `scripts/migrate_to_v2_paths.py` for complete example: - -```python -# Run migration -python scripts/migrate_to_v2_paths.py --dry-run # preview -python scripts/migrate_to_v2_paths.py # execute - -# Rollback if needed -python scripts/migrate_to_v2_paths.py --rollback /path/to/backup -``` - -## Performance - -### Caching - -For hot paths, add caching: - -```python -from functools import lru_cache - -class PathResolver: - @lru_cache(maxsize=128) - def get_memory_dir(self, namespace: str, scope: Scope) -> Path: - # Implementation... -``` - -### Lazy Evaluation - -Don't create resolvers at module level: - -```python -# BAD - creates on import -_resolver = PathResolver() - -# GOOD - create when needed -def get_resolver() -> PathResolver: - return PathResolver() -``` - -## Design Principles - -### 1. Pure Functions - -Path resolution is pure computation - no I/O operations: - -```python -# Resolver just computes paths -path = resolver.get_memory_dir("semantic") # No mkdir - -# Caller handles I/O -path.mkdir(parents=True, exist_ok=True) -``` - -### 2. Explicit Over Implicit - -Be explicit about scope and scheme: - -```python -# Clear and explicit -resolver.get_memory_dir("semantic", Scope.PROJECT) - -# Not implicit defaults -resolver.get_memory_dir("semantic") # would need default -``` - -### 3. Fail Fast - -Invalid inputs should raise early: - -```python -# Type system catches errors -resolver.get_memory_dir("semantic", "invalid") # Type error! -resolver.get_memory_dir("semantic", Scope.PROJECT) # OK -``` - -### 4. Testability First - -Design for testing with dependency injection: - -```python -class Component: - def __init__(self, resolver: PathResolver = None): - self.resolver = resolver or PathResolver() -``` - -## Common Patterns - -### Pattern: Search Across All Scopes - -```python -# Get all search paths in priority order -search_paths = resolver.get_search_paths( - namespace="_semantic/decisions", - include_user=True, - include_project=True, - include_org=True # V2 only -) - -# Search with ripgrep -for path in search_paths: - subprocess.run(["rg", pattern, str(path)]) -``` - -### Pattern: Create Memory - -```python -def create_memory(namespace: str, content: str, scope: Scope): - resolver = PathResolver() - - # Get directory and create if needed - memory_dir = resolver.get_memory_dir(namespace, scope) - memory_dir.mkdir(parents=True, exist_ok=True) - - # Get full path - filename = f"{slug}.memory.md" - memory_path = resolver.get_memory_path(namespace, filename, scope) - - # Write content - memory_path.write_text(content) -``` - -### Pattern: Load Ontology - -```python -def load_ontology(): - resolver = PathResolver() - - # Try paths in precedence order - for ontology_path in resolver.get_ontology_paths(): - if ontology_path.exists(): - return yaml.safe_load(ontology_path.read_text()) - - # Use default - return get_default_ontology() -``` - -### Pattern: Health Check - -```python -def health_check(): - resolver = PathResolver() - stats = {"total": 0, "by_root": {}} - - for root in resolver.get_all_memory_roots(): - count = len(list(root.rglob("*.memory.md"))) - stats["total"] += count - stats["by_root"][str(root)] = count - - return stats -``` - -## Troubleshooting - -### Import Errors - -Add lib to Python path: - -```python -import sys -from pathlib import Path - -# Add lib directory to path -lib_dir = Path(__file__).parent.parent / "lib" -sys.path.insert(0, str(lib_dir)) - -from lib.paths import PathResolver -``` - -### Path Not Found - -Resolver computes paths, doesn't check existence: - -```python -# This always succeeds (just computation) -path = resolver.get_memory_dir("semantic") - -# Check existence when needed -if not path.exists(): - path.mkdir(parents=True) -``` - -### Wrong Scheme - -Explicitly specify scheme if auto-detection wrong: - -```python -from lib.paths import PathContext, PathScheme - -context = PathContext.detect(scheme=PathScheme.V2) -resolver = PathResolver(context) -``` - -## API Reference - -See inline docstrings in `lib/paths.py` for complete API documentation. - -### PathResolver Methods - -- `get_memory_dir(namespace, scope)` - Memory directory path -- `get_memory_path(namespace, filename, scope)` - Full memory file path -- `get_search_paths(namespace, filters)` - Search paths in priority order -- `get_blackboard_dir(scope)` - Blackboard directory -- `get_ontology_paths()` - Ontology paths in precedence order -- `get_all_memory_roots()` - All memory root directories - -### Convenience Functions - -- `get_default_resolver()` - Get resolver with auto-detected context -- `get_memory_dir(namespace, scope)` - Shortcut for get_memory_dir -- `get_search_paths(namespace, filters)` - Shortcut for get_search_paths -- `get_blackboard_dir(scope)` - Shortcut for get_blackboard_dir - -## Related Documentation - -- [ADR-009: Unified Path Resolution](../docs/adrs/adr-009-unified-path-resolution.md) - Architecture decision -- [Integration Guide](../docs/architecture/path-resolution-integration.md) - Component integration -- [Migration Script](../scripts/migrate_to_v2_paths.py) - V2 migration tool -- [Unit Tests](../tests/unit/test_paths.py) - Test examples - -## Contributing - -When adding new path-related functionality: - -1. Add method to `PathResolver` class -2. Add unit tests for new method -3. Update this README with examples -4. Document in ADR if significant change - -## License - -MIT - Same as mnemonic project diff --git a/lib/__init__.py b/lib/__init__.py index 58e2bbf..afe9ed9 100644 --- a/lib/__init__.py +++ b/lib/__init__.py @@ -1,138 +1 @@ -""" -Mnemonic Library Package - -Core utilities and shared libraries for the mnemonic memory system. -""" - -# Make paths module easily importable -from .memory_reader import ( - get_memory_metadata, - get_memory_summary, -) -from .ontology import ( - get_fallback_content_patterns, - get_fallback_file_patterns, - get_ontology_file, - get_ontology_info, - load_content_patterns, - load_file_patterns, - load_ontology_data, - load_ontology_namespaces, - validate_memory_against_ontology, -) -from .paths import ( - PathContext, - PathResolver, - PathScheme, - Scope, - get_all_memory_roots_with_legacy, - get_blackboard_dir, - get_default_resolver, - get_handoff_dir, - get_memory_dir, - get_search_paths, - get_session_blackboard_dir, - get_v2_resolver, - migrate_blackboard_to_session_scoped, -) -from .relationships import ( - RECIPROCAL_TYPES, - REL_DERIVED_FROM, - REL_RELATES_TO, - REL_SUPERSEDES, - RELATIONSHIP_TYPES, - add_bidirectional_relationship, - add_relationship, - get_all_valid_types, - get_inverse, - is_symmetric, - is_valid_type, - to_pascal, - to_snake, -) -from .search import ( - SCORE_CONTENT_KEYWORD, - SCORE_MIN_THRESHOLD, - SCORE_NAMESPACE_EXACT, - SCORE_NAMESPACE_TYPE, - SCORE_TAG_OVERLAP, - SCORE_TITLE_KEYWORD, - detect_file_context, - detect_namespace_for_file, - extract_keywords_from_path, - extract_topic, - find_duplicates, - find_memories_for_context, - find_related_memories, - find_related_memories_scored, - infer_relationship_type, - search_memories, -) - -__all__ = [ - # Core classes - "PathResolver", - "PathContext", - "PathScheme", - "Scope", - # Path convenience functions - "get_default_resolver", - "get_memory_dir", - "get_search_paths", - "get_blackboard_dir", - "get_session_blackboard_dir", - "get_handoff_dir", - "get_v2_resolver", - "get_all_memory_roots_with_legacy", - "migrate_blackboard_to_session_scoped", - # Ontology functions - "get_ontology_file", - "load_ontology_data", - "load_file_patterns", - "load_content_patterns", - "load_ontology_namespaces", - "get_fallback_file_patterns", - "get_fallback_content_patterns", - "get_ontology_info", - "validate_memory_against_ontology", - # Search functions - "search_memories", - "find_related_memories", - "find_related_memories_scored", - "find_memories_for_context", - "find_duplicates", - "detect_file_context", - "detect_namespace_for_file", - "extract_keywords_from_path", - "extract_topic", - "infer_relationship_type", - # Relationship type constants - "REL_RELATES_TO", - "REL_SUPERSEDES", - "REL_DERIVED_FROM", - # Scoring weight constants - "SCORE_NAMESPACE_TYPE", - "SCORE_NAMESPACE_EXACT", - "SCORE_TAG_OVERLAP", - "SCORE_TITLE_KEYWORD", - "SCORE_CONTENT_KEYWORD", - "SCORE_MIN_THRESHOLD", - # Memory reader functions - "get_memory_summary", - "get_memory_metadata", - # Relationship type registry - "RELATIONSHIP_TYPES", - "RECIPROCAL_TYPES", - # Relationship writer functions - "add_relationship", - "add_bidirectional_relationship", - # Relationship type helpers - "to_pascal", - "to_snake", - "get_inverse", - "is_valid_type", - "is_symmetric", - "get_all_valid_types", -] - -__version__ = "1.1.0" +"""Mnemonic core library modules.""" diff --git a/reports/README.md b/reports/README.md deleted file mode 100644 index 05b506d..0000000 --- a/reports/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Research Index - -All market research conducted for the mnemonic project. - -| Topic | Status | Created | Last Updated | Summary | -|-------|--------|---------|--------------|---------| -| [AI Memory Systems with Filesystem-Based Interfaces](./ai-memory-filesystem-research/) | complete | 2026-01-24 | 2026-01-24 | Academic validation and competitive analysis of filesystem-based AI memory approaches | - -## Quick Links - -### Completed Research - -- [AI Memory Systems Research](./ai-memory-filesystem-research/) - Comprehensive analysis validating filesystem-based memory approaches, MCP ecosystem trends, cognitive science foundations, and competitive landscape - ---- - -*Generated by [sigint](https://github.com/zircote/sigint)* diff --git a/reports/ai-memory-filesystem-research/2026-01-24-executive-summary.md b/reports/ai-memory-filesystem-research/2026-01-24-executive-summary.md deleted file mode 100644 index 977413e..0000000 --- a/reports/ai-memory-filesystem-research/2026-01-24-executive-summary.md +++ /dev/null @@ -1,102 +0,0 @@ -# AI Memory Systems: Executive Brief -## Strategic Assessment for Mnemonic - -**Date**: 2026-01-24 | **Classification**: Strategic Planning | **Audience**: Executive Leadership - ---- - -## The Opportunity - -The AI agents market will grow from **$5.25B (2024) to $52.62B (2030)** at 46.3% CAGR. Persistent memory is now **table stakes** for AI assistants. Mnemonic is positioned to capture the underserved "simple + private" market segment. - ---- - -## Key Findings - -| Finding | Implication | -|---------|-------------| -| **Filesystem beats vector databases**: Letta benchmark shows 74.0% vs 68.5% accuracy | Mnemonic's approach is validated empirically | -| **GitHub Copilot validates approach**: 7% PR merge improvement with citation-based memory | Industry leader confirms mnemonic's design direction | -| **Market gap exists**: Cursor/Windsurf lack native memory; Mem0/Zep deprecated community editions | Clear opportunity for simple, private solution | -| **Simplicity correlates with reliability**: LLMs perform better with familiar filesystem tools | Complexity is liability, not feature | - ---- - -## Competitive Position - -``` - Simple <----------------> Complex - | | - Private/Local [MNEMONIC] [Mem0] - | | | - | [Basic Memory] [Zep Cloud] - | | | - Cloud/Hosted [Copilot Memory] [LangChain Memory] -``` - -**Mnemonic owns the "Simple + Private" quadrant** - underserved by market leaders focused on complex cloud solutions. - ---- - -## Strategic Recommendation - -**Pursue organic growth through filesystem simplicity.** - -| Factor | Assessment | -|--------|------------| -| Investment Required | LOW - Documentation and community engagement | -| Timeline to Validation | 6-12 months | -| Risk Level | LOW | -| Success Probability | 60% (Niche Success scenario) | - -AI assistants with Bash access can use mnemonic immediately. No protocol integration required. - ---- - -## Differentiation - -| Mnemonic Advantage | Why It Matters | -|--------------------|----------------| -| Zero dependencies | No databases, cloud, or accounts | -| Git integration | Full audit trail; offline; conflict resolution | -| Human-readable | Developers inspect/edit memories directly | -| POSIX composable | Works with any Unix tool | -| Benchmark validated | Empirical proof of superiority | - ---- - -## Risk Assessment - -| Risk | Likelihood | Impact | Mitigation | -|------|------------|--------|------------| -| AI assistants build native memory | Medium | High | Emphasize portability | -| Scale limitations | Medium | Medium | Performance benchmarking | -| Protocol dominance (MCP) | Low | Medium | Filesystem always works | - ---- - -## Key Metrics to Track - -- GitHub stars growth (target: 1K+ in 12 months) -- Memory Bank community migration rate -- Enterprise pilot opportunities -- AI assistant native memory announcements - ---- - -## Decision Required - -**Approve organic growth strategy** focused on: -1. Documentation and integration guides (DONE) -2. Community engagement with Memory Bank users (DONE) -3. Enterprise positioning around data sovereignty (DONE) - -**Investment**: Minimal (documentation effort) -**Timeline**: Already underway -**Next Review**: Q2 2026 - ---- - -*Full report available: [2026-01-24-report.md](./2026-01-24-report.md)* - -*Generated by sigint market research agent | 2026-01-24* diff --git a/reports/ai-memory-filesystem-research/2026-01-24-report-metadata.json b/reports/ai-memory-filesystem-research/2026-01-24-report-metadata.json deleted file mode 100644 index f6dfa8e..0000000 --- a/reports/ai-memory-filesystem-research/2026-01-24-report-metadata.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "report_id": "ai-memory-filesystem-research-2026-01-24", - "research_id": "ai-memory-filesystem-research", - "generated": "2026-01-24T15:30:00Z", - "version": "1.0", - "status": "final", - "formats": { - "markdown": { - "file": "2026-01-24-report.md", - "generated": true - }, - "html": { - "file": "2026-01-24-report.html", - "generated": true - }, - "executive_brief": { - "file": "2026-01-24-executive-summary.md", - "generated": true - } - }, - "sections": { - "executive_summary": true, - "market_overview": true, - "market_sizing": true, - "competitive_landscape": true, - "trend_analysis": { - "macro": true, - "micro": true, - "transitional_scenarios": true, - "terminal_scenarios": true - }, - "swot_analysis": true, - "recommendations": true, - "risk_assessment": true, - "appendix": true - }, - "visualizations": { - "mermaid_charts": [ - "pie: AI Memory Market Segments", - "pie: Market Sizing Breakdown", - "quadrantChart: Competitive Positioning", - "stateDiagram: Transitional Scenarios", - "quadrantChart: Scenario Trade-offs", - "quadrantChart: SWOT Analysis Overview", - "quadrantChart: Risk Assessment Matrix" - ], - "total_count": 7 - }, - "audience_tailoring": { - "executives": { - "included": true, - "section": "Decision Support - For Executives" - }, - "product_managers": { - "included": true, - "section": "Decision Support - For Product Managers" - }, - "investors": { - "included": true, - "section": "Decision Support - For Investors" - }, - "developers": { - "included": true, - "section": "Decision Support - For Developers" - } - }, - "elicitation_alignment": { - "decision_context": "Academic validation, strategic planning, and feature roadmap for mnemonic", - "hypotheses_validated": true, - "anti_patterns_avoided": true, - "success_criteria_addressed": true - }, - "quality_checks": { - "executive_summary_captures_key_points": true, - "claims_have_cited_sources": true, - "numbers_consistent": true, - "diagrams_render": true, - "recommendations_actionable": true, - "risks_addressed": true, - "audience_appropriate_language": true - }, - "findings_count": 18, - "sources_count": 12, - "recommendations_count": 5, - "risks_identified": 7, - "word_count_estimate": 5500 -} diff --git a/reports/ai-memory-filesystem-research/2026-01-24-report.html b/reports/ai-memory-filesystem-research/2026-01-24-report.html deleted file mode 100644 index 79bbe12..0000000 --- a/reports/ai-memory-filesystem-research/2026-01-24-report.html +++ /dev/null @@ -1,1303 +0,0 @@ - - - - - - AI Memory Systems with Filesystem-Based Interfaces - Market Research Report - - - - -
-

AI Memory Systems with Filesystem-Based Interfaces

-

Comprehensive Market Research Report

- -
- - - -
-

Research Brief Alignment

-

This report addresses the decision context of academic validation, strategic planning, and feature roadmap for mnemonic. All recommendations preserve filesystem simplicity. MCP integration is explicitly out of scope per project decision.

-
- -
-

1. Executive Summary

- -
-

Key Findings

- -
-
1
-
-

Filesystem approaches outperform specialized tools

-

Letta's LoCoMo benchmark demonstrates filesystem-based memory achieves 74.0% accuracy compared to Mem0's graph-based approach at 68.5%.

-
-
- -
-
2
-
-

Unix philosophy is academically validated for AI

-

A recent arxiv paper ("From Everything is a File to Files Are All You Need") explicitly validates Unix's "everything is a file" principle for modern agentic AI design.

-
-
- -
-
3
-
-

Market gap in simple, private memory

-

While MCP-based solutions grow in complexity (97M+ monthly SDK downloads), mnemonic occupies a unique position: zero dependencies, full data sovereignty, human-readable format.

-
-
- -
-
4
-
-

Industry validation from GitHub

-

Copilot's agentic memory system (public preview Jan 15, 2026) demonstrates 7% PR merge rate improvement using citation-based validation.

-
-
- -
-
5
-
-

Agentic memory is now table stakes

-

VentureBeats 2026 predictions identify persistent memory as essential capability for AI assistants.

-
-
-
- -

Primary Strategic Recommendation

-
-

Pursue organic growth through filesystem simplicity. AI assistants with native Bash/filesystem access (Claude Code, Cursor, Windsurf, Copilot) can use mnemonic directly without protocol overhead. This approach is validated by Letta's benchmark finding that LLMs perform better with familiar tools.

-
- -

Market Opportunity Statement

-

The AI memory systems market represents a $52.62B opportunity by 2030 (46.3% CAGR), with mnemonic positioned to capture the underserved "simple + private/local" segment that enterprise and privacy-conscious developers increasingly demand.

-
- -
-

2. Market Overview

- -

Market Definition and Boundaries

-

The AI memory systems market encompasses technologies enabling persistent context and knowledge retention for AI agents and coding assistants, including:

-
    -
  • Memory infrastructure: Storage, retrieval, and management of AI agent memories
  • -
  • Context engineering: Tools for managing and optimizing context windows
  • -
  • Knowledge management for AI: Structured knowledge bases accessible to AI systems
  • -
- -

Total Market Size

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Market Segment2024 Size2030 ProjectionCAGR
AI Agents Market$5.25B$52.62B46.3%
Knowledge Management$773.6B$3.5T (2034)16.3%
Multi-Agent SystemsFastest growing segment
- -

Key Segments and Characteristics

-
-
-pie title AI Memory Market Segments - "Enterprise AI Assistants" : 35 - "Individual Developers" : 30 - "Open Source Projects" : 20 - "Multi-Agent Systems" : 15 -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SegmentCharacteristicsKey Needs
Enterprise AI AssistantsCompliance-driven, security-focusedAudit trails, data sovereignty, offline access
Individual DevelopersValue simplicity, portabilityEasy setup, no vendor lock-in, human-readable
Open Source ProjectsVendor-neutral requirementsSelf-hosted, transparent, community-driven
Multi-Agent SystemsCoordination-focusedShared memory, cross-agent communication
- -

Market Maturity Stage

-

Early Growth Phase: The market is transitioning from experimental to production deployments. GitHub Copilot's public preview of agentic memory (Jan 2026) signals mainstream adoption is imminent.

-
- -
-

3. Market Sizing (TAM/SAM/SOM)

- -

Total Addressable Market (TAM)

-

$52.62B by 2030 - Global AI agents market

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MetricValueTrend
2024 Market Size$5.25B-
2030 Projection$52.62BINC
CAGR46.3%INC
Growth DriverMulti-agent systems, enterprise adoptionINC
- -

Serviceable Addressable Market (SAM)

-

$8B by 2030 - Developer tools and AI coding assistant memory segment

- - - - - - - - - - - - - - - - - - - - - - - - - -
MetricValueTrend
Target SegmentAI coding assistants + developer knowledge toolsINC
Geographic ConstraintsGlobal (English-first documentation)CONST
Estimated SAM~15% of TAMINC
- -

Serviceable Obtainable Market (SOM)

-

$50M-100M by 2028 - Privacy-focused, filesystem-based memory solutions

- - - - - - - - - - - - - - - - - - - - - - - - - -
MetricValueTrend
Realistic Market Share0.5-1% of SAMINC
Timeline24-36 months-
Growth MechanismOrganic community adoption, enterprise pilotsINC
- -
-
-pie title Market Sizing Breakdown - "TAM (Global AI Agents)" : 100 - "SAM (Dev Tools)" : 15 - "SOM (Filesystem-based)" : 2 -
-
-
- -
-

4. Competitive Landscape

- -

Competitor Matrix

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CompanyMarket ShareStrengthsWeaknessesTrend
Mem025%26% accuracy claims; temporal graph; fundingComplex; cloud-dependent; CE deprecatedCONST
Zep20%LangChain integration; session managementCloud-focused; CE deprecatedDEC
LangChain Memory30%Framework integration; flexibilityRequires external DBs; complexCONST
GitHub Copilot Memory15%Native integration; citation validationCopilot-only; cloud; 28-day expiryINC
Filesystem Solutions10%Simple; private; git-integratedLimited awareness; fragmentedINC
- -

Porter's 5 Forces Summary

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ForceLevelAnalysis
Competitive RivalryMediumFragmented market; open source reduces barriers
Supplier PowerLowCommodity infrastructure (filesystems, git)
Buyer PowerHighEasy switching; low costs for simple solutions
Threat of SubstitutionMediumNative AI memory features could substitute
Threat of New EntryHighLow barriers; any developer can build
- -

Competitive Positioning Map

-
-
-quadrantChart - title Competitive Positioning: Simplicity vs Privacy - x-axis Simple --> Complex - y-axis Cloud/Hosted --> Private/Local - quadrant-1 Complex + Private - quadrant-2 Simple + Private - quadrant-3 Simple + Cloud - quadrant-4 Complex + Cloud - Mnemonic: [0.15, 0.9] - Basic Memory: [0.3, 0.7] - Memory Bank: [0.2, 0.8] - Copilot Memory: [0.4, 0.2] - Mem0: [0.8, 0.25] - Zep: [0.75, 0.15] - LangChain: [0.7, 0.5] -
-
- -

Competitive Position Summary

-
Simple <----------------> Complex - | | - Private/Local [MNEMONIC] [Mem0] - | | | - | [Basic Memory] [Zep Cloud] - | | | - Cloud/Hosted [Copilot Memory] [LangChain Memory]
-

Mnemonic's Position: Occupies the "Simple + Private" quadrant - currently underserved by major players who focus on complex cloud solutions.

-
- -
-

5. Trend Analysis

- -

Macro Trends

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TrendDirectionEvidenceImpact on Mnemonic
Agentic AI maturationINCMulti-agent protocols (MCP, ACP, A2A, ANP)Opportunity for multi-agent coordination
Context engineering emergenceINCAnthropic's context engineering guideValidates context management importance
Privacy and data sovereigntyINCEnterprise concerns about cloud AIPositions mnemonic as compliant solution
Agentic memory as table stakesINCVentureBeats 2026 predictionsValidates market timing
Native tool proficiencyINCLetta benchmark findingsConfirms filesystem approach superiority
- -

Micro Trends

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TrendDirectionEvidenceTimeframe
Vector DB fatigueINCLetta benchmark; complexity complaints6-12 months
Citation-based validationINC++GitHub Copilot public previewProduction-ready
Filesystem-based AI toolsINCArxiv paper; Letta research12 months
Context compressionINC6:1 compression at 90% fidelity6-12 months
Cognitive memory modelsCONSTAlready adopted; stabilizingOngoing
Cloud-only solutionsDECPrivacy concerns; data sovereignty12-24 months
- -

Transitional Scenario Graph

-
-
-stateDiagram-v2 - [*] --> CurrentState: Mnemonic v1.0 - - CurrentState --> OrganicGrowth: Community adoption (60%) - CurrentState --> EnterpriseAdoption: Data sovereignty appeal (25%) - CurrentState --> Stagnation: No marketing effort (5%) - - OrganicGrowth --> NicheSuccess: Memory Bank migration - OrganicGrowth --> PlatformPlay: Multi-agent features - - EnterpriseAdoption --> PlatformPlay: Team features - EnterpriseAdoption --> NicheSuccess: Compliance focus - - NicheSuccess --> SteadyState: Sustainable OSS - PlatformPlay --> MarketLeader: Cross-tool dominance - - Stagnation --> Obsolete: Market moves on - - SteadyState --> [*]: Niche success - MarketLeader --> [*]: Market leadership - Obsolete --> [*]: Project archived -
-
- -

Terminal Scenarios

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ScenarioProbabilityPathTrade-offs
Niche Success60%Organic growth -> Steady communityLimited scale but sustainable
Platform Play10%Multi-agent + Enterprise -> Market leaderRequires significant investment
Enterprise Adoption25%Data sovereignty focus -> Compliance nicheMay limit developer appeal
Stagnation5%No action -> Obsolescence-
-
- -
-

6. SWOT Analysis

- -
-
-

Strengths

-
    -
  • Benchmark validation: 74.0% vs 68.5% on LoCoMo
  • -
  • Zero dependencies: No databases, cloud, accounts
  • -
  • Git integration: Version history, conflict resolution
  • -
  • Human readability: Markdown + YAML frontmatter
  • -
  • POSIX composability: Works with any Unix tool
  • -
  • Cognitive types: Academically grounded
  • -
-
- -
-

Weaknesses

-
    -
  • Scale untested: Unknown at 10K+ files
  • -
  • Limited awareness: Low adoption
  • -
  • No cloud offering: Enterprise friction
  • -
  • Single maintainer: Bus factor risk
  • -
-
- -
-

Opportunities

-
    -
  • Market gap: Simple + private underserved
  • -
  • Memory Bank migration: Cursor/Windsurf users
  • -
  • GitHub validation: Citation approach confirmed
  • -
  • Enterprise sovereignty: Privacy regulations
  • -
  • Multi-agent coordination: 4 protocols emerging
  • -
-
- -
-

Threats

-
    -
  • Native AI memory: Assistants build their own
  • -
  • Protocol standardization: MCP dominance
  • -
  • Vector DB simplification: Easier alternatives
  • -
  • Enterprise competitors: Well-funded entrants
  • -
-
-
-
- -
-

7. Recommendations

- -

Strategic Recommendations (Prioritized)

- -
-

Priority 1 Focus on Documentation and Integration Guides

- - - - - -
StatementCreate comprehensive integration guides for Cursor, Windsurf, Claude Code, and Copilot showing Bash-native access patterns
RationaleLLMs perform best with filesystem tools they were trained on
Expected Outcome3x increase in GitHub stars within 6 months
StatusIMPLEMENTED
-
- -
-

Priority 2 Position for Enterprise Data Sovereignty

- - - - - -
StatementEmphasize audit trails, offline access, and data sovereignty
RationaleCloud-only competitors create opportunity for on-premise
Expected OutcomeEnterprise pilot opportunities
StatusIMPLEMENTED
-
- -
-

Priority 3 Engage Memory Bank Community

- - - - - -
StatementActively participate in Memory Bank communities as potential adopters
RationaleExisting workarounds validate need; mnemonic offers superior solution
Expected OutcomeMigration of Memory Bank users
StatusIMPLEMENTED
-
- -
-

Priority 4 Implement Citation Validation

- - - - - -
StatementAdd optional citation fields for code references; create validation tool
RationaleGitHub Copilot's success (7% PR improvement)
Expected OutcomeReduced stale memory usage
StatusIMPLEMENTED
-
- -
-

Priority 5 Implement Memory Compression

- - - - - -
StatementAdd auto-summarization for context window efficiency
RationaleResearch shows 6:1 compression achievable
Expected OutcomeBetter context window utilization
StatusIMPLEMENTED (gc --compress)
-
-
- -
-

8. Risk Assessment

- -

Risk Matrix

-
-
-quadrantChart - title Risk Assessment Matrix - x-axis Low Impact --> High Impact - y-axis Low Probability --> High Probability - quadrant-1 Critical Risks - quadrant-2 Monitor Closely - quadrant-3 Low Priority - quadrant-4 Contingency Plan - Native AI Memory: [0.85, 0.5] - Scale Limitations: [0.5, 0.5] - Memory Sprawl: [0.4, 0.6] - Format Lock-in: [0.2, 0.2] - Protocol Dominance: [0.6, 0.3] - Cross-project Leak: [0.3, 0.4] -
-
- -

Detailed Risk Table

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RiskCategoryProbabilityImpactMitigation
AI assistants build native memoryMarketMedium (50%)HighEmphasize portability; multi-tool design
Scale limitations at 10K+ filesTechnicalMedium (40%)MediumPerformance benchmarking; optimize ripgrep
Memory sprawlTechnicalHigh (60%)LowDecay modeling; GC tooling ✓
Protocol-based solutions dominateMarketLow (30%)MediumFilesystem always works with Bash
Format lock-in concernsTechnicalLow (20%)LowMIF is open standard
- -

Monitoring Indicators

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IndicatorSourceThresholdAction
GitHub stars growthGitHub API<10% monthlyIncrease community engagement
AI assistant native memory announcementsTech newsAny majorAssess portability positioning
Competitor open source movesGitHub, BlogsCE returnsRe-evaluate competitive position
ripgrep performance at scaleInternal testing>100ms queriesOptimize or add indexing
-
- -
-

9. Appendix

- -

A. Complete Data Sources

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SourceTypeReliability
Letta AI Research - Benchmarking AI Agent MemoryResearchHigh
arxiv - Unix Philosophy for Agentic AIAcademicHigh
GitHub - Copilot Agentic MemoryIndustryHigh
Anthropic - Context EngineeringIndustryHigh
ripgrep BenchmarksDocumentationHigh
Martin Fowler - Bitemporal HistoryDocumentationHigh
AI Long-term Memory SurveyAcademicHigh
Mem0 ResearchResearchMedium
- -

B. Glossary

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TermDefinition
MIFMemory Interchange Format - mnemonic's open standard for memory files
MCPModel Context Protocol - Anthropic's protocol for AI-tool communication
LoCoMoLong Context Memory benchmark used by Letta
TAM/SAM/SOMTotal/Serviceable/Obtainable Addressable Market
Bi-temporalData modeling tracking both valid time and transaction time
POSIXPortable Operating System Interface - Unix standards
-
- -
-

Report generated by sigint market research agent

-

Generated: 2026-01-24 | Research ID: ai-memory-filesystem-research

-
- - - - diff --git a/reports/ai-memory-filesystem-research/2026-01-24-report.md b/reports/ai-memory-filesystem-research/2026-01-24-report.md deleted file mode 100644 index 11cfbdb..0000000 --- a/reports/ai-memory-filesystem-research/2026-01-24-report.md +++ /dev/null @@ -1,678 +0,0 @@ -# AI Memory Systems with Filesystem-Based Interfaces -## Comprehensive Market Research Report - -**Report Date**: 2026-01-24 -**Report Version**: 1.0 -**Status**: Final -**Classification**: Strategic Planning - ---- - -## Research Brief Alignment - -This report addresses the decision context of **academic validation, strategic planning, and feature roadmap for mnemonic**. The analysis is structured for multiple audiences: - -| Audience | Focus Areas | -|----------|-------------| -| Executives | Strategic positioning, market opportunity, competitive moat | -| Product Managers | Feature roadmap, competitive features, customer insights | -| Investors | Market size, growth metrics, risk assessment | -| Developers | Technical feasibility, architecture implications, integration patterns | - -**Anti-Pattern Compliance**: All recommendations preserve filesystem simplicity. MCP integration is explicitly out of scope per project decision. No recommendations require departing from POSIX tool compatibility. - ---- - -## 1. Executive Summary - -### Key Findings - -1. **Filesystem approaches outperform specialized tools**: Letta's LoCoMo benchmark demonstrates filesystem-based memory achieves **74.0% accuracy** compared to Mem0's graph-based approach at **68.5%**. - -2. **Unix philosophy is academically validated for AI**: A recent arxiv paper ("From Everything is a File to Files Are All You Need") explicitly validates Unix's "everything is a file" principle for modern agentic AI design. - -3. **Market gap in simple, private memory**: While MCP-based solutions grow in complexity (97M+ monthly SDK downloads), mnemonic occupies a unique position: zero dependencies, full data sovereignty, human-readable format. - -4. **Industry validation from GitHub**: Copilot's agentic memory system (public preview Jan 15, 2026) demonstrates **7% PR merge rate improvement** using citation-based validation - aligning with mnemonic's provenance approach. - -5. **Agentic memory is now table stakes**: VentureBeats 2026 predictions identify persistent memory as essential capability for AI assistants. - -### Primary Strategic Recommendation - -**Pursue organic growth through filesystem simplicity.** AI assistants with native Bash/filesystem access (Claude Code, Cursor, Windsurf, Copilot) can use mnemonic directly without protocol overhead. This approach is validated by Letta's benchmark finding that LLMs perform better with familiar tools. - -### Critical Risks - -- AI coding assistants may build native memory (Medium likelihood, High impact) -- Scale limitations at 10K+ memory files (requires validation) -- Memory sprawl without decay management - -### Market Opportunity Statement - -The AI memory systems market represents a **$52.62B opportunity by 2030** (46.3% CAGR), with mnemonic positioned to capture the underserved "simple + private/local" segment that enterprise and privacy-conscious developers increasingly demand. - ---- - -## 2. Market Overview - -### Market Definition and Boundaries - -The AI memory systems market encompasses technologies enabling persistent context and knowledge retention for AI agents and coding assistants. This includes: - -- **Memory infrastructure**: Storage, retrieval, and management of AI agent memories -- **Context engineering**: Tools for managing and optimizing context windows -- **Knowledge management for AI**: Structured knowledge bases accessible to AI systems - -### Total Market Size - -| Market Segment | 2024 Size | 2030 Projection | CAGR | -|----------------|-----------|-----------------|------| -| AI Agents Market | $5.25B | $52.62B | 46.3% | -| Knowledge Management | $773.6B | $3.5T (2034) | 16.3% | -| Multi-Agent Systems | Fastest growing segment | - | - | - -### Key Segments and Characteristics - -```mermaid -pie title AI Memory Market Segments - "Enterprise AI Assistants" : 35 - "Individual Developers" : 30 - "Open Source Projects" : 20 - "Multi-Agent Systems" : 15 -``` - -| Segment | Characteristics | Key Needs | -|---------|-----------------|-----------| -| Enterprise AI Assistants | Compliance-driven, security-focused | Audit trails, data sovereignty, offline access | -| Individual Developers | Value simplicity, portability | Easy setup, no vendor lock-in, human-readable | -| Open Source Projects | Vendor-neutral requirements | Self-hosted, transparent, community-driven | -| Multi-Agent Systems | Coordination-focused | Shared memory, cross-agent communication | - -### Market Maturity Stage - -**Early Growth Phase**: The market is transitioning from experimental to production deployments. GitHub Copilot's public preview of agentic memory (Jan 2026) signals mainstream adoption is imminent. - ---- - -## 3. Market Sizing (TAM/SAM/SOM) - -### Total Addressable Market (TAM) - -**$52.62B by 2030** - Global AI agents market - -| Metric | Value | Trend | -|--------|-------|-------| -| 2024 Market Size | $5.25B | - | -| 2030 Projection | $52.62B | INC | -| CAGR | 46.3% | INC | -| Growth Driver | Multi-agent systems, enterprise adoption | INC | - -**Calculation Methodology**: Based on AI agents market projections which include infrastructure components for agent memory, coordination, and context management. - -**Data Sources**: Industry analyst reports, venture funding trends, enterprise adoption surveys. - -### Serviceable Addressable Market (SAM) - -**$8B by 2030** - Developer tools and AI coding assistant memory segment - -| Metric | Value | Trend | -|--------|-------|-------| -| Target Segment | AI coding assistants + developer knowledge tools | INC | -| Geographic Constraints | Global (English-first documentation) | CONST | -| Estimated SAM | ~15% of TAM | INC | - -**Segment Characteristics**: -- Developers using AI coding assistants (Cursor, Windsurf, Copilot, Claude Code) -- Teams requiring persistent context across sessions -- Projects needing audit trails and version control - -### Serviceable Obtainable Market (SOM) - -**$50M-100M by 2028** - Privacy-focused, filesystem-based memory solutions - -| Metric | Value | Trend | -|--------|-------|-------| -| Realistic Market Share | 0.5-1% of SAM | INC | -| Timeline | 24-36 months | - | -| Growth Mechanism | Organic community adoption, enterprise pilots | INC | - -**Key Assumptions**: -- Open source adoption follows typical 2-5% active user conversion -- Enterprise segment values data sovereignty at premium -- Memory Bank community migration captures 10-20% of users - -```mermaid -pie title Market Sizing Breakdown - "TAM (Global AI Agents)" : 100 - "SAM (Dev Tools)" : 15 - "SOM (Filesystem-based)" : 2 -``` - ---- - -## 4. Competitive Landscape - -### Competitor Matrix - -| Company | Market Share | Strengths | Weaknesses | Trend | -|---------|--------------|-----------|------------|-------| -| **Mem0** | 25% | 26% accuracy improvement claims; temporal graph; strong funding | Complex infrastructure; cloud-dependent; Community Edition deprecated | CONST | -| **Zep** | 20% | LangChain integration; session management; enterprise focus | Cloud-focused; Community Edition deprecated; complex setup | DEC | -| **LangChain Memory** | 30% | Framework integration; flexibility; developer mindshare | Requires external databases; configuration complexity | CONST | -| **GitHub Copilot Memory** | 15% | Native integration; citation validation; 7% PR improvement | Copilot-only; cloud-dependent; 28-day auto-expiry | INC | -| **Filesystem Solutions** | 10% | Simple; private; human-readable; git-integrated | Limited market awareness; fragmented ecosystem | INC | - -### Porter's 5 Forces Summary - -| Force | Level | Analysis | -|-------|-------|----------| -| **Competitive Rivalry** | Medium | Fragmented market with no dominant player; open source reduces barriers | -| **Supplier Power** | Low | Commodity infrastructure (filesystems, git, text editors) | -| **Buyer Power** | High | Developers can easily switch; low switching costs for simple solutions | -| **Threat of Substitution** | Medium | Native AI assistant memory features could substitute third-party solutions | -| **Threat of New Entry** | High | Low barriers; any developer can build memory system | - -### Competitive Positioning Map - -```mermaid -quadrantChart - title Competitive Positioning: Simplicity vs Privacy - x-axis Simple --> Complex - y-axis Cloud/Hosted --> Private/Local - quadrant-1 Complex + Private - quadrant-2 Simple + Private - quadrant-3 Simple + Cloud - quadrant-4 Complex + Cloud - Mnemonic: [0.15, 0.9] - Basic Memory: [0.3, 0.7] - Memory Bank: [0.2, 0.8] - Copilot Memory: [0.4, 0.2] - Mem0: [0.8, 0.25] - Zep: [0.75, 0.15] - LangChain: [0.7, 0.5] -``` - -**Mnemonic's Position**: Occupies the "Simple + Private" quadrant - currently underserved by major players who focus on complex cloud solutions. - -### Detailed Competitor Profiles - -#### Mem0 - -| Attribute | Detail | -|-----------|--------| -| **Approach** | Vector DB + Knowledge Graph hybrid | -| **Pricing** | Cloud-based subscription; Community Edition deprecated | -| **Key Feature** | 26% accuracy improvement over full-context; 90% token reduction | -| **Weakness** | Requires cloud infrastructure; not self-hostable long-term | -| **Threat Level** | Medium - different target market (enterprise cloud) | - -#### Zep - -| Attribute | Detail | -|-----------|--------| -| **Approach** | Vector + Graph with LangChain integration | -| **Pricing** | Cloud-based; Community Edition deprecated | -| **Key Feature** | Session management; temporal context | -| **Weakness** | Cloud-dependent; complex configuration | -| **Threat Level** | Low - moving away from open source | - -#### GitHub Copilot Memory - -| Attribute | Detail | -|-----------|--------| -| **Approach** | Citation-based validation; cross-agent sharing | -| **Pricing** | Included with Copilot subscription | -| **Key Feature** | 7% PR merge rate improvement; automatic code citations | -| **Weakness** | Copilot-only; 28-day auto-expiry; cloud-dependent | -| **Threat Level** | High for Copilot users; validates mnemonic's approach | - -#### Memory Bank (Community) - -| Attribute | Detail | -|-----------|--------| -| **Approach** | Markdown files with structured sections | -| **Pricing** | Free (community project) | -| **Key Feature** | Works with Cursor/Windsurf rules; simple setup | -| **Weakness** | No versioning; no search optimization; fragmented | -| **Threat Level** | Low - validates need; potential migration target | - ---- - -## 5. Trend Analysis - -### Macro Trends - -| Trend | Direction | Evidence | Impact on Mnemonic | -|-------|-----------|----------|-------------------| -| Agentic AI maturation | INC | Multi-agent protocols (MCP, ACP, A2A, ANP) | Opportunity for multi-agent memory coordination | -| Context engineering emergence | INC | Anthropic's context engineering guide | Validates context management importance | -| Privacy and data sovereignty | INC | Enterprise concerns about cloud AI | Positions mnemonic as compliant solution | -| Agentic memory as table stakes | INC | VentureBeats 2026 predictions | Validates market timing | -| Native tool proficiency | INC | Letta benchmark findings | Confirms filesystem approach superiority | - -### Micro Trends - -| Trend | Direction | Evidence | Timeframe | -|-------|-----------|----------|-----------| -| Vector DB fatigue | INC | Letta benchmark; complexity complaints | 6-12 months | -| Citation-based validation | INC++ | GitHub Copilot public preview | Production-ready | -| Filesystem-based AI tools | INC | Arxiv paper; Letta research | 12 months | -| Context compression | INC | 6:1 compression at 90% fidelity research | 6-12 months | -| Cognitive memory models | CONST | Already adopted; stabilizing | Ongoing | -| Cloud-only solutions | DEC | Privacy concerns; data sovereignty | 12-24 months | - -### Transitional Scenario Graph - -```mermaid -stateDiagram-v2 - [*] --> CurrentState: Mnemonic v1.0 - - CurrentState --> OrganicGrowth: Community adoption (60%) - CurrentState --> EnterpriseAdoption: Data sovereignty appeal (25%) - CurrentState --> Stagnation: No marketing effort (5%) - - OrganicGrowth --> NicheSuccess: Memory Bank migration - OrganicGrowth --> PlatformPlay: Multi-agent features - - EnterpriseAdoption --> PlatformPlay: Team features - EnterpriseAdoption --> NicheSuccess: Compliance focus - - NicheSuccess --> SteadyState: Sustainable OSS - PlatformPlay --> MarketLeader: Cross-tool dominance - - Stagnation --> Obsolete: Market moves on - - SteadyState --> [*]: Niche success - MarketLeader --> [*]: Market leadership - Obsolete --> [*]: Project archived -``` - -### Terminal Scenarios - -| Scenario | Probability | Path | Trade-offs | -|----------|-------------|------|------------| -| **Niche Success** | 60% | Organic growth -> Steady community | Limited scale but sustainable | -| **Platform Play** | 10% | Multi-agent + Enterprise -> Market leader | Requires significant investment | -| **Enterprise Adoption** | 25% | Data sovereignty focus -> Compliance niche | May limit developer appeal | -| **Stagnation** | 5% | No action -> Obsolescence | - | - -### Scenario Trade-off Analysis - -```mermaid -quadrantChart - title Scenario Trade-offs: Investment vs Risk - x-axis Low Investment --> High Investment - y-axis Low Risk --> High Risk - quadrant-1 High Risk / High Investment - quadrant-2 Low Risk / High Investment - quadrant-3 Low Risk / Low Investment - quadrant-4 High Risk / Low Investment - Niche Success: [0.3, 0.2] - Enterprise Adoption: [0.5, 0.4] - Platform Play: [0.8, 0.6] - Stagnation: [0.1, 0.7] -``` - ---- - -## 6. SWOT Analysis - -### SWOT Quadrant Visualization - -```mermaid -quadrantChart - title SWOT Analysis Overview - x-axis Internal --> External - y-axis Harmful --> Helpful - quadrant-1 Opportunities - quadrant-2 Strengths - quadrant-3 Weaknesses - quadrant-4 Threats - Benchmark Validation: [0.2, 0.9] - Zero Dependencies: [0.2, 0.8] - Git Integration: [0.2, 0.7] - Market Gap: [0.8, 0.85] - Industry Validation: [0.8, 0.75] - Scale Untested: [0.2, 0.3] - Limited Awareness: [0.2, 0.2] - Native AI Memory: [0.8, 0.25] - Protocol Dominance: [0.8, 0.15] -``` - -### Strengths (Internal + Helpful) - -| Strength | Evidence | Strategic Value | -|----------|----------|-----------------| -| **Benchmark validation** | 74.0% accuracy vs 68.5% Mem0 on LoCoMo | Empirical proof of approach superiority | -| **Zero dependencies** | No databases, cloud, or accounts required | Reduced complexity; easier adoption | -| **Git integration** | Full version history, conflict resolution | Unique differentiator in market | -| **Human readability** | Markdown + YAML frontmatter | Developer trust; debugging ease | -| **POSIX composability** | Works with any Unix tool | No lock-in; ecosystem compatibility | -| **Cognitive types** | Semantic, episodic, procedural mapping | Academically grounded; industry aligned | -| **Bi-temporal tracking** | SQL:2011 standard compliance | Audit trail; temporal queries | - -### Weaknesses (Internal + Harmful) - -| Weakness | Impact | Mitigation | -|----------|--------|------------| -| **Scale untested** | Unknown performance at 10K+ files | Benchmark and optimize ripgrep usage | -| **Limited market awareness** | Low adoption despite strong foundation | Documentation and community engagement | -| **No cloud offering** | Enterprise procurement friction | Position as feature (data sovereignty) | -| **Single maintainer** | Bus factor risk | Build community contributor base | - -### Opportunities (External + Helpful) - -| Opportunity | Evidence | Action Required | -|-------------|----------|-----------------| -| **Market gap in simple + private** | Mem0/Zep deprecated Community editions | Clear positioning and messaging | -| **Memory Bank migration** | Community workarounds for Cursor/Windsurf | Integration guides; migration tools | -| **GitHub Copilot validation** | Citation-based validation now mainstream | Emphasize mnemonic's provenance features | -| **Enterprise data sovereignty** | Increasing privacy regulation | Compliance documentation | -| **Multi-agent coordination** | 4 protocols emerging (MCP, ACP, A2A, ANP) | Blackboard pattern extension | - -### Threats (External + Harmful) - -| Threat | Likelihood | Impact | Response | -|--------|------------|--------|----------| -| **Native AI assistant memory** | Medium | High | Emphasize portability and tool-agnostic design | -| **Protocol standardization on MCP** | Medium | Medium | Filesystem always works with Bash-capable assistants | -| **Vector DB simplification** | Low | Medium | Filesystem advantages remain (git, offline, readable) | -| **Enterprise competitor entry** | Medium | Medium | Build community moat; first-mover in niche | - ---- - -## 7. Recommendations - -### Strategic Recommendations (Prioritized) - -#### Recommendation 1: Focus on Documentation and Integration Guides - -| Aspect | Detail | -|--------|--------| -| **Statement** | Create comprehensive integration guides for Cursor, Windsurf, Claude Code, and Copilot showing Bash-native access patterns | -| **Rationale** | LLMs perform best with filesystem tools they were trained on; documentation enables immediate adoption | -| **Expected Outcome** | 3x increase in GitHub stars within 6 months; Memory Bank community migration | -| **Resource Requirements** | Low - documentation effort only | -| **Risk Level** | Low | -| **Priority** | 1 - Immediate | -| **Status** | IMPLEMENTED (2026-01-24) | - -#### Recommendation 2: Position for Enterprise Data Sovereignty - -| Aspect | Detail | -|--------|--------| -| **Statement** | Emphasize audit trails, offline access, and data sovereignty in marketing materials | -| **Rationale** | Cloud-only competitors (Mem0, Zep) create opportunity for on-premise solutions | -| **Expected Outcome** | Enterprise pilot opportunities; compliance-driven adoption | -| **Resource Requirements** | Low - messaging and documentation | -| **Risk Level** | Low | -| **Priority** | 2 - Short-term | -| **Status** | IMPLEMENTED (2026-01-24) | - -#### Recommendation 3: Engage Memory Bank Community - -| Aspect | Detail | -|--------|--------| -| **Statement** | Actively participate in Memory Bank project communities as potential adopters | -| **Rationale** | Existing workarounds validate need; mnemonic offers superior solution | -| **Expected Outcome** | Migration of Memory Bank users to mnemonic | -| **Resource Requirements** | Medium - community engagement time | -| **Risk Level** | Low | -| **Priority** | 3 - Short-term | -| **Status** | IMPLEMENTED (2026-01-24) | - -#### Recommendation 4: Implement Citation Validation - -| Aspect | Detail | -|--------|--------| -| **Statement** | Add optional citation fields in MIF format for code references; create validation tool | -| **Rationale** | GitHub Copilot's success with citation-based validation (7% PR improvement) | -| **Expected Outcome** | Reduced stale memory usage; improved memory reliability | -| **Resource Requirements** | Medium - development effort | -| **Risk Level** | Low | -| **Priority** | 4 - Medium-term | -| **Status** | IMPLEMENTED (2026-01-24) | - -#### Recommendation 5: Implement Memory Compression - -| Aspect | Detail | -|--------|--------| -| **Statement** | Add auto-summarization capability for context window efficiency | -| **Rationale** | Research shows 6:1 compression with >90% semantic fidelity achievable | -| **Expected Outcome** | Better context window utilization; larger effective memory | -| **Resource Requirements** | Medium - development effort | -| **Risk Level** | Medium - quality assurance needed | -| **Priority** | 5 - Medium-term | -| **Status** | IMPLEMENTED (gc --compress) | - -### Tactical Next Steps (Next 30 Days) - -| Action | Owner | Due Date | Status | -|--------|-------|----------|--------| -| Update README with Letta benchmark reference | - | 2026-01-31 | DONE | -| Add arxiv Unix philosophy paper to docs | - | 2026-01-31 | DONE | -| Create Cursor integration guide | - | 2026-02-07 | DONE | -| Create Windsurf integration guide | - | 2026-02-07 | DONE | -| Post on Memory Bank community forums | - | 2026-02-14 | DONE | - ---- - -## 8. Risk Assessment - -### Risk Matrix - -```mermaid -quadrantChart - title Risk Assessment Matrix - x-axis Low Impact --> High Impact - y-axis Low Probability --> High Probability - quadrant-1 Critical Risks - quadrant-2 Monitor Closely - quadrant-3 Low Priority - quadrant-4 Contingency Plan - Native AI Memory: [0.85, 0.5] - Scale Limitations: [0.5, 0.5] - Memory Sprawl: [0.4, 0.6] - Format Lock-in: [0.2, 0.2] - Protocol Dominance: [0.6, 0.3] - Cross-project Leak: [0.3, 0.4] -``` - -### Detailed Risk Table - -| Risk | Category | Probability | Impact | Mitigation | Contingency | -|------|----------|-------------|--------|------------|-------------| -| **AI assistants build native memory** | Market | Medium (50%) | High | Emphasize portability; multi-tool design | Pivot to export/integration layer | -| **Scale limitations at 10K+ files** | Technical | Medium (40%) | Medium | Performance benchmarking; optimize ripgrep | Add indexing layer if needed | -| **Memory sprawl** | Technical | High (60%) | Low | Decay modeling; GC tooling ✓ | Manual cleanup guides | -| **Protocol-based solutions dominate** | Market | Low (30%) | Medium | Filesystem always works with Bash | Document protocol-agnostic benefits | -| **Format lock-in concerns** | Technical | Low (20%) | Low | MIF is open standard | Migration tool development | -| **Cross-project contamination** | Technical | Medium (40%) | Low | Namespace isolation; clear scoping | Project-level memory separation | -| **Agent misuse of stale memories** | Technical | Medium (50%) | Medium | Citation validation ✓ | TTL expiry via gc ✓ | - -### Monitoring Indicators - -| Indicator | Source | Threshold | Action | -|-----------|--------|-----------|--------| -| GitHub stars growth | GitHub API | <10% monthly | Increase community engagement | -| AI assistant native memory announcements | Tech news | Any major | Assess portability positioning | -| Competitor open source moves | GitHub, Blogs | Community editions return | Re-evaluate competitive position | -| ripgrep performance at scale | Internal testing | >100ms queries | Optimize or add indexing | -| Memory file count growth | User reports | >5K files common | Tune gc thresholds (already implemented) | - ---- - -## 9. Appendix - -### A. Complete Data Sources - -| Source | URL | Type | Reliability | -|--------|-----|------|-------------| -| Letta AI Research | https://www.letta.com/blog/benchmarking-ai-agent-memory | Research | High | -| arxiv Unix Philosophy Paper | https://arxiv.org/html/2601.11672 | Academic | High | -| GitHub Copilot Memory Blog | https://github.blog/ai-and-ml/github-copilot/building-an-agentic-memory-system-for-github-copilot/ | Industry | High | -| Anthropic Context Engineering | https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents | Industry | High | -| ripgrep Benchmarks | https://github.com/BurntSushi/ripgrep | Documentation | High | -| Martin Fowler Bitemporal | https://martinfowler.com/articles/bitemporal-history.html | Documentation | High | -| AI Long-term Memory Survey | https://arxiv.org/html/2411.00489v1 | Academic | High | -| Windsurf Cascade Docs | https://docs.windsurf.com/windsurf/cascade/memories | Documentation | High | -| Mem0 Research | https://mem0.ai/research | Research | Medium | -| Royal Society Wiki Paper | https://royalsocietypublishing.org/doi/10.1098/rsos.240275 | Academic | High | -| Unix Philosophy Wikipedia | https://en.wikipedia.org/wiki/Unix_philosophy | Reference | High | - -### B. Methodology Notes - -**Research Approach**: Exploratory research focused on three priority areas: -1. Filesystem memory patterns (Priority 1) -2. Emerging trends in AI memory (Priority 2) -3. Academic foundations (Priority 3) - -**Data Collection**: Web research, academic paper analysis, competitor documentation review, community forum analysis. - -**Confidence Scoring**: Each finding rated 0.0-1.0 based on source reliability and corroboration. - -**Trend Indicators**: -- INC: Increasing trend with strong evidence -- INC++: Rapidly accelerating with production validation -- DEC: Declining trend -- CONST: Stable/constant - -### C. Research Timeline - -| Date | Activity | Findings | -|------|----------|----------| -| 2026-01-24 02:15 | Research initiated | Elicitation context captured | -| 2026-01-24 04:00 | Filesystem patterns research | Letta benchmark discovered | -| 2026-01-24 06:00 | Academic foundations | arxiv paper validated approach | -| 2026-01-24 08:00 | Competitive analysis | Memory Bank projects identified | -| 2026-01-24 10:00 | Trend analysis | Multi-agent protocols emerging | -| 2026-01-24 12:30 | Update | GitHub Copilot public preview | -| 2026-01-24 13:00 | Strategic decision | MCP out of scope | - -### D. Full Scenario Analysis - -#### Scenario 1: Organic Niche Success (60% probability) - -**Path**: Community adoption -> Memory Bank migration -> Steady OSS project - -**Dependencies**: -- Strong documentation and integration guides -- Active community engagement -- Regular maintenance and updates - -**Trade-offs**: -- (+) Sustainable with minimal resources -- (+) Clear market position -- (-) Limited scale and revenue potential -- (-) May miss larger market opportunity - -**Key Metrics**: -- GitHub stars: 1K+ within 12 months -- Active users: 500+ monthly -- Community contributors: 10+ - -#### Scenario 2: Enterprise Adoption (25% probability) - -**Path**: Data sovereignty messaging -> Compliance pilots -> Enterprise sales - -**Dependencies**: -- Compliance documentation (SOC2, GDPR) -- Enterprise support options -- Team collaboration features - -**Trade-offs**: -- (+) Higher revenue potential -- (+) Sustainable funding model -- (-) May require commercial entity -- (-) Could reduce open source focus - -**Key Metrics**: -- Enterprise pilots: 5+ within 12 months -- Paid support contracts: Revenue target TBD - -#### Scenario 3: Platform Play (10% probability) - -**Path**: Multi-agent features + Enterprise adoption -> Cross-tool dominance - -**Dependencies**: -- Significant development investment -- Multi-agent coordination features -- Strong enterprise traction -- Possible venture funding - -**Trade-offs**: -- (+) Market leadership potential -- (+) Significant revenue -- (-) High investment required -- (-) Execution risk - -**Key Metrics**: -- Multi-tool integration: 5+ AI assistants -- Market share: 5%+ of SAM - -#### Scenario 4: Stagnation (5% probability) - -**Path**: No action -> Reduced relevance -> Project archived - -**Dependencies**: -- No documentation updates -- No community engagement -- No response to market changes - -**Outcome**: Project becomes unmaintained; users migrate to alternatives - -### E. Glossary - -| Term | Definition | -|------|------------| -| **MIF** | Memory Interchange Format - mnemonic's open standard for memory files | -| **MCP** | Model Context Protocol - Anthropic's protocol for AI-tool communication | -| **LoCoMo** | Long Context Memory benchmark used by Letta | -| **TAM/SAM/SOM** | Total/Serviceable/Obtainable Addressable Market | -| **Bi-temporal** | Data modeling tracking both valid time and transaction time | -| **POSIX** | Portable Operating System Interface - Unix standards | -| **Semantic memory** | Facts and knowledge (things that ARE true) | -| **Episodic memory** | Events and experiences (things that HAPPENED) | -| **Procedural memory** | Workflows and skills (things you DO) | - ---- - -## Decision Support - -### For Executives - -**The Bottom Line**: Mnemonic's filesystem-based approach is empirically validated to outperform complex alternatives. The market is moving toward data sovereignty and simplicity. Recommended strategy: organic growth through community and documentation with enterprise positioning. - -**Investment Required**: Minimal (documentation and community engagement) -**Timeline to Validation**: 6-12 months -**Risk Level**: Low - -### For Product Managers - -**Feature Priority Stack**: -1. Integration guides (DONE) -2. Citation validation (DONE) -3. Memory compression (DONE) -4. Enhanced search (DONE) -5. Multi-agent coordination (DONE) - -**Competitive Moat**: Git integration + human readability + zero dependencies - -### For Investors - -**Market Opportunity**: $52.62B TAM by 2030 (46.3% CAGR) -**Differentiation**: Only filesystem-based solution with benchmark validation -**Growth Path**: Organic -> Enterprise -> Platform -**Key Risk**: Native AI assistant memory - -### For Developers - -**Architecture Validation**: Letta benchmark confirms filesystem > vector DB -**Integration Path**: Bash-native access; no protocol overhead -**Scale Considerations**: Test at 10K+ files; optimize ripgrep patterns - ---- - -*Report generated by sigint market research agent* -*Generated: 2026-01-24* -*Research ID: ai-memory-filesystem-research* diff --git a/reports/ai-memory-filesystem-research/2026-01-24-research.md b/reports/ai-memory-filesystem-research/2026-01-24-research.md deleted file mode 100644 index 0fcb816..0000000 --- a/reports/ai-memory-filesystem-research/2026-01-24-research.md +++ /dev/null @@ -1,346 +0,0 @@ -# AI Memory Systems with Filesystem-Based Interfaces - -**Research Date**: 2026-01-24 -**Last Updated**: 2026-01-24T12:30:00Z -**Status**: Complete -**Researcher**: sigint market research agent - ---- - -## Change Log - -### 2026-01-24T13:00:00Z - Strategic Decision: MCP Out of Scope - -**Project decision**: MCP integration is explicitly out of scope for mnemonic. The project will pursue organic growth through: -- Strong documentation and integration guides -- Community engagement with Memory Bank users -- Direct tool-specific integrations (Cursor rules, Windsurf rules, etc.) -- Enterprise positioning around data sovereignty and simplicity - -This aligns with mnemonic's core philosophy of zero external dependencies. - -### 2026-01-24T12:30:00Z - January 2026 Market Update - -**Significant developments since initial research:** - -- **MCP adoption accelerated**: Now under Linux Foundation AAIF with 97M monthly SDK downloads -- **GitHub Copilot agentic memory public preview** (Jan 15, 2026): Cross-agent memory sharing with 7% PR merge rate improvement, 28-day auto-expiry, citation-based validation -- **Industry consensus**: VentureBeats 2026 predictions identify agentic memory as "table stakes" for AI assistants - -**Impact on mnemonic strategy**: GitHub Copilot's public preview validates mnemonic's citation-based approach. Focus remains on filesystem simplicity and tool-agnostic design. - ---- - -## Research Brief Alignment - -This research addresses the decision context of **academic validation, strategic planning, and feature roadmap for mnemonic**. The findings are structured for a technical audience across product, engineering, and open-source community stakeholders who understand filesystem-based storage, YAML frontmatter, and POSIX tool ecosystems. - ---- - -## Executive Summary - -### Top 5 Findings (Priority-Ranked) - -1. **Filesystem approaches outperform specialized tools**: Letta's LoCoMo benchmark demonstrates that filesystem-based memory achieves 74.0% accuracy compared to Mem0's graph-based approach at 68.5%. This validates mnemonic's core architectural decision. - -2. **Unix philosophy is academically validated for AI**: A recent arxiv paper explicitly connects Unix's "everything is a file" principle to modern agentic AI design, providing theoretical backing for mnemonic's approach. - -3. **Market gap in simple, private memory**: While MCP-based solutions grow in complexity, mnemonic occupies a unique position: zero dependencies, full data sovereignty, human-readable format. This differentiation strengthens as alternatives become more complex. - -4. **Market gap exists in AI coding assistants**: Both Cursor and Windsurf lack native persistent memory; community workarounds using markdown files validate mnemonic's approach and represent adoption opportunity. - -5. **Cognitive memory types are becoming standard**: Semantic, episodic, and procedural memory classification from cognitive science is being directly applied in AI agent architectures, validating mnemonic's memory type taxonomy. - -### Success Criteria Assessment - -| Criterion | Status | Evidence | -|-----------|--------|----------| -| Academic backing for approach | ACHIEVED | Letta benchmark, arxiv Unix philosophy paper | -| Differentiation clarity | ACHIEVED | Simplicity as feature, git integration, POSIX composability | -| Surprising insights | ACHIEVED | Simplicity correlates with reliability; iterative querying advantage | -| Feature opportunities | ACHIEVED | ~~citation validation~~, ~~memory compression~~, ~~validation tool~~, ~~multi-agent coordination~~ *(implemented 2026-01-24)*; MCP out of scope | - ---- - -## Hypothesis Validation - -No explicit hypotheses were stated in the elicitation. However, implicit hypotheses derived from mnemonic's design decisions can be assessed: - -| Implicit Hypothesis | Verdict | Evidence | -|---------------------|---------|----------| -| Filesystem storage can be effective for AI memory | **SUPPORTED** | Letta benchmark: 74.0% vs 68.5% (Mem0) | -| POSIX tools are sufficient for search/retrieval | **SUPPORTED** | ripgrep 5-10x faster than grep; LLMs pretrained on filesystem ops | -| Git versioning adds value | **SUPPORTED** | Only solution offering full audit trail, offline access, conflict resolution | -| Cognitive memory types are appropriate | **SUPPORTED** | Direct mapping to emerging AI agent architectures | -| Bi-temporal tracking is valuable | **SUPPORTED** | SQL:2011 standard; GitHub Copilot using similar validation approach | - ---- - -## Market Overview - -### Market Scope - -The AI memory systems market sits at the intersection of: -- **AI coding assistants** (Cursor, Windsurf, Copilot, Continue, Aider) -- **Agentic AI infrastructure** (LangChain, AutoGen, CrewAI) -- **Developer tools and knowledge management** - -### Market Size Indicators - -- Global knowledge management market: $773.6B (2024), projected $3.5T by 2034 -- AI agents market: $5.25B (2024), projected $52.62B by 2030 (46.3% CAGR) -- Multi-agent systems: fastest-growing segment -- GitHub Copilot agentic memory: **7% PR merge rate improvement** in public preview *(New Jan 2026)* - -### Key Segments - -1. **Enterprise AI assistants**: Need audit trails, compliance, data sovereignty -2. **Individual developers**: Value simplicity, portability, offline access -3. **Open source projects**: Require vendor-neutral, self-hosted solutions -4. **Multi-agent systems**: Need shared memory coordination - ---- - -## Competitive Landscape - -### Direct Competitors - -| Competitor | Approach | Strengths | Weaknesses | -|------------|----------|-----------|------------| -| **Mem0** | Vector DB + Knowledge Graph | 26% accuracy improvement claims; temporal graph | Complex infrastructure; cloud-dependent; Community Edition deprecated | -| **Zep** | Vector + Graph hybrid | LangChain integration; session management | Cloud-focused; Community Edition deprecated | -| **LangChain Memory** | Multiple backends | Framework integration; flexibility | Requires external databases; configuration complexity | - -### Adjacent Solutions - -| Solution | Approach | Relationship to Mnemonic | -|----------|----------|--------------------------| -| **Cursor Memory Bank** | Community-built markdown files | Validates mnemonic's approach; potential adoption target | -| **Windsurf Memories** | Auto-generated + rules | Proprietary; validates need for persistent memory | -| **GitHub Copilot Memory** | Citation-based validation (public preview Jan 2026) | 7% PR merge improvement; cross-agent memory sharing; validates mnemonic's approach | -| **Basic Memory** | MCP-based local memory | Similar philosophy; different integration approach | - -### Competitive Position Analysis - -``` - Simple <----------------> Complex - | | - Private/Local [MNEMONIC] [Mem0] - | | | - | [Basic Memory] [Zep Cloud] - | | | - Cloud/Hosted [Copilot Memory] [LangChain Memory] -``` - -**Mnemonic's Position**: Simple + Private/Local quadrant - underserved by current market leaders. - -### Differentiation Summary - -| Mnemonic Advantage | Why It Matters | -|--------------------|----------------| -| Zero dependencies | No databases, no cloud, no accounts | -| Git integration | Full version history, conflict resolution, offline | -| POSIX composability | Works with any Unix tool; no lock-in | -| Human-readable | Developers can read/edit memories directly | -| MIF compliance | Portable, standardized format | -| Cognitive types | Academically grounded classification | - ---- - -## Trends and Projections - -### Trend Analysis with Direction Indicators - -| Trend | Direction | Evidence | Timeframe | -|-------|-----------|----------|-----------| -| Vector DB fatigue | INC | Letta benchmark; simplicity preference | 6-12 months | -| Multi-agent memory sharing | INC | Multiple protocols emerging | 12-24 months | -| Citation-based validation | **INC++** | GitHub Copilot public preview (Jan 2026); 7% PR merge improvement | **Production-ready** | -| Filesystem-based AI tools | INC | Arxiv paper; Letta research | 12 months | -| Context compression | INC | 6:1 compression at 90% fidelity | 6-12 months | -| Cognitive memory models in AI | CONST | Already adopted; stabilizing | Ongoing | -| Cloud-only solutions | DEC | Privacy concerns; data sovereignty | 12-24 months | - -### Macro Trends - -1. **Agentic AI maturation**: From single agents to coordinated multi-agent systems -2. **Context engineering emergence**: Recognized as critical discipline -3. **Privacy and data sovereignty**: Increasing enterprise concern about cloud AI -4. **Agentic memory as table stakes** *(New Jan 2026)*: VentureBeats 2026 predictions identify memory as essential capability for AI assistants -5. **Native tool proficiency**: LLMs perform best with tools they were trained on (Bash, filesystem ops); specialized protocols add latency and complexity - ---- - -## Scenario Analysis - -```mermaid -stateDiagram-v2 - [*] --> CurrentState: Mnemonic v1.0 - - CurrentState --> OrganicGrowth: Community adoption - - OrganicGrowth --> NicheSuccess: Developer-focused community - - NicheSuccess --> SteadyState: Sustainable open source - - SteadyState --> [*]: Niche success -``` - -> **Strategic Position**: Mnemonic pursues organic growth via filesystem simplicity. AI assistants with native Bash/filesystem access (Claude Code, Cursor, Windsurf, Copilot) can use mnemonic directly without protocol overhead. This aligns with Letta's benchmark finding that LLMs perform better with familiar tools. - -### Scenario Probabilities - -| Scenario | Probability | Key Dependencies | -|----------|-------------|------------------| -| Organic Niche Success | 60% | Strong documentation, community engagement, Memory Bank migration | -| Enterprise Adoption | 25% | Audit trails, data sovereignty messaging, compliance documentation | -| Platform Play | 10% | Multi-agent coordination + enterprise adoption | -| Stagnation | 5% | No action on documentation or community | - -**Strategic rationale**: Filesystem-based approach requires no protocol adoption. Any AI assistant with Bash access can use mnemonic immediately. This is a feature, not a limitation. - ---- - -## Key Insights - -### Academic Validation - -1. **Letta benchmark is definitive**: Filesystem-based memory achieving 74.0% accuracy vs Mem0's 68.5% on the LoCoMo benchmark is strong empirical validation that simplicity can outperform complexity. - -2. **Unix philosophy paper provides theoretical foundation**: The arxiv paper "From Everything is a File to Files Are All You Need" explicitly validates the strategy of collapsing diverse interfaces into uniform file abstraction. - -3. **Cognitive science mapping is correct**: Semantic, episodic, and procedural memory types from cognitive science are being directly adopted by AI agent frameworks, validating mnemonic's classification. - -4. **Bi-temporal modeling has standards backing**: SQL:2011 standard for temporal databases validates mnemonic's valid_time vs recorded_at approach. - -### Differentiation Clarity - -5. **Simplicity is a feature, not a limitation**: LLMs are extensively pretrained on filesystem operations, making simple tools more reliable than specialized knowledge graphs or vector databases. - -6. **Git integration is unique differentiator**: No competing solution offers full version control with meaningful diffs, offline access, and conflict resolution. - -7. **Human readability enables inspection**: Markdown with YAML frontmatter can be directly read and edited, unlike binary vector stores. - -### Surprising Insights - -8. ~~**Iterative querying changes retrieval paradigm**: Rather than single-shot retrieval, agents can generate their own queries and continue searching until finding the right data. This suggests mnemonic could support agent-driven search refinement.~~ *(Implemented: `/mnemonic:search-enhanced` with `mnemonic-search-subcall` agent provides agent-driven iterative search with synthesis)* - -9. **GitHub Copilot validates provenance approach**: Copilot's new memory system uses citation-based validation with code references. Mnemonic's provenance metadata aligns with this industry direction. - -10. **Community workarounds validate market need**: The existence of community-built "Memory Bank" projects for Cursor and Windsurf using markdown files validates both the market need and mnemonic's approach. - -### Feature Opportunities - -11. **Bash-native access is sufficient**: AI assistants with filesystem access (Claude Code, Cursor, Windsurf, Copilot) can use mnemonic directly via Bash. Letta's benchmark validates that LLMs perform better with familiar filesystem tools than specialized protocols. No additional integration layer needed. - -12. ~~**Citation validation could prevent stale memories**: Adding optional code citations that can be verified against the current codebase (like Copilot) could improve memory reliability.~~ *(Implemented: `tools/mnemonic-validate` validates code_refs and citations)* - -13. ~~**Memory compression addresses context limits**: Research shows 6:1 compression with >90% semantic fidelity is achievable. Auto-summarization could help with context window management.~~ *(Implemented: `gc --compress` with compression-worker agent)* - ---- - -## Recommendations - -### Immediate (1-2 weeks) - -1. ~~**Document benchmark validation**: Reference Letta's LoCoMo benchmark results in README and marketing materials~~ *(Implemented 2026-01-24)* -2. ~~**Cite academic foundations**: Link to arxiv Unix philosophy paper in architecture documentation~~ *(Implemented 2026-01-24)* - -### Short-term (1-2 months) - -3. ~~**Expand integration guides**: Detailed setup guides for Cursor, Windsurf, Copilot showing Bash-native access patterns~~ *(Implemented 2026-01-24)* -4. ~~**Add citation fields**: Optional `citations` array in MIF format for code references~~ *(Implemented 2026-01-24)* -5. ~~**Enhance search skill**: Support agent-driven iterative query refinement~~ *(Implemented: `/mnemonic:search-enhanced`)* - -### Medium-term (3-6 months) - -6. ~~**Memory compression**: Implement auto-summarization for large memories~~ *(Implemented: `gc --compress`)* -7. ~~**Multi-agent coordination**: Extend blackboard pattern for agent-to-agent sharing~~ *(Implemented: `mnemonic-agent-coordination` skill)* -8. ~~**Validation tool**: Script to verify memory citations against current codebase~~ *(Implemented: `tools/mnemonic-validate`)* - -### Strategic - -9. ~~**Position for enterprise**: Emphasize audit trails, data sovereignty, offline access~~ *(Implemented 2026-01-24)* -10. ~~**Build integrations**: Create specific guides for Cursor, Windsurf, Copilot users~~ *(Implemented 2026-01-24)* -11. ~~**Community engagement**: Engage Memory Bank project communities as potential adopters~~ *(Implemented 2026-01-24)* - ---- - -## Risks and Considerations - -### Technical Risks - -| Risk | Likelihood | Impact | Mitigation | -|------|------------|--------|------------| -| Scale limitations | Medium | Medium | Monitor performance; consider indexing layer | -| Format lock-in concerns | Low | Low | MIF is open standard; migrations possible | - -### Market Risks - -| Risk | Likelihood | Impact | Mitigation | -|------|------------|--------|------------| -| AI assistants build native memory | Medium | High | Multi-tool integration guides; emphasize data portability | -| Vector DBs improve simplicity | Low | Medium | Filesystem advantages remain (git, offline, human-readable) | -| Protocol-based solutions dominate | Low | Medium | Filesystem always works with any Bash-capable assistant | - -### Risks They Had Not Considered - -1. **Memory sprawl**: Without decay management, memory collections could grow unbounded -2. **Cross-project contamination**: User-level memories could leak context between projects -3. **Agent misuse of memories**: Agents might cite outdated memories without validation - ---- - -## Sources - -### Primary Sources (High Reliability) - -- [Benchmarking AI Agent Memory: Is a Filesystem All You Need?](https://www.letta.com/blog/benchmarking-ai-agent-memory) - Letta Research -- [From Everything is a File to Files Are All You Need](https://arxiv.org/html/2601.11672) - arxiv -- [Building an Agentic Memory System for GitHub Copilot](https://github.blog/ai-and-ml/github-copilot/building-an-agentic-memory-system-for-github-copilot/) - GitHub -- [Effective Context Engineering for AI Agents](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents) - Anthropic -- [GitHub Changelog: Copilot Agentic Memory Public Preview](https://github.blog/changelog/) - GitHub *(Added Jan 2026)* - -### Secondary Sources (High Reliability) - -- [ripgrep benchmarks](https://burntsushi.net/ripgrep/) - Andrew Gallant -- [Bitemporal History](https://martinfowler.com/articles/bitemporal-history.html) - Martin Fowler -- [Human-inspired Perspectives: A Survey on AI Long-term Memory](https://arxiv.org/html/2411.00489v1) - arxiv -- [Unix Philosophy](https://en.wikipedia.org/wiki/Unix_philosophy) - Wikipedia -- [Co-designing a wiki-based community knowledge management system](https://royalsocietypublishing.org/doi/10.1098/rsos.240275) - Royal Society - -### Industry Sources (Medium Reliability) - -- [Windsurf Cascade Memories Documentation](https://docs.windsurf.com/windsurf/cascade/memories) -- [Cursor Forum - Memory Bank discussions](https://forum.cursor.com/) -- [Mem0 AI Memory Research](https://mem0.ai/research) -- [VentureBeats 2026 AI Predictions: Agentic Memory](https://venturebeat.com/) *(Added Jan 2026)* - ---- - -## Further Research Needed - -1. **Performance benchmarks at scale**: Test ripgrep performance with 10K+ memory files -2. **User studies**: How developers interact with memory files manually vs via agents -3. **Decay model optimization**: Research optimal half-life values for different memory types -4. **Multi-agent coordination patterns**: Detailed analysis of blackboard vs other sharing mechanisms -5. **Cross-agent memory sharing**: Learn from GitHub Copilot's 7% PR merge improvement metrics - ---- - -## Anti-Pattern Check - -This research explicitly avoids: - -- Recommendations requiring databases or cloud services -- Suggestions that compromise human readability -- Features that break POSIX tool compatibility -- Complexity that undermines the core value proposition -- **Protocol dependencies** (MCP, etc.) that add abstraction layers - -All recommendations preserve filesystem simplicity. AI assistants with Bash access can use mnemonic directly without additional integration layers. - ---- - -*Generated by [sigint](https://github.com/zircote/sigint) on 2026-01-24* -*Last updated: 2026-01-24T13:00:00Z* diff --git a/reports/ai-memory-filesystem-research/README.md b/reports/ai-memory-filesystem-research/README.md deleted file mode 100644 index eca7856..0000000 --- a/reports/ai-memory-filesystem-research/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# AI Memory Systems with Filesystem-Based Interfaces - Research Summary - -**Research ID**: ai-memory-filesystem-research -**Created**: 2026-01-24 -**Last Updated**: 2026-01-24 -**Status**: complete - -## Research Query - -> Academic validation, strategic planning, and feature roadmap research for mnemonic - a filesystem-based memory system for AI coding assistants. - -## Configuration - -| Setting | Value | -|---------|-------| -| Decision Context | Academic validation, strategic planning, and feature roadmap for mnemonic | -| Target Audience | Product team, technical team, open source community, executives | -| Geographic Scope | Global | -| Time Horizon | Near-term | -| Priority Areas | Filesystem-based approaches, emerging trends, academic foundations | - -## Artifacts - -### Reports -- [Full Report (Markdown)](./2026-01-24-report.md) - Comprehensive analysis with all sections -- [Full Report (HTML)](./2026-01-24-report.html) - Styled HTML with rendered Mermaid diagrams -- [Executive Summary](./2026-01-24-executive-summary.md) - One-page strategic brief -- [Research Findings](./2026-01-24-research.md) - Detailed research findings - -### Data -- [Research State](./state.json) - Elicitation context, findings, and sources -- [Report Metadata](./2026-01-24-report-metadata.json) - Generation details and quality checks - -## Key Findings - -1. **Filesystem approaches outperform specialized tools**: Letta benchmark shows 74.0% accuracy vs Mem0's 68.5% on LoCoMo benchmark -2. **Unix philosophy is academically validated for AI**: Arxiv paper confirms file abstraction is proven strategy for managing complexity -3. **Market gap in simple + private memory**: Mnemonic occupies underserved quadrant as competitors focus on complex cloud solutions -4. **GitHub Copilot validates approach**: Citation-based memory in public preview (Jan 2026) with 7% PR merge improvement -5. **Agentic memory is now table stakes**: VentureBeats 2026 predictions identify memory as essential AI capability - -## Surprising Insights - -- Simplicity correlates with reliability: LLMs use filesystem tools more effectively than novel retrieval mechanisms -- Iterative querying transforms retrieval into exploration - agents generate own queries and refine searches -- Memory Bank community workarounds for Cursor/Windsurf validate both market need and mnemonic's approach - -## Strategic Recommendation - -**Pursue organic growth through filesystem simplicity.** AI assistants with Bash access can use mnemonic directly without protocol overhead. This is validated by Letta's benchmark finding that LLMs perform better with familiar tools. - -## Feature Opportunities (All Implemented) - -1. **Documentation and Integration Guides** - Bash-native access for Cursor, Windsurf, Copilot -2. **Citation Validation** - Optional code citations with validation tool (`tools/mnemonic-validate`) -3. **Memory Compression** - Auto-compress memories for context efficiency (`gc --compress`) -4. **Enhanced Search** - Agent-driven iterative search (`/mnemonic:search-enhanced`) -5. **Multi-Agent Coordination** - Blackboard pattern extension (`mnemonic-agent-coordination`) - -## Report Contents - -| Section | Description | -|---------|-------------| -| Executive Summary | Key findings, strategic recommendation, market opportunity | -| Market Overview | Definition, size indicators, segments, maturity | -| Market Sizing | TAM ($52.62B), SAM ($8B), SOM ($50-100M) with trend indicators | -| Competitive Landscape | Competitor matrix, Porter's 5 Forces, positioning map | -| Trend Analysis | Macro/micro trends, transitional scenarios, terminal scenarios | -| SWOT Analysis | Strengths, weaknesses, opportunities, threats | -| Recommendations | 5 prioritized recommendations (all implemented) | -| Risk Assessment | Risk matrix, detailed risks, monitoring indicators | -| Appendix | Sources, methodology, timeline, glossary | - -## Visualizations Included - -- Market segment pie chart -- Market sizing breakdown -- Competitive positioning quadrant chart -- Transitional scenario state diagram -- Scenario trade-offs quadrant -- SWOT analysis overview -- Risk assessment matrix - ---- - -*Generated by [sigint](https://github.com/zircote/sigint)* diff --git a/reports/ai-memory-filesystem-research/state.json b/reports/ai-memory-filesystem-research/state.json deleted file mode 100644 index 0796510..0000000 --- a/reports/ai-memory-filesystem-research/state.json +++ /dev/null @@ -1,310 +0,0 @@ -{ - "topic": "AI Memory Systems with Filesystem-Based Interfaces", - "slug": "ai-memory-filesystem-research", - "started": "2026-01-24T02:15:00Z", - "updated": "2026-01-24T13:00:00Z", - "status": "complete", - "phase": "synthesis", - "change_log": [ - { - "date": "2026-01-24T13:00:00Z", - "type": "strategic_decision", - "summary": "MCP integration explicitly out of scope", - "changes": [ - "Removed all MCP integration recommendations", - "Updated strategy to focus on Bash-native access patterns", - "Emphasized that LLMs perform best with filesystem tools they were trained on", - "Positioned organic growth via documentation and community engagement" - ] - }, - { - "date": "2026-01-24T12:30:00Z", - "type": "update", - "summary": "Updated with January 2026 developments", - "changes": [ - "GitHub Copilot agentic memory in public preview (Jan 15)", - "VentureBeats 2026 predictions: agentic memory now table stakes" - ] - } - ], - "elicitation": { - "decision_context": "Academic validation, strategic planning, and feature roadmap for mnemonic", - "audience": [ - "product_team", - "technical_team", - "open_source_community", - "executive_strategic" - ], - "audience_expertise": "technical", - "prior_knowledge": "Mnemonic uses filesystem-based storage with MIF Level 3 format, YAML frontmatter, markdown content, git integration", - "hypotheses": [], - "research_style": "exploratory", - "scope": { - "geography": "global", - "segments": ["developer_tools", "ai_coding_assistants"], - "time_horizon": "near_term" - }, - "competitive_position": "new_entrant_simple_open_private", - "known_competitors": [ - "mem0", - "zep", - "langchain_memory", - "vector_databases", - "cursor_memories", - "windsurf_memories" - ], - "priorities": [ - "filesystem_based_approaches", - "emerging_trends", - "academic_foundations" - ], - "success_criteria": [ - "academic_backing_for_approach", - "differentiation_clarity", - "surprising_insights", - "feature_opportunities" - ], - "anti_patterns": "Recommendations that require departing from filesystem simplicity", - "timeline": "this_week", - "budget_context": "open_source" - }, - "research_areas": [ - { - "area": "filesystem_memory_patterns", - "focus": "POSIX tools, plain text storage, git integration, ripgrep search", - "priority": 1 - }, - { - "area": "emerging_trends", - "focus": "MCP ecosystem, multi-agent memory, context management standards", - "priority": 2 - }, - { - "area": "academic_foundations", - "focus": "Cognitive science memory models, temporal reasoning, decay functions", - "priority": 3 - } - ], - "findings": [ - { - "area": "filesystem_memory_patterns", - "finding": "Letta benchmark proves filesystem-based memory outperforms specialized tools: 74.0% accuracy vs Mem0's 68.5% on LoCoMo benchmark", - "source": "Letta AI Research - Benchmarking AI Agent Memory", - "implications": "Strong validation that mnemonic's filesystem approach is not just simpler but potentially more effective than vector/graph alternatives", - "confidence": 0.95 - }, - { - "area": "filesystem_memory_patterns", - "finding": "LLMs have extensive pretraining on filesystem operations, making simple tools more reliable than specialized knowledge graphs", - "source": "Letta AI Research", - "implications": "Agents using familiar tools (read, write, grep) are more reliable than those using novel retrieval mechanisms", - "confidence": 0.9 - }, - { - "area": "filesystem_memory_patterns", - "finding": "Arxiv paper 'From Everything is a File to Files Are All You Need' validates Unix philosophy for agentic AI systems", - "source": "arxiv.org/html/2601.11672", - "implications": "Academic validation that collapsing diverse interfaces into uniform file abstraction is a proven strategy for managing complexity", - "confidence": 0.9 - }, - { - "area": "filesystem_memory_patterns", - "finding": "ripgrep provides 5-10x performance improvement over GNU grep, particularly with line numbers enabled", - "source": "BurntSushi ripgrep benchmarks", - "implications": "mnemonic's reliance on ripgrep is well-founded; can confidently scale to large memory collections", - "confidence": 0.95 - }, - { - "area": "filesystem_memory_patterns", - "finding": "Git-based knowledge management provides version control, conflict resolution, and offline access that databases cannot match", - "source": "DEV Community, GitLab documentation", - "implications": "Git integration is a genuine differentiator for audit trails and collaboration", - "confidence": 0.85 - }, - { - "area": "emerging_trends", - "finding": "Bash-native access is sufficient for AI assistant integration; LLMs perform best with filesystem tools they were trained on", - "source": "Letta AI Research - LoCoMo benchmark", - "implications": "Mnemonic requires no protocol integration; any Bash-capable AI assistant can use it directly", - "confidence": 0.95, - "updated": "2026-01-24T13:00:00Z", - "note": "MCP integration explicitly out of scope per project decision" - }, - { - "area": "emerging_trends", - "finding": "Cursor and Windsurf both lack native persistent memory; community has built 'Memory Bank' workarounds using markdown files", - "source": "Cursor Forum, Windsurf Docs, GitHub memory-bank projects", - "implications": "Market gap exists that mnemonic can fill; existing workarounds validate the markdown-file approach", - "confidence": 0.9 - }, - { - "area": "emerging_trends", - "finding": "GitHub Copilot agentic memory now in public preview (Jan 15, 2026): cross-agent memory sharing with 7% PR merge rate improvement, 28-day auto-expiry, citation-based validation", - "source": "GitHub Changelog Jan 15 2026, GitHub Blog", - "implications": "Cross-agent memory is production-ready at GitHub scale; mnemonic's approach validated by industry leader", - "confidence": 0.95, - "updated": "2026-01-24T12:30:00Z", - "previous_value": "citation-based validation pattern (early access)" - }, - { - "area": "emerging_trends", - "finding": "Multi-agent memory sharing is emerging pattern with 4 major protocols: MCP, ACP, A2A, ANP", - "source": "Multiple industry sources, LinkedIn, MachineLearningMastery", - "implications": "mnemonic's blackboard pattern for cross-session coordination is ahead of curve; extend to multi-agent", - "confidence": 0.8 - }, - { - "area": "emerging_trends", - "finding": "Mem0 claims 26% accuracy improvement and 90% lower token usage vs full-context approaches", - "source": "Mem0 Research, mem0.ai", - "implications": "Memory layer approach is validated; mnemonic can achieve similar benefits with simpler implementation", - "confidence": 0.75 - }, - { - "area": "academic_foundations", - "finding": "Cognitive science memory types (semantic, episodic, procedural) are being directly applied in AI agent architectures", - "source": "Medium articles, arxiv papers on AI memory surveys", - "implications": "mnemonic's three memory types are academically grounded and align with emerging standards", - "confidence": 0.9 - }, - { - "area": "academic_foundations", - "finding": "Bi-temporal data modeling (valid time vs transaction time) has SQL:2011 standard backing", - "source": "Wikipedia, Martin Fowler, XTDB Docs", - "implications": "mnemonic's temporal model follows established database theory; opportunity to enhance temporal queries", - "confidence": 0.9 - }, - { - "area": "academic_foundations", - "finding": "Ebbinghaus forgetting curve research being applied to neural networks; decay modeling shown to enhance training efficiency", - "source": "arxiv paper on human-like forgetting curves in DNNs", - "implications": "mnemonic's decay modeling has academic foundation; could enhance with smarter decay scheduling", - "confidence": 0.8 - }, - { - "area": "academic_foundations", - "finding": "Context compression research shows 6:1 compression with >90% semantic fidelity is achievable", - "source": "Medium article on Context Extension Protocol", - "implications": "Opportunity for mnemonic to implement context compression for memory summaries", - "confidence": 0.7 - }, - { - "area": "surprising_insights", - "finding": "Simplicity correlates with reliability: simpler tools in LLM training data are used more effectively by agents", - "source": "Letta Research", - "implications": "mnemonic's POSIX tool approach is a feature not a limitation; complexity is actually a liability", - "confidence": 0.9 - }, - { - "area": "surprising_insights", - "finding": "Iterative querying advantage: agents can generate own queries and continue searching, transforming retrieval into exploration", - "source": "Letta Research", - "implications": "mnemonic could enhance search with agent-driven iterative refinement capabilities", - "confidence": 0.85 - }, - { - "area": "surprising_insights", - "finding": "Personal science wiki research shows structured documentation in shared repos improves consensus knowledge building", - "source": "Royal Society Open Science paper", - "implications": "mnemonic could position for team/org knowledge sharing beyond individual AI assistant use", - "confidence": 0.75 - }, - { - "area": "feature_opportunities", - "finding": "Integration guides for Cursor, Windsurf, Copilot using Bash-native access patterns", - "source": "Integration documentation analysis", - "implications": "Focus on documentation and rules files that leverage native filesystem access", - "confidence": 0.95, - "updated": "2026-01-24T13:00:00Z", - "note": "MCP integration explicitly out of scope" - }, - { - "area": "feature_opportunities", - "finding": "Citation-based memory validation (like GitHub Copilot) could prevent stale memory usage", - "source": "GitHub Copilot Memory documentation", - "implications": "Add optional citation fields that can be validated against current codebase", - "confidence": 0.8 - }, - { - "area": "feature_opportunities", - "finding": "Memory compression/summarization for context window efficiency is emerging pattern", - "source": "Context window management research", - "implications": "Add auto-summarization capability that preserves semantic content while reducing tokens", - "confidence": 0.75 - } - ], - "sources": [ - { - "url": "https://www.letta.com/blog/benchmarking-ai-agent-memory", - "title": "Benchmarking AI Agent Memory: Is a Filesystem All You Need?", - "type": "research", - "reliability": "high" - }, - { - "url": "https://arxiv.org/html/2601.11672", - "title": "From Everything is a File to Files Are All You Need: Unix Philosophy for Agentic AI", - "type": "academic", - "reliability": "high" - }, - { - "url": "https://github.com/BurntSushi/ripgrep", - "title": "ripgrep - Fast grep alternative", - "type": "documentation", - "reliability": "high" - }, - { - "url": "https://modelcontextprotocol.io/specification/2025-11-25", - "title": "Model Context Protocol Specification", - "type": "specification", - "reliability": "high" - }, - { - "url": "https://github.blog/ai-and-ml/github-copilot/building-an-agentic-memory-system-for-github-copilot/", - "title": "Building an Agentic Memory System for GitHub Copilot", - "type": "industry", - "reliability": "high" - }, - { - "url": "https://docs.windsurf.com/windsurf/cascade/memories", - "title": "Windsurf Cascade Memories Documentation", - "type": "documentation", - "reliability": "high" - }, - { - "url": "https://mem0.ai/research", - "title": "Mem0 AI Memory Research", - "type": "research", - "reliability": "medium" - }, - { - "url": "https://arxiv.org/html/2411.00489v1", - "title": "Human-inspired Perspectives: A Survey on AI Long-term Memory", - "type": "academic", - "reliability": "high" - }, - { - "url": "https://martinfowler.com/articles/bitemporal-history.html", - "title": "Bitemporal History - Martin Fowler", - "type": "documentation", - "reliability": "high" - }, - { - "url": "https://en.wikipedia.org/wiki/Unix_philosophy", - "title": "Unix Philosophy - Wikipedia", - "type": "reference", - "reliability": "high" - }, - { - "url": "https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents", - "title": "Effective Context Engineering for AI Agents - Anthropic", - "type": "industry", - "reliability": "high" - }, - { - "url": "https://royalsocietypublishing.org/doi/10.1098/rsos.240275", - "title": "Co-designing a wiki-based community knowledge management system", - "type": "academic", - "reliability": "high" - } - ] -} diff --git a/scripts/cleanup_memory_paths.py b/scripts/cleanup_memory_paths.py deleted file mode 100644 index 17a58e3..0000000 --- a/scripts/cleanup_memory_paths.py +++ /dev/null @@ -1,244 +0,0 @@ -#!/usr/bin/env python3 -""" -Cleanup Memory Paths Script - -Fixes the messed up directory structure in ${MNEMONIC_ROOT}: -1. Removes double-nested paths (semantic/semantic/decisions → semantic/decisions) -2. Cleans up stray root-level directories that should be under an org -3. Removes empty files and directories -4. Properly structures org/project/namespace hierarchy - -Usage: - python scripts/cleanup_memory_paths.py --dry-run # Preview changes - python scripts/cleanup_memory_paths.py --commit # Execute and commit -""" - -import argparse -import os -import shutil -import subprocess -from pathlib import Path -from typing import List, Tuple - -# Valid org directories (everything else at root should be removed or moved) -VALID_ROOT_ITEMS = { - ".git", - ".gitignore", - ".blackboard", - ".obsidian", - # Known orgs - "zircote", - "default", - "HMH-ProdOps", -} - -# Valid cognitive namespaces -VALID_NAMESPACES = { - "semantic", - "episodic", - "procedural", -} - -# Valid sub-namespaces -VALID_SUB_NAMESPACES = { - "semantic": {"decisions", "knowledge", "entities"}, - "episodic": {"incidents", "sessions", "blockers"}, - "procedural": {"runbooks", "patterns", "migrations"}, -} - - -def find_double_nested_paths(base_path: Path) -> List[Tuple[Path, Path]]: - """Find paths with double nesting like semantic/semantic/decisions.""" - moves = [] - - for ns in VALID_NAMESPACES: - # Look for patterns like semantic/semantic/ or episodic/episodic/ - double_path = base_path / ns / ns - if double_path.exists(): - for item in double_path.iterdir(): - if item.is_dir(): - correct_path = base_path / ns / item.name - moves.append((item, correct_path)) - - # Also check procedural/procedural/patterns -> procedural/patterns - for org in base_path.iterdir(): - if org.name in VALID_ROOT_ITEMS and org.name not in {"zircote", "default", "HMH-ProdOps"}: - continue - if not org.is_dir(): - continue - - for ns in VALID_NAMESPACES: - double_path = org / ns / ns - if double_path.exists(): - for item in double_path.iterdir(): - if item.is_dir(): - correct_path = org / ns / item.name - moves.append((item, correct_path)) - - # Check for procedural/procedural/patterns pattern - triple_path = org / "procedural" / "procedural" / "patterns" - if triple_path.exists(): - correct_path = org / "procedural" / "patterns" - moves.append((triple_path, correct_path)) - - return moves - - -def find_stray_root_items(base_path: Path) -> List[Path]: - """Find items at root that shouldn't be there.""" - strays = [] - - for item in base_path.iterdir(): - if item.name.startswith("."): - continue - if item.name in VALID_ROOT_ITEMS: - continue - # Check if it's an old namespace at root - if item.name in {"apis", "blockers", "context", "decisions", "learnings", - "patterns", "security", "testing", "episodic", "bridge", - "semantic", "procedural", "_test_debug"}: - strays.append(item) - # Check for stray files - if item.is_file(): - strays.append(item) - - return strays - - -def merge_directories(src: Path, dst: Path, dry_run: bool = True) -> int: - """Merge source directory into destination.""" - if not src.exists(): - return 0 - - count = 0 - - for item in src.rglob("*"): - if item.is_file(): - rel_path = item.relative_to(src) - dest_file = dst / rel_path - - if dry_run: - print(f" Would move: {item.name} → {dest_file}") - else: - dest_file.parent.mkdir(parents=True, exist_ok=True) - if dest_file.exists(): - print(f" Skipping (exists): {dest_file}") - else: - shutil.move(str(item), str(dest_file)) - print(f" Moved: {item.name}") - count += 1 - - return count - - -def cleanup_empty_dirs(base_path: Path): - """Remove empty directories recursively.""" - for dirpath, _, _ in os.walk(str(base_path), topdown=False): - path = Path(dirpath) - if path.name.startswith("."): - continue - try: - if not any(path.iterdir()): - path.rmdir() - print(f" Removed empty: {path}") - except OSError: - pass - - -def main(): - parser = argparse.ArgumentParser(description="Cleanup mnemonic memory paths") - parser.add_argument("--dry-run", action="store_true", help="Preview changes") - parser.add_argument("--commit", action="store_true", help="Execute and commit") - parser.add_argument("--path", type=Path, default=Path.home() / ".claude" / "mnemonic") - - args = parser.parse_args() - base_path = args.path - dry_run = args.dry_run or not args.commit - - if not base_path.exists(): - print(f"Path does not exist: {base_path}") - return - - print(f"Cleaning up: {base_path}\n") - - # Step 1: Fix double-nested paths - print("Step 1: Fixing double-nested paths...") - double_nested = find_double_nested_paths(base_path) - for src, dst in double_nested: - if dry_run: - print(f" Would merge: {src} → {dst}") - else: - count = merge_directories(src, dst, dry_run=False) - if count > 0: - # Remove empty source - try: - shutil.rmtree(str(src)) - except Exception as e: - print(f" Error removing {src}: {e}") - - # Step 2: Handle stray root items - print("\nStep 2: Handling stray root items...") - strays = find_stray_root_items(base_path) - for stray in strays: - if stray.is_file(): - if dry_run: - print(f" Would remove file: {stray.name}") - else: - stray.unlink() - print(f" Removed file: {stray.name}") - elif stray.is_dir(): - # Check if it has memory files that should be migrated - memory_files = list(stray.rglob("*.memory.md")) - if memory_files: - print(f" Found {len(memory_files)} memories in stray dir: {stray.name}") - if not dry_run: - # Move to default org - default_dir = base_path / "default" - merge_directories(stray, default_dir, dry_run=False) - - if dry_run: - print(f" Would remove dir: {stray.name}") - else: - try: - shutil.rmtree(str(stray)) - print(f" Removed dir: {stray.name}") - except Exception as e: - print(f" Error removing {stray}: {e}") - - # Step 3: Clean up empty directories - if not dry_run: - print("\nStep 3: Cleaning up empty directories...") - cleanup_empty_dirs(base_path) - - # Step 4: Show final structure - print("\nFinal structure:") - for item in sorted(base_path.iterdir()): - if item.name.startswith(".") and item.name != ".blackboard": - continue - if item.is_dir(): - count = len(list(item.rglob("*.memory.md"))) - print(f" {item.name}/ ({count} memories)") - - if dry_run: - print("\n(Dry run - no changes made)") - print("Run with --commit to execute changes") - elif args.commit: - # Git commit - os.chdir(base_path) - subprocess.run(["git", "add", "-A"], check=True) - result = subprocess.run(["git", "status", "--porcelain"], capture_output=True, text=True) - if result.stdout.strip(): - subprocess.run([ - "git", "commit", "-m", - "chore: cleanup memory directory structure\n\n" - "- Fixed double-nested paths (semantic/semantic → semantic)\n" - "- Removed stray root-level directories\n" - "- Cleaned up empty directories" - ], check=True) - print("\nCreated git commit") - else: - print("\nNo changes to commit") - - -if __name__ == "__main__": - main() diff --git a/scripts/fix_malformed_memories.py b/scripts/fix_malformed_memories.py deleted file mode 100755 index eb8f6b1..0000000 --- a/scripts/fix_malformed_memories.py +++ /dev/null @@ -1,340 +0,0 @@ -#!/usr/bin/env python3 -""" -Fix Malformed Memory Files - -Repairs common issues in memory files: -1. Missing frontmatter delimiter (---) -2. Missing required fields (id, type, namespace, title, created) -3. Invalid UUID format in id field - -Usage: - python scripts/fix_malformed_memories.py --dry-run # Preview changes - python scripts/fix_malformed_memories.py # Execute fixes - python scripts/fix_malformed_memories.py --delete # Delete unfixable files -""" - -import argparse -import re -import uuid -from datetime import datetime, timezone -from pathlib import Path - - -def detect_type_from_namespace(namespace: str) -> str: - """Infer memory type from namespace.""" - if namespace.startswith("semantic") or namespace in [ - "decisions", - "knowledge", - "apis", - "context", - "learnings", - "security", - ]: - return "semantic" - elif namespace.startswith("episodic") or namespace in ["blockers", "incidents", "sessions"]: - return "episodic" - elif namespace.startswith("procedural") or namespace in ["patterns", "runbooks", "migrations", "testing"]: - return "procedural" - return "semantic" - - -def detect_namespace_from_path(file_path: Path) -> str: - """Extract namespace from file path.""" - parts = file_path.parts - - # Look for known namespace patterns - for i, part in enumerate(parts): - if part in ["semantic", "episodic", "procedural"]: - if i + 1 < len(parts) and parts[i + 1] in [ - "decisions", - "knowledge", - "entities", - "incidents", - "sessions", - "blockers", - "runbooks", - "patterns", - "migrations", - ]: - return f"{part}/{parts[i + 1]}" - return part - if part in ["decisions", "learnings", "patterns", "blockers", "apis", "context", "security", "testing"]: - return part - - return "_semantic/knowledge" - - -def is_valid_uuid(value: str) -> bool: - """Check if string is valid UUID.""" - try: - uuid.UUID(value) - return True - except (ValueError, AttributeError): - return False - - -def extract_frontmatter(content: str) -> tuple: - """Extract frontmatter and body from content.""" - if not content.startswith("---"): - return None, content - - match = re.match(r"^---\n(.*?)\n---\n?(.*)", content, re.DOTALL) - if match: - return match.group(1), match.group(2) - return None, content - - -def parse_yaml_frontmatter(frontmatter: str) -> dict: - """Simple YAML frontmatter parser.""" - result = {} - current_key = None - current_list = None - - for line in frontmatter.split("\n"): - if not line.strip(): - continue - - # Check for list item - if line.startswith(" - "): - if current_list is not None: - current_list.append(line[4:].strip().strip('"').strip("'")) - continue - - # Check for key: value - if ":" in line and not line.startswith(" "): - key, _, value = line.partition(":") - key = key.strip() - value = value.strip().strip('"').strip("'") - - if value: - result[key] = value - else: - # Might be a list - result[key] = [] - current_list = result[key] - current_key = key # noqa: F841 — retained for parser state tracking - - return result - - -def generate_frontmatter(data: dict) -> str: - """Generate YAML frontmatter from dict.""" - lines = ["---"] - - # Order fields properly - field_order = ["id", "type", "namespace", "title", "created", "modified", "confidence", "tags"] - - for field in field_order: - if field in data: - value = data[field] - if isinstance(value, list): - lines.append(f"{field}:") - for item in value: - lines.append(f" - {item}") - elif " " in str(value) or ":" in str(value): - lines.append(f'{field}: "{value}"') - else: - lines.append(f"{field}: {value}") - - # Add any remaining fields - for key, value in data.items(): - if key not in field_order: - if isinstance(value, list): - lines.append(f"{key}:") - for item in value: - lines.append(f" - {item}") - elif " " in str(value) or ":" in str(value): - lines.append(f'{key}: "{value}"') - else: - lines.append(f"{key}: {value}") - - lines.append("---") - return "\n".join(lines) - - -def fix_memory_file(file_path: Path, dry_run: bool = True) -> dict: - """Fix a malformed memory file. Returns dict with fix details.""" - result = { - "path": str(file_path), - "fixes": [], - "errors": [], - "fixed": False, - "content": None, - } - - try: - content = file_path.read_text() - except Exception as e: - result["errors"].append(f"Cannot read file: {e}") - return result - - # Check for frontmatter - frontmatter, body = extract_frontmatter(content) - - if frontmatter is None: - # Try to find frontmatter without proper start - if "---" in content: - # Find first --- and assume it ends frontmatter - parts = content.split("---", 2) - if len(parts) >= 2: - frontmatter = parts[1].strip() - body = parts[2] if len(parts) > 2 else "" - result["fixes"].append("Added missing frontmatter start delimiter") - else: - # No frontmatter at all - create minimal one - frontmatter = "" - body = content - result["fixes"].append("Created new frontmatter") - - # Parse frontmatter - data = parse_yaml_frontmatter(frontmatter) if frontmatter else {} - - # Detect namespace from path - namespace = detect_namespace_from_path(file_path) - - # Fix missing id - if "id" not in data or not data["id"]: - # Try to extract from filename - filename = file_path.stem - uuid_match = re.search(r"([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})", filename) - if uuid_match: - data["id"] = uuid_match.group(1) - result["fixes"].append(f"Extracted id from filename: {data['id']}") - else: - data["id"] = str(uuid.uuid4()) - result["fixes"].append(f"Generated new id: {data['id']}") - elif not is_valid_uuid(data["id"]): - old_id = data["id"] - data["id"] = str(uuid.uuid4()) - result["fixes"].append(f"Replaced invalid id '{old_id}' with: {data['id']}") - - # Fix missing type - if "type" not in data or not data["type"]: - data["type"] = detect_type_from_namespace(namespace) - result["fixes"].append(f"Added type: {data['type']}") - - # Fix missing namespace - if "namespace" not in data or not data["namespace"]: - data["namespace"] = namespace - result["fixes"].append(f"Added namespace: {namespace}") - - # Fix missing title - if "title" not in data or not data["title"]: - # Try to extract from filename or first heading - filename = file_path.stem - # Remove UUID prefix if present - title = re.sub(r"^[a-f0-9-]{36}-", "", filename) - title = title.replace("-", " ").replace("_", " ").title() - data["title"] = title - result["fixes"].append(f"Generated title: {title}") - - # Fix missing created - if "created" not in data or not data["created"]: - # Use file modification time - mtime = file_path.stat().st_mtime - created = datetime.fromtimestamp(mtime, tz=timezone.utc).isoformat() - data["created"] = created - result["fixes"].append(f"Added created from file mtime: {created}") - - # Add default confidence if missing - if "confidence" not in data: - data["confidence"] = "0.9" - result["fixes"].append("Added default confidence: 0.9") - - if result["fixes"]: - # Generate new content - new_frontmatter = generate_frontmatter(data) - new_content = f"{new_frontmatter}\n\n{body.strip()}\n" - result["content"] = new_content - result["fixed"] = True - - if not dry_run: - try: - file_path.write_text(new_content) - except Exception as e: - result["errors"].append(f"Cannot write file: {e}") - result["fixed"] = False - - return result - - -def find_memory_files(base_paths: list) -> list: - """Find all memory files in given paths.""" - files = [] - for base_path in base_paths: - if base_path.exists(): - files.extend(base_path.rglob("*.memory.md")) - return files - - -def main(): - parser = argparse.ArgumentParser(description="Fix malformed memory files") - parser.add_argument( - "--dry-run", - action="store_true", - help="Preview changes without executing", - ) - parser.add_argument( - "--delete", - action="store_true", - help="Delete files that cannot be fixed", - ) - parser.add_argument( - "--path", - type=Path, - default=None, - help="Specific path to scan", - ) - parser.add_argument( - "--verbose", - "-v", - action="store_true", - help="Show details for each file", - ) - - args = parser.parse_args() - - # Paths to scan - if args.path: - paths = [args.path] - else: - paths = [ - Path.home() / ".claude" / "mnemonic", - Path.cwd() / ".claude" / "mnemonic", - ] - - print("Scanning for malformed memory files...") - files = find_memory_files(paths) - print(f"Found {len(files)} memory files\n") - - fixed_count = 0 - error_count = 0 - - for file_path in files: - result = fix_memory_file(file_path, dry_run=args.dry_run) - - if result["fixes"]: - fixed_count += 1 - print(f"{'[DRY RUN] ' if args.dry_run else ''}Fixed: {file_path.name}") - if args.verbose: - for fix in result["fixes"]: - print(f" - {fix}") - - if result["errors"]: - error_count += 1 - print(f"Error: {file_path.name}") - for err in result["errors"]: - print(f" ! {err}") - - print(f"\n{'=' * 50}") - print(f"Total files scanned: {len(files)}") - print(f"Files fixed: {fixed_count}") - print(f"Files with errors: {error_count}") - - if args.dry_run and fixed_count > 0: - print("\n(Dry run - no changes made)") - print("Run without --dry-run to apply fixes") - - -if __name__ == "__main__": - main() diff --git a/scripts/migrate_namespaces.py b/scripts/migrate_namespaces.py deleted file mode 100755 index 762448f..0000000 --- a/scripts/migrate_namespaces.py +++ /dev/null @@ -1,277 +0,0 @@ -#!/usr/bin/env python3 -""" -Namespace Migration Script - -Migrates existing mnemonic memories from the v1.0 flat namespace model -to the v2.0 cognitive triad hierarchy. - -Migration mapping: -- apis → semantic/knowledge -- blockers → episodic/blockers -- context → semantic/knowledge -- decisions → semantic/decisions -- learnings → semantic/knowledge -- patterns → procedural/patterns -- security → semantic/knowledge -- testing → procedural/patterns -- episodic → episodic/sessions - -Usage: - python scripts/migrate_namespaces.py --dry-run # Preview changes - python scripts/migrate_namespaces.py # Execute migration - python scripts/migrate_namespaces.py --commit # Execute and commit -""" - -import argparse -import re -import subprocess -from datetime import datetime -from pathlib import Path -from typing import Dict, List, Tuple - -# Migration mapping: old namespace → new namespace path -NAMESPACE_MIGRATION = { - "apis": "_semantic/knowledge", - "blockers": "_episodic/blockers", - "context": "_semantic/knowledge", - "decisions": "_semantic/decisions", - "learnings": "_semantic/knowledge", - "patterns": "_procedural/patterns", - "security": "_semantic/knowledge", - "testing": "_procedural/patterns", - "episodic": "_episodic/sessions", -} - - -def find_memory_files(base_path: Path) -> List[Path]: - """Find all memory files in the given path.""" - if not base_path.exists(): - return [] - return list(base_path.rglob("*.memory.md")) - - -def detect_namespace(file_path: Path) -> str: - """Detect the namespace from file path or content.""" - # Check path for namespace - for old_ns in NAMESPACE_MIGRATION: - if f"/{old_ns}/" in str(file_path): - return old_ns - - # Check frontmatter - try: - with open(file_path) as f: - content = f.read(2000) - match = re.search(r"namespace:\s*['\"]?(\w+)", content) - if match: - return match.group(1) - except Exception: - pass - - return "" - - -def update_frontmatter(content: str, old_ns: str, new_ns: str) -> str: - """Update namespace in frontmatter.""" - # Replace namespace field - content = re.sub( - rf"(namespace:\s*['\"]?){old_ns}(['\"]?)", - rf"\g<1>{new_ns}\g<2>", - content, - ) - - # Add migration note if not present - if "migration:" not in content: - # Find end of frontmatter - match = re.search(r"^---\n(.*?)^---", content, re.MULTILINE | re.DOTALL) - if match: - frontmatter = match.group(1) - migration_note = f"migration:\n from: {old_ns}\n date: {datetime.now().isoformat()}\n" - new_frontmatter = frontmatter.rstrip() + "\n" + migration_note - content = content.replace(frontmatter, new_frontmatter) - - return content - - -def get_new_path(old_path: Path, old_ns: str, new_ns: str) -> Path: - """Calculate the new path for a memory file.""" - path_str = str(old_path) - - # Replace namespace in path - # Handle both /{namespace}/ and /{namespace}/project/ patterns - new_path_str = path_str.replace(f"/{old_ns}/", f"/{new_ns}/") - - return Path(new_path_str) - - -def migrate_file( - file_path: Path, - old_ns: str, - new_ns: str, - dry_run: bool = True, -) -> Tuple[Path, bool]: - """Migrate a single file to new namespace.""" - new_path = get_new_path(file_path, old_ns, new_ns) - - if dry_run: - return new_path, True - - try: - # Read and update content - with open(file_path) as f: - content = f.read() - - updated_content = update_frontmatter(content, old_ns, new_ns) - - # Create destination directory - new_path.parent.mkdir(parents=True, exist_ok=True) - - # Write to new location - with open(new_path, "w") as f: - f.write(updated_content) - - # Remove old file - file_path.unlink() - - # Remove empty directories - try: - file_path.parent.rmdir() - except OSError: - pass # Directory not empty - - return new_path, True - - except Exception as e: - print(f"Error migrating {file_path}: {e}") - return file_path, False - - -def migrate_directory( - base_path: Path, - dry_run: bool = True, -) -> Dict[str, List[Tuple[Path, Path]]]: - """Migrate all memories in a directory.""" - migrations = {} - - for file_path in find_memory_files(base_path): - old_ns = detect_namespace(file_path) - - if old_ns not in NAMESPACE_MIGRATION: - continue - - new_ns = NAMESPACE_MIGRATION[old_ns] - - if old_ns not in migrations: - migrations[old_ns] = [] - - new_path, success = migrate_file(file_path, old_ns, new_ns, dry_run) - - if success: - migrations[old_ns].append((file_path, new_path)) - - return migrations - - -def print_migration_summary(migrations: Dict[str, List[Tuple[Path, Path]]]): - """Print summary of migrations.""" - total = sum(len(files) for files in migrations.values()) - - if total == 0: - print("No files to migrate") - return - - print(f"\nMigration Summary: {total} files\n") - - for old_ns, files in sorted(migrations.items()): - new_ns = NAMESPACE_MIGRATION[old_ns] - print(f"{old_ns} → {new_ns}: {len(files)} files") - for old_path, _new_path in files[:3]: # Show first 3 - print(f" {old_path.name}") - if len(files) > 3: - print(f" ... and {len(files) - 3} more") - - -def create_git_commit(migrations: Dict[str, List[Tuple[Path, Path]]]): - """Create a git commit for the migration.""" - total = sum(len(files) for files in migrations.values()) - - if total == 0: - return - - # Stage all changes - subprocess.run(["git", "add", "-A"], check=True) - - # Create commit message - ns_summary = ", ".join(f"{old}→{NAMESPACE_MIGRATION[old]}" for old in sorted(migrations.keys())) - - message = f"""chore: migrate {total} memories to cognitive triad namespaces - -Migrated namespaces: {ns_summary} - -This migration moves memories from the v1.0 flat namespace model -to the v2.0 cognitive triad hierarchy (semantic/episodic/procedural). -""" - - subprocess.run(["git", "commit", "-m", message], check=True) - print("\nCreated git commit for migration") - - -def main(): - parser = argparse.ArgumentParser(description="Migrate mnemonic memories to new namespace hierarchy") - parser.add_argument( - "--dry-run", - action="store_true", - help="Preview changes without executing", - ) - parser.add_argument( - "--commit", - action="store_true", - help="Create git commit after migration", - ) - parser.add_argument( - "--path", - type=Path, - default=None, - help="Path to migrate (default: ${MNEMONIC_ROOT} and ./.claude/mnemonic)", - ) - - args = parser.parse_args() - - # Determine paths to migrate - if args.path: - paths = [args.path] - else: - paths = [ - Path.home() / ".claude" / "mnemonic", - Path.cwd() / ".claude" / "mnemonic", - ] - - dry_run = args.dry_run or not args.commit - - if dry_run and not args.dry_run: - print("Note: Use --commit to execute migration with git commit") - print() - - all_migrations = {} - - for path in paths: - if not path.exists(): - continue - - print(f"Scanning: {path}") - migrations = migrate_directory(path, dry_run=dry_run) - - for ns, files in migrations.items(): - if ns not in all_migrations: - all_migrations[ns] = [] - all_migrations[ns].extend(files) - - print_migration_summary(all_migrations) - - if dry_run: - print("\n(Dry run - no changes made)") - elif args.commit and all_migrations: - create_git_commit(all_migrations) - - -if __name__ == "__main__": - main() diff --git a/scripts/migrate_scope_paths.py b/scripts/migrate_scope_paths.py deleted file mode 100755 index 9728739..0000000 --- a/scripts/migrate_scope_paths.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env python3 -""" -Scope Path Migration Script - -Migrates memories from redundant /user/ and /project/ subdirectories -to the parent namespace directory. - -Before: ${MNEMONIC_ROOT}/{org}/{namespace}/user/*.memory.md -After: ${MNEMONIC_ROOT}/{org}/{namespace}/*.memory.md - -Before: ./.claude/mnemonic/{namespace}/project/*.memory.md -After: ./.claude/mnemonic/{namespace}/*.memory.md - -Usage: - python scripts/migrate_scope_paths.py --dry-run # Preview changes - python scripts/migrate_scope_paths.py # Execute migration -""" - -import argparse -import shutil -from pathlib import Path - - -def find_scope_dirs(base_path: Path) -> list: - """Find all /user/ and /project/ directories.""" - scope_dirs = [] - for scope_name in ["user", "project"]: - for scope_dir in base_path.rglob(scope_name): - if scope_dir.is_dir(): - # Check if it contains memory files - memories = list(scope_dir.glob("*.memory.md")) - if memories: - scope_dirs.append(scope_dir) - return scope_dirs - - -def migrate_scope_dir(scope_dir: Path, dry_run: bool = True) -> list: - """Move all memories from scope dir to parent namespace dir.""" - migrations = [] - parent_dir = scope_dir.parent - - for memory_file in scope_dir.glob("*.memory.md"): - new_path = parent_dir / memory_file.name - - if dry_run: - migrations.append((memory_file, new_path)) - else: - try: - shutil.move(str(memory_file), str(new_path)) - migrations.append((memory_file, new_path)) - except Exception as e: - print(f"Error moving {memory_file}: {e}") - - # Remove empty scope directory - if not dry_run and not any(scope_dir.iterdir()): - try: - scope_dir.rmdir() - except Exception: - pass - - return migrations - - -def main(): - parser = argparse.ArgumentParser( - description="Migrate memories from /user/ and /project/ subdirectories" - ) - parser.add_argument( - "--dry-run", - action="store_true", - help="Preview changes without executing", - ) - - args = parser.parse_args() - - # Paths to check - paths = [ - Path.home() / ".claude" / "mnemonic", - Path.cwd() / ".claude" / "mnemonic", - ] - - total_migrations = [] - - for base_path in paths: - if not base_path.exists(): - continue - - print(f"Scanning: {base_path}") - scope_dirs = find_scope_dirs(base_path) - - for scope_dir in scope_dirs: - migrations = migrate_scope_dir(scope_dir, dry_run=args.dry_run) - total_migrations.extend(migrations) - - if migrations: - scope_type = scope_dir.name - print(f" {scope_dir.parent.name}/{scope_type}/: {len(migrations)} files") - - if total_migrations: - print(f"\nTotal: {len(total_migrations)} files migrated") - if args.dry_run: - print("\n(Dry run - no changes made)") - print("Run without --dry-run to execute migration") - else: - print("\nNo files to migrate") - - -if __name__ == "__main__": - main() diff --git a/scripts/migrate_to_v2_paths.py b/scripts/migrate_to_v2_paths.py deleted file mode 100644 index 023959e..0000000 --- a/scripts/migrate_to_v2_paths.py +++ /dev/null @@ -1,526 +0,0 @@ -#!/usr/bin/env python3 -""" -Migrate Mnemonic Memories from Legacy to V2 Path Scheme - -Migrates memories from the legacy dual-location structure to the unified -V2 path structure where everything is stored under ${MNEMONIC_ROOT}. - -Legacy Structure: - ${MNEMONIC_ROOT}/{org}/{namespace}/ - ./.claude/mnemonic/{namespace}/ - -V2 Structure: - ${MNEMONIC_ROOT}/{org}/{project}/{namespace}/ - ${MNEMONIC_ROOT}/{org}/{namespace}/ # org-wide - -Usage: - python scripts/migrate_to_v2_paths.py --dry-run # Preview changes - python scripts/migrate_to_v2_paths.py # Execute migration - python scripts/migrate_to_v2_paths.py --rollback # Revert migration - -Features: - - Automatic backup before migration - - Rollback capability - - Progress tracking - - Git commit of changes -""" - -import argparse -import json -import shutil -import subprocess -import sys -from dataclasses import asdict, dataclass -from datetime import datetime, timezone -from pathlib import Path -from typing import Dict, List - -# Add lib to path for imports -sys.path.insert(0, str(Path(__file__).parent.parent)) - -from lib.paths import PathContext, PathResolver, PathScheme, Scope - - -@dataclass -class MigrationRecord: - """Record of a single file migration.""" - source: str - destination: str - namespace: str - scope: str - timestamp: str - success: bool - error: str = "" - - -@dataclass -class MigrationPlan: - """Complete migration plan.""" - legacy_roots: List[str] - v2_root: str - total_memories: int - total_size_bytes: int - migrations: List[MigrationRecord] - created: str - - -class MigrationManager: - """Manages the migration from legacy to V2 path scheme.""" - - def __init__(self, dry_run: bool = True, verbose: bool = False): - self.dry_run = dry_run - self.verbose = verbose - - # Create resolvers for both schemes - self.legacy_context = PathContext.detect(scheme=PathScheme.LEGACY) - self.v2_context = PathContext.detect(scheme=PathScheme.V2) - - self.legacy_resolver = PathResolver(self.legacy_context) - self.v2_resolver = PathResolver(self.v2_context) - - # Track migration state - self.plan: MigrationPlan | None = None - self.backup_dir: Path | None = None - - def analyze(self) -> MigrationPlan: - """ - Analyze current structure and create migration plan. - - Returns: - MigrationPlan with all files to migrate - """ - if self.verbose: - print("Analyzing current memory structure...") - - migrations = [] - total_size = 0 - - # Get all legacy memory roots - legacy_roots = self.legacy_resolver.get_all_memory_roots() - - for legacy_root in legacy_roots: - if not legacy_root.exists(): - continue - - if self.verbose: - print(f" Scanning: {legacy_root}") - - # Find all memory files - for memory_file in legacy_root.rglob("*.memory.md"): - # Determine namespace from path - namespace = self._extract_namespace(memory_file, legacy_root) - - # Determine scope (project if under .claude in cwd, else user) - if self._is_project_memory(memory_file): - scope = Scope.PROJECT - else: - scope = Scope.USER - - # Calculate V2 destination - v2_path = self._compute_v2_path(memory_file, namespace, scope) - - # Get file size - file_size = memory_file.stat().st_size - total_size += file_size - - migrations.append(MigrationRecord( - source=str(memory_file), - destination=str(v2_path), - namespace=namespace, - scope=scope.value, - timestamp=datetime.now(timezone.utc).isoformat(), - success=False, - )) - - plan = MigrationPlan( - legacy_roots=[str(r) for r in legacy_roots], - v2_root=str(self.v2_resolver.context.home_dir / ".claude" / "mnemonic"), - total_memories=len(migrations), - total_size_bytes=total_size, - migrations=migrations, - created=datetime.now(timezone.utc).isoformat(), - ) - - self.plan = plan - return plan - - def _extract_namespace(self, file_path: Path, root: Path) -> str: - """Extract namespace from file path relative to root.""" - relative = file_path.parent.relative_to(root) - return str(relative) if str(relative) != "." else "" - - def _is_project_memory(self, file_path: Path) -> bool: - """Check if memory is in project directory.""" - try: - file_path.relative_to(self.legacy_context.project_dir) - return True - except ValueError: - return False - - def _compute_v2_path( - self, - source: Path, - namespace: str, - scope: Scope - ) -> Path: - """Compute V2 destination path for a memory file.""" - filename = source.name - - # Get V2 directory - v2_dir = self.v2_resolver.get_memory_dir(namespace, scope) - - return v2_dir / filename - - def create_backup(self) -> Path: - """ - Create backup of all legacy memories. - - Returns: - Path to backup directory - """ - timestamp = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S") - backup_dir = ( - self.legacy_context.home_dir / ".claude" / "mnemonic_backups" - / f"legacy_backup_{timestamp}" - ) - - if self.dry_run: - print(f"[DRY RUN] Would create backup at: {backup_dir}") - self.backup_dir = backup_dir - return backup_dir - - print(f"Creating backup at: {backup_dir}") - backup_dir.mkdir(parents=True, exist_ok=True) - - user_base = self.legacy_context.home_dir / ".claude" / "mnemonic" - - # Copy all legacy roots - for root in self.legacy_resolver.get_all_memory_roots(): - if not root.exists(): - continue - - # Preserve directory structure in backup - try: - # Try user-level path first - relative = root.relative_to(user_base) - backup_target = backup_dir / relative - except ValueError: - # Project-level path - use "project" prefix - backup_target = backup_dir / "project" / root.name - - print(f" Backing up: {root} -> {backup_target}") - shutil.copytree(root, backup_target, dirs_exist_ok=True) - - # Save migration plan - plan_file = backup_dir / "migration_plan.json" - with open(plan_file, 'w') as f: - json.dump(asdict(self.plan), f, indent=2) - - self.backup_dir = backup_dir - print(f"Backup complete: {backup_dir}") - return backup_dir - - def execute(self) -> Dict[str, int]: - """ - Execute the migration plan. - - Returns: - Dict with success/failure counts - """ - if not self.plan: - raise ValueError("Must call analyze() before execute()") - - stats = {"success": 0, "failed": 0, "skipped": 0} - - print(f"\nMigrating {self.plan.total_memories} memories...") - - for i, migration in enumerate(self.plan.migrations, 1): - if self.verbose or i % 10 == 0: - print(f" [{i}/{self.plan.total_memories}] {Path(migration.source).name}") - - try: - source = Path(migration.source) - dest = Path(migration.destination) - - # Skip if already migrated - if dest.exists() and not self.dry_run: - if self._files_identical(source, dest): - stats["skipped"] += 1 - migration.success = True - continue - - if self.dry_run: - print(f" [DRY RUN] {source} -> {dest}") - else: - # Create destination directory - dest.parent.mkdir(parents=True, exist_ok=True) - - # Copy file (don't move yet, in case of failure) - shutil.copy2(source, dest) - - migration.success = True - stats["success"] += 1 - - except Exception as e: - migration.error = str(e) - stats["failed"] += 1 - print(f" ERROR: {e}") - - return stats - - def _files_identical(self, file1: Path, file2: Path) -> bool: - """Check if two files are identical.""" - if file1.stat().st_size != file2.stat().st_size: - return False - return file1.read_bytes() == file2.read_bytes() - - def cleanup_legacy(self) -> int: - """ - Remove legacy directories after successful migration. - - Returns: - Number of files removed - """ - if self.dry_run: - print("\n[DRY RUN] Would remove legacy directories:") - for root in self.legacy_resolver.get_all_memory_roots(): - print(f" - {root}") - return 0 - - removed = 0 - print("\nCleaning up legacy directories...") - - for root in self.legacy_resolver.get_all_memory_roots(): - if not root.exists(): - continue - - # Only remove if empty or only contains migrated files - for memory_file in root.rglob("*.memory.md"): - try: - memory_file.unlink() - removed += 1 - except Exception as e: - print(f" Warning: Could not remove {memory_file}: {e}") - - # Remove empty directories - self._remove_empty_dirs(root) - - return removed - - def _remove_empty_dirs(self, root: Path): - """Recursively remove empty directories.""" - for dirpath in sorted(root.rglob("*"), reverse=True): - if dirpath.is_dir() and not any(dirpath.iterdir()): - try: - dirpath.rmdir() - except Exception: - pass - - def commit_changes(self, message: str = None): - """Commit changes to git.""" - if self.dry_run: - print("\n[DRY RUN] Would commit changes to git") - return - - git_dir = self.v2_context.home_dir / ".claude" / "mnemonic" - if not (git_dir / ".git").exists(): - print("\nNo git repository found, skipping commit") - return - - print("\nCommitting changes to git...") - - try: - subprocess.run( - ["git", "add", "-A"], - cwd=git_dir, - check=True, - ) - - commit_msg = message or f"migrate: Legacy to V2 path scheme ({self.plan.total_memories} memories)" - - subprocess.run( - ["git", "commit", "-m", commit_msg], - cwd=git_dir, - check=True, - ) - - print("Changes committed successfully") - - except subprocess.CalledProcessError as e: - print(f"Warning: Git commit failed: {e}") - - def rollback(self, backup_dir: Path): - """ - Rollback migration using backup. - - Args: - backup_dir: Path to backup directory - """ - if not backup_dir.exists(): - raise ValueError(f"Backup directory not found: {backup_dir}") - - print(f"Rolling back from backup: {backup_dir}") - - # Load migration plan - plan_file = backup_dir / "migration_plan.json" - if not plan_file.exists(): - raise ValueError(f"Migration plan not found in backup: {plan_file}") - - with open(plan_file) as f: - plan_data = json.load(f) - - # Restore each file - for migration in plan_data["migrations"]: - dest = Path(migration["destination"]) - - if dest.exists(): - print(f" Removing: {dest}") - dest.unlink() - - # Restore from backup - user_base = self.legacy_context.home_dir / ".claude" / "mnemonic" - for root_str in plan_data["legacy_roots"]: - root = Path(root_str) - try: - relative = root.relative_to(user_base) - backup_source = backup_dir / relative - except ValueError: - # Project-level path - backup_source = backup_dir / "project" / root.name - - if backup_source.exists(): - print(f" Restoring: {backup_source} -> {root}") - shutil.copytree(backup_source, root, dirs_exist_ok=True) - - print("Rollback complete") - - # Commit rollback - self.commit_changes("rollback: Revert V2 migration to legacy paths") - - def print_summary(self, stats: Dict[str, int]): - """Print migration summary.""" - if not self.plan: - print("No migration plan available.") - return - - print("\n" + "=" * 60) - print("MIGRATION SUMMARY") - print("=" * 60) - print(f"Total memories: {self.plan.total_memories}") - print(f"Successfully moved: {stats['success']}") - print(f"Already migrated: {stats['skipped']}") - print(f"Failed: {stats['failed']}") - print(f"Total size: {self._format_bytes(self.plan.total_size_bytes)}") - print(f"Backup location: {self.backup_dir}") - print("=" * 60) - - if stats['failed'] > 0: - print("\nWARNING: Some migrations failed. Check errors above.") - print("Your backup is safe and you can rollback if needed.") - - def _format_bytes(self, size_bytes: int) -> str: - """Format bytes as human-readable size.""" - size = float(size_bytes) - for unit in ['B', 'KB', 'MB', 'GB']: - if size < 1024.0: - return f"{size:.1f} {unit}" - size /= 1024.0 - return f"{size:.1f} TB" - - -def main(): - parser = argparse.ArgumentParser( - description="Migrate mnemonic memories from legacy to V2 path scheme" - ) - parser.add_argument( - "--dry-run", - action="store_true", - help="Preview changes without executing", - ) - parser.add_argument( - "--verbose", - "-v", - action="store_true", - help="Verbose output", - ) - parser.add_argument( - "--no-backup", - action="store_true", - help="Skip backup creation (not recommended)", - ) - parser.add_argument( - "--rollback", - type=Path, - metavar="BACKUP_DIR", - help="Rollback migration using specified backup directory", - ) - - args = parser.parse_args() - - # Handle rollback - if args.rollback: - manager = MigrationManager(dry_run=False, verbose=args.verbose) - manager.rollback(args.rollback) - return - - # Create migration manager - manager = MigrationManager(dry_run=args.dry_run, verbose=args.verbose) - - # Analyze current structure - print("Analyzing memory structure...") - plan = manager.analyze() - - if plan.total_memories == 0: - print("\nNo memories found to migrate.") - print("Either migration already complete or no memories exist.") - return - - print(f"\nFound {plan.total_memories} memories to migrate") - print(f"Total size: {manager._format_bytes(plan.total_size_bytes)}") - - if args.dry_run: - print("\n[DRY RUN MODE] - No changes will be made") - - # Confirm with user - if not args.dry_run: - print("\nThis will migrate all memories to the new V2 path structure.") - print("A backup will be created before migration.") - confirm = input("\nProceed? [y/N]: ") - if confirm.lower() != 'y': - print("Migration cancelled") - return - - # Create backup - backup_dir: Path | None = None - if not args.no_backup: - backup_dir = manager.create_backup() - print(f"\nBackup created: {backup_dir}") - else: - print("\nWARNING: Skipping backup (--no-backup specified)") - - # Execute migration - print("\nExecuting migration...") - stats = manager.execute() - - # Print summary - manager.print_summary(stats) - - # Cleanup legacy directories - if stats["failed"] == 0 and not args.dry_run: - confirm_cleanup = input("\nRemove legacy directories? [y/N]: ") - if confirm_cleanup.lower() == 'y': - removed = manager.cleanup_legacy() - print(f"Removed {removed} files from legacy locations") - - # Commit changes - if not args.dry_run: - manager.commit_changes() - - print("\nMigration complete!") - if not args.dry_run and backup_dir: - print(f"Backup saved at: {backup_dir}") - print(f"To rollback: python scripts/migrate_to_v2_paths.py --rollback {backup_dir}") - - -if __name__ == "__main__": - main() diff --git a/skills/blackboard/SKILL.md b/skills/blackboard/SKILL.md new file mode 100644 index 0000000..91cd028 --- /dev/null +++ b/skills/blackboard/SKILL.md @@ -0,0 +1,137 @@ +--- +name: blackboard +description: Cross-session handoff, persistent context via blackboard, and agent coordination patterns +user-invocable: true +allowed-tools: + - Bash + - Read + - Write + - Glob + - Grep +--- + + +## Memory + +Search first: `/mnemonic:search {relevant_keywords}` +Capture after: `/mnemonic:capture {namespace} "{title}"` + +Run `/mnemonic:list --namespaces` to see available namespaces from loaded ontologies. + + +# Mnemonic Blackboard Skill + +Cross-session handoff, persistent context, and agent coordination. + +## Trigger Phrases + +- "blackboard", "cross-session", "session handoff", "shared context" + +## Coordination Overview + +| Scope | Mechanism | Tools | +|-------|-----------|-------| +| **In-session** | Claude Code native swarm | TeamCreate, SendMessage, TaskCreate, TaskUpdate | +| **Cross-session** | Mnemonic blackboard handoff | `handoff/latest-handoff.md` via hooks | +| **Persistent knowledge** | Mnemonic memories | `*.memory.md` files | + +--- + +## Path Resolution + +```bash +MNEMONIC_ROOT=$(tools/mnemonic-paths root) +BLACKBOARD=$(tools/mnemonic-paths blackboard) +HANDOFF_DIR=${BLACKBOARD}/handoff +``` + +--- + +## Directory Structure + +``` +${BLACKBOARD}/ +├── _legacy/ # Pre-migration files (frozen) +├── sessions/ +│ └── {session_id}/ +│ ├── session-notes.md # Session activity log +│ └── _meta.json # Session lifecycle metadata +├── handoff/ +│ ├── latest-handoff.md # Cross-session context (overwritten each session end) +│ └── handoff-{session_id}.md # Archived per-session handoffs +└── .archive/ # Archived entries +``` + +--- + +## Cross-Session Handoff + +### How It Works + +1. **Session end** (`hooks/stop.py`): Writes summary to `handoff/latest-handoff.md` +2. **Session start** (`hooks/session_start.py`): Reads `handoff/latest-handoff.md` to restore context + +This is automatic via hooks. + +### Handoff Format + +```markdown +# Session Handoff + +**Session:** {session_id} +**Ended:** {timestamp} +**Project:** {org}/{project} + +## What Was Accomplished +- Completed items + +## In Progress +- Ongoing work with current state + +## Blocked +- Blocker: reason + +## Next Steps +- [ ] Action item 1 +- [ ] Action item 2 + +## Important Context +- Key context for next session +``` + +--- + +## Mnemonic Agents + +| Agent | Purpose | Invocation | +|-------|---------|------------| +| `memory-curator` | Maintenance, deduplication, decay | Standalone or native swarm | +| `mnemonic-search-subcall` | Iterative memory search | Spawned via Task tool | +| `compression-worker` | Memory summarization | Spawned via Task tool | +| `ontology-discovery` | Entity discovery from codebase | Spawned via Task tool | + +--- + +## Session Metadata + +Each session creates `_meta.json`: + +```json +{ + "session_id": "abc-123", + "started": "2026-01-15T10:00:00Z", + "ended": "2026-01-15T11:30:00Z", + "project": "zircote/mnemonic", + "org": "zircote", + "status": "ended" +} +``` + +--- + +## Best Practices + +- **Native swarm for in-session work** — don't write coordination state to blackboard +- **Let hooks handle handoff** — session lifecycle hooks manage cross-session context automatically +- **Memories for persistence** — if something should survive beyond the next session, capture it as a memory +- **Keep handoffs actionable** — focus on what the next session needs to continue work diff --git a/skills/mnemonic-core/SKILL.md b/skills/core/SKILL.md similarity index 99% rename from skills/mnemonic-core/SKILL.md rename to skills/core/SKILL.md index 190e403..e4c3792 100644 --- a/skills/mnemonic-core/SKILL.md +++ b/skills/core/SKILL.md @@ -1,5 +1,5 @@ --- -name: mnemonic-core +name: core description: > This skill should be used when the user says "capture memory", "save to memory", "remember this", or trigger phrases like: "I've decided", "let's use", "we're going with", diff --git a/skills/mnemonic-core/references/capture.md b/skills/core/references/capture.md similarity index 100% rename from skills/mnemonic-core/references/capture.md rename to skills/core/references/capture.md diff --git a/skills/mnemonic-core/references/examples.md b/skills/core/references/examples.md similarity index 100% rename from skills/mnemonic-core/references/examples.md rename to skills/core/references/examples.md diff --git a/skills/mnemonic-core/references/recall.md b/skills/core/references/recall.md similarity index 100% rename from skills/mnemonic-core/references/recall.md rename to skills/core/references/recall.md diff --git a/skills/mnemonic-core/references/schema.md b/skills/core/references/schema.md similarity index 100% rename from skills/mnemonic-core/references/schema.md rename to skills/core/references/schema.md diff --git a/skills/format/SKILL.md b/skills/format/SKILL.md new file mode 100644 index 0000000..b73a3d6 --- /dev/null +++ b/skills/format/SKILL.md @@ -0,0 +1,191 @@ +--- +allowed-tools: +- Read +- Write +- Glob +- Bash +- Grep +description: MIF Level 3 specification, memory templates, and formatting guidelines +name: format +user-invocable: true +--- + +## Memory + +Search first: `/mnemonic:search {relevant_keywords}` +Capture after: `/mnemonic:capture {namespace} "{title}"` + +Run `/mnemonic:list --namespaces` to see available namespaces from loaded ontologies. + + +# Mnemonic Format Skill + +MIF Level 3 specification, templates, and formatting guidelines. + +## Trigger Phrases + +- "memory format", "MIF format", "frontmatter template", "memory template", "mnemonic schema" + +--- + +## Quick Start: Minimal Memory + +Only 4 fields are required. Everything else is optional. + +```yaml +--- +id: 550e8400-e29b-41d4-a716-446655440000 +title: "Human-readable title" +type: semantic +created: 2026-01-23T10:30:00Z +--- + +# Title + +Content here. +``` + +**That's it.** Add optional fields only when you need them. + +--- + +## File Naming + +``` +{slug}.memory.md +``` + +- **slug**: URL-safe title, lowercase, max 50 chars +- UUID is stored only in the frontmatter `id:` field +- If a file with the same slug already exists, content is merged + +--- + +## Full Optional Fields Reference + +```yaml +--- +# REQUIRED (always include these 4) +id: 550e8400-e29b-41d4-a716-446655440000 +title: "Human-readable title" +type: semantic +created: 2026-01-23T10:30:00Z + +# COMMON +modified: 2026-01-23T14:22:00Z +namespace: _semantic/decisions/project +tags: + - architecture + - database + +# BI-TEMPORAL TRACKING +temporal: + valid_from: 2026-01-23T00:00:00Z + valid_until: null + recorded_at: 2026-01-23T10:30:00Z + ttl: P90D + decay: + model: exponential + half_life: P7D + strength: 0.85 + access_count: 5 + last_accessed: 2026-01-23T14:22:00Z + +# PROVENANCE +provenance: + source_type: conversation # user_explicit | inferred | conversation + source_ref: file:///path/to/source.ts:42 + agent: claude-opus-4 + confidence: 0.95 + session_id: abc123 + +# CODE REFERENCES +code_refs: + - file: src/auth/handler.ts + line: 42 + symbol: authenticateUser + type: function # function | class | method | variable | type + +# CITATIONS +citations: + - type: documentation # paper | documentation | blog | github | stackoverflow | article + title: "Source Title" + url: https://example.com/source + author: "Author Name" + date: 2026-01-23 + accessed: 2026-01-23T10:30:00Z + relevance: 0.90 + note: "Brief description" + +# COMPRESSION (auto-generated by gc --compress) +summary: "Concise 2-3 sentence summary (max 500 chars)" +compressed_at: 2026-01-24T10:00:00Z +--- + +# Memory Title + +Content in markdown format. + +## Relationships + +- relates-to [[other-memory-id]] +- supersedes [[old-memory-id]] +- derived-from [[source-memory-id]] +``` + +--- + +## Cognitive Memory Types + +| Type | Use For | Namespace Pattern | +|------|---------|-------------------| +| `semantic` | Facts, specs, configs, definitions | `_semantic/{subtype}/project` | +| `episodic` | Debug sessions, incidents, discoveries | `_episodic/{subtype}/project` | +| `procedural` | Runbooks, how-to guides, workflows | `_procedural/{subtype}/project` | + +--- + +## Relationship Syntax + +Add a `## Relationships` section at the end of any memory body using `- {type} [[{memory-id}]]` syntax. + +| Type | Meaning | +|------|---------| +| `relates-to` | General association | +| `supersedes` | Replaces older memory | +| `derived-from` | Built upon another memory | +| `contradicts` | Conflicts with another memory | +| `implements` | Realizes a design/decision | + +--- + +## Quick Templates + +**Generate REAL values for ids and timestamps. Run `uuidgen | tr '[:upper:]' '[:lower:]'` and `date -u +"%Y-%m-%dT%H:%M:%SZ"` before creating any memory. NEVER leave placeholders.** + +See [Quick Start](#quick-start-minimal-memory) above for the minimal template. Below are additional templates for common memory types. + +### Decision Memory + +```yaml +--- +id: +type: semantic +namespace: _semantic/decisions/project +created: +title: "Decision: {what}" +tags: [architecture] +provenance: + confidence: 0.95 +--- + +# Decision: {What} + +## Quick Answer +{What} was chosen for {primary reason}. + +## Context +- **Alternatives:** {Option A}, {Option B} +- **Key drivers:** {Driver 1}, {Driver 2} +- **Trade-offs:** {What was sacrificed} +``` diff --git a/skills/integrate/SKILL.md b/skills/integrate/SKILL.md index 6031c14..399d2ed 100644 --- a/skills/integrate/SKILL.md +++ b/skills/integrate/SKILL.md @@ -28,7 +28,7 @@ Use this skill when you want to: - **Migrate legacy integrations** - Convert old marker-less integrations to the new format **Don't use this skill if:** -- You're building a new plugin from scratch (use mnemonic-core directly) +- You're building a new plugin from scratch (use the core skill directly) - You only need to search/capture memories (use `/mnemonic:search` and `/mnemonic:capture`) ## Overview diff --git a/skills/mnemonic-agent-coordination/SKILL.md b/skills/mnemonic-agent-coordination/SKILL.md deleted file mode 100644 index 8787f4b..0000000 --- a/skills/mnemonic-agent-coordination/SKILL.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -name: mnemonic-agent-coordination -description: Agent coordination patterns - native swarm for in-session, blackboard for cross-session handoff -user-invocable: false -allowed-tools: - - Bash - - Read - - Write - - Glob - - Grep ---- - - - -## Memory - -Search first: `/mnemonic:search {relevant_keywords}` -Capture after: `/mnemonic:capture {namespace} "{title}"` - -Run `/mnemonic:list --namespaces` to see available namespaces from loaded ontologies. - - -# Mnemonic Agent Coordination Skill - -Agent coordination patterns for the mnemonic system. - -## Overview - -Agent coordination is split between two mechanisms: - -| Scope | Mechanism | Tools | -|-------|-----------|-------| -| **In-session** | Claude Code native swarm | TeamCreate, SendMessage, TaskCreate, TaskUpdate, TaskList | -| **Cross-session** | Mnemonic blackboard handoff | `handoff/latest-handoff.md` via hooks | - -### In-Session Coordination (Native Swarm) - -For agents working together within a single session, use Claude Code's built-in tools: - -- **TeamCreate**: Create a team with shared task list -- **TaskCreate / TaskUpdate / TaskList**: Track and assign work items -- **SendMessage**: Direct messages between agents -- **Task tool**: Spawn specialized subagents - -These tools provide real-time coordination, task dependencies, and message delivery. Do **not** duplicate this functionality with blackboard writes. - -### Cross-Session Handoff (Blackboard) - -For context that must survive across sessions: - -```bash -BLACKBOARD=$(tools/mnemonic-paths blackboard) -``` - -The handoff mechanism is automatic: -1. `hooks/stop.py` writes session summary to `${BLACKBOARD}/handoff/latest-handoff.md` -2. `hooks/session_start.py` reads this file to provide context to the new session - ---- - -## Mnemonic Agents - -| Agent | Purpose | Coordination | -|-------|---------|-------------| -| `memory-curator` | Maintenance, deduplication, decay | Standalone or native swarm | -| `mnemonic-search-subcall` | Iterative memory search | Spawned via Task tool | -| `compression-worker` | Memory summarization | Spawned via Task tool | -| `search-enhanced` (orchestrator) | Multi-round search | Uses Task tool to spawn subcalls | - ---- - -## Cross-Session Handoff Format - -When ending a session with important context for the next session, the stop hook writes: - -```markdown -# Session Handoff - -**Session:** {session_id} -**Ended:** {timestamp} -**Project:** {org}/{project} - -## What Was Accomplished -- Completed items - -## In Progress -- Ongoing work with current state - -## Next Steps -- [ ] What the next session should do -``` - ---- - -## Best Practices - -1. **Use native swarm for in-session work** - Don't write coordination state to blackboard files -2. **Let hooks handle handoff** - The session lifecycle hooks manage cross-session context automatically -3. **Capture persistent knowledge as memories** - If insights should last beyond the next session, use `/mnemonic:capture` -4. **Keep handoffs actionable** - Focus on what the next session needs to continue work - ---- - -## Related - -- `mnemonic-blackboard` skill - Blackboard patterns and handoff format -- ADR-003 - Agent Coordination via Blackboard Extension -- ADR-011 - Session-Scoped Blackboard diff --git a/skills/mnemonic-blackboard/SKILL.md b/skills/mnemonic-blackboard/SKILL.md deleted file mode 100644 index a609f16..0000000 --- a/skills/mnemonic-blackboard/SKILL.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -name: mnemonic-blackboard -description: Cross-session handoff and persistent context via blackboard -user-invocable: true -allowed-tools: - - Bash - - Read - - Write - - Glob - - Grep ---- - - - -## Memory - -Search first: `/mnemonic:search {relevant_keywords}` -Capture after: `/mnemonic:capture {namespace} "{title}"` - -Run `/mnemonic:list --namespaces` to see available namespaces from loaded ontologies. - - -# Mnemonic Blackboard Skill - -Cross-session handoff and persistent context. - -## Trigger Phrases - -- "blackboard" -- "cross-session" -- "session handoff" -- "shared context" - -## Overview - -The blackboard provides **cross-session persistence** - the ability to hand off context from one Claude Code session to the next. It is not used for in-session agent coordination, which is handled by Claude Code's native swarm tools (TeamCreate, SendMessage, TaskCreate/TaskUpdate). - -### Scope - -| Concern | Mechanism | -|---------|-----------| -| In-session agent coordination | Native swarm (TeamCreate, SendMessage, TaskCreate) | -| Cross-session context handoff | Blackboard `handoff/latest-handoff.md` | -| Persistent knowledge | Mnemonic memories (`*.memory.md`) | - ---- - -## Path Resolution - -```bash -MNEMONIC_ROOT=$(tools/mnemonic-paths root) -BLACKBOARD=$(tools/mnemonic-paths blackboard) -HANDOFF_DIR=${BLACKBOARD}/handoff -``` - ---- - -## Directory Structure - -``` -${BLACKBOARD}/ -├── _legacy/ # Pre-migration files (frozen) -├── sessions/ -│ └── {session_id}/ -│ ├── session-notes.md # Session activity log -│ └── _meta.json # Session lifecycle metadata -├── handoff/ -│ ├── latest-handoff.md # Cross-session context (overwritten each session end) -│ └── handoff-{session_id}.md # Archived per-session handoffs -└── .archive/ # Archived entries -``` - -The `sessions/` directory provides an audit trail. The `handoff/` directory is the active coordination surface. - ---- - -## Cross-Session Handoff - -### How It Works - -1. **Session end** (`hooks/stop.py`): Writes a handoff summary to `handoff/latest-handoff.md` -2. **Session start** (`hooks/session_start.py`): Reads `handoff/latest-handoff.md` to restore context - -This is automatic - hooks handle the lifecycle. - -### Handoff Entry Format - -```markdown -# Session Handoff - -**Session:** {session_id} -**Ended:** {timestamp} -**Project:** {org}/{project} - -## What Was Accomplished -- Item 1 -- Item 2 - -## In Progress -- Item 3: current state - -## Blocked -- Blocker: reason - -## Next Steps -- [ ] Action item 1 -- [ ] Action item 2 - -## Important Context -- Key context for next session -``` - -### Manual Handoff - -To explicitly write handoff context for the next session: - -```bash -BLACKBOARD=$(tools/mnemonic-paths blackboard) -# Write to handoff/latest-handoff.md -``` - ---- - -## Session Metadata - -Each session creates `_meta.json` with lifecycle tracking: - -```json -{ - "session_id": "abc-123", - "started": "2026-01-15T10:00:00Z", - "ended": "2026-01-15T11:30:00Z", - "project": "zircote/mnemonic", - "org": "zircote", - "status": "ended" -} -``` - -Status values: `active` (session running), `ended` (session completed). - ---- - -## Best Practices - -1. **Let hooks handle it** - Handoff is automatic via session_start and stop hooks -2. **Keep handoffs concise** - Focus on what the next session needs to know -3. **Use memories for persistence** - If something should survive beyond the next session, capture it as a memory -4. **Don't use blackboard for in-session coordination** - Use native swarm tools instead - ---- - -## Related - -- ADR-003 - Agent Coordination via Blackboard Extension -- ADR-011 - Session-Scoped Blackboard diff --git a/skills/mnemonic-format/SKILL.md b/skills/mnemonic-format/SKILL.md deleted file mode 100644 index a8f80e9..0000000 --- a/skills/mnemonic-format/SKILL.md +++ /dev/null @@ -1,745 +0,0 @@ ---- -allowed-tools: -- Read -- Write -- Glob -- Bash -- Grep -description: MIF Level 3 specification, memory templates, and formatting guidelines -name: mnemonic-format -user-invocable: true ---- - -## Memory - -Search first: `/mnemonic:search {relevant_keywords}` -Capture after: `/mnemonic:capture {namespace} "{title}"` - -Run `/mnemonic:list --namespaces` to see available namespaces from loaded ontologies. - - -# Mnemonic Format Skill - -MIF Level 3 specification, templates, and formatting guidelines. - -## Trigger Phrases - -- "memory format" -- "MIF format" -- "frontmatter template" -- "memory template" -- "mnemonic schema" - -## Overview - -MIF Level 3 specification. **Start minimal, add fields as needed.** - ---- - -## Quick Start: Minimal Memory - -Only 4 fields are required. Everything else is optional. - -```yaml ---- -id: 550e8400-e29b-41d4-a716-446655440000 -title: "Human-readable title" -type: semantic -created: 2026-01-23T10:30:00Z ---- - -# Title - -Content here. -``` - -**That's it.** Add optional fields only when you need them. - ---- - -## File Naming - -``` -{slug}.memory.md -``` - -- **slug**: URL-safe title, lowercase, max 50 chars -- UUID is stored only in the frontmatter `id:` field -- If a file with the same slug already exists, content is merged - ---- - -## Optional Fields Reference - -Add these when relevant: - -```yaml ---- -# REQUIRED (always include these 4) -id: 550e8400-e29b-41d4-a716-446655440000 -title: "Human-readable title" -type: semantic -created: 2026-01-23T10:30:00Z - -# COMMON (add when useful) -modified: 2026-01-23T14:22:00Z -namespace: _semantic/decisions/project -tags: - - architecture - - database - -# === PROGRESSIVE DISCLOSURE === -summary: "PostgreSQL chosen for ACID compliance and JSON support" -detail_level: comprehensive # minimal | standard | comprehensive -related_memories: [] # UUIDs of related memories -supersedes: [] # UUIDs of memories this one replaces - -# === BI-TEMPORAL TRACKING === -temporal: - valid_from: 2026-01-23T00:00:00Z # When fact became true - valid_until: null # When fact expired (null = current) - recorded_at: 2026-01-23T10:30:00Z # When captured in system - ttl: P90D # ISO 8601 duration until expiry - decay: - model: exponential # Decay algorithm - half_life: P7D # Time to 50% relevance - strength: 0.85 # Current relevance score 0-1 - access_count: 5 # Times recalled - last_accessed: 2026-01-23T14:22:00Z # Last recall timestamp - -# === PROVENANCE === -provenance: - source_type: conversation # user_explicit | inferred | conversation - source_ref: file:///path/to/source.ts:42 - agent: claude-opus-4 # Capturing agent - confidence: 0.95 # Certainty score 0-1 - session_id: abc123 # Claude session ID - -# === CODE STRUCTURE AWARENESS === -code_refs: - - file: src/auth/handler.ts - line: 42 - symbol: authenticateUser - type: function # function | class | method | variable | type - -# === CITATIONS === -citations: - - type: documentation # paper | documentation | blog | github | stackoverflow | article - title: "Source Title" - url: https://example.com/source - author: "Author Name" # optional - date: 2026-01-23 # publication date, optional - accessed: 2026-01-23T10:30:00Z # when accessed, optional - relevance: 0.90 # how relevant to memory 0.0-1.0, optional - note: "Brief description" # optional context - -# === CONFLICT TRACKING === -conflicts: - - memory_id: xyz789 - resolution: merged # merged | invalidated | skipped - resolved_at: 2026-01-23T12:00:00Z - -# === COMPRESSION (Auto-generated) === -summary: "Concise 2-3 sentence summary (max 500 chars)" # Auto-generated by gc --compress -compressed_at: 2026-01-24T10:00:00Z # When compression occurred ---- - -# Memory Title - -Main content in markdown format. - -## Section 1 - -Detailed information... - -## Rationale - -Why this decision/pattern/learning matters. - -## Relationships - -- relates-to [[other-memory-id]] -- supersedes [[old-memory-id]] -- derived-from [[source-memory-id]] - -## Entities - -- mentions @[[PostgreSQL]] -- uses @[[JWT Authentication]] -``` - ---- - -## Field Reference - -### Required Fields - -| Field | Type | Description | -|-------|------|-------------| -| `id` | UUID | Unique identifier (v4, lowercase) | -| `type` | enum | Cognitive type: `semantic`, `episodic`, `procedural` | -| `namespace` | string | Category/scope: `_semantic/decisions`, `_semantic/knowledge`, `_procedural/patterns`, etc. | -| `created` | ISO 8601 | Creation timestamp with timezone | -| `title` | string | Human-readable title in quotes | - -### Recommended Fields - -| Field | Type | Description | -|-------|------|-------------| -| `modified` | ISO 8601 | Last modification timestamp | -| `tags` | list | Categorization tags (lowercase, hyphenated) | - -### Progressive Disclosure Fields - -| Field | Type | Description | -|-------|------|-------------| -| `summary` | string | 1-2 sentence summary for Level 1 recall (max 200 chars) | -| `detail_level` | enum | `minimal`, `standard`, `comprehensive` | -| `related_memories` | list | UUIDs of related memories for cross-reference | -| `supersedes` | list | UUIDs of memories this one replaces | - -### Temporal Fields - -| Field | Type | Description | -|-------|------|-------------| -| `valid_from` | ISO 8601 | When the fact actually became true | -| `valid_until` | ISO 8601 | When the fact became outdated (null if current) | -| `recorded_at` | ISO 8601 | When captured in the system | -| `ttl` | ISO 8601 duration | Time-to-live (e.g., P90D = 90 days) | -| `decay.model` | string | `exponential`, `linear`, `step` | -| `decay.half_life` | ISO 8601 duration | Time to 50% relevance | -| `decay.strength` | float | Current relevance 0.0-1.0 | -| `access_count` | integer | Number of recalls | -| `last_accessed` | ISO 8601 | Most recent recall | - -### Provenance Fields - -| Field | Type | Description | -|-------|------|-------------| -| `source_type` | enum | `user_explicit`, `inferred`, `conversation` | -| `source_ref` | URI | Source location (file, URL, etc.) | -| `agent` | string | Agent that captured (e.g., `claude-opus-4`) | -| `confidence` | float | Certainty score 0.0-1.0 | -| `session_id` | string | Session identifier | - -### Code Reference Fields - -| Field | Type | Description | -|-------|------|-------------| -| `file` | string | Relative file path | -| `line` | integer | Line number | -| `symbol` | string | Symbol name | -| `type` | enum | `function`, `class`, `method`, `variable`, `type`, `module` | - -### Citation Fields - -| Field | Type | Description | -|-------|------|-------------| -| `type` | enum | `paper`, `documentation`, `blog`, `github`, `stackoverflow`, `article` (required) | -| `title` | string | Human-readable title of source (required) | -| `url` | string | Full URL to source material (required) | -| `author` | string | Author name (optional) | -| `date` | date | Publication date YYYY-MM-DD (optional) | -| `accessed` | ISO 8601 | When source was accessed (optional) | -| `relevance` | float | How relevant to memory 0.0-1.0 (optional) | -| `note` | string | Brief description of what this citation provides (optional) | - -### Compression Fields (Auto-generated) - -These fields are added automatically by `/mnemonic:gc --compress`: - -| Field | Type | Description | -|-------|------|-------------| -| `summary` | string | Concise 2-3 sentence summary (max 500 chars) | -| `compressed_at` | ISO 8601 | When compression was performed | - -Compression is applied to memories that: -- Are older than 30 days AND have > 100 lines, OR -- Have strength < 0.3 AND have > 100 lines - -The summary field enables quick scanning without reading full content. Original content is preserved. - ---- - -## Cognitive Memory Types - -### Semantic (Facts & Concepts) - -**Use for:** API documentation, technical specifications, definitions, configurations - -**Indicators:** -- "X is Y" -- Definitions -- Documentation -- Specifications -- Configuration values - -**Example:** -```yaml ---- -id: abc123 -type: semantic -namespace: _semantic/knowledge/project -title: "REST API Authentication Endpoint" -tags: - - api - - authentication ---- - -# REST API Authentication Endpoint - -POST /api/v1/auth/login - -## Request -- email: string (required) -- password: string (required) - -## Response -- token: JWT access token -- expires_in: seconds until expiry -``` - -### Episodic (Events & Experiences) - -**Use for:** Debug sessions, incidents, deployments, meetings, discoveries - -**Indicators:** -- "On [date], we..." -- "When we tried..." -- Timestamps -- Narratives -- Incident reports - -**Example:** -```yaml ---- -id: def456 -type: episodic -namespace: _episodic/sessions/blockers/project -title: "Database connection timeout incident" -tags: - - incident - - database - - resolved -temporal: - valid_from: 2026-01-20T14:30:00Z - recorded_at: 2026-01-20T16:00:00Z ---- - -# Database Connection Timeout Incident - -## What Happened -On 2026-01-20 at 14:30 UTC, production database connections started timing out. - -## Root Cause -Connection pool exhaustion due to unclosed connections in the batch processor. - -## Resolution -Added connection.close() in finally block. Deployed fix at 15:45 UTC. - -## Prevention -- Added connection pool monitoring -- Set max connection lifetime to 5 minutes -``` - -### Procedural (Processes & Workflows) - -**Use for:** Deployment steps, configuration procedures, how-to guides, workflows - -**Indicators:** -- "To do X, first..." -- Step-by-step instructions -- Sequences -- Procedures -- Runbooks - -**Example:** -```yaml ---- -id: ghi789 -type: procedural -namespace: _procedural/patterns/project -title: "Database migration procedure" -tags: - - database - - deployment - - procedure ---- - -# Database Migration Procedure - -## Prerequisites -- Database backup completed -- Maintenance window scheduled -- Rollback script prepared - -## Steps - -1. Enable maintenance mode - ```bash - ./scripts/maintenance.sh enable - ``` - -2. Run migrations - ```bash - npm run db:migrate - ``` - -3. Verify migrations - ```bash - npm run db:verify - ``` - -4. Disable maintenance mode - ```bash - ./scripts/maintenance.sh disable - ``` - -## Rollback -If step 3 fails: -```bash -npm run db:rollback -``` -``` - ---- - -## Namespace Reference - -| Namespace | Purpose | Memory Type | -|-----------|---------|-------------| -| `_semantic/decisions/` | Architectural choices, rationale | semantic | -| `_semantic/knowledge/` | APIs, context, learnings, security | semantic | -| `_semantic/entities/` | Entity definitions (technologies, components) | semantic | -| `_episodic/incidents/` | Production issues, postmortems | episodic | -| `_episodic/sessions/` | Debug sessions, work sessions | episodic | -| `_episodic/blockers/` | Impediments, issues | episodic | -| `_procedural/runbooks/` | Operational procedures | procedural | -| `_procedural/patterns/` | Code conventions, testing strategies | procedural | -| `_procedural/migrations/` | Migration steps, upgrade procedures | procedural | - -### Memory Scope - -- **Project**: `{org}/{project}/{namespace}/` - Specific to current codebase -- **Organization**: `{org}/{namespace}/` - Shared across projects in org - ---- - -## Progressive Disclosure Structure - -Every comprehensive memory should include three disclosure levels in the body: - -### Level 1: Quick Answer (Default Recall) - -The `## Quick Answer` section provides a 1-3 sentence summary. This is what Claude returns first when recalling a memory. - -**Triggers for Level 1:** "What is X?", "Which X do we use?", basic recall - -### Level 2: Context (Expanded Recall) - -The `## Context` section provides: -- Decision date/timeframe -- Alternatives considered -- Key decision drivers -- Trade-offs made - -**Triggers for Level 2:** "Why?", "Tell me more", "Explain the reasoning" - -### Level 3: Comprehensive (Full Detail) - -The `## Full Detail` section includes: -- Complete alternatives analysis -- Implementation notes -- Related decisions/patterns -- Code references -- Citations - -**Triggers for Level 3:** "All details", "Full context", implementation work, debugging - -### Progressive Disclosure Template - -```markdown -# {Title} - -## Quick Answer -{1-3 sentence summary answering "what" and "why briefly"} - -## Context -- **Decision date:** {date} -- **Alternatives considered:** {list} -- **Key drivers:** {factors that led to decision} -- **Trade-offs:** {what was sacrificed} - -## Full Detail - -### Alternatives Analysis -1. **{Option 1}**: {pros/cons, why rejected or chosen} -2. **{Option 2}**: {pros/cons, why rejected or chosen} - -### Implementation Notes -- {Specific implementation details} -- {Configuration requirements} -- {File locations} - -### Related Decisions -- See: [[{related-memory-id}]] for {context} - -### Code References -- {file:line} - {description} - -### Citations -- {source title} - {url} -``` - ---- - -## Relationship Syntax - -### Memory Links - -```markdown -## Relationships - -- relates-to [[550e8400-e29b-41d4-a716-446655440000]] -- supersedes [[old-memory-id]] -- derived-from [[source-memory-id]] -- contradicts [[conflicting-memory-id]] -- implements [[design-memory-id]] -``` - -### Relationship Types - -| Type | Meaning | -|------|---------| -| `relates-to` | General association | -| `supersedes` | Replaces older memory | -| `derived-from` | Built upon another memory | -| `contradicts` | Conflicts with another memory | -| `implements` | Realizes a design/decision | -| `blocks` | Dependency relationship | -| `blocked-by` | Inverse dependency | - ---- - -## Entity Syntax - -### Entity Mentions - -```markdown -## Entities - -- mentions @[[PostgreSQL]] -- uses @[[JWT Authentication]] -- authored-by @[[John Smith]] -- located-in @[[src/auth/]] -``` - -### Entity Types - -| Type | Examples | -|------|----------| -| Technology | PostgreSQL, Redis, Kubernetes | -| Pattern | Factory Pattern, Singleton | -| Person | Team members, authors | -| Location | File paths, directories | -| Concept | Microservices, REST, GraphQL | - ---- - -## Validation Rules - -### Required Checks - -1. `id` must be valid UUID v4 format -2. `type` must be one of: `semantic`, `episodic`, `procedural` -3. `namespace` must follow pattern: `{namespace}/{scope}` -4. `created` must be valid ISO 8601 timestamp -5. `title` must be non-empty string - -### Recommended Checks - -1. `confidence` should be between 0.0 and 1.0 -2. `valid_from` should be before or equal to `recorded_at` -3. `tags` should be lowercase with hyphens -4. `code_refs.file` paths should be relative - -### Citation Checks - -**Required if citations array exists:** -1. `citations[].type` must be one of: `paper`, `documentation`, `blog`, `github`, `stackoverflow`, `article` -2. `citations[].title` must be non-empty string -3. `citations[].url` must be valid URL format (https:// or http://) - -**Optional field validations:** -4. `citations[].relevance` if present, should be between 0.0 and 1.0 -5. `citations[].date` if present, should be valid YYYY-MM-DD format -6. `citations[].accessed` if present, should be valid ISO 8601 timestamp - -### File Naming - -```bash -# Generate compliant filename -UUID=$(uuidgen | tr '[:upper:]' '[:lower:]') -TITLE="My Memory Title" -SLUG=$(echo "$TITLE" | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | tr -cd 'a-z0-9-' | head -c 50) -FILENAME="${SLUG}.memory.md" -``` - ---- - -## Quick Templates - -**CRITICAL: When using these templates, generate REAL values for `{uuid}` and `{timestamp}`. Run `uuidgen | tr '[:upper:]' '[:lower:]'` and `date -u +"%Y-%m-%dT%H:%M:%SZ"` first. NEVER write placeholder text like "PLACEHOLDER_UUID" or "PLACEHOLDER_DATE".** - -### Minimal Memory - -```yaml ---- -id: -type: semantic -namespace: _semantic/knowledge/project -created: -title: "{title}" -summary: "{Brief summary for quick recall}" -detail_level: minimal ---- - -# {Title} - -## Quick Answer -{Content - serves as both summary and full content for minimal memories} -``` - -### Detail Level Guidelines - -| Level | When to Use | Typical Content | -|-------|-------------|-----------------| -| `minimal` | Simple facts, quick TILs, single-point learnings | Quick Answer only | -| `standard` | Most decisions, patterns with some rationale | Quick Answer + Context | -| `comprehensive` | Architectural decisions, complex patterns, research | All three levels | - -### Decision Memory (with Progressive Disclosure) - -```yaml ---- -id: {uuid} -type: semantic -namespace: _semantic/decisions/project -created: {timestamp} -title: "Decision: {what}" -tags: - - architecture -summary: "{Brief 1-sentence summary of decision and key reason}" -detail_level: comprehensive -related_memories: [] -supersedes: [] -provenance: - confidence: 0.95 ---- - -# Decision: {What} - -## Quick Answer -{What} was chosen for {primary reason}. This enables {key benefit}. - -## Context -- **Decision date:** {date} -- **Alternatives considered:** {Option A}, {Option B}, {Option C} -- **Key drivers:** - - {Driver 1} - - {Driver 2} -- **Trade-offs:** {What was sacrificed for this choice} - -## Full Detail - -### Alternatives Analysis -1. **{Option A}**: {Description} - - Pros: {pros} - - Cons: {cons} - - Verdict: {Chosen/Rejected because...} - -2. **{Option B}**: {Description} - - Pros: {pros} - - Cons: {cons} - - Verdict: {Rejected because...} - -### Implementation Notes -- {Specific implementation details} -- {Configuration requirements} - -### Related Decisions -- relates-to [[{related-decision-id}]] - -## Relationships -- supersedes [[{old-decision-id}]] (if applicable) -``` - -### Incident Memory - -```yaml ---- -id: {uuid} -type: episodic -namespace: _episodic/sessions/blockers/project -created: {timestamp} -title: "Incident: {summary}" -tags: - - incident -temporal: - valid_from: {when_it_happened} ---- - -# Incident: {Summary} - -## Timeline -- {time}: {event} - -## Root Cause -{Why it happened} - -## Resolution -{How it was fixed} - -## Prevention -{How to prevent recurrence} -``` - -### Research Memory with Citations - -```yaml ---- -id: {uuid} -type: semantic -namespace: _semantic/knowledge/project -created: {timestamp} -title: "Learning: {topic}" -tags: - - research -citations: - - type: paper - title: "Research Paper Title" - url: https://arxiv.org/abs/... - author: "Smith et al." - date: 2025-11-15 - accessed: {timestamp} - relevance: 0.95 - note: "Key finding about X" - - type: documentation - title: "Official Documentation" - url: https://docs.example.com/... - accessed: {timestamp} - relevance: 0.85 ---- - -# Learning: {Topic} - -## Summary -{What you learned} - -## Key Points -- {Point 1 from citation 1} -- {Point 2 from citation 2} - -## Application -{How this applies to our project} -``` diff --git a/skills/mnemonic-organization/SKILL.md b/skills/mnemonic-organization/SKILL.md deleted file mode 100644 index 69cd017..0000000 --- a/skills/mnemonic-organization/SKILL.md +++ /dev/null @@ -1,513 +0,0 @@ ---- -name: mnemonic-organization -description: Memory organization including directory structure, namespaces, and garbage collection -user-invocable: true -allowed-tools: - - Bash - - Read - - Write - - Glob - - Grep ---- - - - -## Memory - -Search first: `/mnemonic:search {relevant_keywords}` -Capture after: `/mnemonic:capture {namespace} "{title}"` - -Run `/mnemonic:list --namespaces` to see available namespaces from loaded ontologies. - - -# Mnemonic Organization Skill - -Directory structure, namespaces, maintenance, and garbage collection. - -## Trigger Phrases - -- "organize memories" -- "memory structure" -- "namespaces" -- "memory cleanup" -- "mnemonic organization" -- "memory maintenance" - -## Overview - -This skill covers the organizational structure of mnemonic, including directory layouts, namespace conventions, org/project detection, and maintenance operations. - ---- - -## Directory Structure - -All memories are stored under `${MNEMONIC_ROOT}/` with a unified path structure. - -### Unified Storage Layout - -``` -${MNEMONIC_ROOT}/ -├── default/ # Fallback when org detection fails -│ └── {namespace}/ # Cognitive namespaces -├── {org}/ # Organization-level -│ ├── _semantic/ # Org-wide facts/knowledge -│ │ ├── decisions/ -│ │ ├── knowledge/ -│ │ └── entities/ -│ ├── _episodic/ # Org-wide events -│ │ ├── incidents/ -│ │ ├── sessions/ -│ │ └── blockers/ -│ ├── _procedural/ # Org-wide procedures -│ │ ├── runbooks/ -│ │ ├── patterns/ -│ │ └── migrations/ -│ └── {project}/ # Project-specific memories -│ ├── _semantic/ -│ │ ├── decisions/ -│ │ ├── knowledge/ -│ │ └── entities/ -│ ├── _episodic/ -│ │ ├── incidents/ -│ │ ├── sessions/ -│ │ └── blockers/ -│ ├── _procedural/ -│ │ ├── runbooks/ -│ │ ├── patterns/ -│ │ └── migrations/ -│ └── .blackboard/ # Project session coordination -└── .git/ # Version control -``` - -### Memory Scope Hierarchy - -| Scope | Path | Use Case | -|-------|------|----------| -| Project | `{org}/{project}/{namespace}/` | Project-specific memories (default) | -| Organization | `{org}/{namespace}/` | Shared across projects in org | -| Default | `default/{namespace}/` | Fallback when org detection fails | - ---- - -## Namespace Reference - -### Cognitive Memory Types - -| Type | Purpose | Examples | -|------|---------|----------| -| **Semantic** | Facts, concepts, specifications | API docs, decisions, config values | -| **Episodic** | Events, experiences, incidents | Debug sessions, deployments | -| **Procedural** | Processes, workflows, how-tos | Deployment steps, runbooks | - -### Core Namespaces - -| Namespace | Purpose | Memory Type | -|-----------|---------|-------------| -| `_semantic/decisions/` | Architectural choices with rationale | Semantic | -| `_semantic/knowledge/` | APIs, context, learnings, security | Semantic | -| `_semantic/entities/` | Entity definitions (technologies, components) | Semantic | -| `_episodic/incidents/` | Production issues, postmortems | Episodic | -| `_episodic/sessions/` | Debug sessions, work sessions | Episodic | -| `_episodic/blockers/` | Impediments, issues | Episodic | -| `_procedural/runbooks/` | Operational procedures | Procedural | -| `_procedural/patterns/` | Code conventions, testing strategies | Procedural | -| `_procedural/migrations/` | Migration steps, upgrade procedures | Procedural | - -### Scope Selection - -| Scope | Path | Use Case | -|-------|------|----------| -| project | `{org}/{project}/{namespace}/` | Project-specific (default) | -| org | `{org}/{namespace}/` | Shared across all projects in organization | - -**Guidelines:** -- Use `project` scope for codebase-specific information (architecture decisions, local patterns) -- Use `org` scope for reusable knowledge (org-wide standards, shared patterns) - ---- - -## Organization Detection - -### Detect Org from Git Remote - -```bash -# Extract org from remote URL -# Handles: git@github.com:org/repo.git, https://github.com/org/repo.git - -ORG=$(git remote get-url origin 2>/dev/null | \ - sed -E 's|.*[:/]([^/]+)/[^/]+\.git$|\1|' | \ - sed 's|\.git$||') - -# Fallback to "default" if no remote -[ -z "$ORG" ] && ORG="default" - -echo "Organization: $ORG" -``` - -### Detect Project from Git Root - -```bash -# Get project name from git root directory -PROJECT=$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null) - -# Fallback to current directory name -[ -z "$PROJECT" ] && PROJECT=$(basename "$PWD") - -echo "Project: $PROJECT" -``` - -### Full Context Detection - -```bash -# Resolve MNEMONIC_ROOT from config -if [ -f "$HOME/.config/mnemonic/config.json" ]; then - RAW_PATH=$(python3 -c "import json; print(json.load(open('$HOME/.config/mnemonic/config.json')).get('memory_store_path', '~/.claude/mnemonic'))") - MNEMONIC_ROOT="${RAW_PATH/#\~/$HOME}" -else - MNEMONIC_ROOT="$HOME/.claude/mnemonic" -fi -#!/bin/bash -# detect_context.sh - Get org, project, and paths - -# Organization -ORG=$(git remote get-url origin 2>/dev/null | \ - sed -E 's|.*[:/]([^/]+)/[^/]+\.git$|\1|' | \ - sed 's|\.git$||') -[ -z "$ORG" ] && ORG="default" - -# Project -PROJECT=$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null) -[ -z "$PROJECT" ] && PROJECT=$(basename "$PWD") - -# Paths -USER_MNEMONIC="$MNEMONIC_ROOT/$ORG" -PROJECT_MNEMONIC="$MNEMONIC_ROOT" - -echo "ORG=$ORG" -echo "PROJECT=$PROJECT" -echo "USER_MNEMONIC=$USER_MNEMONIC" -echo "PROJECT_MNEMONIC=$PROJECT_MNEMONIC" -``` - ---- - -## Blackboard - -The blackboard is a shared coordination space for cross-session communication. - -### Location - -- Project: `${MNEMONIC_ROOT}/{org}/{project}/.blackboard/` -- Organization: `${MNEMONIC_ROOT}/{org}/.blackboard/` - -### Structure - -One markdown file per topic: - -``` -.blackboard/ -├── active-tasks.md -├── pending-decisions.md -├── shared-context.md -└── session-notes.md -``` - -### Write to Blackboard - -```bash -# Append entry with session info -SESSION_ID="${CLAUDE_SESSION_ID:-$(date +%s)-$$}" -TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") - -cat >> ${MNEMONIC_ROOT}/.blackboard/active-tasks.md << EOF - ---- -## Session: $SESSION_ID -**Time:** $TIMESTAMP - -- Task 1: Description -- Task 2: Description - -EOF -``` - -### Read from Blackboard - -```bash -# Recent entries -tail -50 ${MNEMONIC_ROOT}/.blackboard/active-tasks.md - -# Entries from specific session -grep -A20 "Session: $SESSION_ID" ${MNEMONIC_ROOT}/.blackboard/active-tasks.md -``` - -### Topic Conventions - -| File | Purpose | -|------|---------| -| `active-tasks.md` | Current work items | -| `pending-decisions.md` | Decisions awaiting input | -| `shared-context.md` | Background for all sessions | -| `session-notes.md` | Handoff notes between sessions | -| `blockers.md` | Known impediments | - ---- - -## Git Versioning - -### Initialize Repository - -```bash -cd ${MNEMONIC_ROOT} - -# Initialize if needed -[ ! -d .git ] && git init - -# Configure gitignore -cat > .gitignore << 'EOF' -*.lock -.blackboard/*.tmp -*.swp -*~ -.DS_Store -EOF - -# Initial commit -git add -A -git commit -m "Initialize mnemonic memory system" -``` - -### Commit Changes - -```bash -cd ${MNEMONIC_ROOT} -git add -A -git commit -m "Memory update: $(date +%Y-%m-%d)" -``` - -### View History - -```bash -cd ${MNEMONIC_ROOT} - -# Recent commits -git log --oneline -20 - -# Changes to specific memory -git log --oneline -- "*/_semantic/decisions/*auth*.memory.md" - -# Show specific version -git show HEAD~3:zircote/_semantic/decisions/abc123-use-jwt.memory.md -``` - -### Restore Previous Version - -```bash -cd ${MNEMONIC_ROOT} - -# Restore specific file from history -git checkout HEAD~1 -- zircote/_semantic/decisions/abc123-use-jwt.memory.md - -# Or restore and commit -git checkout -- path/to/memory.memory.md -git commit -m "Restore: memory title" -``` - ---- - -## Garbage Collection - -### Find Expired Memories (TTL) - -```bash -# Current timestamp for comparison -NOW=$(date +%s) - -# Find memories with ttl field -for f in ${MNEMONIC_ROOT}/**/*.memory.md; do - TTL=$(grep "^ ttl:" "$f" 2>/dev/null | sed 's/.*ttl: //') - CREATED=$(grep "^created:" "$f" 2>/dev/null | sed 's/created: //') - - if [ -n "$TTL" ] && [ -n "$CREATED" ]; then - # Parse and check expiry (simplified - real impl needs date math) - echo "Check: $f (TTL: $TTL, Created: $CREATED)" - fi -done -``` - -### Apply Decay Model - -```bash -# Update decay strength based on last access -# strength = initial * (0.5 ^ (days_since_access / half_life_days)) - -for f in ${MNEMONIC_ROOT}/**/*.memory.md; do - LAST_ACCESS=$(grep "last_accessed:" "$f" 2>/dev/null | sed 's/.*last_accessed: //') - HALF_LIFE=$(grep "half_life:" "$f" 2>/dev/null | sed 's/.*half_life: //') - - if [ -n "$LAST_ACCESS" ]; then - echo "Decay check: $f" - # Calculate new strength and update file - fi -done -``` - -### Archive Low-Relevance Memories - -```bash -# Move memories with strength < 0.2 to archive -ARCHIVE_DIR=${MNEMONIC_ROOT}/.archive/$(date +%Y-%m) -mkdir -p "$ARCHIVE_DIR" - -for f in ${MNEMONIC_ROOT}/**/*.memory.md; do - STRENGTH=$(grep "strength:" "$f" 2>/dev/null | sed 's/.*strength: //') - if [ -n "$STRENGTH" ]; then - # Compare strength (bash can't do float comparison easily) - if python3 -c "exit(0 if $STRENGTH < 0.2 else 1)" 2>/dev/null; then - mv "$f" "$ARCHIVE_DIR/" - echo "Archived: $f" - fi - fi -done -``` - -### Delete Expired - -```bash -# Find and delete truly expired memories (past TTL + grace period) -find ${MNEMONIC_ROOT} -name "*.memory.md" -mtime +365 -type f - -# Dry run -find ${MNEMONIC_ROOT} -name "*.memory.md" -mtime +365 -type f -exec echo "Would delete: {}" \; - -# Actual delete (with confirmation) -find ${MNEMONIC_ROOT} -name "*.memory.md" -mtime +365 -type f -exec rm -i {} \; -``` - ---- - -## Conflict Detection - -### Find Similar Memories - -```bash -# Search for memories with similar titles -TITLE="authentication" -rg -i "^title:.*$TITLE" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l -``` - -### Detect Contradictions - -```bash -# Find memories that might conflict -# Look for opposite patterns in same namespace - -# Example: Find all auth decisions -AUTH_DECISIONS=$(rg -l "auth" ${MNEMONIC_ROOT} --path "*/_semantic/decisions/" --glob "*.memory.md" 2>/dev/null) - -echo "Review these for potential conflicts:" -for f in $AUTH_DECISIONS; do - grep "^title:" "$f" -done -``` - -### Mark Conflict in Memory - -```yaml -conflicts: - - memory_id: xyz789 - resolution: merged - resolved_at: 2026-01-23T12:00:00Z -``` - -### Resolution Strategies - -| Strategy | When to Use | -|----------|-------------| -| `merged` | Combined information from both | -| `invalidated` | Marked conflicting memory as outdated | -| `skipped` | Kept existing, ignored new | - ---- - -## Maintenance Commands - -### Health Check - -```bash -#!/bin/bash -echo "=== Mnemonic Health Check ===" - -# Directory exists -test -d ${MNEMONIC_ROOT} && echo "✓ User mnemonic exists" || echo "✗ User mnemonic missing" - -# Git status -cd ${MNEMONIC_ROOT} -git status --short 2>/dev/null || echo "✗ Git not initialized" -cd - > /dev/null - -# Memory counts by cognitive type -echo "" -echo "=== Memory Counts by Type ===" -SEMANTIC=$(find ${MNEMONIC_ROOT} -path "*/_semantic/*" -name "*.memory.md" 2>/dev/null | wc -l | tr -d ' ') -EPISODIC=$(find ${MNEMONIC_ROOT} -path "*/_episodic/*" -name "*.memory.md" 2>/dev/null | wc -l | tr -d ' ') -PROCEDURAL=$(find ${MNEMONIC_ROOT} -path "*/_procedural/*" -name "*.memory.md" 2>/dev/null | wc -l | tr -d ' ') -echo "_semantic: $SEMANTIC" -echo "_episodic: $EPISODIC" -echo "_procedural: $PROCEDURAL" - -# Memory counts by namespace -echo "" -echo "=== Memory Counts by Namespace ===" -for ns in _semantic/decisions _semantic/knowledge _semantic/entities \ - _episodic/incidents _episodic/sessions _episodic/blockers \ - _procedural/runbooks _procedural/patterns _procedural/migrations; do - count=$(find ${MNEMONIC_ROOT} -path "*/$ns/*" -name "*.memory.md" 2>/dev/null | wc -l | tr -d ' ') - [ "$count" -gt 0 ] && echo "$ns: $count" -done - -# Recent activity -echo "" -echo "=== Recent Captures (7 days) ===" -find ${MNEMONIC_ROOT} -name "*.memory.md" -mtime -7 2>/dev/null | wc -l | tr -d ' ' -``` - -### Rebuild Index (if needed) - -```bash -# Generate manifest of all memories -cat > ${MNEMONIC_ROOT}/.manifest.json << 'EOF' -{ - "generated": "$(date -u +%Y-%m-%dT%H:%M:%SZ)", - "memories": [ -EOF - -first=true -for f in ${MNEMONIC_ROOT}/**/*.memory.md; do - id=$(grep "^id:" "$f" | sed 's/id: //') - title=$(grep "^title:" "$f" | sed 's/title: "//' | sed 's/"$//') - ns=$(grep "^namespace:" "$f" | sed 's/namespace: //') - - [ "$first" = true ] && first=false || echo "," >> ${MNEMONIC_ROOT}/.manifest.json - echo " {\"id\": \"$id\", \"title\": \"$title\", \"namespace\": \"$ns\", \"file\": \"$f\"}" >> ${MNEMONIC_ROOT}/.manifest.json -done - -echo " ]" >> ${MNEMONIC_ROOT}/.manifest.json -echo "}" >> ${MNEMONIC_ROOT}/.manifest.json -``` - -### Validate Memories - -```bash -# Check all memories have required fields -for f in ${MNEMONIC_ROOT}/**/*.memory.md; do - VALID=true - grep -q "^id:" "$f" || VALID=false - grep -q "^type:" "$f" || VALID=false - grep -q "^namespace:" "$f" || VALID=false - grep -q "^created:" "$f" || VALID=false - grep -q "^title:" "$f" || VALID=false - - [ "$VALID" = false ] && echo "Invalid: $f" -done -``` diff --git a/skills/mnemonic-progressive-disclosure/SKILL.md b/skills/mnemonic-progressive-disclosure/SKILL.md deleted file mode 100644 index 5dd302e..0000000 --- a/skills/mnemonic-progressive-disclosure/SKILL.md +++ /dev/null @@ -1,234 +0,0 @@ ---- -allowed-tools: -- Read -- Glob -- Grep -- Bash -- Write -description: Protocol for recalling memories at appropriate detail levels -name: mnemonic-progressive-disclosure -user-invocable: true ---- - -## Memory - -Search first: `/mnemonic:search {relevant_keywords}` -Capture after: `/mnemonic:capture {namespace} "{title}"` - -Run `/mnemonic:list --namespaces` to see available namespaces from loaded ontologies. - - -# Mnemonic Progressive Disclosure Skill - -Protocol for recalling memories at the appropriate detail level. - -## Trigger Phrases - -- "progressive disclosure" -- "disclosure levels" -- "memory recall levels" -- "how to recall" -- "expand memory" -- "more detail" - -## Overview - -Progressive disclosure enables efficient memory recall by surfacing only the detail level needed. Start with Level 1 (Quick Answer), expand to Level 2 (Context) or Level 3 (Full Detail) only when required. - ---- - -## Disclosure Levels - -### Level 1: Quick Answer (Default) - -**What to read:** The `## Quick Answer` section only (or `summary` frontmatter field) - -**Content:** 1-3 sentences answering the core question - -**Sufficient for:** -- "What is X?" -- "Which X do we use?" -- "What did we decide about X?" -- Simple recall questions - -**Example response:** -> PostgreSQL was chosen for primary storage due to ACID compliance and native JSON support. - -### Level 2: Context (On Request) - -**What to read:** `## Quick Answer` + `## Context` sections - -**Content:** -- Decision date/timeframe -- Alternatives considered -- Key decision drivers -- Trade-offs made - -**Sufficient for:** -- "Why did we choose X?" -- "What alternatives did we consider?" -- "Tell me more about X" -- Understanding rationale - -**Triggers:** -- User asks "why?" -- User asks for reasoning/rationale -- User says "tell me more" or "explain" - -**Example response:** -> PostgreSQL was chosen for primary storage due to ACID compliance and native JSON support. -> -> **Context:** -> - Decision made: 2026-01-15 -> - Alternatives considered: MySQL, MongoDB, SQLite -> - Key drivers: Need for JSON queries, team familiarity, existing infrastructure -> - Trade-off: Accepted more complex hosting for better query capabilities - -### Level 3: Comprehensive (Deep Dive) - -**What to read:** Full memory content - -**Content:** -- Complete alternatives analysis -- Implementation notes -- Related decisions/patterns -- Code references -- Citations - -**Sufficient for:** -- Implementation work -- Debugging issues related to decision -- Writing documentation -- Making related decisions -- "Give me all the details" - -**Triggers:** -- User is implementing something -- User is debugging -- User asks for "all details" or "full context" -- User needs to make a related decision - -**Example response:** -> [Full memory content including alternatives analysis, implementation notes, code refs, etc.] - ---- - -## Recall Protocol - -### Step 1: Search for Memories - -```bash -# Search by topic -rg -i "{topic}" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l - -# Search in specific namespace -rg -i "{topic}" ${MNEMONIC_ROOT} --path "*/_semantic/decisions/" --glob "*.memory.md" -l -``` - -### Step 2: Determine Required Level - -| User Intent | Start With | -|-------------|------------| -| Quick question | Level 1 | -| Understanding reasoning | Level 2 | -| Implementation work | Level 3 | -| Debugging | Level 3 | -| Related decision-making | Level 2, then 3 | - -### Step 3: Read Appropriate Section - -```bash -# For Level 1: Read just title and Quick Answer -head -30 {memory_file} # Usually enough for frontmatter + Quick Answer - -# For Level 2: Read through Context section -head -60 {memory_file} - -# For Level 3: Read full file -cat {memory_file} -``` - -### Step 4: Respond and Offer Expansion - -After Level 1 or 2 response, offer to expand: -- "Would you like more context on why this was chosen?" -- "I can provide the full implementation details if needed." - ---- - -## Examples - -### Example 1: Simple Question - -**User:** "What database are we using?" - -**Action:** Search, find postgres-decision.memory.md, read Quick Answer - -**Response:** -> PostgreSQL for primary storage, chosen for ACID compliance and JSON support. - -### Example 2: Reasoning Question - -**User:** "Why PostgreSQL instead of MongoDB?" - -**Action:** Search, find memory, read through Context section - -**Response:** -> We chose PostgreSQL over MongoDB because: -> - Team already familiar with SQL -> - Needed ACID transactions for payments -> - JSON support sufficient for our flexible schema needs -> - MongoDB would require new infrastructure and training - -### Example 3: Implementation Work - -**User:** "I'm implementing the new caching layer" - -**Action:** Search for caching memories, read full content - -**Response:** -> [Full memory with implementation notes, configuration details, code references] - ---- - -## Memory Structure Reference - -Comprehensive memories should have this structure: - -```markdown -# {Title} - -## Quick Answer -{1-3 sentences - Level 1 content} - -## Context -{Decision factors, alternatives, trade-offs - Level 2 content} - -## Full Detail -{Implementation notes, code refs, citations - Level 3 content} -``` - -Memories with `detail_level: minimal` may only have Quick Answer. -Memories with `detail_level: standard` should have Quick Answer + Context. -Memories with `detail_level: comprehensive` should have all three sections. - ---- - -## When to Expand Automatically - -Expand to higher detail level automatically when: - -1. **User is implementing** - They need Level 3 for code refs and implementation notes -2. **User mentions debugging** - They need Level 3 for full context -3. **User is making a related decision** - They need Level 2-3 to understand prior reasoning -4. **Memory is marked as superseded** - Include note about newer decision - ---- - -## Best Practices - -1. **Default to Level 1** - Most questions only need the Quick Answer -2. **Offer expansion** - Let user know more detail is available -3. **Cite the memory** - Reference the memory file for traceability -4. **Check for updates** - Note if memory has low confidence or is old -5. **Search multiple namespaces** - _semantic/decisions, _procedural/patterns, and _semantic/knowledge may all be relevant diff --git a/skills/mnemonic-search-enhanced/SKILL.md b/skills/mnemonic-search-enhanced/SKILL.md deleted file mode 100644 index e9e5f1b..0000000 --- a/skills/mnemonic-search-enhanced/SKILL.md +++ /dev/null @@ -1,453 +0,0 @@ ---- -allowed-tools: -- Task -- Bash -- Read -- Grep -- Glob -- Write -description: Agent-driven iterative memory search with synthesis. Uses subcall agents - for query refinement and produces comprehensive answers. -name: mnemonic-search-enhanced -user-invocable: true ---- - -## Memory - -Search first: `/mnemonic:search {relevant_keywords}` -Capture after: `/mnemonic:capture {namespace} "{title}"` - -Run `/mnemonic:list --namespaces` to see available namespaces from loaded ontologies. - - -# Mnemonic Enhanced Search Skill - -Agent-driven iterative memory search with synthesis. Performs multi-round search with query refinement and produces comprehensive, synthesized answers. - -## Trigger Phrases - -- "deep search memories" -- "comprehensive memory search" -- "thorough search for" -- "analyze memories about" -- "synthesize knowledge about" -- "what do we know about" (followed by complex topic) - -## Overview - -This skill orchestrates an iterative search workflow: - -1. **Initial Search**: Execute first search with user's query -2. **Analyze Results**: Identify gaps and refinement opportunities -3. **Iterative Refinement**: Up to 3 rounds of refined searches -4. **Synthesis**: Aggregate all findings into coherent answer -5. **Citation**: Reference source memories in output - -### When to Use - -Use enhanced search instead of basic `/mnemonic:search` when: -- Query is complex or multi-faceted -- User wants comprehensive coverage -- Topic spans multiple namespaces -- Need synthesized answer, not just file matches - ---- - -## Workflow - -### Step 0: Initialize Workflow (Optional) - -For trackable workflows, register in blackboard: - -```bash -# Resolve MNEMONIC_ROOT from config -if [ -f "$HOME/.config/mnemonic/config.json" ]; then - RAW_PATH=$(python3 -c "import json; print(json.load(open('$HOME/.config/mnemonic/config.json')).get('memory_store_path', '~/.claude/mnemonic'))") - MNEMONIC_ROOT="${RAW_PATH/#\~/$HOME}" -else - MNEMONIC_ROOT="$HOME/.claude/mnemonic" -fi -WORKFLOW_ID="search-$(date +%s)" -SESSION_ID="${CLAUDE_SESSION_ID:-$(date +%s)-$$}" -TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") -BB_DIR="$MNEMONIC_ROOT/.blackboard" -mkdir -p "$BB_DIR" - -# Register orchestrator -cat >> "${BB_DIR}/session-notes.md" << EOF - ---- -**Session:** $SESSION_ID -**Time:** $TIMESTAMP -**Agent:** search-enhanced -**Status:** active -**Capabilities:** [query-parsing, iteration-orchestration, synthesis] - -## Agent Registration - -Enhanced search workflow started: $WORKFLOW_ID - -### Query -$QUERY - ---- -EOF - -# Initialize shared state -cat >> "${BB_DIR}/shared-context.md" << EOF - ---- -**Session:** $SESSION_ID -**Time:** $TIMESTAMP -**Agent:** search-enhanced -**Status:** active - -## Shared State: $WORKFLOW_ID - -### Current State -\`\`\`json -{ - "phase": "initialization", - "query": "$QUERY", - "scope": "$SCOPE", - "max_iterations": $MAX_ITERATIONS, - "iteration": 0, - "total_findings": 0 -} -\`\`\` - ---- -EOF -``` - -### Step 1: Parse User Query - -Extract from user request: -- **Primary topic**: Main subject of search -- **Scope**: user, project, or all (default: all) -- **Max iterations**: 1-3 (default: 3) - -```bash -QUERY="user's search query" -SCOPE="${SCOPE:-all}" -MAX_ITERATIONS="${MAX_ITERATIONS:-3}" -``` - -### Step 2: Generate Initial Search Patterns - -Create search patterns from query: - -```bash -# Primary pattern: exact query -PATTERN_1="$QUERY" - -# Secondary patterns: individual key terms -PATTERN_2=$(echo "$QUERY" | tr ' ' '\n' | head -1) # First word -PATTERN_3=$(echo "$QUERY" | tr ' ' '\n' | tail -1) # Last word -``` - -### Step 3: Execute Iteration Loop - -For each iteration (1 to MAX_ITERATIONS): - -``` -ITERATION 1: - Pattern: Primary query - Namespace: all - → Invoke mnemonic-search-subcall agent - → Collect JSON findings - → Analyze: gaps, coverage, suggestions - -ITERATION 2 (if needed): - Pattern: Based on iteration 1 suggestions - Namespace: Suggested namespace - → Invoke mnemonic-search-subcall agent - → Collect additional findings - → Merge with iteration 1 - -ITERATION 3 (if needed): - Pattern: Based on iteration 2 suggestions or related terms - Namespace: Remaining gaps - → Invoke mnemonic-search-subcall agent - → Collect additional findings - → Merge with previous -``` - -### Step 4: Invoke Search Subcall Agent - -Use Task tool to invoke `mnemonic-search-subcall` agent: - -``` -Task( - subagent_type: "mnemonic:mnemonic-search-subcall", - prompt: "Search mnemonic memories. - Query: {query} - Iteration: {iteration} - Search pattern: {pattern} - Namespace filter: {namespace} - Tag filter: {tag} - Scope: {scope} - - Execute search and return JSON findings.", - model: "haiku" -) -``` - -### Note: Prefer qmd for Complex Queries - -When `@tobilu/qmd` is installed and indexed, prefer `qmd query` over iterative ripgrep for complex or conceptual searches. It combines BM25 keyword matching with semantic vector similarity, often finding relevant memories that exact-match searches miss. - -```bash -# Instead of multiple rg iterations, try: -qmd query "authentication patterns and session handling" -n 10 --json -``` - -Use `/mnemonic:qmd-setup` to install and configure qmd. Use `/mnemonic:qmd-reindex` after adding memories. - -### Step 5: Detect Convergence - -Stop iterating early if: -- New iteration finds < 2 new memories -- > 90% overlap with previous iteration -- All suggested namespaces searched -- Reached MAX_ITERATIONS - -```python -def should_continue(current_findings, previous_findings, suggestions): - new_files = set(current_findings) - set(previous_findings) - if len(new_files) < 2: - return False # Diminishing returns - if not suggestions: - return False # No more suggestions - return True -``` - -### Step 6: Aggregate Findings - -Merge findings from all iterations: -- Deduplicate by file path -- Preserve highest relevance rating per file -- Maintain citation counts -- Sort by relevance (high → low) - -### Step 7: Read Top Memories - -For top 5-10 memories (by relevance): -- Read full content -- Extract key points -- Note citations if present - -```bash -for f in $TOP_MEMORIES; do - echo "=== Reading: $f ===" - cat "$f" -done -``` - -### Step 8: Synthesize Response - -Produce structured markdown output: - -```markdown -## Summary - -[2-3 sentence executive summary answering the query] - -## Key Findings - -### [Category/Namespace 1] - -- **[Memory Title]** (namespace, type) - - Key point from memory - - Evidence: "quote" - - Citations: [if any] - -### [Category/Namespace 2] - -- **[Memory Title]** (namespace, type) - - Key point from memory - -## Analysis - -[Synthesis connecting findings, identifying patterns, explaining relationships] - -## Coverage - -- **Iterations**: {count} -- **Memories examined**: {total} -- **Relevant memories**: {relevant} -- **Namespaces searched**: {list} - -## Source Memories - -- [[uuid-1]] - Title 1 -- [[uuid-2]] - Title 2 -- ... - -## Gaps & Next Steps - -[Areas not fully covered, suggested follow-up searches] -``` - ---- - -## Examples - -### Example 1: Simple Topic Search - -**User**: "What do we know about authentication?" - -**Workflow**: -1. Iteration 1: Pattern "authentication" → 5 memories found -2. Suggestions: Try "OAuth", search apis namespace -3. Iteration 2: Pattern "OAuth" → 2 more memories -4. Iteration 3: Search apis namespace → 1 more memory -5. Synthesize 8 total memories - -**Output**: -```markdown -## Summary - -We have 8 memories about authentication covering JWT tokens, OAuth flow, -and middleware patterns. Key decision: Use JWT with RS256 signing. - -## Key Findings - -### Decisions -- **Use JWT for API Authentication** (decisions/project, semantic) - - RS256 algorithm for signing - - 15-minute access token expiry - - Evidence: "Stateless authentication reduces server load" - -### Patterns -- **Authentication Middleware Pattern** (patterns/project, procedural) - - Always verify signature before trusting claims - - Store refresh tokens in httpOnly cookies - -... - -## Source Memories - -- [[abc123]] - Use JWT for API Authentication -- [[def456]] - Authentication Middleware Pattern -``` - -### Example 2: Complex Multi-Faceted Query - -**User**: "Synthesize everything about our database decisions and performance learnings" - -**Workflow**: -1. Iteration 1: Pattern "database" in decisions → 3 memories -2. Iteration 2: Pattern "performance" in learnings → 4 memories -3. Iteration 3: Pattern "PostgreSQL OR MySQL" in all → 2 more -4. Synthesize 9 total memories with cross-references - ---- - -## Best Practices - -### Query Refinement Strategy - -1. **Start broad**: Use user's exact query first -2. **Narrow by namespace**: Focus on most relevant category -3. **Expand by related terms**: Use terms found in initial results -4. **Check suggestions**: Follow subcall agent's refinement suggestions - -### Performance Optimization - -- Limit to 10 files per iteration (use head -10) -- Read frontmatter + snippet only during search -- Full read only for top 5-10 final memories -- Use haiku model for subcalls (cost-effective) - -### Context Conservation - -- Subcall agents run in isolated context -- Only JSON findings returned to main context -- Full memory content read only during synthesis -- Total context usage: ~3-5k tokens typical - ---- - -## Configuration - -| Parameter | Default | Description | -|-----------|---------|-------------| -| MAX_ITERATIONS | 3 | Maximum search rounds | -| FILES_PER_ITERATION | 10 | Max files to process per round | -| TOP_MEMORIES | 10 | Full memories to read for synthesis | -| MODEL | haiku | Model for subcall agents | - ---- - -## Error Handling - -| Condition | Action | -|-----------|--------| -| No results in iteration 1 | Try broader pattern, check spelling | -| Subcall agent timeout | Skip iteration, continue with current findings | -| Malformed JSON from subcall | Log error, skip that iteration | -| Max iterations reached | Proceed to synthesis with available findings | - ---- - -### Step 9: Complete Workflow (Optional) - -For trackable workflows, update blackboard on completion: - -```bash -TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") - -# Update shared state -cat >> "${BB_DIR}/shared-context.md" << EOF - ---- -**Session:** $SESSION_ID -**Time:** $TIMESTAMP -**Agent:** search-enhanced -**Status:** idle - -## Shared State: $WORKFLOW_ID - -### Final State -\`\`\`json -{ - "phase": "complete", - "iterations": $ITERATIONS_RUN, - "total_findings": $TOTAL_FINDINGS, - "memories_synthesized": $MEMORIES_READ -} -\`\`\` - ---- -EOF - -# Update agent status -cat >> "${BB_DIR}/session-notes.md" << EOF - ---- -**Session:** $SESSION_ID -**Time:** $TIMESTAMP -**Agent:** search-enhanced -**Status:** idle - -## Workflow Complete - -### Summary -- Workflow: $WORKFLOW_ID -- Iterations: $ITERATIONS_RUN -- Findings: $TOTAL_FINDINGS -- Memories synthesized: $MEMORIES_READ - ---- -EOF -``` - ---- - -## Related - -- `/mnemonic:search` - Basic single-shot search (faster, simpler) -- `mnemonic-search-subcall` agent - Executes individual search rounds -- `mnemonic-search` skill - Advanced search patterns reference -- `mnemonic-agent-coordination` skill - Agent coordination patterns diff --git a/skills/mnemonic-search/SKILL.md b/skills/mnemonic-search/SKILL.md deleted file mode 100644 index a746bac..0000000 --- a/skills/mnemonic-search/SKILL.md +++ /dev/null @@ -1,494 +0,0 @@ ---- -allowed-tools: -- Bash -- Read -- Glob -- Grep -- Write -description: > - This skill should be used when the user says "search memories", "find in memories", - "grep mnemonic", "look for memory", or asks questions like "what do we know about X". - Provides progressive disclosure: Level 1 (titles), Level 2 (frontmatter + summary), - Level 3 (full content). Start at Level 1 and expand only if needed. -name: mnemonic-search -user-invocable: true ---- - -## Memory - -Search first: `/mnemonic:search {relevant_keywords}` -Capture after: `/mnemonic:capture {namespace} "{title}"` - -Run `/mnemonic:list --namespaces` to see available namespaces from loaded ontologies. - - -# Mnemonic Search Skill - -Advanced search and filtering techniques for mnemonic memories. - -## Trigger Phrases - -- "search memories" -- "find in memories" -- "grep memories" -- "ripgrep mnemonic" -- "look for memory" -- "search mnemonic" - -## Overview - -This skill teaches comprehensive search patterns using ripgrep, grep, find, and other Unix tools to locate and filter memories efficiently. - ---- - -## Frontmatter Search - -Memories use YAML frontmatter. Search specific fields: - -### Extract YAML Block - -```bash -# Get just the frontmatter -sed -n '/^---$/,/^---$/p' /path/to/memory.memory.md - -# Or using awk -awk '/^---$/{p=!p; print; next} p' /path/to/memory.memory.md -``` - -### Search by Namespace - -```bash -# Find all decisions -rg "^namespace: _semantic/decisions" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l -rg "^namespace: _semantic/decisions" --glob "*.memory.md" -l - -# Find project-scoped only -rg "^namespace: .*/project" --glob "*.memory.md" -l - -# Find user-scoped only -rg "^namespace: .*/user" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l -``` - -### Search by Tag - -```bash -# Single tag (in YAML list format) -rg -l "^ - architecture" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# Multiple tags (AND - both must exist in file) -rg -l "^ - architecture" ${MNEMONIC_ROOT}/ --glob "*.memory.md" | xargs rg -l "^ - database" - -# Tag containing substring -rg -l "^ - auth" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -``` - -### Search by Type - -```bash -# Find semantic memories (facts, concepts) -rg "^type: semantic" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l - -# Find episodic memories (events, experiences) -rg "^type: episodic" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l - -# Find procedural memories (processes, workflows) -rg "^type: procedural" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l -``` - -### Search by Date - -```bash -# Created in January 2026 -rg "^created: 2026-01" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l - -# Created in specific date range -rg "^created: 2026-01-(1[5-9]|2[0-9]|3[01])" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l - -# Modified recently -rg "^modified: 2026-01-2" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l -``` - -### Search by Title - -```bash -# Exact phrase in title -rg '^title: ".*PostgreSQL.*"' ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l - -# Case-insensitive title search -rg -i '^title: ".*auth.*"' ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l -``` - -### Search by Confidence - -```bash -# High confidence memories (0.9+) -rg "confidence: 0\.9" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l - -# Lower confidence (might need review) -rg "confidence: 0\.[0-7]" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l -``` - -### Search by Citations - -```bash -# Find all memories with citations -rg -l "^citations:" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# Find memories by citation type -rg "type: paper" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l -rg "type: documentation" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l -rg "type: github" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l - -# Find memories citing specific domain -rg "url: https://arxiv.org" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l -rg "url: https://docs.python.org" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l - -# Find memories by citation author -rg "author: \"Smith" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l - -# Find high-relevance citations -rg "relevance: 0\.9" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l -``` - ---- - -## Full-Text Search - -### Basic Search - -```bash -# Simple pattern -rg "pattern" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# Case-insensitive -rg -i "pattern" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# Whole word only -rg -w "pattern" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -``` - -### With Context - -```bash -# 3 lines before and after match -rg -C3 "pattern" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# 5 lines after (useful for finding related content) -rg -A5 "pattern" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# 2 lines before (useful for finding headers) -rg -B2 "pattern" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -``` - -### Regex Patterns - -```bash -# Function names -rg "function\s+\w+" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# URLs -rg "https?://[^\s]+" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# File paths -rg "src/[^\s]+" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# Version numbers -rg "\d+\.\d+\.\d+" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -``` - -### Files Only (No Content) - -```bash -# Just list matching files -rg -l "pattern" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# Count matches per file -rg -c "pattern" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -``` - ---- - -## Combined Filters - -### Namespace + Text - -```bash -# Decisions about databases -rg "database" ${MNEMONIC_ROOT} --path "*/_semantic/decisions/" --glob "*.memory.md" - -# Knowledge about testing -rg "test" ${MNEMONIC_ROOT} --path "*/_semantic/knowledge/" --glob "*.memory.md" - -# Project patterns only -rg "pattern" ${MNEMONIC_ROOT} --path "*/_procedural/patterns/" --glob "*.memory.md" -``` - -### Recent + Text - -```bash -# Files modified in last 7 days containing "api" -find ${MNEMONIC_ROOT} -name "*.memory.md" -mtime -7 -exec rg -l "api" {} \; - -# Files modified today -find ${MNEMONIC_ROOT} -name "*.memory.md" -mtime 0 -exec rg -l "pattern" {} \; -``` - -### Type + Namespace - -```bash -# Episodic memories in blockers (incident reports) -rg -l "^type: episodic" ${MNEMONIC_ROOT} --path "*/_episodic/blockers/" --glob "*.memory.md" - -# Procedural memories in patterns (workflows) -rg -l "^type: procedural" ${MNEMONIC_ROOT} --path "*/_procedural/patterns/" --glob "*.memory.md" -``` - -### Tag + Text - -```bash -# Memories tagged "security" mentioning "password" -for f in $(rg -l "^ - security" ${MNEMONIC_ROOT}/ --glob "*.memory.md"); do - rg -l "password" "$f" 2>/dev/null -done -``` - ---- - -## Progressive Disclosure Levels - -### Level 1: Quick Answer (Titles Only) - -```bash -# List all memory titles -for f in ${MNEMONIC_ROOT}/**/*.memory.md; do - title=$(grep "^title:" "$f" 2>/dev/null | head -1 | sed 's/^title: "//' | sed 's/"$//') - [ -n "$title" ] && echo "$title" -done -``` - -### Level 2: Context (Frontmatter + First Section) - -```bash -# Get frontmatter plus first 10 content lines -head -50 /path/to/memory.memory.md -``` - -### Structured Summary (Key Fields) - -```bash -# Extract key fields for quick review -for f in ${MNEMONIC_ROOT}/**/*.memory.md; do - echo "=== $(basename "$f") ===" - grep -E "^(id|type|namespace|title|created):" "$f" | head -5 - echo "" -done -``` - -### Level 3: Full Detail - -```bash -# Complete memory content -cat /path/to/memory.memory.md -``` - ---- - -## Performance Tips - -### Narrow File Set First - -```bash -# Use find to limit scope, then search -find ${MNEMONIC_ROOT} -path "*/_semantic/decisions/*" -name "*.memory.md" | xargs rg "pattern" - -# Or use directory restriction -rg "pattern" ${MNEMONIC_ROOT} --path "*/_semantic/decisions/" --glob "*.memory.md" -``` - -### Limit Output - -```bash -# First 10 matches only -rg "pattern" ${MNEMONIC_ROOT}/ --glob "*.memory.md" | head -10 - -# First matching file only -rg -l "pattern" ${MNEMONIC_ROOT}/ --glob "*.memory.md" | head -1 -``` - -### Use File List Mode - -```bash -# Get file list first -FILES=$(rg -l "pattern" ${MNEMONIC_ROOT}/ --glob "*.memory.md") - -# Then read specific files -for f in $FILES; do - head -30 "$f" -done -``` - -### Parallel Search - -```bash -# Search multiple namespaces in parallel -rg "pattern" ${MNEMONIC_ROOT} --path "*/_semantic/decisions/" --glob "*.memory.md" & -rg "pattern" ${MNEMONIC_ROOT} --path "*/_semantic/knowledge/" --glob "*.memory.md" & -wait -``` - ---- - -## Examples - -### Find All Decisions About Authentication - -```bash -echo "=== Auth Decisions ===" -rg -i "auth" ${MNEMONIC_ROOT} --path "*/_semantic/decisions/" --glob "*.memory.md" -l -``` - -### Recent Knowledge in Current Project - -```bash -echo "=== Recent Project Knowledge ===" -find ${MNEMONIC_ROOT} -path "*/_semantic/knowledge/*" -name "*.memory.md" -mtime -7 -exec basename {} \; -``` - -### Episodic Memories From Last Week - -```bash -echo "=== Last Week's Events ===" -for f in $(find ${MNEMONIC_ROOT} -path "*/_episodic/*" -name "*.memory.md" -mtime -7 2>/dev/null); do - grep "^title:" "$f" | sed 's/^title: "//' | sed 's/"$//' -done -``` - -### High-Confidence Security Knowledge - -```bash -echo "=== Trusted Security Knowledge ===" -for f in $(rg -l "confidence: 0\.9" ${MNEMONIC_ROOT} --path "*/_semantic/knowledge/" --glob "*.memory.md" 2>/dev/null); do - grep "^title:" "$f" -done -``` - -### Code References in Memories - -```bash -echo "=== Memories With Code Refs ===" -rg -l "^code_refs:" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# Find memories referencing specific file -rg "file: src/auth" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l -``` - -### Memories With Relationships - -```bash -echo "=== Linked Memories ===" -rg "\[\[" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l -``` - ---- - -## Semantic Search (requires qmd) - -If `@tobilu/qmd` is installed and indexed (see `/mnemonic:qmd-setup`), you can use semantic search in addition to ripgrep. - -### Commands - -```bash -# BM25 keyword search (like rg, but ranked) -qmd search "authentication middleware" -n 10 - -# Semantic vector search (meaning-based, not keyword) -qmd vsearch "how do we handle user sessions" -n 10 - -# Hybrid search (BM25 + vector combined) -qmd query "authentication patterns and best practices" -n 10 -``` - -### Useful Flags - -```bash -# Scope to a specific collection -qmd search "auth" -c mnemonic-zircote - -# JSON output for programmatic use -qmd search "auth" --json - -# Minimum relevance score -qmd vsearch "auth" --min-score 0.5 -``` - -### When to Use Each - -| Tool | Best For | Requires | -|------|----------|----------| -| `rg` | Exact strings, regex, frontmatter fields, fastest | Nothing | -| `qmd search` | Ranked keyword search, typo-tolerant | `qmd update` | -| `qmd vsearch` | Conceptual/meaning-based queries | `qmd embed` | -| `qmd query` | Best overall recall, combines both signals | Both | - -**Use `rg` when** you know the exact term or field (e.g., `rg "^namespace: _semantic/decisions"`). -**Use `qmd` when** searching by concept, fuzzy matching, or need ranked results. - -### Important - -Indexing is **not** automatic. After adding memories, run `/mnemonic:qmd-reindex` (or `qmd update && qmd embed`). - ---- - -## Search Cheat Sheet - -| Goal | Command | -|------|---------| -| All decisions | `rg "^namespace: _semantic/decisions" ${MNEMONIC_ROOT}/ -l` | -| By tag | `rg -l "^ - tagname" ${MNEMONIC_ROOT}/` | -| By type | `rg "^type: semantic" ${MNEMONIC_ROOT}/ -l` | -| Full-text | `rg -i "search term" ${MNEMONIC_ROOT}/` | -| Recent files | `find ${MNEMONIC_ROOT} -mtime -7` | -| Titles only | `rg "^title:" ${MNEMONIC_ROOT}/` | -| High confidence | `rg "confidence: 0\.9" ${MNEMONIC_ROOT}/ -l` | -| With code refs | `rg "^code_refs:" ${MNEMONIC_ROOT}/ -l` | -| With citations | `rg "^citations:" ${MNEMONIC_ROOT}/ -l` | -| Citation type | `rg "type: paper" ${MNEMONIC_ROOT}/ -l` | -| Citation domain | `rg "url: https://arxiv.org" ${MNEMONIC_ROOT}/ -l` | -| Project only | `rg "pattern"` | - ---- - -## Progressive Disclosure Protocol - -When searching memories, use progressive disclosure to minimize context usage: - -### Level 1: Quick Answer (Titles Only) - START HERE - -```bash -# List matching files first -rg -l "pattern" ${MNEMONIC_ROOT}/ --glob "*.memory.md" - -# Then get titles -for f in $(rg -l "pattern" ${MNEMONIC_ROOT}/ --glob "*.memory.md"); do - grep "^title:" "$f" | head -1 -done -``` - -### Level 2: Context (Frontmatter + Summary) - -Only expand to Level 2 if Level 1 titles aren't sufficient: - -```bash -# Get frontmatter plus first 10 content lines -head -50 /path/to/memory.memory.md -``` - -### Level 3: Full Detail - -Only use full read when absolutely necessary: - -```bash -cat /path/to/memory.memory.md -``` - -**Always start at Level 1. Expand only if needed.** diff --git a/skills/ontology/ontologies.deprecated/base.ontology.yaml b/skills/ontology/ontologies.deprecated/base.ontology.yaml deleted file mode 100644 index 9f8c8ec..0000000 --- a/skills/ontology/ontologies.deprecated/base.ontology.yaml +++ /dev/null @@ -1,72 +0,0 @@ ---- -# Mnemonic Base Ontology -# -# This ontology defines the standard mnemonic namespaces. -# It provides backward compatibility for existing memories -# and serves as a reference for custom ontology development. -# -# Version: 1.0.0 -# Last Updated: 2026-01-25 - -ontology: - id: mnemonic-base - version: "1.0.0" - description: "Base mnemonic namespaces for backward compatibility" - -# Standard Mnemonic Namespaces -# These are the 9 core namespaces that ship with mnemonic. -# Custom ontologies can extend or replace these. - -namespaces: - apis: - description: "API documentation, contracts, endpoints, specifications" - type_hint: semantic - - blockers: - description: "Issues, impediments, incidents, things blocking progress" - type_hint: episodic - - context: - description: "Background information, environment state, project context" - type_hint: semantic - - decisions: - description: "Architectural choices with rationale, technology selections" - type_hint: semantic - - learnings: - description: "Insights, discoveries, TILs (Today I Learned), gotchas" - type_hint: semantic - - patterns: - description: "Code conventions, best practices, recurring solutions" - type_hint: procedural - - security: - description: "Security policies, vulnerabilities, access controls" - type_hint: semantic - - testing: - description: "Test strategies, edge cases, coverage notes" - type_hint: procedural - - episodic: - description: "General events, experiences, debug sessions, meetings" - type_hint: episodic - -# No custom entity types in base ontology -# Memories use the standard types: semantic, episodic, procedural -entity_types: [] - -# No custom traits in base ontology -traits: {} - -# No relationships defined in base ontology -# Standard relationships like relates-to, supersedes are handled by MIF -relationships: {} - -# No discovery patterns in base ontology -# Discovery is disabled by default -discovery: - enabled: false - patterns: [] diff --git a/skills/ontology/ontologies.deprecated/examples/software-engineering.ontology.yaml b/skills/ontology/ontologies.deprecated/examples/software-engineering.ontology.yaml deleted file mode 100644 index 804a12a..0000000 --- a/skills/ontology/ontologies.deprecated/examples/software-engineering.ontology.yaml +++ /dev/null @@ -1,531 +0,0 @@ ---- -# Software Engineering Ontology -# -# A comprehensive ontology for software development teams. -# Extends mnemonic with architecture, component, and incident types. -# -# Usage: -# Copy to ./.claude/mnemonic/ontology.yaml -# Or reference via URL in your project ontology -# -# Version: 1.0.0 -# Last Updated: 2026-01-25 - -ontology: - id: software-engineering - version: "1.0.0" - description: "Software engineering domain ontology for development teams" - -# Custom Namespaces -# These extend the base mnemonic namespaces -namespaces: - architecture: - description: "System architecture decisions and component designs" - type_hint: semantic - - components: - description: "Software components, modules, services, libraries" - type_hint: semantic - - incidents: - description: "Production incidents, outages, postmortems" - type_hint: episodic - - migrations: - description: "Database migrations, schema changes, data transformations" - type_hint: procedural - - dependencies: - description: "Third-party libraries, packages, services, integrations" - type_hint: semantic - -# Entity Types -# These define structured entity schemas with inheritance -entity_types: - - name: component - description: "A software component, module, or service" - base: semantic - traits: - - versioned - - documented - schema: - required: - - name - - responsibility - properties: - name: - type: string - description: "Component name" - responsibility: - type: string - description: "Single responsibility description" - dependencies: - type: array - description: "List of component dependencies" - items: - type: string - interfaces: - type: array - description: "Public interfaces/APIs" - items: - type: string - owner: - type: string - description: "Team or person owning this component" - - - name: architectural-decision - description: "An architectural decision with full context" - base: semantic - traits: - - dated - - cited - schema: - required: - - decision - - rationale - properties: - decision: - type: string - description: "The decision made" - rationale: - type: string - description: "Why this decision was made" - alternatives: - type: array - description: "Alternatives considered" - items: - type: object - consequences: - type: object - description: "Known consequences and trade-offs" - status: - type: string - description: "Decision status" - enum: - - proposed - - accepted - - deprecated - - superseded - - - name: incident-report - description: "A production incident or outage report" - base: episodic - traits: - - timeline - - stakeholders - schema: - required: - - severity - - impact - - resolution - properties: - severity: - type: string - description: "Incident severity level" - enum: - - critical - - high - - medium - - low - impact: - type: string - description: "Business/user impact description" - resolution: - type: string - description: "How the incident was resolved" - root_cause: - type: string - description: "Root cause analysis" - prevention: - type: array - description: "Prevention measures" - items: - type: string - duration_minutes: - type: integer - description: "Incident duration in minutes" - - - name: technology - description: "A technology, framework, or tool" - base: semantic - traits: - - versioned - - documented - schema: - required: - - name - - category - properties: - name: - type: string - category: - type: string - enum: - - database - - framework - - language - - infrastructure - - tool - - library - website: - type: string - format: uri - license: - type: string - use_case: - type: string - description: "Why/where we use this technology" - - - name: design-pattern - description: "A design pattern or architectural pattern" - base: semantic - traits: - - cited - schema: - required: - - pattern_name - - context - - solution - properties: - pattern_name: - type: string - context: - type: string - description: "When to use this pattern" - solution: - type: string - description: "How the pattern solves the problem" - consequences: - type: object - description: "Trade-offs and implications" - related_patterns: - type: array - items: - type: string - - # PROCEDURAL ENTITY TYPES - # These capture step-by-step processes and operational knowledge - - - name: deployment-procedure - description: "Step-by-step deployment or release procedure" - base: procedural - traits: - - versioned - - stakeholders - schema: - required: - - name - - steps - - target_environment - properties: - name: - type: string - description: "Procedure name" - steps: - type: array - description: "Ordered list of steps" - items: - type: object - properties: - order: - type: integer - action: - type: string - verification: - type: string - rollback: - type: string - target_environment: - type: string - description: "Target environment" - enum: - - development - - staging - - production - prerequisites: - type: array - description: "Required conditions before execution" - items: - type: string - estimated_duration: - type: string - description: "Expected time to complete" - automation_level: - type: string - enum: - - manual - - semi-automated - - fully-automated - - - name: runbook - description: "Operational runbook for handling scenarios" - base: procedural - traits: - - versioned - - stakeholders - schema: - required: - - title - - trigger - - procedure - properties: - title: - type: string - trigger: - type: string - description: "What triggers this runbook" - severity: - type: string - enum: - - critical - - high - - medium - - low - procedure: - type: array - description: "Step-by-step procedure" - items: - type: object - properties: - step: - type: integer - action: - type: string - expected_outcome: - type: string - escalation: - type: object - description: "Escalation path" - properties: - conditions: - type: string - contact: - type: string - related_alerts: - type: array - items: - type: string - - - name: migration-guide - description: "Database or system migration procedure" - base: procedural - traits: - - versioned - - dated - schema: - required: - - title - - from_state - - to_state - - steps - properties: - title: - type: string - from_state: - type: string - description: "Current state before migration" - to_state: - type: string - description: "Target state after migration" - steps: - type: array - items: - type: object - rollback_procedure: - type: array - items: - type: object - data_validation: - type: array - description: "Validation checks" - items: - type: string - downtime_required: - type: boolean - -# Traits (Mixins) -# Reusable field sets that can be composed into entity types -traits: - versioned: - description: "Adds version tracking fields" - fields: - version: - type: string - pattern: "^\\d+\\.\\d+\\.\\d+.*$" - changelog: - type: array - items: - type: object - - documented: - description: "Adds documentation reference" - fields: - documentation_url: - type: string - format: uri - readme_path: - type: string - - dated: - description: "Adds decision/event date" - fields: - decision_date: - type: string - format: date - review_date: - type: string - format: date - - cited: - description: "Requires citations/sources" - requires: - - citations - - timeline: - description: "Adds incident timeline" - fields: - timeline: - type: array - items: - type: object - properties: - timestamp: - type: string - format: date-time - event: - type: string - actor: - type: string - - stakeholders: - description: "Adds stakeholder tracking" - fields: - stakeholders: - type: array - items: - type: object - properties: - name: - type: string - role: - type: string - contact: - type: string - -# Relationships -# Define how entities can relate to each other -relationships: - depends_on: - description: "Component dependency relationship" - from: - - component - to: - - component - - technology - symmetric: false - - implements: - description: "Component implements a pattern or decision" - from: - - component - to: - - design-pattern - - architectural-decision - symmetric: false - - caused_by: - description: "Incident causality" - from: - - incident-report - to: - - component - - technology - symmetric: false - - resolves: - description: "Decision resolves an issue" - from: - - architectural-decision - to: - - incident-report - symmetric: false - - supersedes: - description: "Newer version supersedes older" - from: - - architectural-decision - - component - - runbook - - deployment-procedure - to: - - architectural-decision - - component - - runbook - - deployment-procedure - symmetric: false - - documents: - description: "Procedure documents how to work with entity" - from: - - runbook - - deployment-procedure - - migration-guide - to: - - component - - technology - symmetric: false - - triggers: - description: "Incident triggers runbook execution" - from: - - incident-report - to: - - runbook - symmetric: false - -# Discovery Configuration -# Patterns for auto-discovering entities -discovery: - enabled: true - confidence_threshold: 0.8 - - patterns: - # Technology patterns - - content_pattern: "\\b(PostgreSQL|MySQL|MongoDB|Redis|Elasticsearch)\\b" - suggest_entity: technology - - content_pattern: "\\b(React|Vue|Angular|Next\\.js|Django)\\b" - suggest_entity: technology - - content_pattern: "\\b(FastAPI|Express|Flask|Spring)\\b" - suggest_entity: technology - - content_pattern: "\\b(Docker|Kubernetes|Terraform|AWS|GCP|Azure)\\b" - suggest_entity: technology - - # Pattern patterns - - content_pattern: "\\b(Factory|Singleton|Observer|Adapter)\\s+Pattern\\b" - suggest_entity: design-pattern - - content_pattern: "\\b(Repository|Strategy|Decorator)\\s+Pattern\\b" - suggest_entity: design-pattern - - content_pattern: "\\b(CQRS|Event\\s+Sourcing|Saga|Circuit\\s+Breaker)\\b" - suggest_entity: design-pattern - - # Component patterns - - file_pattern: "**/services/**/*.py" - suggest_entity: component - - file_pattern: "**/components/**/*.tsx" - suggest_entity: component - - # Incident patterns - - content_pattern: "\\b(outage|incident|postmortem|RCA)\\b" - suggest_entity: incident-report - - # Procedural patterns - runbooks and deployments - - content_pattern: "\\b(runbook|playbook|SOP|procedure)\\b" - suggest_entity: runbook - - content_pattern: "\\b(deploy|release|rollout)\\s+(steps|procedure)\\b" - suggest_entity: deployment-procedure - - content_pattern: "\\b(migration|migrate|upgrade)\\s+(guide|plan)\\b" - suggest_entity: migration-guide - - file_pattern: "**/runbooks/**/*.md" - suggest_entity: runbook - - file_pattern: "**/docs/procedures/**/*.md" - suggest_entity: deployment-procedure diff --git a/skills/ontology/ontologies.deprecated/schemas/ontology-meta-schema.json b/skills/ontology/ontologies.deprecated/schemas/ontology-meta-schema.json deleted file mode 100644 index 94a4978..0000000 --- a/skills/ontology/ontologies.deprecated/schemas/ontology-meta-schema.json +++ /dev/null @@ -1,258 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://mnemonic.org/schemas/ontology/v1", - "title": "Mnemonic Ontology Schema", - "description": "JSON Schema for validating Mnemonic ontology definition files", - "type": "object", - "properties": { - "ontology": { - "type": "object", - "description": "Ontology metadata", - "required": ["id", "version"], - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the ontology", - "pattern": "^[a-z][a-z0-9-]*$" - }, - "version": { - "type": "string", - "description": "Semantic version string", - "pattern": "^\\d+\\.\\d+\\.\\d+.*$" - }, - "description": { - "type": "string", - "description": "Human-readable description" - }, - "schema_url": { - "type": "string", - "description": "URL to external schema definition", - "format": "uri" - } - } - }, - "namespaces": { - "type": "object", - "description": "Custom namespace definitions", - "additionalProperties": { - "type": "object", - "properties": { - "description": { - "type": "string", - "description": "Namespace description" - }, - "type_hint": { - "type": "string", - "description": "Default memory type for this namespace", - "enum": ["semantic", "episodic", "procedural"] - }, - "replaces": { - "type": "string", - "description": "Base namespace this replaces" - } - } - } - }, - "entity_types": { - "type": "array", - "description": "Custom entity type definitions", - "items": { - "$ref": "#/$defs/entityType" - } - }, - "traits": { - "type": "object", - "description": "Reusable trait/mixin definitions", - "additionalProperties": { - "$ref": "#/$defs/trait" - } - }, - "relationships": { - "type": "object", - "description": "Relationship type definitions", - "additionalProperties": { - "$ref": "#/$defs/relationship" - } - }, - "discovery": { - "type": "object", - "description": "Entity discovery configuration", - "properties": { - "enabled": { - "type": "boolean", - "description": "Whether discovery is enabled", - "default": false - }, - "patterns": { - "type": "array", - "description": "Discovery patterns", - "items": { - "$ref": "#/$defs/discoveryPattern" - } - }, - "confidence_threshold": { - "type": "number", - "description": "Minimum confidence for suggestions", - "minimum": 0, - "maximum": 1, - "default": 0.8 - } - } - } - }, - "$defs": { - "entityType": { - "type": "object", - "description": "Entity type definition", - "required": ["name", "base"], - "properties": { - "name": { - "type": "string", - "description": "Entity type name", - "pattern": "^[a-z][a-z0-9-]*$" - }, - "description": { - "type": "string", - "description": "Entity type description" - }, - "base": { - "type": "string", - "description": "Base memory type", - "enum": ["semantic", "episodic", "procedural"] - }, - "traits": { - "type": "array", - "description": "Traits this entity type includes", - "items": { - "type": "string" - } - }, - "schema": { - "type": "object", - "description": "JSON Schema for entity fields", - "properties": { - "required": { - "type": "array", - "items": { - "type": "string" - } - }, - "properties": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/propertySchema" - } - } - } - } - } - }, - "trait": { - "type": "object", - "description": "Trait/mixin definition", - "properties": { - "description": { - "type": "string" - }, - "fields": { - "type": "object", - "description": "Fields provided by this trait", - "additionalProperties": { - "$ref": "#/$defs/propertySchema" - } - }, - "requires": { - "type": "array", - "description": "MIF fields this trait requires", - "items": { - "type": "string" - } - } - } - }, - "relationship": { - "type": "object", - "description": "Relationship type definition", - "properties": { - "description": { - "type": "string" - }, - "from": { - "type": "array", - "description": "Entity types that can be the source", - "items": { - "type": "string" - } - }, - "to": { - "type": "array", - "description": "Entity types that can be the target", - "items": { - "type": "string" - } - }, - "symmetric": { - "type": "boolean", - "description": "Whether the relationship is symmetric", - "default": false - } - } - }, - "discoveryPattern": { - "type": "object", - "description": "Pattern for discovering entities", - "required": ["suggest_entity"], - "properties": { - "content_pattern": { - "type": "string", - "description": "Regex pattern to match in content" - }, - "file_pattern": { - "type": "string", - "description": "Glob pattern to match file paths" - }, - "suggest_entity": { - "type": "string", - "description": "Entity type to suggest when pattern matches" - } - } - }, - "propertySchema": { - "type": "object", - "description": "JSON Schema property definition", - "properties": { - "type": { - "type": "string", - "enum": [ - "string", - "number", - "integer", - "boolean", - "array", - "object", - "null" - ] - }, - "description": { - "type": "string" - }, - "format": { - "type": "string", - "description": "Format hint (e.g., 'uri', 'date-time')" - }, - "pattern": { - "type": "string", - "description": "Regex pattern for string validation" - }, - "items": { - "type": "object", - "description": "Schema for array items" - }, - "enum": { - "type": "array", - "description": "Allowed values" - } - } - } - } -} diff --git a/skills/qmd-reindex/SKILL.md b/skills/qmd-reindex/SKILL.md index 7eb3073..d37f2a1 100644 --- a/skills/qmd-reindex/SKILL.md +++ b/skills/qmd-reindex/SKILL.md @@ -1,9 +1,7 @@ --- allowed-tools: - Bash -description: > - Re-index mnemonic memories for qmd semantic search. Run after capturing - new memories or bulk imports. +description: Re-index mnemonic memories for qmd semantic search. Run after capturing new memories or bulk imports. name: qmd-reindex user-invocable: true --- diff --git a/skills/qmd-setup/SKILL.md b/skills/qmd-setup/SKILL.md index 7c96c74..0dfa0e6 100644 --- a/skills/qmd-setup/SKILL.md +++ b/skills/qmd-setup/SKILL.md @@ -3,9 +3,7 @@ allowed-tools: - Bash - Read - Write -description: > - Set up @tobilu/qmd semantic search for mnemonic memories. Registers collections, - builds indexes, and generates embeddings. Run this once per machine. +description: Set up @tobilu/qmd semantic search for mnemonic memories. Registers collections, builds indexes, and generates embeddings. Run this once per machine. name: qmd-setup user-invocable: true --- diff --git a/skills/search/SKILL.md b/skills/search/SKILL.md new file mode 100644 index 0000000..0c6ce96 --- /dev/null +++ b/skills/search/SKILL.md @@ -0,0 +1,167 @@ +--- +allowed-tools: +- Bash +- Read +- Glob +- Grep +- Write +- Task +description: > + This skill should be used when the user says "search memories", "find in memories", + "grep mnemonic", "look for memory", "deep search", "synthesize knowledge", or asks + questions like "what do we know about X". Provides progressive disclosure and + enhanced iterative search with synthesis. +name: search +user-invocable: true +--- + +## Memory + +Search first: `/mnemonic:search {relevant_keywords}` +Capture after: `/mnemonic:capture {namespace} "{title}"` + +Run `/mnemonic:list --namespaces` to see available namespaces from loaded ontologies. + + +# Mnemonic Search Skill + +Search and filtering for mnemonic memories. + +## Trigger Phrases + +- "search memories", "find in memories", "grep memories", "search mnemonic" +- "deep search memories", "comprehensive memory search", "synthesize knowledge about" + +--- + +## Core Search Patterns + +### By Namespace + +```bash +rg "^namespace: _semantic/decisions" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l +``` + +### By Tag + +```bash +# Single tag +rg -l "^ - architecture" ${MNEMONIC_ROOT}/ --glob "*.memory.md" + +# Multiple tags (AND) +rg -l "^ - architecture" ${MNEMONIC_ROOT}/ --glob "*.memory.md" | xargs rg -l "^ - database" +``` + +### By Type + +```bash +rg "^type: semantic" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l +rg "^type: episodic" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l +rg "^type: procedural" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l +``` + +### By Date + +```bash +rg "^created: 2026-01" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l +``` + +### By Title + +```bash +rg -i '^title: ".*auth.*"' ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l +``` + +### By Confidence + +```bash +rg "confidence: 0\.9" ${MNEMONIC_ROOT}/ --glob "*.memory.md" -l +``` + +### Full-Text + +```bash +rg -i "search term" ${MNEMONIC_ROOT}/ --glob "*.memory.md" +``` + +### Combined: Namespace + Text + +```bash +rg "database" ${MNEMONIC_ROOT} --path "*/_semantic/decisions/" --glob "*.memory.md" +``` + +### Recent Files + +```bash +find ${MNEMONIC_ROOT} -name "*.memory.md" -mtime -7 +``` + +--- + +## Progressive Disclosure Protocol + +Always start at Level 1. Expand only if needed. + +| Level | What | How | +|-------|------|-----| +| 1 (start here) | Titles only | `rg -l "pattern" ${MNEMONIC_ROOT}/ --glob "*.memory.md"` then extract `^title:` | +| 2 | Frontmatter + summary | Read first ~50 lines of matched files | +| 3 | Full detail | Read entire memory file | + +--- + +## Semantic Search (requires qmd) + +If `@tobilu/qmd` is installed (see `/mnemonic:qmd-setup`): + +```bash +# BM25 keyword search (ranked) +qmd search "authentication middleware" -n 10 + +# Semantic vector search (meaning-based) +qmd vsearch "how do we handle user sessions" -n 10 + +# Hybrid search (BM25 + vector combined) +qmd query "authentication patterns" -n 10 + +# Scope to collection +qmd search "auth" -c mnemonic-zircote +``` + +| Tool | Best For | Requires | +|------|----------|----------| +| `rg` | Exact strings, regex, frontmatter fields | Nothing | +| `qmd search` | Ranked keyword search, typo-tolerant | `qmd update` | +| `qmd vsearch` | Conceptual/meaning-based queries | `qmd embed` | +| `qmd query` | Best overall recall, combines both | Both | + +After adding memories, run `/mnemonic:qmd-reindex` to update indexes. + +--- + +## Enhanced Search (Iterative with Synthesis) + +For complex or multi-faceted queries: + +1. **Initial search** with user's query +2. **Analyze results** for gaps +3. **Iterative refinement** (up to 3 rounds via Task tool with `mnemonic-search-subcall` agent) +4. **Synthesize** findings into a coherent answer with source citations + +Use when queries span multiple namespaces or need comprehensive coverage. + +### Output Format + +```markdown +## Synthesized Answer +{Answer drawing from all found memories} + +### Sources +| Memory | Namespace | Relevance | +|--------|-----------|-----------| +| [[memory-id]] title | namespace | High/Medium | + +### Gaps +- {Topics where no memories were found} +``` + diff --git a/skills/mnemonic-setup/SKILL.md b/skills/setup/SKILL.md similarity index 99% rename from skills/mnemonic-setup/SKILL.md rename to skills/setup/SKILL.md index 519e3a3..b270af6 100644 --- a/skills/mnemonic-setup/SKILL.md +++ b/skills/setup/SKILL.md @@ -1,5 +1,5 @@ --- -name: mnemonic-setup +name: setup description: Configure Claude for proactive mnemonic memory behavior without user intervention user-invocable: true allowed-tools: diff --git a/tools/mnemonic-validate b/tools/mnemonic-validate index 0c21619..93563ef 100755 --- a/tools/mnemonic-validate +++ b/tools/mnemonic-validate @@ -2,7 +2,7 @@ """ mnemonic-validate: Validate mnemonic memory files against MIF Level 3 schema. -This tool parses the MIF schema from skills/mnemonic-format/SKILL.md and validates +This tool parses the MIF schema from skills/format/SKILL.md and validates all memory files against it. Usage: @@ -114,7 +114,7 @@ def find_plugin_root() -> Path: def parse_mif_schema(skill_path: Path) -> MIFSchema: - """Parse MIF schema from mnemonic-format SKILL.md.""" + """Parse MIF schema from format SKILL.md.""" content = skill_path.read_text() schema = MIFSchema() @@ -705,7 +705,7 @@ def main(): plugin_root = Path(__file__).parent.parent # Load schema - skill_path = plugin_root / "skills" / "mnemonic-format" / "SKILL.md" + skill_path = plugin_root / "skills" / "format" / "SKILL.md" if not skill_path.exists(): print(f"Error: Cannot find MIF schema at {skill_path}", file=sys.stderr) sys.exit(1)