Documentation
¶
Index ¶
- Constants
- func AllAngles() []int
- func AllEventTypes() []string
- func AllNotifyLevels() []string
- func AtomicWriteFile(dir, finalName, tmpPattern string, data []byte, perm os.FileMode) error
- func BoolPtr(b bool) *bool
- func BoolVal(p *bool) bool
- func DefaultAngleMapping() map[string][]int
- func DefaultProfiles() map[string]ProfileConfig
- func EffectiveHubRepos(cfg Config) []string
- func EffectiveManual(runOverrides map[Phase]PhaseSpec, phase Phase, manualRunner string) (runnerManual, modelManual string)
- func GroupReviewAngles(parallelReviewers, anglesPerReviewer, totalAngles int) [][]int
- func GroupSelectedAngles(parallelReviewers, anglesPerReviewer int, angles []int) [][]int
- func HumanSize(bytes int64) string
- func Init(root string, cfg Config) error
- func IsSelectablePhase(phase Phase) bool
- func IsSimilarFeature(a, b string) bool
- func IsSimilarFeatureThreshold(a, b string, threshold float64) bool
- func MergeHooks(global, featureHooks map[string][]feature.HookEntry) map[string][]feature.HookEntry
- func NotificationsEnabled(cfg Config) bool
- func ParseReportIssues(report string) (passed bool, issues []string)
- func PhaseToStatus(phase Phase) feature.Status
- func ProcessAlive(pid int) bool
- func ResolveAngleMapping(cfg Config) map[string][]int
- func ResolveAnglesPerReviewer(cfg Config, role Role) int
- func ResolveDeepModel(cfg Config, runnerName string, role Role) (string, error)
- func ResolveFeatureRepoPaths(f feature.Feature, cfg Config, root string) map[string]string
- func ResolveMaxDiscoveredFeatures(cfg Config) int
- func ResolveMaxFixRounds(cfg Config, role Role) int
- func ResolveMiniCoderModel(cfg Config, runnerName, fallbackModel string) (string, error)
- func ResolveModel(cfg Config, runnerName string, role Role) (string, error)
- func ResolveParallelReviewers(cfg Config, role Role) int
- func ResolvePhaseModel(cfg Config, f feature.Feature, pc ProfileConfig, phase Phase, role Role, ...) (string, error)
- func ResolvePhaseRunner(cfg Config, f feature.Feature, pc ProfileConfig, phase Phase, manual string) (string, error)
- func ResolveRepoPaths(cfg Config, root string) map[string]string
- func ResolveTierModel(cfg Config, runnerName, tier string) (string, error)
- func ScanFailPatterns(ws *Workspace, features []feature.Feature, minOccurrences int) ([]Candidate, []CandidateLearning)
- func ScreenshotDir(cfg Config) string
- func SupportedRunnerMap() map[string]RunnerConfig
- func UserConfigPath() (string, error)
- func ValidateConfig(c Config) error
- func ValidateState(s State) error
- func WriteConfig(dotDir string, cfg Config) error
- func WriteUserConfig(cfg UserConfig) error
- type ACEvidence
- type AngleMatch
- type AngleSelection
- type Baseline
- type BaselineRepo
- type CachedWorkspace
- type Candidate
- type CandidateLearning
- type CandidatePool
- type CandidateSource
- type ChangedFile
- type CleanCandidate
- type Config
- type DesignDoc
- type DiscoveredFeature
- type Escalation
- type Event
- type EvolutionConfig
- type HealthCheck
- type IssueTrackerConfig
- type ManualCheck
- type ManualCheckResult
- type Phase
- type PhaseSpec
- type ProfileConfig
- func (pc ProfileConfig) EnabledPhaseNames() []string
- func (pc ProfileConfig) EnablesPhase(phase Phase) bool
- func (pc ProfileConfig) EnablesRole(role Role) bool
- func (pc ProfileConfig) HasPhase(phase Phase) bool
- func (pc ProfileConfig) RoleArtifactView(role Role) RoleArtifactView
- func (pc *ProfileConfig) UnmarshalJSON(data []byte) error
- type ProjectConfig
- type RepoConfig
- type ResolvedPhase
- type ReviewIssue
- type ReviewResult
- type Role
- type RoleArtifactView
- type RoleConfig
- type RoleContract
- type RunnerConfig
- type RunnerPreset
- type SelfModSettings
- type Severity
- type State
- type SubPhase
- type TestProfileOverride
- type TestStrategy
- type UserConfig
- type VerifyCommand
- type VerifyEvidence
- type Workspace
- func (w *Workspace) AppendEvent(featureID string, evt Event) error
- func (w *Workspace) CleanFeature(featureID string) (int64, error)
- func (w *Workspace) CleanableFeatures() ([]CleanCandidate, error)
- func (w *Workspace) ClearStopSignal(featureID string) error
- func (w *Workspace) CompareBacklogMirror() ([]feature.BacklogDrift, error)
- func (w *Workspace) DiscoverScreenshots(featureID, screenshotDir string) ([]feature.ScreenshotGroup, error)
- func (w *Workspace) DotDir() string
- func (w *Workspace) FeatureDir(featureID string) string
- func (w *Workspace) InitFeatureDir(featureID string) error
- func (w *Workspace) ListFeatures() ([]feature.Feature, error)
- func (w *Workspace) LoadFeature(id string) (feature.Feature, error)
- func (w *Workspace) LoadMergedConfig() (Config, error)
- func (w *Workspace) ReadBacklogMirror() (feature.BacklogMirror, bool, error)
- func (w *Workspace) ReadConfig() (Config, error)
- func (w *Workspace) ReadState(featureID string) (State, error)
- func (w *Workspace) ReadTestStrategy(featureID string) (TestStrategy, error)
- func (w *Workspace) ReconcileActive(featureID string, s *State) error
- func (w *Workspace) RequestStop(featureID string) error
- func (w *Workspace) ResolveFeatureID(prefix string) (string, error)
- func (w *Workspace) RoundDir(featureID string, round int) string
- func (w *Workspace) SaveFeature(f feature.Feature) error
- func (w *Workspace) StopRequested(featureID string) bool
- func (w *Workspace) SyncFeatureStatus(featureID string, phase Phase) error
- func (w *Workspace) TotalCost(featureID string) (float64, error)
- func (w *Workspace) WorktreePath(featureID string) string
- func (w *Workspace) WriteState(featureID string, s State) error
- type WorkspaceConfig
- type WorkspaceReader
- type WorktreeConfig
Constants ¶
const ( NotifySuccess = "success" // run 正常結束(done / pending-review) NotifyError = "error" // 失敗或 guard 攔截 NotifyWarning = "warning" // 中斷或 escalation )
通知等級常量,供 server 端標注 Event.Notify 及前端判斷顯示樣式,避免散落字串。
const ( DirName = ".4x" UserConfigDir = ".4x" UserConfigFile = "settings.json" BacklogFile = "feature_list.json" ConfigFile = "settings.json" FeaturesDir = "features" StateFile = "state.json" EventsFile = "events.jsonl" BaselineFile = "baseline.json" RoundsDir = "rounds" // DesignRoundsDir 存放 designer/design-reviewer 循環(design-reviewing FAIL 打回 // designing)每一輪的 task-brief.md/acceptance-criteria.md/design-review-report.md // 快照,避免這些固定檔名的 artifact 被下一輪覆寫、dashboard message 區看不到歷史。 DesignRoundsDir = "design-rounds" FinalReport = "final-report.md" TaskBrief = "task-brief.md" Criteria = "acceptance-criteria.md" TestStratFile = "test-strategy.yaml" DesignReviewReport = "design-review-report.md" ReviewReport = "review-report.md" DeepReviewReport = "deep-review-report.md" CoderReport = "coder-report.md" FixerReport = "fixer-report.md" TestReport = "test-report.md" VerifyFile = "verify.json" BuildGateFile = "build-gate.json" DocsGateFile = "docs-gate.json" GuardFeedback = "guard-feedback.json" EscalationFile = "escalation.json" StopFile = "stop" // CandidatesFile 是 .4x/candidates.json,history miner(4x mine)掃描歷史失敗訊號後 // 產出的 candidate pool(候選 feature + 候選 learnings),供後續 F097 閘門決定是否升級。 RunDir = "run" CandidatesFile = "candidates.json" // F097 evolve 價值閘門相關檔名(皆在 .4x/ 根,CandidatePool 格式)。 GateInputFile = "gate-input.json" // PRE-veto 倖存者,供 gate role 讀 GateVerdictsFile = "gate-verdicts.json" // gate role 產出的價值判斷 AcceptedCandidatesFile = "accepted-candidates.json" // POST-veto 通過者,附 value_score/why_not_hack // F099 evolve driver 相關檔名(皆在 .4x/ 根,非 per-feature)。 EvolveReportFile = "evolve-report.md" // 每輪 evolve pipeline 的摘要報告(dashboard surface) EvolveStateFile = "evolve-state.json" // anti-spin 防空轉跨呼叫持久化計數 // retro learnings 相關檔名。 LearningsFile = "learnings.json" // .4x/learnings.json,跨 feature 累積的 learnings 庫 LearningsContextFile = "learnings-context.md" // .4x/learnings-context.md,active learnings 的 markdown snapshot RetroLearningsFile = "retro-learnings.json" // .4x/{feature-id}/retro-learnings.json,Acceptor 產出 RoleLearningsFileName = "role-learnings.json" // 舊版單一固定檔名,harvester 仍讀取以相容既有 run 目錄 RoleLearningsGlob = "*-learnings.json" // rounds/round-{n}/{role}-learnings.json,各角色獨立檔名的 glob ConsolidateInputFile = "consolidate-input.json" // .4x/consolidate-input.json,供 consolidate runner 讀 ConsolidateResultFile = "consolidate-result.json" // .4x/consolidate-result.json,consolidate runner 產出 // RoundsSummaryFile 是舊輪次摘要,在 round ≥ 3 進入 accepting 前由 round-summarizer 產出。 // Acceptor 讀此檔取代讀取所有輪次全文,節省 context。 RoundsSummaryFile = "rounds-summary.md" // DeepReviewAnglesFile 是 deep review 角度選擇結果的 artifact,記錄本次選了哪些角度及原因。 DeepReviewAnglesFile = "deep-review-angles.json" // ReviewPackage 是 orchestrator 在 coding/amending → reviewing 轉換時預算的 diff 彙整檔 // (commits/file-stat/full-diff),供 reviewer/deep-reviewer 讀檔取代自跑 git diff/log。 ReviewPackage = "review-package.md" // AcceptanceSummaryFile 是 orchestrator 在進 accepting 前彙整各報告產出的檔案, // 供 Acceptor 讀取取代重複讀取 review/test/deep-review report 全文。 AcceptanceSummaryFile = "acceptance-summary.md" )
const DeepReviewAngleCount = 11
DeepReviewAngleCount 是 deep-reviewer 模板定義的 review angle 總數(angle 1..11)。 平行 deep review 依此把 angle 平均分配給各 sub-reviewer。
const DefaultDeepTier = "opus"
DefaultDeepTier 是 deep_model 未設定時的 fallback tier。 full profile 包含 deep-reviewing,即使未明確設定 deep_model, 只要 runner 能解析此 tier 就會自動啟用 deep review。
const DefaultFailPatternThreshold = 3
DefaultFailPatternThreshold 是 fail-pattern 掃描器把一群相似 issue 升級為 candidate 所需的「不同 feature 數」門檻預設值。由 4x mine 的 --min-occurrences flag 覆寫。
Variables ¶
This section is empty.
Functions ¶
func AllAngles ¶ added in v0.3.0
func AllAngles() []int
AllAngles 回傳完整的 1..DeepReviewAngleCount angle 清單。
func AllEventTypes ¶ added in v0.3.6
func AllEventTypes() []string
AllEventTypes 回傳 production 實際發出的 event type 集合(enum SoT)。 以全庫 grep production 程式碼(Type: "..." composite literal 與 pipeOutput(...,type) helper)為準,不以現有 schema enum 為準;schema 曾列出的 phase-end/step/verify/scope-check/blocked/heartbeat/subtask-done 在 production 無任何 emitter,故不列入。
func AllNotifyLevels ¶ added in v0.3.6
func AllNotifyLevels() []string
AllNotifyLevels 回傳 Event.Notify 的合法值(enum SoT)。
func AtomicWriteFile ¶ added in v0.2.0
AtomicWriteFile 以「同目錄 temp file + os.Rename」原子寫入 finalName。
直接 os.WriteFile 會先 truncate 再寫,這段空窗期內 concurrent 的讀者可能讀到 截斷或半寫的內容而解析失敗。改用同目錄 temp file(tmpPattern 為 os.CreateTemp 的 pattern)寫完再 atomic rename 覆蓋,讓讀者永遠看到完整的舊檔或完整的新檔。
temp file 必須與目標同目錄以確保位於同一 filesystem,os.Rename 才保證 atomic。 payload 的結尾換行等差異由呼叫端在 data 內自行決定。
func DefaultAngleMapping ¶ added in v0.3.0
DefaultAngleMapping 回傳預設的 diff 路徑到 deep review angle 的映射表。 key 為路徑前綴;以 "*" 開頭的 key 為後綴匹配(如 "*_test.go")。
func DefaultProfiles ¶
func DefaultProfiles() map[string]ProfileConfig
DefaultProfiles 回傳內建 pipeline profile,作為 auto-select 與 fallback 用。
- full:完整 8 phase,適合高風險功能(金流、結算、核心協議)
- lite:designing → coding → testing,有設計有驗證但省略所有 review 層,token 約 full 的 40%
- normal:coding → reviewing → testing → accepting,已知要做什麼時跳過設計階段
- quick:coding → reviewing,最精簡的 code + review
刻意不在此預填各 phase 的 Model tier:PhaseSpec.Model 的消費路徑(ResolvePhaseModel, 見 override.go)已確認存在且正確運作——resolveRunnerAndModel 呼叫它,per-phase/per-feature 的 model 覆寫today就能生效。但把具體 tier 值(如 "opus")寫死進這裡會是影響所有未自訂 settings.json 專案的全域預設變更:測試過程中發現,Model tier 名稱與 deep-reviewing 的 DefaultDeepTier fallback(見 deep_review.go)共用同一份 runner tiers 設定,導致原本因缺少 "opus" tier 而略過 deep-review 的既有測試/部署,會在毫無預警下開始執行 deep-review、 進而影響 phase 數量與流程;且對 coding/testing/fixing/accepting 填 "sonnet" 也是 no-op (defaultTier 本就是 "sonnet")。故建議 per-role model 路由交由專案 settings.json 的 roles/profiles 區塊自行設定(本專案 .4x/settings.json 已這樣做:designer.model=opus、 reviewer.deep_model=opus),而非在 Go 內建預設值寫死,避免非預期的全域行為變更。
func EffectiveHubRepos ¶
EffectiveHubRepos 合併 Config.HubRepos 與 workspace config 中 Hub: true 的 repo。
func EffectiveManual ¶ added in v0.2.0
func EffectiveManual(runOverrides map[Phase]PhaseSpec, phase Phase, manualRunner string) (runnerManual, modelManual string)
EffectiveManual 計算某 phase 的「有效手動覆寫」:把本次 run 的 per-phase 臨時覆寫 (runOverrides,覆寫優先序最高層)疊在全域 manualRunner(--runner)之上。
- runnerManual:該 phase 有覆寫且 Runner 非空時取覆寫值,否則沿用 manualRunner。
- modelManual:該 phase 有覆寫且 Model 非空時取覆寫值,否則為空(沿用下層解析)。
計算結果作為 ResolvePhaseRunner / ResolvePhaseModel 的 manual 參數傳入, 不改動 F090 既有的解析語意——只是在最高層多疊一層臨時覆寫。
func GroupReviewAngles ¶
GroupReviewAngles 把 1..totalAngles 的 review angle 切分給 parallelReviewers 個 sub-reviewer, 回傳每個 sub-reviewer 負責的 angle 編號清單(1-based、連續、不重複、完整覆蓋)。
切分規則:anglesPerReviewer > 0 時以它為每組固定大小依序切(最後一組可能較少); anglesPerReviewer <= 0 時用 ceil(totalAngles/parallelReviewers) 平均分配。 parallelReviewers <= 1 或 totalAngles <= 0 時回傳 nil(由 caller 走 fallback 單 agent)。 實際產生的非空組數可能少於 parallelReviewers(angle 不夠分時)。
func GroupSelectedAngles ¶ added in v0.3.0
GroupSelectedAngles 把指定的 angle 清單切分給 parallelReviewers 個 sub-reviewer, 回傳每個 sub-reviewer 負責的 angle 編號清單。 parallelReviewers <= 1 或 angles 為空時回傳 nil(走 fallback 單 agent)。
func IsSelectablePhase ¶ added in v0.2.0
IsSelectablePhase 回報某 phase 是否屬於 profile 可選的工作 phase 白名單。
func IsSimilarFeature ¶
IsSimilarFeature 判斷兩段文字是否相似:將文字正規化(小寫、去標點、切 token)後 計算 Jaccard token overlap,>= similarityThreshold(0.6)視為相似。
func IsSimilarFeatureThreshold ¶ added in v0.2.0
IsSimilarFeatureThreshold 同 IsSimilarFeature,但相似門檻可由呼叫端指定(如 F097 的 dedup_threshold)。 任一方無 token 或 union 為 0 時回 false。
func MergeHooks ¶
MergeHooks 合併全域和 feature 的 hooks,feature 同名 key 整組替換全域。 兩者皆為 nil 時回傳 nil;否則複製 global 所有 key,再由 featureHooks 的 key 整組覆蓋。
func NotificationsEnabled ¶ added in v0.1.10
NotificationsEnabled 回報合併後設定是否啟用 OS 通知。 Notifications 為 nil(使用者未設定)時預設啟用,回傳 true。
func ParseReportIssues ¶ added in v0.2.0
ParseReportIssues 解析 review-report.md / deep-review-report.md,回傳 verdict 是否 PASS 及所有 issue 標題。issue 取行首 [CRITICAL] / ### [CRITICAL] / #### [CRITICAL](WARNING 同規則) 之後的文字;verdict 取 "## Verdict" 段第一個非空行是否以 PASS / CONDITIONAL PASS 開頭。 在 protocol 層獨立實作,不依賴 cmd/4x 的 parseReviewVerdict。
func PhaseToStatus ¶
PhaseToStatus 將 state machine 的 Phase 映射為面向 dashboard 的 feature.Status
func ResolveAngleMapping ¶ added in v0.3.0
ResolveAngleMapping 從 config 讀取 deep-reviewer 的 angle mapping; 未設定時回傳 DefaultAngleMapping。
func ResolveAnglesPerReviewer ¶
ResolveAnglesPerReviewer 解析每個 sub-reviewer 負責的 review angle 數量。 讀取 cfg.Roles[role].AnglesPerReviewer(role 一般為 RoleDeepReviewer); 未設定或 <= 0 時回傳 0,由 GroupReviewAngles 改用 ceil(總 angle/N) 平均分配。
func ResolveDeepModel ¶
ResolveDeepModel 解析 role 的 deep_model tier,回傳 runner 認識的 model name。 若 role 未設 deep_model,回傳空字串與 nil error(表示不需要 deep model)。 caller(如 runDeepReviewPhase)可自行用 ResolveTierModel + DefaultDeepTier 做 fallback。
func ResolveFeatureRepoPaths ¶
ResolveFeatureRepoPaths 解析 feature 涉及的 repo name → absolute path。 feature.Repos 為空時:multi-repo 回傳所有 workspace repos,monorepo 回傳 {".": root}。
func ResolveMaxDiscoveredFeatures ¶
ResolveMaxDiscoveredFeatures 回傳自動建立 feature 的數量上限: cfg.MaxDiscoveredFeatures > 0 時用該值,否則套預設值(3)。
func ResolveMaxFixRounds ¶
ResolveMaxFixRounds 解析 deep-reviewing phase 自癒循環的最大修正輪數。 讀取 cfg.Roles[role].MaxFixRounds(role 一般為 RoleDeepReviewer); 未設定或 <= 0 時回傳預設 defaultMaxFixRounds(2)。
func ResolveMiniCoderModel ¶ added in v0.4.0
ResolveMiniCoderModel 解析 deep-reviewing / reviewing 自癒循環中 mini-coder 使用的 model name。 mini-coder 是 coding 性質的子 role,預設沿用 coder 已解析出的 model(fallbackModel),確保未特別 設定時行為不變;若使用者在 roles.mini-coder.model 明確設定 tier,則以該設定優先,讓 mini-coder 可 獨立於 coder 做 per-role model 路由。fallbackModel 由 caller 以 coder 的 ResolvePhaseModel 結果傳入。
func ResolveModel ¶
ResolveModel 根據抽象 tier 解析出指定 runner 認識的 model name。 優先序:runners[name].tiers[tier] > model_tiers[tier][runner] > error。 若 tier 在兩處都找不到對應,回傳 error 而非 pass through tier name。
func ResolveParallelReviewers ¶
ResolveParallelReviewers 解析平行 deep review 要 spawn 的 sub-reviewer 數量。 讀取 cfg.Roles[role].ParallelReviewers(role 一般為 RoleDeepReviewer); 未設定或 <= 0 時回傳 1,代表 fallback 單 agent 模式(不分檔、不跑 synthesizer)。
func ResolvePhaseModel ¶ added in v0.2.0
func ResolvePhaseModel(cfg Config, f feature.Feature, pc ProfileConfig, phase Phase, role Role, runnerName, manual string) (string, error)
ResolvePhaseModel 依統一覆寫優先序解析某 phase 實際使用的 model name。
tier 優先序(高→低):
- manual:4x run 手動帶入的 model tier,空字串代表未手動指定。
- f.PhaseOverrides[phase].Model:feature YAML 對此 phase 的覆寫。
- profile 對應 PhaseSpec.Model:profile 對此 phase 的覆寫。
- 以上皆空 → fallback 回 ResolveModel(roles[role].Model → runner.Model → defaultTier)。
取得 tier 後一律用 runner 的 tiers / model_tiers 解析為實際 model name; 解析不到回 error(沿用 ResolveModel 的錯誤語意)。
func ResolvePhaseRunner ¶ added in v0.2.0
func ResolvePhaseRunner(cfg Config, f feature.Feature, pc ProfileConfig, phase Phase, manual string) (string, error)
ResolvePhaseRunner 依統一覆寫優先序解析某 phase 實際使用的 runner 名稱。
優先序(高→低):
- manual:4x run 手動帶入(--runner flag),空字串代表未手動指定。
- f.PhaseOverrides[phase].Runner:feature YAML 對此 phase 的覆寫。
- profile 對應 PhaseSpec.Runner:profile 對此 phase 的覆寫。
- cfg.Default:default_runner。
解析結果必須存在於 cfg.Runners,否則回 error。
func ResolveRepoPaths ¶
ResolveRepoPaths 從 workspace config 解析 repo name → absolute path。 monorepo 模式回傳 {"." : root}。
func ResolveTierModel ¶ added in v0.2.2
ResolveTierModel 把抽象 tier 解析為指定 runner 認識的實際 model name。 優先序:runners[name].tiers[tier] > model_tiers[tier][runner] > error。 供 ResolveModel、ResolvePhaseModel 共用,也供 caller 對 DefaultDeepTier 做 fallback 解析。
func ScanFailPatterns ¶ added in v0.2.0
func ScanFailPatterns(ws *Workspace, features []feature.Feature, minOccurrences int) ([]Candidate, []CandidateLearning)
ScanFailPatterns 走訪每個 feature 每個 round 的 review-report.md 與 deep-review-report.md, 對 verdict 非 PASS 的報告蒐集其 issue 標題,用 IsSimilarFeature(Jaccard)跨 feature 聚類, 統計每群涵蓋的「不同 feature 數」(同一 feature 多輪只算一次)。涵蓋數 >= minOccurrences 的群 升級為一筆 candidate,並同時產出一筆 CategoryReview 的 CandidateLearning。 best-effort:讀檔失敗只 slog.Warn 後略過。 features 由呼叫端傳入,避免重複呼叫 ListFeatures。
func ScreenshotDir ¶
ScreenshotDir 從 config 取得 tester 的截圖目錄,fallback 到 feature.DefaultScreenshotDir。
func SupportedRunnerMap ¶
func SupportedRunnerMap() map[string]RunnerConfig
SupportedRunnerMap 回傳 name → RunnerConfig 的 map
func UserConfigPath ¶
UserConfigPath 回傳 ~/.4x/settings.json 的路徑
func ValidateConfig ¶ added in v0.1.11
ValidateConfig 驗證 Config 結構的合法性,回傳所有錯誤的彙整。
func ValidateState ¶ added in v0.1.11
ValidateState 驗證 State 結構的關鍵欄位。
func WriteConfig ¶
WriteConfig 寫入 .4x/settings.json
func WriteUserConfig ¶
func WriteUserConfig(cfg UserConfig) error
WriteUserConfig 寫入 ~/.4x/settings.json
Types ¶
type ACEvidence ¶ added in v0.3.0
type ACEvidence struct {
ID string `json:"id"`
Passed bool `json:"passed"`
Evidence []string `json:"evidence"`
VerifyType string `json:"verify_type,omitempty"` // Tester 寫入供記錄;Guard 從 TestStrategy.ACVerifyMap 判斷
}
ACEvidence 是單一 acceptance criterion 的驗證結果
type AngleMatch ¶ added in v0.3.0
type AngleMatch struct {
File string `json:"file"`
Rule string `json:"rule"`
Angles []int `json:"angles"`
}
AngleMatch 描述單一變更檔案匹配到的 mapping 規則與其貢獻的 angle 編號。
func SelectDeepReviewAngles ¶ added in v0.3.0
func SelectDeepReviewAngles(mapping map[string][]int, files []ChangedFile) ([]int, []AngleMatch)
SelectDeepReviewAngles 根據變更檔案路徑和 mapping 表選出應執行的 deep review angle。 每個檔案匹配最長前綴(或後綴規則),取該規則的 angle 清單; 所有檔案的 angle 取聯集並升冪排序。無任何檔案匹配時回傳全部 1..DeepReviewAngleCount。
type AngleSelection ¶ added in v0.3.0
type AngleSelection struct {
SelectedAngles []int `json:"selected_angles"`
TotalAngles int `json:"total_angles"`
ForceAll bool `json:"force_all"`
Matches []AngleMatch `json:"matches"`
}
AngleSelection 是 deep review 角度選擇結果,序列化為 deep-review-angles.json 供 resume 與稽核。
type Baseline ¶
type Baseline struct {
CreatedAt time.Time `json:"createdAt"`
Repos []BaselineRepo `json:"repos"`
}
Baseline 是 baseline.json 的結構
type BaselineRepo ¶
type BaselineRepo struct {
Name string `json:"name"`
Path string `json:"path"`
Branch string `json:"branch"`
Head string `json:"head"`
DirtyFiles []string `json:"dirtyFiles"`
}
BaselineRepo 是 baseline 中每個 repo 的快照
type CachedWorkspace ¶
type CachedWorkspace struct {
*Workspace
// contains filtered or unexported fields
}
CachedWorkspace 在 *Workspace 上加一層 mtime-based in-memory cache,供 long-running dashboard server 使用,減少每次 API 請求重複 parse 大量 YAML/JSON。
失效策略完全靠檔案 mtime 比對:每次讀取先用 os.Stat / os.ReadDir 取 metadata, 與 cache 記錄的 mtime 相同才回傳 cache,否則重新 parse。因此寫入端(SaveFeature / WriteState 等)無需主動通知 cache,下次讀取自動偵測變動。
為避免 stat→parse 之間檔案被改動造成「cache 記錄的 mtime 與資料版本不一致」 (存舊 mtime → 永久 miss;存新 mtime 配舊資料 → 回傳 stale),所有 override 方法採 stat→parse→stat:唯有 parse 前後兩次 mtime 一致才寫入 cache,不一致則 略過 cache(仍回傳這次讀到的正確資料),由下次讀取重試。
透過 Go embedding 滿足 WorkspaceReader 並沿用 *Workspace 的所有其他方法; 僅 ListFeatures / LoadFeature / ReadConfig 被 override 加上 cache。ReadState 刻意不 cache(頻繁變化、檔案小、parse 快)。
注意:Go embedding 無虛擬分派,*Workspace 內部方法呼叫的 w.ListFeatures() 等 仍走原版、不命中 cache,這是已知且可接受的限制(那些路徑非 server hot-path)。
func NewCachedWorkspace ¶
func NewCachedWorkspace(ws *Workspace) *CachedWorkspace
NewCachedWorkspace 建立一個包裝 ws 的 CachedWorkspace,初始 cache 為空。
func (*CachedWorkspace) ListFeatures ¶
func (c *CachedWorkspace) ListFeatures() ([]feature.Feature, error)
ListFeatures 列出所有 feature;features 目錄內容或任一 .yaml 的 mtime 改變時重新 parse。 回傳的是 cache 的 shallow copy:slice 結構與 value 欄位已隔離(增刪元素、改 Name 等 不影響 cache),但 Feature 的 reference 欄位(Repos / Subtasks / Rules / Depends / Hooks / Priority)仍與 cache 共用底層;呼叫端切勿就地修改這些欄位內容,否則會污染 cache 且不受 c.mu 保護。
func (*CachedWorkspace) LoadFeature ¶
func (c *CachedWorkspace) LoadFeature(id string) (feature.Feature, error)
LoadFeature 讀取單一 feature;對應 YAML 的 mtime 未變時回傳 cache。
短 ID(如 "F078",無 slug 後綴)無法用 id+".yaml" 直接命中檔案,此時委派給 非 cache 版 Workspace.LoadFeature(內含 resolveFeatureFile 短 ID 解析),該路徑 每次重新 parse、不建 cache 條目,目標是「短 ID 至少能正確解析」。
回傳值一律經 Clone 深拷貝,與 cache 內存版本不共用任何 slice/map, 呼叫端就地修改不會污染 cache。
func (*CachedWorkspace) LoadMergedConfig ¶
func (c *CachedWorkspace) LoadMergedConfig() (Config, error)
LoadMergedConfig 讀取 project config(走 cache 版 ReadConfig)並合併 user config。 必須 override 而非沿用 embedded *Workspace 版本——Go embedding 無虛擬分派, *Workspace.LoadMergedConfig 內部呼叫的是非 cache 的 w.ReadConfig,會 bypass cache。 語意與 *Workspace.LoadMergedConfig 一致:project config 失敗回 error 不做 user merge, user config 失敗印 slog.Warn 但不中斷。
func (*CachedWorkspace) ReadConfig ¶
func (c *CachedWorkspace) ReadConfig() (Config, error)
ReadConfig 讀取 .4x/settings.json;settings.json 的 mtime 未變時回傳 cache 副本。
type Candidate ¶ added in v0.2.0
type Candidate struct {
Title string `json:"title"` // 候選 feature 標題
Description string `json:"description"` // 描述(含失敗細節)
Source CandidateSource `json:"source"` // 來源分類
Origin string `json:"origin"` // 追溯字串(feature id / round / reason / pattern)
// ValueScore 是 F097 gate role 給的價值分數(0–1),僅 gate 接受後(accepted-candidates.json)有值。
ValueScore float64 `json:"value_score,omitempty"`
// WhyNotHack 是 F097 gate role 強制要求的「為何此 candidate 真有價值、非為看起來有產出而生」論述,
// 僅 gate 接受後(accepted-candidates.json)有值。
WhyNotHack string `json:"why_not_hack,omitempty"`
}
Candidate 是一筆候選 feature,由 history miner 從歷史失敗訊號彙整而成。 只進候選池(candidates.json),是否升級為正式 feature 交由後續 F097 閘門決定。
func DedupeCandidates ¶ added in v0.2.0
func DedupeCandidates(cands []Candidate, existingFeatures []feature.Feature, existingCands []Candidate) []Candidate
DedupeCandidates 過濾候選:保留的 candidate 必須與每個 existingFeatures(Name+" "+Description)、 每個 existingCands(前一份 candidates.json 既有 candidate)、及本批次已保留 candidate 都不相似 (沿用 IsSimilarFeature Jaccard 去重)。比對對象是 candidate 的 Title+" "+Description。 回傳順序維持輸入順序(對齊 DedupeDiscovered 行為)。
func ScanEscalations ¶ added in v0.2.0
ScanEscalations 走訪所有 feature 的所有 round dir,讀取 escalation.json, 對 Needed==true 且 reason 在白名單內的條目產出一筆 candidate。 best-effort:讀檔失敗、JSON 壞掉、reason 不在白名單都只 slog.Warn 後略過, 不 panic、不中斷其他 feature 或其他掃描器。 features 由呼叫端傳入,避免重複呼叫 ListFeatures。
func ScanStuckFeatures ¶ added in v0.2.0
ScanStuckFeatures 掃描卡在 needs-attention/abandoned/blocked 的 feature,抽出阻塞原因產出 candidate。 阻塞原因優先取 state.json 的 StopReason/StopMessage,皆空時回退讀最新 round 的 escalation.json Detail。 best-effort:state 讀不到或壞掉都只 slog.Warn 後略過。 features 由呼叫端傳入,避免重複呼叫 ListFeatures。
type CandidateLearning ¶ added in v0.2.0
type CandidateLearning struct {
Category learning.Category `json:"category"`
Content string `json:"content"`
Source CandidateSource `json:"source"`
Origin string `json:"origin"`
}
CandidateLearning 是一筆候選 learning,沿用 internal/learning 的 category 白名單。 與 Candidate 同樣只進候選池,promotion 進 learnings.json 屬後續 F097。
type CandidatePool ¶ added in v0.2.0
type CandidatePool struct {
Version int `json:"version"` // 固定為 1
GeneratedAt time.Time `json:"generatedAt"` // 由 CLI 層 mine 命令設定,protocol 層不取系統時間
Candidates []Candidate `json:"candidates"`
Learnings []CandidateLearning `json:"learnings"`
}
CandidatePool 對應 .4x/candidates.json,是 history miner 的輸出容器。
func LoadCandidates ¶ added in v0.2.0
func LoadCandidates(path string) (CandidatePool, error)
LoadCandidates 讀取 candidates.json;檔案不存在時回傳空 pool(Version=1),不視為錯誤 (對齊 learning.LoadStore 慣例)。JSON 解析失敗才回傳 error。
func (CandidatePool) Save ¶ added in v0.2.0
func (p CandidatePool) Save(path string) error
Save 把 candidate pool 以 indented JSON 寫入指定路徑。
type CandidateSource ¶ added in v0.2.0
type CandidateSource string
CandidateSource 標記一筆 candidate 的來源分類,供後續 F097 閘門追溯與分流。
const ( // SourceEscalation 來自 round dir 的 escalation.json(spec-mismatch/criteria-wrong/blocker/scope-change)。 SourceEscalation CandidateSource = "escalation" // SourceStuck 來自卡在 needs-attention/abandoned/blocked 的 feature。 SourceStuck CandidateSource = "stuck" // SourceFailPattern 來自跨 feature 反覆出現的 reviewer/deep-reviewer FAIL issue。 SourceFailPattern CandidateSource = "fail-pattern" )
type ChangedFile ¶ added in v0.2.0
type ChangedFile struct {
// Path 是變更檔案相對 scope root 的路徑。
Path string
// Lines 是變更行數:tracked 檔為 added+deleted,untracked 檔為檔案總行數。
Lines int
}
ChangedFile 是檔案層變更的跨層共用型別(guard 與 gitops 共用,放 protocol 避免 import cycle)。
type CleanCandidate ¶
CleanCandidate 描述一個可清理的 feature workspace。
type Config ¶
type Config struct {
Project ProjectConfig `json:"project"`
Runners map[string]RunnerConfig `json:"runners"`
Default string `json:"default_runner"`
Roles map[string]RoleConfig `json:"roles,omitempty"`
Rules []string `json:"rules,omitempty"`
HubRepos []string `json:"hub_repos,omitempty"`
Isolation string `json:"isolation,omitempty"`
MaxConcurrentRuns int `json:"max_concurrent_runs,omitempty"`
Commit string `json:"commit,omitempty"`
ModelTiers map[string]map[string]string `json:"model_tiers,omitempty"`
Workspace WorkspaceConfig `json:"workspace,omitempty"`
Hooks map[string][]feature.HookEntry `json:"hooks,omitempty"`
// Profiles 定義 pipeline profile(名稱 → 啟用的 phase 子集 + 每 phase 的 runner/model 覆寫),
// 供依 feature priority 自動選擇或 --profile 手動覆蓋;為空時所有 feature 一律走 full(6 phase 全跑)。
Profiles map[string]ProfileConfig `json:"profiles,omitempty"`
// DefaultProfile 指定無 --profile flag 且未 resume 時要採用的 profile 名稱(如 full/normal/quick)。
// 為空時 fallback 既有行為(無 profiles 區段→full;有→依 priority auto-select)。
DefaultProfile string `json:"default_profile,omitempty"`
// ParallelReviewTest 啟用後,reviewer 與 tester 在 reviewing phase 並行執行(共用 worktree)。
ParallelReviewTest bool `json:"parallel_review_test,omitempty"`
// HealthCheck 是全域(settings.json)的 testing phase 前環境檢查設定,
// 未設為 nil(跳過);可被 per-feature test-strategy.yaml 整組覆蓋。
HealthCheck *HealthCheck `json:"health_check,omitempty"`
// TestProfiles 讓專案覆寫或擴充內建 test profile(key 為 profile 名稱)。
// 與 Profiles(pipeline profile)語意不同,不可混用。
TestProfiles map[string]TestProfileOverride `json:"test_profiles,omitempty"`
// AutoDiscoverFeatures 啟用後,run loop 在 final deep review PASS 後會 parse
// deep-review-report.md 的 [NEW-FEATURE] 標記並自動建立 feature。預設 false。
AutoDiscoverFeatures bool `json:"auto_discover_features,omitempty"`
// MaxDiscoveredFeatures 限制單次 run 最多自動建立幾張 feature;未設定或 <= 0 時套預設值(3)。
MaxDiscoveredFeatures int `json:"max_discovered_features,omitempty"`
// EnrichDiscoveredFeatures 啟用後,auto-discover 產出的 candidate 會經 LLM enrichment
// 補齊 subtasks/repos/rules/priority 後才存入 backlog;關閉時走舊路徑直接存薄 feature。預設 false。
EnrichDiscoveredFeatures bool `json:"enrich_discovered_features,omitempty"`
// EnrichAutoApprove 控制 enrich 後的 feature 狀態:true → not-started(全自動),
// false → draft(需人工 approve)。僅在 EnrichDiscoveredFeatures 開啟時有意義。預設 false。
EnrichAutoApprove bool `json:"enrich_auto_approve,omitempty"`
// FeatureIDPrefix 設定 feature ID 的前綴字串(如 "F"、"ws-"),預設 "F"。
FeatureIDPrefix string `json:"feature_id_prefix,omitempty"`
// FeatureIDDigits 設定 feature ID 流水號的最小位數(零補齊),預設 3。
FeatureIDDigits int `json:"feature_id_digits,omitempty"`
// DesignDocDirs 指定設計文件(spec/plan)的額外搜尋目錄,優先於預設 docs/design/。
// 例如 ["docs/feature"] 會讓 ResolveDesignDoc 先找 docs/feature/{id}-spec.md。
DesignDocDirs []string `json:"design_doc_dirs,omitempty"`
// Notifications 控制 run 結束時是否推送 OS 原生通知;用 pointer 區分「未設定」與「明確 false」,
// nil(未設定)時 NotificationsEnabled 視為啟用。project 端非 nil 會覆蓋 user 端設定。
Notifications *bool `json:"notifications,omitempty"`
// SelfMod 設定 meta-loop 跑自己時對「改自己核心地基」變更的額外保護(受保護路徑、單輪 diff 上限、
// 是否要求對應測試);nil 時 guard 套用內建預設(見 guard.ResolveSelfMod)。project 端非 nil 會覆蓋 user 端。
SelfMod *SelfModSettings `json:"self_mod_guard,omitempty"`
// Evolution 設定 F097 evolve pipeline 的價值閘門與收斂上限;nil 時由 evolution.ResolveEvolution 套全部預設值。
Evolution *EvolutionConfig `json:"evolution,omitempty"`
// IssueTracker 控制 `4x new`/`4x done` 是否串接 GitHub/GitLab issue 與 MR/PR。
// 純 project-level 欄位,預設 false,關閉時所有既有行為零改動。
IssueTracker IssueTrackerConfig `json:"issue_tracker,omitempty"`
// Worktree 是 scaffold worktree 相關的設定(如 post-scaffold hook)。
Worktree WorktreeConfig `json:"worktree,omitempty"`
}
Config 是 .4x/settings.json 的專案設定
func MergeConfig ¶
func MergeConfig(user UserConfig, project Config) Config
MergeConfig 合併 user-level 和 project-level 設定。 project 非零值欄位覆蓋 user;project-only 欄位(Project、Isolation 等)直接使用 project 的值。
type DesignDoc ¶
type DesignDoc struct {
// Content 是檔案內容,找不到時為空字串。
Content string
// Source 是相對於 root 的來源路徑(YAML 欄位命中時為原始 YAML 路徑字串),空表示找不到。
Source string
}
DesignDoc 是設計文件(spec/plan)的解析結果。 找不到對應文件時,Content 與 Source 皆為空字串。
func ResolveDesignDoc ¶
func ResolveDesignDoc(root string, feature feature.Feature, docType string, extraDirs ...string) DesignDoc
ResolveDesignDoc 依優先序解析 feature 的設計文件,docType 為 "spec" 或 "plan"。 此函式統一 server 與 prompt 兩處原本各自不一致的解析邏輯,新增來源時只需改這裡。
extraDirs 為額外搜尋目錄(相對於 root),優先於預設 docs/design/。
解析優先序:
- Feature YAML 的 Spec/Plan 欄位(依 docType 選取)。
- extraDirs 中各目錄下的 {feature.ID}-{docType}.md 與 {slug}-{docType}.md。
- docs/design/{feature.ID}-{docType}.md。
- docs/design/{slug}-{docType}.md。
- 都找不到 → 回傳零值 DesignDoc{}。
type DiscoveredFeature ¶
DiscoveredFeature 代表從 deep-review-report.md 解析出的一筆候選 feature。
func DedupeDiscovered ¶
func DedupeDiscovered(candidates []DiscoveredFeature, existing []feature.Feature) []DiscoveredFeature
DedupeDiscovered 過濾候選 feature:保留的 candidate 必須與每個 existing feature (Name+" "+Description)都不相似,且與已保留的 candidate 也不相似(batch 內去重)。 比對對象是 candidate 的 Title+" "+Description。回傳順序維持輸入順序。
func ParseDiscoveredFeatures ¶
func ParseDiscoveredFeatures(report string) []DiscoveredFeature
ParseDiscoveredFeatures 掃描 deep-review-report.md 文字,抽出所有 [NEW-FEATURE] block。 每個 block 的標題取 [NEW-FEATURE] 之後的文字(trim);描述為其後續行,直到遇到空行、 下一個 [NEW-FEATURE] 或下一個 "##" heading 為止。標題為空的 block 整個丟棄。 回傳順序與在 report 中出現的順序一致。
type Escalation ¶
type Escalation struct {
Needed bool `json:"needed"`
Reason string `json:"reason"`
Detail string `json:"detail"`
}
Escalation 是 Coder/Tester 觸發 Designer 重新介入
type Event ¶
type Event struct {
Timestamp string `json:"ts"`
Phase Phase `json:"phase"`
Type string `json:"type"`
Role Role `json:"role,omitempty"`
Round int `json:"round,omitempty"`
Action string `json:"action,omitempty"`
Command string `json:"cmd,omitempty"`
Status string `json:"status,omitempty"`
Detail string `json:"detail,omitempty"`
Runner string `json:"runner,omitempty"`
Model string `json:"model,omitempty"`
// Notify 為前端統一判斷通知等級的提示,值域 NotifySuccess / NotifyError / NotifyWarning,
// 空字串代表不通知。新增欄位向下相容(omitempty),不改既有 event 的 Status 語意。
Notify string `json:"notify,omitempty"`
// TokensUsed 記錄本次 runner invocation 使用的 token 數量(從 runner log 解析),
// 0 表示該 runner 未回報或解析失敗。僅 run-end event 填寫。
TokensUsed int `json:"tokens_used,omitempty"`
CostUSD float64 `json:"cost_usd,omitempty"`
DurationMs int64 `json:"duration_ms,omitempty"`
// Index 標記同一 round 內平行執行的同 role 事件屬於第幾個子任務(1-based),
// 目前僅 deep-reviewer 的平行 sub-reviewer 使用。多個平行事件共用同一個 Role
// 字串時,消費端不能再用單一遞增計數器區分 phase-start/run-end 配對(多個
// phase-start 會連續推高計數器,導致之後的 run-end 全部收斂到同一格互相覆蓋),
// 必須靠這個明確的索引還原正確配對。0(zero value)表示不適用,沿用既有的
// 循序重試(如 designer 被打回重做)計數器邏輯。
Index int `json:"index,omitempty"`
}
Event 是 events.jsonl 的一行
type EvolutionConfig ¶ added in v0.2.0
type EvolutionConfig struct {
// ValueFloor 為 gate role 給的 value_score 最低門檻,低於此一律拒;0 時套預設 0.6。
ValueFloor float64 `json:"value_floor,omitempty"`
// MaxAcceptPerRun 限制單次 gate 最多接受幾筆 candidate(convergence cap);0 時套預設 3。
MaxAcceptPerRun int `json:"max_accept_per_run,omitempty"`
// MaxBacklogUndone 為 backlog 未做數上限,超過即停止接受新 candidate;0 時套預設 15。
MaxBacklogUndone int `json:"max_backlog_undone,omitempty"`
// GateRunner 指定 gate role 用哪個 runner;空字串不補預設(由下游決定)。
GateRunner string `json:"gate_runner,omitempty"`
// GateModel 指定 gate role 用哪個 model;空字串用 runner 預設。
GateModel string `json:"gate_model,omitempty"`
// DedupThreshold 為 candidate 去重的 Jaccard 門檻;0 時套預設 0.6。
DedupThreshold float64 `json:"dedup_threshold,omitempty"`
// MaxIdleRounds 控制 anti-spin 防空轉:連續這麼多輪未接受任何 candidate 即早退停跑。
// 用 pointer 區分「未設定」(nil → evolution.ResolveEvolution 套預設 3)與「明確設值」;
// 明確設為 <= 0 表示停用 halt(永遠跑),正數才啟用門檻。
MaxIdleRounds *int `json:"max_idle_rounds,omitempty"`
// CandidateMaxIdleDays 為「從未使用的 candidate」老化為 stale 的天數門檻,僅 `4x learn prune` 消費。
// 用 pointer 區分「未設定」(nil → 套預設 30)與「明確設值」;明確設為 0 表示停用老化,正數為閾值。
CandidateMaxIdleDays *int `json:"candidate_max_idle_days,omitempty"`
}
EvolutionConfig 是 .4x/settings.json 內 evolution 區段的設定,描述 candidate feature 進 backlog 前的價值閘門門檻與收斂上限。各數值欄位為零值時由 evolution.ResolveEvolution 套預設。
type HealthCheck ¶
type HealthCheck struct {
Commands []string `yaml:"commands" json:"commands"`
Recovery []string `yaml:"recovery,omitempty" json:"recovery,omitempty"`
Timeout int `yaml:"timeout,omitempty" json:"timeout,omitempty"`
}
HealthCheck 是 testing phase 啟動前的環境檢查設定。 Commands 逐一執行任一失敗即停;失敗時若有 Recovery 則逐一執行後重跑一次 Commands。 Timeout 為每個 command 的逾時秒數,未設定(0)時由呼叫端套用預設 30 秒。
type IssueTrackerConfig ¶ added in v0.3.10
type IssueTrackerConfig struct {
// Enabled 為 true 時,`4x new` 建/連 issue,`4x done` 改成 push + 開 MR/PR 取代本地 squash-merge。
Enabled bool `json:"enabled"`
}
IssueTrackerConfig 控制 issue-first MR flow 是否啟用。
type ManualCheck ¶ added in v0.3.3
type ManualCheck struct {
ID string `yaml:"id" json:"id"`
ACRef string `yaml:"ac_ref,omitempty" json:"ac_ref,omitempty"`
Description string `yaml:"description" json:"description"`
Steps []string `yaml:"steps" json:"steps"`
}
ManualCheck 是 Designer 在 test-strategy.yaml 定義的手動驗證步驟。 Tester 必須逐步執行 Steps 並記錄實際輸出,不能只讀 code 判定。
type ManualCheckResult ¶ added in v0.3.3
type ManualCheckResult struct {
ID string `json:"id"`
Passed bool `json:"passed"`
Evidence []string `json:"evidence"`
}
ManualCheckResult 是 Tester 對單一 ManualCheck 的執行結果。
type Phase ¶
type Phase string
Phase 表示 4x 狀態機的各階段
const ( PhaseInit Phase = "init" PhaseDesigning Phase = "designing" PhaseDesignReviewing Phase = "design-reviewing" PhaseCoding Phase = "coding" PhaseReviewing Phase = "reviewing" PhaseDeepReviewing Phase = "deep-reviewing" PhaseFixing Phase = "fixing" PhaseTesting Phase = "testing" PhaseAmending Phase = "amending" PhaseAccepting Phase = "accepting" PhasePendingReview Phase = "pending-review" PhaseDone Phase = "done" PhaseAbandoned Phase = "abandoned" PhaseBlocked Phase = "blocked" PhaseNeedsAttention Phase = "needs-attention" )
func AllPhases ¶ added in v0.3.6
func AllPhases() []Phase
AllPhases 回傳所有可持久化於 state.json 的 Phase 值(enum SoT)。 依 internal/state/machine.go 的 CanTransition 裁定:fixing 是合法 to-phase (deep-reviewing→fixing、fixing→{accepting,amending}),abandoned/done 為終態, blocked/needs-attention 為 universal target,皆可寫入 phase,故 15 個全含。
func SelectablePhases ¶ added in v0.2.0
func SelectablePhases() []Phase
SelectablePhases 回傳 profile 可選 phase 的 canonical pipeline 順序清單, 供 UI 列舉與 doctor 驗證使用。
type PhaseSpec ¶ added in v0.2.0
type PhaseSpec struct {
// Phase 必須屬於 profileSelectablePhases 白名單(designing/coding/reviewing/
// deep-reviewing/testing/accepting)。
Phase string `json:"phase"`
// Runner 覆寫此 phase 使用的 runner,空字串代表繼承下層(default_runner)。
Runner string `json:"runner,omitempty"`
// Model 覆寫此 phase 的 model tier,空字串代表繼承下層(roles model)。
Model string `json:"model,omitempty"`
}
PhaseSpec 描述一個 profile 內某個 phase 的設定:是否啟用該 phase,以及覆寫該 phase 的 runner 與 model tier。Runner / Model 為空時代表繼承下層(feature override → default_runner、 roles model → runner model → defaultTier)。
type ProfileConfig ¶
type ProfileConfig struct {
// Phases 是啟用的 phase 規格列表;順序不影響行為(執行順序由 canonical pipeline 決定)。
Phases []PhaseSpec `json:"phases,omitempty"`
// Roles Deprecated:舊格式啟用的 role 名稱列表,僅供向後相容解析(normalize 轉成 Phases)。
Roles []string `json:"roles,omitempty"`
// CoderModel Deprecated:舊格式 coder 的 model tier 覆寫,僅供向後相容解析(轉成 coding phase 的 Model)。
CoderModel string `json:"coder_model,omitempty"`
}
ProfileConfig 描述一個 pipeline profile:啟用哪些 phase、以及每個 phase 的 runner/model 覆寫。 未列入 Phases 的 phase(對應的 role)在 run loop 中以 pass-through 方式沿合法 state 邊跳過、 不呼叫 runner。coding phase 為唯一必要 phase。
Roles / CoderModel 為已廢棄欄位,僅供向後相容解析:載入舊格式 settings.json 時由 normalize 自動轉成 Phases(見 profile.go),不再被任何解析路徑直接讀取。
func ResolveProfile ¶
ResolveProfile 決定本次 run 使用的 profile 名稱與設定。
解析優先序:
- override 非空(--profile / resume 沿用):先查 cfg.Profiles,再退 DefaultProfiles;都找不到回 error。
- override 為空且 feature YAML profile 欄位非空:用 f.Profile(查 cfg.Profiles 再退 DefaultProfiles,找不到回 error),供 batch per-feature 套用不同 profile。
- override 為空且 cfg.DefaultProfile 非空:用 cfg.DefaultProfile(查 cfg.Profiles 再退 DefaultProfiles,找不到印 warning 退 full)。
- override 為空且 cfg.DefaultProfile 為空:維持既有 fallback——cfg.Profiles 為空回 full; 非空時依 feature.Priority auto-select(nil/0/1→full、2→normal、>=3→quick)。
解析出的 profile 若不含 coding phase 視為設定錯誤,回 error(coding 為唯一必要 phase)。
func (ProfileConfig) EnabledPhaseNames ¶ added in v0.4.0
func (pc ProfileConfig) EnabledPhaseNames() []string
EnabledPhaseNames 以 canonical pipeline 順序回傳本 profile 已啟用的 phase 名稱清單, 供 prompt 段落列出 profile 的 phase 流程。
func (ProfileConfig) EnablesPhase ¶ added in v0.2.0
func (pc ProfileConfig) EnablesPhase(phase Phase) bool
EnablesPhase 判斷某 phase 是否啟用於 profile 的 Phases 列表中。
func (ProfileConfig) EnablesRole ¶
func (pc ProfileConfig) EnablesRole(role Role) bool
EnablesRole 判斷某 role 是否啟用:把 role 映射到工作 phase,再檢查該 phase 是否在 Phases 中。 無對應 phase 的 role(如 deep-reviewing 內的子 role)一律回 false。
func (ProfileConfig) HasPhase ¶ added in v0.2.2
func (pc ProfileConfig) HasPhase(phase Phase) bool
HasPhase 回報此 profile 是否包含指定 phase。
func (ProfileConfig) RoleArtifactView ¶ added in v0.4.0
func (pc ProfileConfig) RoleArtifactView(role Role) RoleArtifactView
RoleArtifactView 計算某角色在此 profile 下的產出物視圖(見 RoleArtifactView 型別說明)。 未列入契約表的角色回傳零值。
func (*ProfileConfig) UnmarshalJSON ¶ added in v0.2.0
func (pc *ProfileConfig) UnmarshalJSON(data []byte) error
UnmarshalJSON 解析 ProfileConfig 並在載入後自動 normalize, 把舊格式 Roles[]string / CoderModel 轉成新的 Phases 結構,達成向後相容。
type ProjectConfig ¶
type ProjectConfig struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
Language string `json:"language,omitempty"`
Setup []string `json:"setup,omitempty"`
Build []string `json:"build,omitempty"`
Test []string `json:"test,omitempty"`
Lint []string `json:"lint,omitempty"`
// DocsCheck 是文件/多語系同步的驗證指令(如 make check-docs-sync、check-i18n)。
// 由 coding/amending phase 的 docs-gate 於框架層自動執行,結果寫入 docs-gate.json,
// 讓 coder 在 coder-report 中對這些驗證的聲明可被獨立核對(見 F136)。
// 未設定時 docs-gate 完全跳過,非 4x 專案(無此類指令)不受影響。
DocsCheck []string `json:"docs_check,omitempty"`
Docs []string `json:"docs,omitempty"`
Rules []string `json:"rules,omitempty"`
Includes []string `json:"includes,omitempty"`
}
ProjectConfig 是專案基本設定,包含既有工具鏈的描述
type RepoConfig ¶
RepoConfig 描述 workspace 中單一 repo 的設定。
type ResolvedPhase ¶ added in v0.2.0
type ResolvedPhase struct {
// Phase 是 canonical pipeline 中的 phase 名稱(designing/coding/...)。
Phase string `json:"phase"`
// Role 是該 phase 對應的 role(designer/coder/...)。
Role string `json:"role"`
// Runner 是解析後實際使用的 runner 名稱。
Runner string `json:"runner"`
// Model 是解析後實際使用的 model name(非 tier,已透過 runner tiers 解析)。
Model string `json:"model"`
}
ResolvedPhase 描述 pipeline 中某個啟用 phase 解析後的最終結果: 合併所有覆寫層級(per-phase 臨時覆寫 > --runner > feature YAML > profile > roles > default) 後,該 phase 實際會用哪個 role / runner / model。供 dashboard pipeline 預覽顯示, 也作為「preview 與實際 run loop 解析一致」的共用真相源。
func ResolvePipeline ¶ added in v0.2.0
func ResolvePipeline(cfg Config, f feature.Feature, profileName string, manualRunner string, runOverrides map[Phase]PhaseSpec) ([]ResolvedPhase, error)
ResolvePipeline 解析給定 profile + 臨時覆寫下的完整 pipeline,回傳依 canonical 順序、 僅含 profile 啟用 phase 的 []ResolvedPhase。dashboard preview 與實際 run loop 共用此解析 路徑(透過 EffectiveManual 與 ResolvePhaseRunner / ResolvePhaseModel),確保預覽結果與 實際執行採用的 runner/model 完全一致。
profileName 為空時走 ResolveProfile 既有 fallback(feature YAML / default_profile / priority auto-select)。任一 phase 的 runner/model 解析失敗即回 error。
type ReviewIssue ¶
type ReviewIssue struct {
Severity Severity `json:"severity"`
Rule string `json:"rule"`
File string `json:"file"`
Detail string `json:"detail"`
}
ReviewIssue 是 reviewer 發現的問題
type ReviewResult ¶
type ReviewResult struct {
Passed bool `json:"passed"`
CriticalCount int `json:"criticalCount"`
WarningCount int `json:"warningCount"`
}
ReviewResult 是 review verdict 的結構化結果,包含通過與否及 critical/warning issue 計數
type Role ¶
type Role string
Role 表示 4x pipeline 中的角色
const ( RoleDesigner Role = "designer" RoleDesignReviewer Role = "design-reviewer" RoleCoder Role = "coder" RoleReviewer Role = "reviewer" RoleDeepReviewer Role = "deep-reviewer" RoleTester Role = "tester" RoleAcceptor Role = "acceptor" RoleFixer Role = "fixer" // RoleMiniCoder 與 RoleReVerifier 是 deep-reviewing phase 內自癒循環的子 role, // 不對應任何 state machine phase(全程維持 deep-reviewing),僅用於 prompt template // 與 event/log 辨識。 RoleMiniCoder Role = "mini-coder" RoleReVerifier Role = "re-verifier" // RoleSynthesizer 是平行 deep review 模式下合併多份 partial report 的子 role, // 同樣全程維持 deep-reviewing phase,僅用於 prompt template 與 event/log 辨識。 RoleSynthesizer Role = "synthesizer" // RoleGate 是 F097 evolve 價值閘門 role,判斷 candidate feature 是否值得進 backlog 並強制寫 // why_not_hack。不對應任何 state machine phase,由 evolve driver(F099)在 CLI veto 之間執行。 RoleGate Role = "gate" // RoleConsolidator 是 learnings consolidator role,在 harvest 後判斷語意重複的 learnings 並合併/移除。 RoleConsolidator Role = "consolidator" // RoleRoundSummarizer 是 round summarizer role,在進入 accepting 前將舊輪次的 review/test report // 壓縮為 rounds-summary.md,供 Acceptor 取代讀取所有輪次全文。 RoleRoundSummarizer Role = "round-summarizer" )
func AllRoles ¶ added in v0.3.6
func AllRoles() []Role
AllRoles 回傳所有可出現在 state.json.role 的 Role 值(enum SoT)。 即 internal/state/machine.go 的 PhaseToRole() 會指派(非空)的 8 個 pipeline 角色。 排除 sub-role(mini-coder/re-verifier/synthesizer,全程維持 deep-reviewing,僅用於 event/log 辨識,不佔 state.role)與非 pipeline 角色(gate/consolidator/round-summarizer)。
func ConfigurableRoles ¶ added in v0.4.0
func ConfigurableRoles() []Role
ConfigurableRoles 回傳可在 settings.json roles 區塊設定 per-role model 的 Role 集合(白名單 SoT)。 即全部 pipeline 角色(AllRoles,含 fixer)再加上 deep-reviewing / reviewing 自癒循環的 mini-coder 子 role——mini-coder 可透過 roles.mini-coder.model 做獨立 model 路由,故納入白名單。 其餘子 role(re-verifier/synthesizer)與非 pipeline 角色(gate/consolidator/round-summarizer) 目前不支援 per-role model 設定,故不列入。
type RoleArtifactView ¶ added in v0.4.0
type RoleArtifactView struct {
// Required 是本 profile 下本角色必須產出的 artifact 檔名(排序去重)。
Required []string
// Forbidden 是本 profile 其他啟用角色的產出物,本角色不應寫入(排序去重)。
Forbidden []string
// AbsentUpstream 是本角色消費的上游 artifact 中,本 profile 不會產出者,缺席屬正常(排序去重)。
AbsentUpstream []string
}
RoleArtifactView 是某角色在特定 profile 下的產出物視圖: Required 為本 profile 下必須產出的 artifact;Forbidden 為本 profile 其他啟用角色 的產出物(不含本角色共產者);AbsentUpstream 為本角色會消費、但本 profile 不會 產出(所有 producer 角色的 phase 都未啟用)的上游 artifact,其缺席屬正常。
type RoleConfig ¶
type RoleConfig struct {
Model string `json:"model,omitempty"`
DeepModel string `json:"deep_model,omitempty"`
ScreenshotDir string `json:"screenshot_dir,omitempty"`
Instructions []string `json:"instructions,omitempty"`
Includes []string `json:"includes,omitempty"`
// MaxFixRounds 限制 deep-reviewing phase 內自癒循環(mini-coder + re-verifier)
// 的最大迭代次數,僅對 deep-reviewer role 有意義;未設定時由 ResolveMaxFixRounds 套預設值。
MaxFixRounds int `json:"max_fix_rounds,omitempty"`
// ParallelReviewers 設定平行 deep review 要 spawn 幾個 sub-reviewer,僅對 deep-reviewer
// role 有意義;未設定或 <=1 時走 fallback 單 agent 模式(不分檔、不跑 synthesizer)。
ParallelReviewers int `json:"parallel_reviewers,omitempty"`
// AnglesPerReviewer 設定每個 sub-reviewer 負責的 review angle 數量,僅對 deep-reviewer
// role 有意義;未設定時由 ResolveAnglesPerReviewer 回 0,改用 ceil(總 angle/N) 平均分配。
AnglesPerReviewer int `json:"angles_per_reviewer,omitempty"`
// AngleMapping 定義 diff 檔案路徑前綴到 deep review angle 編號的映射,僅對 deep-reviewer
// role 有意義。key 為路徑前綴(如 "internal/state/");以 "*" 開頭的 key 為後綴匹配
// (如 "*_test.go")。value 為該路徑應啟動的 angle 編號清單(1-based)。
// 未設定時由 DefaultAngleMapping 提供預設映射。
AngleMapping map[string][]int `json:"angle_mapping,omitempty"`
}
RoleConfig 是各角色的模型與行為設定
type RoleContract ¶ added in v0.4.0
type RoleContract struct {
// Produces 是本角色負責產出的 artifact 檔名(canonical 排序)。
Produces []string
// Consumes 是本角色會讀取的上游 artifact 檔名(canonical 排序)。
Consumes []string
}
RoleContract 描述一個 pipeline 角色的產出物契約:Produces 為該角色負責寫入的 artifact 檔名清單,Consumes 為該角色會讀取的上游 artifact 檔名清單。 檔名一律使用 workspace.go 定義的常量(如 TaskBrief / ReviewReport), 不使用字面字串,確保與實際 runtime 檔名同步。
func ArtifactContract ¶ added in v0.4.0
func ArtifactContract(role Role) (RoleContract, bool)
ArtifactContract 查表回傳某角色的產出物契約。未列入本表的角色 (mini-coder / synthesizer 等子角色)回傳 (RoleContract{}, false), 代表不注入 profile-aware 段落。回傳的 slice 為 canonical 排序後的副本。
type RunnerConfig ¶
type RunnerConfig struct {
Command string `json:"command"`
Args []string `json:"args"`
Model string `json:"model,omitempty"`
Tiers map[string]string `json:"tiers,omitempty"`
Stdin *bool `json:"stdin,omitempty"`
Tty *bool `json:"tty,omitempty"`
Quiet *bool `json:"quiet,omitempty"`
OutputFormat string `json:"output_format,omitempty"`
// TransientRetries 設定暫態錯誤(socket closed、connection reset、rate limit、5xx 等)的
// 自動重試上限:nil 表示用預設 3 次、0 表示停用重試、>0 為自訂上限。
TransientRetries *int `json:"transient_retries,omitempty"`
}
RunnerConfig 是 LLM runner 的設定
type RunnerPreset ¶
type RunnerPreset struct {
Name string `json:"name"`
Config RunnerConfig `json:"config"`
}
RunnerPreset 描述一個受支援 runner 的預設設定
func SupportedRunners ¶
func SupportedRunners() []RunnerPreset
SupportedRunners 回傳所有受支援 runner 的預設設定,作為 init 和 dashboard 的單一真相源
type SelfModSettings ¶ added in v0.2.0
type SelfModSettings struct {
// ProtectedPaths 是受保護路徑前綴白名單(相對 scope root),如 "internal/state/"。
ProtectedPaths []string `json:"protected_paths,omitempty"`
// MaxDiffLines 是受保護路徑單輪 diff 行數上限,超過即擋下轉 needs-attention;<= 0 視為未設定。
MaxDiffLines int `json:"max_diff_lines,omitempty"`
// RequireTests 控制改受保護路徑是否必須附帶對應測試才能進 accepting;
// 用 pointer 區分「未設定」(預設 true)與「明確 false」。
RequireTests *bool `json:"require_tests,omitempty"`
}
SelfModSettings 是 .4x/settings.json 內 self_mod_guard 區段的設定, 描述哪些路徑視為「核心地基」受保護、單輪 diff 行數上限、以及是否要求對應測試。 各欄位零值(含 nil)代表「未設定」,由 guard.ResolveSelfMod 退回內建預設。
type State ¶
type State struct {
FeatureID string `json:"featureId"`
Phase Phase `json:"phase"`
Role Role `json:"role"`
SubPhase SubPhase `json:"subPhase,omitempty"`
Round int `json:"round"`
MaxRounds int `json:"maxRounds"`
Active bool `json:"active"`
Pid int `json:"pid,omitempty"`
Runner string `json:"runner"`
Label string `json:"label,omitempty"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Since time.Time `json:"since,omitempty"`
ConsecutiveNoProgress int `json:"consecutiveNoProgress"`
LastFailCount int `json:"lastFailCount"`
StopReason string `json:"stopReason,omitempty"`
StopMessage string `json:"stopMessage,omitempty"`
Runners []string `json:"runners,omitempty"`
// Profile 記錄本次 run 使用的 pipeline profile 名稱,供 dashboard 顯示與 resume 沿用。
Profile string `json:"profile,omitempty"`
// SelfModTouched 標記本 feature 最新一輪 coding/amending 是否觸及受保護路徑(self-mod guard)。
// 由 guard.Check 在 coding 後偵測並持久化,供後續 test-gate 與 done/merge 的人工 approve 關卡讀取。
SelfModTouched bool `json:"selfModTouched,omitempty"`
// SelfModPaths 記錄最新一輪觸及的受保護檔案路徑(相對 scope root),test-gate 以此判斷是否附帶對應測試。
SelfModPaths []string `json:"selfModPaths,omitempty"`
// SelfModApproved 表示人工已透過 --approve-self-mod 核可此 feature 的受保護路徑變更,允許 merge。
SelfModApproved bool `json:"selfModApproved,omitempty"`
// GuardRetries 記錄全域 guard retry 次數(跨 round 累計),超過上限時停止重試。
GuardRetries int `json:"guardRetries,omitempty"`
// BaseCommit 記錄 feature 首次進入 coding phase 時的 HEAD commit sha,供 review-package.md
// 計算 diff 使用。amending 階段沿用同一個 base,讓 review package 累積本 feature 的完整 diff。
BaseCommit string `json:"baseCommit,omitempty"`
// ManualPhase 標記本次 phase 是由 `4x transition` / `4x retry` 手動設定,供 RecoverState
// 尊重人為介入:偵測到此旗標時直接照 state.json 的 phase 派對應 role,不進 SmartResumePhase
// 依磁碟 artifacts 重推導,並在消費後清除(避免下一輪真 crash 時仍被當成人為介入)。
// 正常 run loop 內部的 state.Transition 不設置此旗標,故 recovery 對真 crash 的行為維持不變。
ManualPhase bool `json:"manualPhase,omitempty"`
}
State 是 .4x/{feature-id}/state.json 的權威狀態
type SubPhase ¶ added in v0.1.14
type SubPhase string
SubPhase 表示 deep-reviewing phase 內的子步驟,僅在 phase==deep-reviewing 時有意義; 其餘 phase 一律為空字串。用於 dashboard 顯示細部進度與 crash recovery 推斷重跑起點。
func AllSubPhases ¶ added in v0.3.6
func AllSubPhases() []SubPhase
AllSubPhases 回傳全部 4 個 SubPhase 常量(enum SoT)。
type TestProfileOverride ¶
type TestProfileOverride struct {
Content string `json:"content,omitempty"`
Include string `json:"include,omitempty"`
}
TestProfileOverride 允許專案在 settings.json 覆寫或新增 test profile。 Content 直接指定內容;Include 指定相對於 workspace root 的檔案路徑。兩者擇一,整組取代內建。
type TestStrategy ¶
type TestStrategy struct {
Web bool `yaml:"web" json:"web"`
API bool `yaml:"api" json:"api"`
Gate bool `yaml:"gate" json:"gate"`
CoderOnly bool `yaml:"coder_only" json:"coder_only"`
Verify []string `yaml:"verify_commands" json:"verify_commands"`
HealthCheck *HealthCheck `yaml:"health_check,omitempty" json:"health_check,omitempty"`
VerifyGroups map[string][]string `yaml:"verify_groups,omitempty" json:"verify_groups,omitempty"`
// Profiles 標記本 feature 適用的測試 profile(如 unit/web/api/e2e),
// Tester prompt 會依此自動注入對應的測試方法論;為空時行為與舊版一致。
Profiles []string `yaml:"profiles,omitempty" json:"profiles,omitempty"`
// ManualChecks 定義 Tester 必須實際執行(非讀 code)的驗證步驟。
// Guard 會驗證 verify.json 含有對應的 manual_check_results。
ManualChecks []ManualCheck `yaml:"manual_checks,omitempty" json:"manual_checks,omitempty"`
// ACVerifyMap 標記每條 AC 的驗證類型(unit-test / integration / inspection / skip)。
// Guard 依此決定 evidence 品質要求;未列出的 AC 預設 execution(從嚴)。
ACVerifyMap map[string]string `yaml:"ac_verify_map,omitempty" json:"ac_verify_map,omitempty"`
// E2ERepos 列出本 feature 的 e2e 測試產出所在的獨立 repo 名稱(如 kairos-e2e)。
// testing phase 起(含 testing 之後回到的 amending),這些 repo 的變更不算 scope violation
// (Tester 必要寫入放行);為空時行為與舊版完全一致。granularity 為 repo 層級,比照 Config.HubRepos。
E2ERepos []string `yaml:"e2e_repos,omitempty" json:"e2e_repos,omitempty"`
}
TestStrategy 是 test-strategy.yaml 的結構
type UserConfig ¶
type UserConfig struct {
Locale string `json:"locale,omitempty"`
Theme string `json:"theme,omitempty"`
DefaultRunner string `json:"default_runner,omitempty"`
Runners map[string]RunnerConfig `json:"runners,omitempty"`
Roles map[string]RoleConfig `json:"roles,omitempty"`
// LogLevel 設定 structured logging 的最低輸出等級(debug/info/warn/error),
// 為空時預設 "info";可被環境變數 FOURX_LOG_LEVEL 覆蓋。
LogLevel string `json:"logLevel,omitempty"`
// LogRetainDays 設定 ~/.4x/logs/ 下 log 檔的保留天數,
// 超過此天數的 log 檔會在 Init() 時自動清除;為零時預設 7 天。
LogRetainDays int `json:"logRetainDays,omitempty"`
// Notifications 為使用者層級的 OS 通知開關;用 pointer 區分「未設定」與「明確 false」,
// 會被 project 端非 nil 的設定覆蓋(見 MergeConfig)。
Notifications *bool `json:"notifications,omitempty"`
// SelfMod 為使用者層級的 self-mod guard 設定,project 端非 nil 時被覆蓋(見 MergeConfig)。
SelfMod *SelfModSettings `json:"self_mod_guard,omitempty"`
}
UserConfig 是 ~/.4x/settings.json 的使用者層級設定
func ReadUserConfig ¶
func ReadUserConfig() (UserConfig, error)
ReadUserConfig 讀取 ~/.4x/settings.json,不存在時回傳零值
type VerifyCommand ¶
type VerifyCommand struct {
Command string `json:"command"`
ExitCode int `json:"exitCode"`
ExpectedExitCode *int `json:"expectedExitCode,omitempty"`
DurationMs int64 `json:"durationMs"`
Summary string `json:"summary"`
StartedAt time.Time `json:"startedAt"`
FinishedAt time.Time `json:"finishedAt"`
Group string `json:"group,omitempty"`
Skipped bool `json:"skipped,omitempty"`
}
VerifyCommand 是單一 verify command 的結果
type VerifyEvidence ¶
type VerifyEvidence struct {
Passed bool `json:"passed"`
Round int `json:"round"`
Role Role `json:"role"`
Commands []VerifyCommand `json:"commands"`
Screenshots []feature.Screenshot `json:"screenshots,omitempty"`
ACResults []ACEvidence `json:"ac_results,omitempty"`
ManualCheckResults []ManualCheckResult `json:"manual_check_results,omitempty"`
}
VerifyEvidence 是 rounds/round-N/verify.json 的結構
type Workspace ¶
type Workspace struct {
Root string
// SkipAutoCommit 為 true 時,SyncFeatureStatus 只寫入檔案不自動 commit。
// worktree 模式下主 repo 不應 commit feature YAML status,避免與 branch merge 衝突。
SkipAutoCommit bool
}
Workspace 管理 .4x/ 目錄的讀寫
func (*Workspace) AppendEvent ¶
AppendEvent 追加一行到 events.jsonl
func (*Workspace) CleanFeature ¶
CleanFeature 刪除指定 feature 的 workspace 目錄,回傳釋放的位元組數。 僅允許 done 或 abandoned 且非 active 的 feature;非 terminal 或仍在執行中皆回 error。 feature 定義(.4x/features/{id}.yaml)不受影響。
func (*Workspace) CleanableFeatures ¶
func (w *Workspace) CleanableFeatures() ([]CleanCandidate, error)
CleanableFeatures 列出所有可清理的 feature workspace。 僅納入 done 或 abandoned、有 workspace 目錄、且目前非 active 的 feature, 供 4x clean 與 POST /api/clean 在實際刪除前向使用者預覽清理對象與預估空間。
func (*Workspace) ClearStopSignal ¶ added in v0.1.17
ClearStopSignal 刪除 feature 的 stop signal 檔;檔案不存在時不視為錯誤(比照 ClearBatchConflict)。
func (*Workspace) CompareBacklogMirror ¶
func (w *Workspace) CompareBacklogMirror() ([]feature.BacklogDrift, error)
CompareBacklogMirror 比對 canonical feature YAML 與 legacy feature_list.json mirror。
func (*Workspace) DiscoverScreenshots ¶
func (w *Workspace) DiscoverScreenshots(featureID, screenshotDir string) ([]feature.ScreenshotGroup, error)
DiscoverScreenshots 會合併 verify.json 與截圖目錄掃描結果,並按 round 分組回傳。
func (*Workspace) FeatureDir ¶
FeatureDir 回傳 .4x/run/{featureId}/ 的路徑
func (*Workspace) InitFeatureDir ¶
InitFeatureDir 建立 feature 的運行時目錄
func (*Workspace) ListFeatures ¶
ListFeatures 列出所有 feature。 使用寬鬆驗證:格式有問題的 YAML 仍會載入並附帶 Warnings,只有完全無法解析的才跳過。
func (*Workspace) LoadFeature ¶
LoadFeature 讀取 .4x/features/{id}.yaml
func (*Workspace) LoadMergedConfig ¶
LoadMergedConfig 讀取 project config 並合併 user config,封裝散落各處的三行 boilerplate。 project config 讀取失敗時回傳 error 由呼叫端決定如何處理; user config 讀取失敗時印 slog.Warn 但不中斷(沿用既有各站點的處理慣例)。
func (*Workspace) ReadBacklogMirror ¶
func (w *Workspace) ReadBacklogMirror() (feature.BacklogMirror, bool, error)
ReadBacklogMirror 讀取根目錄 feature_list.json;不存在時回傳 present=false。
func (*Workspace) ReadConfig ¶
ReadConfig 讀取 .4x/settings.json
func (*Workspace) ReadTestStrategy ¶
func (w *Workspace) ReadTestStrategy(featureID string) (TestStrategy, error)
ReadTestStrategy 讀取 .4x/{featureId}/test-strategy.yaml 並解析為 TestStrategy。 檔案不存在時回傳零值 TestStrategy 與 nil error,方便呼叫端把「沒設定」與「解析失敗」分開處理。
func (*Workspace) ReconcileActive ¶
ReconcileActive 以 process 存在為權威來源校正 Active 欄位。 若 state 記錄 Active=true 但 PID 已不存在,自動將 Active 設為 false 並回寫。
func (*Workspace) RequestStop ¶ added in v0.1.17
RequestStop 在 feature dir 下原子寫入 stop signal 檔,請求 run loop 停止該 feature。
採 signal file(對齊既有 BatchStopFile 機制)而非直接改寫 state.json:state.json 的唯一 writer 收斂為 run loop,外部(如 MCP stop)只下「請求停止」信號,避免兩個 writer 競寫整份 state.json 而用過時快照覆蓋掉 loop 剛寫入的 phase/round 進度。
語意上 stop 為「請求」:若目標 feature 已無存活 loop,signal 不會被消費, 留待既有 ReconcileActive 在下次 ReadState 校正 Active。
func (*Workspace) ResolveFeatureID ¶
ResolveFeatureID 用前綴比對找出唯一 feature ID(大小寫不敏感)
func (*Workspace) SaveFeature ¶
SaveFeature 寫入 feature YAML,採用 write-to-temp + rename 確保原子性
func (*Workspace) StopRequested ¶ added in v0.1.17
StopRequested 回傳 feature dir 下是否存在 stop signal 檔。
func (*Workspace) SyncFeatureStatus ¶
SyncFeatureStatus 將 feature YAML 的 Status 欄位同步為對應 phase 的狀態。 內部依序執行 LoadFeature → PhaseToStatus → SaveFeature,供 cmd/4x 與 internal/server 共用,避免 status 同步邏輯分散兩處。 若 feature YAML 被 git 追蹤,會自動 commit 狀態變更。
func (*Workspace) TotalCost ¶ added in v0.3.10
TotalCost 加總 events.jsonl 中所有 run-end 事件的 cost_usd,作為該 feature 跨行程(含中斷重啟)的權威總花費,不依賴 per-role/iteration 比對。 events.jsonl 不存在時回傳 (0, nil)(新 feature 尚無歷史)。
func (*Workspace) WorktreePath ¶
WorktreePath 從 events.jsonl 解析 feature 的 worktree 路徑。 若 feature 未使用 worktree 或 events.jsonl 不存在,回傳空字串。
掃描整個 events.jsonl 並回傳「最後一個」符合 `type==run-output` 且 detail 以 "worktree: " 開頭的路徑(最近一次 run 的 worktree)。re-run 多次後舊事件 會被新事件推到後段,只看前幾行會掃不到或回到已被移除的舊 worktree,故須掃全部行。
func (*Workspace) WriteState ¶
WriteState 寫入 feature 的 state.json。
採用 write-to-temp + rename 而非直接 os.WriteFile:後者會先 truncate 再寫, 在這段時間內 concurrent 的 ReadState 可能讀到截斷或半寫的 JSON 而 Unmarshal 失敗。 改用同目錄 temp file 寫完再 atomic rename 覆蓋,讓讀者永遠看到完整的舊檔或完整的新檔。
type WorkspaceConfig ¶
type WorkspaceConfig struct {
Repos map[string]RepoConfig `json:"repos,omitempty"`
}
WorkspaceConfig 描述 multi-repo workspace 的 repo 映射。 沒有設定時代表 monorepo 模式。
type WorkspaceReader ¶
type WorkspaceReader interface {
// ListFeatures 列出所有 feature。
ListFeatures() ([]feature.Feature, error)
// LoadFeature 讀取單一 feature YAML。
LoadFeature(id string) (feature.Feature, error)
// ReadState 讀取 feature 的 state.json。
ReadState(featureID string) (State, error)
// ReadConfig 讀取 .4x/settings.json。
ReadConfig() (Config, error)
}
WorkspaceReader 定義 Workspace 的唯讀操作集合,用於抽象出可被 cache 層包裝的讀取介面。 long-running server 透過此介面操作,便於以 CachedWorkspace 替換而不影響呼叫端; CLI 短命程序則直接用 *Workspace。寫入方法刻意不納入介面,避免 cache 層被誤用於寫入。
type WorktreeConfig ¶ added in v0.4.0
type WorktreeConfig struct {
// PostScaffold 宣告 scaffold 建立 worktree 後、在 worktree 根目錄依序執行的命令清單;
// 單一命令失敗只 warn 不中止 scaffold。內容由使用端專案自理(4x 不內建專案特定邏輯)。
PostScaffold []string `json:"post_scaffold,omitempty"`
}
WorktreeConfig 是 settings.json 內 worktree 區段的設定。
Source Files
¶
- artifact_contract.go
- cached.go
- config.go
- config_resolve.go
- design_doc.go
- discover.go
- domain.go
- enums.go
- merge.go
- miner.go
- model.go
- override.go
- pipeline.go
- process_unix.go
- profile.go
- reader.go
- review.go
- state.go
- validate.go
- verify.go
- workspace.go
- workspace_config.go
- workspace_feature.go
- workspace_screenshot.go
- workspace_state.go