X22a-2-arch-traits: P11-minio → P21-tekton-pipeline#

Scorecard#

ProjectT1T2T3T4T5T6T7T8Composite
P11-minio101112118
P12-consul2121122213
P13-vault2121223215
P14-terraform2221121314
P15-nomad2121122213
P16-dapr2121121212
P17-k3s111112119
P18-helm2221223216
P19-istio2121221213
P20-argo-cd2121121212
P21-tekton-pipeline3122221215

Evidence#

P11-minio#

P11-minio / T1 (score 1): report:P11-minio–interfaces.md: bimodal — ObjectLayer (~40 methods) and StorageAPI (~35) dominate; narrow interfaces (WarmBackend 5, event.Target 6, RWLocker 4) exist but are secondary; provider-defined large interfaces characterize the public boundary.

P11-minio / T2 (score 0): report:P11-minio–architecture.md: all subsystems initialized as package-level globals (globalIAMSys, globalObjectAPI, globalGrid, globalEventNotifier, etc.); every subsystem is a named global in cmd/; no meaningful separation from package singletons.

P11-minio / T3 (score 1): report:P11-minio–architecture.md: serverMain() has a single bootstrapTrace()-ordered init sequence (one composition point), but all wiring flows into global* vars rather than explicit constructor parameters — the “root” creates globals, not an explicit graph.

P11-minio / T4 (score 1): report:P11-minio–patterns.md: context used throughout (1714 occurrences) for cancellation; no evidence of injected clock interface or parameterized randomness/IO; rate limiting via x/time/rate is narrow and ambient.

P11-minio / T5 (score 1): report:P11-minio–structure.md: 34 internal/ sub-packages ring the single cmd/ god package (~453 Go files all in package cmd); utility packages (bpool, cachevalue) are pure, but business logic is thoroughly mixed with IO in the dominant cmd package.

P11-minio / T6 (score 2): report:P11-minio–architecture.md: ObjectLayer is the single seam replacing the storage hierarchy; internal grid RPC and background workers use concrete types throughout; the narrow use of interfaces at real replacement points (ObjectLayer, event.Target) reflects correct boundary discipline.

P11-minio / T7 (score 1): report:P11-minio–api-surface.md: server-binary only with no exported Go library API; external SDK lives in the separate github.com/minio/pkg repo; extension is via compiled-in event targets and Object Lambda, not an importable package.

P11-minio / T8 (score 1): report:P11-minio–structure.md: internal/ wraps 34 sub-packages correctly, but the dominant cmd/ is a single 453-file god package with no visibility enforcement; no sub-package discipline within the most import-heavy portion of the codebase.


P12-consul#

P12-consul / T1 (score 2): report:P12-consul–interfaces.md: modal size 1–3 methods; 20 single-method proxycfg Notify interfaces; consumer-defined pattern throughout; outlier Authorizer (~35 methods) is a legitimately wide protocol contract, not design laziness.

P12-consul / T2 (score 1): report:P12-consul–architecture.md: BaseDeps struct for explicit DI; but api-surface.md notes HTTP routes registered via init() in agent/http_register.go; some package-level sentinels; not pervasive but present.

P12-consul / T3 (score 2): report:P12-consul–architecture.md: BaseDeps is an explicit manual DI root passed through Server/Client constructors; wiring is discoverable and greppable; no framework, no service locator.

P12-consul / T4 (score 1): report:P12-consul–patterns.md: shutdownCh + context coexistence noted as an in-progress migration; no explicit clock injection or parameterized IO described; context used for request scope but not the primary lifecycle signal.

P12-consul / T5 (score 1): report:P12-consul–structure.md: agent/structs/ is a god package for shared domain types — business logic and IO are entangled at the center; domain-driven layout at top level is correct but structs package prevents true core/IO separation.

P12-consul / T6 (score 2): report:P12-consul–interfaces.md: ca.Provider (9 methods with ISP sub-interfaces), storage.Backend (6), Reconciler (1) — interfaces at real replacement boundaries; internal coordinator/delegate uses concrete types.

P12-consul / T7 (score 2): report:P12-consul–structure.md: api/ sub-module is a public Go client library; sdk/ sub-module as reusable primitives; proto-public/ as stable external proto contracts — three distinct public-facing layers.

P12-consul / T8 (score 2): report:P12-consul–structure.md: 5 sub-modules (api/, sdk/, proto-public/, envoyextensions/, troubleshoot/); internal/ for v2 architecture; domain-driven root layout with intentional visibility separation.


P13-vault#

P13-vault / T1 (score 2): report:P13-vault–interfaces.md: SDK provides narrow clean interfaces (physical.Backend 4, logical.Storage 4, physical.HABackend 2); optional capability extension via type assertions rather than wider interfaces; Core has legitimately wide SecurityBarrier (~25) as protocol contract.

P13-vault / T2 (score 1): report:P13-vault–patterns.md: factory maps in CoreConfig (functions, not instances) keep globals lean; sync.Once guards (72 uses) for lazy singletons; some package-level vars for CA state; limited but present.

P13-vault / T3 (score 2): report:P13-vault–architecture.md: CoreConfig struct carries factory maps (not instances) — explicit DI container; plugins never imported directly; radix-tree router as the dispatch mechanism; composition root is clearly vault.NewCore(CoreConfig{...}).

P13-vault / T4 (score 1): report:P13-vault–patterns.md: ShutdownCh chan struct{} pattern throughout; helper/fairshare/ worker pool with explicit context; no documented clock injection interface; api/auth/ uses functional options but not time parameterization.

P13-vault / T5 (score 2): report:P13-vault–structure.md: sdk/ and api/ as separate Go modules with clean boundaries; physical/ backends separated from core logic; sdk/logical.Backend as a pure plugin contract that carries no IO dependencies itself.

P13-vault / T6 (score 2): report:P13-vault–architecture.md: plugins never imported directly into CoreConfig — only factory functions; sdk/logical.Backend is the universal plugin contract at the real external boundary; internal vault/ package uses concrete collaborators.

P13-vault / T7 (score 3): report:P13-vault–structure.md: three Go modules (root, sdk/, api/); api/ is an independent library used by all Vault clients; sdk/ provides the stable plugin development kit for third-party secrets engines and auth methods — textbook multi-module library design.

P13-vault / T8 (score 2): report:P13-vault–structure.md: internal/ used throughout; Enterprise/CE split via _stubs_oss.go build stubs; three distinct modules with explicit visibility; internalshared/ as a cross-module seam.


P14-terraform#

P14-terraform / T1 (score 2): report:P14-terraform–interfaces.md: GraphNodeExecutable (1 method), GraphTransformer (1) alongside providers.Interface (~35), EvalContext (~30); statemgr.Full is exemplary interface composition (5 interfaces composed); bimodal but consumer-defined throughout.

P14-terraform / T2 (score 2): report:P14-terraform–architecture.md: all-internal architecture with zero exported packages; factory map registry for backends; no package singletons visible in reports; ContextOpts DI container; cleaner than most projects in this chunk.

P14-terraform / T3 (score 2): report:P14-terraform–architecture.md: ContextOpts as explicit DI container; each operation builds a fresh DAG; composition root in main.go is thin but explicit; no service locator.

P14-terraform / T4 (score 1): report:P14-terraform–patterns.md: atomic stop flag used instead of context cancellation for stopping operations; no documented clock injection or parameterized IO beyond context; consistent with the graph/batch model.

P14-terraform / T5 (score 1): report:P14-terraform–architecture.md: DAG logic in internal/dag is pure; providers run as subprocesses (zero in-process IO mixing); internal/promising/ uses generics for pure promise combinators; limited to specific packages.

P14-terraform / T6 (score 2): report:P14-terraform–architecture.md: providers.Interface only at the subprocess boundary (all providers are out-of-process gRPC); internal graph transformers use concrete types; EvalContext wraps the internal pipeline but is a necessary abstraction for the walk.

P14-terraform / T7 (score 1): report:P14-terraform–structure.md: zero exported packages (all internal/); rpcapi provides gRPC automation interface; no importable library; downstream tools consume via CLI or gRPC protocol, not Go packages.

P14-terraform / T8 (score 3): report:P14-terraform–structure.md: all internal/, 9 remote-state backends as separate Go modules, clean layering with no import cycles reported; tfplugin5/tfplugin6 dual protocol separation; textbook package boundary discipline.


P15-nomad#

P15-nomad / T1 (score 2): report:P15-nomad–interfaces.md: Scheduler (1 method), FeasibleIterator/RankIterator (2 each), admissionController (1) are consumer-defined narrow interfaces; StateDB (30+) and DriverPlugin (15) are broader protocol contracts at real external boundaries.

P15-nomad / T2 (score 1): report:P15-nomad–patterns.md: init() subprocess dispatch trick in main.go for task drivers; shutdownCh + context coexistence; limited internal/ enforcement; not pervasive but present.

P15-nomad / T3 (score 2): report:P15-nomad–patterns.md: manual DI via constructor functions; Server and Client constructed with explicit dependency parameters; no service locator; greppable wiring.

P15-nomad / T4 (score 1): report:P15-nomad–patterns.md: shutdownCh + context coexistence (incomplete migration); blocking query/watch semantics via go-memdb; no explicit clock injection described; context present but not the primary mechanism.

P15-nomad / T5 (score 1): report:P15-nomad–structure.md: scheduler/ isolated with no server imports (clear separation); but nomad/structs/ as monolithic domain model entangles domain types with the rest; partial functional core isolation.

P15-nomad / T6 (score 2): report:P15-nomad–interfaces.md: CQRS-style boundary — read from State, write via Planner; Scheduler interface at the scheduling seam; internal server/client use concrete types for collaboration.

P15-nomad / T7 (score 2): report:P15-nomad–structure.md: api/ is a separate Go module providing the public Go client library; used by third-party tooling to interact with Nomad clusters.

P15-nomad / T8 (score 2): report:P15-nomad–structure.md: domain-driven layout at root level; scheduler/ cleanly isolated; api/ as separate module; only internal/testing/ for internal enforcement — less strict than ideal but intentional structure.


P16-dapr#

P16-dapr / T1 (score 2): report:P16-dapr–interfaces.md: leaf/transport interfaces are small (http.API 2 methods, wfengine.Interface 5, channel.AppChannel 5); core subsystem interfaces are broader (actors.Interface 12, security.Handler 16 with //nolint:interfacebloat); deliberate ISP split between subsystem and leaf boundaries.

P16-dapr / T2 (score 1): report:P16-dapr–patterns.md: component registration via init() blank imports with build-tag-controlled flavors (allcomponents.go vs stablecomponents.go); DefaultRegistry singletons per building block type; contained but present.

P16-dapr / T3 (score 2): report:P16-dapr–architecture.md: DaprRuntime struct as composition root; newDaprRuntime() wires all subsystems with Options structs; concurrency.RunnerCloserManager manages structured goroutine lifecycle; explicit and greppable.

P16-dapr / T4 (score 1): report:P16-dapr–patterns.md: context propagation pervasive (4702 context.Context references); context.WithCancelCause in newer subsystems; no documented clock injection or parameterized randomness.

P16-dapr / T5 (score 1): report:P16-dapr–structure.md: compstore is a leaf package (no deps) — closest to pure; pkg/api/universal/ as shared semantic layer is not pure (calls IO); no systematic functional core/IO separation.

P16-dapr / T6 (score 2): report:P16-dapr–interfaces.md: channel.AppChannel (app protocol selection), hotreload/loader.Interface (disk vs operator), resiliency.Provider — interfaces at real deployment-mode and replacement boundaries; internal Options struct wiring is concrete.

P16-dapr / T7 (score 1): report:P16-dapr–api-surface.md: sidecar binary with no importable Go library; extension via pluggable component gRPC protocol (any language can implement); no pkg/action-style embeddable library.

P16-dapr / T8 (score 2): report:P16-dapr–structure.md: standard Go layout (cmd/ + pkg/); pkg/internal/ for non-export; co-located fake/ and mock/ sub-packages; clean per-service isolation (pkg/placement, pkg/sentry only depended on by their cmd/).


P17-k3s#

P17-k3s / T1 (score 1): report:P17-k3s–interfaces.md: Executor (17 methods) and Driver (14) dominate the interface landscape; smaller Cluster (3) and store.ReadCloser (3) exist but are exceptions; provider-defined large interfaces characterize the primary abstractions.

P17-k3s / T2 (score 1): report:P17-k3s–patterns.md: executor singleton as package-level var; init() registration via blank import in main.go; managed.RegisterDriver() appends to a package-level slice; contained but structural.

P17-k3s / T3 (score 1): report:P17-k3s–patterns.md: executor.Set() is the injection point but it writes to a package-level global var — a service locator pattern rather than true constructor injection; large config structs pass deps through the call stack but the central executor is a global.

P17-k3s / T4 (score 1): report:P17-k3s–patterns.md: functional options WithCACertificate, WithTimeout for HTTP client configuration; context cancellation via signals.SetupSignalContext(); no documented clock injection for time-dependent operations.

P17-k3s / T5 (score 1): report:P17-k3s–structure.md: pkg/configfilearg/ is a pure preprocessing step; no pure-logic packages beyond that; executor implementation imports upstream Kubernetes app.Run() entry points directly — IO is deeply embedded.

P17-k3s / T6 (score 2): report:P17-k3s–architecture.md: Executor interface is a deliberate seam isolating k3s orchestration from upstream k8s code; most internal wiring uses concrete large config structs (Control, Node); correct placement of the one major interface.

P17-k3s / T7 (score 1): report:P17-k3s–api-surface.md: StartupHookArgs/StartupHook and RouterFunc as extension points for downstream builds (RKE2); Executor interface as compile-time seam; no versioned public library API.

P17-k3s / T8 (score 1): report:P17-k3s–structure.md: no internal/ directory — all packages under pkg/ are technically importable; no import cycle enforcement; package visibility entirely implicit; unusual for a project of this size.


P18-helm#

P18-helm / T1 (score 2): report:P18-helm–interfaces.md: PostRenderer (1 method), Getter (1), RESTClientGetter (3) are exemplary minimal interfaces; driver.Driver explicitly decomposed into Creator/Updator/Deletor/Queryor role interfaces; kube.Interface (10) is broad but documented as intentionally wide.

P18-helm / T2 (score 2): report:P18-helm–architecture.md: no package singletons; cobra.OnInitialize defers storage driver init until command execution; no Viper; no global registries; ConfigurationOption for customization — cleanest T2 in this chunk outside Terraform.

P18-helm / T3 (score 2): report:P18-helm–architecture.md: Configuration struct as DI container; cobra.OnInitialize deferred init pattern; NewInstall(cfg), NewUpgrade(cfg) constructors receive *Configuration explicitly — clear, greppable composition root.

P18-helm / T4 (score 1): report:P18-helm–patterns.md: sync.Once lazy init for Kubernetes client (lazyClient); With* functional options pervasive; no clock injection interface documented; context propagated through action layer.

P18-helm / T5 (score 2): report:P18-helm–architecture.md: pkg/engine renders Go templates with sprig — pure function, no IO dependency; pkg/storage/driver/memory is a pure in-process store; clear separation of rendering logic from Kubernetes apply logic.

P18-helm / T6 (score 2): report:P18-helm–interfaces.md: kube.Interface for cluster operation swappability (enables full test suite without a cluster); driver.Driver for storage backend selection; internal rendering and coalescing logic uses concrete types throughout.

P18-helm / T7 (score 3): report:P18-helm–architecture.md: pkg/action explicitly documented as “a library for calling top-level Helm actions”; imported by Flux, Argo CD, and other ecosystem tools; ConfigurationOption and With* functional options provide stable extension points — textbook embeddable library.

P18-helm / T8 (score 2): report:P18-helm–architecture.md: internal/ used for plugin runtime and logging; pkg/ exports only intentional surfaces; clean layering (cmd → action → kube/storage/engine); no import cycles reported.


P19-istio#

P19-istio / T1 (score 2): report:P19-istio–interfaces.md: XdsResourceGenerator (1 method!) is near-perfect ISP; XdsDeltaResourceGenerator embeds and extends it cleanly; ConfigStore (7), XDSUpdater (6); Collection[T] small generic interface — strong ISP in the xDS layer, slightly wider in the model layer.

P19-istio / T2 (score 1): report:P19-istio–patterns.md: feature flags registered at init() time via pkg/env.Register*Var() in pkg/features/ packages; xDS generator map populated during InitGenerators(); limited but structural.

P19-istio / T3 (score 2): report:P19-istio–architecture.md: bootstrap.Server as composition root with a 24-step explicitly ordered init sequence; server.Instance.AddStartFunc() component runner; manual wiring — no DI framework, no service locator.

P19-istio / T4 (score 1): report:P19-istio–patterns.md: stop-channel lifecycle dominates (538 <-chan struct{} occurrences) over context (341); no documented clock injection; atomic.Value for readiness state; stop channels are ambient lifecycle signals, not parameterized time.

P19-istio / T5 (score 2): report:P19-istio–patterns.md: PushContext is built as an immutable snapshot per push cycle — generators read it without locks, effectively a pure-read data structure; krt.Collection[T] framework provides declarative reactive transforms as functional pipelines over Kubernetes data.

P19-istio / T6 (score 2): report:P19-istio–interfaces.md: XdsResourceGenerator plugin map at the xDS extensibility boundary; ConfigStore/ConfigStoreController for backend selection; ServiceDiscovery aggregate for registry multiplexing; internal generator implementations use concrete PushContext snapshots.

P19-istio / T7 (score 1): report:P19-istio–architecture.md: control plane binary (pilot-discovery); pkg/kube/krt and pkg/kube/kclient are internally used packages; no versioned public library API; not designed for external import.

P19-istio / T8 (score 2): report:P19-istio–architecture.md: 263 interface definitions in pilot/pkg/model; clean package layering (krt → kclient → model → xds → bootstrap); modular per-concern packages; no import cycles in the core path reported.


P20-argo-cd#

P20-argo-cd / T1 (score 2): report:P20-argo-cd–interfaces.md: AppStateManager (3 methods!), Generator (3 methods) are exemplary; ClusterCache (14) and ArgoDB (~40) are wide but cover complete domain contracts; mix of narrow purpose-built and wider repository-style interfaces.

P20-argo-cd / T2 (score 1): report:P20-argo-cd–patterns.md: 76 init() functions (majority in generated protobuf/Kubernetes client code); non-generated uses register Prometheus metrics at startup; Kubernetes-standard pattern, tolerable but not clean.

P20-argo-cd / T3 (score 2): report:P20-argo-cd–architecture.md: ArgoCDServerOpts struct as “composition root manifest”; manual wiring in cobra.Command.Run for each service; all dependencies injected at the constructor boundary — explicit and auditable.

P20-argo-cd / T4 (score 1): report:P20-argo-cd–patterns.md: context propagation pervasive (4094 occurrences); context.WithTimeout used at all I/O boundaries; no documented clock injection; context is the deadline mechanism, not parameterized time.

P20-argo-cd / T5 (score 1): report:P20-argo-cd–architecture.md: gitops-engine/pkg/diff and pkg/health contain pure diff/health logic (Lua + built-in rules); but these are embedded as a sub-module, not distinctly separated packages; partial isolation rather than systematic.

P20-argo-cd / T6 (score 2): report:P20-argo-cd–interfaces.md: AppStateManager, LiveStateCache, Kubectl, ResourceTracking at real testability/replacement boundaries; ClusterCache from gitops-engine at the cluster-backend boundary; internal controller uses concrete types for reconcile loop wiring.

P20-argo-cd / T7 (score 1): report:P20-argo-cd–architecture.md: single binary, multiple personas; no importable Go library; CMP sidecar gRPC protocol and Generator interface enable community extensions; no versioned library API.

P20-argo-cd / T8 (score 2): report:P20-argo-cd–architecture.md: gitops-engine as embedded sub-module with its own import path; per-service package separation (controller/, server/, reposerver/, applicationset/); some internal/ usage; generally clean boundaries.


P21-tekton-pipeline#

P21-tekton-pipeline / T1 (score 3): report:P21-tekton-pipeline–interfaces.md: Requester (1 method), Waiter/Runner/PostWriter (1 each), ResolvedResource (3), dag.Task (2), dag.Tasks (1) — overwhelmingly single-method or narrow; consumer-defined throughout; optional capabilities (TimedResolution, ConfigWatcher) split correctly as ISP sub-interfaces.

P21-tekton-pipeline / T2 (score 1): report:P21-tekton-pipeline–architecture.md: Knative context-based injection — clients extracted via kubeclient.Get(ctx), taskruninformer.Get(ctx) — is a service-locator pattern through context; init() in generated Kubernetes client code; structurally present even if not pervasive in hand-written code.

P21-tekton-pipeline / T3 (score 2): report:P21-tekton-pipeline–architecture.md: sharedmain.MainWithConfig as composition root; factory functions taskrun.NewController(opts, clock), pipelinerun.NewController(opts, clock) per controller; explicit, discoverable wiring point; Knative framework provides the runner.

P21-tekton-pipeline / T4 (score 2): report:P21-tekton-pipeline–interfaces.md: Waiter, Runner, PostWriter are explicit IO abstractions injected into Entrypointer — each wraps a single IO concern (polling semaphore files, executing a subprocess, writing a result file); parameterized IO at the step-execution boundary is textbook T4 applied narrowly but correctly.

P21-tekton-pipeline / T5 (score 2): report:P21-tekton-pipeline–architecture.md: pkg/reconciler/pipeline/dag has zero Kubernetes dependencies — pure DAG logic tested without any cluster API; pkg/substitution is a pure parameter interpolation package; clear functional core within the reconciler layer.

P21-tekton-pipeline / T6 (score 2): report:P21-tekton-pipeline–interfaces.md: Resolver interface at the remote source extensibility boundary; Requester at the CRD protocol boundary; SPIRE interfaces (ControllerAPIClient, EntrypointerAPIClient) at the security subsystem boundary; internal DAG and substitution logic uses concrete types.

P21-tekton-pipeline / T7 (score 1): report:P21-tekton-pipeline–architecture.md: Kubernetes operator binary; Resolver interface is a plugin extension point for community resolvers; no versioned importable library; RunObject/TaskObject interfaces enable CustomRun extensibility but require CRD implementation.

P21-tekton-pipeline / T8 (score 2): report:P21-tekton-pipeline–architecture.md: Knative-style package layout with explicit pkg/ boundaries; pkg/remoteresolution and legacy pkg/resolution coexist (migration in progress); internal/computeresources for hidden computation; generally disciplined but dual-framework coexistence creates some noise.


Confidence note (chunk-local)#

High confidence: P13-vault (T7=3), P14-terraform (T8=3), P18-helm (T7=3), P21-tekton-pipeline (T1=3) — all strongly evidenced by multiple reports with explicit codebase references.

Medium confidence:

  • T4 universally scored 1 across most projects: reports rarely document clock injection explicitly; the absence of evidence is likely genuine absence of the pattern rather than a reporting gap, but T4=1 vs T4=0 is a judgment call (1 chosen because context propagation demonstrates awareness of parametric dependencies even when time/IO are not fully parameterized).
  • P11-minio T7=1 vs T7=0: MinIO ships no library API but does have github.com/minio/pkg in separate repos; scored 1 for minimal rather than 0 for absent.
  • P17-k3s T3=1: the executor injection point is genuinely a package-level global, not constructor injection; however the init()/blank-import pattern is a deliberate architectural seam; scored 1 rather than 2.

Hardest-to-assign:

  • T5 for projects 11, 12, 15, 16, 20 (all scored 1): reports give mixed signals about which packages are “pure” — some have clear utility packages but no systematic functional-core discipline; the boundary between 1 and 2 here is particularly uncertain.
  • T2 for P14-terraform (scored 2): reports describe “all-internal” and “factory maps” but do not explicitly confirm absence of package-level singletons; this is a positive inference rather than direct observation.
  • T6 is uniformly 2 across all 11 projects: the rubric’s T6 is “contrarian” (high interface count ≠ high T6) and every project in this chunk uses interfaces at real boundaries without pervasive over-abstraction of internals. Score 2 (“present”) reflects this consistent pattern; none reached 3 (“textbook”) because none had strong positive evidence of explicit internal-collaborators-are-concrete design enforcement.