From a15f2ce676000f8b47d9d5321a12189dda8c06c5 Mon Sep 17 00:00:00 2001 From: "operator-stack-publisher[bot]" Date: Sat, 1 Aug 2026 22:21:37 +0000 Subject: [PATCH] Sync Yield from Intelligence Flow @ edca07eaf8a7 --- UPSTREAM.json | 9 ++--- cmd/yskill/main_test.go | 35 +++++++++++++++++-- cmd/yskill/scaffold.go | 22 +++++++++++- evals/results/latest.json | 4 +-- .../2026-08-01-go-scaffold-first-run.md | 7 ++++ 5 files changed, 68 insertions(+), 9 deletions(-) create mode 100644 release-notes/2026-08-01-go-scaffold-first-run.md diff --git a/UPSTREAM.json b/UPSTREAM.json index be7574f..eb9deb9 100644 --- a/UPSTREAM.json +++ b/UPSTREAM.json @@ -4,8 +4,8 @@ "LICENSE": "fff261ce507eabd57666c283a621f33e183a3aedebda04c4ecbc6309a62f5edf", "README.md": "25414dfd686342b2153b63bab6c8a5c9fbab1e5fb80be368b8c43f5161b53b83", "cmd/yskill/main.go": "391d388b1f5ad4eaebcd833d802eca0dcbcb669a876bc9fe6cd57f54e3689732", - "cmd/yskill/main_test.go": "a6f6c5475aebd80bca29434d24ff599bdda7766b3786c41d55f8c44453ed1e0a", - "cmd/yskill/scaffold.go": "e00b024d76ba58bef0f8680147d9a905db565ae6ddd8141bc6718bde22396ed3", + "cmd/yskill/main_test.go": "629a5468f587d9ad69e8147601ab8983db0089fa6856378edb3ab14c1928bfd8", + "cmd/yskill/scaffold.go": "cc528eb8dabb2032ddaf5ac07a54ff5b95a7250c32d6603ec285cc7d8a20619c", "docs/README.md": "cd8a4105f4f04143172661b39789e3c533d031ad46437aa2c078625a29a0a9db", "docs/convert-existing-skill.md": "0dd538e908a1f2d3a1958e4b2cc1efede2a8e7a73341e32c1a75fec69a9acb8a", "docs/examples.md": "3c19bacae7ec7b31bf93417e61d01cd1872f26228fedf0ed6decfce7c41ed274", @@ -59,7 +59,7 @@ "evals/package.json": "84ac7bd7d1c0d1db2233dab54754296195b267e5e907d9f6c402d0d44d569adb", "evals/results/README.md": "65b74bfab83dfc51fc5b8a3a4824c37b722fb3a358a5dcfb217dc2af199f4801", "evals/results/latest-agent.json": "1484174819ae29bbcffeb615036fa165518669525e6d664123f6a38ca3614b69", - "evals/results/latest.json": "ff2bee0e668755d3136b97883ced893b9e0294c003b88252a44604fcc067ffd6", + "evals/results/latest.json": "4fbd1a9322b138cfa0c8518c07daa71a58a8d4c1b590af8bd825a32890bd72cb", "evals/scripts/run.mjs": "119248cd4d383326d396f4459df28c51ce7c31088d97639851f2f5ab4c329892", "evals/scripts/validate.mjs": "7ac2a3239cd1b52a604c8a8a52a1af4ac55c4007ac2751d4fbfe20d0e1f568dc", "examples/convert-skill/SKILL.md": "e6376f34365d4ac030d316db55e91f0c606a501668099f4ecf1e27d43ec806a2", @@ -289,6 +289,7 @@ "release-notes/2026-08-01-evaluation-surface.md": "64fb5e2fdad3ccd41967e028cf4675c45939174000281c443f4b28d96dc07549", "release-notes/2026-08-01-example-library.md": "14d6ca40529a6aeeb72872295e57bb0d7dcc7824df31e029e497602060ce4c97", "release-notes/2026-08-01-first-party-evaluations.md": "9e74c48112343c409a88358138db80d731004f87900f1b23073f16c415163fcf", + "release-notes/2026-08-01-go-scaffold-first-run.md": "3852e7e4eb4289b0de21ed93c96bd217753ecc40b5afd8bcb865f99fa32991c7", "release-notes/2026-08-01-initial-projection.md": "d38f0832b5552fb97237b30d19bb63369442ddde69e678b752ac07eedeb7ba3d", "release-notes/2026-08-01-multi-language-and-converter.md": "d0cf62d191e6a58e827f3b35d442f88b83be4dde98aa25ad54e4ae3ff787a453", "release-notes/2026-08-01-one-package-per-language.md": "6d0d55b4fdcef20332e98c34c1c42c8564aeeeac84647e9f76005b6842d0c91c", @@ -312,7 +313,7 @@ "generator": "operatorstack/yield:project", "schema_version": 1, "source": { - "commit": "4446951aa6a0e3a4fd64fefffacadb8b43252ffa", + "commit": "edca07eaf8a7483829ea03b1c1eed21c323005f7", "path": "labs/22-yield", "repository": "operatorstack/intelligence-flow" } diff --git a/cmd/yskill/main_test.go b/cmd/yskill/main_test.go index 3eeb41d..b4e84ac 100644 --- a/cmd/yskill/main_test.go +++ b/cmd/yskill/main_test.go @@ -53,8 +53,17 @@ func TestParseOnePositionalKeepsFlagFirstOrder(t *testing.T) { func TestScaffoldSkillWritesLanguageSpecificEntrypoints(t *testing.T) { previousVersion := version + previousTidyGoModule := tidyGoModule version = "0.1.9" - t.Cleanup(func() { version = previousVersion }) + tidyCalls := 0 + tidyGoModule = func(string) error { + tidyCalls++ + return nil + } + t.Cleanup(func() { + version = previousVersion + tidyGoModule = previousTidyGoModule + }) tests := []struct { language string @@ -64,7 +73,7 @@ func TestScaffoldSkillWritesLanguageSpecificEntrypoints(t *testing.T) { }{ {"typescript", []string{"main.ts", "package.json", "skill.json"}, "npm exec -- yskill run .", `"@operatorstack/yield": "0.1.9"`}, {"python", []string{"main.py", "requirements.txt", "skill.json"}, "python -m yieldskill run .", "yieldskill==0.1.9"}, - {"go", []string{"main.go", "go.mod"}, "yskill run .", "github.com/operatorstack/yield v0.1.9"}, + {"go", []string{"main.go", "go.mod", "skill.json"}, "yskill run .", "github.com/operatorstack/yield v0.1.9"}, {"rust", []string{"src/main.rs", "Cargo.toml", ".cargo/config.toml", "skill.json"}, "yskill run .", `version = "=0.1.9"`}, } for _, tt := range tests { @@ -98,6 +107,28 @@ func TestScaffoldSkillWritesLanguageSpecificEntrypoints(t *testing.T) { } }) } + if tidyCalls != 1 { + t.Fatalf("go mod tidy calls = %d, want 1", tidyCalls) + } +} + +func TestGoScaffoldCanResolveItsPinnedModuleOnFirstRun(t *testing.T) { + previousVersion := version + previousTidyGoModule := tidyGoModule + version = "0.1.9" + tidyGoModule = func(string) error { return nil } + t.Cleanup(func() { + version = previousVersion + tidyGoModule = previousTidyGoModule + }) + dir := filepath.Join(t.TempDir(), "go-skill") + if err := scaffoldSkill(dir, "go", ""); err != nil { + t.Fatal(err) + } + manifest := readTestFile(t, filepath.Join(dir, "skill.json")) + if manifest != "{\"run\":[\"go\",\"run\",\"-mod=readonly\",\".\"]}\n" { + t.Fatalf("skill.json = %q", manifest) + } } func TestPythonScaffoldUsesInvokingInterpreter(t *testing.T) { diff --git a/cmd/yskill/scaffold.go b/cmd/yskill/scaffold.go index 58bb345..290342b 100644 --- a/cmd/yskill/scaffold.go +++ b/cmd/yskill/scaffold.go @@ -3,6 +3,7 @@ package main import ( "fmt" "os" + "os/exec" "path/filepath" "regexp" "sort" @@ -11,6 +12,16 @@ import ( var releaseVersionPattern = regexp.MustCompile(`^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$`) var unsafePackageCharacter = regexp.MustCompile(`[^a-z0-9_-]+`) +var tidyGoModule = func(dir string) error { + cmd := exec.Command("go", "mod", "tidy") + cmd.Dir = dir + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + return fmt.Errorf("prepare Go scaffold dependencies: %w", err) + } + return nil +} func defaultLanguage() string { if language := strings.TrimSpace(os.Getenv("YIELD_LANGUAGE")); language != "" { @@ -69,6 +80,11 @@ func scaffoldSkill(dir, language, sdkPath string) error { return err } } + if language == "go" { + if err := tidyGoModule(dir); err != nil { + return err + } + } fmt.Printf("init: %s skill %q scaffolded in %s\n", language, name, dir) return nil } @@ -109,7 +125,11 @@ func scaffoldFiles(name, language, sdkPath string) map[string]string { if sdkPath != "" { gomod += fmt.Sprintf("\nreplace github.com/operatorstack/yield => %s\n", sdkPath) } - return map[string]string{"main.go": mainGo, "go.mod": gomod} + return map[string]string{ + "main.go": mainGo, + "go.mod": gomod, + "skill.json": "{\"run\":[\"go\",\"run\",\"-mod=readonly\",\".\"]}\n", + } } } diff --git a/evals/results/latest.json b/evals/results/latest.json index a4948a9..1fcd04c 100644 --- a/evals/results/latest.json +++ b/evals/results/latest.json @@ -1,8 +1,8 @@ { "schema_version": 2, "methodology_version": "1.0", - "generated_at": "2026-08-01T21:57:38.190Z", - "source_digest": "8fba9d25376a73e2a2230d8d10cfe8364a9b2db73e61b6974fa39928956ea9ef", + "generated_at": "2026-08-01T22:15:26.319Z", + "source_digest": "18c4620bc76291a4e8580b488f746cfb0085bf06629cf73ac38c5dbbec4bf099", "status": "passed", "workflow_conformance": { "passed": 40, diff --git a/release-notes/2026-08-01-go-scaffold-first-run.md b/release-notes/2026-08-01-go-scaffold-first-run.md new file mode 100644 index 0000000..7f4e64e --- /dev/null +++ b/release-notes/2026-08-01-go-scaffold-first-run.md @@ -0,0 +1,7 @@ +# Fresh Go scaffolds run immediately + +- Resolve the pinned Yield module when `yskill init` creates a Go workflow. +- Keep later runs read-only so dependency files cannot change after the run is + bound to its source digest. +- Verify a new scaffold completes `yskill test` without a pre-existing + `go.sum` file.