ScobleClaw monorepo
Resolves the #63 root cause: CNPG managed.roles expects each role to reference its own type=kubernetes.io/basic-auth Secret with literal 'username'/'password' keys (see cloudnative-pg/internal/management/utils/secrets.go). The previous shared 'postgres-users' Secret with role-name-suffixed keys (forgejo-password, umami-password, scoble_audit_writer-password) was never going to reconcile, so forgejo/umami had been silently missing from the database for the entire lifetime of the cluster. Changes: - secret-{forgejo,umami,scrole}.yaml: per-role basic-auth Secrets in 'database' ns. forgejo/umami passwords stay at the existing <change-me> placeholder. scrole gets a new random 32-byte password. - secret-scoble-policy-pg-creds.yaml: Opaque Secret in 'scoble-policy' ns with username/password/jdbc-url for the audit-sink Integration to mount. - migrate.sql: drops the previous scoble_policy_audit (decision_id/actor/action shape) and recreates the schema.sql shape (agent_id/kamelet_ref/decision/etc.) with the right indexes, check constraint, and scrole GRANTs. - apply-schema-pod.yaml: one-shot Pod that runs migrate.sql using the CNPG superuser Secret as credential source. - schema.sql: now also documents the scrole GRANTs needed (idempotent). - README.md: updated with apply+verify steps, #62/#64 known issues, and the full diagnosis of #63. End-to-end verified 2026-06-07 23:55 UTC: - All 3 managed roles (forgejo, umami, scoble_audit_writer) exist in PG. - scrole can SELECT/INSERT on scoble_policy_audit. - A 'smoke-1' row is in the table; a Kafka message at scoble-kafka:9092 in the audit-sink shape is consumable end-to-end. - Legacy 'postgres-users' secret deleted (no longer referenced by the cluster). Refs: marcus/engineering#43, marcus/engineering#63 |
||
|---|---|---|
| docs | ||
| kubeclaw | ||
| pkg/floxenv | ||
| pool-manager | ||
| scoble-policy/audit-sink/provisioning | ||
| .gitignore | ||
| coach-pattern-analysis.md | ||
| go.mod | ||
| README.md | ||
floxenv
Go package for managing Flox environment lifecycles via flox activate --detach.
Features
- Activate — start a Flox environment and return an
envID+ PID. - Deactivate — graceful shutdown with
SIGTERMthenSIGKILLafter a 10-second grace period. - IsAlive — lightweight, non-privileged process-existence check using zero-signal delivery.
- Dev-mode stub — transparently falls back to a long-running shell command when
floxis not installed (or whenFLOXENV_DEV_MODE=1is set), useful for CI and local development.
Installation
go get github.com/marcus/scobleclaw/pkg/floxenv
Usage
package main
import (
"fmt"
"log"
"github.com/marcus/scobleclaw/pkg/floxenv"
)
func main() {
r := floxenv.NewRegistry()
envID, pid, err := r.Activate("/path/to/env/.flox/env/manifest.toml")
if err != nil {
log.Fatal(err)
}
fmt.Printf("activated %s (pid %d)\n", envID, pid)
// later …
if err := r.Deactivate(envID, pid); err != nil {
log.Fatal(err)
}
}
Dev mode
When the flox binary is absent, or when FLOXENV_DEV_MODE=1 is set in the environment, the package runs a lightweight stub that forks a shell sleep process instead of invoking flox activate. This keeps dependent tests green in environments where Flox is not available.
Running tests
Unit tests (uses the dev-mode stub):
go test ./pkg/floxenv
Integration tests (requires a working Flox installation):
go test -tags=integration ./pkg/floxenv
API
| Function | Signature | Description |
|---|---|---|
NewRegistry |
() *Registry |
Create a new registry, auto-detecting dev mode. |
(*Registry) Activate |
(manifestPath string) (envID string, pid int, err error) |
Activate a Flox environment. |
(*Registry) Deactivate |
(envID string, pid int) error |
Shutdown an active environment. |
IsAlive |
(pid int) bool |
Non-privileged process existence check. |
(*Registry) List |
() []Info |
Snapshot of tracked environments. |
License
MIT