-
Notifications
You must be signed in to change notification settings - Fork 0
drive: cloud run 55d32822 #52
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
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 |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| import { existsSync } from 'node:fs'; | ||
|
|
||
| const TEST_CLAIM = | ||
| /\b(?:all\s+)?(?:(?:\d+|all|every|the)\s+)?tests?(?:\s+(?:are|is))?\s+(?:pass(?:ed|ing)?|green)\b|\ball\s+(?:merged\s+and\s+)?tested\b/i; | ||
| const INLINE_CODE = /`([^`\n]+)`/g; | ||
| const REPO_PATH = /^(?:\.?[A-Za-z0-9_-][A-Za-z0-9._-]*\/)+[A-Za-z0-9._-]+\/?$/; | ||
|
|
||
| export type NextValidationRefusalReason = | ||
| | 'uncaptured_test_claim' | ||
| | 'nonexistent_path_reference'; | ||
|
|
||
| export type NextValidationResult = | ||
| | { accepted: true } | ||
| | { accepted: false; reason: NextValidationRefusalReason }; | ||
|
|
||
| export type PathExists = (path: string) => boolean; | ||
|
|
||
| const defaultPathExists: PathExists = (path) => existsSync(path); | ||
|
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.
When this exported SDK function is invoked from a directory other than the repository root—for example, from AGENTS.md reference: AGENTS.md:L69-L70 Useful? React with 👍 / 👎. |
||
|
|
||
| /** Refuse recurring, cheaply provable defects in a NEXT.md work package. */ | ||
| export function validateNextWorkPackage( | ||
| markdown: string, | ||
| pathExists: PathExists = defaultPathExists, | ||
| ): NextValidationResult { | ||
| if (hasUncapturedTestClaim(markdown)) { | ||
| return { accepted: false, reason: 'uncaptured_test_claim' }; | ||
| } | ||
| if (referencedPaths(markdown).some((path) => !pathExists(path))) { | ||
| return { accepted: false, reason: 'nonexistent_path_reference' }; | ||
| } | ||
| return { accepted: true }; | ||
| } | ||
|
|
||
| function hasUncapturedTestClaim(markdown: string): boolean { | ||
| const lines = markdown.split('\n'); | ||
| return lines.some((line, index) => { | ||
| if (!TEST_CLAIM.test(line)) return false; | ||
| const nearby = lines.slice(Math.max(0, index - 8), index + 9).join('\n'); | ||
| return !containsCapturedCommandOutput(nearby); | ||
| }); | ||
| } | ||
|
|
||
| function containsCapturedCommandOutput(markdown: string): boolean { | ||
| for (const match of markdown.matchAll(/```[^\n]*\n([\s\S]*?)```/g)) { | ||
| const lines = (match[1] ?? '').trim().split('\n'); | ||
| const command = lines.findIndex((line) => /^\s*\$\s*\S/.test(line)); | ||
| if (command >= 0 && lines.slice(command + 1).some((line) => line.trim().length > 0)) { | ||
|
Comment on lines
+46
to
+47
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.
When valid evidence records a literal command as AGENTS.md reference: AGENTS.md:L62-L64 Useful? React with 👍 / 👎. |
||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| function referencedPaths(markdown: string): string[] { | ||
| return [...markdown.matchAll(INLINE_CODE)] | ||
| .map((match) => match[1] ?? '') | ||
| .filter((candidate) => REPO_PATH.test(candidate)); | ||
|
Comment on lines
+54
to
+57
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.
When a nonexistent repository path is cited using normal Markdown link syntax, such as AGENTS.md reference: AGENTS.md:L69-L70 Useful? React with 👍 / 👎. |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| import { readFileSync } from 'node:fs'; | ||
| import { join } from 'node:path'; | ||
| import { describe, expect, it } from 'vitest'; | ||
|
|
||
| const examples = join(__dirname, '..', '..', 'testdata', 'next-examples'); | ||
| const readExample = (name: string) => readFileSync(join(examples, name), 'utf8'); | ||
|
|
||
| async function validate(markdown: string, paths: readonly string[]) { | ||
| const validator = await import('../src/next-validator.js'); | ||
| return validator.validateNextWorkPackage(markdown, (path) => paths.includes(path)); | ||
| } | ||
|
|
||
| describe('next-validator', () => { | ||
| it('refuses the PR #19/#35 pattern: a passing-test claim without captured output', async () => { | ||
| expect( | ||
| await validate(readExample('uncaptured-test-claim.md'), [ | ||
| 'sdk/src/next-validator.ts', | ||
| ]), | ||
| ).toEqual({ accepted: false, reason: 'uncaptured_test_claim' }); | ||
| }); | ||
|
|
||
| it('refuses the nonexistent ops/TARGET.md path pattern', async () => { | ||
| expect(await validate(readExample('nonexistent-path.md'), [])).toEqual({ | ||
| accepted: false, | ||
| reason: 'nonexistent_path_reference', | ||
| }); | ||
| }); | ||
|
|
||
| it('accepts a NEXT.md with real paths and captured command output', async () => { | ||
| expect( | ||
| await validate(readExample('well-formed.md'), [ | ||
| 'sdk/src/next-validator.ts', | ||
| 'sdk/tests/next-validator.test.ts', | ||
| ]), | ||
| ).toEqual({ accepted: true }); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # NEXT — Fix package validation | ||
|
|
||
| The scope is copied from `ops/TARGET.md`. | ||
|
|
||
| ## Definition of done | ||
|
|
||
| Run the validator tests. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # NEXT — Fix package validation | ||
|
|
||
| ## Files in scope | ||
|
|
||
| - `sdk/src/next-validator.ts` | ||
|
|
||
| ## Definition of done | ||
|
|
||
| All three tests pass. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| # NEXT — Validate NEXT.md | ||
|
|
||
| ## Files in scope | ||
|
|
||
| - `sdk/src/next-validator.ts` | ||
| - `sdk/tests/next-validator.test.ts` | ||
|
|
||
| ## Definition of done | ||
|
|
||
| Run the SDK tests and capture their output: | ||
|
|
||
| ```text | ||
| $ cd sdk && npm test | ||
| Test Files 14 passed (14) | ||
| Tests 65 passed (65) | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a NEXT.md definition of done says that tests must pass in the future, this expression treats it as a completed verification claim and refuses the package unless prior output is present. The changed
ops/NEXT.mditself triggers this through “tests passing that verify refusal,” so the validator rejects the work package it was built for; limit claim detection to assertions of completed verification rather than prospective acceptance criteria.AGENTS.md reference: AGENTS.md:L62-L64
Useful? React with 👍 / 👎.