Skip to content

Feature Request: Support on_archive (post-archive hooks) in schema for custom artifact moves/copies #704

Closed as duplicate

Description

@da1z

Background

Currently, archiving a change in OpenSpec merges delta specs into openspec/specs/ and moves the full change folder to openspec/changes/archive/, preserving all artifacts. However, there is no configurable way to automatically move or copy additional artifacts (such as documentation, generated reports, or other outputs) to other locations (e.g., a project-wide docs/ folder) when a change is archived.

Problem

Custom workflows often generate output files that belong outside the archived change, such as:

  • doc.md files that should end up in docs/
  • Other generated artifacts needed elsewhere in the project

Currently, this must be performed manually before archiving, making the process error-prone and less automatable.

Proposal

Add an on_archive hook to schema.yaml

Support an optional on_archive block in the schema file that declares rules for copying or moving specific artifacts/files when a change is archived.

Example schema.yaml (proposed):

name: my-workflow
version: 1
...
on_archive:
  copy:
    - from: doc.md  
      to: docs/           
  move:
    - from: coverage.txt
      to: builds/coverage/

Benefits

  • Unlocks advanced automation for doc+artifact handoffs
  • Eliminates manual, error-prone steps
  • Enables custom workflows with output location guarantees
  • Makes archiving more powerful and composable

Activity

  1. 21st-connector commented on Feb 12, 2026

    @21st-connector
    Contributor

    Task completed.

    The enrichment comment has been posted on issue #704. Here's a summary of what was covered:

    Comment URL: #704 (comment)


    View full conversation

    Powered by 1Code

  2. 21st-connector commented on Feb 12, 2026

    @21st-connector
    Contributor

    Issue Analysis

    Here's a codebase analysis to help developers evaluate and implement this feature.

    Likely Duplicate: #682

    This issue is closely related to #682 ("Add Extensible Hook Capability to OpenSpec Archive Operation"), which proposes the same concept — user-defined hooks that execute during archiving. The discussion on #682 has already produced a more generalized design direction, including both LLM-instruction hooks and shell-script hooks. The on_archive proposal here is essentially the post-archive hook from #682, scoped specifically to file copy/move operations.

    Other related issues:

    Current Archive Flow

    The archive implementation lives in src/core/archive.ts, specifically the ArchiveCommand.execute() method (line 51). The current 4-step workflow:

    1. Validation (lines 92–151) — validates proposal and delta specs
    2. Task progress check (lines 174–194) — warns about incomplete tasks
    3. Spec updates (lines 196–265) — applies delta specs to main specs in openspec/specs/
    4. Directory move (lines 284–287) — moves the change folder to openspec/changes/archive/<date>-<name>/

    The proposed on_archive copy/move rules would logically execute between steps 3 and 4 (after specs are merged but before the change folder is moved to archive), or after step 4 (operating on the archived copy). The timing matters — if rules reference files like doc.md relative to the change directory, they need to execute before the directory is relocated.

    Schema System — Where on_archive Would Live

    The issue proposes adding on_archive to schema.yaml. The schema type system is defined in src/core/artifact-graph/types.ts using Zod:

    // Current SchemaYamlSchema (types.ts:24-31)
    export const SchemaYamlSchema = z.object({
      name: z.string().min(1),
      version: z.number().int().positive(),
      description: z.string().optional(),
      artifacts: z.array(ArtifactSchema).min(1),
      apply: ApplyPhaseSchema.optional(),
    });

    Adding on_archive would require:

    1. Defining a new Zod schema for the copy/move rules (in src/core/artifact-graph/types.ts)
    2. Adding it as an optional field to SchemaYamlSchema
    3. Updating schema validation in src/core/artifact-graph/schema.ts:23-45 (parseSchema())
    4. Consuming the parsed rules in src/core/archive.ts during execute()

    Alternative location: The #682 discussion raised an important architectural point — schema-level hooks make sense for behavior inherent to a workflow (e.g., an ADR schema always generates decision records on archive), while project-specific hooks belong in openspec/config.yaml. The project config schema (src/core/project-config.ts:19-41) could also be extended. Supporting both levels (schema defines defaults, config overrides) may be the most flexible approach.

    Key Implementation Considerations

    1. Path resolution: The from paths in the proposal are relative to the change directory (openspec/changes/<name>/). The to paths appear to be relative to the project root. This needs to be clearly defined and validated — particularly for security (preventing writes outside the project root via ../ paths).

    2. Existing file system utilities: The codebase already has copyDirRecursive() and moveDirectory() helpers in src/core/archive.ts:16-48 with Windows compatibility (EPERM/EXDEV fallbacks). These could be reused for the proposed copy/move operations.

    3. Error handling: The current archive flow is not transactional — if a copy/move rule fails partway through, there's no rollback. The atomicity question (raised in Feat : Add Extensible Hook Capability to OpenSpec Archive Operation #682) applies here: should a failed file copy abort the archive, or just warn?

    4. Conflict resolution: The proposal doesn't address what happens if the to destination already exists. Overwrite? Skip? Error? This needs a defined behavior.

    5. Glob support: The proposal shows simple filenames (doc.md, coverage.txt), but users may want glob patterns (e.g., *.md → docs/). The codebase already uses fast-glob as a dependency, which could support this.

    Suggested Approach

    Given the overlap with #682, consider consolidating this into the broader hooks design being discussed there. The on_archive copy/move rules proposed here could be a specialized, declarative subset of a more general hook system — no need for shell scripts or LLM instructions for simple file operations:

    # In schema.yaml or config.yaml
    on_archive:
      # Declarative file rules (no scripts needed)
      copy:
        - from: doc.md
          to: docs/
      move:
        - from: coverage.txt
          to: builds/coverage/
      # General hooks (from #682)
      instruction: |
        Review the archived change and update the changelog...
      run: ./scripts/post-archive.sh

    This keeps the simple case simple (declarative copy/move) while fitting into the extensible hook architecture being designed in #682.

    🤖 Generated with Claude Code

  3. lsmonki commented on Feb 12, 2026

    @lsmonki

    Hey! I recently opened PR #701 which adds a lifecycle hook system covering all operations, including pre-archive and post-archive hooks — which addresses this use case.

    Schema authors can define post-archive hook instructions to handle file copy/move operations after archiving, at both schema and project (config.yaml) level. Feel free to take a look and let me know what you think!

  4. clay-good commented on Oct 27, 2026

    @clay-good
    Collaborator

    Thanks, @da1z. This is a use case of the archive hooks in #682, so closing as a duplicate. Please add the copy/move example there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    design-reviewNeeds product/design decision

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions