Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e1149ba
WIP Phase A: bind release revision at gunbc serve startup, publish vi…
Aug 6, 2026
6482fbf
Phase A: /healthz publishes the launch revision, proven end-to-end by…
Aug 6, 2026
25b8ba0
Phase A: supply the candidate at the launcher, compare it at readiness
Aug 6, 2026
ce3c7f6
Phase A: fix two typecheck defects the resolve found
Aug 6, 2026
02e162d
Retract two claims this branch made that its code does not support
Aug 6, 2026
7f2dd0b
Phase A: split the candidate out of the slot topology
Aug 6, 2026
42ac984
Phase A: fix the arity the resolver found, in the one place grep coul…
Aug 6, 2026
45e6e2a
Phase A: fix two typecheck defects, both of which wanted a better sha…
Aug 6, 2026
2ee235c
Phase A: fix the two defects the compiler was actually reporting
Aug 6, 2026
5075e6f
Phase A: build the Optional with none, not a bare Absent
Aug 6, 2026
6ebdc4c
Phase A: delete the dead deploy-script artifacts and the arm that cou…
Aug 7, 2026
f196fa3
Merge remote-tracking branch 'origin/main' into session/still-hawk-63…
Aug 7, 2026
d6b1410
chore: regenerate drifted generated artifacts (ci auto-heal)
Aug 7, 2026
ac07594
Phase A step 4-5: repair the witness closure and split the fused surf…
Aug 7, 2026
a78d2bc
Merge remote-tracking branch 'origin/session/still-hawk-637-phase-a' …
Aug 7, 2026
e5acca5
Phase A: regenerate ci.yml after the artifact deletion
Aug 7, 2026
fe30053
Phase A: close the witness call sites the release parameter left behind
Aug 7, 2026
1e62438
Candidate admission: refuse a deploy whose bytes HEAD does not name
Aug 7, 2026
b2c377d
Name the not-an-object cause for the document, not for one member
Aug 7, 2026
39a22a3
Merge main: #7984 unblocked the tree, so this branch's CI can run clean
Aug 7, 2026
24bc1eb
Move the WorkingTreeStatus annotation to module-item grain
Aug 7, 2026
c4fe948
Sweep the body-grain annotation class instead of one more site
Aug 7, 2026
37534fd
Execute the live launch-A / disk-becomes-B control, and record what i…
Aug 7, 2026
c93e035
Phase A: repair the four discovery-corpus reds batch 2 had been hiding
Aug 7, 2026
094c44b
Phase A: admit ignored deployed files, which the status probe never r…
Aug 7, 2026
9eb5897
Phase A: record the ignored-axis wet receipt beside its unit controls
Aug 7, 2026
401cd1f
Merge origin/main into session/still-hawk-637-phase-a
Aug 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
.githooks/generated-artifact-merge merge=generated-artifact
.githooks/pre-commit merge=generated-artifact
.githooks/pre-push merge=generated-artifact
.github/live-deploy-srv1-apply.sh merge=generated-artifact
.github/live-deploy-srv1-retract.sh merge=generated-artifact
.github/workflows/ci.yml merge=generated-artifact
.github/workflows/falsifier.yml merge=generated-artifact
.gitignore merge=generated-artifact
Expand Down
99 changes: 0 additions & 99 deletions .github/live-deploy-srv1-apply.sh

This file was deleted.

37 changes: 0 additions & 37 deletions .github/live-deploy-srv1-retract.sh

This file was deleted.

4 changes: 1 addition & 3 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

60 changes: 60 additions & 0 deletions dag/extdeps/git/inspect.dag
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,30 @@ data extdeps_external_authority_anchor: ExternalAuthority = ExternalAuthority {

data git_inspect_service_note: String = "Read-only repository-root, revision, and tree inspection operations are de-fused from the broad git.Core service so consumers pay only the upstream facts they inspect. Toplevel, HeadCommit, and ShowTree move here with their existing shapes; MergeBase and ListTreePathsAtRevision extend this same inspection authority for revision-addressed Rust-source observation. No second Git inspection surface remains in extdeps.git."

// WorkingTreeStatus pins every flag Git's own manual says a script must pin. `--porcelain=v1` because the
// manual states plain `--porcelain` may change and that a version should be given for scripting, so the
// version is named rather than implied. `-z` because paths may contain spaces, quotes, or newlines and the
// non-NUL form C-quotes them, which would make every consumer reimplement Git's quoting rules to recover a
// filename. `--untracked-files=all` because the default `normal` collapses an untracked directory to the
// directory name alone, and a consumer asking "does this tree contain files HEAD does not name" needs the
// files, not a folded ancestor.
//
// The mock answers a CLEAN tree because the runner contract hands each job a fresh checkout; a mocked
// observation must report the state the contract guarantees rather than fabricate a dirty one.
//
// IgnoredFiles is a SECOND operation rather than an `--ignored=matching` flag on the first, and the reason is
// measured, not stylistic. `git status --porcelain=v1 -z --untracked-files=all --ignored=matching` reports a
// directory that itself matches an ignore pattern as one folded entry — `!! ign/` — and never names the file
// inside it. That is the same folded-ancestor loss `--untracked-files=all` exists to avoid, and it is fatal
// here specifically, because a consumer asking "which ignored files would the source sync copy" must filter
// each path against the deployed-scope authority and must name the offending path in its refusal; a folded
// directory can do neither. `git ls-files --others --ignored --exclude-standard -z` answers with real file
// paths (`ign/f.dag`), which is the granularity the question needs. Verified by execution against git 2.43.0
// on a constructed repository, both spellings side by side.
//
// `--exclude-standard` is pinned because without it the command applies no ignore rules at all and would
// return every untracked path — the opposite of the question. The output is a bare NUL-separated path list,
// so unlike porcelain v1 it carries no status codes and no rename-source continuation to track.
service git.Inspect {
operation Toplevel {
input {}
Expand Down Expand Up @@ -42,6 +66,42 @@ service git.Inspect {
}
}

operation WorkingTreeStatus {
input {}
output {
entries_nul: String from "stdout"
success: Bool from "exit_success"
stderr: String from "stderr"
}
readonly
transport shell { argv: ["git", "status", "--porcelain=v1", "-z", "--untracked-files=all"] }
exit {
0 => Unit
128 => String "Not a git repository"
}
mock_response {
0 => { entries_nul: "", success: true, stderr: "" } "hermetic checkout is clean: the runner contract hands the job a fresh checkout, so the empty entry list is the state a mocked observation must report rather than a fabricated dirty one"
}
}

operation IgnoredFiles {
input {}
output {
paths_nul: String from "stdout"
success: Bool from "exit_success"
stderr: String from "stderr"
}
readonly
transport shell { argv: ["git", "ls-files", "--others", "--ignored", "--exclude-standard", "-z"] }
exit {
0 => Unit
128 => String "Not a git repository"
}
mock_response {
0 => { paths_nul: "", success: true, stderr: "" } "hermetic checkout carries no ignored files: the runner contract hands the job a fresh checkout, so the empty path list is the state a mocked observation must report rather than a fabricated one"
}
}

operation MergeBase {
input { left: GitRef, right: GitRef }
output {
Expand Down
16 changes: 16 additions & 0 deletions dag/extdeps/git/mock_corpus.dag
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@ data git_inspect_mock_case_merge_base: PublishedMockCase = PublishedMockCase {
case_id: 0
}

data git_inspect_mock_case_working_tree_status: PublishedMockCase = PublishedMockCase {
operation_key: "git.Inspect.WorkingTreeStatus",
service: "git.Inspect",
operation: "WorkingTreeStatus",
case_id: 0
}

data git_inspect_mock_case_ignored_files: PublishedMockCase = PublishedMockCase {
operation_key: "git.Inspect.IgnoredFiles",
service: "git.Inspect",
operation: "IgnoredFiles",
case_id: 0
}

data git_inspect_mock_case_list_tree_paths_at_revision: PublishedMockCase = PublishedMockCase {
operation_key: "git.Inspect.ListTreePathsAtRevision",
service: "git.Inspect",
Expand Down Expand Up @@ -134,6 +148,8 @@ data git_published_mock_corpus: List<PublishedMockCase> = [
git_core_mock_case_remote_branches,
git_inspect_mock_case_merge_base,
git_inspect_mock_case_list_tree_paths_at_revision,
git_inspect_mock_case_working_tree_status,
git_inspect_mock_case_ignored_files,
git_core_mock_case_ls_files,
git_core_mock_case_diff,
git_core_mock_case_diff_unified0,
Expand Down
2 changes: 1 addition & 1 deletion dag/gunbc/fleet_converge_cli.dag
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ fn converge_cli_applied_knob_count(intent: HostEffectIntent, fallback: Int) -> I
Srv3BootOnceReadBackSleep => fallback
Srv3ReceiptEmit { lines: _ } => fallback
HostIdentityShortHostnameRead => fallback
LiveDeployApply { spec: _ } => fallback
LiveDeployApply { spec: _, candidate: _ } => fallback
LiveDeployRetract { spec: _ } => fallback
LiveDeployEnsureDependency { dep: _ } => fallback
LiveDeployDigestReadback { port: _ } => fallback
Expand Down
10 changes: 1 addition & 9 deletions dag/gunbc/generated_artifact.dag
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,14 @@ type GeneratedArtifact
| Stage0CratePartitionGeneratedDagArtifact
| Stage0EmitPlanGeneratedDagArtifact
| V1InterpreterDispatchGeneratedRsArtifact
| LiveDeployApplyScriptArtifact
| LiveDeployRetractScriptArtifact
| AutoinstallUserDataArtifact { spec: HostAutoinstall }
| ProxyDhcpDnsmasqArtifact { spec: InstallServerSpec }
| PlanArtifact { plan: Plan }

data generated_artifact_registry: List<GeneratedArtifact> = concat(
concat(
concat(
[CiYamlArtifact, FalsifierYamlArtifact, GitignoreArtifact, GitattributesArtifact, RoadmapArtifact, DesignArtifact, GithooksPrePushArtifact, GithooksPreCommitArtifact, GeneratedArtifactMergeDriverArtifact, RunnerDeployArtifact, Stage0CrateLayoutGeneratedDagArtifact, Stage0CrateLayoutGeneratedRsArtifact, Stage0CratePartitionGeneratedDagArtifact, Stage0EmitPlanGeneratedDagArtifact, V1InterpreterDispatchGeneratedRsArtifact, LiveDeployApplyScriptArtifact, LiveDeployRetractScriptArtifact],
[CiYamlArtifact, FalsifierYamlArtifact, GitignoreArtifact, GitattributesArtifact, RoadmapArtifact, DesignArtifact, GithooksPrePushArtifact, GithooksPreCommitArtifact, GeneratedArtifactMergeDriverArtifact, RunnerDeployArtifact, Stage0CrateLayoutGeneratedDagArtifact, Stage0CrateLayoutGeneratedRsArtifact, Stage0CratePartitionGeneratedDagArtifact, Stage0EmitPlanGeneratedDagArtifact, V1InterpreterDispatchGeneratedRsArtifact],
map(fleet_autoinstall_specs, s => AutoinstallUserDataArtifact { spec: s })
),
map(fleet_install_server_specs, s => ProxyDhcpDnsmasqArtifact { spec: s })
Expand Down Expand Up @@ -66,8 +64,6 @@ fn artifact_path(a: GeneratedArtifact) -> String {
Stage0CratePartitionGeneratedDagArtifact => "dag/gunbc/stage0_crate_partition_generated.dag"
Stage0EmitPlanGeneratedDagArtifact => "dag/gunbc/stage0_emit_plan_generated.dag"
V1InterpreterDispatchGeneratedRsArtifact => "src/v1/stage0/src/v1_interpreter_dispatch_generated.rs"
LiveDeployApplyScriptArtifact => ".github/live-deploy-srv1-apply.sh"
LiveDeployRetractScriptArtifact => ".github/live-deploy-srv1-retract.sh"
AutoinstallUserDataArtifact { spec } => concat(concat("provisioning/", spec.host), "/user-data")
ProxyDhcpDnsmasqArtifact { spec } => concat(concat("provisioning/", spec.host), "/dnsmasq.conf")
PlanArtifact { plan } => plan_path(p: plan)
Expand All @@ -92,8 +88,6 @@ fn artifact_commit_policy(a: GeneratedArtifact) -> CommitPolicy {
Stage0CratePartitionGeneratedDagArtifact => CommitRequired { consumer: GitProtocol }
Stage0EmitPlanGeneratedDagArtifact => CommitRequired { consumer: GitProtocol }
V1InterpreterDispatchGeneratedRsArtifact => CommitRequired { consumer: GitProtocol }
LiveDeployApplyScriptArtifact => CommitRequired { consumer: HostReconciler }
LiveDeployRetractScriptArtifact => CommitRequired { consumer: HostReconciler }
AutoinstallUserDataArtifact { spec: _ } => NotCommitted
ProxyDhcpDnsmasqArtifact { spec: _ } => NotCommitted
}
Expand Down Expand Up @@ -133,8 +127,6 @@ fn artifact_eq(a: GeneratedArtifact, b: GeneratedArtifact) -> Bool {
Stage0CratePartitionGeneratedDagArtifact => match b { Stage0CratePartitionGeneratedDagArtifact => true _ => false }
Stage0EmitPlanGeneratedDagArtifact => match b { Stage0EmitPlanGeneratedDagArtifact => true _ => false }
V1InterpreterDispatchGeneratedRsArtifact => match b { V1InterpreterDispatchGeneratedRsArtifact => true _ => false }
LiveDeployApplyScriptArtifact => match b { LiveDeployApplyScriptArtifact => true _ => false }
LiveDeployRetractScriptArtifact => match b { LiveDeployRetractScriptArtifact => true _ => false }
AutoinstallUserDataArtifact { spec } => match b { AutoinstallUserDataArtifact { spec: spec2 } => spec.host == spec2.host _ => false }
ProxyDhcpDnsmasqArtifact { spec } => match b { ProxyDhcpDnsmasqArtifact { spec: spec2 } => spec.host == spec2.host _ => false }
PlanArtifact { plan } => match b { PlanArtifact { plan: plan2 } => plan.slug == plan2.slug _ => false }
Expand Down
9 changes: 0 additions & 9 deletions dag/gunbc/generated_artifact_emit.dag
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import gunbc.generated_artifact {
Stage0CratePartitionGeneratedDagArtifact,
Stage0EmitPlanGeneratedDagArtifact,
V1InterpreterDispatchGeneratedRsArtifact,
LiveDeployApplyScriptArtifact, LiveDeployRetractScriptArtifact,
artifact_path
}
import gunbc.ci_yaml_emit { expected_ci_yml }
Expand Down Expand Up @@ -45,10 +44,6 @@ import gunbc.v1_interpreter_dispatch_emit {
V1InterpreterDispatchGenerated,
V1InterpreterDispatchGenerationRefused,
}
import gunbc.live_deploy.emit {
expected_live_deploy_apply_script,
expected_live_deploy_retract_script
}

type ArtifactGenerationOutcome
= ArtifactGenerated { content: String }
Expand Down Expand Up @@ -85,8 +80,6 @@ fn artifact_generate(a: GeneratedArtifact) -> ArtifactGenerationOutcome {
V1InterpreterDispatchGenerationRefused { reason } =>
ArtifactGenerationRefused { reason: reason }
}
LiveDeployApplyScriptArtifact => artifact_generated(content: expected_live_deploy_apply_script())
LiveDeployRetractScriptArtifact => artifact_generated(content: expected_live_deploy_retract_script())
AutoinstallUserDataArtifact { spec } => artifact_generated(content: autoinstall_user_data(payload: spec.payload))
ProxyDhcpDnsmasqArtifact { spec } => artifact_generated(content: install_server_dnsmasq_conf(spec: spec))
PlanArtifact { plan } => artifact_generated(content: expected_plan_md(p: plan))
Expand Down Expand Up @@ -118,8 +111,6 @@ fn artifact_extra_valid(a: GeneratedArtifact, generated: ArtifactGenerationOutco
ArtifactGenerated { content: _ } => true
ArtifactGenerationRefused { reason: _ } => false
}
LiveDeployApplyScriptArtifact => true
LiveDeployRetractScriptArtifact => true
AutoinstallUserDataArtifact { spec: _ } => true
ProxyDhcpDnsmasqArtifact { spec: _ } => true
PlanArtifact { plan: _ } => true
Expand Down
3 changes: 2 additions & 1 deletion dag/gunbc/host_effect.dag
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import extdeps.bmc.webui.nbd_proxy_serve { NbdProxyServeTransportIntent }
import gunbc.fleet_intent { ComputeHost }
import gunbc.host_converge { HostConverge }
import gunbc.live_deploy.spec { DeploymentSpec, DeploymentDependencyStep }
import gunbc.live_deploy.candidate { CandidateRelease }
import std.effects {
EffectShape,
KeySource,
Expand Down Expand Up @@ -50,7 +51,7 @@ type HostEffect =
| Srv3BootOnceReadBackSleep
| Srv3ReceiptEmit { lines: List<String> }
| HostIdentityShortHostnameRead
| LiveDeployApply { spec: DeploymentSpec }
| LiveDeployApply { spec: DeploymentSpec, candidate: CandidateRelease }
| LiveDeployRetract { spec: DeploymentSpec }
| LiveDeployEnsureDependency { dep: DeploymentDependencyStep }
| LiveDeployDigestReadback { port: Int }
Expand Down
Loading
Loading