knowledge: 2 insights — tokio teardown after aborted tasks (abort then await before delete), trailing separator under realpath (macOS resolves file/, glibc/musl ENOTDIR) (2 new pages, 7 amended, 1 folded to #225, 26 plan-gaps retired as local-layer) - #228
Open
choiyounggi wants to merge 1 commit into
Open
choiyounggi wants to merge 1 commit into
choiyounggi wants to merge 1 commit into
Conversation
…d tasks, trailing separator under realpath (1 folded to #225, 26 plan-gaps retired as local-layer)
This was referenced Sep 28, 2026
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.
Knowledge flush — 3 insight(s) (29 claimed rows: 2 ingested as new pages, 1 folded onto open PR #225, 26 plan-gap rows retired as local-layer)
Run id
20260928-134800-34863(inherited from the auto-flush parent; lock held under that id). Branchknowledge/choiyounggi-20260928-134840offorigin/main5986311.Verified best-practice
1. Deleting a resource that spawned async tasks still use —
testing-async-teardown-after-aborted-tasks(NEW, confidence: verified)Claim. In a test (or shutdown path) that spawned tokio tasks, put teardown on the single path every outcome takes (record the outcome, tear down, then assert /
?), and inside teardown abort and await every reachableJoinHandlebefore deleting the directory/socket; keepDroponly as the net for failures before the runtime/handles exist.Sources checked (fetched this run).
.awaitpoint"; "calls toJoinHandle::abortjust schedule the task for cancellation, and will return before the cancellation has completed".JoinHandleawait"; dropping a handle "detaches the associated task";aborton a startedspawn_blockingtask "will not have any effect".Result<T, E>!").Local reproduction (this run, scratch crate under the project's
.claude/tmp/, removed afterwards). tokio 1.53.1 from the cargo registry cache, cargo 1.98.0, macOS,multi_threadruntime with 4 workers; a spawned task loopscreate_dir_all→write→yield_nowwith ~400 µs of non-yielding work per iteration.abort()thenremove_dir_allimmediately: directory left behind 148/200 runs.abort(),awaitthe handle, thenremove_dir_all: 0/200.The candidate's "why" said an aborted task "still gets one more poll"; the docs say cancellation is scheduled and a running task continues to its next
.await— the page uses the documented wording, and the reproduction confirms the effect the candidate observed.Field evidence (from the harvested row, not re-run). handfish crew-run task t3-swap-flake:
RunHandle::shutdownaborted every task but awaited only the bus; leftover.crew-test/<uuid>dirs 1/3 (pass path) and 2/3, 3/3 (panic path) before, 0/12 after.2. A path ending in a separator passed to realpath / canonicalize —
platforms-filesystems-trailing-separator-under-realpath(NEW, confidence: verified)Claim. When a path that may end in
/(or/.) is resolved throughrealpath(3)and the result decides containment or file-vs-directory, check the raw string before resolving and decide by intent (reject, or requireis_dir()after resolving); the resolver'sENOTDIRis platform-dependent.Sources checked (fetched this run).
[ENOTDIR]"… ends with one or more trailing characters and the last pathname component names an existing file that is neither a directory nor a symbolic link to a directory".realpathfunction on Unix and theCreateFileandGetFinalPathNameByHandlefunctions on Windows"..components, and trailing separators"; "Path::joinandPathBuf::pushalso disregard trailing slashes".Local reproduction (this run). libc
realpathcalled through Pythonctypeson a regular fileout/report.md:out/report.md/→Ok(out/report.md),out/report.md/.→Ok(out/report.md).python:3-slim(glibc 2.41, docker): both →errno 20 Not a directory.python:3-alpine(musl, docker): both →errno 20 Not a directory.base.join("out/report.md/")keeps the slash (ends_with(is_separator) == true),std::fs::canonicalize→Ok(…/out/report.md);Path::new("out/report.md/") == Path::new("out/report.md")→true.The
/.suffix divergence (missed byends_with(is_separator)) was found in the reproduction and added as an edge row.Field evidence (from the harvested row). handfish t3-swap-flake: containment accepted
…/out/report.md/on macOS; guard pinned by testpath_entry_with_trailing_slash_is_missing_file_not_found; an auditor's mutation removing the guard turned it red.3. Kotlin top-level helper shadowed by a receiver member inside
apply {}— FOLDED onto open PR #225Claim. Name fixture helpers so they cannot collide with members of the fakes they are used against, or call them outside the
applyblock. Already carried by PR #225's pagebackend-java-kotlin-implicit-receiver-shadowing-in-scope-functions(sources: kotlinlang overload-resolution spec, scope-functions docs; verified there). The candidate's unique addition — asuspendmember called insiderunTestcompiles cleanly and fails only at runtime with the fake's stub error (NotImplementedError) — was not in that page (its edge row covered only the non-coroutine caller, which is a compile error). Pushed as one commit to that PR's branch:0708082onknowledge/choiyounggi-20260928-082803(one edge row + one field-evidence line:CalendarViewModelTest, 3 failures →trip()renamedmakeTrip()→ 14/14). Not re-ingested here.Existing-layer check
Pages read: testing-async-async-testing, testing-data-artifact-leakage-from-a-suite, testing-data-test-data-and-isolation, security-input-validation-at-trust-boundaries, infrastructure-config-path-valued-config, platforms-tools-bsd-vs-gnu-cli, platforms-filesystems-paths-case-and-line-endings, platforms-filesystems-unix-domain-socket-path-length
Also read:
INDEX.md,wiki/testing/index.md,wiki/platforms/index.md,wiki/security/index.md,wiki/backend/index.md(routing),templates/page.md,AGENTS.mdformat rules,log.mdtail.Semantic dedupe (
wiki_search, k=5):Dropin the async case. Verdict: new page, with an edge row on artifact-leakage and on async-testing pointing to it. No conflicting directive found: the new page extends "teardown that runs on failure too" with the ordering the runtime requires.wiki/forJoinHandle|abort()|tokio,canonicalize|realpath|trailing (slash|separator)|path traversal|ENOTDIR: no page owns either trigger (hits were unrelated mentions in frontend/node/testing-quality pages, bsd-vs-gnu-cli'sreadlink -frow, unix-domain-socket-path-length's "realpath can lengthen a path" row).Merged vs created: 2 pages created; 0 merged. Amended: async-testing (edge row), artifact-leakage-from-a-suite (edge row + related), validation-at-trust-boundaries (edge row + related), bsd-vs-gnu-cli (edge row + related), test-data-and-isolation (related), paths-case-and-line-endings (related), path-valued-config (related). Domain indexes: testing (async section), platforms (filesystems section).
log.md: 2 ingest lines.Deferred back-link:
async-testing.md'srelated:line is rewritten by open PR #226 — not touched here (the new page links to async-testing one way; the edge row on async-testing carries the inline[id]link). Expected merge overlap:wiki/testing/index.mdasync section — PR #226 also appends one row afterasync-testing; both rows are keepable, adjacent-line conflict only.Lint run on the checkout (this branch):
node scripts/wiki-structure-checks.js wiki→pages: 355, indexes: 13, findings: 0(after removing arelated:id that pointed at PR #226's not-yet-merged page — that cross-link is deferred until #226 lands);node scripts/wiki-lint-prohibitions.js→directives: 79, compliant: 79, violations: 0;node scripts/wiki-lint-model-era.js wiki→ 6 pre-existingrevalidaterows on other pages, none on the two new ones. Banned-qualifier grep on both new pages: no hits. Body lines: 74 and 76 (≤120).Open-PR check
Open
knowledge/*heads (listed withgh pr list --search "head:knowledge/", thengit fetch+git diff --stat origin/main origin/<head> -- wiki/):knowledge/choiyounggi-20260928-103056— platforms/toolchains native-addon page + back-links. No overlap with any candidate. Toucheswiki/platforms/index.md(toolchains section) — different section from my filesystems row.knowledge/choiyounggi-20260928-092831— testing/asynctransient-state-behind-a-controlled-gate(parking a transient state behind a test-controlled gate; tokio sources) + edits toasync-testing.md(Do-this table row +related:) andtesting/index.md. Read the page: it covers observing mid-run state before a finisher wipes it, not tearing down after tasks; its edge row on theJoinHandleawait guarantee is the post-wipe ordering point, which my page cites for the opposite direction (delete after the await). Insight 1 verdict: new (related-linked both ways from my side only; theirrelated:line is theirs to rewrite). Insight 2/3: no overlap.knowledge/choiyounggi-20260928-082803— 12 insights incl.backend/java/kotlin/implicit-receiver-shadowing-in-scope-functions. Insight 3 verdict: fold — same trigger and directive; pushed the uniquerunTest/suspendedge row + second field evidence to that branch (commit0708082). Insight 1/2: no overlap (its testing pages are fake-intersection-observer and alias-table-contract-tests).knowledge/choiyounggi-20260927-220735— 15 insights (gitignore, jq, shell redirection, hook fields, fake-server, shared-helper invariant, WebMCP retirements). No overlap with any candidate; toucheswiki/platforms/index.md(shells/tools sections) andwiki/testing/index.md(strategy/quality sections), none of the pages I amended.Per-candidate: insight 1 → new; insight 2 → new; insight 3 → fold (#225).
Routing decision
testing/async/teardown-after-aborted-tasks.md(idtesting-async-teardown-after-aborted-tasks,applies_to: [rust, general]). Categoryasync("testing async code") fits;data(artifact leakage) is the symptom page and now links here. General layer: the directive names tokio's documented primitives, no repository files.platforms/filesystems/trailing-separator-under-realpath.md(idplatforms-filesystems-trailing-separator-under-realpath,applies_to: [general, rust]).platformsowns "OS-level differences that break code moving between macOS, Linux";filesystemsis the existing category (no new category). Notsecurity/inputbecause the mechanism is a libc divergence that also bites non-security file/dir checks; security's page gets the edge row instead. Notbackendbecause backend has no rust subtree and the divergence is language-independent (reproduced through ctypes and Rust).backend/java/kotlin/implicit-receiver-shadowing-in-scope-functions.md.No new category.
Local-layer candidates
26
plan-gaprows (allwiki-plan Phase B found no wiki page for this decision), each a one-repository design record whose directive names that repo's own files, constants, RFC numbers or Gradle pins; retired as local-layer, none ingested here. Runwiki-ingestinside each project if the team wants them in itswiki-local/:seagrass (linkly), task t177-numeric-guard-predicate — 8 rows:
NumericPredicate+NUMERIC_PREDICATE_KINDStable relocation →wiki-local/backend/dsl/numeric-predicate-ast-and-reserved-words.mdand→wiki-local/backend/dsl/numeric-predicate-inside-and.mdAnd-loop dispatch →wiki-local/backend/dsl/numeric-predicate-runtime-truth-table.mdwiki-local/qa/rfc-process/draft-rfc-updates-chain.mdwiki-local/backend/dsl/vocab-manifest-keyword-tables.mdwiki-local/qa/document-verification/rfc-registry-edits.mdwiki-local/testing/strategy/rfc-prose-example-over-committed-example.mdwiki-local/backend/change-impact/generic-condition-call-sites.mdhandfish (linkly-crew), t3b-agent-ctrl-drain — 1 row:
wiki-local/backend/concurrency/unserved-control-reply-per-exit-kind.mdhandfish, t7-run-gitflow — 7 rows:
role_harness_cfgflag flip site + unit test →wiki-local/backend/config/role-harness-cfg.mdwiki-local/infrastructure/gitflow/sprint-merge-preconditions.md-c core.hooksPath=/dev/nullon every git call →wiki-local/infrastructure/gitflow/disable-hooks-per-invocation.md(general kernel — "when automation commits on a user's repo, disable all hooks per invocation withcore.hooksPath=/dev/null, not--no-verify" — is worth a future general candidate once a session emits it with its own evidence; the row as harvested is a design record)wiki-local/infrastructure/gitflow/push-policy.mdproject_root Noneissues zero git commands →wiki-local/testing/quality/git-call-counter-seam.mdwiki-local/infrastructure/gitflow/resolve-main-branch.mdwiki-local/security/agent-exposure/merged-agent-files-residual-risk.mddace (linkly-calendar Android), t6a-trip-ui — 10 rows:
isValidKey/readManifestKey→wiki-local/mobile/maps/google-maps-key-gate.mdTripViewModel→wiki-local/mobile/architecture/tab-root-receives-viewmodel.mdOPTIMIZE_APPLY_FAILED_MESSAGEconstant + local state →wiki-local/mobile/presentation/local-error-message-constant.mdmoveItem/removeItempure functions →wiki-local/mobile/presentation/itinerary-move-remove.mdtripDatesInRange/tripShortDisplayonLocalDate→wiki-local/mobile/presentation/trip-date-helpers.mdMarkerComposablebadges →wiki-local/mobile/maps/marker-composable-badges.mddecodePolyline+ test file →wiki-local/mobile/maps/decode-polyline.mdwiki-local/mobile/dependencies/maps-compose-pins.md(general kernel — verify a transitive floor from the artifact's.modulerequiresvsstrictly, not from an HTTP 200 — is a future general candidate)MapStyle.lightnull on parse failure →wiki-local/mobile/maps/map-style-null-fallback.md.orchestration-notes/t6a-trip-ui.mdcontents →wiki-local/infrastructure/agent-orchestration/task-notes-file.mdCount check: 8 + 1 + 7 + 10 = 26.