Skip to content

S0318-dicom-7: the second PS3.15 E.3.6 temporal column, the option name that selects it, and MODIFIED - #137

Open
NSchatz wants to merge 3 commits into
mainfrom
sdd/S0318-dicom-7
Open

NSchatz wants to merge 3 commits into
mainfrom
sdd/S0318-dicom-7

Conversation

@NSchatz

@NSchatz NSchatz commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Spec: pipeline/active/S0318-dicom-7/spec.md (umbrella).

PS3.15 2026c section E.3.6 specifies two mutually exclusive Retain Longitudinal
Temporal Information Options and Table E.1-1 gives them separate columns. This
package published one option name carrying the full-dates column only, so the
modified-dates branch was unreachable and the third Value of (0028,0303) was
never written. This adds the second column, the second option name, and the
MODIFIED declaration.

What changed

  • T1. scripts/generate-annex-e.ts emits Rtn. Long. Modif. Dates Opt. as a
    per-attribute action beside the full-dates one instead of counting its
    divergence and discarding it. The header-label guard already covered both
    temporal indices; it now has a mutation test proving it fires on each.
  • T2. RetainLongitudinalTemporalModifiedDates is a second published option
    name. The two temporal options are mutually exclusive and a call naming both
    is refused with the existing INVALID_OPTIONS typed error.
    RetainLongitudinalTemporal keeps its full-dates meaning unchanged.
  • T3. (0028,0303) takes MODIFIED on that branch, on the option set alone,
    with the existing single-value replacement behaviour. (0012,0063) gains a
    Value naming the option, inside LO's 64-character per-Value maximum. A new
    stable code DICOM_DEIDENT_DATES_NOT_TRANSFORMED on report.warnings states
    that the run resolved the column and transformed no date; it is never added to
    the parse warnings, so a { strict: true } parse of the same input is
    unaffected.
  • T4. The released prose, the release note the prose gate reads, the gate's
    own MODIFIED assertion, the CLAUDE.md line and its agent-notes.md anchor
    all move in the same commits as the behaviour. The locked warning-code
    snapshot moves by hand for the one added code. The locked public-export
    snapshot does not move: this change adds a member to an existing union and an
    entry to an existing frozen array, and no exported name.
  • T5. A patch changeset stating the capability with its limitation, and the
    JSDoc on the option surface corrected.

The residual, stated rather than glossed

Section E.3.6 also requires the dates themselves to be modified and the manner
described in a Conformance Statement. Both are permanently the caller's: PS3.2
Annex N scopes a Conformance Statement to a named product and version, which a
library is not. So this library applies the column and writes the declaration,
and the caller performs the transformation. Nothing here claims PS3.15 Annex E
conformance for the Modified Dates Option.

Evidence

  • pnpm test:coverage: 86 files, 1680 passed, 1 todo; src/deident and
    src/dictionary both over their per-directory floors, and vitest.config.ts
    is byte-identical to main.
  • pnpm gen:all && git diff --exit-code src/dictionary/generated: clean.
  • pnpm lint, pnpm typecheck, pnpm format:check, pnpm phi-scan,
    bash scripts/check-no-emdash.sh: all green.
  • Every grader was run against a mutation that breaks its property and went red;
    the mutations and their results are recorded in the spec folder's notes.md.

…he resolver

T1: the Annex E generator emits Rtn. Long. Modif. Dates Opt. as a per-attribute
action beside the full-dates one instead of counting its divergence and
discarding it, and the header-label guard already covers both temporal indices.
T2: RetainLongitudinalTemporalModifiedDates is a second published option name;
the two E.3.6 options are mutually exclusive and a call naming both is refused
with the existing INVALID_OPTIONS typed error, whose message carries option
names and structural constants only.
T3: (0028,0303) takes MODIFIED on that branch, on the option set alone, and
report.warnings carries the new stable DICOM_DEIDENT_DATES_NOT_TRANSFORMED code
saying this library resolved the column and transformed no date. The code is on
the de-identify report and never on the parse warnings, so a strict parse of the
same input is unaffected.

RetainLongitudinalTemporal keeps its full-dates meaning unchanged.
AC-1 and AC-4 resolve every Table E.1-1 row under each temporal option through
the production resolver, with the differing set derived from the generated table
at run time. AC-7 gets the constructed row PS3.15 2026c does not publish, in the
file that already mocks the table, plus the real-table half. AC-2, AC-5, AC-6,
AC-8, AC-9 and AC-10 sweep the temporal declaration over the whole legal option
domain. AC-3, AC-12 and AC-13 pin the refusals and what their messages may
carry. AC-11 sweeps the (0012,0063) per-Value bound over the new domain. AC-14
moves a Table E.1-1 header label and requires the generator to exit non-zero
with no output, with a control proving the mutation route can still go green.

The sweeps that read 512 subsets now derive the domain from the option list and
skip the quarter naming both mutually exclusive E.3.6 options.
…hange refutes

T4. The prose gate asserted the phrase 'never produces it' about MODIFIED on the
README and the limitations page; that claim is false now, so leaving the gate
green by leaving the pages alone would have shipped a false limitation. The
assertion is replaced by two: the condition under which MODIFIED is produced,
and that this library performs no date transformation. Both pages, the cookbook
and the troubleshooting page carry all three states and both option names, and
the pending changeset the gate reads as a release note no longer says the third
state is never produced.

The locked warning-code snapshot moves by hand for the one added code. The
locked public-export snapshot does NOT move and was read rather than
regenerated: this change adds a member to an existing union and an entry to an
existing frozen array, and no exported NAME.

The CLAUDE.md line that called splitting the option a public-surface change
deliberately not made is refuted by the work; it is relocated to the
agent-notes anchor that owns it, with the retraction stated there and the
divergence count deleted rather than re-quoted.

T5. A patch changeset stating the capability with its limitation, and the JSDoc
on the option surface corrected: one name no longer covers both columns.
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.

1 participant