Release notes
Changelog for Flowgraph (@igentify/helix-flowgraph) — npm client, CLI, and local scan bundle published to CodeArtifact.
0.5.26 (2026-09-23)
Align with findings 23: 0.5.23 is adopted; 0.5.24 is a strict superset (+9 unknown → unordered, nothing else moves) and does not touch TypeScript CALLS. 0.5.25 is npm manifest inventory only. Do not adopt 0.5.19 or 0.5.21.
- Ingest (TypeScript) — imported free-function
CALLS—import { fn } from "./mod.js"(includingasaliases) resolves to that file's function node. Class methods (classifyFailures/extractE2eFailuresinsideE2eExecRunner) and script-level calls (the fix-agent harnessforloop) no longer drop the edge. A script-level caller fact is named{filePath}#module. Contract:ts-imported-function-calls. - Call-site multiplicity — Already one
CALLSedge per site (callSiteLine), including twocompareHttp(...)calls in one function. 0.5.26 does not collapse those. - Unchanged on purpose — Java CVE path (inherited Service type-node CALLS, never CALL
DataModel), compact graph, Ask E ordering, Python no type-node fallback, npm manifest fallback. - Ingest pipeline —
ingestPipelineVersion0.5.26 (re-scan required).
0.5.25 (2026-09-10)
- Ingest (npm) — inventory without
node_modules— Whenpackage-lock.jsonis absent, readpackage.jsondependencies/devDependencies. Import matching (USES_EXTERNAL/CALLS_EXTERNAL) no longer requires an installed tree. Manifest versions may be ranges (weaker purls than lockfile pins). Contract:npm-manifest-fallback. - Ingest pipeline —
ingestPipelineVersion0.5.25 (re-scan required).
0.5.24 (2026-09-03)
Align with findings 22: 0.5.23 supersedes 0.5.22 (same CVE 2,925, more provenance, compact graph, Ask E HashSet/access-sessions closed). Do not adopt 0.5.19 or 0.5.21. Remaining 0.5.23 adoption blocker (samples pin 0.5.17 vs 0.5.18) is consumer-side, not ingest.
- Ingest (Java) — Ask E remainder: assembled
patientReports— A JSONListassembled from a JPQL/Collectors.toSetSet with noORDER BYstampsordering: unordered(notunknown). RainbowPatientReportsServiceisSet<PdfReport>→stream().collect(toList()). Page QueryDSLORDER BYstill wins (java-orderby-assembly). Contract:java-assembled-set-list-unordered. real response shape402 → 393 vs 0.5.22 — Those 9 endpoints are opaque primitive/JsonNodelists (List<String>,List<Map>,List<JsonNode>, …). 0.5.22 inferred a Type from callee/List.of; 0.5.23+ keep the collection envelope and do not invent a DTO (java-opaque-json-collection). Gain vs 0.5.18 (293). Not restored.- Unchanged on purpose — Compact
technical-graph.json, inherited Service type-node CALLS (CVE 2,925), never CALLDataModel(Provider), Python no type-node fallback (CALLS +22 vs 0.5.18 is not closed by restoring it),queryParamBindings[], HashSet gettersset/unordered,access-sessionsopaque envelope. - Ingest pipeline —
ingestPipelineVersion0.5.24 (re-scan required).
0.5.23 (2026-09-02)
Align with findings 21: 0.5.22 is eligible for CVE (summed reachability restored vs 0.5.18). Do not adopt 0.5.19 or 0.5.21. Ask E and graph size were the remaining vendor-actionable asks; consumer pin/emit A/B work is not a Helix defect.
- Ingest (Java) — Ask E (honest) — Inherited
@JsonPropertygetters (walkextendsClass) land on{id}. A getter that returnsHashSet/Collectors.toSetiscollectionKind: set+ordering: unordered— notordered(rainbowsupportedClinicalIndicationsis that shape, not@OrderBy).List<JsonNode>(rainbowaccess-sessionsisList, notPage) emits a collection envelope (opaque_collection_payload) and does notREFERENCES_TYPEJsonNode or invent a DTO. Fixture@OrderBypaths stayordered(java-orderby-schema). Schema fields withoutcollectionKindstill derive it fromtypeHint(patientReports→list/unknown). Contracts:java-inherited-json-getter-collection,java-opaque-json-collection. - Graph size — compact
technical-graph.json— Scan artifacts are compact JSON (pretty-print removed). Rainbow pretty ~188–202 MB → ~127 MB with identical data. 0.5.21 provenance (rfp ~2.4× vs 0.5.15) is kept; compact does not return the graph to 0.5.18's ~101 MB. Contract:graph-json-compact. - Unchanged on purpose — Inherited Service type-node CALLS (0.5.22 CVE),
cve-reachability-summed-baseline, never CALLDataModel(Providercollision),queryParamBindings[],@MappedSuperclassneeds source, Python no type-node CALLS fallback (python-no-type-node-fallback). Unexplained Python CALLS +22 vs 0.5.18 is not closed by restoring that fallback. - Ingest pipeline —
ingestPipelineVersion0.5.23 (re-scan required).
0.5.22 (2026-09-02)
Restore 0.5.18 CVE reachability on the ingest graph without dropping 0.5.21 provenance, method-level CALLS, queryParamBindings[], or the Python type-node guard. Benchmark is 0.5.18, not 0.5.20.
- Ingest (Java) — RELEASE BLOCKER FIX: inherited Service type-node CALLS — When
field.m()resolves to a method on a parent (sampleService.findById→GuardedOperations.findById), ingest still CALLS that method (0.5.21) and the field's Service/Repository/Class type node (the 0.5.18 type-fallback set). 0.5.21 method-only CALLS left those classes with almost no inbound CALLS (rainbow Service type-node CALLS 201 → 5), soopencsv/postgresql/spring-boot-starter-webhit zero endpoints. Own-methodfield.m()stays method-only — a blanket companion over-reported those purls (72 → 295). Still never CALLS aDataModel(jakartaProvidercollision) and does not apply tothis/superor Python. Contract:java-service-type-call-companion. - Query — summed CVE contract —
contract:cve-reachability-summed-baselinerecords a summedimpactedEndpointstotal over a purl inventory and asserts that dropping Service type-node CALLS zeros the sum (the 0.5.21 failure mode a per-hop assertion could not see). Keepcve-reachability-via-repo-type-calls. @MappedSuperclassneeds source — Extra-parent pull (0.5.21) is inert when the superclass exists only as.classwith no-sources.jar. Check outigentify-common-jas a scan root (npm run ingest:igentifyincludes it) or publish Maven sources. Not a package-name allowlist.- Ask E residuals (unchanged, honest) — Rainbow
GET …/access-sessionsisList<JsonNode>(no DTO to provenance).supportedClinicalIndicationsis a getter returningHashSet(no@OrderBy); fixture@OrderBypaths stayordered(java-orderby-schema). - Ingest pipeline —
ingestPipelineVersion0.5.22 (re-scan required).
0.5.21 (2026-09-02)
Close findings 19 Ask 4–6 and query-param → predicate binding — without regressing 0.5.20 CALLS / CVE reachability.
- Ingest (Java) —
@MappedSuperclassoutside the scanned tree — Unresolvedextendspull superclass source from sibling Java--roots,HELIX_JAVA_SOURCE_ROOTS, or Maven*-sources.jar(HELIX_MAVEN_LOCAL/~/.m2). Extra files are symbols-only (no CALLS from those paths). Contract:java-mapped-superclass-external. - Ingest (Java) —
queryParamBindings[]— QueryDSL, JPQL:param, and Criteria predicates map filter params totable.column+ operator onApiEndpoint. Contract:java-query-param-bindings. - Ingest (Java) — Ask E: assembled / paged
{id}collections —@OrderBystampsordering: orderedon entity schema fields and assembled DTO paths; unshapedResponseEntity<?>infers from hop-2 CALLS and callee source (opaque facades). Contracts:java-orderby-schema,java-unshaped-infer. - Ingest (Python) — no type-node CALLS fallback — A missing method on a type name no longer CALLS the class/type node (Java-only fallback remains). Contract:
python-no-type-node-fallback. - Ingest pipeline —
ingestPipelineVersion0.5.21 (re-scan required).
0.5.20 (2026-08-31)
Restore 0.5.18 call resolution on Spring Data repository fields while keeping 0.5.19 provenance (findings 18 Ask 1–3). Do not adopt 0.5.19 for Security Analyst / CVE reachability.
- Ingest (Java) — RELEASE BLOCKER FIX: plain iface extending a generic base —
interface AuditRepository extends RainbowBaseRepository<Audit, Long>again resolvesauditRepository.save(…): walkextendsfor methods, and fall back to the Repository/Interface/Class type node when the callee is missing from the index (Spring Data derived queries). Still never falls back to aDataModel(keeps thejakarta.inject.Provider↔ entityProvidercollision fix). Also records interfaceextendsin the symbol index (extends_interfaces). Contracts:java-repo-iface-extends-generic,java-generic-field-calls. - Query — CVE reachability contract for the severed hop —
contract:cve-reachability-via-repo-type-callsasserts that a service→Repository type-nodeCALLSedge is what keeps a persistence-layer purl walking to endpoints; dropping that edge zeros the count (the 0.5.19 failure mode). - Residual (Ask 4) —
@MappedSuperclassprojection still requires the superclass to be in the scanned roots. Rainbow’sAbstractTimestampEntitylives inigentify-commonsand is not present as source under rainbow alone; in-repo MappedSuperclasses continue to project (contract:java-mapped-superclass). - Ingest pipeline —
ingestPipelineVersion0.5.20 (re-scan required).
0.5.19 (2026-08-31)
Fix the 0.5.18 generic-receiver CALLS regression (findings 17 Ask 1) and close the remaining Ask 2–6 residuals — without regressing provenance / Page envelope / CVE impact.
- Ingest (Java) — restore generic field-receiver CALLS —
resolveCallTargetstrips generics/packages on field types (RainbowBaseRepository<E,I>→RainbowBaseRepository) and never falls back to a type node id for known fields (keeps thejakarta.inject.Provider↔ entityProvidercollision fix). New fixture +contract:java-generic-field-calls. - Ingest (TypeScript) — no self-referential response edges — Unshaped / inline
res.jsonno longer emitREFERENCES_TYPE[response]to the handler itself (contract:ts-no-self-ref-response). - Ingest (Java) —
@MappedSuperclassprojection — Superclass schema fields (e.g.created_at) project onto entity subclasses (contract:java-mapped-superclass). - Ingest (Java) — Jackson residuals — Shape-only
@JsonFormat(shape=STRING)emitsjsonFormat; class-level@JsonIncludepropagates to fields;included: "ALWAYS"is written explicitly;List<Long>carrieselementTypeHint/scalarType(contract:java-json-format-shape,java-json-include-class,java-collection-element-type). - Ingest (Java) — derivation predicates — Only emit
predicate[]when the lambda is balanced; truncated fragments are omitted (honestexpressionPreviewremains). - Ingest pipeline —
ingestPipelineVersion0.5.19 (re-scan required).
0.5.18 (2026-08-31)
Close findings 16 Ask 1 (self-referential REFERENCES_TYPE) and provenance asks A–F for assembled single-entity reads — without regressing 0.5.11–0.5.17 CALLS / REFERENCES_TYPE / Page envelope / DTO-wrap ordering.
- Ingest (Java) — no self-referential response shapes — Never emit
REFERENCES_TYPE[response]wherefromId === toId. Truly unshaped returns (e.g.ResponseEntity<Void>) emit no response edge instead of pointing at the handler Method. - Ingest (Java) — Ask A: structured
derivationon computed/@Transient getters —@Transientmethods join the JSON surface; provenance always emits an entry and attaches{ op, overCollection, predicate?, expressionPreview }for commonallMatch/anyMatch/count/sum/mapshapes (residue =expression). - Ingest (Java) — Ask B: Jackson serialization contract —
schemaFieldsgainjsonName,included,unwrapped,views,enumValueMap; enums with@JsonValue+CONST("serialized")populate the map (order-independent enrich pass). - Ingest (Java) — Ask C:
joinPaththrough JPA metadata — Nested association walks carry authoritativejoinPath[](joinColumn/relationKind/ table); name-match overlay is taggedname_match_fallbackand prefers join metadata when present. - Ingest (Java) — Ask D: scalar type +
@JsonFormat—scalarTypeandjsonFormaton schema fields and mirrored onto provenance entries. - Ingest (Java) — Ask E / F — Assembled collection ordering continues via 0.5.16 producers + source propagation; new
responseAssemblyComplexity(distinctEntities,maxNestingDepth,collectionFieldCount) on endpoints with provenance. - Contracts —
java-no-self-ref-response,java-computed-derivation,java-jackson-contract,java-join-path,java-scalar-json-format,java-assembly-complexity. - Ingest pipeline —
ingestPipelineVersion0.5.18 (re-scan required).
0.5.17 (2026-08-27)
Ship a release-note contract regression suite and 95% coverage gate, and inventory Go modules from go.sum.
- Quality — contract catalog — Every documented product promise has a stable
contract:<id>test.scripts/check-contract-coverage.mjsfails the gate when an ID has no matchingtest("contract:<id> …"). - Quality —
npm run test:gate— Workspace tests + contracts + 95% lines/statements/functions/branches onshared/src,ingest/src,catalog/src. Publish, pre-push, and GitHub Actions all run the gate. - Ingest (Go) —
go.suminventory — Lockfile parser mergesgo.sumtransitive modules intoExternalDependencypurls alongsidego.moddirects. - CLI — npm bin entry — Process entry detects npm
.binshims (helix-flowgraph,helix-ingest) so the published package CLI still runs. - npm client —
filterGraphByRepos/filterGraphByEndpoints(and related graph-filter helpers) are exported fromclient.ts. - Ingest pipeline —
ingestPipelineVersion0.5.17 (re-scan required for Gogo.sumpurls).
0.5.16 (2026-08-27)
Close the tuple/paged assembled-view gap for collection ordering (findings 15 Ask 4) and add a cross-cutting ingest regression suite — without regressing 0.5.11–0.5.15 CALLS / REFERENCES_TYPE / DTO-wrap behavior.
Ingest (Java) — Page/Slice
content[]envelope — When a handler returnsResponseEntity<Page<T>>(orSlice<T>), field provenance paths are prefixed undercontent.*to match the served JSON shape, with acontentlist envelope entry.Ingest (Java) — ORDER BY through QueryDSL/service assembly — Detect
.orderBy(on reachable producers; when any producer carries ORDER BY, stampordering: orderedon all response collection paths (nested tuple/paged arrays included). DTO nested-class walk now recurses through view types classified asMethodanchors.Ingest (Java) — unshaped
ResponseEntityinfer — When the controller declares bareResponseEntity<?>, infer the shaped payload from direct service CALLS return types (fixes assembled views with no generic on the handler).Ingest — regression suite — New
ingestRegressionSuite.test.tsguards signature-key sanitization, TS CALLS strip/simplify, Java collection metadata + Page envelope, DTO-wrap ordering propagation, and Python union encoding across the 0.5.9→0.5.16 arc.Ingest pipeline —
ingestPipelineVersion0.5.16 (re-scan required).Spot-checks (0.5.16 ingest):
Check Result Fixture GET /api/users/view-filtercontent.reportsForPatient.patientReportscollectionKind: list,ordering: orderedFixture GET /api/users/{sampleId}/access-sessionsresponseFieldProvenance > 0 (inferred from service) Fixture GET /api/users/cards/:idownedAccountsunordered(unchanged vs 0.5.15)Ingest regression suite 132 tests pass
0.5.15 (2026-08-27)
Close the 0.5.14 residuals: escape | in signature keys, balance rest-param types, and propagate collection ordering onto assembled-view response paths (findings 14) — without regressing CALLS / REFERENCES_TYPE.
Ingest — signature keys never embed
|—sanitizeSignatureTypeTokenreplaces union|withOr(e.g. Pythonstr | None→strOrNone) so ids stay parseable asrepo:<r>|method:<sig>. Applies at the shared signature-key builders (Java/Python/TS).Ingest (TypeScript) — rest params with parenthesized unions —
simplifyTypeNamestrips[]and unwraps(…)before union erasure, so...parts: (string | undefined)[]becomesstring(not the malformedmakeTestId((string)). RestoresTranslationFilesUploader→makeTestId.Ingest (Java) — collection ordering on assembled-view responses — Wire DTO→entity name-match overlay, copy
collectionKind/orderingfrom entity source fields onto response paths (e.g. viewListwrapping entitySet→unordered), deepen producer CALLS one hop through services, and apply handler-body ordering cues even whencollectionKindwas unset.Ingest pipeline —
ingestPipelineVersion0.5.15 (re-scan required).Spot-checks (0.5.15 ingest):
Check Result makeTestIdidmakeTestId(string)+ 1 inbound CALLShooks → useAuthedAction3 (unchanged) ng-access REFERENCES_TYPE134 / 94 response Python get_graphql_response(…, str | None)…(str,str,strOrNone)— no extra|in method idFixture GET /api/users/cards/:idownedAccountscollectionKind: set,ordering: unordered
0.5.14 (2026-08-27)
Restore the 12 TypeScript CALLS edges lost after signature-keying (findings 13) — without regressing 0.5.13 response shapes or Java/Python behavior.
Ingest (TypeScript) — bare-name strip handles nested / malformed param types —
stripSignatureSuffixnow matches balanced trailing(…)(so()=>voidand(token)=>Promise<_>strip correctly) and falls back to the first(when type text is unbalanced. Fixesthis.m()callers likeStartupMiddleware.useand callees likeaddKeysToLang, plus hook→hook edges such asuseIndications→useAuthedAction.Ingest (TypeScript) —
simplifyTypeNamefor function types — Callback / arrow param types collapse tofn(and rest...is no longer treated as a path separator), so signature keys stay balanced and resolvable.Ingest pipeline —
ingestPipelineVersion0.5.14 (re-scan required for restored TSCALLS).Spot-checks (0.5.14 ingest):
Check Result StartupMiddleware.use→saveDebugFilesrestored addGlobalKeysMapping→addKeysToLangrestored useIndications/useWorkflows/useUsers→useAuthedActionrestored (3) ng-access-service REFERENCES_TYPE134 (unchanged vs 0.5.13)
0.5.13 (2026-08-26)
Restore TypeScript response-shape linkage after 0.5.12 signature-keying (findings 12) — no change to Java/Python gains.
Ingest (TypeScript) —
REFERENCES_TYPEwith signature-keyed Method nodes — Apply the same bareClass.methodindex shim used for CALLS to the handler response-shape builder. Fixes 276 → 0 regression: TS endpoints again link to response DTOs / unshaped service returns (93 of 116endpoints on rainbow).Ingest (TypeScript) — method lookup —
findMethodDeclarationstrips signature suffixes so handler bodies are read correctly when facts are keyed asClass.method(Types…).Ingest pipeline —
ingestPipelineVersion0.5.13 (re-scan required for TS response shapes).Spot-check on ng-access-service (0.5.13 ingest): 134
REFERENCES_TYPEedges (94 response-labelled), 47/56 endpoints with response shape (83.9%). Java/Python paths unchanged in this release.
0.5.12 (2026-08-26)
Close the last self-edge fabrications, signature-key Python/TS, fix Python coverage rows, and surface collection ordering metadata (findings 11) — without touching CVE reachability.
Ingest (Python) — no bare-name self-edges — A class method whose body calls a bare same-name global/builtin (
ConversionTable.sorted→ builtinsorted) no longer emits a self-CALLSloop. Module-level recursion andself.m()recursion are kept.Ingest (Java) — same-arity overload self-loops — When a self-
CALLSwould land on a method that has another same-arity overload, edge the sibling instead (e.g.overrideDisplayLabel(AlternativeMutationName)→overrideDisplayLabel(String)). Rainbow self-CALLS46 → 37 (stricter than 0.5.11; the 9 drops were same-arity fabrications).Ingest (Python + TypeScript) — signature-keyed Method nodes — Method ids/names include parameter types (annotations when present, else
_), matching the Java 0.5.9 shape. TS call indexes also resolve under the bareClass.methodkey so existing CALLS wiring is preserved.Ingest —
symbolCoverageByEcosystem— Always emit a row for ecosystems present in the scan (language-hintedpypi/npm/maven/golang), including zeros. PyPI inventory also readspyproject.toml/requirements*.txtwhen no poetry/Pipfile lock exists.Ingest (Java) — collection ordering provenance — On
schemaFieldsandresponseFieldProvenance:collectionKind(list/set/map/array),ordering(ordered/unordered/unknown),elementTypeHint, and optionalproducers[](accessor method id/name,hasOrderBy, JPQL preview) plus handler-body cues (Collectors.toSet,sorted,LinkedHashSet, …).Query —
query impact— Unchanged (sibling-overload walk from 0.5.10 preserved).Ingest pipeline —
ingestPipelineVersion0.5.12 (re-scan required).Verified on rainbow (fresh 0.5.12 scan):
0.5.11 0.5.12 query impactjava-jwt / commons-lang3 / opencsv / pdfbox373 / 214 / 72 / 58 same self-recursive CALLS46 37 provider_dispatch33 33 security_guardTRIGGERS2984 2984 response fields with collectionKind0 955
0.5.11 (2026-08-24)
Tighten self-CALLS without touching CVE reachability (findings 10).
Ingest — self-
CALLSprecision — Keep genuine recursion (countdown,self.m()). Stop fabricating self-loops for:super.m()→ resolve and edge the parent method viaEXTENDS(never mapsupertothis).field.m()/ other resolved receivers → edge the callee type; no same-file method-name fallback when the receiver is a known enclosing-class field (fixeswireMockServer.start()→WireMockStub.start()).- Python
super().m()and non-selfreceivers — receiver-based rule (Python nodes remain unsigned; no overload-collapse heuristic applied there).
Query —
query impact— Unchanged; sibling-overload walk from 0.5.10 preserved.Ingest (Java) —
Optional.maplambdaprovider_dispatchunchanged from 0.5.10.Docs —
USES_EXTERNALon npm/TS (since 0.5.9) — When a package gets a symbol-levelCALLS_EXTERNAL, the duplicate module-levelUSES_EXTERNALis intentionally omitted (dedup). TS corpus:USES_EXTERNAL507 → 309;CALLS_EXTERNAL+ symbol substrate grew — not a reachability regression.Ingest pipeline —
ingestPipelineVersion0.5.11 (re-scan for self-edge cleanup).Verified on rainbow (fresh scan with 0.5.11 ingest):
0.5.10 0.5.11 query impactjava-jwt / commons-lang3 / opencsv / pdfbox373 / 214 / 72 / 58 same self-recursive CALLS416 46 provider_dispatch33 33 security_guardTRIGGERS2984 2984
0.5.10 (2026-08-24)
Restore query impact after overload split, keep genuine recursive CALLS, and close the Optional.map provider-dispatch gap (findings 9).
Query —
query impact— Reverse walk also enqueues sibling overloads (sameClass.methodwithout parameter suffix) so redistributedCALLSafter signature-keyed Method nodes still reach endpoints. Fixes the 0.5.9 reachability loss (rainbow pdfbox 58→29, commons-lang3 214→195).Ingest — self-
CALLS— Suppress only collapse artifacts (unsigned multi-member overload sets). Genuine recursion is kept (Javacountdown; Python/TS single-symbol self-calls). Replaces the 0.5.9 blanket self-edge ban that dropped real recursion.Ingest (Java) — provider dispatch through
Optional/Stream.map—Optional.ofNullable(facade.getProvider()).map(p → p.method(…))emitsCALLSwithconfidenceReason: provider_dispatch(filed SamplesCardSearchService lambda form). ChainedgetProvider().method(…)unchanged. JDKmap/flatMapno longer early-returns before the lambda pass when the JDK method itself is unresolved.Ingest —
symbolCoverageByEcosystem— Emit a row for every ecosystem present in lockfile inventory, includingsymbols: 0(no empty{}when deps exist; ecosystem parsed from purl when missing on the node).Ingest pipeline —
ingestPipelineVersion0.5.10 (re-scan required for lambda provider edges + coverage rows; impact sibling walk also helps existing 0.5.9 graphs at query time).Verified on rainbow (fresh 0.5.10 scan):
0.5.9 (broken) 0.5.10 query impactpdfbox endpoints29 58 commons-lang3 195 214 opencsv 72 72 java-jwt 373 373 self-recursive CALLS0 (blanket ban) 416 (genuine + super.same-name)provider_dispatch28 33 USES_EXTERNAL1965 1965 (unchanged) security_guardTRIGGERS2984 2984
0.5.9 (2026-08-24)
Method overload fidelity, npm external-symbol substrate, and runtime provider dispatch (findings 8).
Ingest (Java) — signature-keyed Method/Service nodes — Method facts are keyed by erased parameter types (
UserService.findById(String)), notType.namealone. Overload sets become distinct nodes with correctsignature/sourcePreview;CALLSresolves by arity. Self-referentialCALLSedges from overload collapse are suppressed (was 537 fabricated on rainbow 0.5.7).Ingest (Java) — provider dispatch — Chained
facade.getProvider().method(…)calls emitCALLSto matchingIMPLEMENTStarget methods (confidenceReason: provider_dispatch), closing the reverse-walk gap through runtime-resolved beans (same class as 0.5.4/0.5.6 security-guard linking, scoped to the resolved interface).Ingest (TypeScript) — npm
ExternalSymbolsubstrate — Named imports, destructuringrequire, and bare identifier calls registerExternalSymbol+CONTAINS_SYMBOL/CALLS_EXTERNAL(parity path with Maven). Per-scansymbolCoverageByEcosystemontechnical-graph.jsonandmanifest.jsonreports deps vs symbols per ecosystem (honest downgrade when symbol grain is unavailable).Ingest pipeline —
ingestPipelineVersion0.5.9 (re-scan required for method IDs, provider edges, and npm symbol coverage).Verified:
- rainbow — 0 self-recursive
CALLS; 264 overload sets with >1 node;RiskSummaryProvider.getCardRiskSummary→ 3 distinct overload/interface nodes (was 1 collapsed); 28provider_dispatchedges; 8 security-guard sources / 2984security_guardTRIGGERS unchanged. - ng-access-service — npm symbol coverage 61/458 (13.3%) vs ~1.3% fleet baseline in findings 8 (named-import + import-registration path); Maven unchanged.
- rainbow — 0 self-recursive
0.5.8 (2026-08-11)
Java schema-relationship metadata for DB-backed join synthesis, plus dataflow provenance residuals from 0.5.7.
Ingest (Java) — association join metadata — On each
schemaFields[]row withassociation: true, emit structured join facts already parsed from JPA annotations:relationKind(ManyToOne|OneToMany|OneToOne|ManyToMany),owning,joinColumn,referencedColumn,mappedBy, andjoinTable({ table, joinColumn, inverseJoinColumn }or null). Secondary:@Id→id: true; physicalcolumnfrom@Column(name=…)/@JoinColumn(name=…)(fallback = field name).Ingest (Java) —
DataModel.tableNamefix —@Table(name=…)extraction uses top-level annotation arguments only, so nested@Index(name=…)/@UniqueConstraint(name=…)no longer overwrite the real table name (0.5.7 bug on Sample/Patient/Account/Results and peers).Ingest (Java) — no silent provenance drops — Jackson
@JsonProperty/@JsonViewmethods without aget/isprefix (e.g.hasAllResultUploads,approveable) are included; interface default methods merge onto implementors. Empty read-sets emittransform: unresolved(never omitted). Getter calls inside default methods (getResultsUploads()) map to entity field sources when present →computed.Ingest pipeline —
ingestPipelineVersion0.5.8 (re-scan required for correctedtableName+ association metadata).Verified:
- rainbow — Sample/Patient/Account/Results
tableName→samples/patients/accounts/results(0*_idx/*_uniquemis-binds); 198/198 association fields carryrelationKind; Sample.patient→ManyToOne/owning/joinColumn: patient_id; Sample.results→OneToMany/mappedBy: sample; 15/18ManyToManycarryjoinTable. - rainbow
GET /samples/{sampleId:.+}—hasAllResultUploads/approveable/haveResultsConfirmedpresent (computedwith sources); graph-wideunresolvedtransform now emitted (was absent in 0.5.7). - authentication-service — 74/74 response shapes; association + column metadata populate.
- rainbow — Sample/Patient/Account/Results
0.5.7 (2026-08-06)
Java dataflow provenance for migration tooling: field→source links, request-input surface, light handler branches.
Ingest (Java) — Ask 1 field provenance — Shaped
REFERENCES_TYPEresponses carrydata.fieldProvenance[](also on theApiEndpointnode): each response field path → source entity/DTO field(s) withtransform(passthrough|renamed|computed|constant|unresolved),directCopy,sources[], andEXTRACTED/INFERRED/AMBIGUOUSconfidence. Nested association paths (patient.identityNumber),@Transient/@Formula→computed, Jackson@JsonPropertygetters →computedwith read-set. Unresolved fields are labelled, never dropped.Ingest (Java) — Ask 2 request surface — Per endpoint:
requestParams[](path/query/body/modelAttribute/pageable/ …) withname,typeHint,required,defaultValue, and local enum values (enumStatus: local|unresolvedfor JAR enums).@ModelAttributeDTOs expand to query fields. EmitsREFERENCES_TYPErequestBody/requestQuerywhen the type resolves.Ingest (Java) — Ask 3 branches —
handlerBranches[]on endpoints:if/switch/ternaryconditions that contain returns (condition preview + line).Ingest (Java) — Local
enumdeclarations becomeTypenodes (constants asschemaFields) for enum-value recovery.Ingest pipeline —
ingestPipelineVersion0.5.7 (re-scan required). Existing endpoint→handler→service→repository→entityCALLSchains and security-guard edges remain additive.Verified:
- rainbow
GET /samples/{sampleId:.+}—sampleType/patient.identityNumber/patient.dateOfBirth→ entity passthrough;dueDateInDays→computed(readssampleDate); 246/457 shaped endpoints carry provenance. - rainbow
GET /samples/search—SampleFilter→ query fieldssearch/gender(enumStatus: unresolvedJAR) /clinicalIndication(local enum values) +Pageable. - authentication-service (second Java repo) — 74/74 response shapes; provenance + requestParams populate.
- rainbow
0.5.6 (2026-08-04)
Tighten Spring Security guard detection (fixes 0.5.5 ingest over-fire) and harden query impact fan-out.
Ingest (Java) —
isSecurityLibraryPurlno longer matchesspring-security-core/spring-security-web(used app-wide viaSecurityContextHolder, etc.). Guard tagging fromCALLS_EXTERNAL/USES_EXTERNALis Method-only (not Controller/Service class anchors). Filters (doFilter/doFilterInternal) and JWT-named verifiers unchanged.Query —
query impact— Security-guard fan-out requires an auth-library seed or an explicit--node-idthat already emitssecurity_guardTRIGGERS (no longer “any TRIGGERS source”). During a library CVE walk, only direct users of the seed may fan theirsecurity_guardTRIGGERS (stops over-tagged neighbors from claiming the API).Ingest pipeline —
ingestPipelineVersion0.5.6 (re-scan required for corrected guard edges).Verified on rainbow (fresh 0.5.6 scan, same HEAD as findings 5):
fresh 0.5.5 (broken) fresh 0.5.6 edges 68,056 40,454 (matches 0.5.4) security_guardTRIGGERS16,785 2,984 guard TRIGGERS-sources 168 (144 false) 8 (filters + JWT verifiers) java-jwtendpoints402 373 opencsvendpoints199 72 pdfboxendpoints196 58 commons-lang3endpoints— 214
0.5.5 (2026-08-04)
Scope Spring Security guard fan-out in query impact (fixes 0.5.4 over-report on non-auth deps).
Query —
query impact— OutboundTRIGGERSand reverseROUTE_THENedges withconfidenceReason: security_guardfan out to secured endpoints only when the impact seed is an auth library (java-jwt,jwks-rsa,jjwt,spring-security, … viaisSecurityLibraryPurl) or the seed node itself is aTRIGGERSsource (AOP advice / filternodeId). Utility CVEs (opencsv, pdfbox, commons-lang3) no longer transit a guard god-node and claim every secured endpoint.npm client — exports
isSecurityLibraryPurl.No re-ingest required for this fix — works on existing 0.5.4+ graphs (query-side only).
ingestPipelineVersionremains 0.5.4.Verified on rainbow (same graph as 0.5.4 spike):
purl 0.5.4 (broken) 0.5.5 java-jwt373 373 (kept) opencsv375 72 pdfbox375 58 commons-lang3393 214
0.5.4 (2026-08-04)
Spring Security / JWT verifier → endpoint linking for Java CVE blast radius (filter-chain gap after 0.5.3).
Ingest (Java) — Security guards (
doFilter/doFilterInternal, JWT verifier methods, and methods withCALLS_EXTERNALto java-jwt / jwks-rsa / jjwt / …) emitTRIGGERS→ securedApiEndpoints and reverse-friendlyROUTE_THENendpoint → guard (confidenceReason: security_guard).Query —
query impact— Walks outboundTRIGGERSfrom visited nodes so guard/aspect CVEs reach the endpoints they protect (e.g.pkg:maven/com.auth0/java-jwt@…→ hundreds of endpoints on rainbow, not inventory-only app nodes).Ingest pipeline —
ingestPipelineVersion0.5.4.Example:
bashnpx @igentify/helix-flowgraph@0.5.4 query impact \ --purl 'pkg:maven/com.auth0/java-jwt@4.4.0' --local
0.5.3 (2026-08-03)
Java CVE blast radius: wire Maven inventory into app code via usage edges.
Ingest (Java) —
USES_EXTERNAL/CALLS_EXTERNALfrom imports and type-receiver calls (JWT.require(…)) topkg:maven/…ExternalDependency/ExternalSymbolnodes (artifact-token matching so shared groupIds likeorg.springframeworkdo not false-claim every import).Query —
query impact— Java purls now returnimpactedAppNodesand, when usage sits on a handler chain,impactedEndpoints(not inventory-only seeds).Ingest pipeline —
ingestPipelineVersion0.5.3.Example:
bashnpx @igentify/helix-flowgraph@0.5.3 query impact \ --purl 'pkg:maven/org.apache.commons/commons-lang3@3.18.0' --local
0.5.2 (2026-08-03)
Java CVE reachability: Maven/Gradle dependency inventory populates purlIndex for query impact (customer findings after 0.5.1).
Ingest (Java) — Parses root
pom.xml,build.gradle/build.gradle.kts, and optionalgradle.lockfileintoExternalDependencynodes withpkg:maven/group/artifact@version(property /dependencyManagement/strictly/ Spring Boot version heuristics; nomvn/gradleshell-out).Query —
query impact— Java technical scans no longer leavepurlIndexempty;--purl pkg:maven/…resolves a seed (usage edges into app code are still npm/Go/Python-only — inventory join works for Security Analyst CVE matching).Ingest pipeline —
ingestPipelineVersion0.5.2.Example:
bashnpx @igentify/helix-flowgraph@0.5.2 scan start --local --technical-only \ --repo-path ~/code/igentify/rainbow-service npx @igentify/helix-flowgraph@0.5.2 query impact \ --purl 'pkg:maven/com.auth0/java-jwt@4.4.0' --local
0.5.1 (2026-08-03)
Accessible FE↔BE gateway prefix → backend repo mapping (customer Java findings). Same patch as 0.4.4 on the 0.4.x line.
CLI / npm client —
--service-map/--backend-service-map— Pass gateway prefixes at scan time, e.g.--service-map '/api/v1/rainbow=rainbow-service', or a JSON file ({ "services": { "/api/v1/rainbow": "rainbow-service" } }). Also discoversbackendServiceRepos.jsonnext to--out/ repo roots, andHELIX_BACKEND_SERVICE_MAP.Ingest — unmapped prefixes — Lists distinct unknown prefixes in the ingest log (with suggested
--service-mapflags) and writesreports/unmapped-service-prefixes.jsonl.Ingest — no hardcoded rainbow→integration — Removed the silent
/api/v1/rainbow→ng-integration-serviceoverride that yieldedmatched=0for rainbow-ui + rainbow-service.Ingest (Java) —
ResponseEntity<T>generic recovery from source text when tree-sitter drops nested generics; unresolved wiringscopeprefers the injected type (detail) over the declaring site.Ingest pipeline —
ingestPipelineVersion0.5.1.Example:
bashnpx @igentify/helix-flowgraph@0.5.1 scan start --local --technical-only \ --repo-path ~/code/igentify/rainbow-service \ --repo-path ~/code/igentify/rainbow-ui \ --service-map '/api/v1/rainbow=rainbow-service'
0.4.4 (2026-08-03)
Same FE↔BE service-map patch as 0.5.1, for teams staying on the 0.4.x line while 0.5.x is under test.
CLI / npm client —
--service-map/--backend-service-map, discovered overlay files,HELIX_BACKEND_SERVICE_MAP.Ingest — unmapped prefixes listed in logs +
reports/unmapped-service-prefixes.jsonl.Ingest — no hardcoded rainbow→integration override.
Ingest (Java) —
ResponseEntitygeneric source-text fallback; unresolvedscopeby injected type.Ingest pipeline —
ingestPipelineVersion0.4.4.Example:
bashnpx @igentify/helix-flowgraph@0.4.4 scan start --local --technical-only \ --repo-path ~/code/igentify/rainbow-service \ --repo-path ~/code/igentify/rainbow-ui \ --service-map '/api/v1/rainbow=rainbow-service'
0.5.0 (2026-08-03)
Agent- and architect-facing query surface: edge provenance, path/explain, per-scan digest, MCP, and a query-first Cursor skill — without RAG or free-form NL search.
Graph — edge confidence — Every edge in
technical-graph.jsoncarriesdata.confidence:EXTRACTED— explicit in source / AST (calls, handlers, DI with call site, …)INFERRED— Helix-resolved (FE↔BECALLS_REMOTE, featureUSES, exact cross-langTOUCHES, …)AMBIGUOUS— multi-match bridges or alias-basedTOUCHES- Optional
data.confidenceReason(e.g.multi_match,alias,feature_bind,service_prefix_path). - Requires a new scan — graphs built before 0.5.0 have no confidence tags until re-ingest.
CLI / Query API — path & explain — Deterministic graph walks (no embeddings):
query path <from> <to>→GET/POST /query/path— shortest path (BFS); prefer full node ids;--feature-id/--endpointto disambiguate short names; fails closed when ambiguous (returns candidates, does not guess).query explain <node>→GET/POST /query/explain— node metadata + incident edges with confidence.--format textprints a readable hop / neighbour listing (JSON remains default).
CLI / ingest — scan digest — Ingest writes
reports/GRAPH_REPORT.md(also listed inmanifest.jsonartifacts).query report --localregenerates it from the graph +fe-be-bridge.jsonl/unresolved-wiring.jsonl/ cross-lang joins: totals, confidence histogram, unmatched FE↔BE reasons, unresolved wiring by category, highest-degree (“god”) nodes, suggested questions.MCP —
helix-flowgraph mcp [--local] [--transport stdio|http] [--port 8788]— thin JSON-RPC tools over the same helpers:list_features,explain_node,shortest_path,query_impact,query_repos,list_unbridged,graph_report. Stdio for Cursor/Claude MCP config; HTTPPOST /mcpfor shared local use. Not a vector store.Agents — Cursor skill
.cursor/skills/helix-query-first/SKILL.md+ requestable rule.cursor/rules/helix-query-first.mdc: prefer features → explain/path/impact/report before grepping source.UI — Edge inspector shows confidence tag + short legend; drawer title for
CALLS_REMOTE.npm client — exports
queryPath,queryExplain,computeShortestPath,computeExplainNode,formatPathText,formatExplainText,buildScanGraphReportMarkdown,buildScanGraphReportFromDir,runHelixMcpServer,EdgeConfidence/edgeConfidenceFromData, and related types.Ingest pipeline —
ingestPipelineVersion0.5.0.Examples:
bashnpx @igentify/helix-flowgraph query explain 'repo:…|ApiEndpoint:…' --local --format text npx @igentify/helix-flowgraph query path '<ApiClientCall-id>' '<Method-id>' --local --format text npx @igentify/helix-flowgraph query report --local npx @igentify/helix-flowgraph mcp --local
0.4.3 (2026-08-03)
- Ingest (Java) — HTTP response shapes from handler return types (
ResponseEntity<T>,List<T>,Page<T>, …):REFERENCES_TYPEwithresponse/responseShape/responseTypeName, feeding the samehttpShapeCoverageas TypeScript (rainbow 465/471 ≈ 98.7%; authentication-service 74/74). - Ingest (Java) — Security aspects: expand named
@Pointcutrefs and link@Aroundadvice via@annotation/@withinto endpoints already carrying matchingROUTE_THENlayers (TRIGGERS); remaining pointcuts stay in unresolved. - Ingest — Unresolved wiring rows carry
scope: "app" | "framework"(JDK/Spring/AWS/test paths vs app types); ingest log printsscope app=… framework=…. - Ingest (Java) — Spring Data repository detection generalized to
*BaseRepository/JpaSpecificationExecutor(no product-specific base-class name required). - Validation — Second Spring service (
authentication-service) + joint rainbow +ng-integration-service(3TOUCHES) recorded for generalization / B2 proof. - Ingest pipeline —
ingestPipelineVersion0.4.3.
0.4.2 (2026-08-03)
- Ingest (Java) — Persistence hints without product hardcoding:
@QueryJPQL/native, QueryDSLQEntityidentifiers, andJdbcTemplateSQL strings link to knownDataModel/ table names viaUSES_DATA_MODEL; unresolved hints go toreports/unresolved-wiring.jsonl. - CLI / npm client — Absolute paths for under-reporting artifacts: ingest prints full paths for unresolved wiring and questionable HTTP;
startLocalScan/scan start --localreturningestErrorsPath, and when presentunresolvedWiringPath/questionableHttpPath; those reports are listed inmanifest.jsonartifacts. - Ingest pipeline —
ingestPipelineVersion0.4.2.
0.4.1 (2026-08-03)
- Ingest — Java / Spring–Jakarta plugin (
--language java):@RestController/ mapping annotations →ApiEndpoint+HANDLED_BY; constructor / Lombok DI →USES; JPA /RainbowBaseRepository→USES_DATA_MODEL; security annotations →ROUTE_THEN; Spring events →TRIGGERS/FIRES. Unresolved DI/JPA/AOP written toreports/unresolved-wiring.jsonlwith ingest log counts. - Ingest — Cross-language join pass emits
TOUCHESbetween matching endpoints / entities / tables across repos (exact normalized names; optional emptyshared/crossLanguageAliases.jsonfor operator renames). - Ingest — FE↔BE bridge: unmatched reason breakdown in the ingest log; additional HTTP client instance prefixes for access UI gateways.
- Graph — Class-declaration
DataModelfacts keep theDataModelnode label (no longer collapsed toType). - Ingest pipeline —
ingestPipelineVersion0.4.1.
0.4.0 (2026-07-15)
- CVE reachability — Lockfile inventory (
ExternalDependencynodes withpurl,scope, ecosystem) from npm, PyPI, and Go lockfiles across BE and FE repos;purlIndexontechnical-graph.json. - Ingest — Tiered external usage edges: symbol-tier
CALLS_EXTERNAL→ExternalSymbol, module-tierUSES_EXTERNAL→ExternalDependency;CONTAINS_SYMBOLlinks package → symbol;data.captureTieron edges. - Query API / CLI —
POST /query/impactandquery impact --purl <purl> [--symbols a,b]reverse-walk to impactedApiEndpoints, FE surfaces (Hook, ApiClientCall, Component), Features, and app nodes withcaptureSummary(symbol vs module hits). OptionalvulnerableSymbolsfilters OSV symbol granularity. - npm client — exports
computeImpactAnalysis,buildPurl,buildPurlIndex,externalDependencyNodeId,LockfilePackageRecord, and related helpers from@helix/sharedbundle. - Ingest pipeline —
ingestPipelineVersion0.4.0.
0.3.4 (2026-07-15)
- Ingest — Fix plain
res.json(…)response tracing (previously onlyres.status(…).json(…)); traceawait this.service.foo()in thejson()argument and via local variables. - Ingest — Emit
REFERENCES_TYPEresponseedges for untyped returns:data.responseShape(shaped|unshaped),data.responseTypeName, target serviceMethodwhen no DTO node resolves. - Graph / manifest — Per-scan
httpShapeCoverageontechnical-graph.jsonandmanifest.json(apiEndpointsWithResponseShape / apiEndpointsTotal).
0.3.3 (2026-07-14)
- CLI —
--format asciiuses numbered participant columns, a legend, and a── Hops ──caption block so deep flows stay readable in narrow terminals (~80 cols) instead of ultra-wide name headers.
0.3.2 (2026-07-14)
- CLI —
query repo=… --format mermaid|text|ascii: Mermaid source (mermaid), monospace ASCII sequence diagram (ascii), or participant/message text listing (text).--endpointand optional--componentselect the entry point. - CLI breaking —
--format asciinow renders a lifeline diagram; the previous text listing moved to--format text. - npm client — exports
buildSequenceAscii,buildSequenceText,renderFlowDiagram,enumerateSequenceMessages, plus sharedgraphFiltersandsequenceDiagramhelpers aligned with the Flowgraph UI.
0.3.1 (2026-07-13)
- Ingest —
REFERENCES_TYPEHTTP shapes: route-levelvalidateDto(Dto, 'body'|'query')on middleware args (not onlyreq.body asin handlers). - Ingest — Response links via ts-morph
getReturnType()on service/use-case callees behindres.json(result);Document→DataModelname resolution. - Graph — Each HTTP-shape edge sets
labelanddata.httpShapeRole(requestBody|requestQuery|response). - Docs — npm-client section updated for local validation and HTTP contract edges.
0.3.0 (2026-07-13)
- Ingest language plugins — TypeScript (ts-morph, unchanged behavior), Go, and Python (tree-sitter WASM). Auto-detect from repo markers or force with
--language/--languages repoKey=idon scan andstartLocalScan. - Manifest — optional
ingestPluginper repo entry (typescript|go|python);ingestPipelineVersionnow 0.3.0 when graph extraction changes. - npm client —
detectIngestPlugin,IngestPluginId, and language flags onstartLocalScan/scan start --local. - Flow diagram CLI —
query repo=… --format mermaid|text|asciirenders the same sequence view as the Flowgraph UI (mermaid, monospaceascii) or a text listing (text);--endpoint(and optional--componentfor FE) select the entry point. Default--format jsonunchanged. - Bundled publish — tree-sitter WASM deps included; Go/Python smoke tests in publish pipeline.
0.2.8 (2026-07-13)
- Ingest — DTO class anchors graph as
Typenodes (notMethod), soREFERENCES_TYPEtargets match schema-node filters. - Ingest — Type aliases included in handler HTTP ref resolution (
handlerTypeRefs). - Docs — npm-client section on
REFERENCES_TYPE/ HTTP request–response shapes.
0.2.7 (2026-07-12)
- Ingest — New
REFERENCES_TYPEedges fromApiEndpointto request/response types (requestBody,requestQuery,response) in local and cloud scans. - npm client — Bundled ingest with
handlerTypeRefspipeline (initial publish; DTO labeling fixed in 0.2.8).
0.2.6 (2026-07-12)
- Client —
query repo=a,b,c --local(and cloud) returns cross-repoCALLS_REMOTEedges when both FE and BE repos are in the query (getSubgraphForReposfix).
0.2.5 (2026-07-09)
- CLI / library — Stderr
--technical-onlywarning explaining what still runs, what is skipped, and impact on features / AI artifacts. - Docs — Local vs cloud scan scope and
--technical-onlybehavior on docs site.
0.2.4 (2026-07-09)
- Ingest — Call-graph delta:
buildClassImplementsIndex(interface-typed DI → concrete impl, e.g.ISignService→SignService); minor P0a tuning. No material edge-count change vs 0.2.3 on typical ng-* scans. - Publish — Integration test fix:
list --completeduses--from 2026-01-01so CI does not fail when no scans finished “today”.
0.2.3 (2026-07-08)
- Ingest — Interface / type modeling:
InterfaceandTypenodes,IMPLEMENTS/ interfaceEXTENDS, type-alias resolution. - Ingest — Class inheritance (P0a/P0b): class anchors, class
EXTENDS, inherited method resolution through DI properties. - Bundle — Removed unused Claude Agent SDK (~209 MB); tarball ~5.7 MB (was ~68 MB in 0.2.2).
- Includes — Query scan pinning from 0.2.1.
0.2.2 (2026-07-08)
- Ingest — Same inheritance fixes as above (first npm release carrying P0a/P0b after 0.2.1).
- Includes —
?scanId=/?workspaceId=query pinning (0.2.1). - Bundle — Fat local-scan tarball (~68 MB unpacked ~256 MB; Claude Agent SDK still bundled).
0.2.1 (2026-07-08)
- Query API + client —
scanIdandworkspaceIdon all/query/*routes; CLI--scan-id, libraryqueryFeatures({ scanId }), etc. - Workflow — Pin branch/pre-feature scans:
scan startwith commit → query with returnedscanId. - Deployed — Graph Query Lambda + docs site updated.
0.2.0 (2026-07-08)
- Major line —
npx/npm installsufficient for local and cloud; no helix-flowgraph clone required. - Bundle — Fat package: client CLI + bundled
helix-ingest+helix-agent+features/YAML. - CLI — Removed
HELIX_MONOREPO_ROOTfrom user-facing help; default scan output./scans. - Publish —
scripts/test-npx-outside-repo.mjsruns install + local + cloud smoke from/tmp.
0.1.x (2026-07-08)
Early releases: query-only slim client (~60 KB) → cloud scan orchestration → monorepo-dependent local scan → fat bundle preview (0.1.21). Patch versions 0.1.1–0.1.4, 0.1.8–0.1.9, 0.1.12–0.1.15, 0.1.17 were incremental client fixes with sparse notes; 0.1.17 was never published to CodeArtifact.