Files
distributor/docs/roadmap/manifest_create.md

174 lines
6.0 KiB
Markdown

# Roadmap: `distributor manifest create`
## Purpose
Add a producer-facing CLI command that creates a valid source `manifest.json` for
a local bundle directory.
This command depends on the public `pkg/bundle` package. It should be useful
for shell scripts and non-Go producers while sharing behavior with Go producers
through the public package.
## Current Implementation Grounding
The current CLI has top-level `version`, `run`, `validate`, and `inspect`
commands. `validate` and `inspect` currently accept local paths only.
The manifest contract is implemented in `internal/bundle`: source manifests have
`schema_version`, `id`, `digest`, `created`, and ordered `files[]` entries with
`path`, `sha256`, and `size`. Validation already enforces path safety,
reserved distributor metadata paths, digest format, duplicate file paths, file
sizes, per-file SHA-256, and the canonical bundle digest.
This command should not add a second implementation of those rules. Once
`pkg/bundle` exists, `manifest create` should call it.
## Goals
- Add a CLI command that writes `manifest.json` for a local bundle directory.
- Reuse public producer-side manifest creation and validation behavior.
- Produce deterministic manifests.
- Preserve caller-provided file order when explicit files are provided.
- Offer convenient recursive scanning when explicit files are omitted.
- Refuse to overwrite an existing manifest unless explicitly requested.
## Non-Goals
- Do not publish or distribute bundles.
- Do not write destination `.distributor.json` state.
- Do not add config-file dependencies.
- Do not add domain-specific metadata.
- Do not expose publish, storage, transform, or destination internals.
## CLI Shape
Proposed syntax:
```sh
distributor manifest create <bundle-path> --id <bundle-id>
```
Optional flags:
```sh
--file <path> Include a bundle-relative file; repeatable.
--created <time> RFC3339 source created timestamp.
--overwrite Replace an existing manifest.json.
```
The first implementation should always write `manifest.json` in the selected
bundle directory. It should not include a stdout/no-write mode or JSON summary
mode until `docs/roadmap/cli_output_policy.md` is implemented or selected for
implementation.
Examples:
```sh
distributor manifest create ./bundle --id weather.daily.2026-06-01
distributor manifest create ./bundle \
--id weather.daily.2026-06-01 \
--created 2026-06-01T11:00:00Z \
--file report.md \
--file summary.txt
```
## File Selection
Use explicit-first behavior:
- if one or more `--file` flags are provided, use exactly those files in flag
order;
- if no `--file` flags are provided, scan the bundle directory recursively and
sort files lexically by slash-separated relative path.
Scanning should include ordinary regular files, including dotfiles, except:
- `manifest.json`;
- `.distributor.json`;
- directories;
- symlinks and other non-regular entries.
Explicit file paths must be relative, clean, slash-separated or normalized to
slash-separated paths, confined to the bundle root, and listed files must be
regular files. Symlinks should be rejected to match current source validation.
## Manifest Creation Behavior
The command should:
1. resolve the local bundle root;
2. determine the selected file list;
3. build file records with SHA-256 and size;
4. compute the canonical bundle digest;
5. set `schema_version` to the current source manifest version;
6. set `id` from `--id`;
7. set `created` from `--created` or the package's selected default behavior;
8. refuse to replace `manifest.json` unless `--overwrite` is set;
9. write `manifest.json`, using temp-and-rename replacement where practical;
10. reload or validate the generated manifest before reporting success.
Success output should be concise:
```text
created manifest.json
bundle: weather.daily.2026-06-01
files: 2
digest: sha256:...
```
## Relationship To Other Roadmaps
`pkg/bundle` is the preferred underlying implementation. If `manifest create`
is implemented first, its reusable manifest-building logic should be structured
so it can move into `pkg/bundle` without changing command behavior.
Remote `validate` and `inspect` should validate bundles after creation but do
not need to participate in manifest writing.
HTML index mode, link generation, and latest paths are publication features and
must not affect source manifest generation.
JSON summary output should follow `docs/roadmap/cli_output_policy.md` rather
than introducing a command-specific `--json` flag or output envelope.
## Testing Expectations
Suggested coverage:
- creates a manifest for a simple local bundle;
- preserves explicit `--file` order;
- scan mode sorts files deterministically;
- scan mode includes dotfiles and excludes distributor metadata files;
- rejects symlinks, unsafe paths, missing explicit files, and non-regular files;
- refuses overwrite without `--overwrite`;
- overwrites only when `--overwrite` is set;
- generated manifests validate with distributor validation;
- CLI help and argument validation match existing CLI style.
## Documentation Updates After Implementation
- Update `docs/cli.md` with command syntax and examples.
- Update `docs/operations.md` with a producer workflow.
- Cross-reference `pkg/bundle` for Go producers once available.
- Add examples only if they are maintained and load/test friendly.
Keep this roadmap under `docs/roadmap/` until implemented.
## Decisions
- v1 does not include `--stdout` or no-write behavior. The command creates or
replaces the bundle's `manifest.json`.
- `--overwrite` is required to replace an existing manifest and should use
temp-and-rename writes where practical.
- v1 does not include JSON summary output. Human-oriented success output remains
consistent with the current CLI unless this work is implemented together with
`docs/roadmap/cli_output_policy.md`.
## Future Work
- Add `--stdout` or another no-write mode if producer pipelines need to capture
manifest JSON directly.
- Add JSON output through the CLI-wide `--format text|json` policy in
`docs/roadmap/cli_output_policy.md`.