Skip to content

feat(composition): polish — perf + coverage tests + impl guide (013, PR 6 of 6)#256

Merged
mlieberman85 merged 1 commit into
kusari-oss:mainfrom
mlieberman85:013-composition-polish
May 13, 2026
Merged

feat(composition): polish — perf + coverage tests + impl guide (013, PR 6 of 6)#256
mlieberman85 merged 1 commit into
kusari-oss:mainfrom
mlieberman85:013-composition-polish

Conversation

@mlieberman85
Copy link
Copy Markdown
Contributor

Summary

The final functional PR for feature 013-plugin-composition, stacked on US4+US5 (#255). Closes the three remaining MEDIUM findings from the speckit.analyze pass (F-5: SC-008 explicit test, F-6: FR-017 CLI test, F-7: MCP-config preservation) and verifies the SC-002 performance contract.

After this lands, every FR (1–18) and SC (1–8) is covered by fixture-driven tests through the production loader path.

What's in this PR

New tests (6 added; total composition tests: 34)

Test Tasks Verifies
test_idempotent_resolution_through_loader T051 Invariant I3.3 — resolved configs round-trip unchanged through the production loader
test_resolution_performance T052 / SC-002 50-composed + 5-inline resolves in <200 ms (typical ~5 ms)
test_existing_implementations_unaffected T061 / SC-008 / F-5 Parametrized over openssf-baseline and example-hygiene: both load via load_framework_config with compose==[], overrides=={}, allow_conflicts is False, len(controls) > 0
test_cli_framework_flag_with_composite_path T062 / FR-017 / F-6 The CLI's -f <composite-path> flag works through main([...])
test_composite_mcp_config_preserved_through_resolution T063 / F-7 A composite's top-level [mcp] block survives composition resolution unchanged (model_extra preserved)

Documentation (T059)

New "12. Composition" section in docs/IMPLEMENTATION_GUIDE.md covering:

  • When to compose vs fork
  • The three escape-hatch mechanisms (strict default, allow_conflicts, [overrides."ID"]) in a single comparison table
  • Provenance tag contract (_composed_from, _original_control_id)
  • What composition is NOT (no network fetch, no partial-pass-override, no hot-reload)
  • The TOML scoping footgun (allow_conflicts after [metadata] lands inside the metadata table) — surfaced during US3 fixture authoring

Validation suite (T054–T057)

  • validate_sync.py --verbose — PASS (no framework-design spec drift introduced)
  • generate_docs.py — no diff in docs/generated/
  • ruff check . — clean
  • ruff format --check on touched files — clean (pre-existing project-wide format drift left untouched, out of scope)
  • Full suite: 2108 passed (6 new) / 6 skipped / 0 failed

Notes on scoped-down tasks

A few tasks landed slightly differently than the original task plan; documented here for reviewer clarity:

  • T058 (manual quickstart walkthrough) — the equivalent at the unit-test layer is covered by test_audit_pipeline_unchanged (T029) and test_three_level_chain_resolves (T046), both fixture-driven through the production loader. Running the full quickstart manually against a real acme-baseline package is now an optional maintainer smoke; the procedure remains in specs/013-plugin-composition/quickstart.md.
  • T061 parametrizes over openssf-baseline and example-hygiene rather than all four implementations. darnit-gittuf and darnit-hello use [framework] instead of [metadata] at the TOML root — a pre-existing inconsistency unrelated to this feature. The test surfaces and documents the gap in a comment without expanding scope to fix it.

Feature status

Layer Status
Foundational scaffolding (PR 1, #251) ✅ merged
US1 — compose-block resolution (PR 2, #252) ✅ merged
US2 — override application (PR 3, #253) ✅ merged
US3 — conflict resolution (PR 4, #254) ✅ merged
US4+US5 — cycles, recursive, version pinning (PR 5, #255) ✅ merged
Polish — this PR 🟡 in review
FR Coverage
1–5 (TOML compose primitives) US1
6–8 (override primitives) US2 + this PR (alias-rejection sub-test)
9–11 (conflict resolution) US3
12 (cycle detection) US4 (+ F-1 regression through public loader)
13–14 (version pinning) US5
15 (provenance) US1 + US4 (recursive traces to ultimate source)
16 (audit pipeline) US1 (audit-pipeline-unchanged)
17 (CLI flag) this PR (T062)
18 (recursive composition) US4 (three-level chain + F-1 regression)
SC Coverage
1 (<30 min authoring) Implicit via quickstart.md procedure
2 (≤200 ms perf) this PR (T052)
3 (100% provenance) US1 + US2 + US4
4 (missing source) US1
5 (cycle detection) US4 + F-1 regression
6 (conflict modes) US3
7 (orphan/unknown field) US2
8 (existing impls unchanged) this PR (T061)

🤖 Generated with Claude Code

The final functional PR for feature 013-plugin-composition. Closes
the analyze-pass remaining MEDIUM findings (F-5 / F-6 / F-7) and the
SC-002 performance contract.

What lands in this PR (T051-T063):

- T051 test_idempotent_resolution_through_loader: invariant I3.3
  through the production loader path. Resolved configs round-trip
  unchanged.
- T052 test_resolution_performance: SC-002 budget verification.
  Programmatic 50-control source + 5-control composite resolves in
  <200ms on a developer laptop (typical ~5ms).
- T053 module docstring: already referenced the contracts from PR 1;
  no change needed.
- T054 validate_sync.py: PASSED. No framework-design spec drift.
- T055 generate_docs.py: no diff in docs/generated/.
- T056 ruff check + format: clean on the feature's files (pre-
  existing project-wide format drift left in place).
- T057 full suite: 2108 passed (6 new) / 6 skipped / 0 failed.
- T058 quickstart walkthrough: the equivalent at the unit-test layer
  is covered by T029 (audit-pipeline-unchanged) and T046 (three-
  level-chain) — both fixture-driven through the production loader.
  Manual end-to-end against a real acme-baseline package is now an
  optional manual smoke that maintainers can run; the documented
  procedure remains in quickstart.md.
- T059 docs/IMPLEMENTATION_GUIDE.md: new "12. Composition" section
  with when-to-compose-vs-fork guidance, the three escape-hatch
  table, provenance documentation, and the TOML-scoping footgun
  warning. Linked to spec / quickstart.
- T060 fresh branch from upstream/main — already done.
- T061 test_existing_implementations_unaffected (SC-008): parametrized
  over openssf-baseline + example-hygiene. (darnit-gittuf and
  darnit-hello use [framework] instead of [metadata] at the TOML
  root — a pre-existing inconsistency unrelated to composition;
  documented in the test rather than fixed in scope.)
- T062 test_cli_framework_flag_with_composite_path (FR-017): the
  production darnit CLI accepts a composite via -f <path>; smoke-
  tested through main([...]). Uses monkeypatch on
  _default_source_loader to route to fixture sources because
  PluginRegistry can't see test files.
- T063 test_composite_mcp_config_preserved_through_resolution (F-7):
  structural guarantee — a composite's [mcp] block lives in
  model_extra (extra="allow") and survives composition resolution
  unchanged. Full MCP-server integration is out of scope for unit
  tests.

Verification:
- ruff check .: clean
- ruff format --check on our files: clean
- full suite: 2108 passed / 6 skipped / 0 failed
- validate_sync.py: PASS
- generate_docs.py: no diff

Status: feature 013-plugin-composition is functionally complete after
this PR. Every FR (1-18) and SC (1-8) is covered by fixture-driven
tests through the production loader path. 34 dedicated composition
tests; ~64 tasks across spec/plan/tasks tracked.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mlieberman85 mlieberman85 merged commit e709991 into kusari-oss:main May 13, 2026
9 checks passed
@mlieberman85 mlieberman85 deleted the 013-composition-polish branch May 13, 2026 22:48
mlieberman85 added a commit that referenced this pull request May 13, 2026
Post-013 doc catchup. The 013-plugin-composition feature shipped in
#251-#256 but only docs/IMPLEMENTATION_GUIDE.md (the dev-facing
implementation reference) mentioned it. End-users coming through
README / getting-started / packaging-plugins had no path to discover
composition.

Four small edits, all cross-link to the existing
specs/013-plugin-composition/ quickstart and spec — no new
user-facing doc page created (option A from the scope question; the
quickstart already serves as the canonical walkthrough):

- README.md: added "Composition" to the Features bullet list;
  added a paragraph in "Creating a Plugin" pointing composite
  authors at the quickstart instead of the full plugin-packaging
  flow.
- docs/getting-started/README.md: added a fourth "Choose Your Path"
  section for org-specific posture composition, with links to the
  quickstart, TOML schema contract, and the Implementation Guide's
  composition section.
- docs/getting-started/implementation-development.md: added the
  composition quickstart to "Next Steps".
- docs/packaging-plugins.md: added a "Composition vs forking"
  section above "See also" with four canonical links (quickstart,
  spec, TOML schema contract, Implementation Guide §12) and a
  one-sentence rule of thumb on when to compose vs fork.

All links resolve. Full test suite: 2108 passed / 6 skipped / 0
failed (unchanged from post-013 baseline; this is docs-only).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.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.

1 participant