Background
The Go bundle serializer always emits CronTriggerTimetable for a cron schedule, which only matches the default deployment ([scheduler] create_cron_data_intervals = False). When a deployment sets it to True, Python's _create_timetable (task-sdk/src/airflow/sdk/definitions/dag.py) produces CronDataIntervalTimetable instead, so a Go-authored DAG diverges from the equivalent Python DAG.
The Go bundle binary cannot read airflow.cfg, so it has no way to branch on the flag today. The relevant scheduler settings must be delivered from the supervisor (Python ExecutableCoordinator) to the lang-SDK over the coordinator protocol first.
Current hardcoded branch in go-sdk/pkg/execution/serde.go (serializeTimetable):
default:
return map[string]any{
"__type": "airflow.timetables.trigger.CronTriggerTimetable",
"__var": map[string]any{
"expression": *schedule,
"timezone": "UTC",
"interval": 0.0,
"run_immediately": false,
},
}
What needs to happen
- Extend the coordinator protocol so the supervisor sends
create_cron_data_intervals (and create_delta_data_intervals, once timedelta schedules are supported) to the bundle — e.g. as fields on DagFileParseRequest.
- In
serializeTimetable, emit CronDataIntervalTimetable ({expression, timezone}) when create_cron_data_intervals is True and CronTriggerTimetable when False, mirroring _create_timetable.
- Carry the DAG timezone over the same channel;
serializeTimetable currently hardcodes "UTC".
Acceptance criteria
- A cron-scheduled Go DAG serializes to the same timetable
__type and __var as the equivalent Python DAG under both values of create_cron_data_intervals.
- DAG timezone is no longer hardcoded to
"UTC".
- The
TODO on serializeTimetable in go-sdk/pkg/execution/serde.go is removed.
Context
Drafted-by: Claude Code (Opus 4.8); reviewed by @jason810496 before posting
Background
The Go bundle serializer always emits
CronTriggerTimetablefor a cronschedule, which only matches the default deployment ([scheduler] create_cron_data_intervals = False). When a deployment sets it toTrue, Python's_create_timetable(task-sdk/src/airflow/sdk/definitions/dag.py) producesCronDataIntervalTimetableinstead, so a Go-authored DAG diverges from the equivalent Python DAG.The Go bundle binary cannot read
airflow.cfg, so it has no way to branch on the flag today. The relevant scheduler settings must be delivered from the supervisor (PythonExecutableCoordinator) to the lang-SDK over the coordinator protocol first.Current hardcoded branch in
go-sdk/pkg/execution/serde.go(serializeTimetable):default: return map[string]any{ "__type": "airflow.timetables.trigger.CronTriggerTimetable", "__var": map[string]any{ "expression": *schedule, "timezone": "UTC", "interval": 0.0, "run_immediately": false, }, }What needs to happen
create_cron_data_intervals(andcreate_delta_data_intervals, once timedelta schedules are supported) to the bundle — e.g. as fields onDagFileParseRequest.serializeTimetable, emitCronDataIntervalTimetable({expression, timezone}) whencreate_cron_data_intervalsisTrueandCronTriggerTimetablewhenFalse, mirroring_create_timetable.serializeTimetablecurrently hardcodes"UTC".Acceptance criteria
__typeand__varas the equivalent Python DAG under both values ofcreate_cron_data_intervals."UTC".TODOonserializeTimetableingo-sdk/pkg/execution/serde.gois removed.Context
_create_timetableintask-sdk/src/airflow/sdk/definitions/dag.py; config default inairflow-core/src/airflow/config_templates/config.yml(create_cron_data_intervals, defaultFalse).Drafted-by: Claude Code (Opus 4.8); reviewed by @jason810496 before posting