diff --git a/analysis/cleanup-worklog-2026-04-29.md b/analysis/cleanup-worklog-2026-04-29.md
index fb70e8f..7a432b3 100644
--- a/analysis/cleanup-worklog-2026-04-29.md
+++ b/analysis/cleanup-worklog-2026-04-29.md
@@ -577,6 +577,26 @@
- синтаксических ошибок в `v1/lib/rest_api_helper.cfc` не обнаружено
- синтаксических ошибок в `v1/lib/expression_parser.cfc` не обнаружено
+## Обновление: начат консервативный проход по неиспользуемым CFML-файлам
+
+Дата фиксации: 2026-04-29.
+
+### Что проверено
+
+- состав каталогов `v1/resources/bk` и `v1/etc/bk`
+- наличие явных backup-сериализаторов в `v1/resources/bk`
+- отсутствие необходимости затрагивать vendor-слой `v1/taffy`
+
+### Решение по этому этапу
+
+Сразу удаляется только узкий набор файлов с высокой уверенностью, которые являются backup-артефактами и не участвуют в текущем runtime:
+- `v1/resources/bk/JSONUtil.cfc`
+- `v1/resources/bk/JsonBNSerializer.cfc`
+- `v1/resources/bk/JsonSerializer.cfc`
+- `v1/resources/bk/JsonUtilSerializer.cfc`
+
+Каталог `v1/etc/bk` на этом этапе не затрагивается, потому что для его файлов нужна отдельная проверка по назначению и ссылкам.
+
### Следующий мини-этап
Для следующего такого же безопасного прохода выбраны:
diff --git a/v1/resources/bk/JSONUtil.cfc b/v1/resources/bk/JSONUtil.cfc
deleted file mode 100644
index 78b9876..0000000
--- a/v1/resources/bk/JSONUtil.cfc
+++ /dev/null
@@ -1,620 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/v1/resources/bk/JsonBNSerializer.cfc b/v1/resources/bk/JsonBNSerializer.cfc
deleted file mode 100644
index b21fa5a..0000000
--- a/v1/resources/bk/JsonBNSerializer.cfc
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/v1/resources/bk/JsonSerializer.cfc b/v1/resources/bk/JsonSerializer.cfc
deleted file mode 100644
index 4d717f9..0000000
--- a/v1/resources/bk/JsonSerializer.cfc
+++ /dev/null
@@ -1,519 +0,0 @@
-component
- extends="taffy.core.baseSerializer"
- output = false
- hint = "I provide a way to serialize complex ColdFusion data values as case-sensitive JavaScript Object Notation (JSON) strings."
- {
- //2024-06-27 modified by msyu: added server timezone
- //2024-10-05 modified by msyu: null fix from JSONUtils (yet still no luck with case sens and date format).Вспомнил, что этому сериализатору нужно указывать тип каждого поля
-
- // I return the initialized component.
- public any function init() {
-
- // Every key is added to the full key list - used for one-time key serialization.
- fullKeyList = {};
-
- // Every key is added to the hint list so that we don't have to switch on the lists.
- fullHintList = {};
-
- // These key lists determine special data serialization.
- stringKeyList = {};
- booleanKeyList = {};
- integerKeyList = {};
- floatKeyList = {};
- dateKeyList = {};
-
- // These keys will NOT be used in serialization (ie. the key/value pairs will not be
- // added to the serialized output).
- blockedKeyList = {};
-
- // Return the initialized component.
- return( this );
-
- }
-
-
- // ---
- // PUBLIC METHODS.
- // ---
-
-
- // I define the given key without a type. This is here to provide key-casing without caring
- // about why type of data conversion takes place. Returns serializer.
- public any function asAny( required string key ) {
-
- return( defineKey( fullKeyList, key, "any" ) );
-
- }
-
-
- // I define the given key as a boolean. Returns serializer.
- public any function asBoolean( required string key ) {
-
- return( defineKey( booleanKeyList, key, "boolean" ) );
-
- }
-
-
- // I define the given key as a date. Returns serializer.
- public any function asDate( required string key ) {
-
- return( defineKey( dateKeyList, key, "date" ) );
-
- }
-
-
- // I define the given key as a float / decimal. Returns serializer.
- public any function asFloat( required string key ) {
-
- return( defineKey( floatKeyList, key, "float" ) );
-
- }
-
-
- // I define the given key as an integer. Returns serializer.
- public any function asInteger( required string key ) {
-
- return( defineKey( integerKeyList, key, "integer" ) );
-
- }
-
-
- // I define the given key as a string. Returns serializer.
- public any function asString( required string key ) {
-
- return( defineKey( stringKeyList, key, "string" ) );
-
- }
-
-
- // I define the key as one that should not be included in the serialized response.
- public any function exclude( required string key ) {
-
- blockedKeyList[ key ] = true;
-
- return( this );
-
- }
-
-
- /**
- * I serialize the given input as JavaScript Object Notation (JSON) using the case-sensitive
- * values defined in the key-list.
- *
- * @output false
- */
- public string function serialize( required any input ) {
-
- // Write the serialized value to the output buffer.
- savecontent variable = "local.serializedInput" {
-
- serializeInput( input, "any" );
-
- }
-
- return( serializedInput );
-
- }
-
-
- // ---
- // PRIVATE METHODS.
- // ---
-
-
- // I define the given key within the given key list.
- private any function defineKey(
- required struct keyList,
- required string key,
- required string hint
- ) {
-
- if ( structKeyExists( fullKeyList, key ) ) {
-
- throw(
- type = "DuplicateKey",
- message = "The key [#key#] has already been defined within the serializer.",
- detail = "The current key list is: #structKeyList( fullKeyList, ', ' )#"
- );
-
- }
-
- // Add to the appropriate data-type lists. This one is used for existence checking.
- keyList[ key ] = key;
-
- // Add all keys to the full key list as well. This one is used to store the serialization
- // of the key so that it doesn't have to be recalculated each time the object is serialized.
- fullKeyList[ key ] = serializeString( key );
-
- // If we have a specific type, then add the hint to the full hint list as well. This will
- // allow us to quickly look up the pass-through data type hint during serialization.
- // --
- // NOTE: The reason we don't want to pass through "any" is that we want parent types to be
- // able to "fall through" during the object traversal. If we added "any" to the type list,
- // then it would always overwrite the parent data type.
- if ( hint != "any" ) {
-
- fullHintList[ key ] = hint;
-
- }
-
- // Return this reference for method chaining.
- return( this );
-
- }
-
-
- // I walk the given object, writing the serialized value to the output (which is expected to
- // be a content buffer).
- // ---
- // NOTE: THIS METHOD IS HUGE - this is on purpose. Since serialization is a rather intense
- // process, I am trying to cut out as much overhead as possible. In this case, we're cutting
- // out extra stack space by inlining and duplicating a lot of functionality. This is being done
- // at the COST of clarity and non-repetitive code.
- private void function serializeInput(
- required any input,
- required string hint
- ) {
-
- // Serialize the data base on the type of input. We are organizing this in terms of the
- // most commonly-used values first. The anticipation is that the vast majority of data
- // types will be simple values.
- if ( isSimpleValue( input ) ) {
-
- if ( ( hint == "string" ) || ( hint == "any" ) ) {
-
- // If the string appears to be numeric, then we have to prefix it to make sure
- // ColdFusion doesn't accidentally convert it to a number.
- if ( isNumeric( input ) ) {
-
- writeOutput( """" & input & """" );
-
- } else {
-
- serializeInputString( input );
-
- }
-
- } else if ( ( hint == "boolean" ) && isBoolean( input ) ) {
-
- writeOutput( input ? "true" : "false" );
-
- } else if ( ( ( hint == "integer" ) || ( hint == "float" ) ) && isNumeric( input ) ) {
-
- writeOutput( input );
-
- } else if ( ( ( hint == "integer" ) || ( hint == "float" ) ) && isBoolean( input ) ) {
-
- writeOutput( input ? "1" : "0" );
-
- } else if ( ( hint == "date" ) && ( isDate( input ) || isNumericDate( input ) ) ) {
-
- // Write the date in ISO 8601 time string format. We're going to assume that the
- // date is already in the desired timezone.
- ///writeOutput( """" & dateFormat( input, "yyyy-mm-dd" ) & "T" & timeFormat( input, "HH:mm:ss.l" ) & "Z""" );
- //2024-06-27 modified by msyu: added server timezone
- writeOutput( """" & dateFormat( input, "yyyy-mm-dd" ) & "T" & timeFormat( input, "HH:mm:ss.lXX" ) & """" );
-
- } else {
-
- serializeInputString( input );
-
- }
-
- return;
-
- } // END: isSimpleValue().
-
-
- // I'm expecting the struct to be the next most common data type since it will likely be
- // the container for the majority of data values.
- if ( isStruct( input ) ) {
-
- writeOutput( "{" );
-
- var isFirst = true;
-
- for ( var key in input ) {
-
- // Skip any black-listed keys.
- if ( structKeyExists( blockedKeyList, key ) ) {
-
- continue;
-
- }
-
- // Handle the item delimiter.
- if ( isFirst ) {
-
- isFirst = false;
-
- } else {
-
- writeOutput( "," );
-
- }
-
- // Ensure that the given key can be referenced on the full-key list. This way,
- // the subsequent logic will be easier.
- if ( ! structKeyExists( fullKeyList, key ) ) {
-
- asAny( lcase( key ) );
-
- }
-
- writeOutput( fullKeyList[ key ] & ":" );
-
- // Pass in the most appropriate data-type hint based on the parent key.
- if ( structKeyExists( fullHintList, key ) ) {
-
- serializeInput( input[ key ], fullHintList[ key ] );
-
- // If the given key is unknown, just pass through the most recent hint as
- // it may be defining the type for an entire structure.
- } else {
- // patch for null, from JSONUtils
- if (IsDefined("input.#key#")) {
- serializeInput( input[ key ], hint);
- } else {
- writeOutput("null") ;
- }
- }
-
- }
-
- writeOutput( "}" );
-
- return;
-
- } // END: isStruct().
-
-
- if ( isArray( input ) ) {
-
- writeOutput( "[" );
-
- var isFirst = true;
-
- // Handle the item delimiter.
- for ( var value in input ) {
-
- if ( isFirst ) {
-
- isFirst = false;
-
- } else {
-
- writeOutput( "," );
-
- }
-
- // Since we don't have a key to go off of, pass-through the most recent hint.
- serializeInput( value, hint );
-
- }
-
- writeOutput( "]" );
-
- return;
-
- } // END: isArray().
-
-
- // When we serialize a query, we're going to treat it like an array of structs.
- if ( isQuery( input ) ) {
-
- var keys = listToArray( input.columnList );
-
- // Make sure each column is defined as a known key - makes the subsequent logic easier.
- for ( var key in keys ) {
-
- if ( ! structKeyExists( fullKeyList, key ) ) {
-
- asAny( lcase( key ) );
-
- }
-
- }
-
- writeOutput( "[" );
-
- // Serialize each row of the query as a struct.
- for ( var i = 1 ; i <= input.recordCount ; i++ ) {
-
- // Handle the row delimiter.
- if ( i > 1 ) {
-
- writeOutput( "," );
-
- }
-
- writeOutput( "{" );
-
- var isFirst = true;
-
- for ( var key in keys ) {
-
- // Skip any black-listed keys.
- if ( structKeyExists( blockedKeyList, key ) ) {
-
- continue;
-
- }
-
- // Handle the item delimiter (in the current row).
- if ( isFirst ) {
-
- isFirst = false;
-
- } else {
-
- writeOutput( "," );
-
- }
-
- writeOutput( fullKeyList[ key ] & ":" );
-
- // Pass in the most appropriate data-type hint based on the parent key.
- if ( structKeyExists( fullHintList, key ) ) {
-
- serializeInput( input[ key ][ i ], fullHintList[ key ] );
-
- // If the given key is unknown, just pass through the most recent hint as
- // it may be defining the type for an entire structure.
- } else {
-
- serializeInput( input[ key ][ i ], hint );
-
- }
-
- } // END: Key list.
-
- writeOutput( "}" );
-
- } // END: Row list.
-
- writeOutput( "]" );
-
- return;
-
- } // END: isQuery().
-
-
- // If we made it this far, we were given a data type that we're not actively supporting.
- // As such, we just have to hand this off to the native serializer.
- writeOutput( serializeJson( input ) );
-
- }
-
-
- /**
- * I serialize and write the given string to the current output context, escaping all appropriate
- * characters for the JSON specification.
- *
- * NOTE: We are using this manual-encoding process rather than the built-in serializeJson() function
- * as there is a rather nasty bug that corrupts certain patterns in the output. Read more:
- *
- * http://www.bennadel.com/blog/2842-serializejson-and-the-input-and-output-encodings-are-not-same-errors-in-coldfusion.htm
- *
- * @input I am the string being serialized.
- */
- private void function serializeInputString( required string input ) {
-
- // While this may not be technically needed, this will ensure that we are not using any
- // "undocumented features" of the language. If we explicitly cast to a Java string, and
- // something goes wrong due to odd type-casting, it's a ColdFusion bug, at that point, not
- // a logic error ;)
- input = javaCast( "string", input );
-
- var length = input.length();
-
- writeOutput( """" );
-
- for ( var i = 1 ; i <= length ; i++ ) {
-
- var charCode = input.codePointAt( javaCast( "int", i - 1 ) );
-
- // Check for the most common case first (normal characters).
- if (
- ( charCode >= 32 ) &&
- ( charCode != 34 ) &&
- ( charCode != 47 ) &&
- ( charCode != 92 ) &&
- ( charCode != 8232 ) &&
- ( charCode != 8233 )
- ) {
-
- writeOutput( chr( charCode ) );
-
- // Check for the special cases next (control characters, characters that
- // need to be escaped, and characters that need to be encoded nicely).
- } else if ( charCode == 8 ) {
-
- writeOutput( "\b" );
-
- } else if ( charCode == 9 ) {
-
- writeOutput( "\t" );
-
- } else if ( charCode == 10 ) {
-
- writeOutput( "\n" );
-
- } else if ( charCode == 12 ) {
-
- writeOutput( "\f" );
-
- } else if ( charCode == 13 ) {
-
- writeOutput( "\r" );
-
- } else if (
- ( charCode < 32 ) ||
- ( charCode == 8232 ) ||
- ( charCode == 8233 )
- ) {
-
- // For Unicode hex values, we need to enforce a 4-digit code.
- writeOutput( "\u" & right( ( "000" & formatBaseN( charCode, 16 ) ), 4 ) );
-
- } else if ( charCode == 34 ) {
-
- writeOutput( "\""" );
-
- } else if ( charCode == 47 ) {
-
- writeOutput( "\/" );
-
- } else if ( charCode == 92 ) {
-
- writeOutput( "\\" );
-
- }
-
- }
-
- writeOutput( """" );
-
- }
-
-
- /**
- * I serialize and return the given string, escaping all appropriate characters for the
- * JSON specification.
- *
- * @input I am the string being serialized.
- * @output false
- */
- private string function serializeString( required string input ) {
-
- savecontent variable = "local.json" {
-
- serializeInputString( input );
-
- }
-
- return( json );
-
- }
-
-}
\ No newline at end of file
diff --git a/v1/resources/bk/JsonUtilSerializer.cfc b/v1/resources/bk/JsonUtilSerializer.cfc
deleted file mode 100644
index 6a9b071..0000000
--- a/v1/resources/bk/JsonUtilSerializer.cfc
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-