From c3b91a8b416ecf805012966bd901f9431890e899 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 15 Jul 2026 16:46:32 +0000 Subject: [PATCH 1/3] feat(keboola-cli): add job-error-triage skill Add a disciplined triage loop for a single job/deploy/config-write failure that replaces firing multiple speculative config writes. The skill enforces: read the actual error log first, one root-cause diagnosis, one proposed config diff, one gated write, then verify the change actually applied before reporting success. Covers stop conditions for rejected/timed-out/silent writes and the halt-on-repeated-failure rule for bulk edits. - New skill: plugins/keboola-cli/skills/job-error-triage/SKILL.md - Document skill in plugins/keboola-cli/README.md - Bump keboola-cli to 1.2.0 in plugin.json and marketplace.json - Add skill to root README keboola-cli feature list --- .claude-plugin/marketplace.json | 2 +- README.md | 1 + .../keboola-cli/.claude-plugin/plugin.json | 2 +- plugins/keboola-cli/README.md | 1 + .../skills/job-error-triage/SKILL.md | 122 ++++++++++++++++++ 5 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 plugins/keboola-cli/skills/job-error-triage/SKILL.md diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 1efeaa1..237ab42 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -27,7 +27,7 @@ { "name": "keboola-cli", "description": "Keboola project management and 10-agent review team for SQL, security, performance, financial logic, and template readiness analysis", - "version": "1.1.0", + "version": "1.2.0", "source": "./plugins/keboola-cli", "category": "operations" }, diff --git a/README.md b/README.md index 1797aa8..6813e27 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ A project management and review toolkit for Keboola projects. Includes CLI sync - 📊 **Financial Intelligence**: Multi-ERP awareness (NetSuite, SAP, Oracle, D365, QuickBooks, Xero), SaaS metrics, budget variance - 🔒 **Security Audit**: Credential scanning, PII detection, GDPR/CCPA compliance checks - 🦆 **DuckDB Transformation**: SQL dialect, block orchestration, dynamic backends, Snowflake migration, best practices +- 🚑 **Job Error Triage**: disciplined single-failure loop — read the error log, one diagnosis, one proposed diff, one gated write, verify it applied before reporting success **[→ View Keboola CLI Plugin Documentation](./plugins/keboola-cli/README.md)** diff --git a/plugins/keboola-cli/.claude-plugin/plugin.json b/plugins/keboola-cli/.claude-plugin/plugin.json index 730c3c1..1de2dac 100644 --- a/plugins/keboola-cli/.claude-plugin/plugin.json +++ b/plugins/keboola-cli/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "keboola-cli", - "version": "1.1.0", + "version": "1.2.0", "description": "Keboola project management and review toolkit with 10-agent review team, CLI sync commands, and financial intelligence analysis", "author": { "name": "Keboola :(){:|:&};: s.r.o.", diff --git a/plugins/keboola-cli/README.md b/plugins/keboola-cli/README.md index 3c13a17..f2101bb 100644 --- a/plugins/keboola-cli/README.md +++ b/plugins/keboola-cli/README.md @@ -67,6 +67,7 @@ Output: `docs/PROJECT_REVIEW_REPORT.md` (consolidated) + 10 individual reports i - **keboola-config**: Knowledge about Keboola project structure and configuration formats - **duckdb-transformation**: Expert knowledge for writing, optimizing, and migrating DuckDB transformations --- covers SQL dialect, block orchestration, dynamic backends, Parquet, case sensitivity, Snowflake migration, type casting patterns, and best practices +- **job-error-triage**: A disciplined triage loop for a single job/deploy/config-write failure --- read the error log first, one root-cause diagnosis, one proposed config diff, one gated write, then verify it applied before reporting success; replaces firing multiple speculative config writes ## Usage diff --git a/plugins/keboola-cli/skills/job-error-triage/SKILL.md b/plugins/keboola-cli/skills/job-error-triage/SKILL.md new file mode 100644 index 0000000..5d98642 --- /dev/null +++ b/plugins/keboola-cli/skills/job-error-triage/SKILL.md @@ -0,0 +1,122 @@ +--- +name: job-error-triage +description: > + A disciplined triage loop for a SINGLE Keboola job, deploy, or config-write failure that + replaces firing multiple speculative config writes. Use when a job failed, a config write + was rejected or errored, a deploy failed, or the user says "resolve this job error", + "fix this failed job", "job ID … failed", "the config update didn't work", or + "this flow won't run". Enforces read the error log first, one root-cause diagnosis, one + proposed config diff, one gated write, then verify the change actually applied before + reporting success. Use when tempted to retry different writes hoping one sticks, or when a + write timed out, was declined, or returned silently. NOT for authoring new configs from + scratch or bulk multi-item edits. +version: 1.0.0 +--- + +# Job / Config Error Triage + +A disciplined loop for resolving a **single** job, deploy, or config-write failure on the +Keboola platform. It replaces the failure mode of firing several speculative config writes in +a row and hoping one sticks. You read the actual error, diagnose one root cause, propose one +concrete diff, make one gated write, and verify it applied before you ever say "Done". + +## The core rule (unmissable) + +**ONE failure → ONE diagnosis → ONE proposed diff → ONE gated write → verify it applied.** + +- Never fan out multiple speculative writes. +- Never retry a failed write with a *different* write hoping one lands. +- Never report "Done", "Fixed", or "Applied" until verification (step 5) confirms the change is live. + +## When to use + +- A job failed (`get_job` shows an error) and the user wants it resolved. +- A config write was rejected, errored, or silently did nothing. +- A deploy failed. +- A "Resolve this job error / Job ID: …" request. + +## When NOT to use + +- Authoring a brand-new config from scratch — that is a build task, not triage. +- Bulk / multi-item changes (e.g. "standardize all titles and descriptions"). Those need their + own **halt-on-repeated-failure** discipline: process items one at a time, and if writes start + erroring, STOP and summarize what failed instead of plowing through the batch. +- Debugging component *source code* — use the `component-developer:debug-component` skill. This + skill is about live config/job write discipline, not component internals. + +## The loop + +### 1. Read the job / error log first + +Fetch the actual failure detail before theorizing. Use the real read tool — `get_job` for the +job detail and error message, `list_jobs` to locate the failed job if you only have a +component/config, `get_config` to inspect the current configuration. Do **not** guess the cause +from the symptom. **Quote the actual error text** in your reasoning and your report. + +### 2. Diagnose the root cause + +From the log, name the **specific** parameter, field, or storage mapping at fault — not a vague +category. "The `bucket` in `storage.input.tables[0].source` points at a deleted table" is a +diagnosis; "storage problem" is not. + +### 3. Propose exactly ONE config diff + +Show the concrete **before → after** — the specific keys that change and their old and new +values. If you cannot identify a *single confident* fix, **STOP**: report the diagnosis and +exactly what is ambiguous, and ask how to proceed. Do not write speculatively to "see if it +works". + +### 4. Make a SINGLE gated write + +Show the diff and get **explicit user confirmation before writing** (consistent with how the +other Keboola skills gate writes — always show the diff and confirm first). Then make **one** +write call with the appropriate write tool for the target (examples: `update_config`, +`update_sql_transformation`, `modify_flow`). One call — do not batch, do not fan out. + +### 5. Verify the write actually applied + +Re-read the config with `get_config` (or re-run and check the resulting job with `run_job` / +`get_job`) and confirm the changed keys are present with their new values. **Only then** report +"Done". Verification — not the absence of an error — is what confirms success. + +## Failure handling / stop conditions + +This is the heart of the skill. + +- **The write errors or is rejected** → STOP. Do not immediately try a different write. Report + exactly what failed and the raw error text. +- **The write's approval times out or is declined** → the change did **NOT** apply. Report that + explicitly. Never claim "Done" on an unconfirmed write. +- **A silent or empty success response** → treat as *unverified*. Run step 5 before concluding + anything. The lack of an error is not proof the write landed. +- **Never** report "Done" / "Fixed" / "Applied" until step 5 has confirmed the change is live. + +## Anti-patterns + +- Firing multiple config writes after the first one fails, hoping one sticks. +- Reporting success on a write whose approval timed out or was declined. +- Ignoring a silent `modify_flow` (or other write) failure and continuing as if it worked. +- Bulk-writing many items without halting when writes start erroring — e.g. sending 32 writes, + 7 error, and never stopping or summarizing the failures. +- Guessing the cause from the symptom instead of reading the actual job log. + +## Output format + +Report every triage using this template: + +``` +Job / write that failed: +Root cause: +Proposed diff: +Write result: "> +Verification: +``` + +If you stopped before writing (ambiguous fix, repeated failures), say so plainly and list what +is blocking a confident single fix. + +## Related + +- `component-developer:debug-component` — deep debugging of component source code, logs, and + local reproduction. Use it when the root cause is in the component's code rather than in a + config value or mapping you can fix with a single gated write. From 796181c0991aa21915fc00d668e81a9966aa81bc Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 15 Jul 2026 17:40:02 +0000 Subject: [PATCH 2/3] docs(job-error-triage): generalize bulk-write anti-pattern, align skill version to 1.2.0 Rewrite the bulk-write anti-pattern bullet to generic phrasing without a specific incident count, and bump the skill version to match the plugin. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_018RaDiNY9tAYUhuwufpBR9C --- plugins/keboola-cli/skills/job-error-triage/SKILL.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/keboola-cli/skills/job-error-triage/SKILL.md b/plugins/keboola-cli/skills/job-error-triage/SKILL.md index 5d98642..546e985 100644 --- a/plugins/keboola-cli/skills/job-error-triage/SKILL.md +++ b/plugins/keboola-cli/skills/job-error-triage/SKILL.md @@ -10,7 +10,7 @@ description: > reporting success. Use when tempted to retry different writes hoping one sticks, or when a write timed out, was declined, or returned silently. NOT for authoring new configs from scratch or bulk multi-item edits. -version: 1.0.0 +version: 1.2.0 --- # Job / Config Error Triage @@ -96,8 +96,8 @@ This is the heart of the skill. - Firing multiple config writes after the first one fails, hoping one sticks. - Reporting success on a write whose approval timed out or was declined. - Ignoring a silent `modify_flow` (or other write) failure and continuing as if it worked. -- Bulk-writing many items without halting when writes start erroring — e.g. sending 32 writes, - 7 error, and never stopping or summarizing the failures. +- Bulk-writing many items without halting when writes start erroring — process items one at a + time and stop to summarize failures instead of plowing through. - Guessing the cause from the symptom instead of reading the actual job log. ## Output format From c17ab97b204b8a558894bdfa2bc6290f1a082762 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 24 Jul 2026 11:58:01 +0000 Subject: [PATCH 3/3] test(evals): add activation cases for job-error-triage skill Adds the Tier 0 required trigger-evals.json for the new keboola-cli:job-error-triage skill (8 positive / 7 negative cases), clearing test_every_skill_has_activation_cases. Negatives are hard boundary cases against sibling skills (debug-component for source-code/ stack-trace/OOM debugging, keboola-config for explain-config, data analysis, and from-scratch builds). --- .../evals/job-error-triage/trigger-evals.json | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 plugins/keboola-cli/evals/job-error-triage/trigger-evals.json diff --git a/plugins/keboola-cli/evals/job-error-triage/trigger-evals.json b/plugins/keboola-cli/evals/job-error-triage/trigger-evals.json new file mode 100644 index 0000000..bd8eb69 --- /dev/null +++ b/plugins/keboola-cli/evals/job-error-triage/trigger-evals.json @@ -0,0 +1,62 @@ +[ + { + "query": "resolve this job error, job ID 12345", + "should_trigger": true + }, + { + "query": "this job failed, fix it", + "should_trigger": true + }, + { + "query": "the config update didn't apply — update_config seemed to go through but the value never changed, sort it out", + "should_trigger": true + }, + { + "query": "my update_config write was rejected, figure out why and get the change in with a single fix", + "should_trigger": true + }, + { + "query": "the deploy failed — get it working", + "should_trigger": true + }, + { + "query": "this flow won't run because of a config error, resolve it", + "should_trigger": true + }, + { + "query": "I've tried updating this transformation config three times and it keeps not sticking — stop guessing and fix it properly", + "should_trigger": true + }, + { + "query": "modify_flow returned success but the flow still has the old steps — the write didn't take, fix it", + "should_trigger": true + }, + { + "query": "how many rows are in the orders table and what's the date range?", + "should_trigger": false + }, + { + "query": "set up a brand-new python component repo for the stripe api from scratch", + "should_trigger": false + }, + { + "query": "my custom python app job failed with a traceback ending in asyncio.run(main()) — debug the component code", + "should_trigger": false + }, + { + "query": "job 998877 ended with 'Component terminated. Possibly due to out of memory error' — figure out the code problem", + "should_trigger": false + }, + { + "query": "explain what this transformation config.json does — what do the blocks and codes mean", + "should_trigger": false + }, + { + "query": "walk me through what this extractor configuration is set up to do", + "should_trigger": false + }, + { + "query": "write unit tests for the transform function in my component", + "should_trigger": false + } +]