-
Notifications
You must be signed in to change notification settings - Fork 3.1k
refactor(review): remove security receipt ledger #10075
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9163319
b019007
959dde2
085b320
7fee4e4
5e01fd6
7c4210e
df6d1ba
813a6a1
be151b6
ce92871
635325c
df01f61
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,14 +7,12 @@ import os from "node:os"; | |
| import path from "node:path"; | ||
|
|
||
| import type { ToolDefinition } from "@earendil-works/pi-coding-agent"; | ||
| import { canonicalRepoReadPath } from "../tools/advisors/repo-read-only-tools.mts"; | ||
| import { describe, expect, it, onTestFinished, vi } from "vitest"; | ||
|
|
||
| import { TERMINOLOGY_TRACE_TOOL } from "../tools/pr-review-advisor/terminology.mts"; | ||
| import { | ||
| runSpecialistAdvisor, | ||
| writeSpecialistDiff, | ||
| writeSpecialistSummary, | ||
| } from "../tools/pr-review-advisor/run-specialist.mts"; | ||
| import { runSpecialistAdvisor, writeSpecialistSummary } from "../tools/pr-review-advisor/run-specialist.mts"; | ||
| import { writeSpecialistDiff } from "../tools/pr-review-advisor/specialist-context.mts"; | ||
| import type { RunAdvisorResult, RunReadOnlyAdvisorOptions } from "../tools/advisors/session.mts"; | ||
| import { | ||
| ADVISOR_INTERESTS, | ||
|
|
@@ -49,15 +47,15 @@ const context: InvestigateTurnContext = { | |
| }; | ||
|
|
||
| describe("PR review advisor specialist prompts", () => { | ||
| it("writes diff evidence to a new owner-only runtime path", () => { | ||
| const configDir = fs.mkdtempSync(path.join(process.cwd(), ".tmp-specialist-config-")); | ||
| onTestFinished(() => fs.rmSync(configDir, { recursive: true, force: true })); | ||
| const directory = path.join(configDir, "context"); | ||
| it("writes readable diff evidence in the prepared advisor context", async () => { | ||
| const directory = fs.mkdtempSync(path.join(os.tmpdir(), "specialist-context-")); | ||
| onTestFinished(() => fs.rmSync(directory, { recursive: true, force: true })); | ||
| const expected = path.join(directory, "diff.patch"); | ||
|
|
||
| const file = writeSpecialistDiff(configDir, "diff evidence"); | ||
| const file = writeSpecialistDiff(directory, "diff evidence"); | ||
|
|
||
| expect(file).toBe(expected); | ||
| await expect(canonicalRepoReadPath(directory, "diff.patch")).resolves.toBe(expected); | ||
| expect(fs.readFileSync(file, "utf8")).toBe("diff evidence"); | ||
| expect(fs.statSync(directory).mode & 0o777).toBe(0o700); | ||
| expect(fs.statSync(file).mode & 0o777).toBe(0o600); | ||
|
|
@@ -66,18 +64,47 @@ describe("PR review advisor specialist prompts", () => { | |
| it("tightens an existing specialist diff path", () => { | ||
| const configDir = fs.mkdtempSync(path.join(process.cwd(), ".tmp-specialist-config-")); | ||
| onTestFinished(() => fs.rmSync(configDir, { recursive: true, force: true })); | ||
| const directory = path.join(configDir, "context"); | ||
| const directory = configDir; | ||
| const expected = path.join(directory, "diff.patch"); | ||
| fs.mkdirSync(directory, { mode: 0o755 }); | ||
| fs.chmodSync(directory, 0o755); | ||
| fs.writeFileSync(expected, "stale", { mode: 0o644 }); | ||
|
|
||
| writeSpecialistDiff(configDir, "diff evidence"); | ||
| writeSpecialistDiff(directory, "diff evidence"); | ||
|
|
||
| expect(fs.readFileSync(expected, "utf8")).toBe("diff evidence"); | ||
| expect(fs.statSync(directory).mode & 0o777).toBe(0o700); | ||
| expect(fs.statSync(expected).mode & 0o777).toBe(0o600); | ||
| }); | ||
|
|
||
| it("rejects a symbolic-link specialist diff file", () => { | ||
| const directory = fs.mkdtempSync(path.join(os.tmpdir(), "specialist-context-")); | ||
| const target = path.join(directory, "outside.patch"); | ||
| onTestFinished(() => fs.rmSync(directory, { recursive: true, force: true })); | ||
| fs.writeFileSync(target, "unchanged"); | ||
| fs.symlinkSync(target, path.join(directory, "diff.patch")); | ||
|
|
||
| expect(() => writeSpecialistDiff(directory, "diff evidence")).toThrow( | ||
| "Specialist diff file must not be a symbolic link", | ||
| ); | ||
| expect(fs.readFileSync(target, "utf8")).toBe("unchanged"); | ||
| }); | ||
|
|
||
| it("rejects a dangling symbolic-link specialist diff file", () => { | ||
| const directory = fs.mkdtempSync(path.join(os.tmpdir(), "specialist-context-")); | ||
| const targetDirectory = fs.mkdtempSync(path.join(os.tmpdir(), "specialist-target-")); | ||
| const target = path.join(targetDirectory, "missing.patch"); | ||
| onTestFinished(() => { | ||
| fs.rmSync(directory, { recursive: true, force: true }); | ||
| fs.rmSync(targetDirectory, { recursive: true, force: true }); | ||
| }); | ||
| fs.symlinkSync(target, path.join(directory, "diff.patch")); | ||
|
|
||
| expect(() => writeSpecialistDiff(directory, "diff evidence")).toThrow( | ||
| "Specialist diff file must not be a symbolic link", | ||
| ); | ||
| expect(fs.existsSync(target)).toBe(false); | ||
|
Comment on lines
+79
to
+105
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win Restore directory symbolic-link regression coverage. These tests cover symbolic-link files only. Add a symbolic-link directory case for As per path instructions, “For security-sensitive specialist-context changes, add regression coverage for directory and file symlink rejection and verify linked targets remain unmodified.” 🧰 Tools🪛 ast-grep (0.45.1)[warning] 82-82: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use. (detect-non-literal-fs-filename-typescript) [warning] 88-88: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use. (detect-non-literal-fs-filename-typescript) 🤖 Prompt for AI AgentsSource: Path instructions |
||
| }); | ||
|
|
||
| it("parses every discovered specialist interest (#9949)", () => { | ||
| expect(ADVISOR_INTERESTS.map(parseAdvisorInterest)).toEqual(ADVISOR_INTERESTS); | ||
| expect(() => parseAdvisorInterest("missing-specialist")).toThrowError( | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.