Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions cli/session/pipeline_phase.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package session

// PipelinePhase identifies the step of the Agentless-style pipeline
// (localize → repair → validate) that a session turn belongs to.
//
// These string constants mirror hawk-core-contracts/sessions.Phase so that
// cost records emitted by trace can be correlated with hawk's tok.Tracker
// AggregateByPhase output without importing the contracts package
// (trace is a standalone CLI, not part of the hawk Go module graph).
type PipelinePhase string

const (
// PipelinePhaseLocalize is the file/symbol identification phase.
PipelinePhaseLocalize PipelinePhase = "localize"
// PipelinePhaseRepair is the patch generation phase.
PipelinePhaseRepair PipelinePhase = "repair"
// PipelinePhaseValidate is the test/lint verification phase.
PipelinePhaseValidate PipelinePhase = "validate"
// PipelinePhaseReview is code review; the most token-intensive phase
// at 59.4% of total spend (Tokenomics paper, arXiv 2601.14470).
PipelinePhaseReview PipelinePhase = "review"
// PipelinePhaseUnknown is the zero value for unattributed turns.
PipelinePhaseUnknown PipelinePhase = ""
)

// ParsePipelinePhase returns the PipelinePhase matching s, or
// PipelinePhaseUnknown if unrecognised. Matching is case-sensitive to
// stay consistent with the contracts package and JSON encoding.
func ParsePipelinePhase(s string) PipelinePhase {
switch PipelinePhase(s) {
case PipelinePhaseLocalize, PipelinePhaseRepair,
PipelinePhaseValidate, PipelinePhaseReview:
return PipelinePhase(s)
}
return PipelinePhaseUnknown
}
39 changes: 39 additions & 0 deletions cli/session/pipeline_phase_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package session_test

import (
"testing"

"github.com/GrayCodeAI/trace/cli/session"
)

func TestParsePipelinePhase_Known(t *testing.T) {
cases := []struct {
input string
want session.PipelinePhase
}{
{"localize", session.PipelinePhaseLocalize},
{"repair", session.PipelinePhaseRepair},
{"validate", session.PipelinePhaseValidate},
{"review", session.PipelinePhaseReview},
}
for _, tc := range cases {
got := session.ParsePipelinePhase(tc.input)
if got != tc.want {
t.Errorf("ParsePipelinePhase(%q) = %q, want %q", tc.input, got, tc.want)
}
}
}

func TestParsePipelinePhase_Unknown(t *testing.T) {
for _, s := range []string{"", "unknown", "LOCALIZE", "Repair"} {
if got := session.ParsePipelinePhase(s); got != session.PipelinePhaseUnknown {
t.Errorf("ParsePipelinePhase(%q) = %q, want PipelinePhaseUnknown", s, got)
}
}
}

func TestPipelinePhaseString(t *testing.T) {
if string(session.PipelinePhaseReview) != "review" {
t.Errorf("PipelinePhaseReview string = %q, want %q", session.PipelinePhaseReview, "review")
}
}