agentsclimarketplace

Transon authoring

Skill transon-org/transon-authoring-skill/skills/transon-authoring

Author engine-valid Transon JSON transformation templates for a described data transform. Use when the user wants to create, generate, write, or fix a Transon template (a Transon transform), or to reshape, flatten, map, project, or restructure JSON data into another JSON shape via the Transon engine — especially when input/output sample pairs are available to verify against.From its SKILL.md

Install
npx -y skills add transon-org/transon-authoring-skill --skill transon-authoring

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

21.5 KB, ~5.4k tokens by cl100k_base, as published. Nobody here has run it

transon-authoring

Authors engine-valid Transon JSON templates and returns one only after the pinned engine has verified it against a user-confirmed SampleSet to assurance: "matched" — never unverified JSON as success.

Authority

<!-- authority: AD-018 / NFR-001 -->

Precedence for Transon semantics, highest first:

  1. Behavior of the pinned running engine (transon==0.2.3);
  2. The engine's Language Reference for that version, read via python -m transon_authoring language (discover sections with --list-sections, then a specific one with --section <id>);
  3. The pinned get_editor_metadata() snapshot (catalog/examples structure);
  4. The NL intent sidecar — hints only, never authority.

Never model memory, web docs, or Context7 for Transon semantics.

Pin

transon==0.2.3, metadata_version "3.0". The pinned snapshot is bundled with the transon_authoring package — print it with python -m transon_authoring metadata.

Runtime prerequisite. Every command below runs through that package. If any of them reports No module named transon_authoring, the runtime is not installed in this environment: run pip install transon-authoring (it pins the engine transitively), then retry. Do not proceed without it and never substitute another source for engine behavior.

Procedure

Work through sections 1–7 IN ORDER for every authoring request. Do exactly what each step says. Never skip a gate. Every final answer is exactly ONE AuthoringResult object (section 7).

1. Config & samples location

<!-- config: FR-022 / AC-014 -->

If a samples path was given to you — a --samples value or a provided samples file, as in CI or a headless/single-turn run — that path IS your SampleSet: skip the samples-LOCATION discovery below, and do NOT run init-config, prompt, or create a config. Its layout is irrelevant when the path is explicit. But if .transon-authoring.json already exists at the repo root, read it ONCE for its repair_attempts budget only (used by the section 5.1 repair loop) — never create or prompt for one. Then go straight to section 2. The location-discovery steps below apply ONLY when no samples path was given and you must find where SampleSet files live.

  1. Look for .transon-authoring.json at the repo root and read it if present. It gives the samples layout (where SampleSet files live) and the repair_attempts budget.
  2. If it is absent and this is an interactive session, run python -m transon_authoring init-config once, at the repo root, before any other step. It writes .transon-authoring.json to the current working directory and prints the ProjectConfig.
  3. In CI or any non-interactive run: never prompt, never wait for input. A non-interactive run with no explicit --samples path and no existing config has no way to locate SampleSet files — so require one of: an explicit --samples path from the caller (step 4, the usual CI case), or init-config --layout <layout> --non-interactive to establish the config the later steps read. Never guess a location or invent a default; if neither is available, stop and say so rather than proceeding to the sample loop without a resolved path.
  4. An explicit samples path from the caller — a --samples value or a CI fixture path — always wins over any config-derived location. When the config is already present or a samples path is given, there is no layout prompt.

2. Ground & refuse

<!-- ground & refuse: FR-001 / AD-018 / NFR-001 / AC-003 -->
  1. Before using ANY Transon operator, rule, or mode name, resolve it against the pinned snapshot first — prefer TARGETED lookups over dumping the whole catalog:

    • python -m transon_authoring examples search "<query>" — snapshot docs.examples hits, and your PRIMARY grounding tool. ALWAYS quote the query as ONE argument (examples search "flatten map", never examples search flatten map).
    • python -m transon_authoring metadata — the full pinned catalog. It is LARGE: do NOT dump it wholesale or pipe it to head (truncation loses the part you need). Reach for it only to confirm a specific operator/rule/mode name exists.
    • python -m transon_authoring language — the engine's author-facing Language Reference, the authoritative source for language SEMANTICS (what an operator, rule, or mode means). Run python -m transon_authoring language --list-sections to discover the sections, then python -m transon_authoring language --section <id> to read a specific one.
  2. Authority order, highest first: (1) behavior of the pinned running engine; (2) the engine's Language Reference for that version, read via python -m transon_authoring language (--list-sections, then --section <id>); (3) the pinned snapshot; (4) the NL sidecar — hints only. Never use model memory, web docs, or Context7 for Transon semantics.

  3. If the request needs a capability that cannot be grounded in the pinned snapshot — an operator, rule, or mode that does not exist there — REFUSE. Your refusal is an AuthoringResult with ok: false and status: "aborted" naming the missing capability — but do NOT hand-write it, no matter how obvious the refusal seems. A hand-written refusal drops or misnames the required schema_version / explanation fields, and a malformed refusal is scored as a FAILURE even when your decision was correct. Emit it ONLY by running the command below, which builds the complete envelope for you; then return its stdout verbatim as your final message:

    python -m transon_authoring result --refuse --status aborted --explanation "<name the missing capability>"
    

    Never invent names (operator, rule, or mode); never guess syntax.

3. Sample loop

Gate: drive the sample conversation until python -m transon_authoring check-samples --samples <path> reports BOTH coverage_complete: true AND confirmed: true (independent flags — both must come from the check-samples output, never from your own judgment). Do not draft any template until both are true. Confirmation comes only from the user (interactive) or a pre-confirmed CI fixture — the library never sets confirmed: true. Conversation exits are confirm / defer / abort; map defer/abort to section 7 statuses. Run the protocol below in order: 3.1 → 3.2 → 3.3, with 3.4 governing every exit.

<!-- sample-loop protocol: FR-023/024/025 --> <!-- also: AD-014 / AD-016 / AC-010 / AC-011 / AC-012 / OQ-015 -->

3.1 Propose

  1. Draft the SampleSet YOURSELF from the user's NL intent. Write coverage obligations (kinds: happy_path, optional_present, optional_absent, list_empty, list_singleton, list_many, mode_choice, custom), each with acceptance: "proposed", plus candidate cases in cases (each with input, output, and satisfies listing the obligation ids it covers), waivers: [], and confirmation: { "confirmed": false, "content_fingerprint": "" }.
  2. Proposing obligations from natural language is YOUR job, inside the SampleSet artifact. The library never infers obligations from NL — check-samples only checks the artifact.
  3. Persist the SampleSet file at the section 1 location.

3.2 Present gaps

  1. Run python -m transon_authoring check-samples --samples <path>.
  2. For EVERY entry in gaps, present the gap (code + message) to the user together with exactly one proposal: either a concrete new/edited case that would meet the obligation, or a proposed Waiver — clears_obligation_ids naming the obligation ids it clears, a reason, and acceptance: "proposed".
  3. The user accepts or rejects each proposed obligation, case, and waiver. Record every decision by setting that item's acceptance to "accepted" or "rejected" in the SampleSet. Never flip an acceptance without an explicit user decision. Persist the file after every change.
  4. Repeat from step 1 until check-samples reports coverage_complete: true — or the user exits per 3.4.

3.3 Confirm

Only after the user EXPLICITLY confirms the SampleSet — never before, never on their behalf:

  1. Run python -m transon_authoring check-samples --samples <path> on the not-yet-confirmed SampleSet (exit 1 is expected here; the SampleCheck output still carries the recomputed fingerprint).
  2. Copy content_fingerprint from that SampleCheck output VERBATIM into confirmation.content_fingerprint. NEVER compute, hash, guess, or reconstruct the fingerprint yourself.
  3. Set confirmation.confirmed: true and confirmation.confirmed_by: "user". Persist.
  4. Re-run check-samples; proceed to section 4 only when it reports ok_for_verify: true.

3.4 Exits

The loop is unbounded — keep eliciting until exactly one of these three exits happens. Never auto-confirm; never treat silence, repetition, or loop length as confirmation.

  • confirm — 3.3 completed with ok_for_verify: true; continue to section 4.
  • defer — the user chooses to stop for now: emit status: "deferred", no template.
  • abort — the user chooses to abandon the request: emit status: "aborted", no template.

3.5 Real user data

<!-- real-data capture: FR-018 / NFR-011 / AC-025 -->

When a case's input/output (or a failing conversation) comes from real user data and is to be captured into the project's shared eval-fixture corpus: commit only after privacy redaction (fixture redacted: true) AND explicit recorded consent (fixture consent object — by, at, note). Never commit raw secrets or PII.

4. Draft

<!-- draft: FR-001 / NFR-001 -->
  1. Run python -m transon_authoring examples search "<query>" with words from the intent (quote the query as one argument).
  2. Copy the structure of the nearest example's template and adapt names and paths to the confirmed samples. Never improvise operators, rules, modes, or syntax that are not in the pinned snapshot.
  3. The pinned engine is a STRUCTURAL transformer: its only functions are str, int, float, type — there is NO length/count, date, string-case, or string split/replace function. When the intent seems to need one, do NOT assume it is missing and do NOT refuse yet: first check whether it COMPOSES from the primitives you grounded. An expr with a values list reduces its operator across the whole runtime list, which covers most "aggregate" needs (confirm each with verify before trusting it):
    • Count a list's length: map each element to 1, then reduce with + — {"$": "expr", "op": "+", "values": {"$": "map", "item": 1}}.
    • Flatten lists: prefer map with items mode ({"$": "map", "items": <per-element list>}), which concatenates each element's list and is safe on an empty input (yields []). An expr + over a list of strings concatenates them. CAVEAT: an expr whose values reduce over a runtime list REQUIRES at least one element — an empty list raises a DefinitionError. So the reduce-count and expr-+ recipes fail verify whenever a sample case has an empty list (e.g. a zero-count case); handle the empty case separately (a cond/switch on emptiness) or use the empty-safe map/items form. Only refuse (section 2) when the capability is genuinely absent AND cannot be composed this way — e.g. formatting an epoch as an ISO date, changing a string's case, or stripping a prefix.
  4. Write the candidate template JSON to a file.

5. Verify & repair

<!-- verify gate: AD-004 / AC-013 -->
  1. Run python -m transon_authoring verify --template <template> --samples <path>.
  2. Success ONLY when the Verdict has ok: true AND assurance: "matched". Anything else is a failure — never report or return the template as success.
  3. On a failed verify: run the repair protocol 5.1. Never return an unverified template.
<!-- repair protocol: FR-007/NFR-006 --> <!-- also: FR-003 / AC-019 -->

5.1 Repair loop

  1. Read repair_attempts from .transon-authoring.json (section 1); when the config is absent, use the default 3 (allowed range 1..10). Enforcing this bound is YOUR job: the library verify is single-shot — it never loops and has no repair flag.
  2. The repair count starts at 0 after the first failed verify.
  3. To repair: take the failed Verdict's errors[] and diff[] arrays and feed them VERBATIM into the next candidate draft — quote every engine error and diff entry exactly as returned; never paraphrase, reword, or summarize engine errors. Draft the new candidate under the section 4 rules and re-run verify.
  4. Each re-verify after a repair increments the repair count by 1. Total candidates tried is at most 1 + repair_attempts.
  5. If a re-verify succeeds (ok: true, assurance: "matched"), the candidate is matched — go to section 6 (Review), and report the repairs consumed in repair_count.
  6. When the repair count reaches repair_attempts and the last verify still failed: STOP — no further tries; never loop past the bound. Emit status: "repair-exhausted" with ok: false, repair_count set to the repairs consumed (= repair_attempts), the last failed Verdict in verdict, and the last candidate in last_candidate (section 7). Never return an unverified template.
  7. If you stop repairing before the budget is exhausted (without scheduling another repair), emit status: "verify-failed" instead, with repair_count set to the repairs consumed.

6. Review

<!-- interactive review: FR-030 / AC-031 / AC-012 -->

In an interactive session, after section 5 verifies a candidate — the Verdict has ok: true AND assurance: "matched" — present that matched template TOGETHER WITH its Verdict to the user and wait for their decision BEFORE emitting the final AuthoringResult. Only matched candidates are ever presented; this review is ADDITIONAL to, never a substitute for, the verify gate. The loop is unbounded until exactly one of the three exits below happens; never auto-approve; never treat silence as approval.

  • approve — the user accepts the template. Emit the final success envelope (status: "matched") by running the section 7 result command NOW — python -m transon_authoring result --template <template-path> --samples <samples-path> --repair-count <N>, where <N> is the number of repairs the approved candidate took — and returning its stdout verbatim. Do NOT retype or reconstruct the envelope you presented for review: re-typing a template by hand (especially a large one) corrupts the JSON, whereas result re-verifies and machine-builds a well-formed envelope every time — including now, on this later turn after approval.
  • revise — the user supplies feedback. Two kinds, handled differently:
    • NL-only feedback that rewords or restructures the SAME input/output behavior: draft a new candidate under the section 4 grounding rules and re-run section 5 verify with a fresh repair_attempts budget for this revision round (each round independently bounded). Re-present to the user only when the new candidate verifies matched.
    • Feedback that ADDS or CHANGES expected input/output behavior: apply it as SampleSet edits. Any such edit flips confirmed back via fingerprint_mismatch, sending the flow back through the section 3 sample loop to re-confirm before any redraft — so re-enter that sample loop.
  • stop — the user declines the template and ends the request with NO template: emit status: "deferred" (stop for now) or status: "aborted" (abandon).

Non-interactive/CI runs have no reviewer: emit the matched result directly after section 5, with no review step.

7. Result

<!-- result envelope: FR-008 / AC-012 / AC-026 / AC-027 -->

Emit your AuthoringResult by running the module — NEVER by hand-writing the envelope. On a matched success (you hold a template that verified at assurance: "matched"), run — passing <N>, the number of repairs consumed by the section 5.1 loop (0 if your first candidate verified matched):

python -m transon_authoring result --template <template-path> --samples <samples-path> --repair-count <N>

and return its stdout verbatim as your final message. That command re-verifies and machine-builds the complete matched envelope (ok: true, status: "matched", the template, the verdict, repair_count), so it is always well-formed. Do NOT reconstruct it yourself, do NOT wrap it in prose or a code fence, and NEVER answer with the bare template — a reply whose top-level keys are template keys like $ / funcs / items scores as a failure even when the template verifies. This holds equally when you emit after a section 6 approval on a later turn: re-run result and return its fresh stdout — never paste or re-type the envelope from memory (hand-re-typing a large envelope corrupts the JSON).

For a refusal or a failure that has NO matched template — you refused in section 2, the sample loop or review ended in defer/abort, or repairs exhausted — machine-build the failure envelope too, with --refuse, and return its stdout verbatim — do NOT hand-write it (hand-written refusals drop schema_version/explanation and invent keys, which fail scoring):

python -m transon_authoring result --refuse --status <STATUS> --explanation "<why>"

where <STATUS> is the matching status from the table below — one of aborted (refused / abandoned), deferred (stop for now), need-samples (sample loop unconfirmed), repair-exhausted, or profile-rejected (the request demanded a non-default marker/transformer — a skill-level out-of-profile stop). (samples-rejected / verify-failed come from the plain result --template --samples above; schema-error is a CLI ingress error, never a skill AuthoringResult.)

ok: true if and only if status: "matched". Include template only on success. Failures always set ok: false, use a status from the table below, and never present a template as success.

Every AuthoringResult MUST carry these four fields, always:

  • schema_version: the string "1.0".
  • ok: boolean — true only when status is matched.
  • status: exactly one value from the table below.
  • explanation: a one-line string stating what happened.

On a matched success you MUST ALSO include: template (the verified template JSON), verdict (the exact Verdict object the verify step returned — it carries ok: true and assurance: "matched"), and repair_count (repairs consumed; 0 if the first candidate matched). On a failure set ok: false, omit template, and attach whatever diagnostics apply (verdict, repair_count, last_candidate, gaps, sample_check).

Success envelope shape:

{
  "schema_version": "1.0",
  "ok": true,
  "status": "matched",
  "explanation": "Template verified at assurance matched.",
  "template": { "the": "verified template JSON" },
  "verdict": { "schema_version": "1.0", "ok": true, "assurance": "matched", "errors": [] },
  "repair_count": 0
}

Refusal / failure envelope shape:

{
  "schema_version": "1.0",
  "ok": false,
  "status": "aborted",
  "explanation": "The requested capability does not exist in the pinned snapshot."
}
statuswhen
matchedverify returned ok: true with assurance: "matched" — the only success; in interactive sessions, only after the section 6 review approve
need-samplesstopped with incomplete coverage / need more cases (section 3 gate not met)
deferredthe user chose defer during the sample loop, or a section 6 review stop (stop for now)
abortedthe user chose abort (sample loop or a section 6 review stop), or you refused because the request cannot be grounded in the pinned metadata (section 2)
repair-exhaustedall repair_attempts repair cycles consumed without a matched verdict
samples-rejectedcheck-samples (or the verify samples stage) failed on a schema-valid SampleSet
verify-failedvalidate, dry_run, or match failed and you stopped without scheduling another repair
schema-errormalformed JSON or unsupported schema_version on ingress (CLI exit 2)
profile-rejectedthe request demanded an out-of-profile execution option (non-default marker/transformer): stop WITHOUT calling verify — or the CLI rejected a reserved knob

7.1 Trace (optional, diagnostic)

<!-- trace: FR-031 / AC-033 (AD-022) -->

In an interactive session you MAY add an ordered trace array to the AuthoringResult: one TraceEntry per protocol step you performed. Each entry has a 1-based seq (contiguous, in conversation order), a step — one of config, ground, propose, present-gaps, confirm, draft, verify, repair, review, result — and a one-line summary. When the step ran a module command, copy that exact module invocation into command verbatim, and record a step-local outcome (e.g. the reported gap count or the failed_stage).

trace is DIAGNOSTIC ONLY. It never gates anything, is never treated as evidence that a step actually ran, and its absence never invalidates a result. Nothing in trace may change the status, ok, or template of the AuthoringResult you emit — decide those solely from the gates in sections 2–5.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.