review: harden readonly git checks and lint verification

This commit is contained in:
ejclaw
2026-04-22 20:48:33 +09:00
parent 977d22cea7
commit 12838a8b07
9 changed files with 185 additions and 9 deletions

View File

@@ -479,12 +479,12 @@ server.tool(
server.tool(
'run_verification',
'Run a fixed verification profile directly on the host against the current repo snapshot using a restricted environment and snapshot checks. Use this instead of broad shell write access for test/typecheck/build verification.',
'Run a fixed verification profile directly on the host against the current repo snapshot using a restricted environment and snapshot checks. Use this instead of broad shell write access for test/typecheck/build/lint verification.',
{
profile: z
.enum(VERIFICATION_PROFILES)
.describe(
'Fixed verification profile. Runs the workspace test/typecheck/build scripts with the repo-configured package manager.',
'Fixed verification profile. Runs the workspace test/typecheck/build/lint scripts with the repo-configured package manager.',
),
},
async (args) => {

View File

@@ -3,7 +3,12 @@ import path from 'path';
import { pathToFileURL } from 'url';
export { computeVerificationSnapshotId } from '../../../shared/verification-snapshot.js';
export const VERIFICATION_PROFILES = ['test', 'typecheck', 'build'] as const;
export const VERIFICATION_PROFILES = [
'test',
'typecheck',
'build',
'lint',
] as const;
export type VerificationProfile = (typeof VERIFICATION_PROFILES)[number];

View File

@@ -169,6 +169,9 @@ describe('claude reviewer runtime guard', () => {
const env = buildReviewerGitGuardEnv({ PATH: process.env.PATH }, true);
expect(env.PATH).toContain('ejclaw-reviewer-git-');
expect(env.EJCLAW_REAL_GIT).toBeTruthy();
expect(env.GIT_CONFIG_GLOBAL).toContain('global.gitconfig');
expect(env.GIT_CONFIG_NOSYSTEM).toBe('1');
expect(fs.existsSync(env.GIT_CONFIG_GLOBAL!)).toBe(true);
});
it('prefers an executable HOME-scoped wrapper dir before tmp', () => {
@@ -245,6 +248,30 @@ describe('claude reviewer runtime guard', () => {
}
});
it('overrides problematic git config paths so read-only git queries still work', () => {
const cwd = createTempRepo('ejclaw-reviewer-readonly-git-');
const env = buildReviewerGitGuardEnv(
{
PATH: process.env.PATH,
HOME: cwd,
EJCLAW_WORK_DIR: cwd,
GIT_CONFIG_GLOBAL: path.join(cwd, '.gitconfig'),
},
true,
);
expect(env.GIT_CONFIG_GLOBAL).not.toBe(path.join(cwd, '.gitconfig'));
expect(() =>
execFileSync('git', ['log', '--oneline', '-1'], {
cwd,
env,
encoding: 'utf-8',
stdio: ['ignore', 'pipe', 'pipe'],
}),
).not.toThrow();
expect(fs.existsSync(path.join(cwd, '.gitconfig'))).toBe(false);
});
it('accepts a mounted local origin path that resolves as a git repo', () => {
const originDir = createTempRepo('ejclaw-reviewer-origin-');
const cwd = createTempRepo('ejclaw-reviewer-workspace-');