Skip to content

Move rationale essays out of source comments into docs/ and write the comment rule into CONTRIBUTING - #233

Merged
emartynov merged 3 commits into
mainfrom
feature/issue-209-rationale-docs
Oct 15, 2026
Merged

emartynov merged 3 commits into
mainfrom
feature/issue-209-rationale-docs

Conversation

@emartynov

Copy link
Copy Markdown
Contributor

What changed

Comment density was the problem #209 names: 261 comment lines against 462 total in Iban.kt, 120 against 360 in gradle.yml, and the dominant pattern was "why we did not do X" prose carrying issue numbers — the String receiver rationale repeated on three declarations, 16 lines of it for one line of typealias, a page each on the Dokka block and the linuxArm64Test block, and workflow history that git blame already holds.

The reasoning itself was worth keeping, so it moved rather than being deleted. Four new pages under docs/:

Page Holds
docs/209-api-design-notes.md Public-surface decisions: the String receivers, Iban.parse next to Iban.invoke, the JVM-only IBAN typealias, ASCII-only reject-not-normalize, the sealed Malformed.Kind, the midnight-UTC Instant encoding, the defensive knownCountryCodes copy
docs/209-implementation-notes.md Internals: eager pretty, the cached country index, ofValidated vs invoke, validate's check ordering, toPlain's fast path, the pre-sized addSpaces builder, the ASCII case-bit helpers, Modulo97's running remainder
docs/209-build-script-notes.md explicitApi, abiValidation and the duplicated android dump, versioned API docs, signPublications, verifyPublicationTargets, the whole linuxArm64Test emulator block guard by guard, the consumer Kotlin floor, the TestBalloon pin and root-script declaration
docs/209-ci-workflow-notes.md gradle.yml (concurrency, matrix shape, build scans, the JUnit reporting inputs, the two failure-diff steps), publish.yml (the tag guard, the release environment, attestation staging, the docs archive), registry-sync.yml and the two registry scripts, ios-interop-verify.yml, scorecard.yml, cache-konan, dependabot.yml

What stays in the code is the KDoc contract plus a one-line pointer where the choice is not obvious from the signature. Issue numbers are gone from code comments — including the three outside the files #209 lists (build.gradle.kts, IbanTest.kt, MalformedKindTest.kt); the doc pages carry them instead, as the existing docs/ write-ups already do.

CONTRIBUTING.md gains a Comments and documentation section stating the rule so this does not accumulate again: KDoc on a public declaration states the contract only, an inline comment explains one non-obvious line in one or two sentences, anything longer is a doc page, and issue numbers belong in the pull request and git log.

Against the issue's "done when": no source, build or workflow file now carries a comment block longer than roughly five lines that is not a KDoc contract description. What remains over five lines is the Apache licence header, KDoc contract blocks with their @param/@return tags, the two registry scripts' usage headers (their --help text, effectively), the generated /* AD */ markers in CountryCodesData.kt, and three six-to-ten-line file-purpose headers that each end in a pointer.

Out of scope and left alone: the README's duplicate of the String receiver rationale (#212 owns the README), the docs/ index and title-first file names (#214), and whether linuxArm64Test should exist at all (#218) — its block is documented as it stands, with a note pointing at that question.

Verification

Run locally on a Linux container, with an Android SDK installed per CLAUDE.md:

  • ./gradlew jvmTest — passed. (Three retries were needed first: Maven Central returned HTTP 429 to the container, not a test failure.)
  • ./gradlew ktfmtCheck — passed, after ./gradlew ktfmtFormat reflowed the trimmed KDoc.
  • ./gradlew checkKotlinAbi — passed with the committed dumps untouched, which is the check that matters here: this is a comment-only change to the code, so kiban/api/jvm/kiban.api, kiban/api/android/kiban.api and kiban.klib.api had to come back byte-identical, and they did. (apiCheck is the standalone validator's task name and no longer exists in this build; checkKotlinAbi replaced it in Move off the standalone binary-compatibility-validator onto the Kotlin Gradle Plugin's built-in ABI validation #182.)
  • All five workflow files plus dependabot.yml and cache-konan/action.yml re-parsed as YAML after editing.
  • Every relative link in the four new pages, CONTRIBUTING.md and the new CHANGELOG.md entry resolves to a file that exists.

No tests were added, and none should be: the change removes and relocates comments. It adds no behaviour, no declaration and no API; the existing suite passing unchanged, together with the unchanged ABI dumps, is what establishes that nothing but comments moved.

Not verified locally: the Apple-target tests, the XCFramework and samples/swift-console (no Xcode on a Linux container), and jsTest/wasmJsTest (the sandbox proxy breaks Karma's dependency fetch). Neither is plausibly affected by a comment change, but CI's full matrix is the real check. The two scripts/*.main.kts --self-check runs that registry-sync.yml performs could not run either — the kotlin CLI is not installed here — so the edits there were kept strictly inside block comments.

A CHANGELOG.md entry went into the Documentation group of the unreleased section.

Closes #209


Generated by Claude Code

claude added 3 commits October 9, 2026 06:35
Comment density had reached 261 comment lines against 462 total in
Iban.kt and 120 against 360 in gradle.yml, most of it "why we did not
do X" prose carrying issue numbers, repeated across declarations and
duplicated in the README.

The reasoning is worth keeping, so it moved rather than being deleted:

* docs/209-api-design-notes.md - the public-surface decisions (String
  receivers, Iban.parse, the IBAN typealias, ASCII-only rejection, the
  sealed Kind, the Instant encoding).
* docs/209-implementation-notes.md - the internal ones (eager pretty,
  the cached country index, validate's check order, the allocation-free
  fold, the ASCII helpers).
* docs/209-build-script-notes.md - the Gradle configuration, including
  the linuxArm64Test emulator block, abiValidation and the consumer
  Kotlin floor.
* docs/209-ci-workflow-notes.md - the workflows, the composite action,
  dependabot and the two registry scripts.

What stays in the code is the KDoc contract plus a one-line pointer
where the choice is not obvious from the signature. Issue numbers are
gone from code comments; the doc pages carry them instead.

CONTRIBUTING.md now states the rule so this does not accumulate again:
KDoc states the contract, an inline comment explains one non-obvious
line in one or two sentences, anything longer is a doc page.

No API, behaviour or message change; the API dumps are untouched.

Co-Authored-By: Claude  <noreply@anthropic.com>
…ionale-docs

# Conflicts:
#	CHANGELOG.md
#	kiban/src/commonMain/kotlin/nl/bijdorpstudio/kiban/CountryCodes.kt
#	kiban/src/commonMain/kotlin/nl/bijdorpstudio/kiban/Iban.kt
…ionale-docs

# Conflicts:
#	.github/workflows/gradle.yml
#	kiban/build.gradle.kts
@emartynov
emartynov merged commit eca01ad into main Oct 15, 2026
20 checks passed
@emartynov
emartynov deleted the feature/issue-209-rationale-docs branch October 15, 2026 19:27
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.

Move rationale essays out of source comments into docs/ and write the comment rule into CONTRIBUTING

2 participants