[object Object]

← back to Cli Printing Press

fix(pipeline): match short path declarations

3a850fc59a95c9133178a3f81eb253b2efef01ae · 2026-03-28 00:48:40 -0700 · Trevin Chow

Handle generated `path := "..."` assignments in both scorecard path validity
checks and verification path proof, and add regression tests for each path
extractor.

Files touched

Diff

commit 3a850fc59a95c9133178a3f81eb253b2efef01ae
Author: Trevin Chow <trevin@trevinchow.com>
Date:   Sat Mar 28 00:48:40 2026 -0700

    fix(pipeline): match short path declarations
    
    Handle generated `path := "..."` assignments in both scorecard path validity
    checks and verification path proof, and add regression tests for each path
    extractor.
---
 internal/pipeline/scorecard.go            | 14 ++++-----
 internal/pipeline/scorecard_tier2_test.go | 27 +++++++++++++++++
 internal/pipeline/verify.go               |  2 +-
 internal/pipeline/verify_test.go          | 50 ++++++++++++++++++++++++++++---
 4 files changed, 81 insertions(+), 12 deletions(-)

diff --git a/internal/pipeline/scorecard.go b/internal/pipeline/scorecard.go
index bbaad0fc..a41da843 100644
--- a/internal/pipeline/scorecard.go
+++ b/internal/pipeline/scorecard.go
@@ -50,12 +50,12 @@ type SteinerScore struct {
 	Workflows     int `json:"workflows"`      // 0-10
 	Insight       int `json:"insight"`        // 0-10
 	// Tier 2: Domain Correctness (semantic checks)
-	PathValidity          int `json:"path_validity"`           // 0-10
-	AuthProtocol          int `json:"auth_protocol"`           // 0-10
-	DataPipelineIntegrity int `json:"data_pipeline_integrity"` // 0-10
-	SyncCorrectness       int `json:"sync_correctness"`        // 0-10
-	TypeFidelity          int `json:"type_fidelity"`           // 0-5
-	DeadCode              int `json:"dead_code"`               // 0-5
+	PathValidity          int    `json:"path_validity"`           // 0-10
+	AuthProtocol          int    `json:"auth_protocol"`           // 0-10
+	DataPipelineIntegrity int    `json:"data_pipeline_integrity"` // 0-10
+	SyncCorrectness       int    `json:"sync_correctness"`        // 0-10
+	TypeFidelity          int    `json:"type_fidelity"`           // 0-5
+	DeadCode              int    `json:"dead_code"`               // 0-5
 	Total                 int    `json:"total"`                   // 0-100 (weighted: 50% infrastructure + 50% domain)
 	Percentage            int    `json:"percentage"`              // 0-100
 	CalibrationNote       string `json:"calibration_note,omitempty"`
@@ -883,7 +883,7 @@ func scorePathValidity(dir, specPath string) int {
 		return 5
 	}
 
-	pathRe := regexp.MustCompile(`\bpath\s*[:=]\s*"([^"]+)"`)
+	pathRe := regexp.MustCompile(`\bpath\s*(?::=|=|:)\s*"([^"]+)"`)
 	cmdFiles := sampleCommandFiles(dir, 10)
 	if len(cmdFiles) == 0 {
 		return 0
diff --git a/internal/pipeline/scorecard_tier2_test.go b/internal/pipeline/scorecard_tier2_test.go
index 5d5cb9ca..abb5ec56 100644
--- a/internal/pipeline/scorecard_tier2_test.go
+++ b/internal/pipeline/scorecard_tier2_test.go
@@ -205,6 +205,33 @@ func runSync(store interface {
 	})
 }
 
+func TestScorePathValidity(t *testing.T) {
+	t.Run("matches short variable path declarations used by generated commands", func(t *testing.T) {
+		dir := t.TempDir()
+
+		writeScorecardFixture(t, dir, "internal/cli/links.go", `
+package cli
+
+func runLinks() string {
+	path := "/links"
+	return path
+}
+`)
+
+		specPath := filepath.Join(dir, "spec.json")
+		writeScorecardFixture(t, dir, "spec.json", `{
+  "paths": {
+    "/links": {}
+  },
+  "components": {
+    "securitySchemes": {}
+  }
+}`)
+
+		assert.Equal(t, 10, scorePathValidity(dir, specPath))
+	})
+}
+
 func TestScoreTypeFidelity(t *testing.T) {
 	t.Run("scores wrong id flag types and dummy guards low", func(t *testing.T) {
 		dir := t.TempDir()
diff --git a/internal/pipeline/verify.go b/internal/pipeline/verify.go
index c506de84..49a9a839 100644
--- a/internal/pipeline/verify.go
+++ b/internal/pipeline/verify.go
@@ -104,7 +104,7 @@ func (v *Verifier) CompileGate() error {
 }
 
 var (
-	verifyPathAssignRe = regexp.MustCompile(`(?m)\bpath\s*[:=]\s*"([^"]+)"`)
+	verifyPathAssignRe = regexp.MustCompile(`(?m)\bpath\s*(?::=|=|:)\s*"([^"]+)"`)
 	verifyClientCallRe = regexp.MustCompile(`c\.(Get|Post|Patch|Delete|Put)\s*\(\s*"([^"]+)"`)
 )
 
diff --git a/internal/pipeline/verify_test.go b/internal/pipeline/verify_test.go
index a7490591..e275159b 100644
--- a/internal/pipeline/verify_test.go
+++ b/internal/pipeline/verify_test.go
@@ -58,6 +58,48 @@ func bogusGet() {
 	assert.Equal(t, 1, invalidCount, "one path should be hallucinated")
 }
 
+func TestPathProof_DetectsShortDeclarationPaths(t *testing.T) {
+	dir := t.TempDir()
+	setupVerifierDirs(t, dir)
+
+	writeTestFile(t, filepath.Join(dir, "internal", "cli", "users_get.go"), `package cli
+func usersGet() {
+	path := "/users/{id}"
+}
+`)
+	writeTestFile(t, filepath.Join(dir, "internal", "cli", "bogus_get.go"), `package cli
+func bogusGet() {
+	path := "/bogus/endpoint"
+}
+`)
+
+	specPath := filepath.Join(dir, "spec.json")
+	writeTestFile(t, specPath, `{
+  "paths": {
+    "/users/{user_id}": {}
+  },
+  "components": { "securitySchemes": {} }
+}`)
+
+	v, err := NewVerifier(dir, specPath)
+	require.NoError(t, err)
+
+	results := v.PathProof()
+	require.Len(t, results, 2)
+
+	var validCount, invalidCount int
+	for _, r := range results {
+		if r.InSpec {
+			validCount++
+		} else {
+			invalidCount++
+			assert.Equal(t, "/bogus/endpoint", r.Path)
+		}
+	}
+	assert.Equal(t, 1, validCount, "one short-declared path should be in spec")
+	assert.Equal(t, 1, invalidCount, "one short-declared path should be hallucinated")
+}
+
 func TestPathProof_SkipsLocalCommands(t *testing.T) {
 	dir := t.TempDir()
 	setupVerifierDirs(t, dir)
@@ -490,9 +532,9 @@ func initFlags(flags *rootFlags) {
 
 func TestDeriveVerificationVerdict(t *testing.T) {
 	tests := []struct {
-		name    string
-		report  *VerificationReport
-		want    string
+		name   string
+		report *VerificationReport
+		want   string
 	}{
 		{
 			name: "hallucinated paths -> FAIL",
@@ -541,7 +583,7 @@ func TestDeriveVerificationVerdict(t *testing.T) {
 			want: "WARN",
 		},
 		{
-			name: "all clean -> PASS",
+			name:   "all clean -> PASS",
 			report: &VerificationReport{},
 			want:   "PASS",
 		},

← 0dca872a fix(skill): preserve codex fix delegation  ·  back to Cli Printing Press  ·  fix(pipeline): clean generated cli artifacts 421c81bd →