Repository navigation
v0.12.0-alpha #8
nicotem
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
v0.12.0-alpha: pseudonymisation that keeps the coding, and the AI coder name is yours
Pre-release. Install or upgrade with
pip install --upgrade qualcoder-mcp, then restart your MCP host fully so it reloads the tool descriptions. This release raises the dependency floor tomcp>=1.17.0,<2; pip upgrades mcp with the package (see "Upgrading from 0.11.x"). Full details: CHANGELOG, INSTALL, PRIVACY.v0.12 comes out of a ground-truth study of QualCoder 4.0 (master at pinned commit
9bddf17, and the 3.8.2 tag where schema v14 parity matters): seven design dossiers, owner rulings on every question only the owner could answer, then two batches, a flagship and one follow-up, each through a QA gate, a Security gate and re-verification until clean. Three tools are added,pseudonymise_source,set_project_ai_coder_nameandcompare_coders: 70 in the full toolset, 21 incore. Everything schema-dependent is still detected by probing the project database, never by version string.The flagship: pseudonymise a project that is already coded
pseudonymise_sourcereplaces names with pseudonyms in the stored text of the text sources you choose and moves every coding, annotation and case link with the text, all files in one transaction. QualCoder pseudonymises only at import, frompseudonyms.json, and has never had a way to pseudonymise a source that is already coded; this tool is that way.What it does, in plain words:
pseudonyms.json,speakers.jsonorspeaker_regex.jsonis present. Those counts are a deliberately generous heuristic: they report anything a reader would see, including inside a longer word (Thomas_P01) and in any letter case, so they over-report rather than under-report. Read a high count as a list of fields to check, not as a count of names; an entry for a very short name ("Ed") makes them generous and the preview warns about it.shifted(moved, same length),substituted(a coding that was exactly the name and is now exactly the pseudonym, whatever the two lengths),resized(a coding that contained a whole name and changed length only because that name did),snapped(a coding that cut into a name and had that boundary moved: grown to contain the whole pseudonym under the default policy, cut back to exclude it under edit parity),deleted(edit parity only) andclamped(a damaged row whose stored end lay past the end of the text and was pulled back to it). The override,allow_hidden_coder, is required whensnapped,deletedorclampedis non-zero; a shift, a substitution and a resize change no coding decision and need nothing.~/.qualcoder_mcp/pseudonymisation/recording pseudonyms, the replacement spans, the row ids and the old and new offsets of every moved row, enough for a later release to reverse a run exactly. In this release, reversal isrestore_backup.import_text_file(apply_project_pseudonyms=true)applies the project's ownpseudonyms.jsonto a text on the way in, as QualCoder does to every text file it imports. Default off.What it does not do, said plainly because it decides what you may send afterwards:
ai_data/folder: they are neither rewritten nor scanned. QualCoder's own AI search index keeps the previous text until QualCoder reopens the project and re-indexes; its chat history may quote it.pseudonyms.json, the reverse key in plain text at the project root, and it never writes one.Also new
set_project_ai_coder_name) is stored inqualcoder_mcp.jsonbesidedata.qda, so it travels with backups and copies and two hosts agree on it. Reads never ask. Earlier rows keep the name they were written under; the project remembers the names it has used, which is what makes a later comparison between two models possible.QUALCODER_MCP_AI_CODER_NAMEis now this host's declaration, offered as the first quick pick; it never writes a row by itself.merge_codes,delete_code,delete_category,merge_category,restore_backupandprune_backupspreview first and execute only with the token the preview returned, bound to the tool, the effect-deciding arguments, the project and a fingerprint of the rows it would touch. Every cascade preview says whose work is at stake: this project's AI rows, a per-owner breakdown of the rest, hidden coders as a count, and the private notes that would die with their rows.compare_coders. Per code, how much of the text in scope each coder coded, how much they agreed, and two agreement coefficients, both always present:kappa_qualcoder, which reproduces QualCoder's own "Kappa" column expression for expression, andkappa_cohen, the textbook statistic. Read-only, full toolset only.exclude_code_idson the searches drops passages already coded under those codes (QualCoder 4.0's own rule, restricted to the codings you can see); the search and segment tools return cursors that survive a host recycling the server;get_coded_segmentssamples by strategy under a character budget.created: falsewith the existing row and makes no backup; no-op writes answerchanged: false.qualcoder://guidance/methodsresource, and aninstructionsstring in the MCPinitializehandshake. Language, not enforcement: nothing replaces your approval of each suggestion.qualcoder-mcp --version, and a plain-language notice when the server is started by hand in a terminal.What changed
export_frequencies_csvnames visible coders only in its result (the exported file is unchanged), and omits thecoderskey when the coder-visibility table cannot be read.str.lower()in exotic cases only.search_coded_textandget_coded_segmentshave a defined, total order.mcp>=1.17.0,<2: the core toolset callsFastMCP.remove_tool, which does not exist before mcp 1.17.0, so an install at the old floor (>=1.2.0) started with the full surface refused and anAttributeError.Upgrading from 0.11.x
mcpfloor is>=1.17.0,<2.pip install --upgrade qualcoder-mcpupgrades mcp with the package. An environment that cannot move mcp past 1.16.x cannot install 0.12; such an environment could start 0.11 but could not honourQUALCODER_MCP_TOOLSET=core.confirmis inert on the six destructive tools. A call withconfirm=trueand nopreview_tokenreturns the preview with a note; nothing executes. Take the token from the preview and call again with it (the preview'sexecute_withspells the call out).confirmstays in the signatures for this release and is removed in v0.13.AI Coding Assistantkeeps continuity with everything v0.11 wrote; the ask says so when the project already holds rows under a known name.QUALCODER_MCP_AI_CODER_NAMEdeclares, it no longer attributes, andowner=onapply_codingsandimport_text_fileno longer chooses the name.qualcoder_mcp.json, appears in the project folder once a name has been chosen, and in every backup and copy of it, this server's and QualCoder's own. QualCoder ignores it;restore_backupputs back whatever the backup held; deleting it makes the next write ask again.session_idfrom a session-tool response must readcoding_session_id.Known limits
Thomas_Smith) is not counted anywhere in this release. A look-alike letter from another script is out of scope for both the rewrite and the count.Quality gates
Built against QualCoder master at pinned commit 9bddf17 and the 3.8.2 tag. Batch A, Batch B and the flagship each passed a QA gate and a Security gate followed by re-verification rounds (the flagship through five fix rounds), then two follow-ups on the hidden-coder override; six-platform CI (Ubuntu, Windows, macOS on Python 3.10 and 3.13) green on every merge. Suite at the release commit: 3035 passed, 3 skipped, 0 failed, on Python 3.13.5 and 3.11.13, and again under the regenerated
uv.lock. The version canary was checked against a fresh clone and a fresh virtual environment.Not in this release
Planned for v0.13: quote-anchored writes with a fuzzy fallback; a persistent change journal with undo; media region coding; the reverse pseudonymisation run over a manifest; a count of names remaining in the file text beside the residue report, and both readings (wide and whole-word) in that report; rewriting the public part of memos under a separate switch. Support and bug reports: GitHub Issues only. This remains experimental research software; back up your projects (the server also does, before every write).
This discussion was created from the release v0.12.0-alpha.
All reactions