feat(go): add Phase 1 parity sidecar

This commit is contained in:
Luna 2026-07-10 05:02:50 -07:00
parent 65f5be6420
commit f02509aab5
22 changed files with 947 additions and 6 deletions

View file

@ -0,0 +1,75 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// enodia-sentinel-go is the experimental Phase 1 sidecar. Python remains the
// production implementation and behavioral oracle until parity is complete.
package main
import (
"context"
"encoding/json"
"flag"
"fmt"
"os"
"os/signal"
"syscall"
"time"
"codeberg.org/anassaeneroi/enodia-sentinal/go-agent/internal/agent"
"codeberg.org/anassaeneroi/enodia-sentinal/go-agent/internal/config"
"codeberg.org/anassaeneroi/enodia-sentinal/go-agent/internal/model"
"codeberg.org/anassaeneroi/enodia-sentinal/go-agent/internal/system"
)
func main() {
if err := run(); err != nil {
fmt.Fprintln(os.Stderr, "enodia-sentinel-go:", err)
os.Exit(1)
}
}
func run() error {
once := flag.Bool("once", false, "emit one sweep and exit")
configPath := flag.String("config", "", "Sentinel TOML path (default: ENODIA_CONFIG or /etc/enodia-sentinel.toml)")
procRoot := flag.String("proc-root", "/proc", "procfs root")
fixture := flag.String("fixture", "", "JSON SystemState fixture (parity/testing only)")
host := flag.String("host", "", "override hostname (parity/testing only)")
timestamp := flag.String("timestamp", "", "override RFC3339 timestamp (parity/testing only)")
flag.Parse()
cfg, err := config.Load(*configPath)
if err != nil {
return err
}
capture := func() (model.State, error) { return system.Capture(*procRoot) }
if *fixture != "" {
capture = func() (model.State, error) {
var state model.State
raw, err := os.ReadFile(*fixture)
if err != nil {
return state, err
}
err = json.Unmarshal(raw, &state)
return state, err
}
}
runner := agent.New(cfg, capture)
if *host != "" {
runner.Host = func() (string, error) { return *host, nil }
}
if *timestamp != "" {
fixed, err := time.Parse(time.RFC3339Nano, *timestamp)
if err != nil {
return fmt.Errorf("timestamp: %w", err)
}
runner.Now = func() time.Time { return fixed }
}
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
encoder := json.NewEncoder(os.Stdout)
encoder.SetEscapeHTML(false)
return runner.Run(ctx, *once, func(event map[string]any) error {
return encoder.Encode(event)
})
}