microsoft / microsoft/amplifier
Feature Request: Support Bundle-Based Surface Contracts as Alternative to Separate DSL
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 3.1k
- Forks
- 261
- Avg merge
- 3h 28m
- Merged PRs (30d)
- 13
Description
Context
We're building amplifier-surface, a meta-bundle that provides capability contracts, effect declarations, schema validation, and audit trails for reproducible AI workflows. Currently, Surfaces use a separate DSL (.surface.yaml files).
After extensive analysis with amplifier-expert and foundation-expert, we've determined that Surfaces could be implemented using standard bundle semantics instead. This would provide a more unified approach aligned with Amplifier's "thin bundle" philosophy.
The Problem Surfaces Solve
Standard Amplifier bundles answer: "What tools are available?"
Surfaces answer: "What can these tools do, what are they allowed to do, and how do we verify compliance?"
| Need | Bundles | Surfaces |
|---|---|---|
| Include tool X | ✅ | ✅ |
| Restrict tool to read-only effects | ❌ | ✅ |
| Validate inputs match schema | ❌ | ✅ |
| Discover tools by capability interface | ❌ | ✅ |
| Block session if capability missing | ❌ | ✅ |
| Catch import/effect mismatches | ❌ | ✅ |
Current Surface DSL Approach
surface:
name: data-analysis
namespace: science
version: "1.0.0"
effects:
- filesystem.read.file
- compute.cpu
capabilities:
- name: run_statistical_test
type: query
input_schema:
properties:
test_type: {enum: [t_test, anova]}
output_schema:
properties:
p_value: {type: number}
effects: [filesystem.read]
Proposed Bundle-Based Alternative
Key Finding: Bundle loader already ignores unknown fields
The Foundation bundle loader only extracts known fields - unknown fields are ignored, not rejected. This means contract:, effects:, implements: can be added to bundle frontmatter TODAY.
Pattern 1: Contract as Behavior Bundle
# contracts/science-hypothesis.yaml
bundle:
name: contract-science-hypothesis
version: "1.0.0"
contract:
namespace: science
name: hypothesis
effects:
- ai.prompt
- filesystem.read
capabilities:
- name: generate_hypothesis
type: action
input_schema:
type: object
required: [observation]
properties:
observation: { type: string }
output_schema:
type: object
properties:
hypothesis: { type: string }
effects: [ai.prompt]
Pattern 2: Tool Declares Implementation
# behaviors/science.yaml
tools:
- module: tool-hypothesis-generator
config:
implements:
- contract: science:hypothesis
capabilities: [generate_hypothesis, refine_hypothesis]
Pattern 3: Validation via Standard Hooks
hooks:
- module: hook-contract-validator
config:
strict_mode: true
on_violation: deny # Uses HookResult(action="deny")
What Would Be Required
| Component | Complexity | Notes |
|---|---|---|
contract: field convention |
Low | Already ignored by loader |
implements: in tool config |
Low | Just config data |
hook-contract-validator |
Medium | Reads fields, validates |
Schema files in context/ |
None | Already supported |
Minimal change: One new hook module + documentation of conventions.
Tradeoffs
| Separate Surface DSL | Bundle-Based Contracts |
|---|---|
Clear visual distinction (.surface.yaml) |
Mixed with other bundles |
| Purpose-built tooling | Generic bundle tools |
| Independent evolution | Coupled to bundle schema |
| Two schemas to learn | Single unified schema |
| Explicit domain modeling | "Contracts are behaviors with schemas" |
Philosophical Alignment
Foundation expert perspective:
"If Surfaces can be expressed as behaviors + context + hooks, that's preferable to a new primitive type. The power of bundles is their composability - contracts should compose the same way."
Amplifier expert perspective:
"The separation is appropriate separation of concerns, not violation of 'one way to do things'. The Surface DSL exists because contracts are not packages."
Both approaches are valid. The question is whether the ecosystem should:
- Keep Surfaces as a separate DSL (current approach)
- Provide guidance/tooling for bundle-based contracts as an alternative
- Eventually migrate to bundle-based contracts as the primary pattern
Request
We'd like the Amplifier team's perspective on:
- Is bundle-based contracts a pattern worth officially supporting?
- Should Foundation's bundle schema be extended with optional
contract:/implements:fields? - Any concerns with either approach from an ecosystem consistency standpoint?
Related
- Local analysis: https://github.com/michaeljabbour/amplifier-surface/blob/main/docs/SURFACES_VS_BUNDLES.md
- Local tracking issue: https://github.com/michaeljabbour/amplifier-surface/issues/1
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the linked docs/SURFACES_VS_BUNDLES.md and reviewing the Foundation bundle loader behavior described in the issue. Compare the separate Surface DSL with the contract:, implements:, and hook-contract-validator conventions, then document whether bundle-based contracts should be officially supported and whether the optional fields belong in the bundle schema.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100