S0088-cli-deid-1: redact produces a real de-identified copy, delegated to @cosyte/deid - #48
Merged
Merged
Conversation
…d to @cosyte/deid `cosyte redact` (alias `deid`) was an honest refusal gated on a ground layer that now exists. This wires @cosyte/deid behind the existing seam as an optionalDependency, on the lazy per-format import pattern the breadth parsers use. For ccda, fhir, hl7 and x12, stdout carries the de-identified document serialized exactly as `cosyte fmt` serializes that format, and stderr carries the library's own value-free manifest (category, transform, structural locus, count, disposition, stable code) plus its own published label and version. The CLI adds no policy, no locus map, no transform and no fallback scrub, and asserts no de-identification standard. Anything short of a clean, fully-handled pass emits nothing: - astm, mllp, ncpdp have no adapter there: CLI_NOT_IMPLEMENTED, exit 69. (@cosyte/deid/ncpdp is NCPDP Telecom; this CLI resolves SCRIPT.) - dicom is covered there but its de-identified form is a Part 10 byte stream this text stdout cannot carry: CLI_FORMAT_UNSUPPORTED, exit 65, the CLI's own limit rather than a gap in the library. - any locus the library reports it could not handle: new CLI_DEID_INCOMPLETE, exit 1, with the blocked paths and codes named on stderr. - the library absent from the install: CLI_PARSER_UNAVAILABLE, exit 69, decided before the input is read. The default policy pseudonymizes MRN / account / beneficiary numbers, which is a keyed transform, and a keyed transform with no key context is a fatal there. The CLI holds no key material and adds no key surface, so it keys each invocation with an ephemeral random key and discloses that surrogates are consistent within one output and not stable across runs. No published exit value moved and no existing CLI_* code was renamed. redact stays off the MCP tool surface, and it deliberately does not honour --unsafe-show-values. 641 tests (was 524); coverage on core 97.8 and commands 98.2, both over the 90 gate.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Spec:
work/specs/S0088-cli-deid-1/spec.md(umbrella).cosyte redact <file|->(aliasdeid) was an honest, typed refusal gated on a groundlayer that now exists. This wires
@cosyte/deidbehind the existing seam(
src/core/deid.ts) as anoptionalDependency, on the lazy per-format dynamic-importpattern the breadth parsers already use. The CLI adds no policy, no locus map, no
transform and no fallback scrub: it delegates, or it refuses.
What it does now
For
ccda,fhir,hl7,x12: stdout carries the de-identified document,serialized exactly as
cosyte fmtserializes that format. stderr carries the library'sown value-free manifest (one line per locus: category, transform, structural path,
count, disposition, stable code) plus the library's own published output label and
version. The CLI asserts no de-identification standard of its own.
What it refuses, and why the codes differ
0CLI_DEID_INCOMPLETE(new)1astm,mllp,ncpdp: no adapter thereCLI_NOT_IMPLEMENTED69dicom: covered there, binary result this text stdout cannot carryCLI_FORMAT_UNSUPPORTED65@cosyte/deidabsent from the installCLI_PARSER_UNAVAILABLE69Every non-zero outcome emits nothing on stdout. The two refusals are deliberately
distinct: DICOM is the CLI's own channel limit, not a gap in the library, and blaming
the library for it would be a false attribution.
@cosyte/deid/ncpdpis NCPDPTelecom while this CLI resolves SCRIPT, so the subpath exists and the coverage
does not.
Two things worth a reviewer's attention
adt-a01.hl7andpatient.fhir.jsoncome back clean, but834.edidrives tenblockedloci, so it is now the fail-closed fixture and two synthetic X12/C-CDAfixtures carry the clean path. No filter hides a blocked entry.
numbers, and a keyed transform with no context is a fatal there, never an unkeyed
fallback. The CLI holds no key material and adds no key flag, so it keys each
invocation with an ephemeral random key and discloses on stderr and in the docs
that surrogates are consistent within one output and not stable across runs.
Gates
typecheck,lint,format:check,phi-scan,check:no-emdash,check:no-internal-refs,check:agent-notes,smokeandattwall green. 641 tests(was 524); coverage
core97.8 /commands98.2 against the 90 gate. The packedtarball was installed from a directory outside the repo and both bins run.
No published exit value moved and no existing
CLI_*code was renamed.redactstaysoff the MCP tool surface, and it deliberately does not honour
--unsafe-show-values.