feat: Phase 7 — SeedService, SecretsService, ProvisioningService + ssh Provisioner

Seed ingest/export moves behind ports.SeedRepository (SeedRepo in the
postgres adapter; knowledge ingest absorbed from internal/knowledge,
package deleted). pct_create flow (defaults, template/VMID/gateway
pre-flights, pct create, graph registration) moves from httpapi's
approved-execution path into app.ProvisioningService + the ssh
provisioner adapter; CLI seed/export/secret become adapters over the
services. EntityCreateInput gains EnrolledAt. Plan status corrected:
phases 0-7 shipped, 8 + 9 gates open. VERSION 0.34.1.
This commit is contained in:
2026-08-16 09:11:26 +02:00
parent cd44501fa9
commit 60c0432d8b
26 changed files with 1565 additions and 689 deletions

View File

@@ -0,0 +1,43 @@
package ports
import "context"
// SeedCounts summarizes what one seed ingest wrote, by section. Sections
// the file does not exercise stay zero.
type SeedCounts struct {
Lifecycles int
EntityTypes int
RelationshipTypes int
Entities int
Relationships int
Checks int
RiskClasses int
ApprovalRules int
AutonomySettings int
Documents int
Investigations int
Runbooks int
}
// SeedRepository is the seed aggregate: bootstrap ingest (seeds/*.yaml →
// DB) and the inverse export (DB → seeds/*.yaml for DR / version
// control).
//
// Each Ingest method is one transaction — parse, validate against the
// ontology, write, and record the file's content hash in seed_versions —
// and a no-op (applied=false) when the hash is unchanged, so re-running
// `oikos seed` is idempotent. Validation failures roll back the whole
// file. Ingest order across files (ontology before inventory) is a
// SeedService concern; within inventory, default checks derive only after
// relationships exist (a service inherits its container's address).
//
// Export regenerates the three structural seed YAMLs deterministically
// (sorted maps, ordered lists) so export → ingest → export is
// byte-stable. Runtime state (cognition layer) is excluded.
type SeedRepository interface {
IngestOntology(ctx context.Context, filename string, content []byte) (counts SeedCounts, applied bool, err error)
IngestInventory(ctx context.Context, filename string, content []byte) (counts SeedCounts, applied bool, err error)
IngestPolicy(ctx context.Context, filename string, content []byte) (counts SeedCounts, applied bool, err error)
IngestKnowledge(ctx context.Context, filename string, content []byte) (counts SeedCounts, applied bool, err error)
Export(ctx context.Context) (map[string][]byte, error)
}