Pular para conteúdo

AUR-583: architecture guards cover internal/

Measured before (base 64a8bfc1, then main 9c685fde with AUR-581)

  • internal/gate imported internal/render in six files (analysisdata.go, dtrack.go, policy.go, result.go, scanner.go, sources.go) for render.AuditFinding, AuditException, AnalysisDataAudit; internal/render/audit.go imported internal/config for PolicyDigest(policyDir, *config.Config) and config.DefaultConfigPath.
  • internal/config/dtrack.go imported internal/dtrack for AsClientThresholds (only caller: internal/gate/dtrack.go, which runs dtrack.Run) and for ValidateHost (parse-time refusal of an insecure host). internal/config does not run dtrack.Run itself.
  • internal/config/wrap.go imports internal/llm. WrapProviderWithWarnings has no production caller after AUR-579, but config.WrapProvider is still called by finished acceptance scripts and tests: tests/acceptance/AUR-452.sh, AUR-468.sh, AUR-479.sh; tests/unit/AUR-452.go, AUR-468.go, AUR-479.go; tests/integration/AUR-468.go, AUR-479.go; internal/review/prompt_golden_test.go; internal/config/provider_pending_test.go. Comments naming it live in cmd/aurumcode/policygate.go, review_cache.go, main.go and aur513_test.go (outside this card's paths).
  • ApplyCentralPolicy copied each section by hand (124 lines); a new field of Config was, by omission, the repository's.
  • Contributors wrote *res = d and restored Reason/Trail/AnalysisData by hand; MergeDTrackGate duplicated Result.Merge. FoldSources no longer existed.
  • len(text)/4 in internal/prompt/estimator.go, internal/llm/estimator.go and internal/context/skills/skills.go; skill front matter parsed by hand (skills.go, parseFrontMatter/yamlScalar/yamlList).
  • renderSlot (internal/prompt/slots.go) panicked on a template error.
  • The 150-line and card-name guards covered only cmd/aurumcode. The exit ladder guard recognized only exit* identifiers; the engine guard only string literals. No function of internal/ or pkg/ exceeded 150 lines (measured with go/ast).

What changed

  • internal/gate/facts (facts.go): AuditFinding, AuditException, AnalysisDataAudit (same fields and JSON tags). internal/render keeps them as type aliases, so its API and the serialized audit are unchanged; internal/gate uses facts.* and no longer imports render. (A first version put them in pkg/types; moved because pkg is outside the card's paths.)
  • config.(*Config).PolicyDigest(policyDir) (internal/config/policydigest.go) holds the digest, nil-safe; render.PolicyDigest(policyDir, PolicySource) takes any value with that method (a typed or untyped nil gives ""), so render no longer imports config and callers are unchanged.
  • The Dependency-Track threshold conversion moved to internal/gate/dtrack.go (clientThresholds); config keeps only dtrack.ValidateHost, declared as a symbol exception in the layer table.
  • internal/config/governance.go: governedSections (key, rule) in warning order, reviewPolicyFields/reviewRepositoryFields, qualityGateSections. ApplyCentralPolicy walks the table (14 lines; GenerateReviewWithContext is 21). governance_test.go reflects over Config, ReviewConfig and QualityGatesConfig and fails for an unclassified field, a classification of a field that does not exist, or a double classification.
  • gate.Contributor.Apply(ctx, run, prior Result) (Result, error): each contributor returns its partial decision and Pipeline.Run merges it (Result.Merge, which now also carries an AnalysisData fact). MergeDTrackGate removed. The policy-skills partial clears its reason (the run's reason is already in the result), so no reason is joined twice.
  • tokens.Estimate (internal/llm/tokens) is the one heuristic; prompt.HeuristicEstimator, llm.heuristicTokens (never below 1, as before) and skills.EstimateTokens delegate to it.
  • Skill front matter is decoded with gopkg.in/yaml.v3 (already a dependency): a list, a block list or a comma-separated scalar; unknown keys ignored; malformed YAML is an error naming the file (fail closed; it used to be read leniently).
  • renderSlot never panics: a failed slot renders a NUL-delimited failure mark; BuildPrompt and FixedOverheadTokens refuse a prompt that carries one, with the slot name and cause. Signatures (and the anchors finished acceptance scripts edit) are unchanged.
  • docs/architecture.md: new "Layers" table (the test's source), the configuration-section and contributor extension points, the guard list.
  • cmd/aurumcode/structure_test.go: TestImportsFollowLayerTable (reads the table; a file exception or symbol exception that matches nothing fails), TestNoFunctionExceedsLineLimitAnywhere and TestNoProductionFileNamedByCardAnywhere over cmd, internal and pkg, TestReviewSourcesReturnNoGateExitCode (named constants, any gate.Exit* selector, the literal value of gate.ExitFindings; literals 1 and 2 stay legal because each early exit keeps its own code), TestNoEngineBranchInGateOrCmdByAnyName (literal, named constant, map key, index).

Proof

All in the shared container (.board/bin/go-shared).

  • go vet ./... && go test -p 1 ./...: rc=0.
  • bash tests/acceptance/AUR-583.sh all: AUR-583/all/pass. Mutations, each compiling and RED by assertion:
  • MUT-001 (internal/gate/result.go imports render): internal/gate/result.go imports internal/render (internal/gate must not import internal/render).
  • MUT-002 (Telemetry string yaml:"telemetry" in Config): Config.telemetry has no central-policy classification.
  • MUT-003 (150 lines into ApplyCentralPolicy): functions over 150 lines: internal/config/central.go: ApplyCentralPolicy (164).
  • MUT-004 (return 3, true in prReview.generateReview): review sources returning a gate exit code ... [review_pr_generate.go:65 prReview.generateReview].
  • MUT-005 (map[string]int{mutEngine: 1} with const mutEngine = "semgrep" in gate): ../../internal/gate/result.go: an engine name as a map key.
  • AC-004: the audit/SARIF/report tests (AUR-521, AUR-568, AUR-577) pass, and the 17 tutorials were re-run with this tree's image (AURUMCODE_TUT_IMAGE=aurum-tutoriais:aur583); run.sh --check passes for every one against expected/ recorded before the refactor, which was not re-recorded. The out/ diffs are timestamps, the analysis-data tag and the interleaving of stdout and stderr, which differs between two runs of the same image.
  • Regression aceites, each rc=0: AUR-521, 565, 570, 576, 577, 578, 579, 580, 581 end in all/pass; AUR-568 ends in AUR-568/all/ok; AUR-561..564 end in their last mutation line (AC-002-MUT-001/ok).

Left out

  • config ↛ llm: wrap.go stays (file exception in the table) until the finished acceptance scripts above stop calling config.WrapProvider.
  • internal/gate still receives *config.Config (in Run and several sources); narrowing it is a rewrite of the gate's inputs, not done here.