Skip to content

Let step names keep their diacritics and their script - #673

Merged
hanna-paasivirta merged 6 commits into
mainfrom
446-unicode-only
Sep 9, 2026
Merged

hanna-paasivirta merged 6 commits into
mainfrom
446-unicode-only

Conversation

@elias-ba

@elias-ba elias-ba commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator

Short Description

Apollo folded every job and step name to ASCII, so a Spanish name lost its accents and a Japanese or Russian one became the empty string. This lets names keep their diacritics and their script.

Part of #446

Implementation Details

Two names in different scripts both folded to nothing, so they collided, and a lookup for one matched the first of them. Names now go through name_rules, which normalises to NFC, counts graphemes the way Elixir does, and refuses only control characters.

It sits behind APOLLO_UNICODE_STEP_NAMES and defaults to off. With the flag off the new rule is ASCII like the old one, but it is not byte-for-byte what was there before: a newline or tab inside a name becomes a space rather than being kept, names are trimmed and capped at 100 graphemes, and straße folds to strasse rather than strae. Job and trigger keys are now sanitised too, which they never were. Each of those moves in the safe direction, but the off path is not a no-op and I would rather say so than have someone find it.

Two other things came with it. Keys and names are now rewritten together rather than separately, which is what used to leave edges pointing at nothing. And the YAML dump keeps unicode rather than escaping it.

This is split out of #660 so the question about job code in Sentry can be settled on its own. Nothing here depends on how that goes.

AI Usage

  • Yes, I have used AI
  • No, I have not used AI

You can read more details in our Responsible AI Policy

Apollo folded every name to ASCII, so a Spanish name lost its accents and a
Japanese or Russian one became the empty string. Two steps in different scripts
then collapsed onto each other, and a lookup for one matched the first of them.

Names now go through name_rules, which normalises to NFC, counts graphemes the
way Elixir does, and refuses only control characters. It is behind
APOLLO_UNICODE_STEP_NAMES and defaults to off, so nothing changes until
Lightning ships the matching rule.

Keys and names are rewritten together rather than separately, which is what
left edges pointing at nothing before, and the YAML dump keeps unicode instead
of escaping it.

Split out of #660 so the leak-hardening question can be settled on its own.
Review found leak-hardening residue in this branch. A comment about swap
tokens had ended up above _reference_key, where it read as that function's
doc. _section was left with no caller once its tests went to the other
branch. unicodedata was imported for a function that no longer exists. Three
test fixtures and five section banners had nothing left pointing at them.
The rebuild took main's copy of test_yaml_utils.py, so the tests covering
non-Latin name lookup, page parsing and fold resolution never came across.
Putting them back caught a second thing the rebuild had missed: get_page_view
was still main's, which reads only the third path segment, so a step whose name
contains a slash lost its focus entirely.
@hanna-paasivirta

Copy link
Copy Markdown
Contributor

So far I've reproduced the error on main, checked this fix works, and I'm still looking through the implementation.

Comment thread services/name_rules.py Outdated
"for, as they wrote it — do not strip accents or transliterate."
)
return (
"Job names may use only unaccented English letters, digits, spaces, hyphens and underscores. "

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section replaces the previous prompt "Job names cannot have special characters and must be under 100 characters. All job names must be unique within a workflow". Do we need to make it longer than what it was? Were you able to break it?

Comment thread services/name_rules.py Outdated
unicode_mode = unicode_names_enabled()
if unicode_mode:
return (
"Job names may contain anything except control characters. Letters and marks from any "

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think we could trim the examples?

@hanna-paasivirta

Copy link
Copy Markdown
Contributor

Are we keeping track of setting APOLLO_UNICODE_STEP_NAMES=true in staging/prod somewhere?

# Conflicts:
#	services/testing/judges/general.md
#	services/testing/judges/openfn_workflow_expert.md
#	services/workflow_chat/gen_project_prompt.py
#	services/workflow_chat/tests/unit/gen_project/test_prompt_build.py
#	services/workflow_chat/workflow_chat.py
#	services/yaml_utils.py
@hanna-paasivirta
hanna-paasivirta merged commit 802f414 into main Sep 9, 2026
2 of 3 checks passed
@elias-ba
elias-ba deleted the 446-unicode-only branch September 9, 2026 17:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants