| layout | default |
|---|---|
| title | Chapter 8: Production Governance and Rollout |
| nav_order | 8 |
| parent | Crush Tutorial |
Welcome to Chapter 8: Production Governance and Rollout. In this part of Crush Tutorial: Multi-Model Terminal Coding Agent with Strong Extensibility, you will build an intuitive mental model first, then move into concrete implementation details and practical production tradeoffs.
This chapter provides a governance framework for deploying Crush across real engineering teams.
- define production configuration and policy baselines
- enforce attribution, metrics, and privacy preferences intentionally
- standardize rollout stages across teams and repos
- maintain operational quality over time
| Area | Recommended Policy |
|---|---|
| config management | publish approved .crush.json templates per repo class |
| tool safety | start with restrictive allowed_tools and disabled_tools |
| attribution | choose assisted-by, co-authored-by, or none explicitly |
| telemetry | configure disable_metrics or DO_NOT_TRACK where required |
| rollout | pilot -> expand -> enforce policy checks |
- run pilot with senior maintainers and strict permissions
- refine model/provider defaults and command packs
- publish team onboarding docs + starter configs
- expand to broader teams with monitored issue intake
- audit quarterly for drift in models, tools, and policies
You now have an end-to-end framework for adopting Crush as a governed coding-agent platform.
Compare terminal-first practices in the Goose Tutorial.
The PermissionGrant function in internal/workspace/app_workspace.go handles a key part of this chapter's functionality:
// -- Permissions --
func (w *AppWorkspace) PermissionGrant(perm permission.PermissionRequest) {
w.app.Permissions.Grant(perm)
}
func (w *AppWorkspace) PermissionGrantPersistent(perm permission.PermissionRequest) {
w.app.Permissions.GrantPersistent(perm)
}
func (w *AppWorkspace) PermissionDeny(perm permission.PermissionRequest) {
w.app.Permissions.Deny(perm)
}
func (w *AppWorkspace) PermissionSkipRequests() bool {
return w.app.Permissions.SkipRequests()
}
func (w *AppWorkspace) PermissionSetSkipRequests(skip bool) {
w.app.Permissions.SetSkipRequests(skip)
}
// -- FileTracker --
func (w *AppWorkspace) FileTrackerRecordRead(ctx context.Context, sessionID, path string) {
w.app.FileTracker.RecordRead(ctx, sessionID, path)
}
func (w *AppWorkspace) FileTrackerLastReadTime(ctx context.Context, sessionID, path string) time.Time {
return w.app.FileTracker.LastReadTime(ctx, sessionID, path)
}This function is important because it defines how Crush Tutorial: Multi-Model Terminal Coding Agent with Strong Extensibility implements the patterns covered in this chapter.
The PermissionGrantPersistent function in internal/workspace/app_workspace.go handles a key part of this chapter's functionality:
}
func (w *AppWorkspace) PermissionGrantPersistent(perm permission.PermissionRequest) {
w.app.Permissions.GrantPersistent(perm)
}
func (w *AppWorkspace) PermissionDeny(perm permission.PermissionRequest) {
w.app.Permissions.Deny(perm)
}
func (w *AppWorkspace) PermissionSkipRequests() bool {
return w.app.Permissions.SkipRequests()
}
func (w *AppWorkspace) PermissionSetSkipRequests(skip bool) {
w.app.Permissions.SetSkipRequests(skip)
}
// -- FileTracker --
func (w *AppWorkspace) FileTrackerRecordRead(ctx context.Context, sessionID, path string) {
w.app.FileTracker.RecordRead(ctx, sessionID, path)
}
func (w *AppWorkspace) FileTrackerLastReadTime(ctx context.Context, sessionID, path string) time.Time {
return w.app.FileTracker.LastReadTime(ctx, sessionID, path)
}
func (w *AppWorkspace) FileTrackerListReadFiles(ctx context.Context, sessionID string) ([]string, error) {
return w.app.FileTracker.ListReadFiles(ctx, sessionID)
}This function is important because it defines how Crush Tutorial: Multi-Model Terminal Coding Agent with Strong Extensibility implements the patterns covered in this chapter.
The PermissionDeny function in internal/workspace/app_workspace.go handles a key part of this chapter's functionality:
}
func (w *AppWorkspace) PermissionDeny(perm permission.PermissionRequest) {
w.app.Permissions.Deny(perm)
}
func (w *AppWorkspace) PermissionSkipRequests() bool {
return w.app.Permissions.SkipRequests()
}
func (w *AppWorkspace) PermissionSetSkipRequests(skip bool) {
w.app.Permissions.SetSkipRequests(skip)
}
// -- FileTracker --
func (w *AppWorkspace) FileTrackerRecordRead(ctx context.Context, sessionID, path string) {
w.app.FileTracker.RecordRead(ctx, sessionID, path)
}
func (w *AppWorkspace) FileTrackerLastReadTime(ctx context.Context, sessionID, path string) time.Time {
return w.app.FileTracker.LastReadTime(ctx, sessionID, path)
}
func (w *AppWorkspace) FileTrackerListReadFiles(ctx context.Context, sessionID string) ([]string, error) {
return w.app.FileTracker.ListReadFiles(ctx, sessionID)
}
// -- History --
func (w *AppWorkspace) ListSessionHistory(ctx context.Context, sessionID string) ([]history.File, error) {
return w.app.History.ListBySession(ctx, sessionID)This function is important because it defines how Crush Tutorial: Multi-Model Terminal Coding Agent with Strong Extensibility implements the patterns covered in this chapter.
The PermissionSkipRequests function in internal/workspace/app_workspace.go handles a key part of this chapter's functionality:
}
func (w *AppWorkspace) PermissionSkipRequests() bool {
return w.app.Permissions.SkipRequests()
}
func (w *AppWorkspace) PermissionSetSkipRequests(skip bool) {
w.app.Permissions.SetSkipRequests(skip)
}
// -- FileTracker --
func (w *AppWorkspace) FileTrackerRecordRead(ctx context.Context, sessionID, path string) {
w.app.FileTracker.RecordRead(ctx, sessionID, path)
}
func (w *AppWorkspace) FileTrackerLastReadTime(ctx context.Context, sessionID, path string) time.Time {
return w.app.FileTracker.LastReadTime(ctx, sessionID, path)
}
func (w *AppWorkspace) FileTrackerListReadFiles(ctx context.Context, sessionID string) ([]string, error) {
return w.app.FileTracker.ListReadFiles(ctx, sessionID)
}
// -- History --
func (w *AppWorkspace) ListSessionHistory(ctx context.Context, sessionID string) ([]history.File, error) {
return w.app.History.ListBySession(ctx, sessionID)
}
// -- LSP --This function is important because it defines how Crush Tutorial: Multi-Model Terminal Coding Agent with Strong Extensibility implements the patterns covered in this chapter.
flowchart TD
A[PermissionGrant]
B[PermissionGrantPersistent]
C[PermissionDeny]
D[PermissionSkipRequests]
E[PermissionSetSkipRequests]
A --> B
B --> C
C --> D
D --> E