kinogaki-core

libraries/kinogaki-core · 0 open · 10 done

kinogaki-core is healthy and clean: ./build.sh is green (222 cases, 1146 checks). All audit issues are closed — the hyphen path bug is fixed, the README uses Element/codecs vocabulary, the CMake variables are renamed, and overlay layers can now express connection-removal (disconnect). No open issues.

core_1Hyphen in an element name parses but is unaddressable by pathDone MED
bug · completeness

Where: src/Serialize.cpp def-parser (lines 380-451) and src/Path.cpp isNameChar (lines 8-9).

Resolution: The two grammars now agree — both restrict names to [A-Za-z0-9_]. Path.cpp:9 isNameChar and Serialize.cpp:406 isBareName are byte-identical character classes. A bare identifier is lexed by readIdent (the text-format tokenizer in Serialize.cpp, using isIdent/isIdentStart at lines 202-203), which excludes -, so def name-with-hyphen cannot tokenize a hyphenated bare name. A quoted token like def "py-1" { fails isBareName (line 403) and is therefore treated as an anonymous element with quoted TYPE py-1 (line 419-421), not as a name — so it lands at /parent/[i] and is addressable by index. The pathological case from the old finding (a name that parses but Document::has misses) no longer exists: a hyphenated token can never become a name segment. tests/path_test.cpp exercises the segment grammar (line 40 rejects a non-name char; lines 71-75 verify round-trip idempotency).

Note: the lexer lives in Serialize.cpp (lines 202-203), not in SerializeCommon.h — that header is binary-format-only machinery and contains no lexer.

core_6README Model/Layout still use Prim vocabulary; codecs undocumentedDone MED
task · organization

Resolved 2026-06-20. The README Model/Layout sections now use Element/Element.h (not Prim/Prim.h), and a new bullet documents the foreign-format codec layer — decode/encode, Document::load/save/toString, Codec::Markdown/Html/Svg/Json, and the codecs/ directory (the layer the issue tracker and docs site render through).

core_7CMakeLists uses stale PRISMACORE_* variable namesDone LOW
task · naming

Resolved 2026-06-20. The CMake cache options and internal variables were renamed PRISMACORE_* -> KINOGAKICORE_* (KINOGAKICORE_BUILD_TESTS, _SANITIZE, _WARNINGS, _SOURCES, _TESTS), so configuring the build no longer surfaces the dead Prism name.

core_8Overlay does not express connection-removal in a layer (documented limit)Done LOW
task · completeness

Resolved 2026-06-20. Added a disconnect "/target.slot" overlay tombstone — a layer can now REMOVE a connection while keeping both endpoints, the connection analog of delete. Document carries connectionDeletions() (sorted/unique); the text parser, writer, and overlay() all handle it. Covered by three tests (apply-in-a-layer, serialize round-trip, no-op on an unconnected target). Suite green: 222 cases, 1146 checks.

core_9Completeness: no stubs, dead code, or swallowed errorsDone LOW
task · completeness

Where: src/, include/, tests/.

Clean. No TODO/FIXME/stub/XXX/HACK markers remain (the only XXXX hit is \uXXXX in a JSON-escape comment). No empty or catch(...)-swallow blocks exist in src/. Codec decoders fail closed by returning std::nullopt when they decline (src/HtmlCodec.cpp:407, src/MarkdownCodec.cpp:342, src/SvgCodec.cpp:213, src/FileCodecs.cpp:34,52), and the binary/package readers are bounded and fail-closed. The only remaining acknowledged gap is core_8 (overlay connection-removal), tracked separately.

core_10Tests cover pure logic and error paths, including codecsDone LOW
task · tests

Where: tests/ (run via ./build.sh).

The suite is green: 219 cases, 1133 checks, 0 failures. Coverage spans the model (path, value, transform, evaluate, evalcache, scene, compose/overlay, reference/prefab/stage), serialization across all three encodings + compression, the C ABI (c_api_test, c_api_coverage_test), and every codec added to core (json_codec_test, html_codec_test, markdown_codec_test, svg_codec_test, file_codecs_test, bundle_test, codec_test, codecs_api_test), plus regression and review-followup pins. Error paths are exercised (malformed paths, declining codecs, corrupt-input binary).

core_11Separation of concerns is clean across model, serialization, codecs, C ABIDone LOW
task · separation

Where: src/, include/kinogaki/.

Clean layering: the model (Document/Element/Value/Path) is the single mutation surface; serialization is split by concern (Serialize.cpp text parse + dispatch, SerializeTextWrite.cpp emit, SerializeBinary.cpp crate, SerializePackage.cpp archive, private SerializeCommon.h shared low-level machinery used only by the binary TUs); the codec layer routes foreign formats through the internal Codec.h seam to concrete codecs while native encodings route to Serialize.h; the C ABI is isolated in src/C.cpp as a thin Document wrapper (static_assert keeps it thin). No UI/GPU/platform code leaks in.

core_12Public functions read as verbs; bare-noun accessors are intentionalDone LOW
task · naming

Where: include/kinogaki/Document.h, include/kinogaki/C.h, src/Transform.cpp.

Clean. Mutators/queries read as verbs (append, appendChild, connect, disconnect, rename, remove, animate, instantiate, extract, compose, overlay, decode/encode, detect); transform helpers are verbs (makeIdentityAffine, affineMul, affineApply, invertAffine, computeLocalMatrix/computeWorldMatrix). Bare-noun forms (children, connections, roots, get/set/has, eval) are accessors, which the criterion permits. The C ABI is uniformly kinogaki_<noun>_<verb> (kinogaki_document_add_child, kinogaki_element_set_float, …). Only the build-script variable names lag (core_7).

core_13File size: every source file under the 1000-line budgetDone LOW
task · filesize

Where: src/, include/.

Clean. Largest source is src/Serialize.cpp at 911 lines; next are src/C.cpp (619) and src/HtmlCodec.cpp (413). Largest header is include/kinogaki/C.h (245). No file approaches the 1000-line limit.

core_14Organization: clean tree, correct .gitignoreDone LOW
task · organization

Where: repo root, .gitignore.

git status is clean and git ls-files shows no committed build artifacts (.o/.a/.dylib/build//.DS_Store). .gitignore covers .DS_Store and build/; the two .DS_Store files present on disk (./, ./include/) are untracked, as intended. (README accuracy is tracked separately under core_6.)