Skip to content

Let the desk add titles.yml variations - #504

Merged
JesperDramsch merged 2 commits into
mainfrom
ai-agent/keen-brown-zq8f2b
Oct 15, 2026
Merged

JesperDramsch merged 2 commits into
mainfrom
ai-agent/keen-brown-zq8f2b

Conversation

@JesperDramsch

Copy link
Copy Markdown
Owner

The first desk run found series that sources also name another way (PyDay Rancagua as "PyDay Chile Rancagua", PyDay Santiago as "PyDay Chile Santiago") and could not record that, because only the three data files were in scope. This lets the desk add variations to utils/tidy_conf/data/titles.yml, and nothing else in that file.

What changes

  • AGENTS.md: a "Names" rule for when another name a source uses becomes a variation, plus the names that can never be one (shared names, any entry's conference, another series' alt_name). Change sets gain an optional titles list (key, variation, URL, quote). "Data mechanics" says how to add a variation and stages titles.yml along with the data files. rejections.yml, global, regexes and spelling stay with the maintainer.
  • desk.md:
    • New ground rule naming titles.yml as editable data.
    • Step 6.3 lets the stray-write check, the restore and the commit cover titles.yml, and adds evidence rows to the ledger.
    • The tamper check (and its step 4 baseline) leaves out titles.yml with :(exclude). It used to cover all of utils/, so the desk's own edit would have stopped the run.
  • Skills:
    • The critic checks each variation against its source, titles.yml, rejections.yml and the data files.
    • The scouter, enricher and new-year-checker propose variations when sources give another name.
  • tests/test_desk_guard.py: pins that a desk-run edit of titles.yml passes, that a subagent's is blocked, and that the new procedure commands get through. The guard code itself needs no change: outside .github/ it never restricted the desk's own edits.

The rename rule

The sort runs tidy_titles over every entry in all three files. A variation that matches an existing entry's conference renames that entry, and the rename can then trigger merge_duplicates, where the longer value wins. If the sort renames anything after a variation is added, the desk takes the variation out again, commits the rest and defers the variation to the maintainer, naming the entries it would rename. So the desk only lands variations that fold future imports. Consolidating existing entries stays a maintainer call. The enricher's import-duplicate question case therefore stays needs-maintainer.

Checks

  • pytest tests/test_desk_guard.py: 1097 passed.
  • ruff@0.4.4 check utils tests: clean.
  • Ran against the real data with the pinned uv sort:
    • Baseline sort: no diff.
    • Adding PyDay Rancagua → PyDay Chile Rancagua: only 3 added lines in titles.yml, data unchanged, keys still sorted.
    • A variation equal to an existing entry's name (PyDay Copiapó): the sort renames that entry, which the rename rule above catches.
    • Broken YAML in titles.yml: the sort exits 1 and writes nothing.

Outside this repo

  • ~/.desk-guard.json in the Routine environment: if a deny_paths pattern covers utils/, it will still block the edit.
  • The standing orders in the maintainer's global CLAUDE.md list the editable files and need titles.yml added.

🤖 Generated with Claude Code

https://claude.ai/code/session_013sKyvme6kQEAzWQFrJnPCe


Generated by Claude Code

The first desk run found series that other sources name differently
(PyDay Chile Rancagua for PyDay Rancagua) but could only change the three
data files, so it left the titles.yml entries to the maintainer.

The desk may now add variations to utils/tidy_conf/data/titles.yml,
nothing else in it. Subagents propose them in a new `titles` list in
their change sets, the critic verifies each against its source and
against titles.yml, rejections.yml and the data files, and the desk
commits them with the series' data. rejections.yml and the rest of
utils/ stay with the maintainer.

The sort applies titles.yml to every entry, so a variation can rename an
existing entry and set off the duplicate merge. The stray-write check
treats such a rename as a reason to drop the variation and defer it to
the maintainer, so the desk only lands variations that fold future
imports. The tamper check leaves titles.yml out, since step 6.3 now
checks it with the data files.

The guard needs no code change: it never restricted the desk's own file
edits outside .github/, and still blocks subagent writes. Tests pin both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sKyvme6kQEAzWQFrJnPCe
@JesperDramsch JesperDramsch added the Review Ready Runs the PR review Routine; the Routine removes it after posting label Oct 15, 2026

Copy link
Copy Markdown
Owner Author

Routine review

1. Request

The PR body is the request (no linked issue): let the desk add variations to utils/tidy_conf/data/titles.yml and nothing else in it. It names these instances: AGENTS.md (the "Names" rule, the titles field in change sets, "Data mechanics"), desk.md (ground rule, step 4 baseline, steps 6.3.2–6.3.6, step 8, the tamper check, the ledger), the critic, scouter, enricher and new-year-checker skills, and tests/test_desk_guard.py.

2. Checked against

  • Date: Thu Oct 15 13:14:01 UTC 2026.
  • No external facts. Every claim below comes from code in this checkout: utils/tidy_conf/titles.py, utils/tidy_conf/yaml.py and utils/desk_worklist.py.

3. Needs your decision

None. The diff covers every instance the body names and nothing else. The two follow-ups the body lists under "Outside this repo" are not changes in this PR. They are ~/.desk-guard.json deny_paths and the standing orders in your global CLAUDE.md. Until you add titles.yml there, the desk will be blocked or told not to edit it.

4. Findings

Important: None.

Nits

  • Judgement call: the critic's uniqueness check (.claude/skills/critic/SKILL.md, the new titles bullets) compares names "ignoring case and accents". load_title_mappings expands every variation further:

    • it strips Conference/Conf (utils/tidy_conf/yaml.py:144);
    • it strips whitespace and non-word characters;
    • it strips years (utils/tidy_conf/yaml.py:151).

    desk_worklist.py:652 and the importers then use that reverse mapping. So a variation such as PyDay Chile 2026 or PyDay Chile Conference passes the critic, yet it also maps the shared name PyDay Chile to one series. That shared name is the case AGENTS.md "Names" forbids. The step 6.3 rename rule does not catch this when no entry is named exactly PyDay Chile. Smallest fix: one clause in the critic bullet, "…and compared again after removing years, Conference/Conf, spaces and punctuation, the way load_title_mappings expands it".

5. Tests

  • What the tests cover. The new tests check guard behaviour: a desk-run edit of titles.yml is allowed, a subagent's edit is blocked, and the new git add / git checkout / tamper-status commands are allowed. utils/ and .claude/hooks/desk_guard.py are unchanged (git diff --stat origin/main...HEAD lists only the six Markdown files and the test file), so these tests also pass on the base. That is expected, because the PR claims no code fix. They are regression pins, not proof of a fix.
  • What they don't cover. The invariant this PR adds is that a variation must rename nothing. It lives only in desk.md prose, and no test runs over it.
  • Tamper exclusion. I checked it by hand. After appending a line to titles.yml, the step-4/9 tamper git status … ':(exclude)utils/tidy_conf/data/titles.yml' printed no non-ignored lines. I then restored the file.
  • Output of the checks (PR head):
    • npm test: Test Suites: 15 passed, 15 total / Tests: 423 passed, 423 total
    • pytest tests/ -q -x (uv, Python 3.11, pandas<2.3): 2460 passed, 5 skipped, 3 xfailed, 2 xpassed, 251 warnings in 243.13s (0:04:03)
    • uvx ruff@0.4.4 check utils tests: All checks passed!
    • utils/sort_yaml.py --skip_links: exit 0. git diff --stat -- _data is empty.

6. Bounds

  • Route: I fetched the PR through the REST API (pulls/504, diff) and checked it out from refs/pull/504/head. rev-parse matched 6efac3c898db5b5d50673e5817e4a3aad918a9f9.
  • Read in full: the diff; REVIEW.md from main; utils/tidy_conf/titles.py:tidy_titles; utils/tidy_conf/yaml.py:load_title_mappings.
  • Skimmed: titles.yml layout; AGENTS.md / CONTRIBUTING.md from main.
  • Not reviewed: the full surrounding text of desk.md beyond the diff hunks. pre-commit.ci - pr status was not quoted; I did not look it up.
  • Pre-existing problems: none noted.

Generated by Claude Code

@JesperDramsch JesperDramsch removed the Review Ready Runs the PR review Routine; the Routine removes it after posting label Oct 15, 2026

Copy link
Copy Markdown
Owner Author

Routine review

1. Request

No issue is linked, so the request is the PR description: let the desk add variations to utils/tidy_conf/data/titles.yml and nothing else there. It names these places: AGENTS.md (Names rule, titles in change sets, Data mechanics, staging), .claude/routines/desk.md (ground rule, step 6.3 stray-write check / restore / commit / ledger rows, the tamper check and its step 4 baseline), the critic, scouter, enricher and new-year-checker skills, and tests/test_desk_guard.py. The diff touches all of them, and only them.

2. Checked against

  • date: Thu Oct 15 13:17:17 UTC 2026
  • No external facts. Everything below comes from the repository at 6efac3c.

3. Needs your decision

  1. A titles.yml change on main can now block both writers on the rolling branch. Before this PR, nothing on auto/conference-updates changed titles.yml: the importer leaves it unstaged (.github/workflows/canonical-source-update.yml:255-259). With this PR the desk commits it. If you edit nearby lines on main while the rolling PR is open, git merge origin/main conflicts on titles.yml. utils/merge_data.py only resolves conflicts in DATA_FILES (utils/merge_data.py:55) and exits 2 on any other conflicted path. So the canonical-source job fails with "Branch Sync Conflict" (canonical-source-update.yml:125-130), and the desk stops at step 2. Both fail loudly, so no data is lost, but neither writer runs until you merge by hand. main has had 8 commits to titles.yml in 2026 (for example 315a897 "Armenia title doublings"). My recommendation: accept the risk and say so in the PR, or have the desk keep titles.yml edits rare until the rolling PR merges. Teaching merge_data.py to handle titles.yml would widen this PR.

4. Findings

Important

  1. For 24 of the 53 titles.yml keys, the procedure has no allowed way to add a variation, so a correct change stops the desk run. .claude/routines/desk.md:87 says: "titles.yml gains only the lines that add this conference's accepted variations: one line per variation, plus the key and variations: lines when the key is new. Anything else is a stray write". AGENTS.md:86 covers the same two cases: a new key, or a - line at the end of an existing list. 24 existing keys have no variations: list, only global:. Examples are PyCon Germany (utils/tidy_conf/data/titles.yml:72-73, global: PyCon DE), DjangoCon Australia, PyCon Japan and Python Pizza.
    • What goes wrong: say a critic accepts the variation PyConDE & PyData under PyCon Germany. The edit adds two lines:
      >     variations:
      >     - PyConDE & PyData
      
      Step 6.3.3 classes the extra variations: line as a stray write. Step 6.3.4 (desk.md:88) then restores the four files and re-applies the same edits, and the line comes back each time. After five tries the desk stops the whole run.
    • The loader accepts the edited file: load_title_mappings reads global and variations independently (utils/tidy_conf/yaml.py:131-133), and PyCon Armenia already has both.
    • Smallest fix: in desk.md:87, after "when the key is new", add "or the variations: line when the key has none yet". In AGENTS.md:86, add "an existing key without a list gains a variations: line after its other fields".

Nits

None.

5. Tests

  • The tests pin the guard behaviour the request relies on: a desk Edit of titles.yml is allowed (test_desk_data_edit_is_allowed, now covering _data/conferences.yml and titles.yml), a subagent Edit is blocked (test_subagent_edit_inside_the_repository_is_blocked), and the new git add / git checkout / tamper git status … ':(exclude)…titles.yml' commands pass (test_desk_procedure_is_allowed). .claude/hooks/desk_guard.py is unchanged, so these pass on the base guard as well. They document existing behaviour; they don't prove a fix. No test covers the procedure text in step 6.3, which is where the finding above sits.
  • Head 6efac3c, REVIEW.md checks through uv (Python 3.11, pandas<2.3):
    • pytest tests/ -q -x -p no:cacheprovider: 2460 passed, 5 skipped, 3 xfailed, 2 xpassed, 251 warnings in 164.13s (0:02:44)
    • uvx ruff@0.4.4 check utils tests: All checks passed!
    • python utils/sort_yaml.py --skip_links: exit 0, Conference data sorting and cleaning completed successfully. git diff --stat -- _data utils was empty.
  • npm ci: exit 0. npm test: Test Suites: 15 passed, 15 total / Tests: 423 passed, 423 total.
  • I did not run the pre-commit set. The pre-commit.ci - pr status was not read.

6. Bounds

  • Route: cloned the repo, fetched refs/pull/504/head, and git rev-parse HEAD printed 6efac3c898db5b5d50673e5817e4a3aad918a9f9, matching the head SHA. The PR metadata and the diff came from the REST API. The first diff request answered HTTP 503 and the retry worked.
  • Read in full: the whole diff; REVIEW.md from main; utils/tidy_conf/titles.py tidy_titles; utils/tidy_conf/yaml.py load_title_mappings; desk.md steps 1–2, "Pushing" and "Tamper check"; the relevant parts of canonical-source-update.yml and merge_data.py. Skimmed: the rest of tests/test_desk_guard.py and titles.yml.
  • Not checked: the outside-repo items the PR lists (~/.desk-guard.json deny_paths, the global CLAUDE.md standing orders).
  • Pre-existing: load_title_mappings also matches forms derived from each variation (with "Conference"/"Conf", spaces, punctuation, years or accents removed; utils/tidy_conf/yaml.py:120-136). So a variation folds more spellings than its literal text. The critic's checks compare only the literal string. For the current data, the step 6.3 rename check catches this after the fact.

Generated by Claude Code

24 of the 53 titles.yml keys hold only `global:` (and some `regexes:`).
Adding a variation there needs a `variations:` line, which step 6.3
counted as a stray write: the desk would restore, reapply, see the line
again and stop the run after five tries. The stray-write rule and
"Data mechanics" now allow that line, placed after the key's other
fields, which is where yaml.dump puts it.

The critic also checks the forms load_title_mappings derives from a
variation (without years, "Conference"/"Conf", spaces or punctuation),
so a variation such as "PyDay Chile 2026" cannot claim the shared name
"PyDay Chile".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sKyvme6kQEAzWQFrJnPCe
@JesperDramsch
JesperDramsch merged commit 3e3e8ca into main Oct 15, 2026
10 checks passed
@JesperDramsch
JesperDramsch deleted the ai-agent/keen-brown-zq8f2b branch October 15, 2026 13:27
@JesperDramsch JesperDramsch mentioned this pull request Oct 15, 2026
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants