174 lines
6.0 KiB
Markdown
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`.
|