Skip to content

Releases

dsh-ditto v0.3.0

Choose a tag to compare

@darrien1998 darrien1998 released this 20 Sep 11:32

What's Changed

  • feat: localise review pages with zh-TW support by @Kin230k in #11

New Contributors

Full Changelog: v0.2.0...v0.3.0

dsh-ditto 0.2.0 — reviewed file delivery, Recipe v2, fail-closed approval

Choose a tag to compare

@darrien1998 darrien1998 released this 19 Sep 18:11

Review a few. Preview everything. Apply safely. Ditto 0.2.0 turns the file workflow into real batch delivery: authorised external folders, dynamic nested destinations, a complete review surface, and deterministic deliverables — still with nothing written before you approve it.

Highlights

1. File organisation can leave the workspace, on the profile owner's terms

A profile owner can now authorise source and destination roots, so a batch can be read from C:\Users\me\Desktop\ftp-backup and delivered to D:\shared\deliveries:

- id: ditto
  config:
    allowedSourceRoots:      ['/path/to/repo', 'C:/Users/me/Desktop/ftp-backup']
    allowedDestinationRoots: ['/path/to/repo', 'D:/shared/deliveries']
  • allowedSourceRoots / allowedDestinationRoots default to [workspaceRoot] and are checked per role.
  • An external folder is reachable only by absolute path and only when it is listed for that exact role. The agent cannot widen the boundary; only the profile configuration can.
  • A relative path stays anchored to workspaceRoot and never inherits external-root authority.
  • Roots are revalidated on status, revision, review and apply, so removing a root also revokes plans that were reviewed earlier.
  • Code → Spec remains strictly workspace-bound; the allowlists do not widen it.

2. Recipe v2 — capture a name, then build nested destinations

match_regex: '^(?<code>[^_]+)_.*\.pdf$'
match_scope: basename
pattern: 'PRO_FILES/{match.code}/{match.code}{ext}'
  • Matching is linear-time via re2-wasm; lookarounds, backreferences, alternation and nested/counted quantifiers are rejected before a regex is ever built.
  • {match.name} substitutes exactly one safe path segment, so a reviewed template can create directories but never traverse.
  • Non-matches, unsafe captures, invalid names and collisions become explicit, reviewable per-item exceptions instead of silent skips.
  • Exceptions never block the valid copies, and they appear in diagnostics and in the exported manifest with their reason.

3. Review the whole batch, then revise the rule once

  • ditto_revise_rule regenerates every proposal, exception, sidecar and archive identity in one revision — no more editing 174 items by hand.
  • ditto_manifest exports the complete mapping as CSV, JSON or Markdown under Ditto state, with spreadsheet-formula neutralisation.
  • ditto_artifact_review returns the exact reviewed bytes of a sidecar, in bounded pages, before you approve anything.

4. Deliverables: reviewed sidecars and a deterministic archive

  • Sidecars: manifest, SHA-256 checksums, and INSERT ... VALUES text for SQL Server, PostgreSQL and SQLite. Identifiers are validated and values become escaped literals only. Ditto never connects to a database and never executes SQL.
  • Optional store-only ZIP: streamed, byte-identical across runs, and built only from the persisted reviewed allowlist — never by walking the output folder. Classic-ZIP limits (65,535 entries, < 4 GiB) fail closed.
  • Apply runs in three stages (copies → sidecars → archive) and ditto_apply now returns deliverables (output root, sidecars, archive) so the agent can point you at the result.

Security

  • Host approval validates the submitted revision/digest before prompting, so a stale request can never display another plan's counts.
  • rejected and cancelled always deny. A missing approval service, a missing agent identity, or a host unavailable outcome (including approval policy never) now denies by default and writes nothing.
  • Crash recovery adopts an output only when an earlier run recorded a durable intent and the on-disk hash matches exactly; an unrelated same-content file is never adopted or overwritten.
  • State root, categories, lock records, temporary files and leaves are checked against symlink/junction redirection, and per-plan mutations are serialised across processes with atomic state-root locks.
  • Archive inputs are re-hashed while streaming, so an output changed mid-archive aborts the archive instead of shipping a stale bundle.
  • ditto_manifest, ditto_artifact_review and docs/SAFETY.md document the full threat-model boundary, including what Ditto does not protect against.

Tool surface

17 tools — nine Code → Spec, eight file organisation.

Code → Spec File organisation
ditto_spec_create, ditto_spec_queue, ditto_spec_module, ditto_spec_submit, ditto_spec_review, ditto_spec_revise_samples, ditto_spec_approve, ditto_spec_apply, ditto_spec_status ditto_preview, ditto_revise, ditto_revise_rule, ditto_manifest, ditto_artifact_review, ditto_apply, ditto_status, ditto_recipe

The reference is generated from the live schemas: docs/TOOLS.md.

Upgrading from 0.1.0

Ditto 0.1 plans and recipes keep loading with their original digest, and items that predate the new proposalDisposition field are still copied and reported in deliverables. Two behaviour changes are worth knowing:

  • Approval now fails closed. 0.1 fell back to the agent's conversational approval whenever the host composed no approval service. 0.2 denies instead. If you intentionally relied on that fallback, set approvalUnavailable: agent explicitly — it is a profile-owner decision, and it is not proof of human approval.
  • v1 recipes stay frozen. A v1 recipe whose pattern uses the old dotless {ext} is refused by ditto_revise_rule until you pass an explicit pattern such as {stem}{ext}, so a reviewed rule is never silently reinterpreted. (In v2, {ext} includes its leading dot.)

Compatibility

Ditto DSH Node.js Status
0.2.0 0.1.5-rc.1, 0.1.5-rc.2 22, 24 supported
0.2.0 0.1.6-alpha.1 22, 24 canary (non-blocking CI)
0.1.0 0.1.5-rc.1, 0.1.5-rc.2 22, 24 historical

Verification for this release

  • npm run release:check: TypeScript build, 90 tests across 10 files, real Cordis + published ToolRuntime/SkillRegistry component smoke, generated-doc drift check, and a packed-tarball clean-install smoke.
  • npm run smoke:profile: real dsh plugin add from the packed tarball into an isolated DSH_HOME, profile boot, and in-profile doctor reporting 17 of 17 tools.
  • A 174-file insurance-style acceptance run: zero per-item edits, 174 nested outputs, byte-identical sources, 174 manifest rows, 174 SQL statements, and an exact 177-entry central directory.
  • CI green on ubuntu-latest and windows-latest for Node 22 and 24, on the DSH next/alpha canaries, and in the real profile-install job.

Install

dsh plugin --profile web add dsh-ditto

Full changelog: CHANGELOG.md · Compare: v0.1.0...v0.2.0

Ditto 0.1.0 — Review a few. Ditto the rest.

Choose a tag to compare

@darrien1998 darrien1998 released this 17 Sep 03:17

Review a few. Ditto the rest. A review-first batch automation plugin for DeepSeek Harness.

Install: dsh plugin --profile web add dsh-ditto · Verify: dsh plugin --profile web exec dsh-ditto doctor · Demo without a model: npx dsh-ditto demo --headless

First public release.

Added

  • Native DeepSeek Harness plugin (dsh-ditto/dsh): one Cordis service that registers the ditto skill and 14 typed native tools on the host's public skills and tools services, with clean unload.
  • skills/ditto/SKILL.md as the single source of truth for the skill (DSH frontmatter, loaded at runtime).
  • Code → Spec workflow for TypeScript/JavaScript: bounded discovery with exclusion accounting, line-numbered evidence chunks, three structurally different calibration samples, citation-validated JSON drafts, deterministic Markdown rendering, "Needs confirmation" for unsupported claims, revision/digest gates, durable resumable apply.
  • File-organisation workflow: declarative naming recipes, per-file review, copies into a new folder, saved recipes.
  • Host approval gate: with a DSH approval service present, ditto_apply and ditto_spec_apply ask the user before writing (approval: host, the default).
  • LanguageAdapter seam with the shipped TypeScript/JavaScript adapter.
  • dsh-ditto CLI: demo (browser and --headless), demo-files, doctor, serve, --version, --help.
  • dsh-ditto doctor: Node, DSH, pnpm, profile installation, resolved DSH versions, in-process mount (tools and skill), workspace and state folder checks.
  • One-line installation through dsh plugin --profile <name> add dsh-ditto (package declares dsh.bundle.patch; DSH packages are peer dependencies).
  • Generated tool reference (docs/TOOLS.md) with a CI drift check; architecture, safety, compatibility, development, evaluation, roadmap, and launch documentation; English and Traditional Chinese READMEs.
  • Smoke scripts: component host (smoke:dsh), packed-tarball clean install (smoke:tarball), and a real dsh plugin add + profile boot in an isolated DSH_HOME (smoke:profile).
  • GitHub issue and pull request templates, labels, and a CI matrix (Node 22/24 × Ubuntu/Windows, real profile install, non-blocking DSH next/alpha canaries).

Changed

  • Product surface is English-first (tool results, error messages, rendered spec headings, review pages); the Traditional Chinese README is kept in step.
  • Minimum batch size for Code → Spec lowered from 10 to 4 modules (three samples plus at least one to apply the standard to).
  • Relative stateRoot values are anchored to workspaceRoot instead of the process working directory.

Fixed

  • A cross-drive path on Windows could be treated as inside the workspace by the native-tool boundary check; the core within() check is now used everywhere.