Skip to content

Harden opencode-excalidraw output path policy (session-scoped + containment) #186

@anand-testcompare

Description

@anand-testcompare

Context

Issue #129 mixed multiple tracks and was closed after superseding the release-flow/docs portion into #184 (implemented by #185).

A remaining product risk is still present in current main:

  • DEFAULT_OUTPUT_DIR is still sketchi/png (packages/opencode-excalidraw/src/lib/output.ts)
  • resolveOutputPath is still unconstrained resolve(baseDir, path) (packages/opencode-excalidraw/src/lib/output.ts)
  • model/tool-provided outputPath can therefore write anywhere under repo-relative resolution (including root-level files)
  • no automated tests currently cover session-scoped defaults or traversal/containment behavior for outputPath

Goal

Make plugin artifact writes deterministic and safe by default:

  • session-scoped storage under /.sketchi/sessions/<sessionID>/png/...
  • containment enforcement for tool-supplied outputPath
  • explicit and documented opt-out for power users

Scope

  1. Default output root migration
  • Replace sketchi/png default with /.sketchi/sessions/<sessionID>/png/....
  • Ensure all diagram write paths (diagram_from_prompt, diagram_tweak, diagram_restructure, diagram_to_png, diagram_grade) use the same policy.
  1. Containment enforcement
  • By default, reject or normalize tool-provided outputPath so writes cannot escape the session output root.
  • Handle these cases explicitly:
    • bare filename
    • relative nested path
    • absolute path
    • .. traversal attempts
  • Add a clearly named explicit opt-out (env/config) for advanced users.
  1. Git ignore hygiene
  • Ensure generated artifacts under /.sketchi/** are ignored reliably (root .gitignore and/or nested .gitignore strategy).
  1. Automated coverage
  • Add tests for:
    • default session-scoped output path generation
    • outputPath containment for benign and malicious inputs
    • opt-out behavior
  • Keep plugin CI gates exercising these tests.
  1. Docs consistency
  • Update packages/opencode-excalidraw/README.md with the new default output policy and opt-out behavior.

Non-Goals

Acceptance Criteria

  • Default diagram outputs no longer target /sketchi/png; they are session-scoped under /.sketchi/sessions/<sessionID>/png.
  • Default behavior prevents outputPath escaping the session root.
  • Opt-out exists, is explicit, and documented.
  • Tests fail before and pass after the change for traversal/containment scenarios.
  • README reflects actual output path behavior.

Supersedes/Traceability

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions