| name | workbook-authoring |
| description | Author regenerated OAC workbook JSON with deterministic template-first generation, runtime semantic validation checks, MCP save-validation, and preview iteration. |
Workbook Authoring (Regenerated JSON, Runtime-Valid)
Use this skill to generate full workbook JSON that is both schema-shaped and plugin-runtime-valid for shipped template families.
Scope
- Two-mode authoring:
regenerate_workbook is the primary/default path (full deterministic regeneration).
modify_existing is additive and limited to supported scoped edits (filter-value edits, add filter-bar filter, title edits).
- Multi-canvas + multi-viz workbooks are allowed and expected when the use case requires them; do not default to single-canvas/single-viz unless explicitly requested.
- Disk-first output is mandatory.
- Public API/token flows are out of scope.
- Server sample workbook inspection is fallback-only.
- Save-target mode is independent from generation mode: update requests should replace existing workbook by default.
Preflight: OAC MCP connection (fail fast)
- Before anything else, confirm the
oac-mcp-server tools are live — this
skill reads the OAC catalog through them (discovery, describe_data,
save-validation). Probe once with a cheap oracle_analytics-search_catalog
call (or check claude mcp list → oac-mcp-server ✔ Connected).
Required MCP tools and capabilities
- Mandatory:
oracle_analytics_execute_logical_sql
oracle_analytics_describe_data
- Metadata discovery capability:
- prefer
oracle_analytics-find_matching_datasources when available for initial natural-language datasource matching
- then use
oracle_analytics-search_catalog for authoritative catalog resolution
- fallback to
oracle_analytics-discover_data only when newer discovery tools are unavailable
- Modify-mode source acquisition requires one of:
- content resource read capability for
content:// workbook JSON (via resources/read), or
- user-provided local workbook JSON file path.
- Save/export capabilities are optional and independent:
- if
oracle_analytics-save_catalog_content is unavailable, run disk-first generation + validation checks and return deterministic disk-only outcome
- if save is available but
oracle_analytics-export_workbook is unavailable, proceed with save + viewUrl and skip export
- Export is opt-in by user intent; default behavior is save + return
viewUrl without export
Required local assets
Resolve <WB_SKILL_ROOT> as the directory containing the active workbook-authoring SKILL.md. Common package paths:
-
.agents/skills/workbook-authoring (Codex full zip layout)
-
.claude/skills/workbook-authoring (Claude full zip layout)
-
skills/workbook-authoring (local skill/plugin install layout)
-
fail fast if none exist
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/templates/template-index.json
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/templates/*.json
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/metadata-to-json-mapping.v1.json
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/filter-profiling-contracts.v1.json
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/calculation-contracts.v1.json
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/version-field-catalog.json
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/runtime-profile-contracts.v1.json
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/semantic-validation-rules.v1.json
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/plugin-type-aliases.v1.json
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/viz-runtime-catalog.v1.json
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/viz-resolution-profiles.v1.json
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/presentation-polish-contracts.v1.json
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/edit-operation-contracts.v1.json
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/support-window.v1.json
-
<WB_SKILL_ROOT>/tools/runtime-validation-check.mjs
-
<WB_SKILL_ROOT>/tools/modify-workbook.mjs
-
<WB_SKILL_ROOT>/tools/regenerate-workbook.mjs
-
<WB_SKILL_ROOT>/tools/validate-requirements-trace.mjs
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/regenerate-workbook-contract.v1.json
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/regenerate-workbook-adapter-contract.v1.json
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/validation/schema-registry-profile.json
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/schemas/workbook-schema-manifest.json
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/schemas/*.js
-
In multi-version installs, choose <TARGET_VERSION> from installed folders under <WB_SKILL_ROOT>/ (minimum supported 26.01).
Required workflow
1) Parse intent
Capture:
- visual type
- business question
- dimensions/measures/time fields
- filters and layout expectations, including expected canvas count, viz distribution per canvas, and canvas names when known
- whether user intent is update existing workbook vs create new workbook
- whether detailed traces were explicitly requested (
trace, debug, diagnostics, or traceRequested=true)
2) Save target resolution (required)
- Keep generation policy fixed: regenerate complete workbook JSON from requirements.
- Detect save capability first:
- if
oracle_analytics-save_catalog_content is unavailable, skip remote target resolution and continue with disk-only output.
- Resolve save mode from user intent:
replace_existing when user asks to change/update an existing workbook (default for update intent).
create_new only when user explicitly asks for a new workbook/copy/variant.
- Resolve target workbook by capability:
- use
oracle_analytics-search_catalog when available.
- else use
oracle_analytics-discover_data only for metadata discovery and do not attempt remote save target resolution.
- In
replace_existing mode:
- require exactly one resolved workbook target (
id).
- if unresolved or ambiguous, fail fast with actionable message (do not silently create a new workbook).
- In
create_new mode:
- create with
parentId + name.
- if same-name workbook already exists and user did not request duplicate/copy behavior, fail fast instead of creating duplicates.
3) Authoring mode router (required)
- Route request to
regenerate_workbook unless intent clearly requests a supported scoped modify operation.
modify_existing supports only:
- edit existing filter operator/default/source values.
- add filter-bar filter for an existing criteria column.
- edit workbook/canvas/view titles; if title path is missing, create canonical path and then apply title update.
- Route to
modify_existing only when one source path is available:
- catalog content read for
content://, or
- user-provided local workbook JSON file path.
- If neither source path is available, fail with actionable guidance to download workbook JSON to disk and provide file path.
- Unsupported modify intents must fail with actionable
not supported in modify_existing mode.
- Keep
regenerate_workbook flow unchanged as primary path.
- Execute primary regenerate flow through the bundled driver:
node <WB_SKILL_ROOT>/tools/regenerate-workbook.mjs --request <request.json> [--target-version "<YY.MM>"] [--detected-target-version "<YY.MM>"] [--output <workbook.json>]
File-location convention (where the JSONs live). Author per workbook under
a workbooks/<name>/ directory beside bundle.yaml (mirrors
overlays/<name>/ and profiles/):
workbooks/<name>/request.json — the input spec (analysisRequirements).
workbooks/<name>/workbook.json — the generated, disk-first output.
workbooks/<name>/<name>.redacted.json — the only variant safe to commit.
Default --request workbooks/<name>/request.json and
--output workbooks/<name>/workbook.json when the caller doesn't specify
paths. Do not commit the raw workbook.json or any *bound* request —
they carry the OAC host / dataset UUID / session tokens; the bundle
.gitignore ignores workbooks/**/workbook*.json + workbooks/**/*bound*.json
(allowing *.redacted.json). Never write to /tmp (lost on reboot) or into
tests/live/ (that path is for skill evidence, not user work).
- Build request payload to satisfy
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/regenerate-workbook-contract.v1.json.
- Build
adapterPayload to satisfy <WB_SKILL_ROOT>/<TARGET_VERSION>/model/regenerate-workbook-adapter-contract.v1.json.
- For
compose_ootb, include approved analysisRequirements before generation:
- required gate:
brief -> discovery/profile -> requirements artifact -> explicit approval -> generate.
analysisRequirements.approval.status must be approved.
- Treat
analysisRequirements as the single approved story/spec planning artifact. Do not introduce a separate YAML or compact-spec runtime.
analysisShape and adapterPayload are supporting execution inputs: analysisShape may be explicit, or it may be bootstrapped from analysisRequirements.canvases; adapterPayload remains the datasource/profile evidence.
analysisRequirements may include workbook intent (workbook.name / description), datasource aliases, reusable field aliases, reusable calculations, report/canvas filters, canvas layout intent, top-level navigation/data actions, and optional theme/presentation hints.
analysisRequirements must align with analysisShape canvas/view IDs when both are provided.
- each compose view must include detailed planning (
purpose, grain, bindings, labels, filters, calculations, and sort, optional interactions) or supported shorthand that normalizes to those fields.
- supported view shorthand includes simple
type / viewType / visualization values plus fields such as x, y, category, value, metric, rows, columns, location, and filter.
- exact
pluginType, explicit semantic-role bindings, exact calculations, interactions, and full data action metadata remain valid advanced planning; shorthand must not replace detailed planning when exact runtime shape is known.
- unsupported shorthand or conflicting shorthand vs explicit bindings must fail fast; do not silently substitute another visualization.
- each normalized
analysisRequirements.canvases[].views[].filters[] entry must include:
filterID, columnID, location, scope, operator, default, planningOutcome.
- compose preflight lint behavior is controlled by optional
composeFilterTolerance.mode:
- default
strict: missing filter fields fail fast with JSON-pointer diagnostics (for example /analysisRequirements/canvases/0/views/0/filters/0/scope) before generation starts.
- optional
tolerant: missing scope auto-fills to global; missing default is derived from adapterPayload.profiling.filterDecisionTrace.derivedDecisions when possible; if derivation is not possible, fail fast with deterministic diagnostics.
- regenerate output includes
composeFilterToleranceSummary with mode and auto-fill telemetry.
- minimal valid filter object shape:
{"filterID":"flt_year","columnID":"dim_time_year","location":"filter_bar","scope":"global","operator":"in","default":["2025"],"planningOutcome":"applied"}
- Recommend (do not require)
analysisShape.canvases[].name during initial generation so canvas titles are created correctly in one pass.
- If canvas names are omitted, generation remains valid and titles can still be edited later.
- Set
generationStrategy explicitly for deterministic routing:
- prefer
compose_ootb by default for new workbook generation.
- use
passthrough_bound only when one of these is true:
- the user explicitly asks to use an existing workbook and modify/preserve its current structure, or
- the user asks to modify a previously
compose_ootb-generated workbook using that workbook as bound input.
- Do not let bound input presence alone (
adapterPayload.binding.boundWorkbookJson|boundWorkbookPath) force passthrough in agent routing; set generationStrategy="compose_ootb" unless a passthrough condition above applies.
- If
generationStrategy="auto" is used, runtime routing is deterministic and will choose passthrough_bound whenever bound input exists; avoid auto for new-generation flows.
passthrough_bound requires bound workbook input and should not be blocked by OOTB topology limits.
request.workbook.name / request.workbook.description are save-layer metadata inputs only; do not persist them in workbook content.json.
- Consume regenerate response
saveMetadata for save-layer handoff (name / description) when save is attempted.
- requirements trace uses severity split:
- blocking mismatches (for example unresolved bindings/filters/calculations/placeholders) fail compose.
- warnings (for example title caption mismatch) are returned in
requirementsTraceSummary.warnings and do not block.
4) Modify-existing mode contract (when routed to modify_existing)
- Source acquisition gate (required):
- prefer catalog JSON read (
content://) when available.
- otherwise require user-provided local workbook JSON file path.
- if neither source path is available, fail with actionable guidance (download workbook JSON and provide file path).
- Resolve workbook target via catalog (
id/path/name) for remote replace flows. If ambiguous, fail with candidate list and do not write.
- Require explicit confirmation before every modify write.
- Source mode defaults to catalog JSON read (
content://).
- Same-session fast-path bypass is allowed only when all are true:
- same-session artifact path exists.
- session artifact workbook id is present.
- session artifact workbook id equals resolved target id.
- On fast-path version/concurrency conflict, fail immediately (no auto-read fallback).
- Apply deterministic mutator via
<WB_SKILL_ROOT>/tools/modify-workbook.mjs with --operation set to a supported operation id from <WB_SKILL_ROOT>/<TARGET_VERSION>/model/edit-operation-contracts.v1.json.
- Add-filter operation requires
columnID already present in criteria.columns.children; if omitted canvas scope defaults to all canvases.
- Title-edit operation may create missing canonical title paths (
viewCaption.caption.text) before applying updates.
5) Metadata discovery
- Choose discovery method by tool capability:
- use
oracle_analytics-find_matching_datasources first for natural-language datasource shortlist when available.
- use
oracle_analytics-search_catalog to resolve and validate datasets and subjectAreas authoritatively.
- otherwise use
oracle_analytics-discover_data only as compatibility fallback when newer discovery tools are unavailable.
- Build shortlist with
id, type, name, xsaExpr, viewUrl.
- Use
oracle_analytics-describe_data in two phases:
tablesOnly=true
- targeted
tableName/tableNames
- normalize field map: dimensions, measures, temporal, datatypes, defaults.
6) Filter profiling (required)
- Run deterministic filter profiling probes from
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/filter-profiling-contracts.v1.json using oracle_analytics_execute_logical_sql.
- Profile candidate filter columns by class:
- dimensions: top values + cardinality estimate
- measures: min/max (+ bounded distribution sample where needed)
- temporal: min/max + granularity hint
- Enforce guardrails from the contract (deterministic sort/fetch, row/time limits, bounded retries).
- If an individual profiling probe fails, continue with conservative fallback defaults and record fallback reason in filter decision trace.
7) Plugin resolution (required)
- Resolve requested viz plugin type through
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/viz-resolution-profiles.v1.json.
- Determine
runtimeContractFamily, canonicalScaffoldTemplateId, and finalPluginType from resolution profile.
- Use
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/plugin-type-aliases.v1.json only as compatibility fallback metadata.
- If requested plugin type is unmapped in resolution profiles, stop and report missing resolution contract before generation.
8) Profile handshake (version + runtime dialect)
- Resolve target version from installed
<WB_SKILL_ROOT>/<YY.MM>/ bundles.
- If
targetVersion is provided, it must match an installed bundle folder.
- If exactly one version bundle is installed and
targetVersion is omitted, runtime auto-selects it.
- If multiple bundles are installed and
targetVersion is omitted, runtime honors version-bundles.json defaultTargetVersion when present. Without a manifest default, runtime prefers 26.07 when discovery is search_catalog and save is available; otherwise runtime prefers 26.05 when installed, else latest.
- If a prior save validation payload contains version-mismatch signatures, pass
detectedTargetVersion (or --detected-target-version) to keep retries sticky to the last accepted target.
- Always report selected
targetVersion in user-visible output.
- Read support-window + runtime contracts from the selected version bundle for deterministic generation and validation-check behavior.
- Resolve the internal schema target ID from the selected support-window entry for generation.
- Resolve runtime profile/dialect from
runtime-profile-contracts.v1.json.
- Resolve runtime family from viz resolution profile (not by template guesswork).
- Use default dialect; allow one fallback dialect only when known runtime errors indicate mismatch.
9) Template-first generation + calculations
- Start from resolution profile
canonicalScaffoldTemplateId; if user requested a different supported template, use that.
- Keep template IDs stable; bind metadata into selected template.
- Use
metadata-to-json-mapping.v1.json for deterministic binding.
- In
compose_ootb, normalize supported analysisRequirements shorthand first, then consume per-view planning (purpose, grain, bindings, labels, filters, calculations, sort) before semantic fallback inference.
- Rebind direct
criteria.columns[].columnFormula.expr.expression values from scaffold defaults to target subject-area expressions using adapterPayload.describe.columns.
- Post-bind, validate that every referenced
columnID resolves in criteria.columns and each direct formula uses the selected subject-area token and a described target expression; fail fast if unresolved.
- Build workbook structure to match requested analysis shape (single or multi-canvas; single or multi-viz per canvas).
- Preserve requested plugin type by default when a requested plugin lock is provided; do not silently substitute viz types.
- Do not invent ad-hoc JSON shapes.
- Evaluate metric fit:
- If base measures satisfy intent, bind base measures directly.
- If no base measure fits, auto-gap-fill using workbook-local calculations from
calculation-contracts.v1.json.
- Supported calc types:
EXPRESSION, TEXT_GROUP, TIME_SERIES.
- Calculation columns must be persisted under
criteria.columns.children with userExpression=true, columnFormula.expr.expression, and deterministic calc IDs.
- Typed calculations (
TEXT_GROUP/TIME_SERIES) must persist criteria.criteriaConfig.settings.columnPropertyMap[columnID] with type, parentExpression, and options.
- Nested calc references must use
@calculation("<columnID>") and reference calc columns that exist.
- Any derived formula column that is not a direct source-column reference must be marked
userExpression=true (do not emit non-editable derived formulas).
- Persist formulas in OAC Logical SQL; translate source-workbook dialects first. Do not emit Tableau
COUNTD(...); use governed measures or COUNT(DISTINCT ...). POSITION(expr1 IN expr2) is valid OAC syntax.
- Filter mode defaults to
filter_bar; use filter_viz only when explicitly requested.
- For
filter_viz, generated wiring must be runtime-complete:
viewConfig.settings["viz:filter"].filterIDMap / parameterIDMap must exist when relevant.
- filter-viz row
logicalEdgeLayers must match map keys (columnID for column controls, name for parameter controls).
- every map value must resolve to a real filter control ID linked to the same filter-viz view (
location=filter_viz, filterViz=<viewName>).
- If a filter default uses
listParameterBinding/startParameterBinding/endParameterBinding, declare the matching parameters.settings[].name; generated shared listbox bindings use multi-value text parameters.
- Do not persist placeholder UI states such as
None or All into criteria.filter; persist only real query defaults.
- Data actions use top-level
dataActions[], not dataActions.children; BI Navigation and URL Navigation actions must follow the BI Tech source schema and bind context/anchor columns to criteria columns.
- if
generationStrategyApplied=passthrough_bound, do not auto-repair invalid filter wiring; fail fast with deterministic diagnostics.
- Use profiling outputs to choose filter operators/default values and de-prioritize high-cardinality filter candidates unless explicitly requested.
- If the user requests number-format behavior (for example currency, decimal places, grouping, abbreviation, or negative style), persist number-format config in plugin
viewConfig.settings.
- For chart-family settings, use
viewConfig.settings["viz:chart"]:
- use
numberFormat for a shared/default chart formatter.
- use per-field overrides with runtime key conventions (do not use dotted keys like
numberFormat.<fieldLabel>):
- for chart/table/pivot/autoviz/combo families, use
bidvtchart_number_format_<token> and optional variants like bidvtchart_number_format_<token>:::<columnID> and .tooltip.
- for performance tile families, use
numberFormat<token> and optional variants like numberFormat<token>:::<columnID> and .tooltip.
- Number-format payload must follow workbook number-format schema fields (for example
style, currency, useGrouping, minimumFractionDigits, maximumFractionDigits, useAbbreviation, abbreviationScale, negativeValuesStyle, currencyDisplay).
- Number-format enum values must be save-compatible:
abbreviationScale is off|on|thousand|million|billion|trillion (on means automatic abbreviation), and negativeValuesStyle is default|accounting|red|red_accounting (default means minus-sign negatives).
- Do not persist unsupported aliases such as
abbreviationScale:"auto" or negativeValuesStyle:"minus"; normalize them to on and default before validation/save.
- Do not place number-format payloads at workbook root or criteria nodes; keep them under the owning plugin
viewConfig.settings path.
- Presentation polish request block is optional and additive:
presentationPolish.mode: auto | off | strict
presentationPolish.layoutTemplateHints: optional defaultArchetype, byCanvasID, byCanvasIndex
presentationPolish.titlePolicy: optional question_oriented | preserve_input
- Default polish behavior:
- for
compose_ootb, default presentationPolish.mode=auto (apply neutral_v2 layout/style polish + UX lint warnings)
- for non-
compose_ootb, default presentationPolish.mode=auto unless explicitly disabled
- Polish applies deterministic layout archetype normalization (
executive_dashboard, filter_bar, filter_rail, content_grid, cover) and keeps filter preference filter_bar unless user explicitly requests filter_viz.
- In
strict mode, severe UX lint findings must fail generation before save (do not bypass runtime checks).
- Return
presentationPolishSummary in normal output with effectiveChangeCount, layoutChangeCount, styleChangeCount, and noOpReasons; include presentationPolishTrace only when trace is explicitly requested.
- Visualization intelligence request block is optional and advisory-only:
visualizationIntelligence.mode: auto | off (default auto)
visualizationIntelligence.audienceProfile: optional object (for example role, targetLevel) used to tune recommendation wording.
- Visualization intelligence must never block generation/save; if scoring fails, return deterministic
dvIntelligenceSummary.status=scoring_unavailable and continue.
- Return
dvIntelligenceSummary in normal output with overallScore, audienceLevel, dimensionScores, recommendations, evidenceCoverage, and versionProfile; include dvIntelligenceTrace only when trace is explicitly requested.
- Best effort documentation link: if
dvIntelligenceSummary.references is present, include the first reference URL when explaining scoring to end users.
10) Deterministic validation gate (required)
- Schema validation check via bundled schemas/schema registry.
- Semantic validation check via runtime contracts.
- Calc-aware semantic checks must pass:
- calc references resolve
- calc dependency graph is acyclic
- typed calc columnPropertyMap payload exists and is valid
- calc columns are ordered deterministically before dependents
regenerate-workbook.mjs runs requirements-trace validation, canonicalization, and strict semantic validation check automatically.
- Use manual check commands below only for direct debugging or deterministic patch/retry loops.
- Run requirements-trace validation before runtime validation:
node <WB_SKILL_ROOT>/tools/validate-requirements-trace.mjs --request <trace-request.json>
- Run canonicalization check (in-place) before strict validation:
node <WB_SKILL_ROOT>/tools/runtime-validation-check.mjs --input <workbook.json> [--target-version "<YY.MM>"] [--detected-target-version "<YY.MM>"] [--requested-plugin-type "<pluginType>"] --discovery-method "<search_catalog|discover_data>" --save-available "<true|false>" --export-available "<true|false>" [--export-requested "<true|false>"] [--version-selection-reason "<default_policy|user_requested_newer|required_newer_behavior|capability_heuristic_2607|capability_heuristic_2607_missing_fallback_latest|capability_heuristic_2605|capability_heuristic_2605_missing_fallback_latest|validation_fallback|session_sticky>"] --apply-known-patches --in-place
- Then run strict semantic validation check:
node <WB_SKILL_ROOT>/tools/runtime-validation-check.mjs --input <workbook.json> [--target-version "<YY.MM>"] [--detected-target-version "<YY.MM>"] [--requested-plugin-type "<pluginType>"] --discovery-method "<search_catalog|discover_data>" --save-available "<true|false>" --export-available "<true|false>" [--export-requested "<true|false>"] [--version-selection-reason "<default_policy|user_requested_newer|required_newer_behavior|capability_heuristic_2607|capability_heuristic_2607_missing_fallback_latest|capability_heuristic_2605|capability_heuristic_2605_missing_fallback_latest|validation_fallback|session_sticky>"]
- Canonicalization pass must seed runtime defaults (
parameters._version, color/shape service domain scaffolding) to avoid first-open UI dirty rewrites.
- Runtime validation check enforces schema acceptance and strips known-safe internal trace payload keys (
oracle.bi.tech.workbookAuthoringTrace) before save attempts.
- Must pass global checks and plugin-family checks before save attempts.
--requested-plugin-type is optional and should be used only for single-anchor-viz lock scenarios.
- For multi-viz workbooks, omit
--requested-plugin-type; the check still validates all plugin views and family/runtime invariants.
- For modify mode, run validation check with explicit modify context:
node <WB_SKILL_ROOT>/tools/runtime-validation-check.mjs \
--input <workbook.json> \
--discovery-method "<search_catalog|discover_data>" \
--save-available "<true|false>" \
--export-available "<true|false>" \
[--export-requested "<true|false>"] \
[--version-selection-reason "<default_policy|user_requested_newer|required_newer_behavior|capability_heuristic_2607|capability_heuristic_2607_missing_fallback_latest|capability_heuristic_2605|capability_heuristic_2605_missing_fallback_latest|validation_fallback|session_sticky>"] \
--authoring-mode "modify_existing" \
--requested-operation "<operation_id_from_edit-operation-contracts.v1.json>" \
--source-mode "<catalog_read|session_fast_path>" \
--confirmation-state "confirmed" \
--resolved-workbook-id "<targetId>"
- Execution order is strict: do not parallelize
generate -> check -> save -> optional_export.
- Parallelism is allowed only for independent metadata discovery reads.
- Runtime validation check capability inputs are mandatory and capability-driven: always pass
--discovery-method, --save-available, and --export-available from runtime tool detection.
- Pass optional
--export-requested from explicit user intent for export; if omitted, validation check defaults exportRequested=false.
- If orchestration has explicit version-target intent, pass optional
--version-selection-reason (default_policy|user_requested_newer|required_newer_behavior|capability_heuristic_2607|capability_heuristic_2607_missing_fallback_latest|capability_heuristic_2605|capability_heuristic_2605_missing_fallback_latest|validation_fallback|session_sticky); otherwise validation check derives deterministic fallback reason. Optionally pass --detected-target-version when continuing from a prior save-validation mismatch.
- If any required capability input is missing, runtime validation check must fail fast with deterministic
MISSING_EXECUTION_CAPABILITY_INPUT and no save attempt.
- If validation check returns
INPUT_ARTIFACT_NOT_READY, treat it as an orchestration/readiness issue and rerun validation check after generation completes.
- If filter-viz tiles show
No Data, diagnose filter-viz map/linkage first:
- verify
FILTER_VIZ_HAS_REQUIRED_MAPS, FILTER_VIZ_MAP_KEYS_MATCH_LDM_ROW_BINDINGS, FILTER_VIZ_MAP_VALUES_MATCH_EXISTING_FILTER_CONTROLS, and FILTER_VIZ_FILTERCONTROL_LINKAGE_CONSISTENT.
- resolve those invariants before attempting save/export retries.
11) Save loop (disk-first)
- Save JSON locally first and return local path.
- For workbook saves, payload must be wrapped as:
content: { json: <workbook-json-object>, blobs?: [...] }
- Do not pass workbook root JSON directly as
content.
- Pre-save guard: if
type="workbooks" and content.json is missing, fail fast locally before MCP call with an actionable message.
- Keep workbook payload schema-clean: root
name / description must not be present in content.json. Use save-layer metadata (saveMetadata) in save call arguments instead.
- Example:
oracle_analytics_save_catalog_content({
type: "workbooks",
parentId: "<folderId>",
name: "FIFA18_2Canvas_Analyses_1_8",
userApproved: true,
content: {
json: workbookJson
}
});
- Optional blobs:
content: {
json: workbookJson,
blobs: [...]
}
- Save mode contract:
replace_existing -> call oracle_analytics_save_catalog_content with workbook id (replace mode), not parentId.
create_new -> call oracle_analytics_save_catalog_content with parentId + name (create mode).
- Prefer canonical wrapped payload (
content: { json: <workbook-json-object>, blobs?: [...] }) for all saves.
- Server/tool may auto-wrap root workbook objects in some environments, but do not rely on auto-wrap behavior in skill workflow.
- Invalid save payload patterns (reject locally before save call):
- file path references as
content (for example /tmp/workbook.json)
jsonPath-style wrappers or path indirection for workbook content
- non-JSON string content that cannot parse to a JSON object
- Save transport fallback sequence (deterministic, max one retry):
- Pre-save compaction guard: if the workbook JSON is already large enough that Codex MCP argument truncation/transport limits are likely, minify the same workbook object before the first MCP save call.
- Compaction is whitespace-only unless generation knobs are explicitly being changed for a retry; parse original and minified forms and verify canonical deep equivalence (or matching canonical hash) before save.
- Attempt 1 (canonical):
content: { json: <workbook-json-object>, blobs?: [...] }, using the minified-equivalent object when compaction was applied.
- If attempt 1 fails with payload-shape/transport signatures (for example
content string must be valid JSON object, workbook content must include json, Unable to parse the provided json, serialization/size transport errors), run one compaction retry if it was not already applied.
- If payload truncation/argument-size limits are suspected after canonical compaction, generate one reduced-size retry candidate with
numberFormatting.policy=none and presentationPolish.mode=off while keeping the same analysis intent and topology.
- Attempt 2 (interop fallback): retry with string form accepted by save tool (
content as stringified JSON object, or content.json as stringified JSON when wrapper is required by caller environment).
- Do not perform additional transport retries after attempt 2.
- If save tool is available, execute the sequence above and stop on first success.
- On save success, return saved target +
viewUrl immediately.
- If user explicitly requested export and export tool is available, run
oracle_analytics-export_workbook and return preview artifact when ready.
- If save tool is unavailable:
- skip MCP save without failing generation,
- return deterministic disk-only outcome and local artifact path.
- If save succeeded but export tool is unavailable, skip export and still return saved target +
viewUrl.
- In no-save environments,
modify_existing may return modified local JSON output but must not attempt server-side replace.
- In trace mode only, emit
savePayloadMode (canonical_object|stringified_object) and compactionApplied (true|false).
- On save failure, return concrete payload-shape diagnostics including attempted payload mode, matched signature (if any), failure stage, and blocking constraint.
12) Deterministic remediation (one retry max)
If save/runtime returns known error signatures:
- Map error -> patch action from
runtime-profile-contracts.v1.json.
- Apply deterministic patch set only.
- Re-run semantic validation check.
- Retry save once.
Example patch run:
node <WB_SKILL_ROOT>/tools/runtime-validation-check.mjs \
--input <workbook.json> \
--discovery-method "<search_catalog|discover_data>" \
--save-available "<true|false>" \
--export-available "<true|false>" \
[--export-requested "<true|false>"] \
[--version-selection-reason "<default_policy|user_requested_newer|required_newer_behavior|capability_heuristic_2607|capability_heuristic_2607_missing_fallback_latest|capability_heuristic_2605|capability_heuristic_2605_missing_fallback_latest|validation_fallback|session_sticky>"] \
--runtime-error "<save-or-runtime-error-text>" \
--apply-known-patches \
--in-place
If second attempt fails:
- return structured diagnostics
- include contract gap summary
- stop auto-retry
13) Server sample fallback policy
- Do not inspect existing server workbooks by default.
- Allowed only when validation checks pass and one remediation retry still fails runtime/visual acceptance.
- When fallback is used, report the missing/insufficient contract rule.
14) Issue capture and feedback package (opt-in sharing)
When authoring fails, prepare a local feedback package that the user may choose to share.
Failure triggers:
- validation check failure
- save validation failure
- export failure
- saved workbook fails to open/render in UI
- deterministic retry exhausted or unresolved contract gap
Feedback package contract (docs-level, agent-generated):
- package folder name:
feedback-<YYYYMMDD-HHMMSS>-<short_slug>
- required files in both modes:
ISSUE_REPORT.md
feedback_manifest.json
environment_context.json
- mode enum:
full | sanitized (default full when mode is not specified)
feedback_manifest.json must include: mode, targetVersion, authoringMode, failureStage, failureCode, failureMessage, includedFiles, omittedFiles, checksums
- deterministic
failureStage values: validation_check | save | export | ui_runtime | unknown
Mode behavior:
full: include raw artifacts when available (request payload, generated workbook JSON, validation check outputs, save/export error payloads, trace diagnostics).
sanitized: include redacted summaries and field-level masks; do not include raw workbook JSON by default; include omitted-artifact inventory in manifest/report.
Sharing policy:
- always create the package locally first
- never auto-share
- present a concise ready-to-share summary and ask whether the user wants to share
- recommend
sanitized for external sharing; full is acceptable for internal skill maintainers
- if user declines sharing, keep package local and continue troubleshooting
Runtime invariants to enforce
table: no column-edge layers; row carries dimension+measure.
chart_autoviz: innerPluginType, measuresList view entry, embedded MeasureView_0, hidden color measure layer, nested property additions.
chart_autoviz donut normalization: nested property additions must also include min.<measure> and max.<measure> entries.
oracle.bi.tech.chart.scatter: do not treat scatter as generic multi-measure autoviz. Scatter uses one embedded MeasureView_0; top-level and nested measure layers must carry obitech-scatterchart#x / obitech-scatterchart#y tags; nested X/Y layers must include the source-backed min/max/median/color propertyAdditions; and MeasureView_1-style nested measure scaffolding is blocked until backed by a runtime fixture.
chart_combo_multilayer: explicit combo dataLayersInfo in viewConfig + logicalDataModel, valid activeDataLayer, nested layer models per declared layer, and non-empty per-layer measure bindings.
pivot: requires row edge, column edge, and measures edge bindings.
gantt: requires row/category binding plus logical item edge with start/end tags (obitech-gantt#start, obitech-gantt#end).
parallel_coordinates: requires row binding plus at least two measure bindings on logical col edge.
performance_tile: requires logical measures binding and primary measure presence.
map: geography/category fields bind through logicalEdges.detail; metrics bind through map-specific color/size/layer roles, never execution column because OAC renders that role as Unused. Embedded map scaffolds use dataLayersInfo to mirror map logical edges, keep primary row/column edges unbound, carry detail on nested MeasureView_0 row, and use __EmbeddedVizDummyMeasureLink__ only as the embedded runtime measure marker.
ui_control: plugin view pluginType must be mapped; do not inject chart/table data-model assumptions.
layouts.children[].layoutProps.customProps.text must be a JSON-encoded object string; split layouts must include oracle.bi.tech.layout.split.layoutMinSize. Generate this field with JSON.stringify, not manual JSON text.
- profile-required
reportConfig service/settings nodes.
- runtime-canonical defaults:
parameters._version, missing filter parameter-binding definitions, color measure domains, and shape domains are pre-seeded so UI interaction does not rewrite workbook JSON immediately.
- calculations:
@calculation("<columnID>") references must resolve to userExpression columns
- no calc dependency cycles
- typed calc entries require
criteria.criteriaConfig.settings.columnPropertyMap[columnID]
- no unsupported source-workbook formula dialect such as Tableau
COUNTD(...)
- filter parameter bindings resolve to
parameters.settings[].name
- data actions use top-level
dataActions[] and source-schema BI Navigation/URL Navigation payloads
criteria.filter placeholder literals such as None/All are warning-level diagnostics
Output contract
Default output mode is concise.
By default, return only:
- local JSON file path (if produced)
- saved workbook identifier/path (or explicit disk-only outcome when save is unavailable)
viewUrl on save success
- selected
targetVersion (always report this, including auto-selected single-bundle runs)
- selected authoring mode (
regenerate_workbook or modify_existing)
- semantic validation check result summary
- evidence/traceability summary:
evidenceLevel, requirementsTraceSummary, filterPlanningSummary, componentGraphSummary, fallbackUsageSummary, dvIntelligenceSummary
- generation strategy summary:
generationStrategyRequested, generationStrategyApplied, compositionCoverage
- export artifact summary only when export was explicitly requested and completed
Detailed traces are opt-in only. Include trace blocks only when user explicitly asks for trace, debug, diagnostics, or sets traceRequested=true.
When trace is requested, additionally return:
- target execution capability block with
targetVersion, executionMode, reasonForVersionSelection, capabilitySource, saveToolDetected, exportToolDetected, discoveryMethod, saveAvailable, exportAvailable, exportRequested
- selected template ID + runtime family + dialect
- strategy trace fields:
generationStrategyRequested, generationStrategyApplied, compositionCoverage, unsupportedTopologyReasons
- resolution trace block with
requestedPluginType, resolvedFamily, scaffoldTemplate, finalPluginType, fallbackUsed, reason
- filter decision trace block with
selectedFilterMode, queryIntents, probeResults, derivedDecisions, fallbackUsed, fallbackReason
- save target trace block with
requestedSaveIntent, resolvedSaveMode, resolvedWorkbookTarget, createBlockedByCollision, reason
- when in modify mode, modify trace block with
requestedOperation, resolvedWorkbookTarget, sourceMode, confirmationState, mutationsApplied, pathsChanged, fallbackUsed, fallbackReason
- keep filter/modify traces in tool/validation check output only; do not persist internal trace keys in workbook payload JSON
- do not expose internal channel keys or internal
projectVersion IDs in user-facing trace/output
- include
dvIntelligenceTrace only when trace is explicitly requested
On save success, return immediately:
- saved workbook identifier/path
viewUrl
If export was explicitly requested and completed, return:
- export artifact summary
On failure, return:
- error text and available validation details
- applied patch actions (if any)
- contract gap report when unresolved