-
Notifications
You must be signed in to change notification settings - Fork 1
feat(contract): pre-solve formulation.toml (additive; scoped counterpart to #64) #81
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
Draft
jack-champagne
wants to merge
3
commits into
main
Choose a base branch
from
amicode/formulation-toml
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
f8ff177
feat(contract): add pre-solve formulation.toml to the run-dir contract
jack-champagne a8aa327
fix(contract): inline formulation emit + per-family schema
jack-champagne e0e9176
fix(contract): live-finish path reads formulation; gate_name from symbol
jack-champagne File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| import { describe, it, expect } from 'vitest' | ||
| import { mkdtempSync, copyFileSync, existsSync, readFileSync } from 'node:fs' | ||
| import { tmpdir } from 'node:os' | ||
| import { basename, join } from 'node:path' | ||
|
|
||
| // Regression guard (#81). DEPLOYMENT REALITY: AGENTS.md tells the agent to COPY the | ||
| // solve template into a scratch dir and run THAT copy — `julia <scratch>/solve.jl` | ||
| // (see AGENTS.md "Workflow" step 2/3). So inside the running script @__DIR__ is the | ||
| // scratch dir, NOT the bundled templates dir — and any sibling `include(@__DIR__/…)` | ||
| // opens a file only present if the deploy step also copied it. #81's first draft added | ||
| // `include(joinpath(@__DIR__, "emit_formulation.jl"))` while AGENTS.md copies only the | ||
| // template → LoadError before solve!, on every agent-driven run. Nothing in the vitest | ||
| // suite executed the template, so it shipped green. This test closes that gap WITHOUT | ||
| // needing Julia: it ties the two seams together — reproduce exactly the files AGENTS.md | ||
| // copies into scratch, then assert every include() in the deployed script resolves there. | ||
| // Stays green under either fix: inline the helper (no include), or teach AGENTS.md to | ||
| // copy it too. The deeper guard is #78's smoke corpus actually running a solve. | ||
| const EXT = join(__dirname, '..') | ||
| const AGENTS = readFileSync(join(EXT, 'AGENTS.md'), 'utf8') | ||
| const TEMPLATE = join(EXT, 'templates', 'solve_template.jl') | ||
|
|
||
| describe('solve template deploys runnably under AGENTS.md single-file copy [#81]', () => { | ||
| it('every include() in the deployed script resolves in the scratch dir', () => { | ||
| const scratch = mkdtempSync(join(tmpdir(), 'amicode-work-')) | ||
|
|
||
| // Reproduce AGENTS.md's scratch-dir copies: `cp <src> /tmp/amicode-work/<dst>`. | ||
| // {{TEMPLATE_PATH}} is the substitution for the bundled solve_template.jl. | ||
| const copied = new Map<string, string>() // destName -> srcAbs | ||
| for (const m of AGENTS.matchAll(/\bcp\s+(\S+)\s+(\S+)/g)) { | ||
| const [, srcTok, dst] = m | ||
| if (!dst.includes('amicode-work')) continue | ||
| const srcAbs = srcTok.replace('{{TEMPLATE_PATH}}', TEMPLATE) | ||
| copied.set(dst.endsWith('/') ? basename(srcAbs) : basename(dst), srcAbs) | ||
| } | ||
| expect(copied.size, 'AGENTS.md should document copying the template into the scratch dir').toBeGreaterThan(0) | ||
| for (const [name, srcAbs] of copied) copyFileSync(srcAbs, join(scratch, name)) | ||
|
|
||
| // amico-run runs `julia <scratch>/solve.jl`, so @__DIR__ === scratch for the run file. | ||
| const runFile = copied.has('solve.jl') ? 'solve.jl' : [...copied.keys()][0] | ||
| const src = readFileSync(join(scratch, runFile), 'utf8') | ||
|
|
||
| // Julia resolves a relative include (bare or joinpath(@__DIR__, …)) against @__DIR__. | ||
| const unresolved: string[] = [] | ||
| for (const m of src.matchAll(/^[ \t]*include\((.+?)\)[ \t]*(?:#.*)?$/gm)) { | ||
| const arg = m[1].trim() | ||
| const sibling = | ||
| arg.match(/^joinpath\(\s*@__DIR__\s*,\s*"([^"]+)"\s*\)$/)?.[1] ?? | ||
| arg.match(/^"(?!\/)([^"]+)"$/)?.[1] | ||
| if (sibling === undefined) { unresolved.push(`unclassifiable include(${arg})`); continue } | ||
| if (!existsSync(join(scratch, sibling))) unresolved.push(sibling) | ||
| } | ||
| expect( | ||
| unresolved, | ||
| `deployed template can't resolve include(s): ${unresolved.join(', ')} — inline them, or make AGENTS.md copy them into the scratch dir`, | ||
| ).toEqual([]) | ||
| }) | ||
| }) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Does
onFinishedread formulation.toml? Curious if live-finished runs emitformulation: undefinedand only the replay path got the new field. Should we add the same read there?Uh oh!
There was an error while loading. Please reload this page.
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.
Good catch, onFinished (the live-finish path in file_watcher.ts) built the completion as {runId, runDir, status, fidelity}, no formulation. This means live-finished run carried
formulation: undefinedwhich is no-bueno and replayed-already-finished runs do get it.I have pushed a commit with a shared
readFormulation(runDir)for bothingestRunDirandonFinished.readTerminal/completeRunis a third completion path that'll need the same helper when it lands which I noted it on that review too.)