For Agents
Living index of themes for the Alpiq BESS / Mando project. Each H2 is a topic; bullets are wikilinks to related notes. Updated by
obsidian-documenterwhen documenting work. Read byhistorianat bootstrap. Topics kept alphabetical.
Arrow Flight / Deployment
- be-1595-arrow-flight-dev-deploy-runbook-2026-06-24 — Dev deploy runbook (recurring facts). Three artifacts move together (mando image + py-mando wheel + optimization/forecast consumer images; same build on a wire change). Migration drift → mando crash-loop (
V…__… is missing from the filesystem), fix by merging develop so branch migrations ⊇ DB’s. IaC =optimization-universe-iac.worktrees/mando-arrowterraformterraform.auto.tfvars.json(mando/optimization-algo/forecast-algo image pins).terraform_apply:devalways red on a pre-existing customer-portal S3 403 HeadObject despiteApply complete!(harmless, not ours). Runtime switchMANDO_FETCH_STRATEGY=flight+MANDO_FLIGHT_HOST/PORTon algo task defs. Verify in Datadog EUenv:dev:bess-os-service-mando/bess-os-algo-optimization/bess-os-algo-forecast. - be-1595-flight-rest-graceful-degradation-2026-06-24 — F4 capability-gap fallback. Flight/DuckDB passthrough only streams within its cache window; a range predating the cache (Permanent storage) returns
RepoError::MethodNotSupported(repo_passthrough.rs:335). Was mapped to gRPCFailedPrecondition+ client only fell back onis_retryable()→ propagatedFatal, crashed forecast. Fix (commit7926278c): mapMethodNotSupported→ gRPCUnimplemented(mando-bess/src/flight.rs repo_error_to_status) +ClientError::is_unimplemented()(mandarrow-client/src/error.rs); client falls back onis_retryable() || is_unimplemented()(py-mando/src/polars.rs). KEEPCyclicDependencyasFailedPrecondition(real error). Net: optimization fully on Flight, forecast logsfalling back to RESTthen completes. Resolves the “Known limit” in be-1595-flight-execution-id-parity-2026-06-17. - be-1595-flight-wire-type-version-skew-2026-06-24 — #1 deploy hazard: wheel ↔ server skew. Wheel (mandarrow-client Flight wire types + bess client
send(update_id=...)) and server deploy independently; a develop merge bumped sharedDataPointUpdateInfo(fetch_time→update_time, addedupdate_id) → old-wheel↔new-server broke. Fix (commit73cbdcf3): tolerant wire types —#[serde(default)]on every optional/added field,#[serde(alias="old")]on renames, NEVER#[serde(deny_unknown_fields)]on boundary structs, + compat tests. Can’t retroactively fix released versions (deploy mando + wheel from the same build on wire changes); send-side signature mismatch only resolves by rebuilding consumers on the matching wheel. - be-1595-arrow-consumer-lock-script-2026-06-24 — Consumer wheel-lock script (
deploy-arrow-consumers.ps1/ base64iexone-liner). Windows on corp net, Nexus must resolve. Clone via token URL (https://oauth2:$Token@…) +GIT_TERMINAL_PROMPT=0/GCM_INTERACTIVE=Neverto stop the GitLab credential popup hanging. The base64 one-liner is a frozen snapshot → a stale clipboard silently re-locks the WRONG wheel; re-copy fresh + verify the echoed wheel. Dev images gated behind thepython-docker-publishcomponent (Publish Docker Devonly on develop/rc) → script appends a local rules-override forfeature/*. - be-1595-flight-execution-id-parity-2026-06-17 — Brings the Flight streaming path to parity with REST for execution-bound manual overrides; fixes the dev regression where
MANDO_FETCH_STRATEGY=flighthard-broke the optimization/forecast algo runners (they always fetch withexecution_id). Sharedmando_lib::app::execution_override::apply_execution_overrideshelper (DRY across RESTget_data+ Flightdo_get);execution_id: Option<Uuid>added to bothQueryTicket+FlightTicket(#[serde(default)]); overrides injected intoDataPointFilters at the HANDLER layer beforeretrieve_stream(no trait change);MandoFlightServicegained anArc<FlowRepository>; client guard relaxed to error only onaccess_token(headers + access_token-fallback deferred). Deploy needs mando image + wheel + consumer images. - be-1595-enabling-arrow-flight-consumers-2026-06-16 — How to turn ON the Flight client path in BESS consumers. Runtime switch: py-mando env
MANDO_FETCH_STRATEGY(defaultrest; Flight only when ==flight;flight.rs:16, read per-fetchpolars.rs:224-236) +MANDO_FLIGHT_HOST/PORT/PROTOCOL. Dev wheel ships-F flightso it’s a pure env flip, no rebuild. Gotcha: Flight-fetch error → SILENT REST fallback (polars.rs:234); confirm via logs/metrics. Per-service topology: algo-optimization + algo-forecast share the bess-os ECS task (bess_os_ecs.tf, localhost) → add 3 env vars (done onfeature/mando-arrow,d3db63e); trader-dashboard is a separate task (trader_dashboard_ecs.tf, overlocal.mando_domain) with no network path to the gRPC port → needs NLB/ALB-HTTP2 plumbing, left on REST. Server side:var.mando_flight_port(50051) exposed via port mapping + SG rule. - Arrow Flight Streaming Design — Flight streaming server/client design.
- Arrow Flight Gap Analysis 2026-04-30 — gap analysis.
- be-1595-publish-docker-dev-feature-branch-test-need-2026-06-16 — CI gotcha enabling dev-image builds on
feature/*for the Flight consumer repos.
BESS AM / Real-time Telemetry
- BESS AM (BE-2262) - mando-bess-am — BESS Asset Management (ticket BE-2262, in flight, authored by Gergely Vászon). Headless Kinesis stream processor (new crate
mando-bess-am) for per-second WAGO battery telemetry (real-time SoC/SoH) on the FI/Valkeakoski/Beskar asset. PipelineWAGO Box → AWS IoT Core → Kinesis (bess-am-events) → mando-bess-am → Kinesis (bess-os-events) → mando-bess: consumes raw per-second events, persists to Postgres schemabess_am, computes 1-min aggregates (Mean/Max/Min/Last/StdDev/Count/Sum) via windowing + grace-period closure, forwards tobess-os-events. Introduces a NEWEvent-typed data-point class distinct from the time-series flows (NOT one of Trading/Manual Schedule/Auction/Intraday/Data Update/AFRR). Kinesis adapter atmando-lib/src/adapter/kinesis/; Event modelmando-core/src/model/{event,wago}.rs; Event datapoints inbattery_online.yaml. Builds on BE-2132 (interval/Event groundwork), depends on BE-2341 (generic Kinesis producer, folded into the MR). Core MR !512 OPEN/requested_changes; nothing merged todevelopyet. - Dev Deploy 2026-07-14 (error telemetry) - the May feat deploy of the BE-2262 POC left
U202605131400__create_event_table+U202605141900__create_kinesis_checkpoint_tablein dev’srefinery_schema_history; the files exist only on the unmerged branches, so EVERY develop-based image crash-loops on dev at boot (MigrationError::PatchApplicationFailed). Worked around by restoring both files byte-exact (single canonical blobf45b6dd4across all source commits). OPEN ACTION: land the two files on develop (small MR, recommended) or clean dev’s history rows.
Bugs / Investigations
- be-1595-flow-repository-sqlite-bugs-2026-06-17 — Two latent
FlowRepositorySqlitebugs (local Sqlite dev/test path only, NOT Postgres prod; worth a ticket), found writing the test seed for the Flight parity work. (1)create_flow(flow_repository_sqlite.rs:111) uses lazystmt.query()for an INSERT + dropsRowswithout iterating → SQL may never run, row never persists (use.execute()/.insert()). (2)started_atschema defaultcurrent_timestampstores TEXT butget_executionreads column 2 asi64→ row created without explicit integerstarted_atfails to read back (InvalidColumnTypeTEXT vs i64). - calculated-virtual-dp-range-cutoff-bug-2026-05-18 — Calculated & Virtual DPs leak rows past
to(all 4 retrieve methods); root cause inservice_base.rs:94-159, mechanisms inconvert_resolution.rsupsampling +evaluation.rsFull-join/concat. Diagnosed, fix pending. - flow-step-log-message-dropped-2026-05-26 —
ErrorWithStepStatus::log(status, message)dropsmessageat parent log site;StepResult::log()(mod.rs:155-159) destructures with..,Displayis"status: {status}"only (mod.rs:443),status_or_errorcollapsesLogtoOk(mod.rs:231-239), top-level catch inmando-bess/.../flow.rs:289sees"status: Error"only.Error(anyhow)arm OK; only::Logbroken. Tests atmod.rs:548-605only assert log level + wrapper string. Affects all envs. Cross-check follow-up commits onfeature/BE-2272. - mando-cli-v0.4.0-compose-bugs-triage-2026-05-26 — Two confirmed compose-runtime bugs in v0.4.0:
context: .resolves torunconfig/not project root (build.yml:11,build_dev.yml:18); bare service slug passed for mocked runconfig activates malformed override stub viarender_override(templates.rs:298-325) —profiles: ["{run_tag}"]line attemplates.rs:317is a load-bearing invariant keeping mocked stubs dormant. Fixes identified, not yet committed. - mando-cli-v0.4.0-mando-bess-binary-missing-2026-06-25 — The NEXT failure after the above triage’s fixes (commit
2233959). On a fresh clone, default profilemando-mocked-algosabortsdocker compose buildatCOPY target/release/mando_bess→failed to compute cache key … not found. Design gap:mando/Dockerfileis a thin runtime image copying a PRE-built binary (no Rust stage),bess-service.yaml:23-32context_includesit (CI assumption), and the default profile mapsmando→buildrunconfig (runprofile.rs:225) while nothing inupcompiles it (--cargoisartifact-only,cli.rs:55). Workaround:mando up --mando=pull(pulls the registry image). Durable fix pending decision: flip default →pull(open risk: confirm defaultMANDO_IMAGE→ registry notmando:dev) + add anuppreflight guard for missing binary. Diagnosed, not implemented. Reported by gabi on WSL. - mando-cli-v0.4.0-piped-output-invisible-failures-2026-06-25 — Observability bug found while validating the above’s
--mando=pullworkaround. Whenupoutput is piped/redirected (2>&1 | tee log), failures are INVISIBLE: captured.mando/compose-up.logempty, only a baredocker compose up … failed (exit 1)shown. Two stacking root causes (both required): (A)docker composewrites progress+errors to/dev/tty, bypassing mando-cli’s pipe (compose.rsrun_streaming) → fix: top-level--progress plain(compose.rs~L231); (B)CliBuffer::add_log_line(opts.rs:57) usesindicatif::MultiProgress::println, a silent no-op on non-TTY, dropping all streamed output + the failure-tail replay (compose.rs:263-272) → fix:eprintln!fallback when!stderr().is_terminal(). Validated macOS: redirected run 35→138 lines, realpull access denied+ tail + log pointer now visible. Reusable: pipe-captureddocker composeneeds--progress plain/--ansi never;indicatifprintlnneedseprintln!fallback on non-TTY. Tester’s now-visible failure = registrypull access denied(needsdocker login, distinct from mando-cli’s GitLab-API auth). Both fixes built+validated, NOT committed; linux/amd64 build pending. - BESS AM (BE-2262) - mando-bess-am (Update 2026-06-24) — FIXED 2026-06-25.
mando-codegencasing bug:expand_variantsmis-casedpython_fieldfor multi-segment Named variants —Min1/Mean→market.da.price.min1.Meaninstead of all-lowercase…min1.mean(lowercased first path segment but not the value segment). Affected BESS AM 1-minute aggregate datapoint names (Min1/Mean, Min1/Max, Min1/StdDev…). Originated in the branch’s ownfeat: separate out bess-amcommit5a739baa, NOT the develop merge (mando-codegenbyte-identical before/after). Fix: lowercase the value segment atmando-codegen/src/util.rs:41→format!("{pf}.{name_lower}.{}", v.to_lowercase()); commitcc4720b2onfeature/BE-2262-bess-am-poc, pushed to MR !512. Verifiedcargo test -p mando_codegennow 51/51 (was 50/1). Residual (unrelated): two pre-existing rustfmt drifts remain in that same file (~L50, ~L390, author’s code), left untouched. (Same update also recordsorigin/developmerged into the !512 branch as80a17e78— compiles clean, 428 lib tests pass.) - Dev Deploy 2026-07-14 (error telemetry) - dev crash-loop at boot:
MigrationError::PatchApplicationFailed: migration V202605131400__create_event_table is missing from the filesystem. Root cause: dev’srefinery_schema_historycarries two migrations from the UNMERGED BE-2262 bess-am branches (May feat deploy), so refinery validation fails for any image built without those files; the INVERSE of the BE-1595 drift case, merging develop cannot fix it. Fix: byte-exact restore of both files (blobf45b6dd4, checksums pass) as6bc418cd. STANDING WARNING until develop carries the files or the rows are cleaned. - fr-region-missing-datadog-logs-2026-07-21 - FR region services silently absent from Datadog logs:
modules/bess_os/cloudwatch.tfcreates the-frlog groups but thedd-logs-forwardersubscription-filter modules were dropped at module extraction (they live only in top-levelcloudwatch.tf). Diagnosed with live AWS evidence, fix not applied. - mando-ci-lib-only-test-gate-2026-07-22 -
mando-bess/tests/flight_end_to_end.rsis compile-broken on develop itself (E0603:DataPointUpdateInfoimported viamando_lib::servicewhere it is only a privateusesince theb3ce27a8repository crate split), undetected because the CI test gate is--lib-only; fix is a pending one-liner (import frommando_core::model::datapoint), its own change on Andras’s yes. - mando-cli-full-audit-2026-07-22 — full ~18.7k-line mando-cli audit: 37 verified bugs (2 HIGH — unguarded
kill -TERM -{pid}mass-kill inhost_process.rs:108-133with nopid<=1guard; orphaned untracked host procs onrecordfailure inup.rs:262-270— 18 MEDIUM, 17 LOW). Themes: exit-0-on-failure (migrate/get/pull), no reqwest timeouts anywhere,wiremock.enable()silent no-op. Also a −280-line/−5-dep over-engineering cut list, 9 duplication clusters (compose-context prologue copy-pasted across 8 command files), and the simulator runtime spec unimplemented onmain. No fixes applied.
CI/CD
- BESS AM (BE-2262) - mando-bess-am — adds a dedicated CI job “Publish BESS-AM Docker Dev” building the
mando-bess-amimage fromcontainer.bess-am.Dockerfile(ECR tag prefixbess-am-<version>). Crate-split branchfeature/BE-2262-bess-am-poc-build-test(commit5a739baa) separates it into its own image. - be-1595-publish-docker-dev-feature-branch-test-need-2026-06-16 — GitLab gotcha: enabling
Publish Docker Devonfeature/*in the BESS Python consumer repos needsoptional: trueon the.Publish→Testdependency, or the pipeline won’t start. - be-1595-arrow-consumer-lock-script-2026-06-24 — consumer dev images gated behind the
python-docker-publishcomponent (Publish Docker Devonly on develop/rc); the wheel-lock script appends a local rules-override sofeature/*builds. Also the GitLab credential-popup hang fix (GIT_TERMINAL_PROMPT=0/GCM_INTERACTIVE=Never+ token-URL clone). - be-1595-arrow-flight-dev-deploy-runbook-2026-06-24 —
terraform_apply:devalways red on a pre-existing customer-portal S3 403 HeadObject despiteApply complete!(harmless); IaC image pins inoptimization-universe-iac.worktrees/mando-arrowterraform.auto.tfvars.json. - clippy-disallowed-macros-allow-placement-2026-06-22 — keeping clippy green across versions:
disallowed_macrosallow must be a module-root#![allow]at the macro’s definition (mando-core/src/error.rs), not at the call site (ineffective on clippy 1.95). Workspace pins1.88.0; verify clippy-clean under the pinned toolchain since the call-site/block form is version-fragile. - mando-cli-github-build-mirror — GitHub-Actions build pipeline, GitLab Package Registry publishing, parallel-release flow (init → matrix-publish → finalize).
- mando-cli-wsl-linux-build — local macOS (Apple Silicon) cross-compile of a Linux x86_64 / WSL
mandobinary;--platform linux/amd64+poc/-parent-mount gotchas. The manual counterpart to the CI mirror. - Mando AGENTS.md Master Guide — the verified mando gate set: NO
cargo fmtgate in CI (never barecargo fmt— ~64 legacy files reformat; scope to touched files); lint gatecargo clippy --release --all-features; canonical testcargo test --all-features --release -- --test-threads=1(single-threaded MANDATORY — shared in-memory DB pools). Runtime image now ca-certificates/libc6/libssl3 only (samba dropped); build image base stillrust:1.88.0-bookworm+ samba (toolchain 1.89.0 viarust-toolchain.toml). Pipeline etiquette: title-only Conventional Commits,feature/BE-xxxxbranches, py-mando publish is manual,release/*flows back to main+develop. Round 2 (2026-07-13):rustfmt.toml’s import-grouping/comment options are nightly-only + silently ignored on stable 1.89 (tip tree NOT fmt-clean — import grouping maintained by hand); CI gained a “PyMando Simulation Linux Dev” job (pytest without--nbval) + a simulator docker publish child pipeline; no MR/issue templates, no CODEOWNERS. - Mando Deployment Ceremony - the two-repo deploy ceremony (AGENTS.md section 14): mando CI only publishes images (
Publish Service Docker Dev,only:develop + rc/, tag{version}-dev.{pipeline_id}.{short_sha}, APP_VERSION+becomes-); optimization-universe-iac pins versions interraform/terraform.auto.tfvars.jsonwith ALLterraform_applyjobswhen: manual(dev/test from develop, int from release/, prod from main). Feature-branch deploy = temporaryonly:edit that MUST be reverted before the MR merges. Never deploy from mando alone. - Dev Deploy 2026-07-14 (error telemetry) - worked example of the feature-branch deploy on BOTH repos: throwaway mando branch
feature/BE-3482-dev-deploy(develop tip51d2b516+ !569 cherry-picks +only:edit + the PyMando Win Devneeds/dependenciesentry commented out; that job is absent on feature branches and a dangling need kills pipeline creation) + IaC branchfeature/error-hdl(version bump + “ci: enable dev apply from error-hdl branch” adding the branch toterraform_apply:devonly:, which normally exists ONLY on IaC develop). All CI edits temporary; strip on merge. - mando-ci-lib-only-test-gate-2026-07-22 - the CI test gate (
.gitlab/scripts/test.sh) runscargo test --all-features --release --lib -- --test-threads=1: ONLY lib unit tests are gated;*/tests/integration targets are never compiled by the pipeline and rot silently (the separate “Integration Test Linux Dev” job covers only the mando-lib archiver Postgres suite). Local gates need--libfor CI parity.--libarrived with the archiver split commit7278f36a. Companion lesson 2026-07-23 (BE-3657 phase 3): per-crate task gates (-p mando_lib) likewise miss CONSUMER crates - the final whole-branch review caught 2 tuple-syntax construction sites inmando-simulatorthat no task gate ever compiled (a Critical); workspace-widecargo clippy --release --all-features(no-p) is the only gate that catches cross-crate fallout.
Clippy / Lints
- clippy-disallowed-macros-allow-placement-2026-06-22 — clippy
disallowed_macros(mando banstracing::error!/log::error!inclippy.tomlto force logging through themando_core::error!wrapper): a per-invocation/per-block/per-fn#[allow(clippy::disallowed_macros)]at the call site is silently ineffective on a newer clippy (1.95) and is flagged “unused, applied to a macro invocation”. The lint resolves at the lexical site where the banned tokens live (the macro definition), so the only robust fix is a module-root#![allow(clippy::disallowed_macros)]in the defining file (mando-core/src/error.rs) — one allow covers all cross-crate callers. Caveat: workspace pins1.88.0; the block form ondeveloppresumably passes CI on 1.88 but is fragile across clippy versions; module-root#![allow]can’t be worse on 1.88 and is confirmed on newer clippy. General rule: for lints that fire on macro expansions,#[allow]at the call site no-ops — put#![allow]at the macro’s definition.
Conventions / Agent Guides
- Mando AGENTS.md Master Guide — master conventions doc for AI agents at
/Volumes/bandi/coding/poc/mando/AGENTS.md(untracked, deliberately never committed; synthesized 2026-07-10 from 5 parallel researchers ondevelop). 12 sections + 8 recipes: crate map/dependency direction, 10 non-negotiables, Rust style,mando_core::error!system, mando-bess API + py-mando PyO3 conventions, testing/git/CI ceremonies, verified-landmines table. Headline corrections:mando-bess/build/generated/**is generated BUT tracked in git (edit YAML/template → build → commit both, never hand-edit); NOErrorCodederive / NOmando-lib-macroon develop (worktree experiments only; parentpoc/CLAUDE.mdstale); JWTtoken_layersignature validation DISABLED (audit metadata, not authz); flow versions immutable once released. Rebuilt 2026-07-13 (round 2) against the true develop tip92bfe1c8(Jul-9, v1.16.0) via 5 re-run researchers on a.worktrees/developworktree — the stale-merge-base caveat is obsolete; localdevelopfast-forwarded + now tracksorigin/develop. Round-2 facts:FlowStepService= construction trait (type Params: ParamMeta; type Response;+ asyncfrom_config(config, &StepProviders)),manifest.yamldeployment catalog (schedule_env/semaphore_group, semaphores capacity 1), 36type_entry!registrations, error redesign partially landed (ae6d1098), py-mando-simulation split (BREAKING), second async bridge (future_into_py), rustfmt opts nightly-only/ignored, zero tests in the new crates, no MR templates/CODEOWNERS. Maintenance rule: code wins, then update the file. Rebuild process gotcha:agentops:researchersubagents can’t SendMessage — collect reports via scratchpad files or transcript extraction (~/.claude/projects/<project>/<session>.jsonl, longest assistant text). - Mando MR Review Patterns - evidence base behind the guide’s “Recurring review feedback” section: all 21 of Andras’s mando MRs (!322 through !558; 17 merged / 2 closed / 2 open) mined 2026-07-13 via read-only glab API; 108 reviewer notes (krisztian.fekete1 87 / gabor.nagy6 13 / balazs.mracsko.alpiq 7). Nine themes with source MRs: zero unrelated diff changes; delete ALL unused code before review (most repeated complaint); failures are errors never warnings (
mando_core::error!+ enum variant, no custom message strings); placement (route helpers next to routes, util inutil); completeness before review (mirror sibling configs); green pipeline + no conflicts before assigning review; rustfmt every new file; Jira ticket in sync; idioms (errors imported frommando_core, nounwrap, bind service once). Plus config direction (new config:config::Configover Envconfig) and the dictated rules: commits title-only NO scopes/descriptions (reviewer-mandated !322), commit every ~3 tasks, never em dashes anywhere, always subagent-driven development. - BE-3482 Datadog Logs and APM Conformance - source of the 2026-07-13 fmt correction:
cargo fmt -- <file>does NOT scope (field-verified, it touchedapi_docs.rswhich was never named); format single files withrustfmt --edition 2021 <file>, every form ofcargo fmtbanned. Propagated toAGENTS.mdsections 2.3, 10, 13.5 + the landmines table, Mando AGENTS Guide (mirror) resynced, fmt warnings in Mando AGENTS.md Master Guide / Agent Context amended. - BE-3482 Datadog Logs and APM Conformance - second 2026-07-13 tooling landmine: the RTK shell hook rewrites
cargo test --all-features --release -- --test-threads=1so the threads flag becomes a test-name filter (every test filtered out, exit 0 in 0.00s, signature0 passed, N filtered out; two gate runs false-green before detection). On RTK machines runrtk proxy cargo test --all-features --release -- --test-threads=1and confirm the summed passed totals are nonzero; exit 0 alone proves nothing. Adjacent pitfall:cargo test | grep | tail; echo $?reports tail’s exit, not cargo’s. Recorded inAGENTS.mdsection 10 + the landmines table; mirror resynced. - BE-3482 pymando Branch Review - third 2026-07-13 tooling landmine:
rustfmt --check --skip-childrenis UNRECOGNIZED on the pinned stable rustfmt and prints nothing (false green); check without the flag, attribute reported hunks by theDiff in <path>:headers (rustfmt followsmoddeclarations into child files), and baseline againstgit show <base>:<path>to separate pre-existing churn from branch-introduced churn. Recorded inAGENTS.mdsection 10 + the landmines table; Mando AGENTS Guide (mirror) resynced. - BE-3482 pymando Branch Review - fourth and fifth 2026-07-13 tooling landmines (from the rework session): (a) rustfmt base-file checks that COPY the file to a scratch dir are FALSE GREEN (rustfmt cannot resolve the
modchildren from the new location and reports 0 hunks), and running rustfmt on a module-declaring file WRITES INTO its child files (6 unrelated py-mando files were touched and reverted); the only sound method is checking out the base revision at its real path; (b) develop’s committedCargo.lockcan be STALE (mandarrow-client1.16.0 vs workspace 1.16.1); plaincargo buildregenerates it, so a lock hunk in a branch diff may be legitimate, not churn. Recorded inAGENTS.mdsection 10 + the landmines table; Mando AGENTS Guide (mirror) resynced.
Data Point Retrieval
- BESS AM (BE-2262) - mando-bess-am — introduces a NEW
Event-typed data-point class (real-time telemetry) alongside the existingTimeSeriesDouble/TimeSeriesDoubleMatrix/StaticData. Event datapoints (BATTERY_SOC_ONLINE/BATTERY_SOH_ONLINE) defined inmando-bess/config/parts/battery_online.yamlunderAsset/FI/Valkeakoski/Beskar/Battery/.../Online, keyed to Kinesis external IDs[bess-am-events, OnlineSOC/OnlineSOH]. Model atmando-core/src/model/event.rs; built on BE-2132 interval/Event groundwork. - calculated-virtual-dp-range-cutoff-bug-2026-05-18 —
[from, to)range not enforced for Virtual/Calculated DPs inhandle_data_point_types;EvaluationMetaData.rangeplumbed but unused by final output.
Docker Compose / Runtime
-
mando-cli-simulator-runtime-2026-05-30 — adds second compose project
mando-simas a peer to devmando; two-stack ergonomics via sharedservice_stack::select_profileresolver (single source of truth forlogs/exec/volume); env merged viafill_build_args(NOT--env-file, which hard-fails on missing.env); Python healthcheck; Gurobi license as file mount, not multiline env. (§A env contract SUPERSEDED 2026-06-02 — see mando-cli-simulator-env-contract-2026-06-02) -
mando-cli-simulator-env-contract-2026-06-02 — realigned simulator env to real images: orchestrator
SIMULATOR_DATABASE_*(replacesPOSTGRES_*), per-runnerSIMULATOR_<NAME>_HOST(replacesSIMULATOR_RUNNERSCSV), repo URL/branch/commit_hash moved orchestrator → runners. Runners read unprefixedSIMULATOR_REPO_URL/BRANCH/COMMIT_HASH(assumption — verify when image lands). Healthcheck Python →curl; Gurobi mount →GUROBI_LICenv. Schemabess_simulation→simulator. -
mando-cli-v0.4.0-compose-bugs-triage-2026-05-26 — v0.4.0 baseline compose-runtime triage;
context: .relative-path bug; load-bearingprofiles: ["{run_tag}"]invariant inrender_override. -
mando-cli-v0.4.0-mando-bess-binary-missing-2026-06-25 — next compose-build failure once the above fixes (commit
2233959) landed: defaultmando-mocked-algosresolvesmandoto thebuildrunconfig (runprofile.rs:225), butmando/Dockerfileis a thin runtime image that COPYs a pre-builttarget/release/mando_bessand theupflow never compiles it →docker compose buildaborts on a fresh clone (failed to compute cache key: "/target/release/mando_bess": not found). Workaroundmando up --mando=pull; durable fix (flip default →pull+ preflight guard) pending decision. -
mando-cli-v0.4.0-piped-output-invisible-failures-2026-06-25 — the streaming compose runner (
compose.rsrun_streaming) loses ALL output under pipe/redirect:docker composewrites progress+errors to/dev/tty(bypassing the pipe) → add top-level--progress plain(compose.rs~L231); andCliBuffer::add_log_line(opts.rs:57) routes lines throughindicatif::MultiProgress::println, a non-TTY silent no-op → fall back toeprintln!on!stderr().is_terminal(). Together they restore the captured.mando/compose-up.log, the streamed lines, and the--- last 40 log lines ---failure tail (compose.rs:263-272) for piped/CI/teeruns. Both fixes required. -
mando-cli-full-audit-2026-07-22 — 2026-07-22 audit of the compose runtime and command layer: 2 HIGH bugs in host-process signalling (
host_process.rs), MEDIUM compose/volume/down flag-drop + name-mapping bugs (down.rs,volume.rs,exec.rs/logs.rs), a 9-cluster duplication list headed by the compose-context prologue duplicated across 8 command files (→compose::prepare), and the simulator runtime spec still unimplemented onmain. -
mando-cli-datadog-local-logs-2026-07-22 —
mando up --datadogrenders an optional infra template (src/runtime/templates/infra/datadog.yml→.infra/datadog.builtin.yaml) with a local Datadog agent (container_name local-dd-agent,name:^mando-.*include filter), included existence-driven bycompose::assemble(NOT inINFRA_BUILTIN_FILES) so a flag-offupcan delete it. Compose interpolates env on EVERY verb → the template MUST use${DD_API_KEY:-}not:?(a:?hard-failsdown/logswhen the var is absent while the file exists). Extractedbuild_args::atomic_write_with_dirunifying 3 write sites. UPDATE 2026-07-23:docs/datadog-guide.md(tipc2becf1) verified end to end, every claim holds: 4 fail-fast paths, mando-only tailing, EU shipping (103 logs), teardown at both levels (flag-offup--remove-orphans+down). UPDATE 2026-07-23 (ddtags override): the embeddedddtagsenv WINS when mando emits one - Datadog JSON parsing promotes the bodyddtags(MANDO_ENVIRONMENT=local→env:local, unindexed by the org → 202-accepted lines VANISH); the “no env in ddtags” claim holds only whileMANDO_ENVIRONMENTputs none there; setMANDO_ENVIRONMENT=dev-local-<user>for ANY local mando (containerized included); the per-developer env tag is the only wall from the shared org’s REALenv:prodtelemetry under the same service name. -
mando-local-host-run-recipe-2026-07-23 - running a locally built
mando_bessas a HOST process against the mando-cli infra stack (mando up --datadog -p infra: postgres + wiremock + local-dd-agent). Env from.cargo/config.toml.example+ overrides (file is STALE, see Env / Configuration); infra pg credsbess_transactional_db/postgres/postgres @ localhost:5432;MANDO_PORT=8081(wiremock owns 8080), adapter hosts at localhost:8080 for hermetic 404s. DANGER: mando’s refinery races the mando-cli migrations container in DuckDbPostgres mode (idle-in-transaction boot wedge,move_schema_objectsblocked; recovery =pg_terminate_backend+ drop public/data/bess_os cascade + single-writer relaunch; DuckDb mode skips pg migrations but the stale container set lacks the setting table). Host processes are invisible to the local dd agent (mando-*filter): ship to Datadog via direct intake. Teardown:mando down+pkill mando_bess. UPDATE 2026-07-23 (epilogue): the first direct-intake forward VANISHED - Datadog promotes the embeddedddtagsfrom the JSON line, so mando’senv:local(fromMANDO_ENVIRONMENT=local) overrode the envelope’senv:dev-local-levanderand the org indexes noenv:local; fix = rewrite embedded ddtags before forwarding; durable = setMANDO_ENVIRONMENT=dev-local-<user>in the run env.
DuckDB
- BE-1597 DuckDB UI Exposure Research — BE-1597: exposing the DuckDB UI of running mando-bess + remote client access to its in-memory DuckDB. Root cause both prior attempts failed: the UI JS bundle hardcodes
"localhost:4213" === window.location.host ? "duckdb_ui" : "web", so any non-localhost:4213origin (path prefix, custom hostname, ALB) silently degrades — killing Attempt A (socat 4214 + ALB TG +/duckdb*listener rule; died on the 8080/healthcheck) and Attempt B (reqwest reverse proxymando-bess/src/route/duckdb_proxy.rs+<base href>/JS string-patch). Fix = SSMAWS-StartPortForwardingSessionToRemoteHostforwarding the LOCAL port 4213 → browsehttp://localhost:4213(literallocalhost, not127.0.0.1); no ALB (alreadyinternal=true); bastion hop required since ECS Exec is interactive-only. UI ext: onlyui_local_port(4213)/ui_remote_url/ui_polling_interval(284ms) settings, NO bind-address (binds::1→ socat), no auth, proxies assets from ui.duckdb.org per session (internet required), not statically linked (verifiednm -Don vendored 1.4.2.so→ only Icu/Json). Remote client → in-mem DB: only via Quack (DuckDB 1.5.3+, beta until 2.0). Includes a full 1.4.2→1.5.4 upgrade assessment (low-risk, in-memory-only sidesteps storage churn;=1.4.2pinCargo.toml:60vs the new1.MAJOR_MINOR_PATCH.xcrate scheme, 1.5.4→1.10504.0; C API additive-only; date_trunc/lambda SQL breaks clear). - BE-1597 DuckDB UI — Design — the approved decision/spec built on the research above (status: design approved, NOT implemented; owner Geri Vászon; repos mando + optimization-universe-iac). Phased: Approach 1 dev-only NOW via SSM
AWS-StartPortForwardingSessionToRemoteHostforwarding the LOCAL port 4213 →http://localhost:4213(literallocalhost, not127.0.0.1; no ALB / target group / health check //duckdb*prefix / reverse proxy / bundle patching — the bastion hop is only needed because ECS Exec is interactive-only); Approach 2 = Quack for a remote client → in-memory DB, deferred to DuckDB 2.0 (Sept 2026) since Quack is Beta in 1.5.x. Container change: addsocat+ adocker-entrypoint.shbridgingTCP4:4214 → TCP6:[::1]:4213whenDUCK_DB_UI_SERVER=true(NO Rust change; env already read atlib.rs:181/:301). Never in int/prod (proprietary MotherDuck frontend, no auth). Blocking open Q: Fargate egress to duckdb.org UNVERIFIED.
Env / Configuration
- BESS AM (BE-2262) - mando-bess-am — BESS AM service config uses env prefix
BESS_AM_*andconfig/bess-am.yaml; reads thebess-am-eventsKinesis stream and writesbess-os-events; Postgres schemabess_am. Local-dev Kinesis viadoc/kinesis-local-setup.md+ MiniStack (ministackorg/ministack). - be-1595-enabling-arrow-flight-consumers-2026-06-16 — Flight client toggled by
MANDO_FETCH_STRATEGY(defaultrest, Flight only when ==flight, case-insensitive) +MANDO_FLIGHT_HOST/PORT/PROTOCOL. Pure runtime env flip on the-F flightdev wheel; co-located consumers reach mando overlocalhost, separate tasks can’t (no network path to the gRPC port). Silent REST fallback on error. - be-1595-arrow-flight-dev-deploy-runbook-2026-06-24 — deploy-side view of the same switch:
MANDO_FETCH_STRATEGY=flight+MANDO_FLIGHT_HOST/PORTset on the algo task defs; verify in Datadog EUenv:dev(mando/optimization/forecast) — expect forecastfalling back to REST, optimization fully on Flight. - mando-cli-simulator-env-contract-2026-06-02 — three reusable patterns: (1) arbitrary extras passthrough — filter workspace
.envkeys against a managed-set const (MANAGED_SIM_ENV_KEYS), auto-inject survivors asKEY: "${KEY}", sorted alphabetically, withtracing::info!per injection; (2) sim-postgres aliasing — when two services share a default credential, route the dependent service’s native env (POSTGRES_USER) through the orchestrator’s contract (SIMULATOR_DATABASE_USERNAME) so one.envoverride controls both; (3) derive UI summary strings from the actual invocation-args function — never hardcode the verb+flags in summary text or it goes stale (pre-fix bug: literal"up -d --build --remove-orphans"in success row whileup_compose_argshad dropped--buildfor sim). - BE-1597 DuckDB UI — Design — the DuckDB-UI dev gate is
DUCK_DB_UI_SERVER(already read in mando-bess atlib.rs:181/:301; NO Rust change), set in terraform asDUCK_DB_UI_SERVER = tostring(var.environment == "dev")on the mando container and mirrored by thedocker-entrypoint.shif [ "$DUCK_DB_UI_SERVER" = "true" ]socat guard. Usevar.environment, NOTlocal.environment_group— the group collapses int+prod and dev+test, so it’s the wrong knob for a dev-only gate. - Mando MR Review Patterns - config direction from review (two reviewers, MR !556): NEW config uses
config::Config, notEnvconfig; existing envconfig adapters stay as-is (no mass migration). - Mando Deployment Ceremony - per-env mando runtime config WITHOUT rebuild:
.environment-vars:{env}blocks in optimization-universe-iac.gitlab-ci.ymlflow toTF_VAR_*(MANDO_FLOW_SCHEDULE_*crons,MANDO_FLOW_ACTIVE_VERSION,EBS_SMB_HOST,SIMULATION_MODE, CPU/memory, notification channels). Constraint:MANDO_FLOW_ACTIVE_VERSION(V1_4 in all envs) must name a setup version existing in mandoconfig/flows/manifest.yaml; bump the two together. dev runsSIMULATION_MODE=true. - fr-region-missing-datadog-logs-2026-07-21 - mando reads the
DD_SERVICEenv since commitab8cfd11onfeature/BE-3657(resolve_dd_service()+ OnceLock-cacheddd_service()inmando-lib/src/app/mod.rs, hardcodedbess-os-service-mandoas fallback also on empty string, all 6 call sites routed incl. 4 rawglobal::meterliterals); deployment-neutral on the main stack because IaCbess_os_ecs.tf:218already sets the var on the mando container, and it unblocks the FR-frsuffix. - mando-cli-json-output-agent-skill-2026-07-23 -
MANDO_OUTPUT=json(exact-match"json"only; the--jsonflag beats it) is the env knob that flips mando-cli output to terse NDJSON on stdout. Any other value / unset = human mode (byte-identical to pre-feature). - mando-local-host-run-recipe-2026-07-23 -
.cargo/config.toml.exampleis STALE (field-verified 2026-07-23):MANDO_FLOW_ACTIVE_VERSIONis DEAD, the config now wantsMANDO_SETUP_ACTIVE_VERSION(V1_4) +MANDO_SETUP_SCHEDULER_DISABLED(prefixMANDO_SETUP, config-crate style);FINGRID_API_KEYmust be NON-EMPTY (init panics via unwrap: “must contain at least one key”); the postgres cert loader reads<cwd>/certs/eu-central-1-bundle.pem, so running from a workspace root needs acertssymlink tomando-bess/certs.
Error Handling
- BE-3117 Per-Flow Error Context Store — “OEF v2”: one aggregate business
ERRORper flow run with full fidelity.ErrorRecord+FLOW_ERROR_CONTEXTtask-localVec+record_error!macro (TT-muncher, in mando-lib not mando-core) +flush_flow_errors/FlowCompletionGuard. Invariant: record exactly once per flow, gated bylogged_at_site. Hand-written redactingSerialize(drops bodies whenhttp_context.sensitive). Removes OEF v1’s dd_formatter ERROR→WARN demotion. Fixed pre-existingMarketNotFounddouble-log viamark_logged(). - BE-2272 — DD log JSON flattening to root (
flow.*,step.*,error.*siblings). - flow-step-log-message-dropped-2026-05-26 —
ErrorWithStepStatus::Log { message }payload silently dropped byStepResult::log()destructure +Displayimpl +status_or_errorcollapse. Only::Logarm broken;::Error(anyhow)correctly logs. - clippy-disallowed-macros-allow-placement-2026-06-22 — tooling gotcha behind the error-logging path: mando bans
tracing::error!/log::error!(clippy.toml) to force logging throughmando_core::error!; that wrapper’s own#![allow(clippy::disallowed_macros)]must be a module-root attribute inmando-core/src/error.rs, not at the call site (call-site/block allow is ineffective on clippy 1.95). Found during the BE-3117 error-handling redesign. - Mando AGENTS.md Master Guide — correction: NO
ErrorCodederive and NOmando-lib-macrocrate ondevelop(verifiedgit grep ErrorCode origin/developempty) — worktree experiments only (poc-error-extractor, BE-2023, BE-1595/BE-3482); mando-lib-macro marked outdated.error.kind(fully-qualified path) /error.code(Enum::Variant) /error.sourceare extracted at runtime bymando_core::error!from the Debug repr, no derive. Canonical pattern: every component defines athiserrorenum…Error;anyhowonly in init/flow-step glue; HTTP mapping via deterministicmap_*_error_to_response(same variant ⇒ same status); py-mando maps everything to the singlePyMandoErrorviamap_*_errorfns (mando-lib/src/python/error.rs).doc/errors.json= untracked generated catalog (generator not in CI — likely poc-error-extractor worktree). Direction of travel: log-once-at-step-boundary (docs/error-handling-redesign-plan.md). Round 2 (2026-07-13): the redesign PARTIALLY landed in commitae6d1098—error.message= root cause,error.stack= source chain,error.fingerprint={code}|{step_path},ErrorWithStepStatus.logged_at_sitedouble-log guard withnew()/logged()constructors; NOT landed:error.trace,.step_context(); the plan doc +doc/errors.jsonremain untracked on develop. - Mando MR Review Patterns - review-mandated error policy (15+ “should be error” comments + policy statement from balazs, MR !481): failures are ERRORS, never warnings; log via
mando_core::error!with an error-code enum variant;Fatalfails the execution; NO custom error message strings (the error’sto_string()IS the message, human context goes in themessagefield). - BE-3657 error_stack Adoption - LOCKED decision (2026-07-16, planned/awaiting go): full
error_stack=0.8.0adoption over the ErrorCode-derive direction. Principle “leave what we can to error_stack”: mando adds only theErrorCodefull-path attachment (captured statically inCodedExtatchange_context/newsites) + extraction fns + anerror!(report=...)arm. Field contract:error.code==kind==type==outermost full-path code;error.errors= codes array;error.details=[{code,file,line,message}]; fingerprint full-path. Crate’s own tree rendering with codes as attachment sub-lines. Boundary message template"{outermost}: {static}: {chain}". Phase-2 direction: per-variant#[error_meta(event_type, resolution step, business_message, description)]→ details enrichment + resolution-doc codegen (phase 1 must not preclude; attachments are open-ended). Branchfeature/BE-3657not yet created, off BE-3656 heada0735ebb; spec/plan underdocs/superpowers/{specs,plans}/2026-07-15-*error-stack*. UPDATE 2026-07-22: phases 1+2 BUILT + PUSHED @2baea68a(13 commits atop the rebased BE-3656 head8f50ef2a); boundary template FLIPPED static-first"{static}: {outermost}[: {chain}]"(2026-07-16); MR only after !578 merges + explicit yes, thenrebase --onto develop; standalonecargo build -p mando_corebroken by a pre-existing BE-3643 uuid/serde issue (workspace graph fine). UPDATE 2026-07-22 afternoon: !578 MERGED (merge4a0d297f= develop tip); rebased onto it zero-conflict (2baea68a→22ccae93, patch-id byte-identical, pipeline2696324182green) + DD_SERVICE env fix appended (ab8cfd11, branch now 14 commits); MR pending ONLY on Andras’s yes. UPDATE 2026-07-22 evening: phases 1+2 ride MR !580; phase 3 PLANNED + approved: scope “plumbing + adapters” (rejected: plumbing-only, full workspace breadth), mechanics = seam replication per the Volue pilot (rejected: native Report signatures, boundary-only wrapping), same ticket (branchfeature/BE-3657-phase3off develop AFTER !580 merges, one phase = one MR); conformance-tightened against Balazs’slogs-and-apm.md(line 157 absolute: ALL tuple/transparent variants restructured;error.details.attributesvia new mando-coreErrorAttrlanding before any adapter; line 159 http roll-up = outermost-winsHttpContextpick,with_reportfillshttp_contextwhen unset; auth providers: no bodies/tokens, method/url/status only); adapter order auth providers → volue/ems completion → volue/atp → alpiq/ebs (SMB, share/path ErrorAttr) → mdr/opl/data_platform/et_3000 → fingrid → metis → mando group → position_manager; vetoable defaults: archiver deferred to the repos phase, startup mock ported to mainline behindMANDO_DEBUG_MOCK_ERRORdefault-off; spec/plandocs/superpowers/{specs,plans}/2026-07-22-*phase3*(15 tasks); execution NOT started, gated on !580. UPDATE 2026-07-23: !580 MERGED (squashde7cd4c6, merge4c3442df, zero review comments); phase 3 EXECUTED subagent-driven onfeature/BE-3657-phase3(14 tasks + final whole-branch review; 20 commits, HEADe0184bc3, pushed + ls-remote verified, CI running, NO MR yet): mando-coreErrorAttr+ per-levelerror.detailsattributes +error_attr_value+report_first_attachment+with_reporthttp roll-up; ALL in-scope adapter groups migrated (*_reportedseams, exhaustive no-wildcard*_error_from_report, zeroerror(transparent)left inmando-lib/src/adapterincl. archiver); auth providers first (no bodies/tokens, sentinel leak tests); PyO3map_report_errorforward plumbing (grep-proven unreachable this phase); sharederror_json_field_valueacross all three log formatters;MANDO_DEBUG_MOCK_ERRORenv-gated report-backed mock. KEY FINDING (formal spec exception): onlyvolue/emscarries Reports to the step boundary in production (Error = Report<VolueEmsError>); the other seven groups are WALLED (flat-typed service towers +pub(crate)seams make cross-crate wiring structurally impossible), chains flatten at legacy wrappers until a services-phase tower restructure - every wall independently verified genuine. Gates ate0184bc3: workspace clippy 0, 574 lib tests / 0 failed, no lock churn, 61 files +4390/-1482 vs develop; follow-up bundle triaged (auth-provider pre-existing body logs, ErrorAttr ids on non-success terminals only, py delegation tests CI-only, data_platform test panic-safety, oplclear_strategiesportfolio attr,map_errclosure-form drift). develop since moved (6fae64a5); pre-MR rebase possible on go. UPDATE 2026-07-23 (local e2e): phase 3 telemetry VERIFIED LOCALLY end to end from the real runtime (branch binaryb394e0d4, rebase-descendant ofe0184bc3, run as a host process against the mando-cli infra stack): boot mock 4-level report (error.errors4 full-path codes,error.detailsreal file:line +attributesincl.data_group,error.stackbox tree with theErrorAttrsub-line + the opaqueHttpContextattachment, codekindtype, root-cause message, trace correlation); Volue EMS spot single-level fingerprintcode|step_path(spot_data.rs:79); Volue EMS retrieve TWO-LEVEL auth chain live (ems.rs:217+ems_auth_provider.rs:155, the final-review auth level confirmed); Metis full-path code with NOerror.errors(walled-tower flattening as designed); dd_formatter real nested JSON; 12 error lines to Datadog EU via direct intake (env:dev-local-levander). Run recipe + friction: mando-local-host-run-recipe-2026-07-23. UPDATE 2026-07-23 evening (MR + short-code decision): phase 3 IN REVIEW as MR !585 “feat: adopt error stack across all adapters” (feature/BE-3657-phase3→ develop, heada58df341, 22 commits, no conflicts, branch pipeline green on the same sha; reviewers krisztian.fekete1 / gabor.nagy6 / balint.budavoelgyi / jozsef.nagy1). Same head implements the NEW DECISION (Andras, 2026-07-23) amending the field contract:error.codegoes SHORT (Enum::Variant, bare struct name when variantless, per the team spec’s line-100 mobile-readability intent) whileerror.kind/error.type/error.errors/error.detailscodes/error.fingerprintALL stay full module path - mando-coreshort_error_coderesolver (PascalCase-segment heuristic, valid due to house naming), applied at the 4 macro emission sites only (span/boundary layers passthrough), pinned by testkind_type_fingerprint_stay_full_while_code_goes_short, 577/0 workspace lib tests, verified LIVE locally + forwarded to Datadog (env:dev-local-levander). Consequences: the “mobile readability rationale is dead” pending team sentence WITHDRAWN (conformance restored); DD cutover impact for@error.code-keyed assets shrinks (short form resembles legacy codes);@error.sourceRETIRED (renamed toerror.messagein the redesign, pinned by a mando-core regression test) - delete or rekey any facet/monitor still on it to@error.message/@error.errors(an emptyerror.sourceconsumer was hit and fixed by Andras 2026-07-23). UPDATE 2026-07-24 (Caused-by stack renderer): NEW DECISION (Andras) REVISING the locked “crate’s own tree, codes as sub-lines” trade-off:error.stackrendering switches from the error-stack crate’s Debug tree to a custom prefix-style “Caused by” chain renderer, because Datadog collapses newlines in several views and the crate’s ASCII connectors (|-, lone|,|->) turned into unreadable pipe soup in the real DD UI. Per-level format:{short code}: {message}head (first level bare, subsequent prefixedCaused by:) +at file:line:column+with key = valueperErrorAttr; opaque attachments no longer mentioned. Commit1f9cd611(new MR !585 head, 23 commits):render_stack_treewalks frames likereport_details; crate debug-hook plumbing (install_debug_hook,Charset/ColorMode,HOOK_INIT) deleted as dead; 579/0 workspace lib tests incl. an exact multiline golden pin; verified live + forwarded to Datadog (2026-07-24env:dev-local-levanderevents carry the new stacks AND the shorterror.codetogether). Datadog research recorded: Error Tracking for logs needs error status + service + (error.kindOR a validerror.stack) and mando always emitserror.kind(stack format never gates tracking/grouping); DD’s valid-stack bar wants a frame with a FUNCTION NAME + filename, which error_stackLocations never carry (mando stacks never frame-parseable regardless of format); thesourcetag auto-parses only conventional language stacks; remappers relocate but do not parse - soerror.stackis purely presentational, optimized for human readability and graceful newline-collapse (which theCaused by:separators survive). UPDATE 2026-07-24 (error-authoring DX overhaul): decision series (Andras), north star: error reporting must not break Rust’s natural flow,?is the API; 3 commits (branch now headf771805e, ~27 commits, pushed, riding MR !585):f5beabd4report vocabulary (new_coded/CodedExt/change_context_codedDELETED workspace-wide →ToReport::into_report(crate already exportsIntoReport, hence the name) /Result::reported()/.wrap()/.attr(k,v)/flatten_reportfor Clone enums collapsing 6 conversion fns to one-liners; 307 sites, 37 files; bonus find: 20map_err(new_coded)fn-pointer sites - the exact#[track_caller]-losing form - had degraded locations until swept);4e519269shorterror.details[].code(the details panel is the human panel,file:linecarries precision;errors/kind/type/fingerprintstay full path; split pinned by a test in ONE emission);f771805enative report signatures REVISING the phase-3 seam-replication decision (dual*_reportedseams “not fit for a codebase this big”: ~35 flat twins deleted, bareMandoReport<C>(Report<C>)newtype in mando-core with Deref /as_report/into_inner/ delegating Display+Debug /std::error::Errorsource-None / plainFrom<Report<C>>?auto-lift +MandoResult<T,E>alias; adapters ONE fn per op returningMandoResult; ~50 consumer edits flattening at tower edges; ems towers keepReport<VolueEmsError>internally withinto_innerat 5 sites; 5 dead conversion fns deleted; the walls stand, the seam mechanics are gone). Gates 580/0 workspace lib tests + clippy clean. NEXT MR spec’d (docs/superpowers/specs/2026-07-24-be3657-report-derive-design.md):#[derive(MandoReport)]From-impl generation (#[report(from(Src))]display-mapping default,#[report(wraps(Inner, message = "..."))]chain levels,MandoErrormarker bounds at boundaries + clippy ban onReport::new); spike (scratchpad/spike-trackcaller, rustc 1.89.0, error-stack 0.8.0) proved directFromonReport<LocalEnum>orphan-blocked (E0117, naive design dead) while#[track_caller]through the local newtype propagates?-site locations EXACTLY (no ergonomics-for-locations sacrifice needed, despite Andras offering it); grounding pass caught 2 design regressions pre-implementation (from(Src)must display-map or source fields kill Clone/flatten;wraps()needs an explicit static message for struct variants). - BE-3482 Datadog Logs and APM Conformance - BE-3482 status note (2026-07-13): core conformance MERGED 2026-07-08 (MR !558 squash
ae6d1098); the unpushed continuation adds the fingerprint ACTIVITY component (error.fingerprint=code|path|activityviaErrorWithStepStatus.activity: Option<String>+ consumingwith_activity(), all constructors default None so behavior is bit-identical when absent; reference wiring inmando-lib/src/service/volue/ems/ts_data_send.rs, every per-data-group error carries the data group name). Orphan commit478cd993(addsdd_formatter::app_version(), removes 3 panicking unwraps in mando-bess, fixes the known local mando-bess panic) was salvaged same day: cherry-picked onto the fingerprint branch asbc3727ba(Andras’s call, instead of a separate MR); the branch has 2 commits, gates green on both (clippy exit 0, 387 passed / 0 failed across 22 suites), pushed 2026-07-13 and open as MR !569 awaiting review; the old worktree + localfeature/BE-3482are purely historical and archivable. Known limit: at-site-logged variants (VolueEmsError::ApiError) reach the boundary as WARN with no fingerprint until the single-emission migration (own future ticket). UPDATE 2026-07-22: !569 MERGED (merge53912a70); the single-emission migration MERGED as !571 (BE-3541 Single Error Emission), closing the limit; !570 (pymando) + wheel also landed. - BE-3541 Single Error Emission - MERGED via MR !571 (squash
d1cf9c75“refactor: emit step errors once by removing the logged-at-site path”, merge1c4c33a5): one ERROR emission per step failure at the step boundary withHttpContextcarried on the error;ErrorWithStepStatus.logged_at_site+logged()REMOVED - construct withnew/message, never log at the detection site; unlocks fingerprint +http.*for previously at-site-logged variants. - mando-cli-datadog-local-logs-2026-07-22 -
mando up --datadogverifies BE-3482’sdd_formattererror/log JSON (error.code/error.fingerprint) in the real Datadog EU UI from a local run. Confirms the bodyddtagsservicetag overrides infra enrichment whiledd_formatterddtagscarries NOenv(agentDD_ENVauthoritative). Filterenv:dev-local-<user>→service:bess-os-service-mando.
Infrastructure / AWS
- AWS CLI Access via Identity Center - how AWS CLI auth works since 2026-07-21:
[sso-session alpiq-sso]in~/.aws/config(IdC start URLssoins-69878836cb6e09c7, eu-central-1) + fourDeveloper-role profilesbessos-{dev,test,int,prod}mapping to accounts 794038257734 / 071128452852 / 621553445748 / 282467977019 (same set as the section 14.1 deploy matrix); oneaws sso login --sso-session alpiq-ssocovers all four; saml2aws retired but left on disk. Landmine: the RTK hook manglesawsoutput, alwaysrtk proxy aws .... Used for ECR/ECS access during mando deployments. - BE-1597 DuckDB UI Exposure Research — reusable mando AWS-infra facts gathered for BE-1597: mando ALB
aws_lb.bess_os_serviceisinternal=true, 443-only, single target group on port 8080 (bess_os_load_balancer.tf); bastion (bastion.tf) t3.medium in a private subnet, no public IP, SSM Session Manager only, egress-all + ZERO ingress; mando runs on ECS Fargatedesired_count=1withenable_execute_command = environment=="dev"(bess_os_ecs.tf:499), and ECS Exec is interactive-only — no port forwarding (SSMAWS-StartPortForwardingSessionToRemoteHostvia the bastion is the actual port-forward path); thebess_os_ecsSG (security_group.tf:4-23) uses INLINEingressblocks — a standaloneaws_vpc_security_group_ingress_ruleis silently deleted on the next apply; must use adynamic "ingress"block inside the existing resource; NO NAT gateway / VPC endpoints defined (the VPC is abase-vpctag data lookup owned by another team) → Fargate egress to duckdb.org UNVERIFIED;int+prodboth map to account groupint_prod(main.tf:5-6). - BE-1597 DuckDB UI — Design — the approved terraform/infra shape for BE-1597: open port 4214 to the DuckDB UI via a
dynamic "ingress"block INSIDE thebess_os_ecsSG referencing the bastion SG (not the VPC CIDR), gatedvar.environment == "dev"— a standaloneaws_vpc_security_group_ingress_rulewould be silently reaped because that SG uses inline ingress blocks. No ALB listener / target group / health check (mando ALB alreadyinternal=true); the bastion SSM hop (AWS-StartPortForwardingSessionToRemoteHost) is required because ECS Exec is interactive-only. Blocking pre-check: Fargate egress to extensions/ui.duckdb.org is UNVERIFIED (no NAT / VPC endpoints;base-vpcowned by another team) — if blocked, Phase 1 can’t ship and no terraform fixes it.desired_count=1+ Fargate re-IPs each deploy, so theduckdb-ui.shhelper re-resolves the task IP every run. - Mando Deployment Ceremony - the environment matrix: 4 envs map to 2 terraform component groups in
main.tf(dev+test →dev_test, int+prod →int_prod); per-group ECR registries (843164609896…/poc/mando/deployfor dev_test,748634852998…/poc/mandofor int_prod); int_prod naming trap reconfirmed (historically INT, not real prod). Observed pins onrc/1.11.0: dev_test1.11.0-dev.2555942905.50575825, int_prod1.10.0-2533146896.b06b6b59. Expected plan diff on a version bump: the mando container image in the bess-os ECS task def ONLY. - Dev Deploy 2026-07-14 (error telemetry) - terraform plan-reading lesson: a version bump producing 17 add / 19 change / 5 destroy was IaC develop drift catch-up (12 genuinely new resources: the
bess_os_frincoming_synclambda stack + 2 RDS analytics SG rules) plus immutable task-definition replacement mechanics (all destroys were “must be replaced” task defs), NOT danger; the second apply after the migration fix was down to 4 added / 19 changed / 4 destroyed. - fr-region-missing-datadog-logs-2026-07-21 - the FR deployment shape: dev-only
module "bess_os_fr"(terraform/bess_os_fr.tf,count = var.environment == "dev" ? 1 : 0) instantiating sharedterraform/modules/bess_oswithregion_code = "fr"in account 794038257734/eu-central-1; log shipping is awslogs → CloudWatch → subscription filter →datadog-forwarderLambda (dd-logs-forwardermodule from bit-tf-modules v3.21.4), the DD agent sidecar does metrics/APM only. Landmine:modules/bess_oslacks the forwarder wiring, so every regional instantiation ships log groups with no Datadog forwarding. - mando-cli-datadog-local-logs-2026-07-22 - DD_API_KEY acquisition route (2026-07-23): the deployed Datadog API key lives in AWS Secrets Manager, dev account, secret
DdApiKeySecret-pkeeEykkaqu3(referenced from optimization-universe-iacterraform/secret.tfvia CI varDATADOG_API_KEY_SECRET_NAME); fetch withaws sso login --profile bessos-devthenaws secretsmanager get-secret-value --secret-id DdApiKeySecret-pkeeEykkaqu3 --query SecretString --output text(eu-central-1). Needed because the Alpiq Standard Operations Datadog role lacks “API Keys Read” (org key page blocked) and Personal Settingsddpat_/ddapp_tokens do NOT work asDD_API_KEY(real API keys are plain 32-hex; app keys are 40-hex/ddapp_and pair with an API key for queries only). Follow-up: request the permission or a personal org key from the Datadog admin.
Licensing
- BE-1597 DuckDB UI Exposure Research — DuckDB UI frontend = proprietary MotherDuck code, blocks production use. DuckDB core, the prebuilt libduckdb binaries, duckdb-rs, libduckdb-sys, the
uiextension SOURCE (github.com/duckdb/duckdb-ui), quack, ICU (Unicode-3.0), yyjson are all MIT/permissive (IP: Stichting DuckDB Foundation) — safe to vendor closed-source with attribution/NOTICE. BUT the DuckDB UI frontend assets served fromui.duckdb.orgare proprietary, source unpublished (DuckDB’s own 2025-03-12 launch post says so); MotherDuck said Mar 2025 they were “reviewing licensing options” and as of Jul 2026 there is still no published license / terms of use. Served with no auth and (per DuckDB docs) “can access the data you load into DuckDB” → fine on a dev laptop / dev container, NOT acceptable for theint_prodtrading service. (The Quack remote-protocol extension, by contrast, is a core DuckDB-signed MIT extension — no such issue.) Cf. the GPL-avoidance decision in remotefs-smb to smb migration. - BE-1597 DuckDB UI — Design — the licensing finding turned into an approved decision: because the DuckDB UI frontend is proprietary MotherDuck JS served live from ui.duckdb.org with no auth (source unpublished, still no license as of Jul 2026), the spec forbids running the UI in int/prod and ships it dev-only (Phase 1) / on the developer’s own laptop via Quack (Phase 2, where MotherDuck’s JS is already trusted). Everything else in the supply chain (DuckDB core / libduckdb / duckdb-rs / libduckdb-sys / the ui-ext SOURCE / quack / ICU / yyjson) is MIT/permissive and safe to vendor closed-source with a NOTICE bundle. Evidence: License finding (the important one).
mando-cli
- mando-cli-v2 — current architecture (AppContext, CommandDelegate, 13 commands).
- mando-cli-docker-lifecycle — DockerClient + ContainerSpec, bollard 0.19 wiring.
- mando-cli-mock-command-2026-04-28 —
mando mocksubcommands and WireMock infra. - mando-cli-mock-down-idempotent-2026-05-06 —
mando mock down+ WireMock healthcheck endpoint fix; canonical 7-step lifecycle pattern; idempotent-teardown rule (404 = success). - mando-cli-status-readonly-2026-05-06 —
mando statusmade read-only and bounded (connect_readonly,table_exists,statement_timeout = '2s'); status-must-be-pure-reads rule. - mando-cli-build-context-filter-2026-05-06 — yaml-driven
context_includesandbuild_filtered_tarto stop COPY-everything build-context hangs. - mando-cli-build-variants-shelved-2026-05-06 — SHELVED design for profile-driven build variants (dev vs release Dockerfile,
pre_command, 3-field profile syntax). - mando-cli-wsl-linux-build — how to build a Linux x86_64 / WSL release binary locally from an Apple Silicon Mac (musl static target, Docker
--platform linux/amd64, optional-querypath-dep gotcha). - mando-cli-v0.4.0-compose-bugs-triage-2026-05-26 — v0.4.0 compose-runtime triage: two confirmed bugs in the post-bollard rewrite;
context: .relative-path resolution + bare-slug positional arg activating a malformedrender_overridestub. Documents the load-bearingprofiles: ["{run_tag}"]invariant. - mando-cli-v0.4.0-mando-bess-binary-missing-2026-06-25 — design gap surfaced after the triage fixes (commit
2233959): the default profile buildsmandofrommando/Dockerfile, a thin runtime image that COPYs a pre-compiledtarget/release/mando_bess, but no builtin profile mapsmandotopull/artifactand nothing inuprunscargo build --release(--cargoisartifact-only). Freshmando upaborts the compose build. Workaroundmando up --mando=pull; durable fix (default →pull+ missing-binary preflight inup) pending user decision. Reported by gabi (WSL). - mando-cli-v0.4.0-piped-output-invisible-failures-2026-06-25 —
mando upfailures are invisible when output is piped/redirected (tester does2>&1 | tee log): the user gets only a barefailed (exit 1)and an empty.mando/compose-up.log. Two fixes in the compose runner + buffer: (A)--progress plainon thedocker composecall (compose.rs~L231) so compose stops writing progress/errors to/dev/tty; (B)eprintln!fallback inCliBuffer::add_log_line(opts.rs:57) when stderr isn’t a TTY, becauseindicatif::MultiProgress::printlnsilently no-ops there. Validated macOS (35→138 lines). Also clarifies mando-cli’s “registry auth” (GitLab API creds) ≠docker login(container registry) — the now-visible tester failure is a registrypull access denied. Built+validated, not committed. - mando-cli-simulator-runtime-2026-05-30 — second first-class Docker Compose stack
mando-simcoexisting with the devmandoproject; six runners generated from a data-drivenSIMULATOR_RUNNERSlist; own Postgres on host port 5433;RunProfile.compose_project/layers()routes commands; newsrc/runtime/service_stack.rs::select_profileshared resolver forlogs/exec/volume; defines the §A orchestrator↔runner env contract that the (WIP)mando_simulatorcrate,simulator-runnerimage, and six sim repos must implement. Supersedes GitLab MR !2 (balint). Landedb244f2eonfeature/simulator-runtime. Process lesson: use fullcargo test, not--bin mando(skipstests/). - mando-cli-simulator-env-contract-2026-06-02 — follow-up to the simulator runtime: §A env contract realigned to real images (
simulator:1.11.0-feat.2569583284.7d69a070+ runner shapef7aa42f); adds arbitrary-extras passthrough viafilter_extras/MANAGED_SIM_ENV_KEYS; sim-postgres aliased toSIMULATOR_DATABASE_*so one.envoverride controls both. Landedc3f0af7onfeature/simulator-runtime(8 files, +440/−67, 813 tests). - mando-cli-datadog-local-logs-2026-07-22 -
mando up --datadoglocal Datadog log shipping; 2026-07-23 end-to-end test ofdocs/datadog-guide.md(tipc2becf1): guide accurate, every claim verified. HAZARD: a stale pre-feature binary reporting the SAME 0.4.0 version silently swallows--datadogas a service arg and starts a realup; the guide’s flag-position warning cannot protect against it (suggested guide follow-up: a version-check note). Nit: the new error strings use em dash characters, against Andras’s conventions elsewhere. - mando-cli-as-forecast-removal-2026-07-24 - removed obsolete
bess-os-algo-forecast-as(Project::AsForecast) via compiler-driven deletion (enum variant/slug/aliases/config default; builtin profiles now 4 services; README five repos/two algos). LESSON: an enum variant used as a persistedHashMap<Project,_>map key in.bessstate.json— deleting it made a stale"AsForecast"key fail deser and theunwrap_or_defaultfallback silently WIPE the whole projects map (all overrides/toggles). Fix: per-key tolerantfilter_known_projectsmirroringsave()’s PascalCase keys viaProject::deserialize(NOTfrom_alias),warn!per dropped key, fixture restored as regression guard. Rule: deleting an enum variant = audit every persisted format keyed by it before shipping. - mando-cli-json-output-agent-skill-2026-07-23 -
mando --json <cmd>/MANDO_OUTPUT=json(flag wins, exact-match"json") renders all output as terse NDJSON on stdout (kv/step/err/data+ ALWAYS-LAST{"t":"result","ok","code"}frommain.rs’s single exit path); human mode byte-identical, spinners suppressed, logs/exec/compose chatter stay raw on stderr. One pure mappersrc/ui/json.rs::element_to_eventcovers all 21 commands via the Element seam (format!-built fort-first order; payload keys alphabetical,preserve_orderoff). Agent skill.claude/skills/mando/SKILL.md(64 lines): grammar + minimal invocations + error→remedy + frugality (status before logs, trust exit codes, never parse human tables);mock -pgoes BEFORE the subcommand. NO top-levelwarnevent (warnings aresteps:"warn"). Working tree, UNCOMMITTED 2026-07-23.
py-mando / Python Bindings
- Mando AGENTS.md Master Guide — round-2 (2026-07-13) verified py-mando facts: py-mando-simulation split out of py-mando in commit
3559042d—py_mando.SimulationRunneris GONE (breaking change); the new package requires Python ≥3.11, shipsddtrace, no polars/pandas. Both packages runinit()at import (JsonFormatter + rustls ring) and preload libduckdb (ctypesRTLD_GLOBAL/add_dll_directory);build.rscopieslib/libduckdb/1.4.2intodata/platlib. Two sanctioned async bridges: blockingpy.allow_threads(|| pyo3_async_runtimes::tokio::get_runtime().block_on(…))+pyo3_async_runtimes::tokio::future_into_pyfor the*_asyncawaitable variants. Errors: singlePyMandoErrorviamap_*_errorfns (mando-lib/src/python/error.rs). Test posture: py-mando-simulation Rust side zero tests, 1 Python integration test; CI job “PyMando Simulation Linux Dev” (pytest without--nbval). - py-mando — crate overview (abi3-py38 stable ABI, algo params, DataFrame ops, algo runner HTTP server).
- BE-3482 pymando Branch Review - 2026-07-13 read-only review of
feature/BE-3482-pymando(13 commits, py-mando DD log/APM conformance): NEEDS REWORK BEFORE MR despite genuinely green gates (clippy clean; 366 passed / 0 failed / 35 ignored viartk proxy;fmt_utilproven feature-flag-clean by buildingmando_libwith and without--features python). Blockers: 13/13 scoped commit titles (banned per !322), 7 orphaned ContextVars intracing.py, byte-identical duplicates of the fingerprint branch’s version-fallback fix. Landing order: fingerprint MR first, then rebase dropping the duplicates; sharpest option also drops the fmt_util extraction for a zero-conflict 9-commit MR. Rework EXECUTED same day: rebuilt from scratch asfeature/BE-3482-pymando-v2(worktree.worktrees/BE-3482-pymando-v2), 15 title-only no-scope commits off develop tip51d2b516, zero cherry-pick conflicts, 10 files +374/-55;9b0c4e70kept,86d7ffd8/34e749d5/d0986230dropped (dropping the extraction cost zero extra code,level_to_statuswas still inline); all blockers/should-fixes done (build_ddtagspublic, bare-code fingerprint,caplog+ genuine global restore); gates green (clippy 0, 434/0/35 cargo tests, rustfmt 0 branch hunks, pytest 120 passed / 1 skipped vs baseline 114); NOT pushed, no MR; v1 untouched as fallback. UPDATE 2026-07-22: pushed + MERGED as MR !570 (squashfde2425e“feat: pymando logging conformance”, merge14dfb3ad); conformant wheelpy-mando==1.16.1+dev.2691658359.14dfb3adpublished to Nexus dev. - BE-3613 Algo Services py-mando Conformance - moving the algo services (bess-os-algo-optimization + bess-os-algo-forecast; forecast-as OUT of scope) onto the conformant wheel
py-mando==1.16.1+dev.2691658359.14dfb3ad: pin bump + fork replacement +log_erroradoption per repo; code COMPLETE 2026-07-22 on bothfeature/BE-3613branches (bess-optimizationbb0555e/d47212d/71fb146; bess-forecast-day-ahead50231b6/927e1e5/e1d5ade+ fork-test file deletions), UNPUSHED, blocked only on VPN/Nexus forpoetry lock --no-update && poetry install && poetry run pytest. - BE-3657 error_stack Adoption - phase 3 (planned 2026-07-22 evening, execution gated on !580) plans a shared
error_json_field_valuefn in mando-core unifying theerror.errors/error.detailsJSON parsing across mando-lib’sdd_formatterand BOTH python package log formatters (py-mando/src/log_formatter.rs,py-mando-simulation/src/log_formatter.rs); today only dd_formatter has that parse. UPDATE 2026-07-23: SHIPPED onfeature/BE-3657-phase3@e0184bc3(unmerged) - the shared hook unifies all three formatters; PyO3 also gainedmap_report_errorforward plumbing, its wiring grep-proven unreachable this phase; py-mando/py-mando-simulation pytest deferred to CI (no local venv, Nexus VPN-gated).
Tracing / Observability
- clippy-disallowed-macros-allow-placement-2026-06-22 — mando bans
tracing::error!directly (clippy.tomldisallowed-macros) so all error logging routes through themando_core::error!wrapper; the wrapper suppresses the lint for its own expansion via a module-root#![allow(clippy::disallowed_macros)]inmando-core/src/error.rs(call-site allow is ineffective on clippy 1.95). - BE-3117 Per-Flow Error Context Store —
FLOW_ERROR_CONTEXTtask-local store created inside the spawned flow task (task-locals don’t crosstokio::spawn); drained after scope returns into ONEtracing::error!aggregate withflow.error.*flat facets + fullflow.errorsJSON. Hand-writtenSerializeredacts HTTP bodies whenhttp_context.sensitive. - BE-2272 — DD log JSON flattening to root.
- BE-1842 Datadog Observability — span-scope walking,
tokio::spawncontext-inheritance gotcha, dd_formatter field plumbing. - BE-3482 Datadog Logs and APM Conformance - Datadog logs/APM conformance state + ranked open deferrals: single-emission migration (biggest win, unlocks fingerprint +
http.*on at-site errors) >error.*/http.*on trace spans > verifydd.trace_idcorrelation in DD >flow.step.timeout_ms. The fingerprint ACTIVITY component (pushed 2026-07-13, open as MR !569; MERGED by 2026-07-15 as53912a70) makes DA vs AS schedule failures in the auction scheduling step group SEPARATELY in Datadog (previously ONE error group). Authoritative fingerprint standard: architecture-design repo,logs-and-apm.md(error.code + flow.step.path + specific activity). - BE-3482 pymando Branch Review - review outcome for the py-mando DD conformance branch: solid work (flat
flow.step.path, conformantlogging.conf,log_errorhelper with root-cause unwinding,set_log_tagsddtags bridge into the Rust formatter) but needs rework before MR. Sharpest conformance finding:error.fingerprintserializescode|Nonewhen no step context is set (tracing.py:109), polluting DD fingerprint aggregation forlog_errorcalls outside atrace()/run_with_tracescope. The same-day rework FIXED it (bare code, no"None", with a new test) and added a NEWflow.step.systemspan tag: the non-Mando counterparty taken straight fromStepMetadata.systeminmando-lib/src/workflow/mod.rs(the structured sourceflow.step.connectionis formatted from), one line, no string parsing; runtime JSON conformance proven from the Rust stream during pytest (120 passed / 1 skipped). - Dev Deploy 2026-07-14 (error telemetry) - first LIVE validation of the BE-3482 telemetry on dev, observed from the deploy’s own crash-loop logs:
error.code==error.kind==error.type(spec-verified: architecture-designlogs-and-apm.mdlines 87-104 explicitly mandate three fields with the same value for APM/logs/mobile),error.message= root cause,error.stack= source chain (wrapper-embeds-source Display pattern causes cosmetic text duplication),error.fingerprintabsent as expected for non-step errors. Follow-up idea: emit a bare-code fingerprint from the Rusterror!macro outside flow steps (parity with py-mandolog_error), needs one sentence added to the standard. - fr-region-missing-datadog-logs-2026-07-21 - why FR services show APM/metrics but zero logs in Datadog: container logs travel CloudWatch →
datadog-forwarderLambda via subscription filters (NOT the agent sidecar), and the-frlog groups have no subscription filters becausemodules/bess_os/cloudwatch.tfnever got thedd-logs-forwarderblocks. - BE-3657 error_stack Adoption - Datadog verification of the dev throwaway build
1.16.1-feat.2682437891.b7d15e2c(2026-07-16..22): nestederror.details(4-level chain, real file:line),error.errorsarray queries (element/wildcard/negation), nestedhttp.{request{method,url,version,body,content_length}, response{status_code,body,content_length}}, trace correlation confirmed (sample trace0dc8d42739a08ac0805808b2d14b6644); startup mock deep error fires once per task boot (still the typederror!arm, not the report arm). PENDING DD cutover AT BE-3657 MERGE: create facets@error.fingerprint/@error.errors/@error.details.code; inventory monitors keyed on short codes, flathttp.*, exact message “Failed running step” - all code/fingerprint values change format at that deploy. UPDATE 2026-07-23: !580 (phases 1+2) MERGED (merge4c3442df), so the cutover checklist becomes actionable with the first develop-based dev deploy carrying it; the mock is superseded on the phase 3 branch by an env-gated report-backed port (MANDO_DEBUG_MOCK_ERROR, default off, unmerged). UPDATE 2026-07-23 evening: the short-code decision (commita58df341, in review with MR !585) narrows that format break:error.codebecomes the SHORTEnum::Variantform (close to the legacy shape, so@error.code-keyed monitor impact shrinks), whileerror.kind/error.type/error.fingerprint/error.errors/error.detailscodes stay full module path and DO still change format at that deploy. NEW cutover item:@error.sourceis RETIRED (renamed toerror.messagein the redesign, pinned by a mando-core regression test) - delete or rekey any facet/monitor still on it to@error.message/@error.errors(an emptyerror.sourceconsumer already hit and fixed by Andras 2026-07-23). UPDATE 2026-07-24 (DX batch + live stream):error.details[].codealso goes SHORT (commit4e519269;errors/kind/type/fingerprintstay full path), so the@error.details.codefacet keeps a readable short form at cutover. Local LIVE stream now operational: server on 8081 + a CONTINUOUS forwarder shipping error/warning lines to Datadog EU within ~5s underenv:dev-local-levander(MANDO_ENVIRONMENT=dev-local-levanderset at source, no forward-time ddtags rewrite); complete field contract verified live (code short, errors full, details codes short per level, fingerprint full, Caused-by stack, nested http blocks on 5xx paths). GOTCHAS: facet queries with::in the value MUST be quoted (@error.code:"VolueEmsError::ApiError", unquoted silently matches nothing); a survived stale local server held port 8081 so a new launch died AddrInUse while old-format emissions kept flowing (diagnose with lsof on the port + the holder’s binary path). - mando-cli-datadog-local-logs-2026-07-22 - Datadog host-tag join latency (2026-07-23 guide test):
env:dev-local-<user>ridesDD_ENVHOST metadata, and the host-tag join takes up to ~10 min for a brand-new agent host (~8 min observed), so freshly shipped logs are initially queryable byservice:/container_name:only and get the env tag retroactively; an env filter that looks broken right after agent start is just the join lag. Logs Search APIapi.datadoghq.eu/api/v2/logs/events/searchworks with the org API key + a Personal Settingsddapp_application key.
Workflow / Flow Engine
- be-1595-flow-repository-sqlite-bugs-2026-06-17 — Two latent
FlowRepositorySqlitebugs (Sqlite dev/test only):create_flowlazy-query()INSERT that never persists, andstarted_atcurrent_timestampTEXT default unreadable asi64inget_execution. - be-1595-flight-execution-id-parity-2026-06-17 — Execution-bound manual overrides resolved via
FlowRepository.execution_idlookup, now shared between REST and Flight paths (apply_execution_overrides);MandoFlightServicecarries anArc<FlowRepository>so the Flight handler can resolve execution overrides like REST. - BE-3117 Per-Flow Error Context Store — flow boundary in
workflow/flow.rswraps execution inFLOW_ERROR_CONTEXT.scope(...)+FlowCompletionGuard(Drop-flush for panic/cancel). Step-level recording inStepResult::logviaErrorRecord::from(&ErrorWithStepStatus), gated on!logged_at_site. Thelogged_at_siteflag is the successor tologged_at_failure_site. - flow-step-log-message-dropped-2026-05-26 — Step-failure logging contract:
ErrorWithStepStatus::log(status, message)is the “I haven’t logged yet, parent please log me” path (logged_at_failure_site: false), but the parent’sStepResult::log()dropsmessage. Documents the constructor/Display/status_or_error/top-level-catch chain and thec945514e/4c543cb1cross-check. - Mando AGENTS.md Master Guide — released flow versions are immutable: never change a released vN’s YAML or generated code; breaking behavior → v(N+1); exemplar manual_schedule v3. Definition YAML (
mando-bess/config/flows/fi/*.yaml) →build.rs→ generated Rust that is TRACKED in git (commit YAML + output together). Tip flows @ 2026-07-08: as_auction_update_v2, auction_v4, data_update_v2, intraday_v2, manual_schedule_v3. Jul-08 develop restructured src-side wiring from per-typesrc/flow/{type}/v{n}/dirs toflow_registry.rs, backed by new cratesmando-flow-step(FlowStepServicetrait: uniform async step construction from YAML) +mando-flow-step-derive(ParamEnum/ParamMetaderives). Round 2 (2026-07-13):FlowStepServiceis a construction trait, NOT execute()-style —type Params: ParamMeta; type Response;+ asyncfrom_config(config: &str, providers: &StepProviders);StepProviderscarries flow_repository/data_point_registry/6 auth providers/simulation_enabled; 36type_entry!registrations inmando-bess/build.rs; param structs derive#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, ParamMeta)];config/flows/manifest.yamlis the deployment catalog (setup: {version}: flows: {name}: {path, schedule_env, semaphore_group}— scheduling env + concurrency groups in the manifest, not code; semaphores capacity 1/group); the flow-step crates ship with zero tests. - BE-3656 APM Span Enrichment -
SpanEnrichmentLayercopieserror.*/http.*off ERROR-level tracing events onto the active OTel span as Datadog APM tags; readsopentelemetry::Context::current().span()NOTtracing::Span::current()(empty insideLayer::on_eventunder scoped subscribers). MERGED via MR !578 2026-07-22 (squash46a9be1b, merge4a0d297f). Verified live on dev (3 commits,a0735ebbreview-hardening: bodies off spans, first-error-wins guard, no MR yet). Dev-deploy prototyped17227acvalidates the BE-3657 field shapes: full-patherror.code, startup mock deep error,error.errors/error.detailsas real JSON arrays (targeteddd_formatterparse),flow.step.systemfrom !570; DD array queries verified (element/wildcard/object-field/numeric/negation). Note: DD flattens array SPAN attrs tokey.0/key.1(breaks faceting) so arrays are log-side only, spans keep scalarerror.code. Three tooling landmines added: Bash cwd resets to main checkout between calls, RTK garbles grep/sed (Read to ground-truth),grep "test result" | tail -1cargo false green. - BE-3482 pymando Branch Review - the step
info_span!inmando-lib/src/workflow/mod.rsgained aflow.step.systemtag (2026-07-13 rework, commit52b4d270onfeature/BE-3482-pymando-v2, unpushed): the non-Mando counterparty taken directly fromStepMetadata.system(the same structured sourceconnection()formats), no string parsing; verified all 14DataFlow::Wrappersteps declaresystem: "Mando"and externals declare real names (Volue EMS x19, Metis x14, Position Manager x8); 4-case#[test_case]matrix covers Receive/Send/Wrapper semantics. Scope tension: one mando-lib commit on an otherwise py-mando-only branch, trivially splittable.