microsoft / microsoft/amplifier

Feature Request: Support Bundle-Based Surface Contracts as Alternative to Separate DSL

Open
#182 0 comments 0 reactions 0 assignees View on GitHub

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:

  1. Keep Surfaces as a separate DSL (current approach)
  2. Provide guidance/tooling for bundle-based contracts as an alternative
  3. Eventually migrate to bundle-based contracts as the primary pattern

Request

We'd like the Amplifier team's perspective on:

  1. Is bundle-based contracts a pattern worth officially supporting?
  2. Should Foundation's bundle schema be extended with optional contract: / implements: fields?
  3. Any concerns with either approach from an ecosystem consistency standpoint?

Related

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.