Skip to content

feat(M018/S03): manifest generation (core + MCP + CLI)#212

Merged
wollax merged 5 commits into
mainfrom
kata/root/M018/S03
Apr 1, 2026
Merged

feat(M018/S03): manifest generation (core + MCP + CLI)#212
wollax merged 5 commits into
mainfrom
kata/root/M018/S03

Conversation

@wollax
Copy link
Copy Markdown
Owner

@wollax wollax commented Apr 1, 2026

Summary

Closes M018/S03 — Manifest generation (core + MCP + CLI).

Operators can now generate a Smelt-ready manifest.toml from a planned milestone or all specs with a single command, instead of hand-writing it.

What's in this PR

assay-core: manifest_gen module (T01)

New crates/assay-core/src/manifest_gen.rs module (gated behind orchestrate feature):

  • ManifestSource enum — Milestone(slug) and AllSpecs variants
  • generate_manifest(source, config) -> Result<RunManifest> — reads milestone chunks via milestone_load, maps each ChunkRef.depends_on through to ManifestSession.depends_on; or scans all specs for fully-parallel sessions
  • write_manifest(manifest, path) — atomic tempfile-then-rename write
  • 8 unit tests covering all paths: deps, no-deps, error cases, round-trip validation, file write

assay-mcp: manifest_generate tool (T02)

  • ManifestGenerateParams struct with source, slug, output fields
  • manifest_generate tool registered in AssayServer router
  • Returns { "written": "<path>", "sessions": N } on success
  • 3 handler tests: registration, milestone generation, missing slug error

assay-cli: assay manifest generate subcommand (T03)

  • --from-milestone <slug> — generate from named milestone
  • --from-specs — generate from all specs (fully parallel)
  • --output <path> — defaults to manifest.toml
  • Mutually exclusive flag validation
  • Prints Written <path> (N sessions) on success

Verification

Check Result
cargo test -p assay-core -- manifest_gen ✅ 8/8
cargo test -p assay-mcp -- manifest_generate ✅ 3/3
cargo run -p assay-cli -- manifest generate --help ✅ exit 0
just ready ✅ 1595 tests

Requirements

  • R102 (manifest_generate MCP tool) — validated
  • R103 (manifest generate CLI) — validated

wollax and others added 4 commits April 1, 2026 14:39
Adds `depends_on: Vec<String>` to `ChunkRef` in assay-types for Smelt manifest scheduling constraints.

- Additive serde field with default/skip-serializing-if for backward compat
- Updated struct-level doc; clarified order is cosmetic-only
- JSON + TOML roundtrip tests, schema snapshots regenerated
- All ChunkRef struct literals updated across 9 files

Closes WOL-161 (M018/S02)
…_manifest

New assay-core::manifest_gen module (gated behind orchestrate feature):
- ManifestSource enum: Milestone(slug) and AllSpecs
- generate_manifest() maps ChunkRef -> ManifestSession with depends_on
- write_manifest() uses atomic tempfile-then-rename
- 8 unit tests covering all paths (deps, no-deps, errors, round-trip)
New manifest_generate tool in AssayServer tool router:
- ManifestGenerateParams: source (milestone/all-specs), slug, output
- Delegates to manifest_gen::generate_manifest + write_manifest via spawn_blocking
- Returns JSON with written path and session count
- 3 handler tests: tool registration, milestone generation, missing slug error
New 'assay manifest generate' subcommand:
- --from-milestone <slug>: generate from milestone chunks with depends_on
- --from-specs: generate from all specs (fully parallel)
- --output <path>: output file path (default: manifest.toml)
- Mutually exclusive flag validation
- Prints 'Written <path> (N sessions)' on success
Copilot AI review requested due to automatic review settings April 1, 2026 16:48
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds end-to-end “manifest generation” support so operators can emit a Smelt-ready manifest.toml from either a milestone’s chunks (with intra-milestone dependencies) or from all specs, exposed via both MCP and the CLI. This extends the milestone model to include chunk-level scheduling constraints (depends_on) that flow into generated run manifests.

Changes:

  • Extend assay-types::ChunkRef with depends_on and update JSON schema snapshots accordingly.
  • Add assay-core::manifest_gen (generate + atomic write) and wire it into MCP (manifest_generate) and CLI (assay manifest generate).
  • Update assorted tests and milestone-creation helpers to populate the new depends_on field.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
crates/assay-types/src/milestone.rs Adds ChunkRef.depends_on and updates docs/tests for milestone chunk scheduling constraints.
crates/assay-types/tests/snapshots/schema_snapshots__milestone-schema.snap Snapshot update to reflect new depends_on field and updated descriptions.
crates/assay-types/tests/snapshots/schema_snapshots__chunk-ref-schema.snap Snapshot update to reflect new depends_on field and updated descriptions.
crates/assay-core/src/manifest_gen.rs New core module to generate RunManifest from milestones or specs and write it atomically.
crates/assay-core/src/lib.rs Exposes manifest_gen behind the orchestrate feature.
crates/assay-mcp/src/server.rs Registers MCP tool manifest_generate and adds handler tests.
crates/assay-cli/src/main.rs Adds top-level assay manifest command group.
crates/assay-cli/src/commands/mod.rs Registers new manifest command module.
crates/assay-cli/src/commands/manifest.rs New CLI subcommand implementation for assay manifest generate.
crates/assay-core/src/wizard.rs Ensures wizard-created milestones initialize depends_on for chunks.
crates/assay-core/src/pr.rs Updates milestone construction in tests for new depends_on field.
crates/assay-core/tests/pr.rs Updates test milestones to include depends_on: vec![].
crates/assay-core/tests/milestone_io.rs Updates milestone I/O tests for new depends_on field.
crates/assay-core/tests/cycle.rs Updates cycle tests for new depends_on field.
crates/assay-core/tests/analytics.rs Updates analytics test milestone construction for new depends_on field.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +38 to +42
/// A reference to a `GatesSpec` chunk within a milestone, identified by slug and scheduling constraints.
///
/// Each `ChunkRef` corresponds to a directory-based spec (a "chunk") that
/// contributes to the parent milestone. The `order` field controls the
/// canonical sequence for display and progress tracking.
/// contributes to the parent milestone. The `order` field is cosmetic display ordering only;
/// use `depends_on` to declare scheduling constraints between chunks.
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs now describe ChunkRef.order as “cosmetic display ordering only”, but milestone cycle logic uses order to determine the active/next chunk (lowest-order incomplete). That makes order behaviorally significant. Please update this docstring/schema wording to reflect its role in cycle progression (or update the cycle algorithm if depends_on is intended to replace it).

Copilot uses AI. Check for mistakes.
Comment on lines +96 to +100
let specs_dir = config.assay_dir.join("specs");
let scan_result = spec::scan(&specs_dir)?;

if scan_result.entries.is_empty() {
return Err(AssayError::Io {
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ManifestSource::AllSpecs hard-codes the specs directory as <assay_dir>/specs, but .assay/config.toml allows overriding Config.specs_dir (and other CLI/MCP codepaths honor it). This will generate incorrect/empty manifests for projects with a non-default specs directory. Consider loading config to resolve the specs dir, or extending ManifestGenConfig to include the resolved specs path.

Copilot uses AI. Check for mistakes.
Comment on lines +88 to +92
prompt_layers: vec![],
file_scope: vec![],
shared_files: vec![],
depends_on: chunk.depends_on.clone(),
})
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Milestone generation copies ChunkRef.depends_on directly into ManifestSession.depends_on but does not validate unknown deps, self-deps, or cycles. Since the output is meant to be consumed as a DAG by Smelt/orchestrate, generate_manifest should validate the dependency graph (e.g., via orchestrate::dag::DependencyGraph::from_manifest) and return a clear error before writing an invalid manifest. Adding unit tests for unknown/cyclic deps would help prevent regressions.

Copilot uses AI. Check for mistakes.
- Use typed ManifestSourceParam enum in MCP params (proper JSON schema enum constraint)
- Add manifest_gen imports to server.rs (style: avoid long module paths in handler)
- Fix AssayError::Io message duplication in empty-chunks/no-specs error paths
- Fix write_manifest doc: clarify crash-safety guarantee (no corruption, may leave temp file)
- Fix ManifestSource doc: accurate assay_dir path reference
- Add PartialEq + Eq to ManifestSource for testability
- Remove unused dir.clone() in CLI handler
- Fix CLI command description (drop 'manage' — only generate exists)
- Fix manifest_gen module doc: clarify feature gate rationale
- Fix depends_on field doc: remove (S03) slice ref, remove upward coupling to manifest_generate
- Improve TOML spec comment in test helper
- Update chunk-ref and milestone schema snapshots
- Add tracing::warn on manifest_generate error path
@wollax wollax merged commit caaeb09 into main Apr 1, 2026
1 of 2 checks passed
@wollax wollax deleted the kata/root/M018/S03 branch April 1, 2026 17:00
@wollax wollax restored the kata/root/M018/S03 branch April 1, 2026 17:03
@wollax wollax deleted the kata/root/M018/S03 branch April 9, 2026 21:57
wollax added a commit that referenced this pull request Apr 17, 2026
* feat(M018/S02): ChunkRef dependency encoding — add depends_on field

Adds `depends_on: Vec<String>` to `ChunkRef` in assay-types for Smelt manifest scheduling constraints.

- Additive serde field with default/skip-serializing-if for backward compat
- Updated struct-level doc; clarified order is cosmetic-only
- JSON + TOML roundtrip tests, schema snapshots regenerated
- All ChunkRef struct literals updated across 9 files

Closes WOL-161 (M018/S02)

* feat(S03/T01): add manifest_gen module with generate_manifest + write_manifest

New assay-core::manifest_gen module (gated behind orchestrate feature):
- ManifestSource enum: Milestone(slug) and AllSpecs
- generate_manifest() maps ChunkRef -> ManifestSession with depends_on
- write_manifest() uses atomic tempfile-then-rename
- 8 unit tests covering all paths (deps, no-deps, errors, round-trip)

* feat(S03/T02): register manifest_generate MCP tool + handler tests

New manifest_generate tool in AssayServer tool router:
- ManifestGenerateParams: source (milestone/all-specs), slug, output
- Delegates to manifest_gen::generate_manifest + write_manifest via spawn_blocking
- Returns JSON with written path and session count
- 3 handler tests: tool registration, milestone generation, missing slug error

* feat(S03/T03): add assay manifest generate CLI subcommand

New 'assay manifest generate' subcommand:
- --from-milestone <slug>: generate from milestone chunks with depends_on
- --from-specs: generate from all specs (fully parallel)
- --output <path>: output file path (default: manifest.toml)
- Mutually exclusive flag validation
- Prints 'Written <path> (N sessions)' on success

* fix(S03): address PR review findings

- Use typed ManifestSourceParam enum in MCP params (proper JSON schema enum constraint)
- Add manifest_gen imports to server.rs (style: avoid long module paths in handler)
- Fix AssayError::Io message duplication in empty-chunks/no-specs error paths
- Fix write_manifest doc: clarify crash-safety guarantee (no corruption, may leave temp file)
- Fix ManifestSource doc: accurate assay_dir path reference
- Add PartialEq + Eq to ManifestSource for testability
- Remove unused dir.clone() in CLI handler
- Fix CLI command description (drop 'manage' — only generate exists)
- Fix manifest_gen module doc: clarify feature gate rationale
- Fix depends_on field doc: remove (S03) slice ref, remove upward coupling to manifest_generate
- Improve TOML spec comment in test helper
- Update chunk-ref and milestone schema snapshots
- Add tracing::warn on manifest_generate error path

---------

Co-authored-by: Test <test@test.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants