mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-04 20:17:09 +00:00
feat(campaign): sweep seeds for one experiment cell
campaign.json lists the seeds a sweep intended to run and is written before the first run, so a host that dropped runs shows up as missing seeds rather than as a smaller sample. Seed 0 is rejected: sanderling test reads it as "derive a seed from the clock", which is why conformance/gates.sh controls nothing today. Each run contributes one runs.jsonl line carrying steps to first violation by origin step, the step that armed the failed obligation, so the survival analysis never reopens a trace. Claude-Session: https://claude.ai/code/session_01A5KmftdEJ49A9z5mF5ESrX
This commit is contained in:
1 parent
9f9a01f773
commit
028534cadc
11 files changed
+1605
No files matched your search
@@ -0,0 +1,67 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
manifestFileName = "campaign.json"
|
||||
recordsFileName = "runs.jsonl"
|
||||
seedPlaceholder = "{seed}"
|
||||
devicePlaceholder = "{device}"
|
||||
)
|
||||
|
||||
// manifest is campaign.json: what the campaign INTENDED to run, written before
|
||||
// the first run so a host that dropped runs shows up as missing seeds rather
|
||||
// than as a smaller sample.
|
||||
type manifest struct {
|
||||
Arm string `json:"arm"`
|
||||
Generator string `json:"generator"`
|
||||
Platform string `json:"platform"`
|
||||
SpecPath string `json:"spec_path"`
|
||||
BundleID string `json:"bundle_id"`
|
||||
MaxSteps int `json:"max_steps"`
|
||||
DurationMillis int64 `json:"duration_millis"`
|
||||
Seeds []int64 `json:"seeds"`
|
||||
Devices []string `json:"devices"`
|
||||
Host string `json:"host"`
|
||||
SanderlingPath string `json:"sanderling_path"`
|
||||
SanderlingVersion string `json:"sanderling_version"`
|
||||
StartedAt time.Time `json:"started_at"`
|
||||
ArgumentTemplate []string `json:"argument_template"`
|
||||
}
|
||||
|
||||
func buildManifest(configuration config, host, binaryPath, version string, startedAt time.Time) manifest {
|
||||
devices := configuration.devices
|
||||
if devices == nil {
|
||||
devices = []string{}
|
||||
}
|
||||
return manifest{
|
||||
Arm: configuration.arm,
|
||||
Generator: configuration.generator,
|
||||
Platform: configuration.platform,
|
||||
SpecPath: configuration.specPath,
|
||||
BundleID: configuration.bundleID,
|
||||
MaxSteps: configuration.maxSteps,
|
||||
DurationMillis: configuration.duration.Milliseconds(),
|
||||
Seeds: configuration.seeds,
|
||||
Devices: devices,
|
||||
Host: host,
|
||||
SanderlingPath: binaryPath,
|
||||
SanderlingVersion: version,
|
||||
StartedAt: startedAt,
|
||||
ArgumentTemplate: runArguments(configuration, seedPlaceholder, devicePlaceholder),
|
||||
}
|
||||
}
|
||||
|
||||
func writeManifest(directory string, value manifest) error {
|
||||
body, err := json.MarshalIndent(value, "", " ")
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshal manifest: %w", err)
|
||||
}
|
||||
return os.WriteFile(filepath.Join(directory, manifestFileName), append(body, '\n'), 0o644)
|
||||
}
|
||||
Reference in new issue
Block a user