@aria_asi/cli 0.2.26 → 0.2.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLIENT-ONBOARDING.md +282 -0
- package/bin/aria.js +1140 -14
- package/dist/aria-connector/src/auth-commands.d.ts +1 -0
- package/dist/aria-connector/src/auth-commands.d.ts.map +1 -1
- package/dist/aria-connector/src/auth-commands.js +89 -41
- package/dist/aria-connector/src/auth-commands.js.map +1 -1
- package/dist/aria-connector/src/chat.d.ts +3 -0
- package/dist/aria-connector/src/chat.d.ts.map +1 -1
- package/dist/aria-connector/src/chat.js +146 -8
- package/dist/aria-connector/src/chat.js.map +1 -1
- package/dist/aria-connector/src/codebase-scanner.d.ts +2 -2
- package/dist/aria-connector/src/codebase-scanner.d.ts.map +1 -1
- package/dist/aria-connector/src/codebase-scanner.js +1 -1
- package/dist/aria-connector/src/codebase-scanner.js.map +1 -1
- package/dist/aria-connector/src/config.d.ts +12 -0
- package/dist/aria-connector/src/config.d.ts.map +1 -1
- package/dist/aria-connector/src/config.js +2 -0
- package/dist/aria-connector/src/config.js.map +1 -1
- package/dist/aria-connector/src/connectors/claude-code.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/claude-code.js +80 -24
- package/dist/aria-connector/src/connectors/claude-code.js.map +1 -1
- package/dist/aria-connector/src/connectors/codebase-awareness.d.ts +37 -0
- package/dist/aria-connector/src/connectors/codebase-awareness.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/codebase-awareness.js +335 -0
- package/dist/aria-connector/src/connectors/codebase-awareness.js.map +1 -0
- package/dist/aria-connector/src/connectors/codex.d.ts +3 -0
- package/dist/aria-connector/src/connectors/codex.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/codex.js +248 -0
- package/dist/aria-connector/src/connectors/codex.js.map +1 -0
- package/dist/aria-connector/src/connectors/cognitive-skills.d.ts +2 -0
- package/dist/aria-connector/src/connectors/cognitive-skills.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/cognitive-skills.js +47 -0
- package/dist/aria-connector/src/connectors/cognitive-skills.js.map +1 -0
- package/dist/aria-connector/src/connectors/opencode.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/opencode.js +90 -4
- package/dist/aria-connector/src/connectors/opencode.js.map +1 -1
- package/dist/aria-connector/src/connectors/repo-git-hooks.d.ts +3 -0
- package/dist/aria-connector/src/connectors/repo-git-hooks.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/repo-git-hooks.js +87 -0
- package/dist/aria-connector/src/connectors/repo-git-hooks.js.map +1 -0
- package/dist/aria-connector/src/connectors/repo-guard.d.ts +19 -0
- package/dist/aria-connector/src/connectors/repo-guard.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/repo-guard.js +509 -0
- package/dist/aria-connector/src/connectors/repo-guard.js.map +1 -0
- package/dist/aria-connector/src/connectors/runtime.d.ts +2 -0
- package/dist/aria-connector/src/connectors/runtime.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/runtime.js +330 -0
- package/dist/aria-connector/src/connectors/runtime.js.map +1 -0
- package/dist/aria-connector/src/connectors/shell.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/shell.js +78 -13
- package/dist/aria-connector/src/connectors/shell.js.map +1 -1
- package/dist/aria-connector/src/connectors/syncd.d.ts +27 -0
- package/dist/aria-connector/src/connectors/syncd.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/syncd.js +405 -0
- package/dist/aria-connector/src/connectors/syncd.js.map +1 -0
- package/dist/aria-connector/src/decisions.d.ts +207 -0
- package/dist/aria-connector/src/decisions.d.ts.map +1 -0
- package/dist/aria-connector/src/decisions.js +291 -0
- package/dist/aria-connector/src/decisions.js.map +1 -0
- package/dist/aria-connector/src/garden-control-plane.d.ts.map +1 -1
- package/dist/aria-connector/src/garden-control-plane.js +74 -17
- package/dist/aria-connector/src/garden-control-plane.js.map +1 -1
- package/dist/aria-connector/src/github-connect.d.ts +18 -0
- package/dist/aria-connector/src/github-connect.d.ts.map +1 -0
- package/dist/aria-connector/src/github-connect.js +117 -0
- package/dist/aria-connector/src/github-connect.js.map +1 -0
- package/dist/aria-connector/src/harness-client.d.ts +15 -0
- package/dist/aria-connector/src/harness-client.d.ts.map +1 -1
- package/dist/aria-connector/src/harness-client.js +106 -3
- package/dist/aria-connector/src/harness-client.js.map +1 -1
- package/dist/aria-connector/src/hive-client.d.ts +30 -0
- package/dist/aria-connector/src/hive-client.d.ts.map +1 -1
- package/dist/aria-connector/src/hive-client.js +124 -5
- package/dist/aria-connector/src/hive-client.js.map +1 -1
- package/dist/aria-connector/src/index.d.ts +13 -2
- package/dist/aria-connector/src/index.d.ts.map +1 -1
- package/dist/aria-connector/src/index.js +10 -1
- package/dist/aria-connector/src/index.js.map +1 -1
- package/dist/aria-connector/src/lib/aristotle-noor-wire.d.ts +102 -0
- package/dist/aria-connector/src/lib/aristotle-noor-wire.d.ts.map +1 -0
- package/dist/aria-connector/src/lib/aristotle-noor-wire.js +231 -0
- package/dist/aria-connector/src/lib/aristotle-noor-wire.js.map +1 -0
- package/dist/aria-connector/src/providers/types.d.ts +5 -0
- package/dist/aria-connector/src/providers/types.d.ts.map +1 -1
- package/dist/aria-connector/src/runtime-proof.d.ts +45 -0
- package/dist/aria-connector/src/runtime-proof.d.ts.map +1 -0
- package/dist/aria-connector/src/runtime-proof.js +340 -0
- package/dist/aria-connector/src/runtime-proof.js.map +1 -0
- package/dist/aria-connector/src/self-update.d.ts +2 -1
- package/dist/aria-connector/src/self-update.d.ts.map +1 -1
- package/dist/aria-connector/src/self-update.js +84 -8
- package/dist/aria-connector/src/self-update.js.map +1 -1
- package/dist/aria-connector/src/setup-wizard.d.ts.map +1 -1
- package/dist/aria-connector/src/setup-wizard.js +34 -2
- package/dist/aria-connector/src/setup-wizard.js.map +1 -1
- package/dist/assets/hooks/aria-agent-handoff.mjs +224 -0
- package/dist/assets/hooks/aria-agent-ledger-merge.mjs +164 -0
- package/dist/assets/hooks/aria-architect-fallback.mjs +267 -0
- package/dist/assets/hooks/aria-cognition-substrate-binding.mjs +668 -0
- package/dist/assets/hooks/aria-discovery-record.mjs +101 -0
- package/dist/assets/hooks/aria-harness-via-sdk.mjs +412 -0
- package/dist/assets/hooks/aria-import-resolution-gate.mjs +330 -0
- package/dist/assets/hooks/aria-outcome-record.mjs +84 -0
- package/dist/assets/hooks/aria-pre-emit-dryrun.mjs +294 -0
- package/dist/assets/hooks/aria-pre-text-gate.mjs +112 -0
- package/dist/assets/hooks/aria-pre-tool-gate.mjs +2133 -0
- package/dist/assets/hooks/aria-preprompt-consult.mjs +438 -0
- package/dist/assets/hooks/aria-preturn-memory-gate.mjs +570 -0
- package/dist/assets/hooks/aria-repo-doctrine-gate.mjs +397 -0
- package/dist/assets/hooks/aria-stop-gate.mjs +1551 -0
- package/dist/assets/hooks/aria-trigger-autolearn.mjs +229 -0
- package/dist/assets/hooks/aria-userprompt-abandon-detect.mjs +192 -0
- package/dist/assets/hooks/doctrine_trigger_map.json +479 -0
- package/dist/assets/hooks/lib/canonical-lenses.mjs +64 -0
- package/dist/assets/hooks/lib/gate-audit.mjs +43 -0
- package/dist/assets/hooks/test-aria-preturn-memory-gate.mjs +245 -0
- package/dist/assets/hooks/test-tier-lens-labeling.mjs +399 -0
- package/dist/assets/opencode-plugins/harness-context/index.js +60 -0
- package/dist/assets/opencode-plugins/harness-context/inject-context.mjs +179 -0
- package/dist/assets/opencode-plugins/harness-context/package.json +9 -0
- package/dist/assets/opencode-plugins/harness-gate/index.js +248 -0
- package/dist/assets/opencode-plugins/harness-outcome/index.js +129 -0
- package/dist/assets/opencode-plugins/harness-role/index.js +77 -0
- package/dist/assets/opencode-plugins/harness-role/package.json +9 -0
- package/dist/assets/opencode-plugins/harness-stop/index.js +241 -0
- package/dist/runtime/discipline/CLAUDE.md +339 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-essence/SKILL.md +63 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-essence/references/domain-matrix.md +80 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-essence/references/evolution-loop.md +30 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-essence/references/readable-cognition.md +27 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-forge-guardrails/SKILL.md +35 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-forge-guardrails/references/checklist.md +31 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-repo-doctrine/SKILL.md +39 -0
- package/dist/runtime/discipline/skills/aria-cognition/forge-quality-rules/SKILL.md +43 -0
- package/dist/runtime/discipline/skills/aria-cognition/ghazali-8lens/SKILL.md +38 -0
- package/dist/runtime/discipline/skills/aria-cognition/istiqra-induction/SKILL.md +26 -0
- package/dist/runtime/discipline/skills/aria-cognition/ladunni-22/SKILL.md +35 -0
- package/dist/runtime/discipline/skills/aria-cognition/mizan/SKILL.md +72 -0
- package/dist/runtime/discipline/skills/aria-cognition/nadia/SKILL.md +38 -0
- package/dist/runtime/discipline/skills/aria-cognition/nadia-psi/SKILL.md +38 -0
- package/dist/runtime/discipline/skills/aria-cognition/predictor/SKILL.md +25 -0
- package/dist/runtime/discipline/skills/aria-cognition/qiyas-analogy/SKILL.md +26 -0
- package/dist/runtime/discipline/skills/aria-cognition/soul-domains/SKILL.md +25 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-intra-phase/SKILL.md +81 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-post-phase/SKILL.md +98 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-pre-phase/SKILL.md +99 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-deploy/SKILL.md +127 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-no-stripping/SKILL.md +117 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-onboarding/SKILL.md +112 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-output-discipline/SKILL.md +102 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-substrate-binding/SKILL.md +121 -0
- package/dist/runtime/doctor.mjs +23 -0
- package/dist/runtime/local-phase.mjs +650 -0
- package/dist/runtime/manifest.json +15 -0
- package/dist/runtime/mizan-scheduler.mjs +331 -0
- package/dist/runtime/package.json +6 -0
- package/dist/runtime/provider-proxy.mjs +594 -0
- package/dist/runtime/sdk/BUNDLED.json +5 -0
- package/dist/runtime/sdk/index.d.ts +477 -0
- package/dist/runtime/sdk/index.js +1469 -0
- package/dist/runtime/sdk/index.js.map +1 -0
- package/dist/runtime/sdk/package.json +8 -0
- package/dist/runtime/sdk/runWithCognition.d.ts +77 -0
- package/dist/runtime/sdk/runWithCognition.js +157 -0
- package/dist/runtime/sdk/runWithCognition.js.map +1 -0
- package/dist/runtime/service.mjs +3058 -0
- package/dist/runtime/vendor/aria-gate-runtime/index.d.ts +53 -0
- package/dist/runtime/vendor/aria-gate-runtime/index.d.ts.map +1 -0
- package/dist/runtime/vendor/aria-gate-runtime/index.js +292 -0
- package/dist/runtime/vendor/aria-gate-runtime/index.js.map +1 -0
- package/dist/runtime/vendor/aria-gate-runtime/package.json +6 -0
- package/dist/sdk/BUNDLED.json +2 -2
- package/dist/sdk/index.d.ts +283 -0
- package/dist/sdk/index.js +622 -85
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/runWithCognition.d.ts +77 -0
- package/dist/sdk/runWithCognition.js +157 -0
- package/dist/sdk/runWithCognition.js.map +1 -0
- package/hooks/aria-agent-handoff.mjs +11 -1
- package/hooks/aria-architect-fallback.mjs +109 -40
- package/hooks/aria-cognition-substrate-binding.mjs +668 -0
- package/hooks/aria-harness-via-sdk.mjs +34 -21
- package/hooks/aria-import-resolution-gate.mjs +330 -0
- package/hooks/aria-outcome-record.mjs +5 -1
- package/hooks/aria-pre-emit-dryrun.mjs +294 -0
- package/hooks/aria-pre-tool-gate.mjs +828 -41
- package/hooks/aria-preprompt-consult.mjs +113 -13
- package/hooks/aria-preturn-memory-gate.mjs +298 -6
- package/hooks/aria-repo-doctrine-gate.mjs +397 -0
- package/hooks/aria-stop-gate.mjs +739 -76
- package/hooks/aria-userprompt-abandon-detect.mjs +5 -1
- package/hooks/doctrine_trigger_map.json +209 -15
- package/hooks/lib/canonical-lenses.mjs +64 -0
- package/hooks/lib/gate-audit.mjs +43 -0
- package/opencode-plugins/harness-context/index.js +1 -1
- package/opencode-plugins/harness-context/inject-context.mjs +82 -23
- package/opencode-plugins/harness-gate/index.js +248 -0
- package/opencode-plugins/harness-outcome/index.js +129 -0
- package/opencode-plugins/harness-stop/index.js +241 -0
- package/package.json +9 -3
- package/runtime-src/doctor.mjs +23 -0
- package/runtime-src/local-phase.mjs +650 -0
- package/runtime-src/mizan-scheduler.mjs +331 -0
- package/runtime-src/provider-proxy.mjs +594 -0
- package/runtime-src/service.mjs +3058 -0
- package/scripts/bundle-sdk.mjs +317 -0
- package/scripts/install-client.sh +176 -0
- package/scripts/publish-all.sh +344 -0
- package/scripts/publish-docker.sh +27 -0
- package/scripts/validate-hook-contracts.mjs +54 -0
- package/scripts/validate-skill-prompts.mjs +95 -0
- package/skills/aria-cognition/aria-essence/SKILL.md +63 -0
- package/skills/aria-cognition/aria-essence/references/domain-matrix.md +80 -0
- package/skills/aria-cognition/aria-essence/references/evolution-loop.md +30 -0
- package/skills/aria-cognition/aria-essence/references/readable-cognition.md +27 -0
- package/skills/aria-cognition/aria-forge-guardrails/SKILL.md +35 -0
- package/skills/aria-cognition/aria-forge-guardrails/references/checklist.md +31 -0
- package/skills/aria-cognition/aria-repo-doctrine/SKILL.md +39 -0
- package/skills/aria-cognition/forge-quality-rules/SKILL.md +43 -0
- package/skills/aria-cognition/ghazali-8lens/SKILL.md +38 -0
- package/skills/aria-cognition/istiqra-induction/SKILL.md +26 -0
- package/skills/aria-cognition/ladunni-22/SKILL.md +35 -0
- package/skills/aria-cognition/mizan/SKILL.md +72 -0
- package/skills/aria-cognition/nadia/SKILL.md +38 -0
- package/skills/aria-cognition/nadia-psi/SKILL.md +38 -0
- package/skills/aria-cognition/predictor/SKILL.md +25 -0
- package/skills/aria-cognition/qiyas-analogy/SKILL.md +26 -0
- package/skills/aria-cognition/soul-domains/SKILL.md +25 -0
- package/src/auth-commands.ts +111 -45
- package/src/chat.ts +174 -13
- package/src/codebase-scanner.ts +4 -0
- package/src/config.ts +15 -0
- package/src/connectors/claude-code.ts +79 -25
- package/src/connectors/codebase-awareness.ts +408 -0
- package/src/connectors/codex.ts +274 -0
- package/src/connectors/cognitive-skills.ts +51 -0
- package/src/connectors/opencode.ts +93 -4
- package/src/connectors/repo-git-hooks.ts +86 -0
- package/src/connectors/repo-guard.ts +589 -0
- package/src/connectors/runtime.ts +374 -0
- package/src/connectors/shell.ts +83 -14
- package/src/connectors/syncd.ts +488 -0
- package/src/decisions.ts +469 -0
- package/src/garden-control-plane.ts +101 -26
- package/src/github-connect.ts +143 -0
- package/src/harness-client.ts +128 -3
- package/src/hive-client.ts +165 -5
- package/src/index.ts +41 -2
- package/src/lib/aristotle-noor-wire.ts +310 -0
- package/src/providers/types.ts +6 -0
- package/src/runtime-proof.ts +392 -0
- package/src/self-update.ts +89 -8
- package/src/setup-wizard.ts +37 -2
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { dirname, extname, isAbsolute, join, resolve } from 'node:path';
|
|
5
|
+
import { execFileSync } from 'node:child_process';
|
|
6
|
+
import { homedir } from 'node:os';
|
|
7
|
+
|
|
8
|
+
const HOME = homedir();
|
|
9
|
+
const AUDIT_PATH = `${HOME}/.claude/aria-repo-doctrine-gate-audit.jsonl`;
|
|
10
|
+
const ALLOW_MARKER = 'ARIA_ALLOW_STUB';
|
|
11
|
+
const TEACHING_PROSE_MARKER = 'ARIA_TEACHING_PROSE';
|
|
12
|
+
const ALLOW_EXTERNAL_LLM_CALL_MARKER = 'ARIA_ALLOW_EXTERNAL_LLM_CALL';
|
|
13
|
+
const CODE_EXTENSIONS = new Set([
|
|
14
|
+
'.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs',
|
|
15
|
+
'.py', '.sh', '.bash', '.zsh', '.rb', '.go', '.rs', '.java', '.kt', '.cs',
|
|
16
|
+
'.php', '.swift', '.scala', '.yml', '.yaml',
|
|
17
|
+
]);
|
|
18
|
+
const DOCTRINE_ROOT_PREFIXES = ['apps/', 'packages/', 'harness/', 'ops/', 'scripts/'];
|
|
19
|
+
const IGNORE_PATH_RX = [
|
|
20
|
+
/(^|\/)(node_modules|dist|build|coverage|archive|generated|telegram_env|backup-opencode-config|training-data|\.next|\.turbo|\.cache)(\/|$)/i,
|
|
21
|
+
/(^|\/)(package-lock\.json|pnpm-lock\.yaml|yarn\.lock)$/i,
|
|
22
|
+
/\.map$/i,
|
|
23
|
+
];
|
|
24
|
+
const ALLOW_PATH_RX = [
|
|
25
|
+
/(^|\/)(__tests__|tests?|specs?|fixtures?|examples?|demos?|benchmarks?|mocks?)(\/|$)/i,
|
|
26
|
+
/\.(test|spec)\.[^.]+$/i,
|
|
27
|
+
];
|
|
28
|
+
const DIRECT_LLM_GUARDED_PATH_RX = [
|
|
29
|
+
/(^|\/)packages\/aria-hardening-worker\//i,
|
|
30
|
+
/(^|\/)packages\/openclaw-shared\//i,
|
|
31
|
+
/(^|\/)packages\/aria-connector\/hooks\//i,
|
|
32
|
+
/(^|\/)packages\/aria-connector\/opencode-plugins\//i,
|
|
33
|
+
/(^|\/)packages\/aria-connector\/src\/connectors\//i,
|
|
34
|
+
];
|
|
35
|
+
const DIRECT_LLM_INTERNAL_ALLOW_RX = [
|
|
36
|
+
/(^|\/)harness\/packages\/harness-http-client\/src\//i,
|
|
37
|
+
/(^|\/)packages\/aria-connector\/runtime-src\//i,
|
|
38
|
+
/(^|\/)packages\/aria-connector\/hooks\/aria-architect-fallback\.mjs$/i,
|
|
39
|
+
/(^|\/)apps\/arias-soul\/api\/v1\//i,
|
|
40
|
+
/(^|\/)apps\/arias-soul\/api\/harness\//i,
|
|
41
|
+
];
|
|
42
|
+
const BLOCK_RULES = [
|
|
43
|
+
{
|
|
44
|
+
id: 'stub_semantics',
|
|
45
|
+
message: 'stub or mock semantics in doctrine-bound source',
|
|
46
|
+
rx: /\b(?:stub|stubs|mock|mocks|implementation pending|not implemented|fake implementation|synthetic payload|synthetic response|synthetic data|coming soon|will be wired)\b/i,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 'placeholder_semantics',
|
|
50
|
+
message: 'placeholder implementation semantics in doctrine-bound source',
|
|
51
|
+
rx: /\bplaceholder\b(?!(?:\s*=))[^\n]{0,40}\b(?:implementation|handler|route|logic|response|payload|data|endpoint|function|service)\b/i,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 'todo_stub_semantics',
|
|
55
|
+
message: 'TODO tied to stub or pending implementation in doctrine-bound source',
|
|
56
|
+
rx: /\bTODO\b[^\n]{0,120}\b(?:stub|mock|placeholder|pending|implement)\b/i,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: 'http_501_pending',
|
|
60
|
+
message: '501 or pending-path marker in doctrine-bound source',
|
|
61
|
+
rx: /(?:\bstatus\s*\(\s*501\s*\)|\bsendStatus\s*\(\s*501\s*\)|\b501\b)[^\n]{0,120}\b(?:TODO|pending|not implemented|placeholder)\b|(?:\bTODO\b|\bpending\b|\bnot implemented\b)[^\n]{0,120}(?:\bstatus\s*\(\s*501\s*\)|\bsendStatus\s*\(\s*501\s*\)|\b501\b)/i,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: 'mock_import',
|
|
65
|
+
message: 'mock or stub import in doctrine-bound source',
|
|
66
|
+
rx: /\b(?:from|require\s*\()\s*['"][^'"]*(?:mock|stub|fake)[^'"]*['"]/i,
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: 'direct_llm_bypass',
|
|
70
|
+
message: 'bare direct LLM/provider call outside approved runtime or SDK surface',
|
|
71
|
+
rx: /\bfetch\s*\([^\n]{0,240}(?:\/v1\/chat\/completions|\/v1\/messages|api\.anthropic\.com\/v1\/messages|api\.openai\.com\/v1\/chat\/completions|api\.deepseek\.com(?:\/v1)?\/chat\/completions|openrouter\.ai\/api\/v1\/chat\/completions|integrate\.api\.nvidia\.com\/v1\/chat\/completions|api\.x\.ai\/v1\/chat\/completions|open\.bigmodel\.cn\/api\/paas\/v4\/chat\/completions)\b/i,
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: 'direct_llm_sdk_bypass',
|
|
75
|
+
message: 'direct provider SDK call outside approved runtime or SDK surface',
|
|
76
|
+
rx: /\b(?:anthropic\.messages\.create|client\.messages\.create|chat\.completions\.create)\s*\(/i,
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
function audit(event, data = {}) {
|
|
81
|
+
try {
|
|
82
|
+
mkdirSync(dirname(AUDIT_PATH), { recursive: true, mode: 0o700 });
|
|
83
|
+
appendFileSync(
|
|
84
|
+
AUDIT_PATH,
|
|
85
|
+
JSON.stringify({ ts: new Date().toISOString(), event, ...data }) + '\n',
|
|
86
|
+
);
|
|
87
|
+
} catch {}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function parseArgs(argv) {
|
|
91
|
+
const parsed = {
|
|
92
|
+
mode: 'working-tree',
|
|
93
|
+
repo: null,
|
|
94
|
+
paths: [],
|
|
95
|
+
};
|
|
96
|
+
for (let i = 0; i < argv.length; i++) {
|
|
97
|
+
const arg = argv[i];
|
|
98
|
+
if (arg === '--mode' && argv[i + 1]) {
|
|
99
|
+
parsed.mode = argv[++i];
|
|
100
|
+
} else if (arg === '--repo' && argv[i + 1]) {
|
|
101
|
+
parsed.repo = argv[++i];
|
|
102
|
+
} else if (arg === '--path' && argv[i + 1]) {
|
|
103
|
+
parsed.paths.push(argv[++i]);
|
|
104
|
+
} else if (arg === '--paths') {
|
|
105
|
+
parsed.paths.push(...argv.slice(i + 1));
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return parsed;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function runGit(args, cwd, options = {}) {
|
|
113
|
+
return execFileSync('git', args, {
|
|
114
|
+
cwd,
|
|
115
|
+
encoding: 'utf8',
|
|
116
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
117
|
+
...options,
|
|
118
|
+
}).trim();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function resolveRepoRoot(hint, fallbackPaths = []) {
|
|
122
|
+
const candidates = [hint, ...fallbackPaths, process.cwd()].filter(Boolean);
|
|
123
|
+
for (const candidate of candidates) {
|
|
124
|
+
const base = existsSync(candidate) ? candidate : dirname(candidate);
|
|
125
|
+
try {
|
|
126
|
+
const root = runGit(['-C', base, 'rev-parse', '--show-toplevel'], base);
|
|
127
|
+
if (root) return root;
|
|
128
|
+
} catch {}
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function readStdin() {
|
|
134
|
+
return new Promise((resolvePromise) => {
|
|
135
|
+
let input = '';
|
|
136
|
+
process.stdin.setEncoding('utf8');
|
|
137
|
+
process.stdin.on('data', (chunk) => { input += chunk; });
|
|
138
|
+
process.stdin.on('end', () => resolvePromise(input));
|
|
139
|
+
process.stdin.on('error', () => resolvePromise(''));
|
|
140
|
+
if (process.stdin.isTTY) resolvePromise('');
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function isDoctrineBound(relPath) {
|
|
145
|
+
return DOCTRINE_ROOT_PREFIXES.some((prefix) => relPath.startsWith(prefix));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function isIgnored(relPath) {
|
|
149
|
+
return IGNORE_PATH_RX.some((rx) => rx.test(relPath));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function isAllowlisted(relPath, text) {
|
|
153
|
+
if (text.includes(ALLOW_MARKER) || text.includes(TEACHING_PROSE_MARKER)) return true;
|
|
154
|
+
return ALLOW_PATH_RX.some((rx) => rx.test(relPath));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function stripQuotedContent(line) {
|
|
158
|
+
return line
|
|
159
|
+
.replace(/`(?:\\.|[^`])*`/g, '``')
|
|
160
|
+
.replace(/"(?:\\.|[^"])*"/g, '""')
|
|
161
|
+
.replace(/'(?:\\.|[^'])*'/g, "''");
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function buildMultilineStringMask(text) {
|
|
165
|
+
const lines = String(text || '').split('\n');
|
|
166
|
+
const mask = new Array(lines.length).fill(false);
|
|
167
|
+
let inTemplate = false;
|
|
168
|
+
|
|
169
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
170
|
+
const line = lines[lineIndex];
|
|
171
|
+
let escaped = false;
|
|
172
|
+
let inSingle = false;
|
|
173
|
+
let inDouble = false;
|
|
174
|
+
let lineInsideTemplate = inTemplate;
|
|
175
|
+
|
|
176
|
+
for (let i = 0; i < line.length; i++) {
|
|
177
|
+
const ch = line[i];
|
|
178
|
+
if (escaped) {
|
|
179
|
+
escaped = false;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (ch === '\\') {
|
|
183
|
+
escaped = true;
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
if (!inDouble && !inTemplate && ch === '\'') {
|
|
187
|
+
inSingle = !inSingle;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
if (!inSingle && !inTemplate && ch === '"') {
|
|
191
|
+
inDouble = !inDouble;
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
if (!inSingle && !inDouble && ch === '`') {
|
|
195
|
+
inTemplate = !inTemplate;
|
|
196
|
+
lineInsideTemplate = true;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
mask[lineIndex] = lineInsideTemplate;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return mask;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function isCommentOnlyLine(line) {
|
|
207
|
+
return /^\s*(?:\/\/|#|\*)/.test(line);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function isPolicyOrRuleDefinitionLine(line) {
|
|
211
|
+
const lower = String(line || '').toLowerCase();
|
|
212
|
+
if (!lower) return false;
|
|
213
|
+
if (/\bpattern\s*:\s*\/.*\/[a-z]*\s*,\s*violation\s*:/.test(line)) return true;
|
|
214
|
+
if (lower.includes('code quality default')) return true;
|
|
215
|
+
if (lower.includes('anti-patterns')) return true;
|
|
216
|
+
if (lower.includes('produce real working code')) return true;
|
|
217
|
+
if (lower.includes('non-stub check')) return true;
|
|
218
|
+
if (lower.includes('output file is a stub')) return true;
|
|
219
|
+
if (/\bno stubs?\b/.test(lower)) return true;
|
|
220
|
+
if (/\bno placeholders?\b/.test(lower)) return true;
|
|
221
|
+
if (/\bno fake implementations?\b/.test(lower)) return true;
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function isDirectLlmGuardedPath(relPath) {
|
|
226
|
+
return DIRECT_LLM_GUARDED_PATH_RX.some((rx) => rx.test(relPath));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function isDirectLlmAllowlisted(relPath, text) {
|
|
230
|
+
if (text.includes(ALLOW_EXTERNAL_LLM_CALL_MARKER)) return true;
|
|
231
|
+
return DIRECT_LLM_INTERNAL_ALLOW_RX.some((rx) => rx.test(relPath));
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function shouldScan(relPath, absPath) {
|
|
235
|
+
if (!existsSync(absPath)) return false;
|
|
236
|
+
if (isIgnored(relPath)) return false;
|
|
237
|
+
if (!isDoctrineBound(relPath)) return false;
|
|
238
|
+
return CODE_EXTENSIONS.has(extname(relPath).toLowerCase());
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function collectViolations(repoRoot, relPaths) {
|
|
242
|
+
const violations = [];
|
|
243
|
+
for (const relPath of relPaths) {
|
|
244
|
+
const absPath = resolve(repoRoot, relPath);
|
|
245
|
+
if (!shouldScan(relPath, absPath)) continue;
|
|
246
|
+
let text;
|
|
247
|
+
try {
|
|
248
|
+
text = readFileSync(absPath, 'utf8');
|
|
249
|
+
} catch {
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
if (isAllowlisted(relPath, text)) continue;
|
|
253
|
+
const lines = text.split('\n');
|
|
254
|
+
const multilineStringMask = buildMultilineStringMask(text);
|
|
255
|
+
lines.forEach((line, index) => {
|
|
256
|
+
const semanticLine = stripQuotedContent(line);
|
|
257
|
+
const commentOnly = isCommentOnlyLine(line);
|
|
258
|
+
const inMultilineString = multilineStringMask[index] === true;
|
|
259
|
+
for (const rule of BLOCK_RULES) {
|
|
260
|
+
if (
|
|
261
|
+
(rule.id === 'stub_semantics' || rule.id === 'placeholder_semantics') &&
|
|
262
|
+
isPolicyOrRuleDefinitionLine(line)
|
|
263
|
+
) {
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
if ((rule.id === 'direct_llm_bypass' || rule.id === 'direct_llm_sdk_bypass')) {
|
|
267
|
+
if (!isDirectLlmGuardedPath(relPath)) continue;
|
|
268
|
+
if (isDirectLlmAllowlisted(relPath, text)) continue;
|
|
269
|
+
}
|
|
270
|
+
const scanLine =
|
|
271
|
+
(rule.id === 'stub_semantics' || rule.id === 'placeholder_semantics')
|
|
272
|
+
? (commentOnly || inMultilineString ? '' : semanticLine)
|
|
273
|
+
: (rule.id === 'todo_stub_semantics' || rule.id === 'http_501_pending' || rule.id === 'mock_import')
|
|
274
|
+
? (inMultilineString ? '' : semanticLine)
|
|
275
|
+
: line;
|
|
276
|
+
if (rule.rx.test(scanLine)) {
|
|
277
|
+
violations.push({
|
|
278
|
+
path: relPath,
|
|
279
|
+
line: index + 1,
|
|
280
|
+
rule: rule.id,
|
|
281
|
+
message: rule.message,
|
|
282
|
+
excerpt: line.trim().slice(0, 240),
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
return violations;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function parsePrePushRefs(stdin) {
|
|
292
|
+
const ranges = [];
|
|
293
|
+
for (const line of String(stdin || '').split('\n').filter(Boolean)) {
|
|
294
|
+
const [localRef, localSha, remoteRef, remoteSha] = line.trim().split(/\s+/);
|
|
295
|
+
if (!localSha || !remoteSha) continue;
|
|
296
|
+
ranges.push({ localRef, localSha, remoteRef, remoteSha });
|
|
297
|
+
}
|
|
298
|
+
return ranges;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function emptyTreeSha(repoRoot) {
|
|
302
|
+
return runGit(['hash-object', '-t', 'tree', '/dev/null'], repoRoot);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function changedPathsForMode(repoRoot, mode, explicitPaths, stdin) {
|
|
306
|
+
if (explicitPaths.length > 0) {
|
|
307
|
+
return explicitPaths.map((candidate) => {
|
|
308
|
+
const abs = isAbsolute(candidate) ? candidate : resolve(process.cwd(), candidate);
|
|
309
|
+
return resolve(repoRoot, abs).startsWith(repoRoot) ? abs.slice(repoRoot.length + 1).replace(/\\/g, '/') : candidate;
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (mode === 'staged') {
|
|
314
|
+
return runGit(['diff', '--cached', '--name-only', '--diff-filter=ACMR'], repoRoot)
|
|
315
|
+
.split('\n')
|
|
316
|
+
.filter(Boolean);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (mode === 'push') {
|
|
320
|
+
const refs = parsePrePushRefs(stdin);
|
|
321
|
+
const paths = new Set();
|
|
322
|
+
const emptyTree = emptyTreeSha(repoRoot);
|
|
323
|
+
for (const ref of refs) {
|
|
324
|
+
const remoteSha = /^0+$/.test(ref.remoteSha) ? emptyTree : ref.remoteSha;
|
|
325
|
+
const diff = runGit(['diff', '--name-only', '--diff-filter=ACMR', `${remoteSha}...${ref.localSha}`], repoRoot);
|
|
326
|
+
diff.split('\n').filter(Boolean).forEach((entry) => paths.add(entry));
|
|
327
|
+
}
|
|
328
|
+
if (paths.size > 0) return [...paths];
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return runGit(['diff', '--name-only', '--diff-filter=ACMR'], repoRoot)
|
|
332
|
+
.split('\n')
|
|
333
|
+
.filter(Boolean);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function renderReason(repoRoot, violations, mode) {
|
|
337
|
+
const lines = violations
|
|
338
|
+
.slice(0, 20)
|
|
339
|
+
.map((violation) => `- ${violation.path}:${violation.line} [${violation.rule}] ${violation.excerpt}`);
|
|
340
|
+
return [
|
|
341
|
+
`Aria repo doctrine gate blocked ${mode}.`,
|
|
342
|
+
'',
|
|
343
|
+
'Doctrine-bound source cannot introduce stub/mock/pending semantics outside explicit allowlists.',
|
|
344
|
+
`Repo: ${repoRoot}`,
|
|
345
|
+
'',
|
|
346
|
+
'Violations:',
|
|
347
|
+
...lines,
|
|
348
|
+
'',
|
|
349
|
+
`Allow path categories: tests/specs/fixtures/examples/demos/mocks, or add ${ALLOW_MARKER} in the file when the exception is intentional and reviewable.`,
|
|
350
|
+
`External provider calls require explicit ${ALLOW_EXTERNAL_LLM_CALL_MARKER} marker or an approved internal runtime/SDK path.`,
|
|
351
|
+
].join('\n');
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
async function main() {
|
|
355
|
+
const args = parseArgs(process.argv.slice(2));
|
|
356
|
+
const stdin = await readStdin();
|
|
357
|
+
let event = null;
|
|
358
|
+
try { event = stdin ? JSON.parse(stdin) : null; } catch {}
|
|
359
|
+
|
|
360
|
+
const eventPaths = [];
|
|
361
|
+
if (event?.tool_input?.file_path) eventPaths.push(event.tool_input.file_path);
|
|
362
|
+
if (event?.tool_input?.path) eventPaths.push(event.tool_input.path);
|
|
363
|
+
if (event?.tool_input?.command && typeof event.tool_input.command === 'string') {
|
|
364
|
+
// For Bash mutations, scan repo diff rather than trying to parse arbitrary shell.
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const repoRoot = resolveRepoRoot(
|
|
368
|
+
args.repo || event?.cwd || event?.working_directory || event?.tool_input?.file_path || event?.tool_input?.path,
|
|
369
|
+
eventPaths,
|
|
370
|
+
);
|
|
371
|
+
if (!repoRoot) process.exit(0);
|
|
372
|
+
|
|
373
|
+
const mode = args.mode || (event ? 'working-tree' : 'working-tree');
|
|
374
|
+
const relPaths = changedPathsForMode(repoRoot, mode, args.paths, stdin);
|
|
375
|
+
const violations = collectViolations(repoRoot, relPaths);
|
|
376
|
+
if (violations.length === 0) {
|
|
377
|
+
audit('repo_doctrine_gate_pass', { repoRoot, mode, scanned: relPaths.length });
|
|
378
|
+
process.exit(0);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const reason = renderReason(repoRoot, violations, mode);
|
|
382
|
+
audit('repo_doctrine_gate_block', { repoRoot, mode, violations });
|
|
383
|
+
|
|
384
|
+
if (event) {
|
|
385
|
+
console.log(JSON.stringify({ decision: 'block', reason }));
|
|
386
|
+
process.exit(2);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
console.error(reason);
|
|
390
|
+
process.exit(1);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
main().catch((err) => {
|
|
394
|
+
audit('repo_doctrine_gate_error', { err: err instanceof Error ? err.message : String(err) });
|
|
395
|
+
console.error(`Aria repo doctrine gate failed closed: ${err instanceof Error ? err.message : String(err)}`);
|
|
396
|
+
process.exit(1);
|
|
397
|
+
});
|