
Vs Item Onboarding
- 3 installs
- 1.2k repo stars
- Updated July 31, 2026
- volcengine/searchcli
Onboards structured item data into Viking search by profiling data, designing a schema, and creating datasets, optionally continuing to app-level setup.
About
Handles item-level onboarding for Viking AI Search: profiling structured item data, generating schema and config plans, and creating datasets. A developer uses it to provision a dataset only, or continue to app-level search onboarding, via item profile/plan/apply commands.
- item profile/plan/apply plus dataset create/ingest/schema-check standardize high-risk steps
- Defaults to dataset-only mode unless the user explicitly asks for app creation
Vs Item Onboarding by the numbers
- 3 all-time installs (skills.sh)
- +1 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #435 of 550 CLI & Terminal skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/volcengine/searchcli --skill vs-item-onboardingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 3 |
|---|---|
| repo stars | ★ 1.2k |
| Last updated | July 31, 2026 |
| Repository | volcengine/searchcli ↗ |
What it does
Onboards structured item data into Viking search by profiling data, designing a schema, and creating datasets, optionally continuing to app-level setup.
Files
Viking Item Onboarding
When to Use
Use this skill when a user provides structured item data and expects the agent to understand the data, design the schema, and either provision a dataset only or continue to app-level search onboarding. Understand the business goal and the requested delivery boundary first, then use item profile / plan / apply plus lower-level dataset commands to standardize the high-risk execution steps.
Preconditions
vsCLI and Viking skills are installed- authentication is complete; at least
vs auth statusandvs doctorsucceed - input file is preferably
JSON array,JSONL, orCSV(convert binary spreadsheets first) - the user has stated a business goal such as "Build catalog search" or "Build content search"
High-level Flow
For dataset-only, there is exactly one valid schema-level user confirmation for the current draft: Stage A. That dialog must happen only after the full schema context has been rendered.
1. item profile --file <data> --type <item|video> — first-pass profiling 2. Confirm the requested provisioning mode: dataset-only or dataset+app; if the user did not ask for app creation, default to dataset-only 3. item plan --file <data> --type <item|video> --goal "<goal>" — generate plan directory; add --skip-app when the requested mode is dataset-only. If execution later goes through item provision or item apply, those commands also accept --skip-app as an execution-time guard rail. 4. Stage A — render the schema header and full schema table, verify row count, then ask exactly one dialog question (see agent-confirmation-ux.md §A) 5. If the requested mode is dataset-only, run dataset create + dataset ingest immediately after a valid Stage A answer and stop after dataset provisioning succeeds; do not issue another schema-level confirmation. Prefer creating the dataset from the full dataset-create.json payload so Schema and DataFieldConfig.FieldDescMap are submitted together. For --type video, this full-payload path is mandatory; do not use schema.json alone 6. If the requested mode is dataset+app, run Stage B — bind-time field-config review (table per group + dialog, see agent-confirmation-ux.md §B); for --type video apply video-field-constraints.md first 7. item apply --plan-dir <dir> --confirm-review — stage-one execution for the dataset+app branch 8. Optional: --run-trials, recommend bootstrap, app diagnose for failures. For any failure, see references/recovery.md — do NOT blindly retry.
Full step-by-step workflow, dataset-type selection rules, examples, and extended guidance live in workflow.md.
Commands
See the commands: frontmatter above for the exhaustive list; the primary entry points are item profile, item plan, dataset create, dataset ingest, and item apply --plan-dir <dir> --confirm-review. Detailed command forms, flags, dataset-only branching, and dataset-type selection rules live in workflow.md.
Workflow
The high-level 8-step flow is listed above under High-level Flow. The full branch-aware workflow — including dataset-only vs. dataset+app routing, profiling, plan review, Stage A, conditional Stage B, dataset provisioning, optional app provisioning, optional --run-trials, and recommend bootstrap — with per-step cross-references to the Hard Rules below lives in workflow.md.
Customer Environment Principle
- In customer environments, assume repository source code is unavailable.
- Execute tasks using only the installed skills, the packaged
vsCLI surface (--help, command output, and observed runtime behavior), and explicit user-provided information. - Do not rely on reading local repository source files, generated repo snapshots, or implementation details to decide runtime actions.
- If the installed CLI behavior conflicts with a skill, trust the installed CLI behavior first.
- If the skills and the packaged CLI still do not provide enough information to proceed safely, stop and ask the user instead of searching source code.
Constraints
The enforceable rules are organized in two layers:
- Hard Rules (MUST / MUST NOT) — listed below; violating any one stops the workflow.
- Pre-apply Checklist — listed below; a mechanical gate that the agent MUST verify before running
vs item apply --plan-dir <dir> --confirm-review. - Additional MUST / Guidance — lower-priority MUST rules and quality guidance live in workflow.md under Extended Constraints.
Hard Rules (MUST / MUST NOT)
These rules prevent server-side failures and silent data loss. Violating any rule stops the workflow.
1. Dataset type is explicit. MUST pass --type <item|video> on both profile and plan. MUST NOT infer dataset type from --goal. If data looks video-like but the user did not specify, MUST ask before continuing. 2. App creation is explicit. MUST ask or infer from an explicit user request whether the target is dataset-only or dataset+app. If the user did not ask for app creation, bind-time config, search/chat verification, or app-level setup, MUST default to dataset-only. MUST NOT create or bind an app on the user's behalf. 3. Stage A gates every provisioning path. MUST run Stage A (schema confirmation) before dataset create, dataset ingest, item apply, or any app-level bind. MUST NOT treat first-pass plan generation as schema approval. 4. Stage A lists every field and every relevant schema attribute. MUST render a per-field table (name, type, attributes, meaning) covering every field in schema.json; MUST NOT summarize only key fields. For --type video, MUST also surface the status of the semantic slots content_id, content_type, video_url, parent_content_id, and sequence_index before approval. 5. Stage A dialog comes last and only once per unchanged draft. MUST NOT issue the Stage A dialog before the header block, the full schema table, and the row-count self-check are complete. If a dialog is issued earlier, MUST discard it and restart Stage A instead of asking a second schema-level confirmation. For dataset-only, once a valid Stage A dialog answer is captured for the current schema draft, MUST NOT ask another schema-level confirmation unless the schema changes. 6. Stage B is conditional and app-only. MUST run Stage B (bind-time field-config confirmation) only when the requested outcome includes application creation or dataset binding. MUST NOT run bind-time confirmation for a dataset-only request, and MUST NOT skip Stage B when app binding will happen. 7. Plan artifacts are drafts, not confirmed bind config. item plan may emit draft dataset-side config artifacts such as field-config.json or dataset-create.json with DataFieldConfig. Treat them as execution inputs, not as user-confirmed bind config. For dataset-only, dataset creation SHOULD prefer the full dataset-create.json payload so Schema and DataFieldConfig.FieldDescMap are submitted together. For dataset-only + --type video, dataset creation MUST use a full payload that includes DataFieldConfig; using only --schema @schema.json can fail with MissingParameter.DefaultFieldStrategy. For dataset-only + --type item, fall back to --schema @schema.json only when dataset-create.json is missing or clearly unsuitable for the current plan. 8. Video DefaultFieldStrategy is mandatory for app/bind flows. For --type video, any Stage B proposal MUST satisfy every row of video-field-constraints.md. Fix violations in memory before rendering Stage B; MUST NOT write a violating proposal to field-config.json or review-confirmation.json. 9. Real bind is real. After Stage B confirmation, MUST run vs item apply --plan-dir <dir> --confirm-review without --dry-run and MUST NOT degrade into OnlySave=true semantics. 10. Stop at the requested boundary. For dataset-only, stage one ends after dataset creation and ingest succeed. For dataset+app, stage one ends after dataset creation, ingest, app creation, and bind succeed. MUST NOT continue beyond the requested boundary unless the user explicitly asks. 11. Recommend bootstrap needs explicit input. MUST NOT auto-create or update recommend scenes without both --recommend-bhv-scene-types and --confirm-recommend-entry-binding.
Pre-apply Checklist
Before provisioning anything, the agent MUST first decide whether the requested path is dataset-only or dataset+app. Use the checklist below only for the dataset+app path. If the request is dataset-only, stop after Stage A and dataset provisioning; do not run Stage B or item apply.
1. Plan directory resolved — <plan-dir> points to the latest item plan output for the current dataset (not a stale one from earlier in the conversation). 2. Dataset type matches intent — plan.json.defaults.datasetType and dataset-create.json.Type both equal the requested --type (item or video). 3. Provisioning mode confirmed — the user explicitly asked for app-level setup, or explicitly agreed to continue from dataset-only into dataset+app. If not, do not run app-level provisioning. 4. Stage A done — the header block was rendered, a per-field schema table was rendered (row count == len(schema.json.Fields)), and the user answered one valid interactive question dialog with a non-abort option. For --type video, the Stage A summary also surfaced the status of content_id, content_type, video_url, parent_content_id, and sequence_index. 5. Stage B done — per-group tables for IndexFields / FilterFields / SuggestFields / ImageIndexFields / VideoIndexFields were rendered with Field / Type / Meaning / Reason to include / Risk or note, and the user answered an interactive dialog with a non-abort option. 6. Video DefaultFieldStrategy satisfied — for --type video, the final proposal satisfies every row of video-field-constraints.md. MUST re-verify after any user adjustment in Stage B. 7. Artifacts written — field-config.json reflects the final Stage B groups, and review-confirmation.json has status=confirmed, every requiredChecks.* true, and a fieldConfigReview block with the final groups. 8. Validation not bypassed — validation.json has no unresolved blocking issues (or --force has been explicitly acknowledged by the user for a controlled test). 9. Apply command is real — the command about to run is exactly vs item apply --plan-dir <dir> --confirm-review, with no --dry-run and without any flag that would degrade into OnlySave=true semantics.
If the user makes a follow-up edit (rename a field, drop a group member, switch --type, etc.) after this checklist passed, MUST re-run the affected checks before apply.
- If provisioning failure analysis or user follow-up turns into a product concept, capability, API field, console UI path, purchase, billing, or general troubleshooting question outside this onboarding workflow, temporarily hand off to
vs-product-qa; return to this workflow only after the grounded product answer is complete.
References
- Full workflow & extended guidance: references/workflow.md
- Artifact review checklist: references/review-checklist.md
- Stage A / Stage B UX contract: references/agent-confirmation-ux.md
- Video
DefaultFieldStrategy(authoritative): references/video-field-constraints.md - Failure recovery & idempotency: references/recovery.md
- JSON walkthrough: references/walkthrough-card-full.md
- CSV walkthrough: references/walkthrough-csv.md
- External agent prompt: references/agent-prompt-template.md
Agent Confirmation UX
This reference defines the in-chat confirmation UX an agent MUST use during item / video onboarding. Stage A always applies before provisioning; Stage B applies only when the requested outcome includes app creation or dataset binding. The two review stages are:
- Stage A —
schema.jsondraft approval (before any dataset is created) - Stage B — bind-time
field-configreview (beforevs app dataset bindor the bind stage ofitem apply)
The goal is to keep both stages consistent: tables first, then an interactive question dialog. Do NOT degrade either stage into a terminal y/N prompt or a single-line summary. Stage A is a single review cycle with exactly one valid order: header -> full schema table -> risk notes -> one dialog. If that order is broken, the Stage A attempt is invalid and MUST be restarted from the top rather than patched with an extra confirmation.
---
Core Rules
1. Both stages MUST render a field-by-field table before asking the user for a decision. 2. Both stages MUST ask the user through an interactive question dialog (the agent's question tool). A free-form chat answer or a terminal y/N does NOT count as confirmation, even if the user's text clearly says "yes". If the dialog was never issued, the stage is unconfirmed. 3. The agent MUST NOT auto-confirm either stage on the user's behalf, and MUST NOT treat chat messages, verbal approvals, or dialog previews as substitutes for the dialog answer. 4. When an item / video onboarding is driven from an agent chat, the agent MUST drive the required stages itself through the dialog. Stage A always applies; Stage B applies only to the dataset+app branch. Do not replace the agent dialog with a CLI-only confirmation step. 5. Any manual edit triggered by the review MUST be written back to the plan directory before continuing:
- schema edits →
schema.json - field-config edits →
field-config.json - confirmation snapshot →
review-confirmation.json(status=confirmed,requiredChecksall true, and afieldConfigReviewblock with the final field groups)
6. review-confirmation.json MUST NOT be set to status=confirmed unless the corresponding stage's dialog has been issued and answered with a non-abort option. The agent MUST NOT write confirmed based on a free-form message alone. 7. For Stage A, the dialog is valid only after the header block, the full schema table, and the row-count self-check are complete. A placeholder confirmation or a "preview" dialog issued earlier does not count.
---
Stage A — schema.json Review
Stage A is the single schema-approval cycle for the current draft. For dataset-only, once a valid Stage A dialog answer is captured, do not ask for another schema-level confirmation unless the schema itself changes and the review is restarted from the top.
A.1 Header block (plain text)
Before the table, list:
- Provisioning mode (
dataset-only/dataset+app) - Dataset type (
item/video) - Dataset name
- Application name (planned) or
not requested - Primary key field
- Title field
- Required fields
- For
video: a semantic-slot checklist forcontent_id,content_type,video_url,parent_content_id,sequence_index, showingpresent / missing / ambiguousplus the current BizAttr mapping for each slot - Source file path and record count
A.2 Schema table (one row per field)
| # | Name | Type | Attributes | Meaning |
|---|
- Row-count anchor (hard rule): the table MUST contain exactly
len(schema.json.Fields)data rows — one row per schema field, in the order they appear inschema.json. No summarization, no "key fields only" view, no omissions. Before issuing the dialog, the agent MUST self-check thatrendered_rows == len(schema.json.Fields); if they differ, re-render and do NOT proceed to §A.4. #MUST be a monotonically increasing integer starting at 1, so the user can see at a glance whether every field made it into the table.NameMUST match the exact field name inschema.json.Fields[i].Name. Do not rename, pluralize, or translate it in the table.TypeMUST show both the numeric code and a human-readable name, e.g.1 (string),3 (int64),6 (array<string>).AttributesMUST listPK,Required, andBizAttr=<code> (<semantic name>)when present; use—when empty.MeaningMUST come fromschema.json(prompt-inferred). If the meaning is empty or clearly wrong, flag it and offer to fix it instead of continuing. TheMeaningcell MUST NOT be left blank — use⚠️ missing (please fix)when the source is empty, so the omission is visible to the user.- The dialog in §A.4 MUST NOT be issued until the header block has been shown, the full table has been rendered, and the row-count self-check has passed.
A.3 Risk notes (optional but recommended)
Right after the table, highlight any risk signals observed in profile / validation:
- fields with
missingCount > 0 - high-cardinality text fields
- URL-like values in non-media fields
- likely duplicated fields (e.g.
actorsvs.actor_list) - samples that are
nullor[null] - for
video: any missing or ambiguously mapped semantic slot amongcontent_id,content_type,video_url,parent_content_id,sequence_index
A.4 Dialog
Ask exactly one question using the question dialog, with these options:
- "Confirm as-is, continue to the requested provisioning path" (recommended default)
- "Change application / dataset name first"
- "Fix schema first (I will tell you which fields)"
The dialog MUST be issued; MUST NOT proceed until the user picks an option through the dialog. A free-form chat reply (even one that clearly says "yes / ok / confirm") does NOT count as Stage A confirmation — in that case, still issue the dialog and use the chat reply only as context for the "Other" option. Each Stage A attempt allows exactly one valid dialog after the table is complete. For dataset-only, a successful Stage A confirmation should lead directly to dataset provisioning, not to another schema-level dialog or bind-time review. Writing review-confirmation.requiredChecks to true or proceeding to Stage B without a dialog answer is a bug.
A.5 Invalid sequence recovery
If the agent asks the Stage A dialog before rendering the complete schema context, that dialog is invalid. The agent MUST:
1. discard that dialog as a confirmation source, 2. restart Stage A from A.1 Header block, 3. re-render the full schema table and any risk notes, 4. issue one new dialog only after the table is complete.
Do not treat the first premature dialog as "the first confirmation" and then ask a second schema-level confirmation to compensate. The restarted Stage A produces the only valid dialog for that schema draft.
---
Stage B — Bind-time field-config Review
This stage applies only when the requested path includes application creation or dataset binding. Skip this entire stage for dataset-only. When Stage B is needed, replace the legacy vs item review summary-only y/N flow with the process below.
B.1 Summary block (plain text)
- Plan directory
- Dataset type and name
- Group sizes:
IndexFields=N, FilterFields=N, SuggestFields=N, ImageIndexFields=N, VideoIndexFields=N TitleFieldandPrimaryKey
B.2 Per-group tables
Render one table per group in this order:
1. IndexFields — text / lexical recall 2. FilterFields — filter, facet, range 3. SuggestFields — search suggest 4. ImageIndexFields — image asset recall 5. VideoIndexFields — video asset / metadata recall
Each table MUST have the columns below. Reason and Risk are mandatory; this is what lifts the UX above a plain field-name list.
| Field | Type | Meaning | Reason to include | Risk / note |
|---|
Row-count anchors (hard rules):
- For every group
G, the corresponding table MUST contain exactlylen(field-config.json.<G>)data rows — one row per field currently proposed in that group, in the same order. No summarization, no "key fields only" view, no omissions. - All five groups MUST have a rendered table, even when the group is empty. For an empty group, render the table with zero data rows and a single italic line
_No fields currently proposed for this group._below it, so the user sees that the agent explicitly decided to leave it empty rather than forgot about it. - Before issuing the Stage B dialog, the agent MUST self-check
rendered_rows_in_group == len(field-config.json.<G>)for each of the five groups; if any mismatch, re-render and do NOT proceed to §B.3. - Every cell MUST be populated. If no business signal is available, use these defaults instead of leaving blanks:
Reason to include→business-goal alignment(default) or a more specific phrase from the guidance belowRisk / note→none observed(default) or a more specific phrase from the guidance below- For
--type video, the row-count check runs AFTER the DefaultFieldStrategy correction described in §B.2.1; the proposal fed into §B.2 MUST already satisfy that server constraint.
Guidance for Reason to include — prefer a specific phrase; fall back to the business-goal alignment default only when none of these apply:
IndexFields: "primary text recall", "named-entity recall (person / role / org)", "semantic long text", "category recall"FilterFields: "faceted filter", "range filter", "id-style filter", "language / locale filter"SuggestFields: "short title / alias for type-ahead"ImageIndexFields: "true image URL / asset field"VideoIndexFields: "video URL / duration / content type metadata"
Guidance for Risk / note — prefer a specific phrase; fall back to the none observed default only when no risk signal is present:
- "duplicate with
<other_field>" - "URL-like value, usually not useful for lexical index"
- "samples are null /
[null], recall will be empty" - "high-cardinality text, may hurt suggest relevance"
- "stored as string, range filter will be lexical not numeric"
B.2.1 Video DefaultFieldStrategy constraint (mandatory for --type video)
For --type video datasets, the server enforces a hard DefaultFieldStrategy constraint table on the bind-time field groups (IndexFields / FilterFields / SuggestFields). The authoritative table lives in video-field-constraints.md; this file intentionally does not duplicate it to avoid drift.
Before rendering the per-group tables for a video dataset, the agent MUST:
1. Load the constraint table from video-field-constraints.md. 2. Compare the current proposal (including LLM-inferred defaults) against every row of that table. 3. If any row is violated, fix the proposal in memory BEFORE rendering Stage B tables and BEFORE asking the Stage B dialog. The corrective action is deterministic: add missing mandatory placements, remove forbidden placements. Do NOT ask the user to resolve the violation — surface the corrected proposal and explain what was changed in a short note above the tables (e.g. "Adjusted to satisfy video DefaultFieldStrategy: added video_url to IndexFields; moved content_id/content_type/parent_content_id/sequence_index into FilterFields."). 4. Re-run step 2 after the correction; only a fully constraint-satisfying proposal may go into the Stage B dialog.
Additional rules:
- The Stage B dialog (§B.3) MUST still be issued after the correction; the user confirms the final, constraint-satisfying proposal, never a violating one.
- Violating proposals MUST NEVER be written to
field-config.jsonorreview-confirmation.json, and MUST NEVER be submitted tovs item apply/vs app dataset bind, because the server will reject them withMissingParameter.DefaultFieldStrategy. - If the user's Stage B answer asks for a change that would re-introduce a violation, do not silently override the user; stop, cite video-field-constraints.md, and ask the user to amend the proposal.
B.3 Dialog
Stage B MUST be confirmed through an interactive question dialog. A free-form chat reply, a summary message, or the user saying "looks good" in chat does NOT count as Stage B confirmation. Ask the user per-group, using the question dialog. Two equivalent flows are available; pick one:
Flow B.3.a — compact (preferred when the config is reasonable): One question with these options:
- "Confirm all groups, continue to provision" (recommended default)
- "Adjust one or more groups (I will tell you which)"
- "Abort and regenerate the plan"
Flow B.3.b — per-group (preferred when several risks exist): Ask one question per non-trivial group, each with options:
- "Keep this group as-is"
- "Drop the following fields: …"
- "I will edit
field-config.jsonmanually"
After collecting the answers, summarize the final groups and issue ONE final confirmation dialog before writing review-confirmation.json and invoking item apply. If the final confirmation dialog was not issued or not answered, Stage B is unconfirmed — do not proceed to apply.
B.4 Post-confirmation actions (agent-side)
After the user confirms:
1. If any group changed, rewrite field-config.json with the new groups. 2. Update review-confirmation.json:
status = "confirmed"confirmedBy = "<reviewer name or 'user'>"confirmedAt = <current ISO timestamp>requiredChecks.{fieldTypesReviewed, fieldAttributesReviewed, displayStyleReviewed, runtimeFieldConfigReviewed} = truefieldConfigReview.{indexFields, filterFields, suggestFields, imageIndexFields, videoIndexFields}= final arrays
3. Run vs item apply --plan-dir <dir> --confirm-review (do NOT add --dry-run, do NOT degrade into OnlySave=true).
B.5 What NOT to do
- Do NOT merge Stage A and Stage B into a single confirmation.
- Do NOT skip Stage B because Stage A already happened; they cover different artifacts.
- Do NOT rely on a CLI-only confirmation step when the user is driving the workflow through an agent chat — that path loses the table + dialog UX.
- Do NOT claim the groups are "confirmed" just because
field-config.jsonexists; confirmation requires an explicit dialog answer. - Do NOT auto-confirm CLI bind prompts (
Proceed to bind the dataset with this field config? (yes/no):). - Do NOT treat a free-form chat reply ("yes", "ok", "looks good", "go ahead", etc.) as a dialog answer. The dialog MUST still be issued; the free-form text can at most populate the
Otheroption of that dialog. - Do NOT write
review-confirmation.jsonwithstatus=confirmedor anyrequiredChecks=trueuntil the matching stage's dialog has been issued and answered with a non-abort option. - Do NOT issue a placeholder Stage A confirmation before rendering the full schema table.
- Do NOT re-ask the same Stage A confirmation in a
dataset-onlyflow once a valid dialog has already been answered for the current schema draft.
---
Agent-mode apply handoff
After the agent has completed Stage A and, when needed, Stage B through in-chat tables + interactive dialogs:
1. Treat the dialog answers as the human review source of truth. 2. If the requested path is dataset-only, run dataset create and dataset ingest, then stop. Prefer the full dataset-create.json payload so Schema and DataFieldConfig.FieldDescMap are submitted together. Do not write a bind-time fieldConfigReview snapshot for a flow that never binds an app. 3. If the requested path is dataset+app, persist any approved group edits back to field-config.json. 4. For the dataset+app path, write review-confirmation.json with:
status = "confirmed"confirmedByconfirmedAt- all
requiredChecks = true fieldConfigReviewcontaining the final reviewed groups
5. For the dataset+app path, run vs item apply --plan-dir <dir> --confirm-review.
The CLI review artifact is now a simple review record. Agents do not need to compute or align a separate fingerprint.
---
Minimal Pseudocode for an Agent
# Stage A
render_header(plan)
render_schema_table(plan.schema)
render_risks(plan.profile, plan.validation)
answer_a = ask_dialog(
question = "schema confirmation?",
options = [confirm, rename_app, fix_schema]
)
if answer_a != confirm: handle and loop
if provisioning_mode == "dataset-only":
if file_exists("dataset-create.json"):
run("vs dataset create --data @dataset-create.json") # preferred: keeps Schema + FieldDescMap together; mandatory for video
elif plan.datasetType == "video":
stop("dataset-create.json is required for video dataset creation")
else:
run("vs dataset create --name <dataset> --type item --schema @schema.json") # fallback only when full payload is unavailable or unsuitable
run("vs dataset ingest --dataset-id <id> --fields @<normalized-items-artifact>")
stop
# Stage B
render_bind_summary(plan.fieldConfig)
if plan.datasetType == "video":
enforce_video_default_field_strategy(plan.fieldConfig) # see video-field-constraints.md
# fixes: video_url -> IndexFields; content_id/content_type/parent_content_id/sequence_index -> FilterFields;
# removes any of those fields from forbidden groups (SuggestFields, IndexFields vs FilterFields, etc.)
for group in [IndexFields, FilterFields, SuggestFields, ImageIndexFields, VideoIndexFields]:
render_group_table(group, with_reason_and_risk=True)
answer_b = ask_dialog(
question = "bind-time field-config confirmation?",
options = [confirm_all, adjust_groups, abort]
)
if answer_b == adjust_groups: per_group_dialog_loop()
if answer_b == abort: stop
persist_field_config_if_changed()
write_review_confirmation_json()
run("vs item apply --plan-dir <dir> --confirm-review")---
Related Files
- Plan artifacts consumed by this UX:
schema.json,field-config.json,review-confirmation.json,plan.json - Stage A constraint comes from review-checklist.md §1.
- Stage B constraint comes from review-checklist.md §2 and the bind-time rules in
vs-app-dataset-bind/SKILL.md. - Stage B video-specific server constraint comes from video-field-constraints.md (applied automatically in §B.2.1 before the dialog).
Agent Prompt Template
Use the text below when you want an external agent to run item-data onboarding with the vs-item-onboarding skill. The template is kept in sync with SKILL.md Hard Rules; if you change it, re-check the rule list there.
Template
Help me onboard a structured item dataset into Viking for item-level search.
Please confirm the following first:
1. SearchCLI and Viking skills are installed; if not, install them first. 2. The current terminal is already authenticated for Viking; if not, handle auth in this order:
- if
VIKING_AK/VIKING_SKalready exist in the current shell, runvs auth import-env; - otherwise, if you can keep a real terminal session open for user input, run
vs auth login; - otherwise, ask me to set
VIKING_AK/VIKING_SKin the current shell and then runvs auth import-env.
Then run this workflow:
1. Understand my business goal and the meaning of the dataset fields before using any generated plan. 2. Decide the dataset type explicitly:
- if I ask for a video dataset, use
--type video; - if I ask for an item / catalog / card dataset, use
--type item; - if the data contains video-like signals (
video_url,duration,content_type=video,parent_content_id,sequence_index) but I did not specify the type, ask me to chooseitemorvideobefore running any command; - never infer the dataset type from
--goalalone.
3. Decide the provisioning mode explicitly:
- if I ask only for dataset creation / import / ingestion, use the
dataset-onlypath; - if I ask for application creation, bind-time field config, search/chat verification, or app-level debugging, use the
dataset+apppath; - if I did not ask for app creation, default to
dataset-only.
4. Run vs item profile --file <DATA_FILE> --type <item|video> --pretty. 5. Run vs item plan --file <DATA_FILE> --type <item|video> --goal "<BUSINESS_GOAL>"; add --skip-app when the requested path is dataset-only. If execution later goes through vs item provision or vs item apply, those commands also accept --skip-app as an execution-time guard rail. 6. Review the plan artifacts that actually exist at this stage: schema.json, online-config.json, validation.json, and the search / recommend templates. If item plan also emitted field-config.json or embedded DataFieldConfig in dataset-create.json, treat those as draft execution artifacts only; they are not user-confirmed bind config yet. 7. Stage A — follow agent-confirmation-ux.md §A as the sole detailed UX contract. Render the header block first, then the full per-field schema table, then risk notes, and only then issue one interactive question dialog for approval of the generated schema.json draft (not a free-form yes/no, not a terminal y/N). Do not summarize only key fields. Make sure the Meaning values came from prompt-based inference grounded in the source data and the business goal; if they look wrong, fix schema.json before continuing. For --type video, also show whether content_id, content_type, video_url, parent_content_id, and sequence_index are present and which BizAttr mapping currently claims each slot. Never ask for schema confirmation before rendering the complete schema table; if you did, discard that dialog and restart Stage A instead of asking a second schema-level confirmation. 8. If the requested path is dataset-only, stop after one valid Stage A answer and provision only the dataset. Prefer vs dataset create --data @dataset-create.json so Schema and DataFieldConfig.FieldDescMap are submitted together. For --type video, this full-payload path is mandatory; using only --schema @schema.json can fail with MissingParameter.DefaultFieldStrategy. For --type item, fall back to vs dataset create --name <DATASET_NAME> --type item --schema @schema.json only when dataset-create.json is missing or clearly unsuitable for the current plan. Then run vs dataset ingest --dataset-id <DATASET_ID> --fields @<NORMALIZED_ITEMS_ARTIFACT>. Do not create or bind an application in this branch, and do not ask any second schema-level confirmation unless the schema changes and Stage A restarts. 9. If the requested path is dataset+app and a human reviewer wants a preflight preview, you may optionally run vs item apply --plan-dir <PLAN_DIR> --dry-run and summarize the planned steps. This is optional; do not let it replace Stage A or Stage B. 10. Stage B — only for the dataset+app path, after Stage A is confirmed, drive the bind-time field-config review yourself. Render one per-group table for IndexFields, FilterFields, SuggestFields, ImageIndexFields, VideoIndexFields, each with columns Field / Type / Meaning / Reason to include / Risk or note, and issue an interactive question dialog. For --type video, first load the authoritative DefaultFieldStrategy constraint table from references/video-field-constraints.md, enforce every row of it on the proposal in memory, and explain any auto-fix above the tables. Do not hard-code the constraint list into your own reasoning — always re-read the file; the server-side rules may evolve. Do not replace the agent dialog with a CLI-only confirmation step. 11. After Stage B is confirmed, write back field-config.json (if any group changed) and review-confirmation.json (status=confirmed, all requiredChecks=true, fieldConfigReview populated with the final groups), then run vs item apply --plan-dir <PLAN_DIR> --confirm-review directly. Do not keep --dry-run on this real bind step and do not degrade the request into OnlySave=true semantics. 12. Treat stage one as complete at the requested boundary: after dataset creation + ingest for dataset-only, or after dataset creation + ingest + app creation + bind for dataset+app. Do not add --wait-ready unless I explicitly ask for readiness verification. 13. For recommend bootstrap, only bind recommend scenes automatically when both the target page / module and the required BhvSceneTypes are known; in that case pass --confirm-recommend-entry-binding --recommend-bhv-scene-types <scene_a,scene_b>. Otherwise keep the generated recommend template and tell me what input is still needed. 14. If search or chat verification fails later, fall back to vs app diagnose --application-id <APP_ID>.
Output requirements:
- Start by summarizing your understanding of the business goal and the dataset.
- Explain the reasoning behind your schema, online-config, and (at bind time) field-config choices.
- If you ran an optional preflight preview, summarize its result before the real apply.
- Never merge Stage A and Stage B; always keep them as two separate table + dialog exchanges in that order.
- For Stage A, list every schema field (name, type, attributes, meaning) and, for
video, also list the status ofcontent_id,content_type,video_url,parent_content_id, andsequence_index; for Stage B, list every field in every group withReason to includeandRisk or note. - Never ask for Stage A confirmation before rendering the full schema table and completing the row-count self-check.
- Never auto-confirm either stage on my behalf. Free-form replies from me do not count as confirmation unless you captured them through the interactive question dialog.
- Never write
field-config.jsonorreview-confirmation.jsonbefore Stage B is confirmed through the dialog. - If I only asked for dataset provisioning, do not create or bind an application by default.
- If I only asked for dataset provisioning, do not ask a second schema-level confirmation after a valid Stage A answer for the current schema draft.
- Treat a successful dataset ingest (
dataset-only) or a successful bind (dataset+app) as the end of stage one; do not wait for readiness or run trials unless I explicitly ask. - If you find blocking issues, data-modeling problems, or a conflict between my answer and the video
DefaultFieldStrategy, stop and explain before continuing.
Filled Example
Help me onboard ./content-cards.json into Viking for content search.
Please understand the fields and the search use case first, then follow the vs-item-onboarding workflow:
1. Decide dataset type — this is a content-card catalog, so use --type item. 2. Run vs item profile --file ./content-cards.json --type item --pretty and vs item plan --file ./content-cards.json --type item --goal "Build content search". 3. Review schema.json, online-config.json, validation.json, and the search / recommend templates. If item plan emitted field-config.json or embedded DataFieldConfig in dataset-create.json, treat those as draft artifacts rather than confirmed bind config. 4. Stage A: render a per-field schema table (name, type, attributes, meaning) for every field and confirm it with me through an interactive question dialog. Make sure field meanings came from prompt inference grounded in source samples; fix any wrong meanings in schema.json before continuing. 5. Because I asked for content search, use the dataset+app branch rather than dataset-only. 6. Optional preflight: vs item apply --plan-dir <PLAN_DIR> --dry-run for a preview; this does not replace Stage A or Stage B. 7. Stage B: render per-group tables for IndexFields / FilterFields / SuggestFields / ImageIndexFields / VideoIndexFields with Field / Type / Meaning / Reason to include / Risk or note, and confirm through the dialog. Write back field-config.json and review-confirmation.json only after the dialog answer. 8. Real apply: vs item apply --plan-dir <PLAN_DIR> --confirm-review (no --dry-run, no only-save). 9. Stop here unless I explicitly ask for readiness checks, smoke trials, or recommend bootstrap. If recommend is needed and the target page / module and BhvSceneTypes are known, add --confirm-recommend-entry-binding --recommend-bhv-scene-types <scene_a,scene_b>; otherwise keep the template and tell me what is still missing.
If at any point you see a conflict with the video DefaultFieldStrategy constraint or blocking validation issues, stop and explain instead of force-applying.
Recovery Paths
When vs item apply, vs app dataset bind, or a subsequent search / chat verification fails, do NOT re-run the last command blindly. Diagnose the error, then follow the minimal fix path below. All recovery paths MUST preserve the Stage A / Stage B confirmation contract — if a fix changes schema.json or field-config.json, the corresponding stage MUST be re-rendered and re-confirmed through the dialog before re-applying.
Decision Procedure
For any failure, the agent MUST:
1. Capture the full error payload (code + message + any Detail / ResponseMetadata fields). 2. Match it to one of the entries below; if none match, run vs app diagnose --application-id <app> and surface its output to the user. 3. Apply the "Minimal fix" column exactly — do NOT combine unrelated fixes in one pass. 4. Re-run only the step that failed (usually the bind step), not the full item apply, unless the entry says otherwise. 5. If the fix changes plan artifacts, re-run the affected Stage (A or B) before re-applying.
Failure Catalogue
F1. MissingParameter.DefaultFieldStrategy
- Where it surfaces:
CreateDatasetorBindAppDatasetfor--type video. - Root cause: proposed
IndexFields/FilterFields/SuggestFieldsviolate video-field-constraints.md. - Minimal fix:
1. Re-load the authoritative table from video-field-constraints.md. 2. Apply the deterministic correction described in agent-confirmation-ux.md §B.2.1. 3. Rewrite field-config.json with the corrected groups. 4. Re-render Stage B per-group tables and re-issue the dialog (a violating proposal means the previous Stage B was effectively invalid). 5. Re-run vs item apply --plan-dir <dir> --confirm-review.
F2. InvalidParameter.SchemaMismatch / dataset schema conflict
- Where it surfaces:
BindAppDataset, after data was already ingested with a different schema. - Root cause:
schema.jsonin the plan no longer matches the dataset's stored schema. - Minimal fix:
1. Run vs dataset schema check --dataset-id <id> to diff the two schemas. 2. Decide with the user whether to:
- align the plan to the stored schema (edit
schema.json, re-run Stage A dialog), or - drop and recreate the dataset (only when data is reingestable and the user explicitly agrees).
3. Never silently mutate a live dataset's schema to satisfy the plan.
F3. ResourceAlreadyExists — dataset / app already exists
- See idempotency rules below. Not a real failure when the agent is reusing an existing resource; becomes a failure only when the agent tried to create a duplicate.
F4. PrimaryKey / duplicate-doc errors during ingest
- Where it surfaces:
ingest_itemsstep ofitem apply. - Root cause: source data contains duplicate primary-key values, or
PrimaryKeywas inferred incorrectly. - Minimal fix:
1. Run vs item profile --file <data> --type <item|video> --pretty and inspect primaryKeyCandidates / duplicateCount. 2. If the primary-key field is wrong: fix schema.json.PrimaryKey, re-run Stage A dialog, then re-apply. 3. If the data itself has duplicates: dedupe the source file first; do NOT bypass with --force unless the user explicitly acknowledges the loss.
F5. Bind succeeds but app diagnose reports NotReady
- Where it surfaces: after a successful bind, when the user requested second-stage verification.
- Root cause: default scene or runtime config has not finished provisioning, or
ChatConfig.SearchSceneIDis missing. - Minimal fix:
1. Run vs app diagnose --application-id <app> and read readiness / sceneBindings sections. 2. If SearchSceneID is missing, run vs item apply --plan-dir <dir> --run-trials (this bootstraps the default search scene and binds it). 3. If the scene exists but the app is still not ready, wait and re-check — do NOT re-bind.
F6. search run / chat run returns empty / irrelevant results
- Where it surfaces: smoke verification.
- Root cause: usually
IndexFields/FilterFieldschosen in Stage B are not aligned with the query shape. - Minimal fix:
1. Inspect the resolved field config via vs app dataset describe. 2. If the config is wrong, rewrite field-config.json, re-run Stage B dialog, and re-run vs app dataset bind. 3. If the config is fine but recall is still poor, suspect data quality (nulls, short titles, URL-only fields) — discuss with the user before touching the plan.
F7. Auth / token expired mid-flow
- Minimal fix: run the auth recovery chain from agent-prompt-template.md (
vs auth import-env→vs auth login→ ask user to setVIKING_AK/VIKING_SK), then resume from the failed step. No plan changes.
Idempotency Rules
Creating resources is NOT always retryable; Viking distinguishes between "resource exists with matching config" (safe) and "resource exists with mismatched config" (not safe).
Dataset already exists
- If
plan.json.defaults.datasetNamematches an existing dataset:
1. Call vs dataset describe --dataset-id <id> and diff its stored config against dataset-create.json. 2. If type, schema, and primary key all match → skip create_dataset; proceed to ingest. 3. If any of them differ → STOP and surface the diff to the user. Do NOT silently reuse the dataset.
- Never call
CreateDatasettwice for the same name assuming the second call is a no-op; the server may returnResourceAlreadyExistsand the agent MUST treat that as a match check, not as a success.
Application already exists
- If
plan.json.defaults.applicationNamematches an existing app:
1. Call vs app describe --application-id <id>. 2. If the app is unbound or bound to the same dataset the plan is targeting → reuse; proceed to bind (which itself is idempotent when the binding already matches). 3. If the app is bound to a different dataset → STOP and ask the user whether to rebind (destructive) or rename the plan target.
Binding already exists
BindAppDatasetwith the same(AppID, DatasetID, fieldConfig)IS idempotent server-side: it returns success without re-provisioning.BindAppDatasetwith the same(AppID, DatasetID)but a differentfieldConfigREPLACES the binding. The agent MUST re-run Stage B dialog before submitting a replacement bind; a silent overwrite is a bug.
Multi-dataset Context Isolation
When a single conversation onboarded more than one dataset, stale plan directories are a major source of silent corruption.
- The agent MUST always resolve
<plan-dir>from the most recent successfulvs item planoutput in the conversation. Never reuse an earlier<plan-dir>implicitly. - Every Stage A / Stage B dialog MUST echo back the resolved
<plan-dir>in its header so the user can catch a mismatch. review-confirmation.json.fieldConfigReviewMUST reflect the current plan's reviewed field groups; never reuse a review record from a different plan.- If the user's follow-up message implies a different dataset (new file path, new
--type, new goal), the agent MUST NOT continue with the previous<plan-dir>— run a newitem profile+item planfirst.
What NOT to Recover With
- Do NOT use
--forceto bypass validation unless the user explicitly asked for a controlled test. - Do NOT degrade the real bind to
--dry-runorOnlySave=truein order to "get past" a bind failure; the server rejection is the signal, not the obstacle. - Do NOT re-run
item applyfrom scratch when only the bind step failed — re-binding viavs app dataset bindis cheaper and avoids re-ingesting data. - Do NOT invent recovery steps that are not listed above; when unsure, ask the user or run
vs app diagnoseand surface the output.
Review Checklist
Before provisioning anything, first confirm whether the requested path is dataset-only or dataset+app. The schema review below always applies; the bind-time field-config review applies only to the dataset+app branch before running item apply.
1. schema.json
- Is
PrimaryKeya stable identifier rather than a display field or temporary ID? - Is the requested provisioning boundary explicit (
dataset-onlyordataset+app), so the agent does not create an application by default? - Are field names normalized into maintainable long-term names?
- Do field types match the raw data, especially for numeric, boolean, and multi-value fields?
- Are obvious large noise fields excluded from the stored schema?
- Before approval, has every schema field been shown to the user with its name, type, attributes, and intended meaning or use instead of only a key-field summary?
- Row-count anchor (Stage A): does the rendered schema table contain exactly
len(schema.json.Fields)data rows, with the fields in the same order as inschema.json? If the count differs, Stage A MUST be re-rendered before issuing the dialog. - Are all
Meaningcells populated? Empty meanings MUST be surfaced as⚠️ missing (please fix)in the table so the user can see the omission. - For
--type video, did the Stage A summary explicitly show the status ofcontent_id,content_type,video_url,parent_content_id, andsequence_index, including whether each semantic slot is present and which BizAttr mapping currently claims it?
2. field-config.json
- This section applies only to the
dataset+apppath. Skip it entirely fordataset-only. - Does
FieldDescMapdescribe the stored fields accurately and with stable business meaning? - Are field descriptions clear enough for later bind-time inference and manual review?
- Are image-like or display-facing fields described clearly enough for later
ImageIndexFieldsconfirmation? - Have the field attributes and display-facing expectations been confirmed with the user?
- For bind-time review (Stage B), has each of
IndexFields,FilterFields,SuggestFields,ImageIndexFields, andVideoIndexFieldsbeen presented to the user as a dedicated per-group table with columnsField / Type / Meaning / Reason to include / Risk or note? - Row-count anchor (Stage B): for every group
G, does the rendered table contain exactlylen(field-config.json.<G>)data rows, in the same order as infield-config.json? If any group mismatches, Stage B MUST be re-rendered before issuing the dialog. - Empty groups are still rendered: are all five groups rendered with a table header, even when the group is empty (shown with zero data rows + an italic line
_No fields currently proposed for this group._)? An absent group table MUST NOT be silently skipped. - No blank cells: are
Reason to includeandRisk / notepopulated for every row (defaulting tobusiness-goal alignment/none observedwhen no stronger signal exists)? - Has an interactive question dialog been issued to collect the user's decision for Stage B, instead of relying on a free-form yes/no or the
vs item reviewterminaly/N? - After Stage B confirmation, has
review-confirmation.jsonbeen updated withstatus=confirmed, allrequiredChecks=true, and afieldConfigReviewblock that records the final field groups shown to the user? - For
--type videodatasets, does the proposed field-config satisfy theDefaultFieldStrategyserver constraint? The authoritative rule table lives in video-field-constraints.md — this checklist intentionally does not duplicate the per-field rows to avoid drift. Verify by re-loading that file row by row against the currentfield-config.json, and if any row fails, fix the proposal and rerun Stage B before writingreview-confirmation.json.
3. online-config.json
- Do default search parameters align with the business goal?
- Does the chat config already include
SearchSceneID? - Have fields that should not be used online been excluded?
- Has the intended result-card or display style already been clarified with the user?
4. validation.json
- Are there any blocking issues?
- Are there duplicate primary keys, missing primary keys, missing titles, or mixed types?
- Did cleanup rename fields or normalize values more aggressively than expected?
5. search-scene*.json
- Are the scene name and description understandable to the next maintainer?
- Is the scene type appropriate for the current item-search scenario?
- If this is a new app, is the default search scene good enough for the first smoke check?
6. recommend-scene*.json
- Does the user actually need recommendation?
- Are
BhvSceneTypesalready known? - Has the target page / module been confirmed with the user?
- If behavior scene types are not known, do not force a recommend scene into production
- If the page / module is not confirmed yet, do not create or update the recommend scene
When Not To Continue With Apply
- The business goal is too vague to choose stable field descriptions or later bind-time field groups
- The user only asked for dataset provisioning, but the current plan would continue into app creation or binding
- The primary-key strategy is obviously unstable
- The raw data needs splitting, flattening, or aggregation before it can represent an item cleanly
- Validation still has blocking issues that the user has not accepted
- The page / module for recommendation is still unknown
When It Is Safe To Continue
- The schema and field config only need small edits
- Validation has warnings but no blocking issues
- If you chose to run an optional preflight preview,
item apply --dry-runshows the expected steps and resource names - The user has explicitly confirmed the full schema field-by-field, field attributes, display style, bind-time field groups, and any recommend entry binding
- The real bind step will run directly without
--dry-runorOnlySave=truesemantics once the user confirms
Video Dataset Field Constraints (DefaultFieldStrategy)
This reference documents the hard bind-time field-group constraints that the Viking aisearch server enforces for video datasets. Violating these constraints causes CreateDataset / BindAppDataset to fail with:
Error.Code = MissingParameter.DefaultFieldStrategy
Error.Message = The default field strategy is missing.These rules are NOT business recommendations. They are server-side validation rules (checkFieldConstraint in app_data_config.go). Any Stage B proposal that violates them will be rejected, regardless of how the agent reasons about the business goal.
Scope
- Applies to every dataset created with
--type video(Dataset.Type = 3). - Applies to both dataset-creation time (
DataFieldConfiginCreateDataset)
and bind time (vs app dataset bind --field-config).
- Does NOT apply to
itemdatasets;--type itemhas noDefaultFieldStrategy
constraint of this form.
Constraint Table
For every field below, the server enforces a fixed status (Must / Forbidden / Any) in each of the three bind-time field groups. Any means the agent is free to include or exclude the field based on business judgement.
| Field | IndexFields | FilterFields | SuggestFields |
|---|---|---|---|
video_url | Must | Forbidden | Forbidden |
content_id | Forbidden | Must | Forbidden |
content_type | Forbidden | Must | Forbidden |
parent_content_id | Forbidden | Must | Forbidden |
sequence_index | Forbidden | Must | Forbidden |
Legend:
- Must — the field MUST appear in that group. Omitting it causes
MissingParameter.DefaultFieldStrategy.
- Forbidden — the field MUST NOT appear in that group. Including it causes
the same error.
Any— no server-side constraint. Decide based on business goal and data.
ImageIndexFields and VideoIndexFields are not part of the DefaultFieldStrategy constraint table and are chosen based on the actual image / video asset fields in the schema. The fixed field video_url is commonly also added to VideoIndexFields for video feature extraction, but that is independent of the DefaultFieldStrategy table above.
Agent Checklist (Stage B for video datasets)
Before presenting the Stage B per-group tables and asking for confirmation, the agent MUST verify:
1. video_url
- [x] listed in
IndexFields - [ ] NOT in
FilterFields - [ ] NOT in
SuggestFields
2. content_id
- [x] listed in
FilterFields - [ ] NOT in
IndexFields - [ ] NOT in
SuggestFields
3. content_type
- [x] listed in
FilterFields - [ ] NOT in
IndexFields - [ ] NOT in
SuggestFields
4. parent_content_id
- [x] listed in
FilterFields - [ ] NOT in
IndexFields - [ ] NOT in
SuggestFields
5. sequence_index
- [x] listed in
FilterFields - [ ] NOT in
IndexFields - [ ] NOT in
SuggestFields
If any row fails, fix field-config.json / the Stage B proposal before running vs item apply --confirm-review or vs app dataset bind.
Why These Constraints Exist
The server relies on these fixed fields for video understanding and cross-video linking:
video_urlis the primary index signal that the video content pipeline
consumes. It must be indexable as a content field, so the server requires it in IndexFields. Treating it as a filter or suggest source would break the pipeline.
content_id,content_type,parent_content_id, andsequence_index
describe the hierarchical relationship between a collection (series) and its videos. They are structural identifiers rather than free-text search signals, so the server requires them only in FilterFields and forbids them in IndexFields / SuggestFields.
Common Failure Modes
- Putting
video_urlintoVideoIndexFieldsonly and forgetting to put it in
IndexFields → MissingParameter.DefaultFieldStrategy.
- Treating
content_id/parent_content_id/sequence_indexas "internal
system fields" and omitting them from FilterFields → MissingParameter.DefaultFieldStrategy.
- Including
content_typeinIndexFieldsbecause it looks like a search
facet → MissingParameter.DefaultFieldStrategy.
- Including
video_urlinSuggestFieldsbecause it is a string array →
MissingParameter.DefaultFieldStrategy.
See Also
vs-item-onboarding/SKILL.mdStage B video constraints sectionvs-app-dataset-bind/SKILL.mdStage B video constraints sectionvs-item-onboarding/references/review-checklist.md§2 bind-time reviewvs-item-onboarding/references/agent-confirmation-ux.mdStage B pseudo-flow
Walkthrough: Content Cards JSON
This walkthrough uses a generic content-card style JSON file such as:
./content-cards.json
It is a good fit for showing how content-card style item data moves through the onboarding flow.
1. Start With Profile
vs item profile --file ./content-cards.json --prettyTypical first-pass results are close to:
doc_idis inferred as the primary keytitleis inferred as the title field- field meanings are inferred well enough to populate
schema.json
2. Generate The Plan
vs item plan \
--file ./content-cards.json \
--goal "Build content search"In the plan directory, pay special attention to:
schema.jsononline-config.jsonvalidation.jsonsearch-scene-create.jsonrecommend-scene-create.jsonreport.md- Confirm the generated field meanings are grounded in prompt inference rather than ad-hoc guesses
- Do not expect
field-config.jsonat this stage; bind-time field groups are inferred only if you later choose thedataset+appbranch
3. Review The Plan Carefully
- Is
doc_idreally a stable primary key? - Does
titlerepresent the main card title well enough? - Do the generated field descriptions capture the real business meaning?
- Are content, keywords, category, and tag fields described clearly enough for later bind-time inference?
If any of these inferences look wrong, edit the generated JSON directly instead of forcing the first-pass output.
4. Optional Preflight Preview
If a human reviewer wants to preview the execution steps before the real app-provisioning run, use:
vs item apply --plan-dir ./.viking/item-plans/<plan> --dry-runTypical preview steps include:
validation_gateschema_checkcreate_datasetingest_itemscreate_applicationactivate_applicationsearch_scene_bootstrapsearch_trialchat_trial
If the user only wants dataset provisioning, skip this preview and use the dataset-only branch instead:
vs item plan \
--file ./content-cards.json \
--type item \
--goal "Build content search" \
--skip-appIf you later execute via vs item provision or vs item apply instead of the lower-level dataset commands, you may pass --skip-app again as an execution-time guard rail.
Then, after Stage A confirms the schema:
vs dataset create --data @dataset-create.json
vs dataset ingest --dataset-id <dataset-id> --fields @<normalized-items-artifact>Prefer the full dataset-create.json payload here so Schema and DataFieldConfig.FieldDescMap are submitted together. Fall back to --schema @schema.json only when that plan artifact is missing or clearly unsuitable for the current plan.
5. Run The Real Apply
vs item apply \
--plan-dir ./.viking/item-plans/<plan> \
--confirm-reviewUse this real apply only for the dataset+app branch. Treat bind success as the end of stage one. Only add readiness checks or --run-trials if the user explicitly asks for second-stage verification. After the user confirms the schema and bind-time field groups, run this real apply directly without --dry-run or only-save semantics.
If you already know the behavior scene types required for recommend bootstrap and the target page / module has been confirmed, add:
--confirm-recommend-entry-binding \
--recommend-bhv-scene-types your_bhv_scene6. Fallback Paths
- If the fresh app is not ready:
vs app diagnose --application-id <app> - If recall quality is poor after binding: inspect the bind-time field config and the search scene first
- If chat does not trigger retrieval: inspect the chat section of
online-config.jsonand the default search-scene binding
Walkthrough: Generic CSV Catalog
This walkthrough is intended for flat CSV datasets such as catalogs, content tables, asset tables, or SKU-style exports.
Assume the user provides:
./catalog.csv
Typical columns include:
item_idtitlecategorybrandpricetagsdescriptionimage_url
1. Run Profile
vs item profile --file ./catalog.csv --prettyConfirm these first:
- Is
item_idstable and unique? - Is
titlereally the display title users should search and see? - Is
tagsalready a multi-value field, or is it just a comma-joined string? - Should
pricebe used as a filter instead of an index field?
2. Run Plan
vs item plan --file ./catalog.csv --goal "Build catalog search"If the user only wants dataset provisioning, add --skip-app here. If execution later goes through vs item provision or vs item apply, you may pass --skip-app again as an execution-time guard rail.
Pay special attention to:
price,brand, andcategoryshould have clear field descriptions for later bind-time filter inferencedescriptionshould be described clearly enough for later search-field inferenceimage_urlmust remain a clearly described displayable URL for later image-field inference- If
tagsis a comma-separated string, split or fix its strategy before apply
3. Common Edits
- Improve
FieldDescMapwhen field meaning is vague or misleading - Clarify which structured fields are intended for later filter use
- Clarify which long-text fields are intended for later search use
- If CSV headers are messy, rename fields in the plan output to stable, maintainable names
4. Apply Strategy
If a human reviewer wants a preflight preview for the dataset+app branch, start with:
vs item apply --plan-dir ./.viking/item-plans/<plan> --dry-runAfter the user confirms the schema and bind-time field groups, continue with the real stage-one apply for the dataset+app branch:
vs item apply --plan-dir ./.viking/item-plans/<plan> --confirm-reviewTreat bind success as the end of stage one, and run that real apply directly without --dry-run or only-save semantics. Only continue with readiness checks or smoke tests when the user explicitly asks for that second-stage verification.
If the user only wants dataset provisioning, stop after Stage A and use:
vs dataset create --data @dataset-create.json
vs dataset ingest --dataset-id <dataset-id> --fields @<normalized-items-artifact>Prefer the full dataset-create.json payload here so Schema and DataFieldConfig.FieldDescMap are submitted together. Fall back to --schema @schema.json only when that plan artifact is missing or clearly unsuitable for the current plan.
5. When This Workflow Is Not A Good Fit
- One CSV mixes several different entities and needs table splitting first
- Key fields are nested JSON strings and require preprocessing
- There is no stable primary key
- The same column mixes incompatible value types such as price, prose, and booleans
Viking Item Onboarding — Workflow & Constraints
This reference holds the full, detailed workflow and constraint list for vs-item-onboarding. SKILL.md only keeps the short entry point and hard rules; everything operational lives here.
Commands
item profile: first-pass profiling for field shape, primary-key candidates, title candidates, cleanup, and validation riskitem plan: generate a reviewable first-pass draft that containsschema.json,online-config.json,validation.json, and search/recommend templates. It may also emit draft dataset-side config artifacts such asfield-config.jsonordataset-create.jsonwithDataFieldConfig; treat these as execution inputs, not as user-confirmed bind config. Add--skip-appwhen the requested outcome is dataset-only.item provision/item apply: both commands also accept--skip-app. Use it as an execution-time guard rail when you need to enforce dataset-only behavior from an existing plan or when the plan was generated before the boundary was finalized.dataset create/dataset ingest: the preferred dataset-only provisioning path after Stage A confirms the schema; preferdataset-create.jsonsoSchemaandDataFieldConfig.FieldDescMaptravel togetheritem apply: stable executor for thedataset+appbranch:validation gate -> schema check -> create dataset -> ingest -> create app -> bind dataset -> optional smoke checkssearch run/chat run: verify the new app with minimal runtime requestsrecommend scene create: continue recommend bootstrap only after the user confirms the target page / module and the requiredBhvSceneTypesapp diagnose: inspect readiness, scene, or runtime-config problems
Dataset Type Selection
The workflow supports item and video dataset types via the --type flag on item profile and item plan.
- If the user explicitly asks for a video dataset, you MUST pass
--type videoto bothitem profileanditem plan. - If the user explicitly asks for an item dataset, you MUST pass
--type item. - If the source data contains video-like signals (
video_url,duration,content_type=video,parent_content_id,sequence_index) but the user did not specify the dataset type, you MUST ask a clarifying question before planning or applying. - Do not infer dataset type from
--goalalone (e.g.Build video searchdoes not imply--type video). - Before
item apply, verify thatplan.json.defaults.datasetTypeanddataset-create.json.Typematch the requested dataset type.
Provisioning Mode Selection
After the dataset type is clear, the agent MUST decide the requested provisioning boundary:
dataset-only: the user wants a dataset created and ingested, but did not ask for app creation, bind-time field config, search/chat verification, or app-level setupdataset+app: the user explicitly wants an application created or reused, or asks for bind-time field config, search/chat verification, scene bootstrap, or app-level debugging
Rules:
- If the user did not ask for app creation or app-level setup, default to
dataset-only. - For
dataset-only, preferitem plan --skip-app, then rundataset create --data @dataset-create.jsonanddataset ingestafter Stage A so the dataset-sideFieldDescMapis submitted together with the schema. Fall back to--schema @schema.jsononly when the full payload is missing or clearly unsuitable for the current plan. If execution later goes throughitem provisionoritem apply, pass--skip-appagain as a guard rail. Stop there. - For
dataset+app, run the full Stage A -> Stage B ->item apply --confirm-reviewpath. - Do not create or bind an application "just in case". App creation is an explicit branch decision, not a default side effect.
Examples:
# Generic item / catalog / card-style dataset
vs item profile --file ./items.json --type item --pretty
vs item plan --file ./items.json --type item --goal "Build item search"
# Video dataset
vs item profile --file ./videos.jsonl --type video --pretty
vs item plan --file ./videos.jsonl --type video --goal "Build video search"Before provisioning anything, do not ask for a blind yes/no. Show the user the schema field-by-field (see agent-confirmation-ux.md §A):
- provisioning mode (
dataset-onlyordataset+app) - dataset type and dataset name
- application name (planned) or
not requested - every schema field (name, type, attributes such as
PK/Required/BizAttr, and intended meaning or use) - primary key and title field
- required fields
- for
video, the semantic-slot status and BizAttr mappings forcontent_id,content_type,video_url,parent_content_id,sequence_index; if any slot is missing or ambiguous, stop and fix the schema before approval
Do not issue the Stage A dialog until the header block is shown, the full schema table has been rendered, and the row-count self-check passes. If a dialog was issued earlier, discard it and restart Stage A instead of asking for a second schema confirmation.
Video Dataset Field Constraints
--type video carries HARD server-side constraints on the bind-time field groups (IndexFields / FilterFields / SuggestFields). Violations cause CreateDataset / BindAppDataset to fail with MissingParameter.DefaultFieldStrategy.
The authoritative table and the agent checklist live in video-field-constraints.md. This file intentionally does not repeat the table to avoid drift.
Before vs item apply --confirm-review on a video dataset, the agent MUST verify the Stage B proposal against that table. If the user explicitly adjusts Stage B in a way that violates the table, do not silently override the user; stop, explain the server constraint, and ask the user to amend the proposal.
Workflow
Each step below annotates which Hard Rules in SKILL.md constrain it, so the agent can map "what I am doing now" to "which rule stops me from making the common mistake".
1. Clarify the business goal and desired search experience: what users will search for, which fields matter most for recall, and whether the user wants dataset-only or dataset+app. 2. Determine the dataset type (item or video) using the rules above. (Hard Rule #1) 3. Determine the provisioning mode (dataset-only or dataset+app) using the rules above. If the user did not ask for app creation, default to dataset-only. (Hard Rule #2) 4. Skim a few raw rows, then run item profile --file <data> --type <item|video> for first-pass profiling. (Hard Rule #1) 5. Run item plan --file <data> --type <item|video> --goal "<business goal>" to generate the plan directory. Add --skip-app when the requested path is dataset-only. If execution later goes through item provision or item apply, those commands also accept --skip-app as an execution-time guard rail. (Hard Rules #1, #2, #6) 6. Review schema.json, online-config.json, validation.json with review-checklist.md. If item plan also emitted field-config.json or embedded DataFieldConfig in dataset-create.json, treat them as draft artifacts only; bind-time confirmation is still deferred to Stage B. (Hard Rule #6) 7. Stage A: explicitly ask the user for approval of the generated schema.json draft (name, type, attributes such as PK / Required / BizAttr, intended meaning). For --type video, explicitly show whether the semantic slots content_id, content_type, video_url, parent_content_id, and sequence_index are present and how they map to BizAttr. Do not treat first-pass plan generation as approval. Do not ask the user to confirm dataset-side field groups at this stage. The Stage A dialog may be issued only after the full schema context has been rendered. (Hard Rules #3, #4; UX contract in [agent-confirmation-ux.md §A](agent-confirmation-ux.md)) 8. Verify that schema Meaning values came from prompt-based inference grounded in source data and business goal. If meanings are wrong, or if any required video semantic slot is missing or ambiguously mapped, fix schema.json before continuing. If the plan emitted FieldDescMap or other draft field-group config, do not treat it as confirmed until the appropriate review stage. (Hard Rules #4, #6; "Additional MUST" below) 9. If automatic inference is wrong, edit the generated JSON directly. Fall back to lower-level dataset / app / search commands only when the item workflow is clearly a bad fit. 10. If the requested path is dataset-only, provision only the dataset and then stop after ingest succeeds. This branch has exactly one valid schema-level confirmation for the current draft: the Stage A dialog. Prefer dataset create --data @dataset-create.json so Schema and DataFieldConfig.FieldDescMap are submitted together. For --type video, this full-payload path is mandatory; --schema @schema.json alone can fail with MissingParameter.DefaultFieldStrategy. For --type item, fall back to dataset create --name <dataset> --type item --schema @schema.json only when dataset-create.json is missing or clearly unsuitable for the current plan, and surface that the remote dataset may not retain field meanings as reliably. Then run dataset ingest --dataset-id <id> --fields @<normalized-items-artifact>. Do not create or bind an application. (Hard Rules #2, #3, #9) 11. If the requested path is dataset+app and a human reviewer wants a preflight preview, optionally run item apply --plan-dir <dir> --dry-run and review the planned steps. 12. Stage B: for the dataset+app branch only, drive the bind-time field-config review per agent-confirmation-ux.md §B (one table per group + dialog). For --type video, first enforce the DefaultFieldStrategy constraint in memory. (Hard Rules #5, #7; the `vs-app-dataset-bind` skill's own Stage B MUST NOT be re-initiated here — see "Additional MUST" below) 13. After Stage B confirmation, hand off to the real apply path described in agent-confirmation-ux.md §"Agent-mode handoff to vs item apply". Do NOT assume the agent can safely hand-write review-confirmation.json from field-config.json alone. Use the CLI's own runtime snapshot path when recording the final review artifact, then run the real stage-one apply. Do NOT add --dry-run and do NOT degrade into OnlySave=true semantics. (Hard Rule #8; Pre-apply Checklist in `SKILL.md` MUST all pass first) 14. Treat the first stage as complete at the requested boundary: after dataset creation + ingest for dataset-only, or after dataset creation + ingest + app creation + bind for dataset+app. Do not keep waiting after that boundary by default. (Hard Rule #9) 15. item apply --run-trials is an optional second-stage verification that bootstraps a default search scene and binds it into ChatConfig.SearchSceneID. 16. If required behavior scene types are known and the target page / module has been confirmed, add --confirm-recommend-entry-binding --recommend-bhv-scene-types <scene_a,scene_b> for recommend bootstrap. Otherwise keep the generated recommend template and wait for user input. (Hard Rule #10) 17. If search or chat verification fails, use app diagnose --application-id <app> to inspect readiness, scene, and runtime config. For specific failure codes, see recovery.md.
Extended Constraints
The Hard Rules in SKILL.md are the MUST / MUST NOT set that would cause server-side failures or silent data corruption. The rules below complement them: some are additional MUST rules that were not hot enough to go into SKILL.md; others are Guidance that affect quality but not executability. Keeping them separated lets the agent recognise priority at a glance.
Additional MUST / MUST NOT
- Field
Meaninginschema.jsonMUST come from prompt-based inference grounded in source samples and the business goal; MUST NOT silently invent or hand-wave field meanings when prompt inference is available. - When asking the user to confirm
schema.json, MUST list every schema field with name, type, attributes, and intended meaning or use; MUST NOT summarize only key fields. - For Stage A, MUST NOT issue the dialog before the header block, the full schema table, and the row-count self-check are complete.
- If a Stage A dialog was issued before the schema context was fully rendered, MUST discard it and restart Stage A; MUST NOT compensate by asking a second schema-level confirmation for the same unchanged draft.
- When the user did not ask for application provisioning, MUST keep the flow in
dataset-onlymode and MUST NOT create or bind an app as a default side effect. - For
dataset-only, after one valid Stage A dialog answer is captured for the current schema draft, MUST proceed to provisioning or schema edits; MUST NOT ask another schema-level confirmation unless the schema changes and Stage A restarts. - For
--type video, Stage A MUST explicitly show the status ofcontent_id,content_type,video_url,parent_content_id, andsequence_index, including whether each semantic slot is present and which BizAttr mapping currently claims it. - For
dataset+app, all dataset-side field config (FieldDescMap,IndexFields,FilterFields,SuggestFields,ImageIndexFields,VideoIndexFields,TitleField) MUST be confirmed at bind time viavs app dataset bindor the bind stage ofitem apply; draft values emitted byitem planMUST NOT be treated as already approved. - For
dataset-only, preferdataset create --data @dataset-create.jsonwhenever that plan artifact exists, because it preserves dataset-sideFieldDescMapwhile keeping the workflow short. Do not re-run extra inference or ask a second confirmation just to use the full payload. - For binding, MUST use
item applystage-one semantics orvs app dataset bind; MUST NOT rely onapp activate. - MUST NOT bypass blocking validation issues; exception is an explicit controlled test with
--forceacknowledged by the user. - When driven by this skill, Stage B (bind-time field-config review) MUST be handled by this skill's flow; MUST NOT be re-initiated separately by the
vs-app-dataset-bindskill's own Stage B. Callvs item apply --plan-dir <dir> --confirm-reviewdirectly after this skill's Stage B dialog. - Agents MUST write
review-confirmation.jsononly after Stage B is confirmed through the agent dialog. The file should record the final bind-time groups that were shown to the user; do not add extra runtime-alignment logic beyond that review record. - When failures occur, MUST follow recovery.md (diagnose → match failure catalogue → apply minimal fix → re-run affected stage); MUST NOT blindly retry or combine unrelated fixes.
- When an existing dataset or app name matches the plan target, MUST follow the idempotency rules in recovery.md; MUST NOT silently reuse a resource with mismatched config.
Guidance (quality / process expectations)
item profile / plan / applyare stable execution primitives, not a substitute for human or agent judgement.- The generated
schema.jsonfromitem planis a first-pass proposal; allow review and manual edits for complex data. item applygenerates recommend templates; it only bootstraps recommend scenes automatically when--recommend-bhv-scene-typesis provided and--confirm-recommend-entry-bindingis explicitly acknowledged.- If the dataset obviously requires custom modeling, table splitting, or semantic cleanup, do not force the item workflow; explain why and switch to lower-level commands.
- When the same conversation onboards multiple datasets, always resolve
<plan-dir>from the most recentitem planoutput; do not reuse a stale one (see recovery.md "Multi-dataset Context Isolation").