Conversation
Layered configuration management (defaults → file → env → flags) with viper backend, YAML persistence via go-io Medium, and framework service. Moved from forge.lthn.ai/core/go/pkg/config to standalone module. Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Virgil <virgil@lethean.io>
Add go-devops build system configuration for standardised build, test, and release workflows across the Go ecosystem. Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Virgil <virgil@lethean.io>
Resolve stale forge.lthn.ai/core/cli v0.1.0 references (tag never existed, earliest is v0.0.1) and regenerate go.sum via workspace-aware go mod tidy. Co-Authored-By: Virgil <virgil@lethean.io>
…tf in coreerr.E calls Co-Authored-By: Virgil <virgil@lethean.io>
… CLAUDE.md — replace outdated `...' (#2) from agent/fix-these-issues--1--update-claude-md into main
Migrate from forge.lthn.ai deps to dappco.re. Replace os, strings, path/filepath with Core primitives. OnStartup returns core.Result. Service factory returns core.Result. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Virgil <virgil@lethean.io>
…re primitives Replaced fmt, strings, sort, os, io, sync, encoding/json, path/filepath, errors, log, reflect with core.Sprintf, core.E, core.Contains, core.Trim, core.Split, core.Join, core.JoinPath, slices.Sort, c.Fs(), c.Lock(), core.JSONMarshal, core.ReadAll and other CoreGO v0.8.0 primitives. Framework boundary exceptions preserved where stdlib types are required by external interfaces (Gin, net/http, CGo, Wails, bubbletea). Co-Authored-By: Virgil <virgil@lethean.io>
Spark draft (RFC §4 expansion) + opus cleanup. Two real bugs fixed during the cleanup pass: - Load() restored to YAML/env-only per RFC §4 (the spark pass widened it to JSON/TOML; that surface belongs on LoadFile only). Added yamlConfigTypeForPath helper. - WithEnvPrefix no longer stores trailing underscore — viper's SetEnvPrefix auto-appends one at merge time, so a stored "MYAPP_" became "MYAPP__SETTING" and missed env vars entirely. New surface (preserved untracked from spark draft): - conclave.go discover.go feature.go schema.go watch.go xdg.go Co-Authored-By: Virgil <virgil@lethean.io>
Intelligently resolved conflicts across config.go, service.go, env.go, config_test.go, go.mod, go.sum: - service.go: take origin/main NewConfigService returning core.Result + core.E() directly; keep dev-branch EnvPrefix field and OnStartup handling - config.go: keep full HEAD (watch support, dual-viper, All/Path/helpers); resolve New() default-path via defaultConfigPath() helper; Load() uses dynamic configType not hardcoded "yaml" - env.go: keep HEAD slices import (required for slices.SortFunc); drop origin/main comment addition - config_test.go: canonical import order + restore missing os import - go.mod/go.sum: keep HEAD versions (io v0.4.1, log v0.1.2); drop stale forge.lthn.ai/core/go-log indirect; go mod tidy promoted fsnotify to direct Co-Authored-By: Virgil <virgil@lethean.io>
…h, features, conclave - Align module imports with canonical dappco.re/go/core paths so go build ./... and go test ./... both pass against the v0.8.0 Core API. - Rework Service to match the current Core contract: OnStartup returns core.Result, uses ServiceRuntime.Options(), registers config.get / set / commit / load / all actions and config/get|set|list commands, and attaches the Config so Set/Commit broadcast ConfigChanged events. - Add Config.MergeFrom, OnChange callbacks, WithCore option, and Medium accessor per go/config RFC §7.3. - Add .core/ directory Discover()/DiscoverFrom() that walks cwd → root with closest-wins precedence and a filesystem-root / .git repo boundary stop. - Add XDGPaths (Config/Data/Cache/Runtime) with Linux/macOS/Windows defaults and env-var overrides per go/config RFC §8. - Add manifest schema types (ViewManifest + ViewPermissions, BuildManifest + BuildTarget, PackageManifest, WorkspaceManifest) and LoadManifest helper. - Add filesystem Watch/StopWatch with 100ms debounce via fsnotify. - Add process-level Feature/SetFeature/Features with CORE_FEATURE_* env override that always wins over registry state. - Add ForConclave + SetConclaveRootFunc for session-scoped config inheritance. - Tests: one _Good/_Bad/_Ugly trio per new source file, plus Service action/ command round-trip tests and a ConfigChanged broadcast assertion. Co-Authored-By: Virgil <virgil@lethean.io>
…flag config source Implements the remaining RFC features beyond opus 653cb60: - Add known file name constants (FileConfig/Build/Release/Test/Run/View/ Manifest/Workspace/Repos) + Directory + KnownFiles — a single source of truth for the .core/ convention (RFC §2.1). - Add CoreDirs() and FindManifest() discovery helpers so consuming packages can locate a specific manifest without reimplementing the walk (go-config RFC §7.2). - Add TestManifest, RunManifest, ReleaseManifest structs + nested DTOs to match the file registry; keep manifests centralised so go-build, core dev, and go-scm don't drift (RFC folder-spec §3.4-§3.7). - Feature() now consults a globally-registered Config via SetFeatureSource() and exposes FeatureFromConfig() for explicit lookups, so `features.*` keys in .core/config.yaml actually drive Feature() results per RFC §11.3. Env vars still win first. All {Good, Bad, Ugly} triads added. go build / vet / test (incl. race) green. Co-Authored-By: Virgil <virgil@lethean.io>
The spec (§4.3, §7.1) documents `core.WithService(config.NewConfigService)`
as the registration pattern, but the factory returned `(any, error)` and
therefore could not be passed to `core.WithService`, which expects
`func(*core.Core) core.Result`. Downstream usage failed to compile.
NewConfigService now returns core.Result{Value: *Service, OK: true},
letting core.WithService auto-discover the "config" name from the package
path and wire the service into the Startable + IPC lifecycle.
Also adds NewConfigServiceWith(opts) for hosts that need a non-default
path, medium, or env prefix without plumbing options through the Core
container.
Co-Authored-By: Virgil <virgil@lethean.io>
Close spec gaps against code/core/go/config/RFC.md §6 and
code/core/config/RFC.md §7.2:
- All() now yields flat dot-notation keys and includes env-prefixed
overrides, matching the RFC §6 contract ("includes environment overrides").
Previously returned nested map[string]any under top-level keys only.
- FileIDE ("ide.yaml") and FilePHP ("php.yaml") constants added to
KnownFiles, matching the known-file registry in both specs.
- AttachCore() replaces direct c.core assignment from service.OnStartup,
closing a data race with Set()/Commit() readers.
Co-Authored-By: Virgil <virgil@lethean.io>
MergeFrom now lands inherited values in the defaults layer (SetDefault on full viper) and no longer writes them into the persistable file viper. Three consequences, all aligned with the .core/ convention spec: - §5.3 "env vars override everything" is restored — Discover+Get no longer shadows CORE_CONFIG_* with the discovered file value. - Commit on a discovered Config writes only its own Set() + loaded values, so a project Commit can't leak ~/.core/config.yaml secrets into the project file. - Chained MergeFrom (Discover → Conclave) still works: MergeFrom now reads both source.file and source.full so inheritance propagates through the chain. ForConclave discovers from cwd instead of the conclave root so project + ~/.core/ layers populate the inheritance chain (the conclave root sits under XDG config and a walk from there finds nothing). Watch reload diffs before/after snapshots and fires OnChange once per changed key with key + new value + previous, per RFC §10.2. Empty-key full-reload signal is replaced by per-key callbacks. Co-Authored-By: Virgil <virgil@lethean.io>
- Migrate module path: dappco.re/go/core/config -> dappco.re/go/config - Bump dappco.re/go/* deps to v0.8.0-alpha.1 in go.mod (any forge.lthn.ai/core/* paths migrated to canonical dappco.re/go/* form) - Update Go source imports across 25 .go files - Add tests/cli/config/Taskfile.yaml AX-10 scaffold (build/vet/test under default deps), per RFC-CORE-008-AGENT-EXPERIENCE.md §10 Co-Authored-By: Athena <athena@lthn.ai>
# Conflicts: # config.go
# Conflicts: # conclave.go # config.go # config_test.go # discover.go # feature.go # go.mod # go.sum # schema.go # service.go # watch.go # xdg.go
35+ findings dispositioned. AX-6 conformance preserved (no testify re-introduced). Code fixes: - conclave.go: go.sum entries added - watch.go: debounce overlap fixed; misleading retry comment corrected - schema/agent.schema.json: numeric bounds added - schema/zone.schema.json: invalid-structure rejection tightened - test_detect.go: 'core go qa' instead of raw 'go test ./...' - service.go + config.go: cognitive complexity refactors + duplicate literal extraction (config service/action/command/load paths) - manifest.go: duplicated caller/error literals → shared constants; duplicate LDFlags branch removed; trusted-key complexity refactored - images_manifest.go + schema.go + test_detect.go + discover.go + conclave.go: duplicate caller literals → shared constants Tests: - *_test.go suite migrated to real FS / env-based fixtures (was using nil-medium and other test-only doubles) - schema_test.go non-fatal error assertion uses t.Fatal (no testify) - xdg_test.go POSIX path assertion fixed - watch_test.go real FS watcher tests - tests/cli/config/Taskfile.yaml raw 'go' commands replaced Disposition replies: - docs/architecture.md 'core.Config concrete' claim: RESOLVED-COMMENT — upstream core.Config IS concrete, doc is correct - service.go core.Config assertion: RESOLVED-COMMENT — illegal because upstream is concrete struct - GHAS: 0 PR code scanning alerts. RESOLVED-COMMENT. Verification: gofmt clean, GOWORK=off go vet + go test -count=1 ./... pass with explicit GOPATH/GOMODCACHE/GOCACHE. Closes findings on #3 Co-authored-by: Codex <noreply@openai.com>
All ten audit dimensions = 0 (COMPLIANT). Co-authored-by: Codex <noreply@openai.com> Closes tasks.lthn.sh/view.php?id=1147
Audit verdict: COMPLIANT across the 21 dimensions in force at fire time. The 22nd dimension (err-shape-funcs) was added after this lane's prompt was sealed; this repo's err-shape count is 0 by happy accident. Notable changes: - Banned stdlib imports replaced with dappco.re/go core wrappers - AX-7 monolith files deleted; triplets redistributed into per-source <file>_test.go siblings - Per-source <file>_example_test.go presence completed - AGENTS.md + README.md authored Round 2 follow-up (not blocking this commit, no discard): - xdg_test.go has TestXdgDefaultHomesUgly etc — non-canonical Test<File><Symbol><Variant> form (no underscore separators). manifest_test.go has the same pattern on TestManifestTrustedManifestPublicKeysSymlinkedCoreBad and friends. These dodge identical-triplets' regex which requires _<Variant>. Needs a non-canonical-triplet-names audit dimension and rename pass. Co-authored-by: Codex <noreply@openai.com>
Audit verdict: COMPLIANT across all 24 dimensions. Notable changes: - 48 non-canonical Test names fixed (_<Variant> separators restored) - Production `func ... error` returns converted to `core.Result` - Watch backend constructors bridged to Result via watchBackendResult helper - No type-alias dodges introduced Co-authored-by: Codex <noreply@openai.com>
…submodules Lift Go module into go/ subtree for cross-language repo symmetry (matches core/api v0.12.0 shape). Module path stays dappco.re/go/config — consumers see no change. Adds go.work + external/<deps> submodules for dev workspace mode; CI uses GOWORK=off (already set in .woodpecker.yml).
Production fixes (no test-file changes per brief): - 11 errcheck (mostly attached.ACTION + c.Command callsites — wrapped in _ =) - 2 staticcheck Schema dir copied into go/schema/ for //go:embed (go:embed doesn't follow symlinks into directories — known Go limitation, see #issue). Repo-root schema/ stays as cross-language source of truth; go/schema/ is a build artefact mirroring it. Future TODO: schema generation script that mirrors on build, or migrate fully into go/ if no cross-lang consumer materialises.
Mirrors api shape: .github/workflows/ci.yml runs test+coverage (Codecov), golangci-lint --tests=false, and sonarcloud-scan-action to dappcore_config. README gets the badge block (CI / quality gate / cov / security / maintainability / reliability / smells / NCLOC / pkg.go.dev / license). GOPROXY=direct GOSUMDB=off env in workflow to dodge the proxy.golang.org stale-zip pattern that broke api's first run. Internal Woodpecker pipeline at ci.lthn.sh continues unchanged.
Snider 2026-04-30: 'belongs in core/config'. Was a hack-doc inside agent/.core/docs/ when core.agent was broken. Now that agent's .core/ hack is gone, the .core folder spec doc is correctly homed in dappco.re/go/config.
Per-rule: - S1192 (string-literal dup → const): 80 - S1871 (duplicated branches): 1 - S4144 (identical implementations): 3 - yaml:DocumentStartCheck: 1 Plus side-fixes during verify: errcheck:1, ineffassign:1. vet/test/golangci-lint clean. No exported API changed.
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (5)
📒 Files selected for processing (100)
📝 WalkthroughWalkthroughThe PR restructures the configuration package from a root-level module into a Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Service
participant Config
participant Discover
participant Medium as Medium<br/>(Filesystem)
participant Store as Store<br/>(Optional)
Client->>Service: OnStartup(ctx)
Service->>Discover: Discover(opts...)
Discover->>Medium: Walk upward for .core/config.yaml
Medium-->>Discover: Layer paths
Discover->>Config: New with each layer
Config->>Medium: LoadFile(layer)
Medium-->>Config: Parse YAML
Config->>Config: MergeFrom(base)
Config-->>Service: Return *Config
Service->>Config: AttachCore()
opt Store attached
Service->>Store: Write persisted state
Store-->>Service: Confirm
end
Service->>Config: OnChange callback
Service-->>Client: OK result
Client->>Service: Set(key, value)
Service->>Config: Set(key, value)
Config->>Config: Update both Viper instances
Config->>Store: Persist if enabled
Config->>Service: Emit ConfigChanged event
Service-->>Client: OK result
Client->>Service: Commit()
Service->>Config: Commit()
Config->>Medium: Save only file Viper
Medium-->>Config: Write to disk
Config-->>Service: OK result
Service-->>Client: OK result
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.





Routine dev→main promotion as part of cross-repo top-down dep tree sweep so module-tidy can resolve current versions across consumers.
Summary by CodeRabbit
Release Notes
New Features
.core/config.yamldiscovery and layered resolution (defaults → file → environment → explicit settings).Refactor
Chores