diff --git a/.github/workflows/governance-gates.yml b/.github/workflows/governance-gates.yml index a5bb376..b503e8d 100644 --- a/.github/workflows/governance-gates.yml +++ b/.github/workflows/governance-gates.yml @@ -8,6 +8,8 @@ on: jobs: gates: uses: ./.github/workflows/reusable-governance-gates.yml + with: + audit_omit_dev: true secrets: inherit notify-org-control-loop: diff --git a/.github/workflows/reusable-governance-gates.yml b/.github/workflows/reusable-governance-gates.yml index b1c6143..6f905ee 100644 --- a/.github/workflows/reusable-governance-gates.yml +++ b/.github/workflows/reusable-governance-gates.yml @@ -7,6 +7,10 @@ on: required: false type: boolean default: true + audit_omit_dev: + required: false + type: boolean + default: false permissions: contents: read @@ -90,7 +94,7 @@ jobs: run: npm ci - name: Dependency Audit (High+) if: ${{ steps.lockfile.outputs.present == 'true' }} - run: npm audit --audit-level=high + run: npm audit --audit-level=high ${{ inputs.audit_omit_dev && '--omit=dev' || '' }} - name: Skip Dependency Audit (no package-lock.json) if: ${{ steps.lockfile.outputs.present != 'true' }} run: echo "No package-lock.json found; skipping dependency audit." diff --git a/CLAUDE.md b/CLAUDE.md index 4f30d06..539c7e5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -92,7 +92,7 @@ Three modes: - `src/lib/dispute-sync.ts` — Dispute ↔ Notion ↔ TriageAgent sync coordinator - `src/routes/bridge/index.ts` — Inter-service bridge (scrape, ledger, finance, Plaid) - `src/routes/bridge/disputes.ts` — Dispute-Notion manual sync bridge -- `src/routes/mcp.ts` — MCP server for Claude integration (48 tools) +- `src/routes/mcp.ts` — MCP server for Claude integration (50 tools) - `src/routes/meta.ts` — Public canon/schema/beacon + authenticated whoami - `src/routes/connect.ts` — ChittyConnect discovery proxy (rate-limited) - `src/routes/ledger.ts` — ChittyLedger evidence/custody passthrough @@ -137,7 +137,7 @@ Example client-side MCP configuration (conceptual): } ``` -The server exposes 48 tools across 12 domains: +The server exposes 50 tools across 12 domains: **Core meta** — `get_canon_info`, `get_registry_status`, `get_schema_refs`, `whoami`, `get_context_summary` **Financial** — `query_obligations`, `query_accounts`, `query_disputes`, `get_recommendations`, `get_cash_position`, `get_cashflow_projections`, `query_revenue_sources`, `get_payment_plan` diff --git a/templates/governance-baseline/.github/workflows/reusable-governance-gates.yml b/templates/governance-baseline/.github/workflows/reusable-governance-gates.yml index 5ebc75c..6f905ee 100644 --- a/templates/governance-baseline/.github/workflows/reusable-governance-gates.yml +++ b/templates/governance-baseline/.github/workflows/reusable-governance-gates.yml @@ -7,6 +7,10 @@ on: required: false type: boolean default: true + audit_omit_dev: + required: false + type: boolean + default: false permissions: contents: read @@ -20,8 +24,8 @@ jobs: shell: bash run: | set -euo pipefail - secrets_in_use="$(grep -RhoE 'secrets\.[A-Za-z_][A-Za-z0-9_]*' .github/workflows \ - | sed -E 's/.*secrets\.([A-Za-z_][A-Za-z0-9_]*).*/\1/' \ + secrets_in_use="$(grep -RhoE '\$\{\{\s*secrets(\.[A-Za-z_][A-Za-z0-9_]*|\['"'"'\"[A-Za-z_][A-Za-z0-9_]*'"'"'\"\])\s*\}\}' .github/workflows \ + | sed -E "s/.*secrets[.\['\"]([A-Za-z_][A-Za-z0-9_]*).*/\1/" \ | sort -u || true)" if [[ -z "${secrets_in_use}" ]]; then @@ -90,7 +94,7 @@ jobs: run: npm ci - name: Dependency Audit (High+) if: ${{ steps.lockfile.outputs.present == 'true' }} - run: npm audit --audit-level=high + run: npm audit --audit-level=high ${{ inputs.audit_omit_dev && '--omit=dev' || '' }} - name: Skip Dependency Audit (no package-lock.json) if: ${{ steps.lockfile.outputs.present != 'true' }} run: echo "No package-lock.json found; skipping dependency audit." diff --git a/tests/mcp.test.ts b/tests/mcp.test.ts index 1f536b2..f207113 100644 --- a/tests/mcp.test.ts +++ b/tests/mcp.test.ts @@ -141,13 +141,13 @@ describe('MCP — tools/list', () => { expect(tools.length).toBeGreaterThanOrEqual(1); }); - it('exposes exactly 48 tools', async () => { + it('exposes exactly 50 tools', async () => { const { post } = buildApp(); const res = await post({ jsonrpc: '2.0', id: 1, method: 'tools/list' }); const json = await res.json() as Record; const result = json.result as Record; const tools = result.tools as unknown[]; - expect(tools.length).toBe(48); + expect(tools.length).toBe(50); }); it('each tool has a name and inputSchema', async () => { diff --git a/ui/package-lock.json b/ui/package-lock.json index 9c36b7a..4e9a4c0 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -13,6 +13,7 @@ "react": "^18.3.0", "react-dom": "^18.3.0", "react-grid-layout": "^2.2.2", + "react-is": "^19.2.5", "react-router-dom": "^6.23.0", "recharts": "^3.7.0", "tailwind-merge": "^2.3.0" @@ -2644,11 +2645,10 @@ } }, "node_modules/react-is": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.4.tgz", - "integrity": "sha512-W+EWGn2v0ApPKgKKCy/7s7WHXkboGcsrXE+2joLyVxkbyVQfO3MUEaUQDHoSmb8TFFrSKYa9mw64WZHNHSDzYA==", - "license": "MIT", - "peer": true + "version": "19.2.5", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.5.tgz", + "integrity": "sha512-Dn0t8IQhCmeIT3wu+Apm1/YVsJXsGWi6k4sPdnBIdqMVtHtv0IGi6dcpNpNkNac0zB2uUAqNX3MHzN8c+z2rwQ==", + "license": "MIT" }, "node_modules/react-redux": { "version": "9.2.0", diff --git a/ui/package.json b/ui/package.json index becf7ac..27d18ba 100644 --- a/ui/package.json +++ b/ui/package.json @@ -14,6 +14,7 @@ "react": "^18.3.0", "react-dom": "^18.3.0", "react-grid-layout": "^2.2.2", + "react-is": "^19.2.5", "react-router-dom": "^6.23.0", "recharts": "^3.7.0", "tailwind-merge": "^2.3.0"