Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
186 changes: 161 additions & 25 deletions dag/gunbc/fleet_converge_emit.dag
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,18 @@ import gunbc.host_converge {
dag_root_binding_path,
fleet_converge_policy,
}

data fleet_converge_protocol: LayoutProtocol = LayoutProtocol { indent_unit: "" }

type FleetConvergeEmitFrontierRow {
construct: String
site: String
import v2.std.orchestration {
PipelineStep,
Let,
Call,
ExprLit,
ExprCmdSubst
}
import v2.std.diagnostic { Accepted, Rejected }
import v2.compiler.emit_orchestration { orch_emit_step }
import v2.extdeps.languages.bash_orchestration_emit { bash_orchestration_emit_medium }

data fleet_converge_protocol: LayoutProtocol = LayoutProtocol { indent_unit: "" }

fn sh_arg(s: String) -> String {
concat(concat("\"", s), "\"")
Expand All @@ -54,6 +58,148 @@ fn sh_cmd(cmd: String, args: List<String>) -> String {
fold(args, init: cmd, f: (acc, p) => concat(concat(acc, " "), sh_arg(s: p)))
}

data fresh_standup_bootstrap_emit_refused_poison: String = "__GUNBC_ORCH_EMIT_REFUSED__ fresh-standup bootstrap intent emission was rejected by v2.compiler.emit_orchestration; this marker is not valid fleet-converge shell, so the committed .github/fleet-converge.sh drift gate goes red rather than a hand-spelled fallback masking the refusal (DESIGN §5: refuse, never widen)\n"

fn fresh_standup_bootstrap_emit_step(s: PipelineStep) -> String {
match orch_emit_step(s: s, medium: bash_orchestration_emit_medium()) {
Accepted { value: source, diagnostics: d } =>
match d {
None => source.carried
Some { diagnostics: _ } => fresh_standup_bootstrap_emit_refused_poison
}
Rejected { diagnostics: _ } => fresh_standup_bootstrap_emit_refused_poison
}
}

fn fresh_standup_dag_pin_cmdsubst_intent() -> PipelineStep {
Let {
name: "dag_pin",
value: ExprCmdSubst {
callee: "converge_read_gunbc_host_pin",
args: ["\"$checkout\""]
}
}
}

fn fresh_standup_dag_pin_cmdsubst_line() -> String {
concat(" ", fresh_standup_bootstrap_emit_step(s: fresh_standup_dag_pin_cmdsubst_intent()))
}

fn fresh_standup_dag_pin_empty_intent() -> PipelineStep {
Let { name: "dag_pin", value: ExprLit { spelling: "\"\"" } }
}

fn fresh_standup_dag_pin_else_line() -> String {
concat(
" else ",
concat(fresh_standup_bootstrap_emit_step(s: fresh_standup_dag_pin_empty_intent()), "; fi")
)
}

fn fresh_standup_effective_absent_intent() -> PipelineStep {
Let { name: "effective", value: ExprLit { spelling: "ABSENT" } }
}

fn fresh_standup_verdict_absent_intent() -> PipelineStep {
Let { name: "verdict", value: ExprLit { spelling: "absent" } }
}

fn fresh_standup_then_branch_line() -> String {
concat(
fresh_standup_bootstrap_emit_step(s: fresh_standup_effective_absent_intent()),
concat(
"; ",
fresh_standup_bootstrap_emit_step(s: fresh_standup_verdict_absent_intent())
)
)
}

fn fresh_standup_decide_verdict_call_intent() -> PipelineStep {
Call {
callee: "decide_verdict",
args: ["\"$dag_pin\"", "\"$desired_pin\""]
}
}

fn fresh_standup_effective_dag_pin_intent() -> PipelineStep {
Let { name: "effective", value: ExprLit { spelling: "\"$dag_pin\"" } }
}

fn fresh_standup_else_branch_line() -> String {
concat(
fresh_standup_bootstrap_emit_step(s: fresh_standup_decide_verdict_call_intent()),
concat(
"; ",
fresh_standup_bootstrap_emit_step(s: fresh_standup_effective_dag_pin_intent())
)
)
}

fn fresh_standup_verdict_gate_line() -> String {
concat(
" if [ -z \"$dag_pin\" ]; then ",
concat(
fresh_standup_then_branch_line(),
concat("; else ", concat(fresh_standup_else_branch_line(), "; fi"))
)
)
}

fn fresh_standup_bootstrap_arm_golden() -> String {
concat(
" # fresh_standup: restart-free apply path for greenfield hosts (srv3 exemplar).\n",
concat(
" if [ -d \"$checkout/.git\" ]; then\n",
concat(
" (cd \"$checkout\" && git fetch --prune origin >/dev/null 2>&1) || true\n",
concat(
" (cd \"$checkout\" && git checkout --detach \"$ctrl_pin\" >/dev/null 2>&1) || true\n",
concat(
" dag_pin=\"$(converge_read_gunbc_host_pin \"$checkout\")\"\n",
concat(
" else dag_pin=\"\"; fi\n",
concat(
" mkdir -p \"$7\"\n",
concat(
" if [ ! -x \"$7/${13}\" ]; then\n",
concat(
" echo \"binary pull ${11}@sha:$ctrl_pin into $7 (steady-state CAS/ghcr transport keyed by derived pin)\" >&2\n",
concat(
" if [ ! -x \"$7/${13}\" ] && [ -d \"$checkout\" ]; then\n",
concat(
" (cd \"$checkout\" && cargo build -p v1-compiler --release --bin \"${13}\" >/dev/null 2>&1) || true\n",
concat(
" if [ -x \"$checkout/target/release/${13}\" ]; then cp \"$checkout/target/release/${13}\" \"$7/${13}\" 2>/dev/null || true; fi\n",
concat(
" fi\n",
concat(
" fi\n",
concat(
" if [ -x \"$7/${13}\" ]; then export \"$6=$7\"; fi\n",
concat(
" if [ -z \"$dag_pin\" ]; then effective=ABSENT; verdict=absent; else decide_verdict \"$dag_pin\" \"$desired_pin\"; effective=\"$dag_pin\"; fi\n",
concat(
" emit_receipt \"$1\" \"$2\" \"$3\" \"$desired_pin\" \"$effective\" \"$verdict\"\n",
" record \"$verdict\""
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
}

fn converge_script_header() -> Doc {
doc_concat(parts: map([
"#!/usr/bin/env bash",
Expand Down Expand Up @@ -303,8 +449,8 @@ fn converge_script_header() -> Doc {
" if [ -d \"$checkout/.git\" ]; then",
" (cd \"$checkout\" && git fetch --prune origin >/dev/null 2>&1) || true",
" (cd \"$checkout\" && git checkout --detach \"$ctrl_pin\" >/dev/null 2>&1) || true",
" dag_pin=\"$(converge_read_gunbc_host_pin \"$checkout\")\"",
" else dag_pin=\"\"; fi",
fresh_standup_dag_pin_cmdsubst_line(),
fresh_standup_dag_pin_else_line(),
" mkdir -p \"$7\"",
" if [ ! -x \"$7/${13}\" ]; then",
" echo \"binary pull ${11}@sha:$ctrl_pin into $7 (steady-state CAS/ghcr transport keyed by derived pin)\" >&2",
Expand All @@ -314,7 +460,7 @@ fn converge_script_header() -> Doc {
" fi",
" fi",
" if [ -x \"$7/${13}\" ]; then export \"$6=$7\"; fi",
" if [ -z \"$dag_pin\" ]; then effective=ABSENT; verdict=absent; else decide_verdict \"$dag_pin\" \"$desired_pin\"; effective=\"$dag_pin\"; fi",
fresh_standup_verdict_gate_line(),
" emit_receipt \"$1\" \"$2\" \"$3\" \"$desired_pin\" \"$effective\" \"$verdict\"",
" record \"$verdict\"",
"}",
Expand Down Expand Up @@ -463,21 +609,11 @@ data fleet_converge_steady_state_doc_projection_dissolution_trigger: Disposition
}
}

data fleet_converge_fresh_standup_bootstrap_emit_frontier: List<FleetConvergeEmitFrontierRow> = [
FleetConvergeEmitFrontierRow {
construct: "orch_construct_procedure",
site: "converge_gunbc_pinned_tree fresh_standup: decide_verdict/converge_read_gunbc_host_pin shell function calls"
},
FleetConvergeEmitFrontierRow {
construct: "orch_construct_cmdsubst_assign",
site: "converge_gunbc_pinned_tree fresh_standup: dag_pin=$(converge_read_gunbc_host_pin ...) cmdsubst assignment"
},
FleetConvergeEmitFrontierRow {
construct: "orch_construct_let_assign",
site: "converge_gunbc_pinned_tree fresh_standup: verdict=/effective=/export shell assignments"
data fleet_converge_fresh_standup_bootstrap_emit_dissolution_trigger: Disposition = Scaffold {
dissolves_to: RealizationDispatch,
bind: DeclarationRef {
module_path: "gunbc.fleet_converge_emit",
decl_name: "converge_script_header",
field: WholeDeclaration
}
]

fn fleet_converge_fresh_standup_bootstrap_emit_frontier_count() -> Int {
list_length(items: fleet_converge_fresh_standup_bootstrap_emit_frontier)
}
32 changes: 30 additions & 2 deletions dag/test/claim/fleet_converge_emit_test.dag
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,12 @@ import gunbc.fleet_converge_emit {
fleet_converge_sh_for,
fleet_converge_drifted,
fleet_converge_steady_state_doc_projection_dissolution_trigger,
fleet_converge_fresh_standup_bootstrap_emit_frontier_count,
fleet_converge_fresh_standup_bootstrap_emit_dissolution_trigger,
fresh_standup_bootstrap_emit_refused_poison,
fresh_standup_bootstrap_arm_golden,
fresh_standup_dag_pin_cmdsubst_line,
fresh_standup_dag_pin_else_line,
fresh_standup_verdict_gate_line,
}
import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly }

Expand Down Expand Up @@ -312,6 +317,27 @@ fn witness_sessions_membership_line_emitted() -> Bool {
&& has(s: sh, p: "ls -d \"$2\"/docker-*.scope 2>/dev/null | wc -l | tr -d ' ' || true")
}

fn witness_fresh_standup_bootstrap_emit_bytes_hold() -> Bool {
let sh = expected_fleet_converge_sh()
has(s: sh, p: fresh_standup_bootstrap_arm_golden())
&& has(s: sh, p: fresh_standup_dag_pin_cmdsubst_line())
&& has(s: sh, p: fresh_standup_dag_pin_else_line())
&& has(s: sh, p: fresh_standup_verdict_gate_line())
&& !has(s: sh, p: fresh_standup_bootstrap_emit_refused_poison)
}

fn witness_fresh_standup_bootstrap_arm_perturb_red() -> Bool {
!has(s: expected_fleet_converge_sh(), p: concat(fresh_standup_bootstrap_arm_golden(), "x"))
&& !has(s: expected_fleet_converge_sh(), p: concat(fresh_standup_dag_pin_cmdsubst_line(), "x"))
}

fn witness_fresh_standup_bootstrap_emit_dissolution_scaffold() -> Bool {
match fleet_converge_fresh_standup_bootstrap_emit_dissolution_trigger {
Scaffold { dissolves_to: _, bind: _ } => true
Terminal { reason: _ } => false
}
}

test fn fleet_converge_emit_holds() -> Bool {
witness_live_converge_is_conservation_sound()
&& witness_drift_red_receipt()
Expand All @@ -329,7 +355,9 @@ test fn fleet_converge_emit_holds() -> Bool {
&& witness_gunbc_apply_mode_srv3_fresh_standup()
&& witness_gunbc_pinned_tree_runs_first()
&& witness_sessions_membership_line_emitted()
&& fleet_converge_fresh_standup_bootstrap_emit_frontier_count() == 3
&& witness_fresh_standup_bootstrap_emit_bytes_hold()
&& witness_fresh_standup_bootstrap_arm_perturb_red()
&& witness_fresh_standup_bootstrap_emit_dissolution_scaffold()
&& match fleet_converge_steady_state_doc_projection_dissolution_trigger {
Scaffold { dissolves_to: _, bind: _ } => true
Terminal { reason: _ } => false
Expand Down
34 changes: 1 addition & 33 deletions src/v2/compiler/05_emit_orchestration.dag
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ import v2.std.orchestration_emit {
orch_construct_procedure,
orch_construct_call,
orch_construct_cmdsubst_assign,
orch_construct_let_assign,
orch_construct_arith
orch_construct_let_assign
}
import v2.extdeps.languages.bash {
bash_stmt_negation_emitted,
Expand Down Expand Up @@ -57,10 +56,7 @@ import v2.std.orchestration {
Expr,
ExprLit,
ExprVarRef,
ExprArith,
ExprCmdSubst,
ArithAdd,
ArithSub,
EscalationLevel,
Predicate,
ExitZero,
Expand Down Expand Up @@ -352,34 +348,6 @@ fn orch_emit_expr_spelling(e: Expr, medium: OrchestrationEmitMedium) -> Outcome<
match e {
ExprLit { spelling: s } => outcome_accepted(s)
ExprVarRef { name: n } => outcome_accepted(concat("$", n))
ExprArith { op: op, lhs: lhs, rhs: rhs } =>
bind_outcome(
o: orch_emit_expr_spelling(e: lhs, medium: medium),
f: fn(lhs_spelling) {
bind_outcome(
o: orch_emit_expr_spelling(e: rhs, medium: medium),
f: fn(rhs_spelling) {
bind_outcome(
o: match op {
ArithAdd =>
orch_emit_from_registry(
medium: medium,
construct_tag: orch_construct_arith,
target: medium.realize_arith(lhs_spelling, "+", rhs_spelling)
)
ArithSub =>
orch_emit_from_registry(
medium: medium,
construct_tag: orch_construct_arith,
target: medium.realize_arith(lhs_spelling, "-", rhs_spelling)
)
},
f: fn(m) { outcome_accepted(m.carried) }
)
}
)
}
)
ExprCmdSubst { callee: c, args: args } =>
outcome_accepted(orch_emit_cmdsubst_word_spelling(callee: c, args: args))
}
Expand Down
6 changes: 0 additions & 6 deletions src/v2/extdeps/languages/bash_orch_tier2.dag
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,3 @@ fn orch_cmdsubst_assign_target_model(name: String, body: String) -> TargetModel
fn orch_let_assign_target_model(name: String, value: String) -> TargetModel {
bash_stmt_assign_target_model(name: name, value: value)
}

fn orch_arith_target_model(lhs: String, op: String, rhs: String) -> TargetModel {
let inner = concat(lhs, concat(" ", concat(op, concat(" ", rhs))))
let arith_spelling = concat("$((", concat(inner, "))"))
bash_orch_call_target_model(spelling: arith_spelling)
}
13 changes: 3 additions & 10 deletions src/v2/extdeps/languages/bash_orchestration_emit.dag
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ import v2.extdeps.languages.bash_orch_tier2 {
orch_procedure_target_model,
orch_call_target_model,
orch_cmdsubst_assign_target_model,
orch_let_assign_target_model,
orch_arith_target_model
orch_let_assign_target_model
}
import v2.extdeps.languages.bash_command_fold { bash_fold_raw_line_target_model }
import std.algebra { FreeMonoid }
Expand Down Expand Up @@ -55,8 +54,7 @@ import v2.std.orchestration_emit {
orch_construct_procedure,
orch_construct_call,
orch_construct_cmdsubst_assign,
orch_construct_let_assign,
orch_construct_arith
orch_construct_let_assign
}
import v2.std.text { String }

Expand Down Expand Up @@ -107,10 +105,6 @@ fn bash_orchestration_emit_registry_node() -> Node {
bash_named_edge(
name: orch_construct_let_assign,
target: bash_stmt_assign_emitted
),
bash_named_edge(
name: orch_construct_arith,
target: bash_orch_call_emitted
)
],
occurrence_id: SyntheticOccurrence
Expand Down Expand Up @@ -190,7 +184,6 @@ fn bash_orchestration_emit_medium() -> OrchestrationEmitMedium {
realize_procedure: orch_procedure_target_model,
realize_call: orch_call_target_model,
realize_cmdsubst_assign: orch_cmdsubst_assign_target_model,
realize_let_assign: orch_let_assign_target_model,
realize_arith: orch_arith_target_model
realize_let_assign: orch_let_assign_target_model
}
}
3 changes: 0 additions & 3 deletions src/v2/std/orchestration.dag
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,9 @@ type EscalationLevel {

type FailurePolicy = FailFast | Continue

type ArithOp = ArithAdd | ArithSub

type Expr
= ExprLit { spelling: String }
| ExprVarRef { name: String }
| ExprArith { op: ArithOp, lhs: Expr, rhs: Expr }
| ExprCmdSubst { callee: String, args: List<String> }

type Procedure {
Expand Down
Loading
Loading