Skip to content

docs(decisions): Treat settings-only pnpm workspace as root package - #79

Merged
yunseo-kim merged 4 commits into
mainfrom
docs/adr-0078-pnpm-workspace-settings-only
Aug 12, 2026
Merged

yunseo-kim merged 4 commits into
mainfrom
docs/adr-0078-pnpm-workspace-settings-only

Conversation

@yunseo-kim

@yunseo-kim yunseo-kim commented Aug 12, 2026 •

Copy link
Copy Markdown
Member

Summary

  • What changed?
    • Add accepted ADR 0078, Treat settings-only pnpm-workspace.yaml as standalone root package mode.
    • Amend ADR 0018 with a symmetric amends / amended-by relation scoped to pnpm root-package selection.
    • Synchronize the JS/TS npm build-pack and verification-fixture specs, bilingual indexes, and standing implementation follow-up.
  • Why is this needed?
    • The first live vers-js dogfood run rejected a valid settings-only pnpm-workspace.yaml with windlass.verify.error.package-resolution-invalid. pnpm documents an omitted packages field as root-only membership, so the existing malformed-metadata clause over-rejects modern pnpm repositories.
    • This docs-only PR pins the corrected contract while preserving fail-closed behavior for present malformed packages values, unsupported patterns, and genuinely ambiguous resolution. N02 implementation and fixtures remain a follow-up.

Related Issues

Change Type

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Test/CI
  • Breaking change
  • Other:

Changelog

  • Category: None
  • User-facing note: Docs-only architecture decision and specification sync; the observable behavior change lands with the N02 implementation follow-up.

Changelog update:

  • CHANGELOG.md [Unreleased] updated
  • Not needed because this change is not user-facing

Checklist

General

  • PR title follows Conventional Commits format: type(scope): Summary
  • This PR does not expose backend/internal implementation details in a public repo.
  • No secrets, tokens, keys, or private endpoints are included.
  • Changes stay within this repository's intended scope.

CI/Workflow Changes (if applicable)

If this PR modifies GitHub Actions workflows or CI/CD configuration, it must comply with our Supply Chain Integrity requirements:

  • All uses: references are pinned to full 40-character commit SHAs (with # vX.Y.Z comment)
  • step-security/harden-runner is included as the first step in every job
  • Job-level permissions are used instead of top-level permissions

Protocol / Compatibility Impact

  • No protocol/spec impact
  • Protocol/spec updated
  • Conformance tests updated
  • Breaking change is versioned and migration notes are included

If impacted, describe compatibility impact:

ADR 0078 narrows an over-broad rejection: an object-form pnpm-workspace.yaml with no packages member is root-only package mode. Present malformed members, unsupported patterns, and ambiguous package resolution remain fail-closed under the existing diagnostic taxonomy. The implementation and conformance fixtures are explicitly deferred to N02.

Testing

  • Unit tests added/updated
  • Integration or conformance tests added/updated
  • Tests pass
  • Lint and format pass
  • Type check passes
  • Manual verification performed

Describe test evidence:

  • python3 .agents/skills/adr-relations-check/scripts/check_relations.py → 79 ADRs, 162 edges — NO PROBLEMS
  • go test ./internal/diagnostic -run TestRegistryMatchesSpecTaxonomy -count=1 → pass
  • pnpm exec prettier --check "AGENTS.md" "docs/**/*.md" → pass
  • pnpm exec markdownlint-cli2 "AGENTS.md" "docs/**/*.md" → 0 errors
  • git diff --check → pass

Documentation

  • README updated
  • Spec/docs updated
  • Changelog decision completed above

Rollout / Risk

  • Risk level: Low
  • Rollback plan: Revert this docs-only PR. No runtime implementation, fixtures, workflow behavior, or diagnostic IDs change here.

Reviewer Checklist

  • Scope is clear and minimal
  • Security and boundary checks passed
  • Tests and docs are sufficient
  • Compatibility impact is correctly handled

Record the live dogfood classification gap and amend ADR 0018 so an
omitted pnpm packages member maps to the existing root-package case.

Signed-off-by: Yunseo Kim <git@yunseo.kim>
Narrow malformed workspace metadata while preserving fail-closed
handling and pin the implementation fixture follow-up.

Signed-off-by: Yunseo Kim <git@yunseo.kim>
Add the decision and its specification mappings to the bilingual ADR
and architecture inventories.

Signed-off-by: Yunseo Kim <git@yunseo.kim>
Advance ADR numbering and retain the N02 fixture work and vers-js
dogfood retry as a standing implementation item.

Signed-off-by: Yunseo Kim <git@yunseo.kim>
@yunseo-kim
yunseo-kim merged commit 508f394 into main Aug 12, 2026
16 checks passed
@yunseo-kim
yunseo-kim deleted the docs/adr-0078-pnpm-workspace-settings-only branch August 12, 2026 17:58
yunseo-kim added a commit that referenced this pull request Aug 12, 2026
## Summary

- What changed?
- Treat a parsed `pnpm-workspace.yaml` object without `packages` as a
terminal standalone-root package boundary with zero workspace patterns.
- Keep present non-array/non-string `packages` values and unsupported
patterns fail-closed.
- Add the ADR 0078 accepted and rejected fixture matrix and register it
with the F06 harness.
- Why is this needed?
- The first `vers-js` dogfood run 31622651874 exposed that valid modern
pnpm policy settings were incorrectly classified as malformed workspace
metadata.

## Related Issues

- Closes #
- Related #22

Issue #22 remains open for the orchestrator's post-merge dogfood retry.

## Change Type

- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Documentation
- [x] Test/CI
- [ ] Breaking change
- [ ] Other:

## Changelog

- Category: Fixed
- User-facing note: Standalone pnpm root packages with settings-only
`pnpm-workspace.yaml` files now resolve successfully without weakening
malformed-workspace rejection.

Changelog update:

- [x] `CHANGELOG.md` `[Unreleased]` updated
- [ ] Not needed because this change is not user-facing

## Checklist

### General

- [x] PR title follows [Conventional
Commits](https://www.conventionalcommits.org/) format: `type(scope):
Summary`
- [x] This PR does not expose backend/internal implementation details in
a public repo.
- [x] No secrets, tokens, keys, or private endpoints are included.
- [x] Changes stay within this repository's intended scope.

### CI/Workflow Changes (if applicable)

Not applicable; no workflow files changed.

- [ ] All `uses:` references are pinned to full 40-character commit SHAs
(with `# vX.Y.Z` comment)
- [ ] `step-security/harden-runner` is included as the first step in
every job
- [ ] Job-level `permissions` are used instead of top-level
`permissions`

### Protocol / Compatibility Impact

- [x] No protocol/spec impact
- [ ] Protocol/spec updated
- [x] Conformance tests updated
- [ ] Breaking change is versioned and migration notes are included

If impacted, describe compatibility impact:

ADR 0078 and both architecture specs were already synchronized by #79.
This implementation admits only the documented root-only pnpm shape;
existing npm/Yarn workspaces and pnpm arrays remain unchanged.

## Testing

- [x] Unit tests added/updated
- [x] Integration or conformance tests added/updated
- [x] Tests pass
- [x] Lint and format pass
- [ ] Type check passes
- [x] Manual verification performed

Describe test evidence:

- RED: `go test ./internal/npmprofile -run
'TestWorkspaceDiscovery|TestLockfileRules' -count=1` failed because
`pnpm settings-only root` emitted
`windlass.verify.error.package-resolution-invalid`.
- GREEN: `go test ./internal/npmprofile -count=1` passed.
- Fixture harness: `go run ./cmd/slsa-builder-internal fixture-check
--index testdata/fixtures/index.json --surface npm --phase build-pack`
returned pass/exit 0.
- Full gates: `go test -race ./...`, `go vet ./...`, `golangci-lint run
./...` (0 issues), and `golangci-lint fmt --diff` (clean) passed.

Fixture matrix:

| Fixture | Case | Expected |
| --- | --- | --- |
| `pnpm-settings-only-root-valid` | Settings-only root, omitted
`packages` | Pass; root package and root manager directory |
| `pnpm-workspace-packages-wrong-type` | Present scalar `packages` |
Fail with `windlass.verify.error.package-resolution-invalid` |
| `pnpm-settings-only-subdirectory` | Subdirectory beneath settings-only
root | Fail with `windlass.verify.error.package-resolution-invalid` |

Security review: no new path or pattern input is accepted. The relaxed
branch is reachable only after strict YAML object parsing and only when
`packages` is absent; it accepts exact candidate-root equality and
rejects subdirectories immediately, so farther ancestor discovery and
standalone subpackage fallback cannot weaken one-package or ambiguity
checks.

## Documentation

- [ ] README updated
- [ ] Spec/docs updated
- [x] Changelog decision completed above

Specs were already updated by #79; no ADR/spec files changed here.

## Rollout / Risk

- Risk level: Low
- Rollback plan: Revert the implementation and additive fixture commits;
no persisted data or remote mutation behavior changes.

## Reviewer Checklist

- [x] Scope is clear and minimal
- [x] Security and boundary checks passed
- [x] Tests and docs are sufficient
- [x] Compatibility impact is correctly handled

---------

Signed-off-by: Yunseo Kim <git@yunseo.kim>
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.

1 participant