scripts/maintenance/vikingdb_content_backfill/README.md
This maintenance script backfills empty content fields in historical OpenViking
VikingDB records. It is intended for one-off operational use after the target
VikingDB collection already has the content text field and FullText configured.
content fields with update_data.upsert_data.openviking-server.Run from the repository root with the project virtual environment:
./venv/bin/python scripts/maintenance/vikingdb_content_backfill/backfill_vikingdb_content.py
The script depends on the current OpenViking codebase and configuration:
ov.conf must point to the target environment.storage.vectordb.backend must be volcengine or vikingdb.content text field and
FullText configuration.The script is designed for OpenViking versions that use the current deterministic vector ID rule:
id = md5(f"{account_id}:{seed_uri}")
Where:
{directory_uri}/.abstract.md{directory_uri}/.overview.mdIt also assumes the current Vectorize.full_text -> content write semantics.
For each account directory under /local, the script traverses viking:// with
node_limit=None, level_limit=None, and show_all_hidden=True. It no longer
maintains a hard-coded list such as resources, agent/skills, or user
resources / memories / skills, because that list can miss newer
namespaces such as peer-scoped content.
Directories generate L0/L1 candidates; files generate L2 candidates. Hidden
L0/L1 marker files (.abstract.md and .overview.md) are not emitted again as
L2 candidates. Existing VikingDB records are then checked by deterministic ID;
missing IDs are simply skipped.
Start with a dry run:
./venv/bin/python scripts/maintenance/vikingdb_content_backfill/backfill_vikingdb_content.py \
--limit 100
Inspect the generated files under:
scripts/maintenance/vikingdb_content_backfill/result/<timestamp>/
Then execute the update:
./venv/bin/python scripts/maintenance/vikingdb_content_backfill/backfill_vikingdb_content.py \
--execute
Optional throttling:
./venv/bin/python scripts/maintenance/vikingdb_content_backfill/backfill_vikingdb_content.py \
--execute \
--batch-size 100 \
--limit 10000
Each run writes to a timestamped directory under result/.
The repository .gitignore already ignores result/, so run outputs should not
be committed.
summary.json: final counters for the run.progress.json: latest counters, written after the initial root traversal and
refreshed after each processed candidate.updated.jsonl: records actually updated by the script.failed.jsonl: records that failed to update.By default, the script does not write full candidate or skipped-record details, because those files can become very large on production datasets.
Optional detail files:
candidates.jsonl: written only with --record-candidates.skipped.jsonl: written only with --record-skipped.The script does not support checkpoint resume in the current version. Re-running
is safe because non-empty content is skipped by default.
candidate_count: number of deterministic vector candidates generated from
Local AGFS source data.existing_records: number of candidates that already had a VikingDB record.processed_count: number of records whose content was empty and for which
replacement content was successfully resolved.updated_count: number of records updated through update_data. This is 0
in dry-run mode.skipped_count: number of records skipped for any reason.failed_count: number of records that failed during update_data.missing_record_count: number of candidates whose deterministic VikingDB
record ID did not exist.non_empty_content_count: number of records skipped because content was
already non-empty.created_after_cutoff_count: number of records skipped because their
created_at / create_time was later than the script start time.empty_resolved_content_count: number of records skipped because the script
could not resolve non-empty source content.changed_during_run_count: number of records skipped because updated_at
changed between the first fetch and the pre-update fetch.--execute is
provided.content is skipped by default.--rewrite-non-empty only when intentionally replacing existing content.--record-candidates or --record-skipped only for debugging or small
datasets.content
is no longer empty or updated_at changed during the run.OpenVikingService,
queue workers, or transaction lock managers.