Repository navigation
T017: A dir with a TAB or a backslash is listed, indexed and reached as recorded, a stored sub-field reads back as written, and request-handoff refuses a host or container the fence rejects (opensoft/openRepoTools#301) (part of opensoft/openRepoTools#186) - #4
Conversation
…ndexed and reached as recorded, a stored sub-field reads back as it was written, and request-handoff refuses a host or container the binding fence rejects T017 continuation, in opensoft/openRepoTools-code, of the opensoft/openRepoTools branch fix/subfield-misreads-301 at f68030f466ad49c81f02edf8f21a58423a7f8173 (issue opensoft/openRepoTools#301). It carries that branch's own change against e0970a8, the head of fix/dir-space-listing-295 it is stacked on, for the code leg's paths: lanes-edit.sh, lane, lanes and tests/test_subfield_misreads_301.py. Its one other path, docs/README-lanes.md (+1 -1, the lanes row of the reads table naming column 7's escape), belongs to the spec leg and is not in this commit. lanes_rows escapes column 7 as lane-worktrees' porcelain escapes a field and lanes-edit.sh, lane and lanes decode it; payload_subfield reads its payload through ENVIRON instead of awk -v; and request-handoff refuses a host or container that lanes_binding_value_ok rejects. The subjects below are quoted from the originals; a bare #N in them is opensoft/openRepoTools#N. Old-to-new receipt (the original's own non-merge commits): 773a562bccd1 Add the tests that a recorded dir holding a TAB or a backslash, and a requesting host holding a space, are read back as they were written (#301) dd361f3839cf The #301 tests split the listings they read on a newline alone, not on every line boundary Python knows (#301) 430ac8f0804b The lane listing escapes a lane's directory in its seventh column as lane-worktrees' porcelain escapes a field, and lanes-edit.sh, lane and lanes decode it, so a TAB in a recorded dir no longer shifts the row (#301) 647f4511b210 request-handoff refuses a requesting host that lanes_binding_value_ok rejects, on the request path and the --force path alike, before anything is planned or written (#301) ae14da06a53f payload_subfield hands the payload to awk through ENVIRON instead of awk -v, so a stored sub-field holding a backslash reads back as it was written (#301) c0491f1db6f6 Pin what item 2 moves: lane-start reaches a backslash lane's own checkout, lane-handoff writes its dir back byte for byte, and its lifecycle starts again at the new root while the index holds the old rows (#301) 567035fec28b request-handoff refuses a container that lanes_binding_value_ok rejects, on the request path and the --force path alike, before anything is planned or written (#301) 27253fe78a10 The #301 tests pin a carriage return in a recorded dir and the decoders' pass-through arm, and the lanes_rows contract comment says column 7 is escaped (#301) e1d26e135cec The #301 tests now pin the fallback for a dir the encoder cannot escape, where a refused name came from, the free-lane answer before a bad host, and a container of the fence's alphabet (#301) f68030f466ad The #301 tests now pin a capital letter in the binding fence's whole-alphabet row and pin that a free lane's request leaves the published register where it was (#301) Resolutions: none. The patch applied clean, with no offset. Lane: openRepoTools-4 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewer's GuideAPIEscape directory values in listing column 7 and decode them in each row consumer, preserving the tab-separated interface when paths contain control characters.
Pass stored payloads to awk through the environment so sub-field reads preserve literal backslashes.
Refuse handoff requests and forced releases when the requesting host or container fails the binding-value fence, before planning or writing.
TestsAdd regression coverage for escaped listing fields, exact sub-field reads, lifecycle root behavior, and rejected handoff host and container values.
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
|
Sorry @brettheap, you've used your own review budget of 250,000 diff characters for the last 7 days. You can request another review in 6 days and 7 hours by commenting |



What this is
This is the T017 continuation, in this leg (opensoft/openRepoTools-code), of the
opensoft/openRepoToolsbranchfix/subfield-misreads-301atf68030f466ad, for opensoft/openRepoTools#301 (part of opensoft/openRepoTools#186). The original tree and branch stay as the archived original (lane 4's decision, opensoft/openRepoTools#186 comment 6548343086). One commit here,a04c937f1b96, carries it.It carries that branch's own change against
e0970a8, the head offix/dir-space-listing-295it is stacked on (so against the previous PR of this chain), for the code leg's paths:lanes-edit.sh(+147 −3),lane(+30),lanes(+30) and the newtests/test_subfield_misreads_301.py(+1084). Its one other path,docs/README-lanes.md(+1 −1, thelanesrow of the reads table, which names the escape on column 7), is the spec leg's, in the paired PR.lane-startandlane-handoffhave no diff.What was wrong and what changed
What was wrong
Three ways a stored lane sub-field was misread. A TAB in a recorded
dirshifted the listing's tab-separated row, so the lane dropped out ofworktrees --alland the inventory index.payload_subfieldpassed its payload throughawk -v, which expands backslash escapes, so a stored\t,\\,\n,\101or\"read back as something else. Andrequest-handoffwrote the requesting host'sby hostsub-field unquoted and unfenced, somy hostread back asmyand was typed into a session's pane.Found by the independent review of the opensoft/openRepoTools#295 fix, which listed the three under "older problems this branch does not touch"; the third was first raised by that branch's writer. The opensoft/openRepoTools#295 fix causes none of them and makes none worse. This change is stacked on it.
lanes_rowsprints the dir into column 7 of the seventeen-column, TAB-separated row, and every reader splits that row with a tab-IFSread. A TAB inside the dir was one separator more: the row had 18 columns, and each column after the dir arrived one place early. In a sandbox estate (mawk 1.3.4) the lane leftworktrees --alland the inventory index with noUNREADand noPARTIAL(a sync upserted 2 trees instead of 3),worktrees <lane>said 8, and thelanescommand showed the lane's objects as its AGE and printed a falseDEFECT: ... live fork(s) of this lane transcript, because the fork-count column then held the lane's home.lane'sgo_availabletookR_DIRcut at the TAB, which may be a different existing directory.payload_subfieldexpanded backslash escapes. It handed the payload toawk -v pay=..., andawk -vprocesses escapes in the value it is given. A storeddirofback\tslashread back holding a TAB,\\as one backslash,\nas a newline that cut the answer in two,\101and\x41asA,\"as". Every read of a lane's sub-fields goes through it:lane-diranswered a path that does not exist, and the writers filed the lane's lifecycle under$PROJECTS_ROOT/.lane-stateor, foroct\101x, in a sibling directory that belongs to another checkout.worktrees --allstill listed those lanes, because it made the same wrong pass as the writers. A host spelleda\tbalso read back with a TAB.request-handoffwrote its host unquoted and unfenced. WithLANES_HOST='my host'it wrote and pushedby host my host; container none; window none; wait 0s, which the bound session's guard reads back withpayload_subfield, up to its first space, asmy, and types into that session's pane in/handoff --exit requested by .... A;, a"or a control byte would have been typed into the pane too. The forced release wroteforced by <uuid>@<h>/<container>the same way, and its container was just as unfenced:LANES_HOST=plainhost LANES_CONTAINER='a b'withrequest-handoff ... --forceexited 0 and wrote...@plainhost/a b, where the request path refused the same container, and only at the write.write_event'sbinding_subfields_checkfences the sub-fields namedhost,osandcontainer, and neither of these is one.On the real register (brett-wip
e27b539, read on 2026-10-22), no recordeddirholds a backslash, a TAB or a space, and there is oneby host,Eagle. Nothing there moves under any fix below.What changed
row_field_escapeinlanes-edit.shwrites a value withpesc's four escapes, the alphabetlane-worktreesescapes a porcelain field with: a backslash as\\, a TAB as\t, a newline as\n, a carriage return as\r. It is an awk loop over the value's bytes read throughENVIRONunderLC_ALL=C, becauseawk -vwould process escapes and Apple's awk'sgsubmissed non-ASCII bytes. If the encoder prints nothing, column 7 isnoneand the listing says that the dir could not be escaped.row_field_unescape_intodecodes left to right in the shell and keeps a backslash before anything else.lanes-edit.sh,laneandlaneseach carry one (laneandlanesare lane 3's own files, and run underset -euo pipefail; the decoder is pure shell and runs no utility throughcommand).lanes_rowsescapes column 7 at the print only, and only where the dir holds one of the four bytes, so the--dirfilter still compares the stored dir and an ordinary dir costs no process.worktree_rowsdecodes it before it hands the dir on,lane'ssplit_rowdecodes it so thatgo_availabletests and enters the directory the log records, and thelanesrenderer decodes it before it shows it.lanesrow of the reads table (the paired spec PR).payload_subfieldchanges. The payload goes in asPSF_PAYand is read asENVIRON["PSF_PAY"], aslane_sidecar_schema_okalready reads its id.wantandmodestay on-v: they are the callers' own words. The function stays self-contained, because the test cuts it out of the file and runs it alone. Its callers' answers change with it where a stored value holds a backslash, and only there:lane-dir,lane-profile,lane-agent,lane-transcript, both control roots,lane_reconcile,session_start_block,lane_state_follow,holder_is_deadandguard_runread the stored text;lane-startandlane-handoffread the recorded dir as written, with no source change of their own (accepted in lane 3's ruling 5).binding_subfields_add,binding_subfields_checkandpause_subfields_checkjudge the text that is written rather than its expansion, sohost a\101bis no longer passed asaAb: stricter, as Brett Heap accepted with ruling 3.awk -vexpanded now finds its control root beside its checkout. Its records filed under the old root,$PROJECTS_ROOT/.lane-stateor a sibling directory, stay where they are, unread, with no migration (Brett Heap's ruling 3, "Accept, no migration"; no recorded dir on the register holds a backslash).lanes-index syncholds such a lane's rows while the generation read at the new root is below the stored one (insynconly, and only where the stored generation is at least 1; not inreconcile). A test names, and does not fix, the old-root restart intent thatlane_restart_control_rootdoes not find.request-handoffarm holdsLANES_HOST_NAMEandLANES_CONTAINER_NAMEtolanes_binding_value_ok, the fencebinding_subfields_addholds the binding's own host to, once, after the binding is read and before the--forcebranch. A value that fails it is refused with exit 2 and "Nothing was written" on the request path, on the--forcepath and on either one's--dry-run. The refusal says where the value came from (LANES_HOST_SOURCEorLANES_CONTAINER_SOURCE: theLANES_HOSTorLANES_CONTAINERseam, the workstation name inside a container,hostname -s, or the container's ownhostname) and names the setting to put right. Outside every container the container value isnone, which the fence takes. Only therequest-handoffarm changes: no lock function and no call site of one. The cost: a host or a container outside letters, digits,.,_,-and:can never ask.Not in this PR
diratlane-startandlane-handoff, withswapped's TAB-joined row andlane-start's rung 2, which reads the dir bycut -f4; also lane 3's 782 and 842, a TAB inLANES_HOSTorLANES_CONTAINER, whichlanes_host_paircuts at the TAB (it truncates the value and injects nothing). Until then a lane recorded with a TAB in its dir shows the old shift inswapped's row.brief_forandwriters_nameinlane-handoffmatch a tree path throughawk -v, so a path holding a backslash never matches its own writers-file line.profile,windowandhomecan also hold a TAB and shift the row, and a US byte (0x1f) cuts any dir at that byte in every read. Neither is in this PR.lanes-index syncstops holding a lane's rows once the new generation EQUALS the stored one, not only once it passes it (the hold from Derived index: a worktrees table mirroring every lane's #97 inventory under inventory:<Workstation>, nudged by every inventory write, and lanes --worktrees to read it with or without --index openRepoTools#171), so after the first handoff at the new root the next sync removes the old rows while their sidecars stay on disk. Lane 3 said not to file it, because the root move leaves the old records unread and the index mirrorsworktrees --all; a test pins today's behaviour.restart-intentanswers 8 while a lane's intent is still under the old root, becauselane_restart_control_rootlooks only beside the recorded dir and under$PROJECTS_ROOT. Named by a test, not fixed.esc-no-lcallis unkillable on the original's workstation: droppingLC_ALL=Cfromrow_field_escape'sawkcannot change behaviour under mawk 1.3.4, and there was no gawk. Lane 3 ruled that this change gets no test for it; it belongs in a portability run if one is ever added.0andZof the fence's alphabet are unpinned) are not taken.lane-handoff'sawk -v p=sites are lane-handoff's brief_for and writers_name never match a tree path that holds a backslash, because awk -v expands its escapes (from #301's review) openRepoTools#314's.Old to new: the receipt
The original's own non-merge commits in
opensoft/openRepoTools(e0970a8..f68030f), 10 in all, are carried by one commit in this leg,a04c937f1b96. The list is the commit's own body, and it equals the original's non-merge commits read from the chain'srefs/root/ref (checked).The subjects are the original's, byte for byte; a bare
(#N)in them names the root issue.Resolutions
None. The patch applied clean, with no offset.
The pairing
The manual's part of this change (
docs/README-lanes.md, +1 −1) is the commit454f062c13a5onfix/subfield-misreads-301in opensoft/openRepoTools-spec, its own PR, opensoft/openRepoTools-spec#7 (basemain). The code leg's checks read the manual throughOPENREPOTOOLS_SPEC_ROOT:tests/test_repo_hygiene.pyreadsdocs/README-lanes.md(call sites at lines 1373, 1404, 1423, 3139 and 3572 of the code leg'smain; 1404 is the tuple of surfaces that a loop reads throughdoc()) andtests/test_test_roots.pypins which manual a run reads. The code leg's own CI (OPENREPOTOOLS_COMPOSED: '0', no spec leg beside the checkout) skips those checks, so they bind only in a composed run or with the variable set to a spec clone. A search of the manual lines this change touches for the strings those checks pin (the rung-count heading, the two settlement quotes,every lane on this workstation, the exit-code section's two markers andlane-end <lane> --retire) finds none: read, not run. So the two PRs are one change in two repositories, and they land together, as a pair. The code PR goes first, so that the manual never describes behaviour the code lacks: this PR first, then its spec PR, opensoft/openRepoTools-spec#7. The state that order passes through, the code chain's tip beside the spec leg'smain, passed-k test_repo_hygienein the independent review (run (e) under Tests: 223 passed, 14 skipped; that run read the chains' tips, not this commit alone). The other order's state, the spec tip beside the code leg'smain, was not run. I found no check that turns either order red; that is a reading, not a run.Tests
Run by the CODE writer, in a sandbox clone, with
env -i(HOME, XDG_* and TMPDIR inside the sandbox),OPENREPOTOOLS_CODE_ROOTset andOPENREPOTOOLS_COMPOSED=0, as the leg's CI sets it. Each targeted run read this branch's own commit in its own worktree; that commit was8acd8f66374cbefore the message amend, and the amend kept its tree, so the results stand fora04c937f1b96.bash -nonlanes-edit.sh,laneandlanes, at every commit of the chainpy_compileon every changed.pyfile and onlanes-indexrun.sh -k test_subfield_misreads_301shellcheck, over the whole chain (mainto the tip): errors 0 to 0 and warnings 108 to 108 (lane14 to 14,lanes8 to 8); notes up by 3, 2 and 2, all SC1003 on the literal'\'patterns of opensoft/openRepoTools#301's commit.The pair runs below are of the two chains' tips, so they cover this commit with every later commit of its chain; apart from the targeted run above, no run was made at this commit alone. They are lane 4's independent paired review, 2026-10-31 (the letters are the review report's own), with
OPENREPOTOOLS_SPEC_ROOTset to the spec clone shown,env -i,TMPDIR=/tmpand a 54-characterXDG_STATE_HOME.-k test_repo_hygiene5f2995d43893+ spec tip8104f2cf965c-k test_repo_hygiene, baselinemain2a057a6+ specmain9f8b21a-k lane_helpers-k test_repo_hygiene5f2995d43893+ specmain9f8b21aThe pair runs read the chains' tips as they were before the message amend (code
5f2995d43893, spec8104f2cf965c). The amend kept every tree (git difffrom each old commit to its new one is empty), so the runs stand for the amended tips, code2c15aa6613c3and spec430ea20784ac. No failure is new at the tips. Run (d), the manual-reading tests at each branch, was skipped under the review's brief, because none of the five branches' test files reads the manual.The CODE writer's first run of
-k lane_helpersat the chain's tip, with a 212-character run root, gave 5 FAILs in the shell suite (4870 ok, 5 FAIL, 3 skipped), becauserc_tree_idintests/test_lane_helpers.shlacks the 180-character cap thattree_id_forinlanes-edit.shhas, so at that length the two names differ and the planted records are never read; the chain changes neither, and run (c) above, with the 54-character state root, gave 0 FAIL.Not run: the suite at the leg's
mainfor comparison, bash 3.2, macOS and the assembly's composed check; the submodule was not initialized, so 6 tests skip.Test files this commit adds or changes:
tests/test_subfield_misreads_301.py, new (+1084): 118 cases from 23 test functions at the root head, on an estate of eight recorded dirs (a plain one, one with a space, one with a TAB, one with a carriage return, and four with a backslash:\t,\\,\nand an octal\101). Item 1: a row keeps its seventeen columns, column 7 is the dir escaped aspescescapes a field,lanesshows each dir as recorded with noDEFECTline,lane <name> --dry-runreaches each dir, and the listing, the named read and the inventory index keep every lane's trees; a round trip of 226 values runs the encoder against each decoder. Item 2:lane-dirand the writers read each backslash lane as recorded,payload_subfieldalone gives back what was stored, and three pins for ruling 5 and the root move. Item 3: a host or container the fence refuses is never written, on all four invocations, with the setting named; the whole alphabet is written whole.The original's own record, from the root repository, at the root heads and not repeated in this leg: the file was red at
e0970a8(23 failed and 35 passed for phase 1's 58 cases), 118 of 118 atf68030fby lane 3's direct calls, and 355 passed for-k "subfield_misreads_301 or repo_hygiene"throughtests/run.sh. Of lane 4's 20 scripted mutants, 18 were killed;guard-drop-nlis an equivalent, andesc-no-lcallis unkillable on that workstation's mawk (see Not in this PR).Release notes (v1.2.0)
Proposed by lane 4's writer, for lane 3's 785(b) ("the release-notes line should name the stricter gates Brett accepted, as
ae14da0's message does"). Not established: whether lane 3 accepts the line; it has seen only a two-bullet summary of it, not the line itself. Lane 3 ruled (opensoft/openRepoTools#301 comment 6352342484) that each line goes in the PR description under "Release notes (v1.2.0)" and that nodocs/release-notes/v1.2.0.mdis created.A lane whose recorded directory holds a TAB or a backslash is now listed, indexed and reached as recorded.
lane-worktreesescapes a porcelain field, and decoded bylanes,laneandworktrees.payload_subfieldno longer passes it throughawk -v.$PROJECTS_ROOT/.lane-stateor a sibling directory stay there unread, with no migration, since no recorded dir on the register holds a backslash.binding_subfields_add,binding_subfields_checkandpause_subfields_checknow judge the text that is written rather than itsawk -vexpansion, sohost a\101bis no longer passed asaAb(accepted by Brett Heap with ruling 3, "Accept, no migration").request-handoffrefuses a requesting host or container outside letters, digits,.,_,-and:, on the request and--forcepaths and on either one's--dry-run, with exit 2 and "Nothing was written" (lane 3's ruling 2). (Three ways a stored lane sub-field is misread: a TAB in a recorded dir drops the lane from worktrees --all, payload_subfield expands backslash escapes through awk -v, and request-handoff writes its by host sub-field unquoted openRepoTools#301)The line is here, in the code PR of the pair, and only here: the paired spec PR, opensoft/openRepoTools-spec#7, repeats none.
Review
READY, lane 4's independent paired review of both chains, 2026-10-31. It found no MUST and no SHOULD against the commits, and three NITs. Report sha256:
4ac9e5441affc6aeac48e6d73419580f6786440dc0e5dd32722cc40b8070a682. The review read the chains before the message amend (tips5f2995d43893and8104f2cf965c, the same trees as the amended tips).lanes-indexlines 1904 to 1905, docstring only:lane_generation's docstring reads as the full list oflane-state's 10s, but since A lane control root that cannot be searched reads as "no trees", so an inventory sync removes its rows (from #289's review) openRepoTools#291 there is a third, a blocked lookup; optional, and the same text would arise when the root branches land.rc_tree_idlacks the 180-character cap, so the shell suite fails when the run root is longer than about 111 characters, and the shell suite does not setXDG_STATE_HOME, so run (c) left two files outside its run root.The original's recorded review, from the root repository; the comment ids are copied from the root draft, which lists them as the comments of opensoft/openRepoTools#301, and were not re-read (no network):
c0491f1(comment 6368074244): READY TO LAND, after v1.1.0 and after A lane whose recorded dir has a space is missing from worktrees --all and the inventory index: worktree_rows hands lane_control_root the dir unquoted, and payload_subfield cuts it at the first space openRepoTools#295, no MUST and no SHOULD, five NITs (781 to 785), all folded in or ruled.27253fe(6371960135),e1d26e1(6376432313, then 6376868666) andf68030f(6377071275, then 6385185600): each READY TO LAND, no finding open; the two conditions were the root's CI runs 40035107631 and 40040602419, both green on all four jobs.esc-no-lcall(6376200017) are summarised under Tests and Not in this PR.Landing
It lands only on Brett Heap's word, PR by PR; nothing in this text is a landing.
fix/dir-space-listing-295(the code PR for A lane whose recorded dir has a space is missing from worktrees --all and the inventory index: worktree_rows hands lane_control_root the dir unquoted, and payload_subfield cuts it at the first space openRepoTools#295, T017: A lane whose recorded dir holds a space is no longer left out of worktrees --all and the inventory index: worktree_rows hands that dir on quoted where it holds a space (opensoft/openRepoTools#295) (part of opensoft/openRepoTools#186) #3), which lands before it. Lane 3's order for the original, in its review of the finished code (comment 6368074244): A lane whose recorded dir has a space is missing from worktrees --all and the inventory index: worktree_rows hands lane_control_root the dir unquoted, and payload_subfield cuts it at the first space openRepoTools#295 first, then Three ways a stored lane sub-field is misread: a TAB in a recorded dir drops the lane from worktrees --all, payload_subfield expands backslash escapes through awk -v, and request-handoff writes its by host sub-field unquoted openRepoTools#301, retargeted tomain, after v1.1.0.fix/dir-space-listing-295, the branch of T017: A lane whose recorded dir holds a space is no longer left out of worktrees --all and the inventory index: worktree_rows hands that dir on quoted where it holds a space (opensoft/openRepoTools#295) (part of opensoft/openRepoTools#186) #3.mainshowsMerge pull request #1). A merge commit keeps this commit's message and its receipt byte for byte, and the stacked chain lands as built, each PR after the one its base names. A PR stacked on this one is retargeted tomainbefore this PR's branch is deleted: deleting a merged base branch first closes the dependent PR.33ce26dinto the branch at open", with its push and the PR's own CI record:33ce26dis the root's frozenmain, and this leg's ownmainis the base here (the head is the commit above, with nothing merged in).[REFRESH AT PR TIME ...]and[REFRESH AT LAND TIME ...]brackets, which name the root's own CI runs and the root landing; this leg's own checks at open are recorded when the PR is opened (see Tests).Closes #Nline and itsgh pr merge --squash --match-head-commit --body-filesteps, with theland-ort4.shandland-ort3.shnotes: the commit's own message stands in, byte for byte, andCloses #Nbecomes "part of", with no closing keyword.lanes-edit.sh, equal at the base and at the head, and a call-site diff that prints nothing), on git objects only. The md5 isb0809a1e84722f1f518941b0063c926d(65 lines), lane 3's own recorded value, at the leg'smain2a057a6d84e5and at every commit of the chain, this commita04c937f1b96among them. The call-site diff from this PR's base (the commit95866d375199of A lane whose recorded dir has a space is missing from worktrees --all and the inventory index: worktree_rows hands lane_control_root the dir unquoted, and payload_subfield cuts it at the first space openRepoTools#295) to this commit prints no line, out of 150 changed lines oflanes-edit.sh, so the check is not vacuous; frommainto this commit it prints none either, out of 166. The term holds.worktree_rowshunk inherited from A lane whose recorded dir has a space is missing from worktrees --all and the inventory index: worktree_rows hands lane_control_root the dir unquoted, and payload_subfield cuts it at the first space openRepoTools#295 against A named worktree read answers "none" for a lane whose log or register could not be read (from #289's review) openRepoTools#290 (those two branches are not in this chain; A named worktree read answers "none" for a lane whose log or register could not be read (from #289's review) openRepoTools#290's own commit here carries the resolution of the three parts)Lane: openRepoTools-4
Claim: opensoft/openRepoTools#301 (comment 6349895849)
🤖 Generated with Claude Code
Summary by Sourcery
Ensure lane metadata with special characters is preserved end to end and prevent unsafe handoff identities from being written.
Bug Fixes:
Enhancements:
Documentation:
Tests: