diff --git a/.aegis/experiments/repository-wide-verification-v1.json b/.aegis/experiments/repository-wide-verification-v1.json new file mode 100644 index 000000000..cbbf18fa2 --- /dev/null +++ b/.aegis/experiments/repository-wide-verification-v1.json @@ -0,0 +1,24 @@ +{ + "admission_executable": {"blob_id":"b9c998ddc85b9beeefec30121e88e828b15a8405","path":"sovereign-omega-v2/scripts/validate-experiment-plan.ts"}, + "admission_workflow": {"blob_id":"01a59d129b0431c9ccb92b1227a0e46992b1562f","path":".github/workflows/experiment-admission.yml"}, + "budget": {"max_cost_microunits":0,"max_duration_seconds":21600,"max_mutations":32}, + "claims_ledger": {"path":".aegis/claims-ledger.json","root":"495a01d7a942d5f90b39f2d2b178b074aee60c5e6460e1622f1917982ac59652"}, + "constitution": {"blob_id":"d0c210443e03313113e43da46c4d98269494baeb","path":"CONSTITUTIONAL_DECLARATION.md"}, + "evidence_tier":"T1", + "execution_class":"EXPERIMENT", + "expected_outputs":["ADMISSION_RECEIPT.json","EVIDENCE_MANIFEST.json","EXPERIMENT_PLAN.json","INTEGRATION_LEDGER.json","INTEGRATION_LEDGER.md","SHA256SUMS"], + "expected_parent_sha":"afe904d0c313691353eae0d5c3ff782a2f740a7f", + "expected_parent_state_root":"7f12fe22431cb3af5b311f28174ca139434966a2d0a3ebed1bc232b246df824c", + "experiment_id":"repository-wide-verification-v1", + "integration_ledger_generator": {"blob_id":"28823ae5b630be273b78210f0addf9c0a86aad05","path":"scripts/integration_ledger.py"}, + "observability": {"cancellation_mechanism":"github-actions-cancel-run","durable_execution_required":true,"emergency_stop_reference":"github-actions:cancel-run","heartbeat_max_seconds":3600,"provider":"github-actions"}, + "operator_approval": {"approval_record_hash":"139577599338a7d056e2b78d41759a0182a1497157cbe93123b839d44fba8c71","authorization_basis":"user-explicit-pa-de-popravi-mi-sve-repository-wide-remediation-without-merge","decided_at":"2026-07-31T17:25:00Z","operator_actor_id":"tarikskalic","operator_session_id":"chatgpt-session-2026-07-31-repository-wide-remediation","required":true,"signature_mode":"GITHUB_OIDC_ATTESTATION","state":"APPROVED"}, + "policy": {"blob_id":"5937cf4d9fc59f224faabfb7865bba7aa5da90dc","path":"docs/rfcs/0001-operator-sovereign-control-plane.md"}, + "replay_package": {"include_admission_receipt":true,"include_evidence_manifest":true,"include_integration_ledger":true,"include_plan":true,"required":true}, + "repository":"Aegis-Omega/AEGIS-OMEGA", + "requested_authority_domains":["github:artifact-metadata-write","github:attestation-write","github:oidc-token-mint","github:repository-content-write","github:workflow-artifact-write"], + "schema_version":"0.1.0", + "sovereignty_contracts": {"blob_id":"d53860f1340293cf08955ebb8729a853432551eb","path":"sovereign-omega-v2/src/sovereignty/contracts.ts"}, + "termination_conditions":["budget_exhausted","observability_expired","operator_emergency_stop"], + "title":"Execute, reconcile, and remediate repository-wide test, lint, constitutional-integrity, dependency, and security-policy evidence" +} diff --git a/.claude.json b/.claude.json index db426975c..1c866fe48 100644 --- a/.claude.json +++ b/.claude.json @@ -9,8 +9,8 @@ "provenance": { "generator": "scripts/build-cognitive-manifest.py", "repository": "Aegis-Omega/AEGIS-OMEGA", - "source_ref": "claude/blissful-rubin-mt9jS", - "parent_state_hash": "410bcd49c721e65050382ae759db7af2f41fa9f572e625174252c72a8748ea93", + "source_ref": "verification/repository-wide-receipt-v1", + "parent_state_hash": "e9f0ec153b0b320a1e791092f73209442ec43a982e503203d9c101ec40949cba", "signature_mode": "GITHUB_OIDC_ATTESTATION" }, "hashing": { @@ -488,5 +488,5 @@ "on_success": "broadcast-attested-verified-event-stream" } }, - "state_hash": "e9f0ec153b0b320a1e791092f73209442ec43a982e503203d9c101ec40949cba" + "state_hash": "036fad30ebc01117e033a99cb1694748a788604f8e2fd689209b2bf517e7aba3" } diff --git a/.github/workflows/production-dependency-audit.yml b/.github/workflows/production-dependency-audit.yml new file mode 100644 index 000000000..6c7eee541 --- /dev/null +++ b/.github/workflows/production-dependency-audit.yml @@ -0,0 +1,86 @@ +name: AEGIS Production Dependency Audit + +on: + pull_request: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: production-audit-${{ github.ref }} + cancel-in-progress: true + +env: + CANDIDATE_SHA: ${{ github.event.pull_request.head.sha || github.sha }} + +jobs: + audit: + name: Production audit · ${{ matrix.surface }} + runs-on: ubuntu-latest + timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + include: + - surface: sovereign-runtime + directory: sovereign-omega-v2 + lockfile: sovereign-omega-v2/package-lock.json + - surface: studio + directory: studio + lockfile: studio/package-lock.json + - surface: mcp-server + directory: sovereign-omega-v2/mcp-server + lockfile: sovereign-omega-v2/mcp-server/package-lock.json + steps: + - name: Checkout exact candidate head + uses: actions/checkout@v4 + with: + ref: ${{ env.CANDIDATE_SHA }} + + - name: Assert exact checkout identity + run: test "$(git rev-parse HEAD)" = "$CANDIDATE_SHA" + + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: npm + cache-dependency-path: ${{ matrix.lockfile }} + + - name: Install locked graph + working-directory: ${{ matrix.directory }} + run: npm ci + + - name: Audit production dependencies + id: audit + working-directory: ${{ matrix.directory }} + shell: bash + run: | + set +e + npm audit --omit=dev --audit-level=high --json > production-audit.json + status=$? + set -e + node - <<'NODE' + const fs = require('node:fs') + const report = JSON.parse(fs.readFileSync('production-audit.json', 'utf8')) + const vulnerabilities = report.metadata?.vulnerabilities ?? {} + console.log(JSON.stringify({ + dependencies: report.metadata?.dependencies ?? null, + vulnerabilities, + }, null, 2)) + NODE + echo "status=$status" >> "$GITHUB_OUTPUT" + + - name: Upload exact audit report + if: always() + uses: actions/upload-artifact@v4 + with: + name: production-audit-${{ matrix.surface }}-${{ env.CANDIDATE_SHA }} + path: ${{ matrix.directory }}/production-audit.json + if-no-files-found: error + retention-days: 90 + + - name: Fail on high or critical production vulnerability + if: ${{ steps.audit.outputs.status != '0' }} + run: exit 1 diff --git a/.github/workflows/repository-verification.yml b/.github/workflows/repository-verification.yml new file mode 100644 index 000000000..c27464b6f --- /dev/null +++ b/.github/workflows/repository-verification.yml @@ -0,0 +1,189 @@ +name: AEGIS Repository-Wide Verification + +on: + pull_request: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: repository-verification-${{ github.ref }} + cancel-in-progress: true + +env: + CANDIDATE_SHA: ${{ github.event.pull_request.head.sha || github.sha }} + PYTHONUNBUFFERED: '1' + +jobs: + verify: + name: Repository verification receipt + runs-on: ubuntu-latest + timeout-minutes: 180 + steps: + - name: Checkout exact candidate head + uses: actions/checkout@v4 + with: + ref: ${{ env.CANDIDATE_SHA }} + fetch-depth: 0 + + - name: Assert exact checkout identity + shell: bash + run: | + set -euo pipefail + actual="$(git rev-parse HEAD)" + test "$actual" = "$CANDIDATE_SHA" + echo "candidate=$actual tree=$(git rev-parse 'HEAD^{tree}')" + + - uses: actions/setup-node@v4 + with: + node-version: '22' + + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + cache: pip + + - uses: dtolnay/rust-toolchain@stable + + - name: Install shared Python verification dependencies + run: | + python -m pip install --upgrade pip + python -m pip install pytest flask flask-cors psutil numpy scikit-learn 'PyYAML==6.0.2' + python -m pip install -r sovereign-omega-v2/python/requirements.txt + + - name: Execute complete named verification corpus + id: corpus + shell: bash + run: | + set -euo pipefail + mkdir -p verification-out verification-final + python -m py_compile scripts/repository_verification.py + + python scripts/repository_verification.py census \ + --output verification-out/definition-census.json \ + --exclusion 'sovereign-omega-v2/python/tests/test_ledger_persist.py=requires approximately 4 GB and real CoreMatrix allocation; explicitly excluded by the current CI contract' \ + --exclusion 'sovereign-omega-v2/python/tests/stress_test.py=performance stress program is not part of the deterministic unit and contract corpus' + + failures=0 + + run_suite() { + suite_id="$1" + parser="$2" + classification="$3" + command="$4" + log="verification-out/${suite_id}.log" + result="verification-out/${suite_id}.json" + + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "SUITE $suite_id" + echo "COMMAND $command" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + + set +e + bash -lc "$command" >"$log" 2>&1 + status=$? + set -e + cat "$log" + + python scripts/repository_verification.py record \ + --suite-id "$suite_id" \ + --suite-command "$command" \ + --parser "$parser" \ + --classification "$classification" \ + --log "$log" \ + --exit-code "$status" \ + --output "$result" + + if [[ "$status" -ne 0 ]]; then + failures=$((failures + 1)) + fi + } + + run_suite rust-cl-psi cargo WIRED \ + 'cd aegis-cl-psi && cargo test --jobs 1 -- --test-threads 1' + + run_suite rust-aegis-runtime cargo WIRED \ + 'cd aegis-runtime && cargo test' + + run_suite rust-hypervisor cargo TESTED_ONLY \ + 'cargo test' + + run_suite rust-constitutional-substrate cargo TESTED_ONLY \ + 'cd crates/constitutional-substrate && cargo test' + + run_suite typescript-sovereign-runtime vitest TESTED_ONLY_MIXED_WITH_WIRED_SHELL \ + 'cd sovereign-omega-v2 && npm ci && npm run test -- --reporter=verbose && npm run typecheck && npm run build' + + run_suite typescript-sovereign-lint none WIRED_QUALITY_GATE \ + 'cd sovereign-omega-v2 && npm ci && npm run lint' + + run_suite constitutional-frozen-hashes none WIRED_CONSTITUTIONAL_INTEGRITY \ + 'node sovereign-omega-v2/scripts/verify-hashes.mjs && (cd sovereign-omega-v2 && node scripts/verify-hashes.mjs)' + + run_suite repository-security-policy none WIRED_POLICY \ + "grep -F '## Repository-Wide Security Invariants' SECURITY.md && grep -F 'deny-by-default' SECURITY.md && grep -F 'These requirements apply to every executable surface' SECURITY.md && grep -F 'A passing test suite proves only the named commands' SECURITY.md" + + run_suite python-bridge pytest WIRED_AND_TESTED_ONLY \ + 'cd sovereign-omega-v2 && python -m pytest -q python/tests --ignore=python/tests/test_ledger_persist.py' + + run_suite python-aegis-interface pytest WIRED \ + 'cd packages/aegis-interface && PYTHONPATH=. python -m pytest -q && PYTHONPATH=. python -m aegis_interface.cli check wit/skill_snapshot.wit --out generated && PYTHONPATH=. python -m aegis_interface.cli evolve --from wit/skill_snapshot.wit --to wit/skill_snapshot_v2.wit && PYTHONPATH=. python -m aegis_interface.cli compose wit/skill_snapshot.wit wit/skill_snapshot_v2.wit wit/skill_snapshot_v3.wit' + + run_suite python-kernel-one unittest WIRED_LOCAL_REFERENCE \ + 'cd kernel-one && python -m py_compile kernel_one.py validator.py init_db.py test_kernel_one.py && python test_kernel_one.py' + + run_suite typescript-mcp-server none WIRED \ + 'cd sovereign-omega-v2/mcp-server && npm ci && npm run test:resources && npm run test:automaton3' + + run_suite cross-runtime-proofs none WIRED_PROOF \ + 'cd genomics && python3 test_replay_proof.py && python3 interpret_demo.py && cd ../verifiable && python3 test_generality.py && cd .. && bash verifiable/cross_language/verify.sh && cd verifiable && python3 certify_all.py --twice' + + run_suite studio-build none WIRED_BUILD_NO_REMOTE_TEST_SCRIPT \ + 'cd studio && npm ci && npm run build' + + set +e + python scripts/repository_verification.py aggregate \ + --input-dir verification-out \ + --required-suite constitutional-frozen-hashes \ + --required-suite cross-runtime-proofs \ + --required-suite python-aegis-interface \ + --required-suite python-bridge \ + --required-suite python-kernel-one \ + --required-suite repository-security-policy \ + --required-suite rust-aegis-runtime \ + --required-suite rust-cl-psi \ + --required-suite rust-constitutional-substrate \ + --required-suite rust-hypervisor \ + --required-suite studio-build \ + --required-suite typescript-mcp-server \ + --required-suite typescript-sovereign-lint \ + --required-suite typescript-sovereign-runtime \ + --json-output verification-final/REPOSITORY_VERIFICATION_RECEIPT.json \ + --markdown-output verification-final/REPOSITORY_VERIFICATION_RECEIPT.md + aggregate_status=$? + set -e + + cat verification-final/REPOSITORY_VERIFICATION_RECEIPT.md >> "$GITHUB_STEP_SUMMARY" + + final_status=0 + if [[ "$failures" -ne 0 || "$aggregate_status" -ne 0 ]]; then + final_status=1 + fi + echo "status=$final_status" >> "$GITHUB_OUTPUT" + + - name: Upload receipt, suite records and complete logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: aegis-repository-verification-${{ env.CANDIDATE_SHA }} + path: | + verification-final/* + verification-out/* + if-no-files-found: error + retention-days: 90 + + - name: Fail closed on incomplete repository evidence + if: ${{ steps.corpus.outputs.status != '0' }} + run: exit 1 diff --git a/.github/workflows/typescript-lint.yml b/.github/workflows/typescript-lint.yml new file mode 100644 index 000000000..6c17c530d --- /dev/null +++ b/.github/workflows/typescript-lint.yml @@ -0,0 +1,44 @@ +name: AEGIS TypeScript Lint + +on: + pull_request: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: typescript-lint-${{ github.ref }} + cancel-in-progress: true + +env: + CANDIDATE_SHA: ${{ github.event.pull_request.head.sha || github.sha }} + +jobs: + lint: + name: TypeScript lint · sovereign runtime + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - name: Checkout exact candidate head + uses: actions/checkout@v4 + with: + ref: ${{ env.CANDIDATE_SHA }} + + - name: Assert exact checkout identity + run: test "$(git rev-parse HEAD)" = "$CANDIDATE_SHA" + + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: npm + cache-dependency-path: sovereign-omega-v2/package-lock.json + + - name: Install locked graph + working-directory: sovereign-omega-v2 + run: npm ci + + - name: Lint complete TypeScript source surface + working-directory: sovereign-omega-v2 + run: npm run lint diff --git a/.github/workflows/typescript-source-lint-repair.yml b/.github/workflows/typescript-source-lint-repair.yml new file mode 100644 index 000000000..d7e54a472 --- /dev/null +++ b/.github/workflows/typescript-source-lint-repair.yml @@ -0,0 +1,80 @@ +name: AEGIS Bounded TypeScript Source Repair + +on: + pull_request: + branches: [main] + paths: + - '.github/workflows/typescript-source-lint-repair.yml' + +permissions: + contents: write + +jobs: + repair: + name: Repair eleven reproducible TypeScript lint errors + if: ${{ github.event.pull_request.head.repo.full_name == github.repository }} + runs-on: ubuntu-latest + timeout-minutes: 90 + env: + HEAD_BRANCH: ${{ github.head_ref }} + EXPECTED_HEAD: ${{ github.event.pull_request.head.sha }} + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ env.HEAD_BRANCH }} + fetch-depth: 0 + token: ${{ github.token }} + + - name: Assert exact writable branch + run: | + set -euo pipefail + test "$(git rev-parse HEAD)" = "$EXPECTED_HEAD" + test -z "$(git status --short)" + + - uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Apply deterministic bounded patch + run: python3 scripts/apply_typescript_lint_repairs.py + + - name: Verify complete TypeScript surface + working-directory: sovereign-omega-v2 + run: | + set -euo pipefail + npm ci + npm run lint + npm run typecheck + npm run test -- --reporter=dot + npm run build + + - name: Enforce exact five-file mutation set + run: | + set -euo pipefail + mapfile -t changed < <(git diff --name-only | sort) + expected=( + 'sovereign-omega-v2/src/api/claude-client.ts' + 'sovereign-omega-v2/src/api/managed-agent-client.ts' + 'sovereign-omega-v2/src/core/ralph-loop.ts' + 'sovereign-omega-v2/src/scale-os/control-plane.ts' + 'sovereign-omega-v2/src/skill-harness/scanner/codebase-scanner.ts' + ) + printf '%s\n' "${changed[@]}" + test "${#changed[@]}" -eq 5 + for i in "${!expected[@]}"; do + test "${changed[$i]}" = "${expected[$i]}" + done + + - name: Commit verified repairs + run: | + set -euo pipefail + git config user.name 'aegis-verification[bot]' + git config user.email 'aegis-verification[bot]@users.noreply.github.com' + git add \ + sovereign-omega-v2/src/api/claude-client.ts \ + sovereign-omega-v2/src/api/managed-agent-client.ts \ + sovereign-omega-v2/src/core/ralph-loop.ts \ + sovereign-omega-v2/src/scale-os/control-plane.ts \ + sovereign-omega-v2/src/skill-harness/scanner/codebase-scanner.ts + git commit -m 'fix(lint): repair typed API and deterministic source boundaries' + git push origin "HEAD:${HEAD_BRANCH}" diff --git a/SECURITY.md b/SECURITY.md index 1aa3e420c..a7d8892dc 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,40 +2,158 @@ ## Supported Versions -Only the `main` branch is supported. There are no versioned releases; fixes land on -`main` and deploy from there. +Only the `main` branch is supported. There are no versioned releases. Security fixes +land through reviewed, exact-head pull requests and deploy from an explicitly admitted +`main` revision. -## Reporting a Vulnerability +## Repository-Wide Security Invariants + +These requirements apply to every executable surface in this repository, including +services, browser applications, CI workflows, Supabase functions, MCP integrations, +commercial tools, scripts, and future components. + +They are acceptance requirements. Their presence here does **not** claim that every +historical or dormant path already complies. + +### Authentication and authorization + +- Consequential, cost-incurring, data-bearing, administrative, notification, mutation, + and model-execution routes must be **deny-by-default**. +- Authentication proves identity; authorization separately proves permission for the + requested resource, action, tenant, and authority domain. +- Anonymous callers must never be able to claim credentials, invoke paid providers, + access customer records, mutate governance state, or trigger owner notifications. +- Development bypasses must be impossible in production and must fail closed when the + environment is missing, malformed, or ambiguous. + +### Inputs, tools, and agent boundaries + +- All external text, files, model output, MCP metadata, tool results, webhook payloads, + and retrieved content are untrusted inputs. +- Tool invocation requires an explicit capability allowlist, least-privilege credentials, + bounded arguments, timeout, rate limit, and auditable principal. +- Prompt content must not grant authority. Instructions discovered in data, webpages, + repositories, messages, or model output cannot override operator or policy authority. +- Consequential actions require an explicit intent boundary and, where applicable, + operator confirmation bound to the exact target and side effects. + +### Webhooks and replay resistance + +- Webhooks must verify signatures over the exact raw request body using a constant-time + comparison and a bounded replay window. +- Event identity or idempotency keys must prevent duplicate side effects. +- Missing secrets, unsupported event types, invalid timestamps, malformed signatures, + and ambiguous account or tier mappings fail closed. + +### Secrets and credentials + +- Secrets must not be committed, logged, embedded in client bundles, returned to models, + included in receipts, or exposed through diagnostic endpoints. +- Production credentials must be scoped to the smallest practical resource and action + set, stored in an approved secret manager, and rotated after suspected exposure. +- Service-role, cloud-admin, signing, deployment, billing, and root credentials must not + be shared with untrusted workloads or general-purpose agents. + +### Data protection + +- Every data access path must enforce tenant and object-level authorization before + retrieval, transformation, or tool exposure. +- Responses and logs must minimize sensitive data and redact credentials, tokens, + payment information, customer records, and private prompts. +- Model and tool outputs must be filtered so that privileged data cannot cross into an + unauthorized principal or execution context. + +### Abuse resistance and resource controls + +- Public and semi-public routes require bounded request sizes, concurrency limits, + rate limits, timeouts, spend ceilings, and safe cancellation. +- Notification systems require authenticated callers, recipient and template allowlists, + deduplication, and anti-spam controls. +- Provider failures, partial writes, retries, and timeout paths must not silently produce + duplicate charges, credentials, notifications, or state transitions. -Report suspected vulnerabilities privately via **GitHub private vulnerability reporting** -for `Aegis-Omega/AEGIS-OMEGA`: repository **Security** tab → **Report a vulnerability**. +### Supply chain and build integrity -Do **not** open public issues or pull requests for undisclosed security problems. +- Production dependency graphs must be lockfile-reproducible and scanned in CI. +- Known high or critical production vulnerabilities block admission unless an explicit, + time-bounded exception identifies the affected path, compensating controls, owner, + and expiry. +- Build, test, policy, and security claims must be bound to an exact commit and must not + be inferred from a different branch, local worktree, historical document, or static + source count. +- Frozen constitutional files and other protected anchors must be verified from any + working directory and fail closed on missing or mismatched bytes. -Include in your report: -- A clear description of the issue and affected component(s) -- Steps to reproduce (proof of concept if available) -- Potential impact and severity assessment -- Any suggested remediation or mitigations +### Auditability and incident evidence -**Response target: 72 hours** for initial acknowledgment and triage. If a report is -accepted we will coordinate fix and disclosure timing with you; if declined we will -explain why. +- Security-relevant decisions must record the authenticated principal, target, policy + result, outcome, and correlation identifier without recording secrets. +- Evidence and receipts must distinguish executed checks, static inventories, skipped + surfaces, deployment state, and runtime authority. +- Security failures must remain visible. Tests, scanners, or policy checks must not be + weakened, excluded, or reclassified merely to obtain a green result. + +## Security Change Requirements + +A security-sensitive change must include, as applicable: + +- regression tests for the vulnerable and permitted paths; +- exact-head build, test, lint, dependency, and constitutional-integrity evidence; +- explicit trust-boundary and authorization analysis; +- migration, rollback, and credential-rotation notes where state or secrets are involved; +- no unrelated runtime, deployment, billing, or authority expansion. + +A passing test suite proves only the named commands at the tested revision. It does not +by itself prove deployment state, live configuration, absence of unknown vulnerabilities, +or permission to deploy or merge. ## Scope In scope: -- The governance bridge service (`sovereign-omega-v2/python/`, deployed as Cloud Run - `aegis-vertex`), including all `/platform/*`, `/claude`, and `/node` endpoints -- The hub storefront (`hub/`, aegisomega.com) and its payment flow -- Supabase edge functions (`supabase/functions/` — payment verification, key issuance, - agent/chat/notify/slack handlers) -- The commercial tools and shared libraries they embed (`packages/shared/`) -Out of scope: sibling research repositories, third-party services themselves -(PayPal/Stripe/Supabase/GCP), and findings that require physical access. +- the governance bridge service (`sovereign-omega-v2/python/`, deployed as Cloud Run + `aegis-vertex`), including `/platform/*`, `/claude`, and `/node` endpoints; +- the TypeScript and Rust governance, verification, consensus, replay, and execution + surfaces under `sovereign-omega-v2/`, `aegis-cl-psi/`, `aegis-runtime/`, and `crates/`; +- the hub storefront (`hub/`, `aegisomega.com`) and payment flow; +- Supabase edge functions (`supabase/functions/`), including payment verification, + credential issuance, agent, chat, notification, and Slack handlers; +- MCP servers, connected-tool boundaries, CI workflows, deployment manifests, operator + surfaces, and commercial tools; +- shared libraries and packages embedded by those systems. + +Out of scope are third-party services themselves, sibling repositories not owned by this +project, social engineering against maintainers, denial-of-service requiring unrealistic +resources, and findings requiring physical access. A vulnerability in this repository's +use or configuration of a third-party service remains in scope. + +## Reporting a Vulnerability + +Report suspected vulnerabilities privately through **GitHub private vulnerability +reporting** for `Aegis-Omega/AEGIS-OMEGA`: repository **Security** tab → +**Report a vulnerability**. + +Do not open a public issue or pull request for an undisclosed vulnerability. + +Include: + +- affected component, revision, route, role, or workflow; +- reproduction steps or a minimal proof of concept; +- required attacker capabilities and trust boundary crossed; +- impact, affected data or authority, and severity rationale; +- suggested remediation or compensating controls, when available. + +Initial acknowledgment and triage target: **72 hours**. Accepted reports will receive a +coordinated remediation and disclosure plan. Declined reports will receive a technical +reason when possible. + +## Safe Harbor + +Good-faith research that avoids privacy violations, service disruption, persistence, +data destruction, credential use beyond what is required to demonstrate the issue, and +access to unrelated accounts will not be pursued by the project. Stop testing and report +immediately if sensitive data or active credentials are encountered. ## Bounty -There is no bounty program. Good-faith reports are appreciated and will be credited on -request. +There is no bounty program. Good-faith reporters may be credited on request. diff --git a/scripts/apply_typescript_lint_repairs.py b/scripts/apply_typescript_lint_repairs.py new file mode 100644 index 000000000..4012d78c0 --- /dev/null +++ b/scripts/apply_typescript_lint_repairs.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python3 +"""Apply the bounded TypeScript lint repair set for PR #248. + +This script is intentionally temporary. Every replacement asserts the expected +preimage count and exits before writing the affected file if the preimage does +not match the admitted source state. +""" + +from pathlib import Path +import textwrap + + +def replace_exact(path: str, old: str, new: str, expected: int = 1) -> None: + target = Path(path) + text = target.read_text(encoding="utf-8") + count = text.count(old) + if count != expected: + raise SystemExit( + f"{path}: expected {expected} matches, found {count}: {old!r}" + ) + target.write_text(text.replace(old, new), encoding="utf-8") + + +replace_exact( + "sovereign-omega-v2/src/api/claude-client.ts", + " input_tokens: (event as any).usage?.input_tokens ?? 0,", + """ input_tokens: + 'input_tokens' in event.usage && typeof event.usage.input_tokens === 'number' + ? event.usage.input_tokens + : 0,""", +) + +managed_path = Path("sovereign-omega-v2/src/api/managed-agent-client.ts") +managed = managed_path.read_text(encoding="utf-8") + +config_marker = """export interface ManagedAgentClientConfig { + readonly apiKey?: string + readonly agentId?: string // pre-existing agent to reuse +} +""" +wire_types = """export interface ManagedAgentClientConfig { + readonly apiKey?: string + readonly agentId?: string // pre-existing agent to reuse +} + +interface ManagedAgentWireRecord { + readonly id: string +} + +interface ManagedSessionWireRecord { + readonly id: string + readonly agent_id?: string + readonly status?: AgentSession['status'] + readonly created_at?: string +} + +interface ManagedSessionWireEvent { + readonly type?: SessionEvent['type'] + readonly content?: unknown +} + +type ManagedSessionWireStream = AsyncIterable + +interface ManagedAnthropicExtension { + readonly beta: { + readonly agents: { + create(input: unknown): Promise + } + readonly sessions: { + create(input: unknown): Promise + stream(sessionId: string): ManagedSessionWireStream | null | Promise + createEvent(sessionId: string, event: unknown): Promise + retrieve(sessionId: string): Promise + } + } +} +""" +if managed.count(config_marker) != 1: + raise SystemExit("managed-agent-client.ts: config marker mismatch") +managed = managed.replace(config_marker, wire_types, 1) + +replacements = { + "(this._client as any).beta?.agents?.create": "this.managedClient().beta.agents.create", + "(this._client as any).beta?.sessions?.create": "this.managedClient().beta.sessions.create", + "(this._client as any).beta?.sessions?.stream": "this.managedClient().beta.sessions.stream", + "(this._client as any).beta?.sessions?.createEvent": "this.managedClient().beta.sessions.createEvent", + "(this._client as any).beta?.sessions?.retrieve": "this.managedClient().beta.sessions.retrieve", +} +replaced_casts = 0 +for old, new in replacements.items(): + count = managed.count(old) + replaced_casts += count + managed = managed.replace(old, new) +if replaced_casts != 6 or "as any" in managed: + raise SystemExit( + f"managed-agent-client.ts: expected 6 any-cast replacements, got {replaced_casts}" + ) + +method_marker = "\n /** Create or retrieve the AEGIS constitutional agent. Returns agent_id. */" +helper = """ + private managedClient(): ManagedAnthropicExtension { + return this._client as unknown as ManagedAnthropicExtension + } + + /** Create or retrieve the AEGIS constitutional agent. Returns agent_id. */""" +if managed.count(method_marker) != 1: + raise SystemExit("managed-agent-client.ts: method marker mismatch") +managed = managed.replace(method_marker, helper, 1) + +cause_line = " `Ensure your API key has Managed Agents access.`" +if managed.count(cause_line) != 1: + raise SystemExit("managed-agent-client.ts: cause line mismatch") +managed = managed.replace( + cause_line, + """ `Ensure your API key has Managed Agents access.`, + { cause: err },""", + 1, +) +managed_path.write_text(managed, encoding="utf-8") + +ralph_path = Path("sovereign-omega-v2/src/core/ralph-loop.ts") +ralph = ralph_path.read_text(encoding="utf-8") +ralph_changes = [ + ( + " const loop = this\n", + " const cycleNumber = this._cycleNumber\n const targetScale = this.targetScale\n", + ), + (" harmonize(gateResult) {", " harmonize: (gateResult) => {"), + (" cycle_number: loop._cycleNumber,", " cycle_number: cycleNumber,"), + (" target_scale: loop.targetScale,", " target_scale: targetScale,"), + (" loop.cycles.push(cycle)", " this.cycles.push(cycle)"), +] +for old, new in ralph_changes: + if ralph.count(old) != 1: + raise SystemExit(f"ralph-loop.ts marker mismatch: {old!r}") + ralph = ralph.replace(old, new, 1) +ralph_path.write_text(ralph, encoding="utf-8") + +replace_exact( + "sovereign-omega-v2/src/scale-os/control-plane.ts", + "const IDENTIFIER_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:@/+\\-]{1,255}$/", + "const IDENTIFIER_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:@/+-]{1,255}$/", +) + +replace_exact( + "sovereign-omega-v2/src/skill-harness/scanner/codebase-scanner.ts", + " let content = ''", + " let content: string", +) diff --git a/scripts/repository_verification.py b/scripts/repository_verification.py new file mode 100644 index 000000000..4244061e2 --- /dev/null +++ b/scripts/repository_verification.py @@ -0,0 +1,299 @@ +#!/usr/bin/env python3 +"""Create deterministic repository-wide verification evidence. + +The collector keeps static definitions, executed tests, and exclusions separate. +A source-pattern count is never represented as a passing-test count. +""" +from __future__ import annotations + +import argparse +import hashlib +import json +import os +from pathlib import Path +import re +import subprocess +import sys +from typing import Any, Iterable, Sequence + +SCHEMA_VERSION = "1.0.0" +RESULT_KIND = "AEGIS_VERIFICATION_SUITE_RESULT_V1" +CENSUS_KIND = "AEGIS_TEST_DEFINITION_CENSUS_V1" +RECEIPT_KIND = "AEGIS_REPOSITORY_VERIFICATION_RECEIPT_V1" +ANSI = re.compile(r"\x1b\[[0-?]*[ -/]*[@-~]") + + +def canonical(value: Any) -> str: + return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def digest(value: Any) -> str: + return hashlib.sha256(canonical(value).encode("utf-8")).hexdigest() + + +def git(*args: str) -> str: + result = subprocess.run( + ["git", *args], capture_output=True, text=True, timeout=120, check=False + ) + if result.returncode: + raise RuntimeError(result.stderr.strip() or f"git {' '.join(args)} failed") + return result.stdout.strip() + + +def identity() -> tuple[str, str]: + return git("rev-parse", "HEAD"), git("rev-parse", "HEAD^{tree}") + + +def tracked(pattern: str) -> list[Path]: + output = git("ls-files", pattern) + return [Path(line) for line in output.splitlines() if line] + + +def count_definitions(paths: Iterable[Path], pattern: re.Pattern[str]) -> tuple[int, int]: + count = files = 0 + for path in paths: + try: + text = path.read_text(encoding="utf-8") + except (OSError, UnicodeError): + continue + files += 1 + count += sum(bool(pattern.search(line)) for line in text.splitlines()) + return count, files + + +def build_census(exclusions: list[dict[str, str]]) -> dict[str, Any]: + rust, rust_files = count_definitions( + tracked("*.rs"), re.compile(r"^\s*#\[(?:tokio::)?test\]") + ) + typescript, ts_files = count_definitions( + tracked("*.ts") + tracked("*.tsx"), re.compile(r"^\s*(?:it|test)\s*\(") + ) + python, py_files = count_definitions( + tracked("*.py"), re.compile(r"^\s*def\s+test_[A-Za-z0-9_]*\s*\(") + ) + commit, tree = identity() + body: dict[str, Any] = { + "schema_version": SCHEMA_VERSION, + "artifact_kind": CENSUS_KIND, + "repository": os.getenv("GITHUB_REPOSITORY", "Aegis-Omega/AEGIS-OMEGA"), + "commit_sha": commit, + "tree_sha": tree, + "definition_counts": { + "python": {"definitions": python, "files_scanned": py_files}, + "rust": {"definitions": rust, "files_scanned": rust_files}, + "typescript": {"definitions": typescript, "files_scanned": ts_files}, + }, + "definition_total": rust + typescript + python, + "exclusions": sorted(exclusions, key=lambda item: item["path"]), + "warning": "Static definitions are not executed-test evidence.", + } + body["census_digest"] = digest(body) + return body + + +def clean(log: str) -> str: + return ANSI.sub("", log).replace("\r", "") + + +def parse_cargo(log: str) -> tuple[int | None, int | None]: + matches = re.findall( + r"test result:\s+(?:ok|FAILED)\.\s+(\d+) passed;\s+(\d+) failed;\s+(\d+) ignored", + clean(log), + ) + if not matches: + return None, None + return sum(int(row[0]) for row in matches), sum(int(row[2]) for row in matches) + + +def parse_vitest(log: str) -> tuple[int | None, int | None]: + matches = re.findall( + r"\bTests\s+(\d+)\s+passed(?:\s*\|\s*(\d+)\s+skipped)?", + clean(log), + ) + if not matches: + return None, None + passed, skipped = matches[-1] + return int(passed), int(skipped or 0) + + +def parse_pytest(log: str) -> tuple[int | None, int | None]: + matches = re.findall( + r"(?:^|\s)(\d+) passed(?:,\s*(\d+) skipped)?", clean(log), re.MULTILINE + ) + if not matches: + return None, None + passed, skipped = matches[-1] + return int(passed), int(skipped or 0) + + +def parse_unittest(log: str) -> tuple[int | None, int | None]: + matches = re.findall(r"Ran\s+(\d+)\s+tests?", clean(log)) + return (int(matches[-1]), 0) if matches else (None, None) + + +def parse_log(parser: str, log: str) -> tuple[int | None, int | None]: + functions = { + "cargo": parse_cargo, + "pytest": parse_pytest, + "unittest": parse_unittest, + "vitest": parse_vitest, + "none": lambda _: (None, None), + } + return functions[parser](log) + + +def build_result(args: argparse.Namespace) -> dict[str, Any]: + path = Path(args.log) + log = path.read_text(encoding="utf-8", errors="replace") if path.exists() else "" + passed, skipped = parse_log(args.parser, log) + commit, tree = identity() + body: dict[str, Any] = { + "schema_version": SCHEMA_VERSION, + "artifact_kind": RESULT_KIND, + "suite_id": args.suite_id, + "classification": args.classification, + "status": "PASSED" if args.exit_code == 0 else "FAILED", + "exit_code": args.exit_code, + "command": args.suite_command, + "parser": args.parser, + "executed_tests": passed, + "skipped_tests": skipped, + "commit_sha": commit, + "tree_sha": tree, + "log_sha256": hashlib.sha256(log.encode("utf-8")).hexdigest(), + } + body["result_digest"] = digest(body) + return body + + +def read_documents(root: Path) -> list[dict[str, Any]]: + documents: list[dict[str, Any]] = [] + for path in sorted(root.rglob("*.json")): + try: + value = json.loads(path.read_text(encoding="utf-8")) + except (OSError, json.JSONDecodeError): + continue + if isinstance(value, dict): + documents.append(value) + return documents + + +def aggregate(root: Path, required: Sequence[str]) -> tuple[dict[str, Any], str]: + documents = read_documents(root) + census = next((item for item in documents if item.get("artifact_kind") == CENSUS_KIND), None) + results = [item for item in documents if item.get("artifact_kind") == RESULT_KIND] + by_id = {str(item.get("suite_id")): item for item in results} + missing = sorted(set(required) - set(by_id)) + failed = sorted(key for key, item in by_id.items() if item.get("status") != "PASSED") + commits = sorted({str(item.get("commit_sha")) for item in results}) + trees = sorted({str(item.get("tree_sha")) for item in results}) + identity_valid = len(commits) == 1 and len(trees) == 1 + parsed = [item for item in results if isinstance(item.get("executed_tests"), int)] + complete = census is not None and not missing and not failed and identity_valid + body: dict[str, Any] = { + "schema_version": SCHEMA_VERSION, + "artifact_kind": RECEIPT_KIND, + "epistemic_status": "EXECUTION_EVIDENCE", + "repository": os.getenv("GITHUB_REPOSITORY", "Aegis-Omega/AEGIS-OMEGA"), + "commit_sha": commits[0] if identity_valid else None, + "tree_sha": trees[0] if identity_valid else None, + "status": "VERIFIED" if complete else "INCOMPLETE_OR_FAILED", + "required_suites": sorted(required), + "observed_suites": sorted(by_id), + "missing_suites": missing, + "failed_suites": failed, + "executed_test_total_known": sum(int(item["executed_tests"]) for item in parsed), + "skipped_test_total_known": sum(int(item.get("skipped_tests") or 0) for item in parsed), + "suites_with_unparsed_assertion_count": sorted( + str(item.get("suite_id")) for item in results if item.get("executed_tests") is None + ), + "definition_census": census, + "suite_results": sorted(results, key=lambda item: str(item.get("suite_id"))), + "authority_boundary": { + "grants_runtime_authority": False, + "proves_deployment_state": False, + "proves_only_named_commands_at_commit": True, + }, + } + body["receipt_digest"] = digest(body) + lines = [ + "# AEGIS Repository Verification Receipt", + "", + f"- Status: **{body['status']}**", + f"- Commit: `{body['commit_sha']}`", + f"- Executed tests with parsed counts: **{body['executed_test_total_known']}**", + f"- Skipped tests with parsed counts: **{body['skipped_test_total_known']}**", + f"- Static definitions found: **{census.get('definition_total') if census else 'MISSING'}**", + f"- Receipt digest: `{body['receipt_digest']}`", + "", + "| Suite | Status | Executed | Skipped |", + "|---|---:|---:|---:|", + ] + for item in body["suite_results"]: + lines.append( + f"| `{item['suite_id']}` | {item['status']} | " + f"{item['executed_tests'] if item['executed_tests'] is not None else 'UNPARSED'} | " + f"{item['skipped_tests'] if item['skipped_tests'] is not None else 'UNPARSED'} |" + ) + if missing: + lines += ["", f"Missing suites: `{', '.join(missing)}`"] + if failed: + lines += ["", f"Failed suites: `{', '.join(failed)}`"] + lines += [ + "", + "> This receipt reports named commands at one exact commit. Static definitions, " + "unparsed contract assertions, exclusions, deployment state, and runtime authority remain separate.", + "", + ] + return body, "\n".join(lines) + + +def write_json(path: Path, value: Any) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(json.dumps(value, ensure_ascii=False, indent=2, sort_keys=True) + "\n", encoding="utf-8") + + +def arguments(argv: Sequence[str]) -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + commands = parser.add_subparsers(dest="command", required=True) + census = commands.add_parser("census") + census.add_argument("--output", required=True) + census.add_argument("--exclusion", action="append", default=[]) + record = commands.add_parser("record") + record.add_argument("--suite-id", required=True) + record.add_argument("--suite-command", required=True) + record.add_argument("--parser", choices=["cargo", "pytest", "unittest", "vitest", "none"], required=True) + record.add_argument("--log", required=True) + record.add_argument("--exit-code", type=int, required=True) + record.add_argument("--classification", required=True) + record.add_argument("--output", required=True) + final = commands.add_parser("aggregate") + final.add_argument("--input-dir", required=True) + final.add_argument("--required-suite", action="append", default=[]) + final.add_argument("--json-output", required=True) + final.add_argument("--markdown-output", required=True) + return parser.parse_args(argv) + + +def main(argv: Sequence[str] | None = None) -> int: + args = arguments(argv or sys.argv[1:]) + if args.command == "census": + exclusions = [] + for raw in args.exclusion: + path, separator, reason = raw.partition("=") + if not separator or not path or not reason: + raise ValueError("--exclusion requires path=reason") + exclusions.append({"path": path, "reason": reason}) + write_json(Path(args.output), build_census(exclusions)) + return 0 + if args.command == "record": + write_json(Path(args.output), build_result(args)) + return 0 + receipt, markdown = aggregate(Path(args.input_dir), args.required_suite) + write_json(Path(args.json_output), receipt) + Path(args.markdown_output).write_text(markdown, encoding="utf-8") + return 0 if receipt["status"] == "VERIFIED" else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/sovereign-omega-v2/eslint.config.js b/sovereign-omega-v2/eslint.config.js new file mode 100644 index 000000000..3bd8479b8 --- /dev/null +++ b/sovereign-omega-v2/eslint.config.js @@ -0,0 +1,34 @@ +import js from '@eslint/js' +import globals from 'globals' +import tseslint from 'typescript-eslint' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores([ + 'coverage/**', + 'dist/**', + 'node_modules/**', + ]), + { + files: ['src/**/*.{ts,tsx}'], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + ], + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + globals: { + ...globals.browser, + ...globals.node, + }, + }, + rules: { + '@typescript-eslint/no-unused-vars': ['error', { + argsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + varsIgnorePattern: '^_', + }], + }, + }, +]) diff --git a/sovereign-omega-v2/mcp-server/package-lock.json b/sovereign-omega-v2/mcp-server/package-lock.json index 202cf830d..22d26aa92 100644 --- a/sovereign-omega-v2/mcp-server/package-lock.json +++ b/sovereign-omega-v2/mcp-server/package-lock.json @@ -1,14 +1,14 @@ { "name": "@aegis/mcp-server", - "version": "0.1.0", + "version": "0.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@aegis/mcp-server", - "version": "0.1.0", + "version": "0.2.0", "dependencies": { - "@modelcontextprotocol/sdk": "^1.12.1" + "@modelcontextprotocol/sdk": "1.30.0" }, "bin": { "aegis-mcp": "dist/index.js" @@ -462,24 +462,24 @@ } }, "node_modules/@hono/node-server": { - "version": "1.19.14", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz", - "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.0.12.tgz", + "integrity": "sha512-eWpQYr67tqJLeaSUl0Q+TquuYfUdTibpOJlUMV2FfUP7+KqCC5TufnwnlXL6mobZBJbGAYRd7ZvEBDCbLInjhg==", "license": "MIT", "engines": { - "node": ">=18.14.1" + "node": ">=20" }, "peerDependencies": { "hono": "^4" } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.29.0.tgz", - "integrity": "sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==", + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.30.0.tgz", + "integrity": "sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA==", "license": "MIT", "dependencies": { - "@hono/node-server": "^1.19.9", + "@hono/node-server": "^1.19.9 || ^2.0.5", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", @@ -570,20 +570,20 @@ } }, "node_modules/body-parser": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", - "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", + "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", "license": "MIT", "dependencies": { "bytes": "^3.1.2", - "content-type": "^1.0.5", + "content-type": "^2.0.0", "debug": "^4.4.3", - "http-errors": "^2.0.0", - "iconv-lite": "^0.7.0", + "http-errors": "^2.0.1", + "iconv-lite": "^0.7.2", "on-finished": "^2.4.1", - "qs": "^6.14.1", - "raw-body": "^3.0.1", - "type-is": "^2.0.1" + "qs": "^6.15.2", + "raw-body": "^3.0.2", + "type-is": "^2.1.0" }, "engines": { "node": ">=18" @@ -593,6 +593,19 @@ "url": "https://opencollective.com/express" } }, + "node_modules/body-parser/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -933,9 +946,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz", + "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==", "funding": [ { "type": "github", @@ -1085,9 +1098,9 @@ } }, "node_modules/hono": { - "version": "4.12.25", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.25.tgz", - "integrity": "sha512-2NFaIyNVgJmBs/ecmtGzlmluTFs5cHEWGTdu0t1HBwYzoGXOL5nUQBRMXsXWla5i4KkG//QMzVP88m1+I3fdAQ==", + "version": "4.12.32", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.32.tgz", + "integrity": "sha512-XcuyW9qE2kJn07PkecMOBd5Vq/hMy7mmGw+idz1yblbg9N17ijJODrvPkn7/dwL3Kulj8LcRJ69DLOWf91dRUg==", "license": "MIT", "engines": { "node": ">=16.9.0" diff --git a/sovereign-omega-v2/mcp-server/package.json b/sovereign-omega-v2/mcp-server/package.json index 652332bb6..b938616d5 100644 --- a/sovereign-omega-v2/mcp-server/package.json +++ b/sovereign-omega-v2/mcp-server/package.json @@ -4,7 +4,9 @@ "description": "AEGIS constitutional agent swarm — MCP server", "type": "module", "main": "dist/index.js", - "bin": { "aegis-mcp": "dist/index.js" }, + "bin": { + "aegis-mcp": "dist/index.js" + }, "scripts": { "build": "tsc", "start": "node dist/index.js", @@ -13,11 +15,11 @@ "test:automaton3": "npm run build && node test/automaton3-authority.mjs" }, "dependencies": { - "@modelcontextprotocol/sdk": "^1.12.1" + "@modelcontextprotocol/sdk": "1.30.0" }, "devDependencies": { "@types/node": "^22.10.0", - "typescript": "^5.5.0", - "tsx": "^4.15.0" + "tsx": "^4.15.0", + "typescript": "^5.5.0" } } diff --git a/sovereign-omega-v2/package-lock.json b/sovereign-omega-v2/package-lock.json index 7d66eb650..f5565d581 100644 --- a/sovereign-omega-v2/package-lock.json +++ b/sovereign-omega-v2/package-lock.json @@ -16,6 +16,7 @@ "uuid": "^14.0.0" }, "devDependencies": { + "@eslint/js": "10.0.1", "@types/node": "^25.8.0", "@types/react": "^18.3.1", "@types/react-dom": "^18.3.1", @@ -23,12 +24,14 @@ "@vitejs/plugin-react": "^6.0.3", "@vitest/coverage-v8": "^4.1.6", "autoprefixer": "^10.4.20", - "eslint": "^9.9.0", + "eslint": "10.3.0", "fake-indexeddb": "^6.2.5", + "globals": "17.6.0", "jsdom": "^29.1.1", "postcss": "^8.4.41", "tailwindcss": "^3.4.10", "typescript": "^5.5.3", + "typescript-eslint": "8.59.2", "vite": "^8.0.16", "vitest": "^4.1.6" } @@ -375,9 +378,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", + "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", "dev": true, "license": "MIT", "dependencies": { @@ -417,105 +420,89 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", - "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.7", + "@eslint/object-schema": "^3.0.5", "debug": "^4.3.1", - "minimatch": "^3.1.5" + "minimatch": "^10.2.4" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.5.tgz", + "integrity": "sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.17.0" + "@eslint/core": "^1.2.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@types/json-schema": "^7.0.15" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", - "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.14.0", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.1", - "minimatch": "^3.1.5", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/js": { - "version": "9.39.4", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", - "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", "dev": true, "license": "MIT", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", + "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.17.0", + "@eslint/core": "^1.2.1", "levn": "^0.4.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@exodus/bytes": { @@ -1023,6 +1010,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", @@ -1082,6 +1076,236 @@ "dev": true, "license": "MIT" }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.2.tgz", + "integrity": "sha512-j/bwmkBvHUtPNxzuWe5z6BEk3q54YRyGlBXkSsmfoih7zNrBvl5A9A98anlp/7JbyZcWIJ8KXo/3Tq/DjFLtuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.59.2", + "@typescript-eslint/type-utils": "8.59.2", + "@typescript-eslint/utils": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.59.2", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz", + "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.2.tgz", + "integrity": "sha512-plR3pp6D+SSUn1HM7xvSkx12/DhoHInI2YF35KAcVFNZvlC0gtrWqx7Qq1oH2Ssgi0vlFRCTbP+DZc7B9+TtsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.2.tgz", + "integrity": "sha512-+2hqvEkeyf/0FBor67duF0Ll7Ot8jyKzDQOSrxazF/danillRq2DwR9dLptsXpoZQqxE1UisSmoZewrlPas9Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.59.2", + "@typescript-eslint/types": "^8.59.2", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.2.tgz", + "integrity": "sha512-JzfyEpEtOU89CcFSwyNS3mu4MLvLSXqnmX05+aKBDM+TdR5jzcGOEBwxwGNxrEQ7p/z6kK2WyioCGBf2zZBnvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.2.tgz", + "integrity": "sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.2.tgz", + "integrity": "sha512-nhqaj1nmTdVVl/BP5omXNRGO38jn5iosis2vbdmupF2txCf8ylWT8lx+JlvMYYVqzGVKtjojUFoQ3JRWK+mfzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2", + "@typescript-eslint/utils": "8.59.2", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.2.tgz", + "integrity": "sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.2.tgz", + "integrity": "sha512-o0XPGNwcWw+FIwStOWn+BwBuEmL6QXP0rsvAFg7ET1dey1Nr6Wb1ac8p5HEsK0ygO/6mUxlk+YWQD9xcb/nnXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.59.2", + "@typescript-eslint/tsconfig-utils": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.2.tgz", + "integrity": "sha512-Juw3EinkXqjaffxz6roowvV7GZT/kET5vSKKZT6upl5TXdWkLkYmNPXwDDL2Vkt2DPn0nODIS4egC/0AGxKo/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.2.tgz", + "integrity": "sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.2", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@vitejs/plugin-react": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.3.tgz", @@ -1253,9 +1477,9 @@ } }, "node_modules/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", "dev": true, "license": "MIT", "bin": { @@ -1292,22 +1516,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", @@ -1336,13 +1544,6 @@ "dev": true, "license": "MIT" }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -1410,11 +1611,14 @@ } }, "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } }, "node_modules/baseline-browser-mapping": { "version": "2.10.30", @@ -1453,14 +1657,16 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", - "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" } }, "node_modules/braces": { @@ -1510,16 +1716,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/camelcase-css": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", @@ -1561,23 +1757,6 @@ "node": ">=18" } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -1616,26 +1795,6 @@ "node": ">= 6" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -1646,13 +1805,6 @@ "node": ">= 6" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -1840,33 +1992,30 @@ } }, "node_modules/eslint": { - "version": "9.39.4", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", - "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.3.0.tgz", + "integrity": "sha512-XbEXaRva5cF0ZQB8w6MluHA0kZZfV2DuCMJ3ozyEOHLwDpZX2Lmm/7Pp0xdJmI0GL1W05VH5VwIFHEm1Vcw2gw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.2", - "@eslint/config-helpers": "^0.4.2", - "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.5", - "@eslint/js": "9.39.4", - "@eslint/plugin-kit": "^0.4.1", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.5.5", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", - "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", @@ -1876,8 +2025,7 @@ "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.5", + "minimatch": "^10.2.4", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -1885,7 +2033,7 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://eslint.org/donate" @@ -1900,48 +2048,50 @@ } }, "node_modules/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.15.0", + "acorn": "^8.16.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" + "eslint-visitor-keys": "^5.0.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" @@ -2148,9 +2298,9 @@ } }, "node_modules/flatted": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", - "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", + "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", "dev": true, "license": "ISC" }, @@ -2207,9 +2357,9 @@ } }, "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.6.0.tgz", + "integrity": "sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==", "dev": true, "license": "MIT", "engines": { @@ -2278,23 +2428,6 @@ "node": ">= 4" } }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -2436,29 +2569,6 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "license": "MIT" }, - "node_modules/js-yaml": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", - "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/puzrin" - }, - { - "type": "github", - "url": "https://github.com/sponsors/nodeca" - } - ], - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/jsdom": { "version": "29.1.1", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.1.1.tgz", @@ -2865,13 +2975,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -2922,19 +3025,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-dir/node_modules/semver": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", - "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/mdn-data": { "version": "2.27.1", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", @@ -2967,16 +3057,19 @@ } }, "node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^5.0.8" }, "engines": { - "node": "*" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/ms": { @@ -3122,19 +3215,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/parse5": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", @@ -3506,16 +3586,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -3607,6 +3677,19 @@ "loose-envify": "^1.1.0" } }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -3671,19 +3754,6 @@ "dev": true, "license": "MIT" }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/sucrase": { "version": "3.35.1", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", @@ -3941,6 +4011,19 @@ "integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==", "license": "MIT" }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", @@ -3983,6 +4066,30 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.59.2.tgz", + "integrity": "sha512-pJw051uomb3ZeCzGTpRb8RbEqB5Y4WWet8gl/GcTlU35BSx0PVdZ86/bqkQCyKKuraVQEK7r6kBHQXF+fBhkoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.59.2", + "@typescript-eslint/parser": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2", + "@typescript-eslint/utils": "8.59.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, "node_modules/undici": { "version": "7.28.0", "resolved": "https://registry.npmjs.org/undici/-/undici-7.28.0.tgz", diff --git a/sovereign-omega-v2/package.json b/sovereign-omega-v2/package.json index 7e7e6ceaa..df19c6732 100644 --- a/sovereign-omega-v2/package.json +++ b/sovereign-omega-v2/package.json @@ -26,6 +26,7 @@ "uuid": "^14.0.0" }, "devDependencies": { + "@eslint/js": "10.0.1", "@types/node": "^25.8.0", "@types/react": "^18.3.1", "@types/react-dom": "^18.3.1", @@ -33,12 +34,14 @@ "@vitejs/plugin-react": "^6.0.3", "@vitest/coverage-v8": "^4.1.6", "autoprefixer": "^10.4.20", - "eslint": "^9.9.0", + "eslint": "10.3.0", "fake-indexeddb": "^6.2.5", + "globals": "17.6.0", "jsdom": "^29.1.1", "postcss": "^8.4.41", "tailwindcss": "^3.4.10", "typescript": "^5.5.3", + "typescript-eslint": "8.59.2", "vite": "^8.0.16", "vitest": "^4.1.6" } diff --git a/sovereign-omega-v2/python/requirements.txt b/sovereign-omega-v2/python/requirements.txt index 32fd243ae..a1f9eadf9 100644 --- a/sovereign-omega-v2/python/requirements.txt +++ b/sovereign-omega-v2/python/requirements.txt @@ -1,3 +1,5 @@ anthropic[vertex]>=0.52.0 google-auth>=2.0.0 +jsonschema>=4.23.0 psutil>=5.9.0 +redis>=5.2.0 diff --git a/sovereign-omega-v2/python/tests/conftest.py b/sovereign-omega-v2/python/tests/conftest.py new file mode 100644 index 000000000..642be65d7 --- /dev/null +++ b/sovereign-omega-v2/python/tests/conftest.py @@ -0,0 +1,28 @@ +"""Pytest collection boundary for the mixed Python verification corpus. + +Historical AEGIS contract tests include executable scripts that intentionally run +at module load and terminate with ``sys.exit``. Importing those files as pytest +modules aborts collection even when the script reports success. They are not +silently skipped: ``test_standalone_contract_scripts.py`` executes each one in an +isolated subprocess and binds its exit status and output to a pytest result. +""" +from __future__ import annotations + +from pathlib import Path + +_WRAPPER = "test_standalone_contract_scripts.py" + + +def is_standalone_contract_script(path: Path) -> bool: + if path.name == _WRAPPER or not path.name.startswith("test_") or path.suffix != ".py": + return False + try: + source = path.read_text(encoding="utf-8") + except OSError: + return False + return "sys.exit(" in source + + +def pytest_ignore_collect(collection_path: Path, config): # type: ignore[no-untyped-def] + del config + return is_standalone_contract_script(Path(collection_path)) diff --git a/sovereign-omega-v2/python/tests/test_standalone_contract_scripts.py b/sovereign-omega-v2/python/tests/test_standalone_contract_scripts.py new file mode 100644 index 000000000..0c0c63010 --- /dev/null +++ b/sovereign-omega-v2/python/tests/test_standalone_contract_scripts.py @@ -0,0 +1,37 @@ +"""Execute legacy standalone contract tests without importing them into pytest.""" +from __future__ import annotations + +from pathlib import Path +import subprocess +import sys + +import pytest + +from conftest import is_standalone_contract_script + +TEST_DIRECTORY = Path(__file__).resolve().parent +STANDALONE_SCRIPTS = tuple( + path + for path in sorted(TEST_DIRECTORY.glob("test_*.py")) + if is_standalone_contract_script(path) +) + + +@pytest.mark.parametrize( + "script_path", + STANDALONE_SCRIPTS, + ids=lambda path: path.name, +) +def test_standalone_contract_script(script_path: Path) -> None: + completed = subprocess.run( + [sys.executable, str(script_path)], + cwd=TEST_DIRECTORY.parent, + capture_output=True, + text=True, + timeout=300, + check=False, + ) + output = "\n".join(part for part in (completed.stdout, completed.stderr) if part) + assert completed.returncode == 0, ( + f"standalone contract script failed: {script_path.name}\n{output}" + ) diff --git a/sovereign-omega-v2/scripts/verify-hashes.mjs b/sovereign-omega-v2/scripts/verify-hashes.mjs index a8f299028..37a62c7d7 100644 --- a/sovereign-omega-v2/scripts/verify-hashes.mjs +++ b/sovereign-omega-v2/scripts/verify-hashes.mjs @@ -1,17 +1,20 @@ #!/usr/bin/env node // ============================================================ // SOVEREIGN OMEGA — Frozen File Hash Verification -// Run before any session that touches constitutional files. +// CWD-independent: resolves constitutional files relative to this script. // // Exit codes: // 0 — all files present and hash-correct -// 1 — at least one file present but hash WRONG (constitutional violation) -// 2 — at least one file absent (not yet authored; /guardian decision pending) -// A missing constitutional file is NOT the same as a passing check. +// 1 — at least one file present but hash WRONG +// 2 — at least one required file absent // ============================================================ -import { createHash } from 'crypto' -import { readFileSync, existsSync } from 'fs' +import { createHash } from 'node:crypto' +import { existsSync, readFileSync } from 'node:fs' +import { dirname, resolve } from 'node:path' +import { fileURLToPath } from 'node:url' + +const RUNTIME_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..') const FROZEN_FILES = { 'python/gate.py': 'bbe942b819594fd522b421bb9d3aa084735a873d526f35a1e782f31346f3d0fc', @@ -22,37 +25,38 @@ const FROZEN_FILES = { let hashFailed = false let filesMissing = false -for (const [file, expectedHash] of Object.entries(FROZEN_FILES)) { - if (!existsSync(file)) { - console.warn(` WARN: ${file} — file not present; constitutional check INCOMPLETE`) +for (const [relativePath, expectedHash] of Object.entries(FROZEN_FILES)) { + const absolutePath = resolve(RUNTIME_ROOT, relativePath) + + if (!existsSync(absolutePath)) { + console.error(` MISSING: ${relativePath}`) filesMissing = true continue } - const content = readFileSync(file) - const actualHash = createHash('sha256').update(content).digest('hex') + + const actualHash = createHash('sha256') + .update(readFileSync(absolutePath)) + .digest('hex') + if (actualHash === expectedHash) { - console.log(` OK: ${file}`) + console.log(` OK: ${relativePath}`) } else { - console.error(` FAIL: ${file}`) - console.error(` Expected: ${expectedHash}`) - console.error(` Got: ${actualHash}`) + console.error(` FAIL: ${relativePath}`) + console.error(` Expected: ${expectedHash}`) + console.error(` Got: ${actualHash}`) hashFailed = true } } if (hashFailed) { - console.error('\n[FROZEN FILE VIOLATION] One or more constitutional files have been modified.') - console.error('Requires /guardian APPROVED verdict before proceeding.') + console.error('\n[FROZEN FILE VIOLATION] Constitutional bytes differ from the approved hashes.') + console.error('A new hash may be admitted only through an explicit, evidence-bound constitutional change.') process.exit(1) } if (filesMissing) { - console.warn('\n[CONSTITUTIONAL FILES ABSENT] gate.py / dna.py / router.py do not exist.') - console.warn('Integrity check is INCOMPLETE — not a pass.') - console.warn('Operator must decide: migrate from sovereign-omega/ or author new implementations.') - console.warn('Creation requires /guardian APPROVED verdict.') + console.error('\n[CONSTITUTIONAL FILES MISSING] Integrity verification is incomplete and fails closed.') process.exit(2) } -console.log('\nAll frozen files present and hash-verified.') - +console.log(`\nAll frozen files present and hash-verified under ${RUNTIME_ROOT}.`) diff --git a/sovereign-omega-v2/src/api/claude-client.ts b/sovereign-omega-v2/src/api/claude-client.ts index 4d68da33f..3451dc57b 100644 --- a/sovereign-omega-v2/src/api/claude-client.ts +++ b/sovereign-omega-v2/src/api/claude-client.ts @@ -173,7 +173,10 @@ export class ConstitutionalClaudeClient { delta: '', is_final: false, usage: { - input_tokens: (event as any).usage?.input_tokens ?? 0, + input_tokens: + 'input_tokens' in event.usage && typeof event.usage.input_tokens === 'number' + ? event.usage.input_tokens + : 0, output_tokens: event.usage.output_tokens, }, } diff --git a/sovereign-omega-v2/src/api/managed-agent-client.ts b/sovereign-omega-v2/src/api/managed-agent-client.ts index eacb49f30..a1cb5e9e9 100644 --- a/sovereign-omega-v2/src/api/managed-agent-client.ts +++ b/sovereign-omega-v2/src/api/managed-agent-client.ts @@ -61,6 +61,38 @@ export interface ManagedAgentClientConfig { readonly agentId?: string // pre-existing agent to reuse } +interface ManagedAgentWireRecord { + readonly id: string +} + +interface ManagedSessionWireRecord { + readonly id: string + readonly agent_id?: string + readonly status?: AgentSession['status'] + readonly created_at?: string +} + +interface ManagedSessionWireEvent { + readonly type?: SessionEvent['type'] + readonly content?: unknown +} + +type ManagedSessionWireStream = AsyncIterable + +interface ManagedAnthropicExtension { + readonly beta: { + readonly agents: { + create(input: unknown): Promise + } + readonly sessions: { + create(input: unknown): Promise + stream(sessionId: string): ManagedSessionWireStream | null | Promise + createEvent(sessionId: string, event: unknown): Promise + retrieve(sessionId: string): Promise + } + } +} + // ─── Client ─────────────────────────────────────────────── export class ManagedAgentClient { @@ -77,12 +109,16 @@ export class ManagedAgentClient { this._agentId = config.agentId ?? null } + private managedClient(): ManagedAnthropicExtension { + return this._client as unknown as ManagedAnthropicExtension + } + /** Create or retrieve the AEGIS constitutional agent. Returns agent_id. */ async ensureAgent(): Promise { if (this._agentId) return this._agentId try { - const agent = await (this._client as any).beta?.agents?.create({ + const agent = await this.managedClient().beta.agents.create({ name: AEGIS_AGENT_DEFINITION.name, model: AEGIS_AGENT_DEFINITION.model, system_prompt: AEGIS_AGENT_DEFINITION.system_prompt, @@ -98,7 +134,8 @@ export class ManagedAgentClient { // Managed agents may not be available in all regions/tiers throw new Error( `[MANAGED_AGENT] Failed to create agent: ${String(err)}. ` + - `Ensure your API key has Managed Agents access.` + `Ensure your API key has Managed Agents access.`, + { cause: err }, ) } } @@ -107,7 +144,7 @@ export class ManagedAgentClient { async startSession(task: string): Promise { const agentId = await this.ensureAgent() - const session = await (this._client as any).beta?.sessions?.create({ + const session = await this.managedClient().beta.sessions.create({ agent_id: agentId, initial_message: task, }) @@ -123,7 +160,7 @@ export class ManagedAgentClient { /** Stream events from a running session. */ async *streamSession(sessionId: string): AsyncGenerator { - const stream = await (this._client as any).beta?.sessions?.stream(sessionId) + const stream = await this.managedClient().beta.sessions.stream(sessionId) if (!stream) { yield { @@ -147,7 +184,7 @@ export class ManagedAgentClient { /** Send a follow-up message to a running session. */ async sendEvent(sessionId: string, message: string): Promise { - await (this._client as any).beta?.sessions?.createEvent(sessionId, { + await this.managedClient().beta.sessions.createEvent(sessionId, { type: 'user', content: message, }) @@ -155,7 +192,7 @@ export class ManagedAgentClient { /** Get the current status of a session. */ async getSession(sessionId: string): Promise { - const session = await (this._client as any).beta?.sessions?.retrieve(sessionId) + const session = await this.managedClient().beta.sessions.retrieve(sessionId) return { session_id: session.id, /* c8 ignore next -- SDK always provides agent_id; ?? fallbacks structurally unreachable */ @@ -169,7 +206,7 @@ export class ManagedAgentClient { /** Interrupt a running session. */ async interrupt(sessionId: string): Promise { - await (this._client as any).beta?.sessions?.createEvent(sessionId, { + await this.managedClient().beta.sessions.createEvent(sessionId, { type: 'interrupt', }) } diff --git a/sovereign-omega-v2/src/core/ralph-loop.ts b/sovereign-omega-v2/src/core/ralph-loop.ts index c6d665963..543edbdf0 100644 --- a/sovereign-omega-v2/src/core/ralph-loop.ts +++ b/sovereign-omega-v2/src/core/ralph-loop.ts @@ -69,17 +69,18 @@ export class RalphLoop { const links: string[] = [] const patches: RalphPatch[] = [] - const loop = this + const cycleNumber = this._cycleNumber + const targetScale = this.targetScale const builder: RalphCycleBuilder = { addFinding(f) { findings.push(f); return builder }, addAnalysisNote(n) { analysisNotes.push(n); return builder }, addLink(d) { links.push(d); return builder }, addPatch(p) { patches.push(p); return builder }, - harmonize(gateResult) { + harmonize: (gateResult) => { const cycle = deepFreeze({ cycle_id: cycleId as UUIDv7, - cycle_number: loop._cycleNumber, - target_scale: loop.targetScale, + cycle_number: cycleNumber, + target_scale: targetScale, phase: RalphPhase.HARMONIZE, findings: findings.map(f => f.description), analysis_notes: analysisNotes, @@ -89,7 +90,7 @@ export class RalphLoop { gate_result: gateResult, sequence, }) - loop.cycles.push(cycle) + this.cycles.push(cycle) return cycle }, } diff --git a/sovereign-omega-v2/src/scale-os/control-plane.ts b/sovereign-omega-v2/src/scale-os/control-plane.ts index abd99ca7b..002c3d083 100644 --- a/sovereign-omega-v2/src/scale-os/control-plane.ts +++ b/sovereign-omega-v2/src/scale-os/control-plane.ts @@ -97,7 +97,7 @@ const SHA256_PATTERN = /^[0-9a-f]{64}$/ const PUBLIC_KEY_PATTERN = /^[0-9a-f]{64}$/ const SIGNATURE_PATTERN = /^[0-9a-f]{128}$/ const DECIMAL_PATTERN = /^(0|[1-9][0-9]*)$/ -const IDENTIFIER_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:@/+\-]{1,255}$/ +const IDENTIFIER_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:@/+-]{1,255}$/ const ISO8601_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/ const EVENT_TYPES = new Set([ diff --git a/sovereign-omega-v2/src/skill-harness/scanner/codebase-scanner.ts b/sovereign-omega-v2/src/skill-harness/scanner/codebase-scanner.ts index 6ae849991..da7d79f61 100644 --- a/sovereign-omega-v2/src/skill-harness/scanner/codebase-scanner.ts +++ b/sovereign-omega-v2/src/skill-harness/scanner/codebase-scanner.ts @@ -98,7 +98,7 @@ function walkDir(root: string, rel = ''): FileStat[] { const ext = path.extname(entry.name).toLowerCase() if (!EXT_DOMAINS[ext]) continue const absPath = path.join(absDir, entry.name) - let content = '' + let content: string try { const raw = fs.readFileSync(absPath, 'utf-8') content = raw.length > 32_000 ? raw.slice(0, 32_000) : raw diff --git a/studio/package-lock.json b/studio/package-lock.json index a6015271d..509d82894 100644 --- a/studio/package-lock.json +++ b/studio/package-lock.json @@ -10,7 +10,7 @@ "dependencies": { "autoprefixer": "^10.5.0", "lucide-react": "^1.16.0", - "postcss": "^8.5.14", + "postcss": "8.5.18", "react": "^19.2.6", "react-dom": "^19.2.6", "tailwindcss": "^3.4.19" @@ -1359,9 +1359,9 @@ } }, "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "version": "8.5.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.18.tgz", + "integrity": "sha512-xdB1oSLHbz1vRWgCDalrCqEFTWzFlhqFC5tIHLMOSUIjhm3XXQ1qrFy8S/ESr1JYRRXqM3c1QFiMZUJdUTqyMQ==", "funding": [ { "type": "opencollective", diff --git a/studio/package.json b/studio/package.json index 07447f36a..8f59ce30b 100644 --- a/studio/package.json +++ b/studio/package.json @@ -11,7 +11,7 @@ "dependencies": { "autoprefixer": "^10.5.0", "lucide-react": "^1.16.0", - "postcss": "^8.5.14", + "postcss": "8.5.18", "react": "^19.2.6", "react-dom": "^19.2.6", "tailwindcss": "^3.4.19"