Skip to content

feat(agent): add system fact collection and display#223

Merged
retr0h merged 24 commits intomainfrom
feat/agent-facts
Mar 5, 2026
Merged

feat(agent): add system fact collection and display#223
retr0h merged 24 commits intomainfrom
feat/agent-facts

Conversation

@retr0h
Copy link
Collaborator

@retr0h retr0h commented Mar 5, 2026

  • New providers: Extended host.Provider with GetArchitecture, GetKernelVersion, GetFQDN, GetCPUCount, GetServiceManager, GetPackageManager. New netinfo.Provider
    for network interfaces with IPv4/IPv6/MAC/family support. Linux + Darwin implementations.
  • Facts KV bucket: New agent-facts NATS KV bucket. Agent writes facts on a 60s interval, separate from the 10s heartbeat. Provider errors are non-fatal.
  • Job client merge: ListAgents and GetAgent merge facts from the KV bucket into AgentInfo responses transparently.
  • API + OpenAPI: AgentInfo schema extended with architecture, kernel_version, cpu_count, fqdn, service_mgr, package_mgr, interfaces, facts fields.
  • CLI: agent get now displays all facts fields including network interfaces.
  • Config: New nats.facts and agent.facts config sections.
  • SDK: Pinned to latest with replace directive removed.
  • Tests: 100% coverage on new providers and mergeFacts.

retr0h and others added 22 commits March 4, 2026 09:57
Replace all gen type usage in CLI commands with SDK domain types.
HandleError uses errors.As() for typed error handling. All 22
cmd files, audit export package, and CLI UI helpers updated.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Design for extensible fact gathering per agent, stored in a separate
facts KV bucket with typed fields for common facts and a flexible map
for pluggable collectors (cloud metadata, local facts).

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
10-task TDD implementation plan covering types, config, collector
interface, facts KV infrastructure, fact writer, merging, OpenAPI
spec, and documentation.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Remove Collector interface. Route all fact gathering through the
existing provider layer (extend host.Provider, new netinfo.Provider).
Add documentation update tasks for configuration reference, feature
pages, architecture pages, and CLI docs.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Add NetworkInterface and FactsRegistration types for the agent facts
collection system. Extend AgentInfo with facts fields (architecture,
kernel version, CPU count, FQDN, service/package managers, network
interfaces, and arbitrary facts map).

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add NATSFacts struct for configuring the agent facts KV bucket
(bucket, TTL, storage, replicas) and AgentFacts struct for
configuring the facts collection interval. Wire both into the
NATS and AgentConfig parent structs.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add six new methods to the host.Provider interface for system fact
collection: GetArchitecture, GetKernelVersion, GetFQDN, GetCPUCount,
GetServiceManager, and GetPackageManager. Implemented for Ubuntu and
Darwin providers with testable function variables (HostnameFn, NumCPUFn,
StatFn, LookPathFn). Linux provider has stub implementations. All
methods follow existing patterns with table-driven tests covering
success and error paths.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add a new provider that retrieves non-loopback, up network interfaces
with name, IPv4, and MAC address. Uses InterfacesFn struct field for
testability, matching the pattern used by the host provider.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Wire up the NATS KV bucket for storing agent facts. Add
BuildFactsKVConfig helper, create the bucket in setupJetStream,
pass factsKV through natsBundle and job client Options, and
include it in the health metrics KV bucket list.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add IPv6 field to NetworkInterface type and update netinfo provider
to extract both IPv4 and IPv6 addresses from network interfaces.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add facts writer that runs alongside the heartbeat in the agent,
collecting system facts via host and netinfo providers and writing
them to the agent-facts KV bucket on a 60-second interval.

- Create facts.go with startFacts/writeFacts/factsKey functions
- Add factsKV and netinfoProvider fields to Agent struct
- Update New() constructor and CreateProviders() factory
- Wire startFacts() into Start() lifecycle
- Pass factsKV and netinfo provider from cmd/agent_helpers.go
- Update all existing test files for new constructor signature

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add Family field ("inet", "inet6", "dual") computed from which
addresses are present on the interface.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add mergeFacts helper that reads from the facts KV bucket and enriches
AgentInfo with architecture, kernel version, CPU count, FQDN, service
manager, package manager, network interfaces, and custom facts. Called
in both ListAgents and GetAgent after building info from registration.
Gracefully degrades when factsKV is nil or Get returns an error.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add architecture, kernel_version, cpu_count, fqdn, service_mgr,
package_mgr, interfaces, and facts fields to the AgentInfo OpenAPI
schema. Add NetworkInterfaceResponse schema with name, ipv4, ipv6,
mac, and family fields. Update buildAgentInfo to map new domain
fields to the generated API types.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add nats.facts (bucket, TTL, storage) and agent.facts (interval)
configuration sections.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add package comment to netinfo, rename unused params to _, fix
goimports formatting.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add AddrsFn to Netinfo struct to make address resolution mockable,
enabling test cases for IPv4/IPv6/dual/no-address interfaces and
non-IPNet address types. Add ExecNotFoundError.Error() assertion
to the host package manager test table.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add architecture, kernel, CPUs, FQDN, service/package manager, and
network interfaces to `agent get` CLI output. Add mergeFacts invalid
JSON test for 100% coverage. Update local config with facts KV bucket.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

Thank you for contributing to this project! 😊🕹️

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@codecov
Copy link

codecov bot commented Mar 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

Impacted file tree graph

@@           Coverage Diff            @@
##             main     #223    +/-   ##
========================================
  Coverage   99.98%   99.98%            
========================================
  Files         137      157    +20     
  Lines        5083     5293   +210     
========================================
+ Hits         5082     5292   +210     
  Misses          1        1            
Files with missing lines Coverage Δ
internal/agent/agent.go 100.00% <100.00%> (ø)
internal/agent/factory.go 100.00% <100.00%> (ø)
internal/agent/facts.go 100.00% <100.00%> (ø)
internal/agent/server.go 100.00% <100.00%> (ø)
internal/api/agent/agent_list.go 100.00% <100.00%> (ø)
internal/audit/export/file.go 100.00% <ø> (ø)
internal/cli/nats.go 100.00% <100.00%> (ø)
internal/cli/ui.go 100.00% <100.00%> (ø)
internal/job/client/client.go 100.00% <100.00%> (ø)
internal/job/client/query.go 100.00% <100.00%> (ø)
... and 21 more

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d186feb...4b59f88. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@retr0h retr0h merged commit 04438c7 into main Mar 5, 2026
7 checks passed
@retr0h retr0h deleted the feat/agent-facts branch March 5, 2026 01:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant