{
  "checker": {
    "claims": [
      {
        "claim": "The optional ecc-memory-mcp server exposes save, search, read, and doctor tools",
        "command": "ecc-memory-mcp tools/call {\"tool\": \"memory_save\", \"arguments\": {\"title\": \"Cache policy note\", \"body\": \"Use a 300 second TTL for the session cache.\", \"kind\": \"note\"}}",
        "evidence": "Cache policy note\\\",\\n    \\\"kind\\\": \\\"note\\\",\\n    \\\"scope\\\": \\\"project\\\",\\n    \\\"trust\\\": \\\"unreviewed\\\",\\n    \\\"status\\\": \\\"active\\\",\\n    \\\"sourceHarness\\\": \\\"codex\\\",\\n    \\\"targetHarnesses\\\": [\\n      \\\"all\\\"\\n    ],\\n    \\\"tags\\\": [],\\n    \\\"links\\\": [],\\n    \\\"createdAt\\\": \\\"2026-10-23T17:42:12.643Z\\\",\\n    \\\"updatedAt\\\": \\\"2026-10-23T17:42:12.643Z\\\"\\n  }\\n}\"}]}",
        "expected": "saved memory returned with its title",
        "input": "{\"tool\": \"memory_save\", \"arguments\": {\"title\": \"Cache policy note\", \"body\": \"Use a 300 second TTL for the session cache.\", \"kind\": \"note\"}}",
        "kind": "claim",
        "outcome": "Real input produced the expected result: Cache policy note",
        "source": "The optional `ecc-memory-mcp` server exposes the same bounded save, search, read, and doctor surface without enabling itself by default.",
        "source_checked": true,
        "source_file": "README.md",
        "verdict": "yes"
      },
      {
        "claim": "ecc memory search returns active project memories from the vault",
        "command": "ecc memory search 'authentication migration' --target-harness codex",
        "evidence": "Continue authentication migration (score 38)\n  Continue the authentication migration: move session tokens to httpOnly cookies, then update the login tests.\n",
        "expected": "the saved handoff is listed",
        "input": "ecc memory search \"authentication migration\" --target-harness codex",
        "kind": "claim",
        "outcome": "Real input produced the expected result: Continue authentication migration",
        "returncode": 0,
        "source": "Normal search recall returns active project and team memories.",
        "source_checked": true,
        "source_file": "README.md",
        "verdict": "yes"
      }
    ],
    "cycle_checks": [
      {
        "claim": "Scheduled or looping main behavior",
        "command": "",
        "evidence": "Inspected README and entry points (scripts/ecc.js, scripts/memory-mcp.mjs, scripts/loop-status.js, package.json bin list). No README cron, scheduler, loop, --once/--now or webhook trigger exists; loop-status.js only reads transcripts for stale ScheduleWakeup waits and is not a product scheduler. CI schedules are not product cycles.",
        "expected": "identify the product trigger",
        "input": "source inspection",
        "kind": "cycle",
        "outcome": "Inspected README and entry points (scripts/ecc.js, scripts/memory-mcp.mjs, scripts/loop-status.js, package.json bin list). No README cron, scheduler, loop, --once/--now or webhook trigger exists; loop-status.js only reads transcripts for stale ScheduleWakeup waits and is not a product scheduler. CI schedules are not product cycles.",
        "source": "repository entry points",
        "verdict": "yes"
      }
    ],
    "details": {
      "argv": [
        "ecc-memory-mcp"
      ],
      "kind": "mcp",
      "scope": "product operation",
      "serverInfo": {
        "name": "ecc-memory-vault",
        "version": "1.0.0"
      },
      "tool_result": {
        "content": [
          {
            "text": "{\n  \"memory\": {\n    \"schema\": \"ecc.memory.v1\",\n    \"id\": \"mem_20261023_b1d7f0993574451eacca\",\n    \"title\": \"Cache policy note\",\n    \"kind\": \"note\",\n    \"scope\": \"project\",\n    \"trust\": \"unreviewed\",\n    \"status\": \"active\",\n    \"sourceHarness\": \"codex\",\n    \"targetHarnesses\": [\n      \"all\"\n    ],\n    \"tags\": [],\n    \"links\": [],\n    \"createdAt\": \"2026-10-23T17:42:12.322Z\",\n    \"updatedAt\": \"2026-10-23T17:42:12.322Z\"\n  }\n}",
            "type": "text"
          }
        ]
      },
      "tool_result_checked": true,
      "tool_schema_bytes": 2332,
      "tools": [
        "memory_save",
        "memory_search",
        "memory_read",
        "memory_doctor"
      ],
      "working": true
    },
    "evidence_strength": "readme_checked",
    "example_checks": [
      {
        "claim": "Documented unit tests for utils pass",
        "command": "node tests/lib/utils.test.js",
        "deferred": false,
        "evidence": "y string for non-string input\n  \u2713 preserves string with no ANSI codes\n  \u2713 handles CSI with question mark parameter (DEC private modes)\n\n=== Test Results ===\nPassed: 195\nFailed: 0\nTotal:  195\n\n[readStdinJson] stdin exceeded 100 bytes; input truncated and treated as empty\n[readStdinJson] stdin exceeded 100 bytes; input truncated and treated as empty\n[readStdinJson] stdin exceeded 100 bytes; input truncated and treated as empty\n[Utils] replaceInFile failed for /tmp/utils-test-readonly-1792777339146/readonly.txt: EACCES: permission denied, open '/tmp/utils-test-readonly-1792777339146/readonly.txt'",
        "expected": "Passed: 195, Failed: 0",
        "input": "none",
        "kind": "example",
        "outcome": "command completed successfully",
        "returncode": 0,
        "source": "README.md Running Tests: node tests/lib/utils.test.js",
        "verdict": "yes"
      },
      {
        "claim": "Documented package-manager tests pass",
        "command": "node tests/lib/package-manager.test.js",
        "deferred": false,
        "evidence": "object Object]\"\n\nRound 109: getExecCommand (path traversal in binary \u2014 SAFE_NAME_REGEX permits ../ in binary name):\n \u2713 getExecCommand accepts ../../../etc/passwd as binary because SAFE_NAME_REGEX allows ../\n\nRound 108: getRunCommand (path traversal \u2014 SAFE_NAME_REGEX permits ../ via allowed / and . chars):\n \u2713 getRunCommand accepts @scope/../../evil because SAFE_NAME_REGEX allows ../\n\nRound 111: getExecCommand (newline in args \u2014 SAFE_ARGS_REGEX \\s matches \\n):\n \u2713 getExecCommand accepts newline in args because SAFE_ARGS_REGEX includes newline\n\n=== Test Results ===\nPassed: 116\nFailed: 0\nTotal: 116",
        "expected": "Passed: 116, Failed: 0",
        "input": "none",
        "kind": "example",
        "outcome": "command completed successfully",
        "returncode": 0,
        "source": "README.md Running Tests: node tests/lib/package-manager.test.js",
        "verdict": "yes"
      },
      {
        "claim": "Documented hooks tests pass",
        "command": "node tests/hooks/hooks.test.js",
        "deferred": false,
        "evidence": "\nRound 94: session-end.js (tools used without files modified):\n  \u2713 session file includes Tools Used but omits Files Modified when only Read/Grep used\n\nRound 95: pre-compact.js (transcript_path provided + ECC_SKIP_LLM_SUMMARY=1 \u2014 LLM skipped):\n  \u2713 pre-compact falls back to compaction log entry when ECC_SKIP_LLM_SUMMARY=1\n\nRound 95: session-end.js (ECC_LLM_SUMMARY_INTERVAL \u2014 controls LLM trigger cadence):\n  \u2713 session-end triggers LLM when totalMessages % interval === 0\n  \u2713 session-end does NOT trigger LLM when totalMessages % interval !== 0\n\n=== Test Results ===\nPassed: 258\nFailed: 0\nTotal:  258",
        "expected": "Passed: 258, Failed: 0",
        "input": "none",
        "kind": "example",
        "outcome": "command completed successfully",
        "returncode": 0,
        "source": "README.md Running Tests: node tests/hooks/hooks.test.js",
        "verdict": "yes"
      },
      {
        "claim": "Memory vault doctor passes after init and handoff",
        "command": "ecc memory doctor",
        "deferred": false,
        "evidence": "ECC memory doctor: PASS\nMemories: 8\nInvalid files: 0\nDuplicate IDs: 0\nBroken links: 0\nSkipped symlinks: 0",
        "expected": "ECC memory doctor: PASS",
        "input": "none",
        "kind": "example",
        "outcome": "command completed successfully",
        "returncode": 0,
        "source": "README.md Share context between harnesses: ecc memory doctor",
        "verdict": "yes"
      }
    ],
    "status": "PASS"
  },
  "deviations": [
    "Guest apt Node was v18.19.1 (README needs 18+). Installed Node 20.19.0 per .tool-versions into /tmp/node20 and used it for npm install and tests.",
    "npm install under Node 20 still printed EBADENGINE warnings for some dev dependencies that declare node >=22; install still exited 0.",
    "README's 'npm install -g <email>' (published package) was replaced with 'npm install -g --prefix /tmp/ecc-global .' from this checkout, so the ecc and ecc-memory-mcp bins match this snapshot. Both are on PATH via /tmp/ecc-global/bin.",
    "node tests/run-all.js did not finish within the 900s limit (exit 124). Its output reached hooks/pre-bash-commit-quality.test.js and stopped there, so the full suite was not established. Substitute: the three test files listed in README 'Running Tests' were run individually and all passed.",
    "npx <email> setup and ./install.sh were not run. They change Claude Code / user config, need Claude Code CLI 2.1+ on PATH, and are interactive. Claude Code is not installed in this guest.",
    "Replay wrote additional memories into /tmp/ecc-demo/.ecc/memory/project (create-only writes, expected)."
  ],
  "fault_owner": null,
  "main_blocker": null,
  "operation": "Run the ECC (ecc-universal 2.2.3) Memory Vault: init a project vault, save and search a handoff with the ecc CLI, and save/search memories through the ecc-memory-mcp stdio server; run the README's documented unit test files.",
  "operation_scope": "Pinned commit 90606c8315ee09cafc303515c5f33024db6b9882, Ubuntu 24.04 guest, Node 20.19.0 (from .tool-versions), npm 9.2.0. Memory operations run in scratch project /tmp/ecc-demo. The Claude Code plugin install (npx <email> setup, ./install.sh) was not run; it needs Claude Code CLI 2.1+ and an interactive session.",
  "outcome": "working",
  "plain_failure": null,
  "steps": [
    "git init; git remote add origin https://github.com/affaan-m/ECC; git fetch --depth 1 origin 90606c8315ee09cafc303515c5f33024db6b9882; git reset --mixed FETCH_HEAD",
    "sudo apt-get install -y nodejs npm (provided Node v18.19.1)",
    "npm install --prefix /tmp/node20 <email> (Node 20.19.0 for .tool-versions)",
    "PATH=/tmp/node20/node_modules/.bin:$PATH npm install (in checkout)",
    "PATH=/tmp/node20/node_modules/.bin:$PATH npm install -g --prefix /tmp/ecc-global .",
    "node tests/run-all.js (timed out after 900s, exit 124)",
    "node tests/lib/utils.test.js (Passed: 195, Failed: 0)",
    "node tests/lib/package-manager.test.js (Passed: 116, Failed: 0)",
    "node tests/hooks/hooks.test.js (Passed: 258, Failed: 0)",
    "ecc memory init --scope project (in /tmp/ecc-demo)",
    "ecc memory handoff --from hermes --target codex --title \"Continue authentication migration\" --body-file ./handoff.md",
    "ecc memory search \"authentication migration\" --target-harness codex",
    "ecc memory doctor (ECC memory doctor: PASS)",
    "ecc-memory-mcp over stdio: tools/call memory_save (Cache policy note) and memory_search (returned the saved memory)",
    "<env-var>=<guest-path> python3 -I <guest-path> --validate --replay (valid, replay PASS)"
  ],
  "stuck_step": null,
  "suggested_fix": "Make run-all.js finish or identify the hanging test (it stopped after hooks/pre-bash-commit-quality.test.js). Document Node 20 as the required runtime, since several dev dependencies reject Node 18. Document the local-checkout global install path for the Memory Vault bins."
}
