individualization.json

Reference for advanced individualization behavior.

individualization.json controls advanced processing behavior for variable replacement, solution deletion, warnings, file handling, artifact processors, and compatibility variation settings.

This file is optional. If it is missing, Divekit falls back to built-in defaults.

Minimal Example

{
  "variables": {
    "variableDelimiter": "$"
  }
}

Common Example

{
  "variables": {
    "variableDelimiter": "$",
    "values": {
      "semester": "SS2026"
    }
  },
  "solutionDeletion": {
    "enabled": true,
    "files": ["src/main/java/Solution.java"]
  },
  "warnings": {
    "enabled": true,
    "ignore": ["*.tmp"],
    "variationResidues": {
      "typeWhiteList": ["java", "md"],
      "ignoreList": ["UUID"],
      "matchMode": "word",
      "ignoreRules": [
        {
          "paths": ["src/test/java/**"],
          "values": ["Dish"]
        },
        {
          "values": ["Dish|Meal"],
          "matchMode": "regex"
        }
      ]
    }
  },
  "processors": {
    "uml": {
      "mode": "both",
      "imageFormat": "jpg"
    },
    "tableHash": {
      "solutionTableFileName": "${id}.solution.md",
      "hashedSolutionTableFileName": "${id}.hashed.md",
      "tableConfigFileName": "${id}.config.json"
    }
  }
}

Top-Level Keys

KeyTypeNotes
variablesobjectToken delimiters and fixed values.
solutionDeletionobjectFiles, directories, and markers used to remove solution content.
warningsobjectValidation and unresolved-token warning behavior.
fileManipulationobjectTarget-specific file naming conventions such as _workrepo.
processorsobjectBuilt-in artifact processors such as UML source/image generation.
relationsobjectObject-relation metadata.
variableExtensionsobjectPrefix, suffix, and transformation maps.
variationsobjectUnified compatibility container for variation data.
objectVariationsarrayLegacy flattened object variations.
relationVariationsarrayLegacy flattened relation variations.
logicVariationsarrayLegacy flattened logic variations.

variables

This section controls token delimiters and fixed token values.

KeyTypeNotes
variables.variableDelimiterstringOpening delimiter for tokens. Default: $. With the default, a token looks like $Vehicle$.
variables.variableDelimiterEndstringOptional closing delimiter when start and end should differ. For example, "{%" and "%}".
variables.valuesobjectFixed token values that are available during individualization, independent of selected variations.

solutionDeletion

This section removes solution-only content before repositories are distributed.

KeyTypeNotes
solutionDeletion.enabledbooleanEnables solution deletion. Default: false.
solutionDeletion.filesarray of stringsRepository-relative files to remove completely. When deletion is enabled, configure at least one entry in files or directories.
solutionDeletion.directoriesarray of stringsRepository-relative directories to remove completely. When deletion is enabled, configure at least one entry in files or directories.
solutionDeletion.deleteFileKeystringMarker that removes a whole file when found in its content. Default: // DELETEFILE.
solutionDeletion.deleteParagraphKeystringMarker used for paragraph-level solution removal. Default: DELETE.
solutionDeletion.replaceMapobjectLiteral replacement map applied during solution deletion.

warnings

This section controls warnings for unresolved tokens and leftover variation values.

KeyTypeNotes
warnings.enabledbooleanEnables warning checks. Default: false.
warnings.ignorearray of stringsIgnore patterns for warning checks. Required when warnings are enabled.
warnings.variationResiduesobjectOptional rules for leftover variation-value warnings.
warnings.variationResidues.typeWhiteListarray of stringsFile extensions to inspect, without leading dots. When set, include every extension that should still be scanned.
warnings.variationResidues.ignoreListarray of stringsGlobal residue values or surrounding fragments to suppress.
warnings.variationResidues.matchModestringMatching mode for residue detection: substring, word, or identifierPart. Default: substring.
warnings.variationResidues.ignoreRulesarrayPath-specific or mode-specific suppression rules.
warnings.variationResidues.ignoreRules[].pathsarray of stringsOptional repository-relative path patterns where the rule applies. Omit for a global rule.
warnings.variationResidues.ignoreRules[].valuesarray of stringsResidue values to suppress for this rule. Must not be empty.
warnings.variationResidues.ignoreRules[].matchModestringMatching mode for this rule. Supports substring, word, identifierPart, and regex.

fileManipulation

This section controls target-specific file and directory markers.

KeyTypeNotes
fileManipulation.filePreIdentifierstringPrefix used when building target markers. Default: _.
fileManipulation.filePostIdentifierstringSuffix used when building target markers. Default: repo.
fileManipulation.noRepoIdentifierstringMiddle part used for the exclude-from-all marker. Default: no.

With the default values

{
  "filePreIdentifier": "_",
  "filePostIdentifier": "repo",
  "noRepoIdentifier": "no"
}

these built-in defaults produce the markers below. You only need to write fileManipulation when you want to override them.

the resulting markers are:

  • _workrepo: include only for target work
  • _evalrepo: include only for target eval
  • _norepo: exclude from all generated repositories

The marker is removed from the final exported path.

Examples:

src/tests_evalrepo/HiddenTests.java -> src/tests/HiddenTests.java (eval only)
docs/teacher_workrepo.md            -> docs/teacher.md (work only)
assets/_norepo/logo.svg             -> excluded everywhere

Legacy compatibility:

  • _mainrepo and _coderepo are still accepted and map to work
  • _testrepo is still accepted and maps to eval
  • older sandbox terminology may still appear in existing repositories, but eval is the canonical target name

processors

This section configures built-in artifact processors that run during individualization.

KeyTypeNotes
processors.umlobjectUML source/image processor configuration.
processors.uml.modestringoff, source, image, or both. Default: both.
processors.uml.imageFormatstringOutput format for rendered UML images. Default: jpg.
processors.tableHashobjectOptional naming patterns for hashed solution table artifacts.
processors.tableHash.solutionTableFileNamestringEval solution table filename pattern. Default: ${id}.solution.md.
processors.tableHash.hashedSolutionTableFileNamestringWork hashed table filename pattern. Default: ${id}.hashed.md.
processors.tableHash.tableConfigFileNamestringTable config filename pattern. Default: ${id}.config.json.

Currently supported:

{
  "processors": {
    "uml": {
      "mode": "both",
      "imageFormat": "jpg"
    },
    "tableHash": {
      "solutionTableFileName": "${id}.solution.md",
      "hashedSolutionTableFileName": "${id}.hashed.md",
      "tableConfigFileName": "${id}.config.json"
    }
  }
}

processors.uml

UML processing applies to .uxf and .uml files.

Default behavior:

  • the individualized source UML file is kept
  • an additional rendered image is emitted
  • the default image format is jpg

Supported keys:

KeyTypeNotes
processors.uml.modestringoff, source, image, or both. Default: both.
processors.uml.imageFormatstringOutput format for rendered images. Default: jpg.

Supported modes:

  • off: disables UML-specific artifact generation; the individualized source file remains
  • source: keeps only the individualized UML source file
  • image: emits only the rendered image artifact
  • both: keeps the individualized UML source file and emits the rendered image artifact

Target markers from fileManipulation also apply to UML files. After marker removal, Divekit uses the cleaned path for every emitted UML artifact.

Examples with default settings:

docs/test1_evalrepo.uxf -> eval only: docs/test1.uxf + docs/test1.jpg
docs/test2_workrepo.uxf -> work only: docs/test2.uxf + docs/test2.jpg
docs/test3.uxf          -> both targets: docs/test3.uxf + docs/test3.jpg

Rendering modes image and both require UMLet to be available on the machine running Divekit.

processors.tableHash

Table hashing generates work-repository hash artifacts from eval-repository solution tables. It is useful when students fill Markdown table cells and tests should compare hashed expected values.

With the default naming convention, author these files:

src/main/resources/E1.md
src/test/resources/E1.solution_evalrepo.md
src/test/resources/E1.config.json

After target markers are resolved, Divekit reads E1.solution.md from the eval target, reads E1.config.json, and writes E1.hashed.md to the work target. This happens during divekit distribute and during file patches that affect the related work/eval repositories.

The ${id} placeholder is captured from the solution table file name and reused for the hashed output and config file names. Configure this section only when the default dot-suffix convention does not match your project:

{
  "processors": {
    "tableHash": {
      "solutionTableFileName": "E${id}-solution_testrepo.md",
      "hashedSolutionTableFileName": "E${id}-hashed-solution.md",
      "tableConfigFileName": "E${id}-config.json"
    }
  }
}

Table config files are separate from individualization.json and are resolved next to the solution table by default:

{
  "tableType": "ROWS_AND_COLUMNS",
  "explanationDimensions": ["Question"],
  "validRowValues": [],
  "validColumnValues": ["Question", "Answer"],
  "validCellValues": [],
  "hashedColumns": [false, true],
  "showRowHints": true,
  "showColumnHints": true
}
KeyTypeNotes
tableTypestringOptional legacy table mode. Use ROWS_AND_COLUMNS for question/answer tables where the first Markdown column identifies the row.
explanationDimensionsarray of stringsRow or column names whose cell values are explanatory and are not checked against validCellValues.
validRowValuesarray of stringsOptional case-insensitive allow-list for row labels. An empty list accepts all rows.
validColumnValuesarray of stringsOptional case-insensitive allow-list for column labels. An empty list accepts all columns.
validCellValuesarray of stringsOptional case-insensitive allow-list for comma-separated cell values. An empty list accepts all values.
hashedColumnsarray of booleansMarks columns whose cell values are replaced with SHA-256 hashes.
caseSensitiveColumnsarray of booleansPreserves case before hashing for marked columns. Missing entries default to false, so hashed values are lowercased by default.
caseInsensitiveColumnsarray of booleansCompatibility alias for explicitly lowercasing marked columns when caseSensitiveColumns is not set. Prefer caseSensitiveColumns for Java test-library compatibility.
trimCellsbooleanTrims leading and trailing cell whitespace before hashing. Default: true.
showRowHintsbooleanLegacy test-library hint setting. Stored for compatibility with existing configs.
showColumnHintsbooleanLegacy test-library hint setting. Stored for compatibility with existing configs.

Columns are zero-based by position in the Markdown table. For ROWS_AND_COLUMNS, index 0 is the row-label column and the first answer column is index 1, matching the legacy Java table config. Unlisted positions are treated as false.

Before hashing, Divekit trims each comma-separated cell value, removes empty values, sorts the remaining values case-insensitively, joins them with commas, and lowercases the joined value unless caseSensitiveColumns marks that column as true.

relations

This section stores explicit object-relation metadata.

KeyTypeNotes
relations.objectRelationsarrayRelation entries between configured objects.
relations.objectRelations[].sourceTypestringType of the source object.
relations.objectRelations[].sourceNamestringName of the source object.
relations.objectRelations[].targetTypestringType of the target object.
relations.objectRelations[].targetNamestringName of the target object.
relations.objectRelations[].typestringRelation type.

variableExtensions

This section customizes generated token names and transformation behavior.

KeyTypeNotes
variableExtensions.prefixesobjectMaps token names or variation fields to prefixes.
variableExtensions.suffixesobjectMaps token names or variation fields to suffixes.
variableExtensions.transformationsobjectMaps token names or variation fields to named transformations.

variations

This section is the unified compatibility container for variation definitions. New standalone variation definitions usually belong in variation.json; keep inline variations only when you need compatibility with an existing setup.

KeyTypeNotes
variations.objectsarrayObject-level choices.
variations.objects[].idstringCanonical object ID used to build tokens.
variations.objects[].aliasesarray of stringsAdditional object IDs accepted as aliases.
variations.objects[].kindsarrayCanonical list of object variations.
variations.objects[].idsstringLegacy comma-separated object IDs. The first value becomes id; remaining values become aliases.
variations.objects[].objectVariationsarrayLegacy name for kinds. Still accepted on read.
variations.objects[].kinds[].idstringVariation option ID.
variations.objects[].kinds[].typestringObject type, for example class or method.
variations.objects[].kinds[].namestringHuman-readable object name.
variations.objects[].kinds[].propertiesobjectOptional object properties that can vary.
variations.objects[].kinds[].variablesobjectToken values contributed when this variation is selected.
variations.relationsarrayRelation-level choices.
variations.relations[].idstringRelation variation ID.
variations.relations[].typestringRelation type.
variations.relations[].sourcestringSource object ID.
variations.relations[].targetstringTarget object ID.
variations.relations[].optionsarray of stringsSelectable relation options.
variations.relations[].variablesobjectToken values contributed by the relation variation.
variations.logicarrayLogic-level choices.
variations.logic[].idstringLogic variation ID.
variations.logic[].typestringLogic type, for example algorithm or condition.
variations.logic[].locationstringLocation where the logic variation applies.
variations.logic[].optionsarraySelectable logic options. Options may be strings or objects with an id and custom fields.
variations.logic[].variablesobjectToken values contributed by the logic variation.

Validation Notes

  • variables.variableDelimiter must not be empty.
  • If solutionDeletion.enabled is true, at least one file or directory must be configured.
  • If warnings.enabled is true, warnings.ignore must be present.
  • warnings.variationResidues.ignoreRules[].values must not be empty.
  • warnings.variationResidues.matchMode must be substring, word, or identifierPart.
  • warnings.variationResidues.ignoreRules[].matchMode may additionally be regex.
  • processors.uml.mode must be off, source, image, or both.
  • processors.uml.imageFormat must not be empty when image output is enabled.

warnings.variationResidues

Use this block to suppress leftover variation values that still appear after sample individualization, and to control the matching rules that also help divekit dev avoid related unresolved-token false positives.

Matching modes:

  • substring: matches anywhere, including inside larger identifiers
  • word: matches only whole words
  • identifierPart: matches identifier parts such as Dish inside ovenDish

typeWhiteList should contain the complete set of file types you want Divekit to inspect. If you set it explicitly, include every extension you still want to scan, for example ["java", "md", "json"].

ignoreList is global. Entries may suppress either the residue value itself (for example Dish) or the surrounding word, identifier, or path fragment that produced the match (for example Feedback or coffee for a Fee residue hit). ignoreRules can be path-specific, or global when paths is omitted. Each rule must list the values it suppresses.

Example:

{
  "warnings": {
    "variationResidues": {
      "ignoreList": ["Dish", "Feedback", "coffee"],
      "ignoreRules": [
        {
          "paths": ["src/generated/**"],
          "values": ["GeneratedDish"]
        }
      ]
    }
  }
}

Legacy compatibility:

  • variationResidues is the canonical key
  • variationResidueWarnings is still accepted on read
  • variableValueWarnings is deprecated and still accepted on read for backwards compatibility

Resolution Order

Divekit resolves unified individualization.json in this order:

  1. .divekit/distributions/<distribution>/individualization.json
  2. .divekit/individualization.json
  3. ~/.divekit/individualization.json
  4. built-in defaults

Variation definitions use a more detailed fallback because legacy variation.json files are still supported:

  1. distribution individualization.json
  2. distribution variation.json
  3. project .divekit/individualization.json
  4. project .divekit/variation.json
  5. user ~/.divekit/individualization.json
  6. built-in defaults with no variations

If variations is omitted, Divekit continues to the next source. Set it to an empty object to disable variations and stop fallback resolution:

{
  "version": "2.0",
  "variations": {}
}

Legacy Compatibility

Divekit still contains compatibility loading for these older files:

  • originRepositoryConfig.json
  • variationsConfig.json
  • relationsConfig.json
  • variableExtensionsConfig.json

For new setups, prefer a single individualization.json.

Scripting Clarification

Lua, shell, Python, Node, Deno, Java, and Kotlin execution belong to scripting and extensions, not to dedicated individualization.json keys.

Related pages: