Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,11 @@ The `xyflow` no-op refresh decision is now captured as a checked example
fixture under `tests/fixtures/refresh_decisions/`, giving future tooling a
stable artifact for `updateNeeded: false` without making no-op records registry
authority.
SpecPM can now prepare refresh decision records from a fresh generated candidate
tree with `specpm producer-bundle prepare-refresh-decision`, compare
contract-bearing generated files, and emit read-only
`SpecPMGeneratedCandidateRefreshDecisionPrepareReport` evidence before any
maintainer registry decision.
SpecPM now has a consumer-side `preflight-ai-draft` gate for
`SpecHarvesterPackageSetAIDraftProposal`. It verifies AI-proposed member
selection, exclusions, and `contains` relations against deterministic workspace
Expand Down
9 changes: 9 additions & 0 deletions Sources/SpecPM/Documentation.docc/CLIReference.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,15 @@ is provided. The report kind is
review evidence only and does not mutate accepted packages, generated
candidates, relations, or registry metadata.

`prepare-refresh-decision` builds a draft
`SpecPMGeneratedCandidateRefreshDecision` from a fresh generated artifact tree
and current registry evidence. It compares `specpm.yaml` and
`specs/*.spec.yaml`, writes the decision JSON with `--output` when requested,
and emits `SpecPMGeneratedCandidateRefreshDecisionPrepareReport`. It can produce
`no_update_required` for byte-identical generated contract files or
`manual_review_required` when contract drift needs maintainer review. It is
read-only and does not mutate registry artifacts.

`materialize-package-set` consumes the same package-set handoff only after
maintainers pass explicit `--package` and optional `--relation` selections. In
dry-run mode it writes a materialization report, accepted-manifest candidate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,38 @@ A complete example fixture is available at
and snapshots generated contract-file digests that support
`updateNeeded: false`.

## Prepare Helper

SpecPM can prepare a draft refresh decision by comparing fresh generated
candidate artifacts with the current registry evidence:

```bash
specpm producer-bundle prepare-refresh-decision \
--root . \
--fresh-generated-root <fresh-public-index-generated-root> \
--package xyflow.workspace \
--package xyflow.react \
--package xyflow.svelte \
--package xyflow.system \
--package-id xyflow.workspace \
--version 0.1.0 \
--source-repository https://github.com/xyflow/xyflow \
--source-revision <40-char-source-sha> \
--output refresh-decision.json \
--json
```

The command emits `SpecPMGeneratedCandidateRefreshDecisionPrepareReport` and can
write the prepared `SpecPMGeneratedCandidateRefreshDecision` with `--output`.
It compares only contract-bearing generated files (`specpm.yaml` and
`specs/*.spec.yaml`), records current generated contract-file SHA-256 digests,
and runs the same consumer-side preflight rules against the prepared decision.

Matching contract files produce `status: no_update_required`,
`updateNeeded: false`, and `reason: no_contract_delta`. Contract, source
revision, or accepted-artifact drift produces `manual_review_required` with
`updateNeeded: true`. Both outcomes remain review evidence only.

## Consumer-Side Preflight

SpecPM can verify refresh decision records with:
Expand Down
22 changes: 22 additions & 0 deletions Sources/SpecPM/Documentation.docc/ProducerBundleProposalPolicy.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,28 @@ The command verifies the `specpm.decisions/v0` decision envelope,
authority boundary, safe artifact paths, and generated contract-file digests.
It is review evidence only and does not perform registry acceptance or mutation.

When maintainers have a fresh generated candidate tree and need to decide
whether it changes current registry evidence, SpecPM can prepare the decision
record first:

```bash
specpm producer-bundle prepare-refresh-decision \
--root <repository-root> \
--fresh-generated-root <fresh-generated-root> \
--package <package-id> \
--version <version> \
--source-revision <40-char-source-sha> \
--output <generated-candidate-refresh-decision.json> \
--json
```

The report kind is `SpecPMGeneratedCandidateRefreshDecisionPrepareReport`. The
helper compares contract-bearing generated files, emits a draft
`SpecPMGeneratedCandidateRefreshDecision`, and immediately runs the same
consumer-side preflight checks. It is read-only review evidence and does not
write accepted packages, generated candidates, relations, or public registry
metadata.

## Fixture Alignment

Cross-repository fixture ownership and drift handling are defined in
Expand Down
5 changes: 5 additions & 0 deletions Sources/SpecPM/Documentation.docc/Roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,11 @@ The `xyflow` no-op refresh decision is now captured as a checked example
fixture under `tests/fixtures/refresh_decisions/`, giving future tooling a
stable artifact for `updateNeeded: false` without making no-op records registry
authority.
SpecPM can now prepare refresh decision records from a fresh generated candidate
tree with `specpm producer-bundle prepare-refresh-decision`, compare
contract-bearing generated files, and emit read-only
`SpecPMGeneratedCandidateRefreshDecisionPrepareReport` evidence before any
maintainer registry decision.
SpecPM now has a consumer-side `preflight-ai-draft` gate for
`SpecHarvesterPackageSetAIDraftProposal`. It verifies AI-proposed member
selection, exclusions, and `contains` relations against deterministic workspace
Expand Down
1 change: 1 addition & 0 deletions specpm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ index:
- specpm.registry.curated_accepted_artifacts
- specpm.registry.generated_candidate_refresh_decision_policy
- specpm.registry.generated_candidate_refresh_decision_preflight
- specpm.registry.generated_candidate_refresh_decision_prepare
- specpm.registry.index_removal_request_flow
- specpm.registry.namespace_claim_request_flow
- specpm.registry.namespace_claim_policy
Expand Down
35 changes: 35 additions & 0 deletions specs/GENERATED_CANDIDATE_REFRESH_DECISION_POLICY.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,41 @@ records all four `xyflow` package-set members, cites the current curated and
generated artifact paths, and snapshots the generated contract-file digests
used to justify `updateNeeded: false`.

## Prepare Helper

SpecPM can prepare a draft refresh decision by comparing a fresh generated
candidate tree with the current registry evidence:

```bash
specpm producer-bundle prepare-refresh-decision \
--root . \
--fresh-generated-root <fresh-public-index-generated-root> \
--package xyflow.workspace \
--package xyflow.react \
--package xyflow.svelte \
--package xyflow.system \
--package-id xyflow.workspace \
--version 0.1.0 \
--source-repository https://github.com/xyflow/xyflow \
--source-revision <40-char-source-sha> \
--output refresh-decision.json \
--json
```

The command emits `SpecPMGeneratedCandidateRefreshDecisionPrepareReport` and can
write the prepared `SpecPMGeneratedCandidateRefreshDecision` with `--output`.
It compares only contract-bearing generated files (`specpm.yaml` and
`specs/*.spec.yaml`), records current generated contract-file SHA-256 digests,
checks the prepared decision with the same consumer-side preflight rules, and
keeps the output read-only review evidence.

If fresh and current generated contract files match, the draft decision uses
`status: no_update_required`, `updateNeeded: false`, and
`reason: no_contract_delta`. If contract files, source revisions, or accepted
artifact assumptions differ, the draft uses `manual_review_required` and
`updateNeeded: true`; it still does not mutate curated artifacts, generated
artifacts, relations, or registry metadata.

## Consumer-Side Preflight

SpecPM can verify a generated candidate refresh decision before maintainers use
Expand Down
6 changes: 6 additions & 0 deletions specs/MULTI_PACKAGE_PRODUCER_INTAKE.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,12 @@ The full curated artifact lifecycle is documented in
- package relation acceptance is recorded separately in
`public-index/accepted-packages.yml` `relations[]`.

When a fresh package-set run is available, maintainers can use
`specpm producer-bundle prepare-refresh-decision` to draft the refresh decision
from generated contract-file comparisons before running
`preflight-refresh-decision`. This remains evidence preparation, not package or
relation acceptance.

## Bundle-Set Checklist

Before accepting any part of a multi-package proposal, maintainers should verify:
Expand Down
22 changes: 22 additions & 0 deletions specs/PRODUCER_BUNDLE_PROPOSAL_POLICY.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,28 @@ The command verifies the `specpm.decisions/v0` decision envelope,
authority boundary, safe artifact paths, and generated contract-file digests.
It is review evidence only and does not perform registry acceptance or mutation.

When maintainers have a fresh generated candidate tree and need to decide
whether it changes current registry evidence, SpecPM can prepare the decision
record first:

```bash
specpm producer-bundle prepare-refresh-decision \
--root <repository-root> \
--fresh-generated-root <fresh-generated-root> \
--package <package-id> \
--version <version> \
--source-revision <40-char-source-sha> \
--output <generated-candidate-refresh-decision.json> \
--json
```

The report kind is `SpecPMGeneratedCandidateRefreshDecisionPrepareReport`. The
helper compares contract-bearing generated files, emits a draft
`SpecPMGeneratedCandidateRefreshDecision`, and immediately runs the same
consumer-side preflight checks. It is read-only review evidence and does not
write accepted packages, generated candidates, relations, or public registry
metadata.

## Fixture Alignment

Cross-repository fixture ownership and drift handling are defined in
Expand Down
20 changes: 20 additions & 0 deletions specs/PUBLIC_INDEX_OPERATOR_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,26 @@ record `status: no_update_required` instead of opening a registry churn PR.
Producer receipt churn, local output paths, or a newly emitted advisory quality
report are review evidence, not accepted contract deltas by themselves.

When a fresh generated candidate tree is available but no refresh decision has
been written yet, maintainers can prepare a draft record from the current
registry evidence:

```bash
specpm producer-bundle prepare-refresh-decision \
--root . \
--fresh-generated-root <fresh-public-index-generated-root> \
--package <package-id> \
--version <version> \
--source-revision <40-char-source-sha> \
--output <generated-candidate-refresh-decision.json> \
--json
```

The prepare helper compares generated `specpm.yaml` and `specs/*.spec.yaml`
files, emits `SpecPMGeneratedCandidateRefreshDecisionPrepareReport`, writes the
draft decision with `--output`, and performs the same preflight checks. It is
read-only review evidence.

When a `SpecPMGeneratedCandidateRefreshDecision` record is available,
maintainers should run:

Expand Down
48 changes: 48 additions & 0 deletions specs/WORKPLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -2362,6 +2362,54 @@ Result:
operator guidance, DocC, and self-spec document the command and non-authority
boundary.

### P66-T20. Generated Candidate Refresh Decision Prepare Helper

Status: Completed.

Motivation:

- P66-T19 can verify an already-written refresh decision, but maintainers still
need a repeatable way to draft that decision from a fresh generated candidate
run.
- Manual fixture editing is too error-prone for package-set refresh review:
paths, package IDs, source revision metadata, and generated contract-file
digests must stay aligned.

Goal:

- Add a read-only `specpm producer-bundle prepare-refresh-decision` command that
compares a fresh generated artifact tree with the current
`public-index/generated` evidence.
- Compare contract-bearing generated files (`specpm.yaml` and
`specs/*.spec.yaml`), record current generated SHA-256 digests, and produce a
draft `SpecPMGeneratedCandidateRefreshDecision`.
- Return `no_update_required` when fresh and current contract files match, and
`manual_review_required` when generated contract drift or source revision
drift requires maintainer review.
- Immediately run the existing preflight rules against the prepared decision,
while keeping the helper read-only and non-authoritative.

Expected result:

- Maintainers can run prepare against a fresh SpecHarvester output and get both
a machine-readable prepare report and an optional decision JSON file.
- The helper does not mutate accepted packages, generated candidates, accepted
relations, or public registry metadata.
- The prepared decision can be passed directly to
`specpm producer-bundle preflight-refresh-decision`.

Result:

- `specpm producer-bundle prepare-refresh-decision` emits
`SpecPMGeneratedCandidateRefreshDecisionPrepareReport`.
- The command supports package-set comparisons through repeated `--package`,
explicit `--package-id`, `--version`, `--source-revision`, and `--output`.
- Regression coverage checks the real `xyflow` no-op prepare path, CLI decision
output, preflight compatibility, and generated contract-delta detection.
- Refresh decision policy, producer bundle policy, public index operator guide,
CLI reference, DocC, roadmap, and self-spec document the helper and
non-authority boundary.

## Post-MVP Tracks

- Remote registry service implementation.
Expand Down
16 changes: 15 additions & 1 deletion specs/specpm.spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ provides:
- id: specpm.registry.generated_candidate_refresh_decision_preflight
role: secondary
summary: Preflight SpecPMGeneratedCandidateRefreshDecision records for decision shape, no-op consistency, authority boundaries, safe paths, and generated contract-file digests.
- id: specpm.registry.generated_candidate_refresh_decision_prepare
role: secondary
summary: Prepare draft SpecPMGeneratedCandidateRefreshDecision records from fresh/current generated artifact comparisons without mutating registry state.
- id: specpm.registry.package_set_relation_metadata
role: secondary
summary: Publish maintainer-reviewed package-set relation metadata through additive `/v0` payloads and the static viewer without inferring relations from producer output.
Expand Down Expand Up @@ -459,12 +462,16 @@ interfaces:
- text/plain
- id: cli_producer-bundle
kind: cli
summary: specpm producer-bundle preflight, preflight-refresh-decision, and materialize-package-set for consumer-side review of producer evidence, refresh decisions, and maintainer-selected package-set accepted-source artifacts.
summary: specpm producer-bundle preflight, prepare/preflight-refresh-decision, and materialize-package-set for consumer-side review of producer evidence, refresh decisions, and maintainer-selected package-set accepted-source artifacts.
outputs:
- name: producer_bundle_preflight_report
mediaTypes:
- application/json
- text/plain
- name: refresh_decision_prepare_report
mediaTypes:
- application/json
- text/plain
- name: refresh_decision_preflight_report
mediaTypes:
- application/json
Expand Down Expand Up @@ -734,6 +741,7 @@ evidence:
- specpm.registry.accepted_manifest_pr_helper
- specpm.registry.public_index_accepted_manifest
- specpm.registry.generated_candidate_refresh_decision_preflight
- specpm.registry.generated_candidate_refresh_decision_prepare
- id: add_specpackages_issue_template
kind: documentation
path: .github/ISSUE_TEMPLATE/add-specpackages.yml
Expand Down Expand Up @@ -838,6 +846,7 @@ evidence:
- specpm.specs.ai_enrichment_preflight
- specpm.specs.ai_draft_preflight
- specpm.registry.generated_candidate_refresh_decision_preflight
- specpm.registry.generated_candidate_refresh_decision_prepare
- id: index_submission_validator_source
kind: source
path: src/specpm/index_submission.py
Expand Down Expand Up @@ -1010,6 +1019,7 @@ evidence:
- specpm.specs.ai_enrichment_preflight
- specpm.specs.ai_draft_preflight
- specpm.registry.generated_candidate_refresh_decision_preflight
- specpm.registry.generated_candidate_refresh_decision_prepare
- specpm.registry.package_set_materialization_helper
- specpm.specs.producer_receipt_contract
- producer_receipts_not_generation_authority
Expand Down Expand Up @@ -1163,6 +1173,7 @@ evidence:
supports:
- specpm.registry.generated_candidate_refresh_decision_policy
- specpm.registry.generated_candidate_refresh_decision_preflight
- specpm.registry.generated_candidate_refresh_decision_prepare
- specpm.registry.curated_artifact_lifecycle
- specpm.registry.curated_accepted_artifacts
- specpm.specs.multi_package_producer_intake
Expand Down Expand Up @@ -1299,6 +1310,7 @@ evidence:
- specpm.registry.observed_intent_catalog
- specpm.specs.ai_draft_preflight
- specpm.registry.generated_candidate_refresh_decision_preflight
- specpm.registry.generated_candidate_refresh_decision_prepare
- id: core_source
kind: source
path: src/specpm/core.py
Expand Down Expand Up @@ -1465,6 +1477,7 @@ evidence:
- specpm.specs.ai_enrichment_preflight
- specpm.specs.ai_draft_preflight
- specpm.registry.generated_candidate_refresh_decision_preflight
- specpm.registry.generated_candidate_refresh_decision_prepare
- specpm.specs.producer_receipt_contract
- id: docc_producer_bundle_fixture_policy
kind: documentation
Expand Down Expand Up @@ -1585,6 +1598,7 @@ evidence:
- specpm.documentation.docc_site
- specpm.registry.generated_candidate_refresh_decision_policy
- specpm.registry.generated_candidate_refresh_decision_preflight
- specpm.registry.generated_candidate_refresh_decision_prepare
- specpm.registry.curated_artifact_lifecycle
- specpm.registry.curated_accepted_artifacts
- specpm.specs.multi_package_producer_intake
Expand Down
Loading