Dagger
Search

dagmar

This is dagmar's own Dagger module (seed cbb8 spike: engine tenancy & Run concurrency).
It prototypes dagmar's Hybrid-C topology hermetically: an in-cluster Dagger engine
serving agent pods, brought up inside an isolated k3s cluster that itself runs inside
the OUTER Dagger engine (Docker Desktop). The outer engine runs this module; the inner
engine (deployed into k3s) is the system under test. Never touches the production
netcup cluster.

Installation

dagger install github.com/denkhaus/dagmar@ef831774e5eff33b9012d4cc7ac9570ec2bc605d

Entrypoint

Return Type
Dagmar !
Arguments
NameTypeDefault ValueDescription
projectDirectory -The target Project's source directory (per-Project binding seam).
seedsString -seeds issue-store path for the Project (os-eco binding, per-Project).
mulchString -mulch expertise-store path for the Project (os-eco binding, per-Project).
canopyString -canopy prompt-store path for the Project (os-eco binding, per-Project).
Example
dagger -m github.com/denkhaus/dagmar@ef831774e5eff33b9012d4cc7ac9570ec2bc605d call \
func (m *MyModule) Example() *dagger.Dagmar  {
	return dag.
			Dagmar()
}
@function
def example() -> dagger.Dagmar:
	return (
		dag.dagmar()
	)
@func()
example(): Dagmar {
	return dag
		.dagmar()
}

Types

Dagmar 🔗

Dagmar is dagmar’s main Dagger object (auto-named from the module). It is the primary entry point into dagmar’s Dagger functionality AND the per-Project binding seam: the New constructor binds the target Project + os-eco configuration once, and every method (Run, Sandbox, Gate, …) reuses that bound state (ADR-0010 §5).

deployEngine() 🔗

DeployEngine deploys the singleton Dagger engine as a privileged DaemonSet into k3s and reports the Ready engine pod. (cbb8 spike — the nesting test.)

Return Type
String !
Arguments
NameTypeDefault ValueDescription
clusterString "dagmar-spike"

name of the throwaway k3s cluster

Example
dagger -m github.com/denkhaus/dagmar@ef831774e5eff33b9012d4cc7ac9570ec2bc605d call \
 deploy-engine
func (m *MyModule) Example(ctx context.Context) string  {
	return dag.
			Dagmar().
			Deployengine(ctx)
}
@function
async def example() -> str:
	return await (
		dag.dagmar()
		.deployengine()
	)
@func()
async example(): Promise<string> {
	return dag
		.dagmar()
		.deployEngine()
}

probe() 🔗

Probe validates Research Q3: can a Dagger CLIENT reach the singleton (nested) engine via kube-pod://? Deploys the engine, then runs dagger core version in a client container pointed at the inner engine through _EXPERIMENTAL_DAGGER_RUNNER_HOST=kube-pod://… A version reported from the inner engine proves the singleton engine serves clients — the precondition for multi-tenancy on one engine.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
clusterString "dagmar-spike"

name of the throwaway k3s cluster

Example
dagger -m github.com/denkhaus/dagmar@ef831774e5eff33b9012d4cc7ac9570ec2bc605d call \
 probe
func (m *MyModule) Example(ctx context.Context) string  {
	return dag.
			Dagmar().
			Probe(ctx)
}
@function
async def example() -> str:
	return await (
		dag.dagmar()
		.probe()
	)
@func()
async example(): Promise<string> {
	return dag
		.dagmar()
		.probe()
}

probeCache() 🔗

ProbeCache is the dagmar-d8f0 spike: it empirically validates that a Dagger engine isolates cache by volume NAME (the ADR-0008 §3 design assumption — “Dagger isolates cache by volume name; cache poisoning across Projects is prevented as long as Projects use distinct cache-volume names”). It is run as THREE separate dagger call probe-cache --mode ... invocations — i.e. three separate client sessions against one engine, the cheapest faithful analogue of “two client pods on the singleton engine”:

dagger call probe-cache --mode write     # write MARKER_A into cache volume "…-A"
dagger call probe-cache --mode readsame  # read volume "…-A"  (expect MARKER_A → shares)
dagger call probe-cache --mode readdiff  # read volume "…-B"  (expect EMPTY   → isolates)

If readsame sees the marker AND readdiff does not, name-based isolation is CONFIRMED (the ADR-0008 §3 claim holds locally); the remaining cross-Project concern is then purely the controller’s allocation of distinct names (a control-plane guarantee). LLM-free. (cbb8/d8f0-style spike; to be refactored into workflows/ later — ADR-0010 Consequences.)

Return Type
String !
Arguments
NameTypeDefault ValueDescription
modeString !-

which leg of the test to run: write | readsame | readdiff

Example
dagger -m github.com/denkhaus/dagmar@ef831774e5eff33b9012d4cc7ac9570ec2bc605d call \
 probe-cache --mode string
func (m *MyModule) Example(ctx context.Context, mode string) string  {
	return dag.
			Dagmar().
			Probecache(ctx, mode)
}
@function
async def example(mode: str) -> str:
	return await (
		dag.dagmar()
		.probecache(mode)
	)
@func()
async example(mode: string): Promise<string> {
	return dag
		.dagmar()
		.probeCache(mode)
}

probeNet() 🔗

ProbeNet is the dagmar-911b trust-zone spike: it empirically tests whether a Dagger container exec has outbound network access by default. Dagger v0.21.8 exposes NO per-exec no-network option (ContainerWithExecOpts has no network/egress field). This establishes the residual-risk fact that ADR-0011 consciously accepts: tool-set exclusion is NOT a hard network guarantee (a raw exec path can still reach the network). LLM-free. (cbb8-style spike; to be refactored into workflows/ later — ADR-0010 Consequences.)

Return Type
String !
Example
dagger -m github.com/denkhaus/dagmar@ef831774e5eff33b9012d4cc7ac9570ec2bc605d call \
 probe-net
func (m *MyModule) Example(ctx context.Context) string  {
	return dag.
			Dagmar().
			Probenet(ctx)
}
@function
async def example() -> str:
	return await (
		dag.dagmar()
		.probenet()
	)
@func()
async example(): Promise<string> {
	return dag
		.dagmar()
		.probeNet()
}

sandbox() 🔗

Sandbox realizes an isolated, credentialed execution slot (a Dagger Container — Tier A, used directly; ADR-0010 §3). This is the v0 vertical proving the layout seams (functional core -> app Tier-A-direct -> main delegation -> a chainable custom return object) without an LLM call. Delegates to app.BuildSandbox.

NOTE: the args are primitives (not a domain.SandboxSpec) because Dagger cannot code-generate for a foreign (non-main-package) input type. The pure domain.SandboxSpec is constructed at this seam from the primitives; domain stays Dagger-free and unit-tested (ADR-0010 §3).

Return Type
Sandbox !
Arguments
NameTypeDefault ValueDescription
imageString !-

Base OCI image for the Sandbox container.

workingDirString -

Working directory inside the Sandbox (empty = image default). Named workingDir, not workdir, to avoid a CLI flag collision with *dagger.Container’s own workdir field.

Example
dagger -m github.com/denkhaus/dagmar@ef831774e5eff33b9012d4cc7ac9570ec2bc605d call \
 sandbox --image string
func (m *MyModule) Example(image string) *dagger.DagmarSandbox  {
	return dag.
			Dagmar().
			Sandbox(image)
}
@function
def example(image: str) -> dagger.DagmarSandbox:
	return (
		dag.dagmar()
		.sandbox(image)
	)
@func()
example(image: string): DagmarSandbox {
	return dag
		.dagmar()
		.sandbox(image)
}

up() 🔗

Up brings up an isolated k3s cluster inside Dagger and proves the API is reachable.

First checkpoint of the cbb8 spike: validates that k3s-in-Dagger works on this host (nested privileges / cgroup v2) before we deploy the Dagger engine DaemonSet into it.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
clusterString "dagmar-spike"

name of the throwaway k3s cluster

Example
dagger -m github.com/denkhaus/dagmar@ef831774e5eff33b9012d4cc7ac9570ec2bc605d call \
 up
func (m *MyModule) Example(ctx context.Context) string  {
	return dag.
			Dagmar().
			Up(ctx)
}
@function
async def example() -> str:
	return await (
		dag.dagmar()
		.up()
	)
@func()
async example(): Promise<string> {
	return dag
		.dagmar()
		.up()
}

Sandbox 🔗

Sandbox is the Dagger object returned by Dagmar.Sandbox — a thin, chainable wrapper over the realized Container. Exported methods on it become callable Dagger functions.

container() 🔗

Container returns the underlying Dagger Container (Tier A).

Return Type
Container !
Example
dagger -m github.com/denkhaus/dagmar@ef831774e5eff33b9012d4cc7ac9570ec2bc605d call \
 sandbox --image string \
 container
func (m *MyModule) Example(image string) *dagger.Container  {
	return dag.
			Dagmar().
			Sandbox(image).
			Container()
}
@function
def example(image: str) -> dagger.Container:
	return (
		dag.dagmar()
		.sandbox(image)
		.container()
	)
@func()
example(image: string): Container {
	return dag
		.dagmar()
		.sandbox(image)
		.container()
}