From 7b03f796f5ae3b581e9dd5a28db922cd35fa56e1 Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Fri, 10 Oct 2025 08:57:06 -0400 Subject: [PATCH 1/4] feat: organize help commands into logical groups Organize the sourcetool CLI help output into three logical command groups to improve discoverability and user experience: - Verification Commands: verifycommit, audit, status - Attestation & Evaluation Commands: checklevel, checklevelprov, checktag, prov - Configuration & Setup Commands: setup, auth, policy, createpolicy This uses Cobra's AddGroup feature to categorize commands by their primary function, making it easier for users to find the command they need. Assisted-by: Claude Code Signed-off-by: Ralph Bean --- internal/cmd/audit.go | 5 +++-- internal/cmd/auth.go | 1 + internal/cmd/checklevel.go | 5 +++-- internal/cmd/checklevelprov.go | 5 +++-- internal/cmd/checktag.go | 5 +++-- internal/cmd/createpolicy.go | 5 +++-- internal/cmd/policy.go | 3 ++- internal/cmd/prov.go | 5 +++-- internal/cmd/root.go | 34 ++++++++++++++++++++++++++++------ internal/cmd/setup.go | 3 ++- internal/cmd/status.go | 3 ++- internal/cmd/verifycommit.go | 5 +++-- 12 files changed, 56 insertions(+), 23 deletions(-) diff --git a/internal/cmd/audit.go b/internal/cmd/audit.go index e5c3da40..817a507a 100644 --- a/internal/cmd/audit.go +++ b/internal/cmd/audit.go @@ -81,8 +81,9 @@ func (ao *auditOpts) AddFlags(cmd *cobra.Command) { func addAudit(parentCmd *cobra.Command) { opts := &auditOpts{} auditCmd := &cobra.Command{ - Use: "audit", - Short: "Audits the SLSA properties and controls of a repository", + Use: "audit", + GroupID: "verification", + Short: "Audits the SLSA properties and controls of a repository", Long: `Checks the revisions on the specified branch within the repository. Revisions 'pass' an audit if they have: diff --git a/internal/cmd/auth.go b/internal/cmd/auth.go index c9cf6a42..c258d079 100644 --- a/internal/cmd/auth.go +++ b/internal/cmd/auth.go @@ -18,6 +18,7 @@ var colorHiRed = color.New(color.FgHiRed).SprintFunc() func addAuth(parentCmd *cobra.Command) { authCmd := &cobra.Command{ + GroupID: "configuration", Short: "Manage user authentication", Use: "auth", SilenceUsage: false, diff --git a/internal/cmd/checklevel.go b/internal/cmd/checklevel.go index 337957f1..76237eca 100644 --- a/internal/cmd/checklevel.go +++ b/internal/cmd/checklevel.go @@ -42,8 +42,9 @@ func addCheckLevel(parentCmd *cobra.Command) { opts := checkLevelOpts{} checklevelCmd := &cobra.Command{ - Use: "checklevel", - Short: "Determines the SLSA Source Level of the repo", + Use: "checklevel", + GroupID: "attestation", + Short: "Determines the SLSA Source Level of the repo", Long: `Determines the SLSA Source Level of the repo. This is meant to be run within the corresponding GitHub Actions workflow.`, diff --git a/internal/cmd/checklevelprov.go b/internal/cmd/checklevelprov.go index 88c27d5b..56570e10 100644 --- a/internal/cmd/checklevelprov.go +++ b/internal/cmd/checklevelprov.go @@ -51,8 +51,9 @@ func addCheckLevelProv(parentCmd *cobra.Command) { opts := &checkLevelProvOpts{} checklevelprovCmd := &cobra.Command{ - Use: "checklevelprov", - Short: "Checks the given commit against policy using & creating provenance", + Use: "checklevelprov", + GroupID: "attestation", + Short: "Checks the given commit against policy using & creating provenance", PreRunE: func(cmd *cobra.Command, args []string) error { if len(args) > 0 { if err := opts.ParseLocator(args[0]); err != nil { diff --git a/internal/cmd/checktag.go b/internal/cmd/checktag.go index c4e01f13..21ee557f 100644 --- a/internal/cmd/checktag.go +++ b/internal/cmd/checktag.go @@ -50,8 +50,9 @@ func addCheckTag(parentCmd *cobra.Command) { opts := &checkTagOptions{} checktagCmd := &cobra.Command{ - Use: "checktag", - Short: "Checks to see if the tag operation should be allowed and issues a VSA", + Use: "checktag", + GroupID: "attestation", + Short: "Checks to see if the tag operation should be allowed and issues a VSA", RunE: func(cmd *cobra.Command, args []string) error { return doCheckTag(opts) }, diff --git a/internal/cmd/createpolicy.go b/internal/cmd/createpolicy.go index 8a3947f5..276f6a34 100644 --- a/internal/cmd/createpolicy.go +++ b/internal/cmd/createpolicy.go @@ -30,8 +30,9 @@ func addCreatePolicy(parentCmd *cobra.Command) { opts := createPolicyOptions{} createpolicyCmd := &cobra.Command{ - Use: "createpolicy", - Short: "Creates a policy in a local copy of source-policies", + Use: "createpolicy", + GroupID: "configuration", + Short: "Creates a policy in a local copy of source-policies", Long: `Creates a SLSA source policy in a local copy of source-policies. The created policy should then be sent as a PR to slsa-framework/source-policies.`, diff --git a/internal/cmd/policy.go b/internal/cmd/policy.go index c456d964..2f7fb73d 100644 --- a/internal/cmd/policy.go +++ b/internal/cmd/policy.go @@ -39,7 +39,8 @@ func (pco *policyCreateOpts) AddFlags(cmd *cobra.Command) { func addPolicy(parentCmd *cobra.Command) { policyCmd := &cobra.Command{ - Short: "tools to work with source policies", + GroupID: "configuration", + Short: "tools to work with source policies", Long: fmt.Sprintf(` %s %s diff --git a/internal/cmd/prov.go b/internal/cmd/prov.go index 6cd76d6e..36c8d51e 100644 --- a/internal/cmd/prov.go +++ b/internal/cmd/prov.go @@ -40,8 +40,9 @@ func (po *provOptions) AddFlags(cmd *cobra.Command) { func addProv(parentCmd *cobra.Command) { opts := provOptions{} provCmd := &cobra.Command{ - Use: "prov", - Short: "Creates provenance for the given commit, but does not check policy.", + Use: "prov", + GroupID: "attestation", + Short: "Creates provenance for the given commit, but does not check policy.", PreRunE: func(cmd *cobra.Command, args []string) error { if len(args) > 0 { if err := opts.ParseLocator(args[0]); err != nil { diff --git a/internal/cmd/root.go b/internal/cmd/root.go index 9aefc8b0..4554dc54 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -44,17 +44,39 @@ controls and much more. rootCmd.PersistentFlags().StringVar(&githubToken, "github_token", "", "the github token to use for auth") - addCheckLevel(rootCmd) - addCheckLevelProv(rootCmd) + // Define command groups for better organization + rootCmd.AddGroup( + &cobra.Group{ + ID: "verification", + Title: "Verification Commands:", + }, + &cobra.Group{ + ID: "attestation", + Title: "Attestation & Evaluation Commands:", + }, + &cobra.Group{ + ID: "configuration", + Title: "Configuration & Setup Commands:", + }, + ) + + // Verification commands addVerifyCommit(rootCmd) - addStatus(rootCmd) - addSetup(rootCmd) addAudit(rootCmd) - addProv(rootCmd) + addStatus(rootCmd) + + // Attestation & evaluation commands + addCheckLevel(rootCmd) + addCheckLevelProv(rootCmd) addCheckTag(rootCmd) - addCreatePolicy(rootCmd) + addProv(rootCmd) + + // Configuration & setup commands + addSetup(rootCmd) addAuth(rootCmd) addPolicy(rootCmd) + addCreatePolicy(rootCmd) + return rootCmd } diff --git a/internal/cmd/setup.go b/internal/cmd/setup.go index 21a80bf4..d7b5e2cd 100644 --- a/internal/cmd/setup.go +++ b/internal/cmd/setup.go @@ -52,7 +52,8 @@ func (so *setupOpts) Validate() error { func addSetup(parentCmd *cobra.Command) { setupCmd := &cobra.Command{ - Short: "configure SLSA source features in a repository", + GroupID: "configuration", + Short: "configure SLSA source features in a repository", Long: fmt.Sprintf(` %s %s diff --git a/internal/cmd/status.go b/internal/cmd/status.go index 63fe0156..e340ec17 100644 --- a/internal/cmd/status.go +++ b/internal/cmd/status.go @@ -47,7 +47,8 @@ func (so *statusOptions) AddFlags(cmd *cobra.Command) { func addStatus(parentCmd *cobra.Command) { opts := &statusOptions{} statusCmd := &cobra.Command{ - Short: "Check the SLSA Source status of a repo/branch", + GroupID: "verification", + Short: "Check the SLSA Source status of a repo/branch", Long: ` sourcetool status: Check the SLSA Source status of a repo/branch diff --git a/internal/cmd/verifycommit.go b/internal/cmd/verifycommit.go index 155d1878..bb73ebee 100644 --- a/internal/cmd/verifycommit.go +++ b/internal/cmd/verifycommit.go @@ -40,8 +40,9 @@ func (vco *verifyCommitOptions) AddFlags(cmd *cobra.Command) { func addVerifyCommit(cmd *cobra.Command) { opts := verifyCommitOptions{} verifyCommitCmd := &cobra.Command{ - Use: "verifycommit", - Short: "Verifies the specified commit is valid", + Use: "verifycommit", + GroupID: "verification", + Short: "Verifies the specified commit is valid", PreRunE: func(cmd *cobra.Command, args []string) error { if len(args) > 0 { if err := opts.ParseLocator(args[0]); err != nil { From e450364b82d99b6ef3a07567dd9170828aba433e Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Fri, 10 Oct 2025 08:59:29 -0400 Subject: [PATCH 2/4] refactor: separate policy commands into dedicated group Move createpolicy and policy commands from the Configuration & Setup group into their own Policy Commands group for better organization. The help output now shows four distinct command groups: - Verification Commands - Attestation & Evaluation Commands - Policy Commands - Configuration & Setup Commands This makes policy management commands more discoverable and logically separated from general configuration tasks. Assisted-by: Claude Code Signed-off-by: Ralph Bean --- internal/cmd/createpolicy.go | 2 +- internal/cmd/policy.go | 2 +- internal/cmd/root.go | 10 ++++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/internal/cmd/createpolicy.go b/internal/cmd/createpolicy.go index 276f6a34..101592b6 100644 --- a/internal/cmd/createpolicy.go +++ b/internal/cmd/createpolicy.go @@ -31,7 +31,7 @@ func addCreatePolicy(parentCmd *cobra.Command) { createpolicyCmd := &cobra.Command{ Use: "createpolicy", - GroupID: "configuration", + GroupID: "policy", Short: "Creates a policy in a local copy of source-policies", Long: `Creates a SLSA source policy in a local copy of source-policies. diff --git a/internal/cmd/policy.go b/internal/cmd/policy.go index 2f7fb73d..451906fe 100644 --- a/internal/cmd/policy.go +++ b/internal/cmd/policy.go @@ -39,7 +39,7 @@ func (pco *policyCreateOpts) AddFlags(cmd *cobra.Command) { func addPolicy(parentCmd *cobra.Command) { policyCmd := &cobra.Command{ - GroupID: "configuration", + GroupID: "policy", Short: "tools to work with source policies", Long: fmt.Sprintf(` %s %s diff --git a/internal/cmd/root.go b/internal/cmd/root.go index 4554dc54..1244a8dd 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -54,6 +54,10 @@ controls and much more. ID: "attestation", Title: "Attestation & Evaluation Commands:", }, + &cobra.Group{ + ID: "policy", + Title: "Policy Commands:", + }, &cobra.Group{ ID: "configuration", Title: "Configuration & Setup Commands:", @@ -71,11 +75,13 @@ controls and much more. addCheckTag(rootCmd) addProv(rootCmd) + // Policy commands + addPolicy(rootCmd) + addCreatePolicy(rootCmd) + // Configuration & setup commands addSetup(rootCmd) addAuth(rootCmd) - addPolicy(rootCmd) - addCreatePolicy(rootCmd) return rootCmd } From 1d3c8d6fc40c564b98edb4bc6b68402d06ef32a4 Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Fri, 10 Oct 2025 09:04:10 -0400 Subject: [PATCH 3/4] docs: clarify audit command description Change audit command short description from "Audits the SLSA properties and controls of a repository" to "Verifies multiple commits in the branch history" to better describe what the command actually does. The word "multiple" is more accurate than "all" since the command can be limited with --depth and --ending-commit flags. Assisted-by: Claude Code Signed-off-by: Ralph Bean --- internal/cmd/audit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cmd/audit.go b/internal/cmd/audit.go index 817a507a..e72bcef5 100644 --- a/internal/cmd/audit.go +++ b/internal/cmd/audit.go @@ -83,7 +83,7 @@ func addAudit(parentCmd *cobra.Command) { auditCmd := &cobra.Command{ Use: "audit", GroupID: "verification", - Short: "Audits the SLSA properties and controls of a repository", + Short: "Verifies multiple commits in the branch history", Long: `Checks the revisions on the specified branch within the repository. Revisions 'pass' an audit if they have: From 6cd1a4e7c7cf0f9fb690658a812cf69e10bc980f Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Fri, 10 Oct 2025 09:30:10 -0400 Subject: [PATCH 4/4] refactor: reorganize commands into Assessment group Rename "Attestation & Evaluation Commands" to "Assessment Commands" and move status from Verification to Assessment group. The new organization better reflects command behavior: Verification Commands (2): - audit: verifies multiple commits by reading existing VSAs - verifycommit: verifies single commit by reading existing VSA Assessment Commands (5): - status: assesses current repository controls - checklevel: assesses controls and creates VSA - checklevelprov: assesses with provenance creation - checktag: assesses tag operations - prov: creates provenance without policy evaluation "Assessment" encompasses both evaluation (status, checklevel) and attestation creation (prov), making it a better umbrella term than "Attestation & Evaluation". Assisted-by: Claude Code Signed-off-by: Ralph Bean --- internal/cmd/checklevel.go | 2 +- internal/cmd/checklevelprov.go | 2 +- internal/cmd/checktag.go | 2 +- internal/cmd/prov.go | 2 +- internal/cmd/root.go | 8 ++++---- internal/cmd/status.go | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/internal/cmd/checklevel.go b/internal/cmd/checklevel.go index 76237eca..9e845aa1 100644 --- a/internal/cmd/checklevel.go +++ b/internal/cmd/checklevel.go @@ -43,7 +43,7 @@ func addCheckLevel(parentCmd *cobra.Command) { checklevelCmd := &cobra.Command{ Use: "checklevel", - GroupID: "attestation", + GroupID: "assessment", Short: "Determines the SLSA Source Level of the repo", Long: `Determines the SLSA Source Level of the repo. diff --git a/internal/cmd/checklevelprov.go b/internal/cmd/checklevelprov.go index 56570e10..2d56bf80 100644 --- a/internal/cmd/checklevelprov.go +++ b/internal/cmd/checklevelprov.go @@ -52,7 +52,7 @@ func addCheckLevelProv(parentCmd *cobra.Command) { checklevelprovCmd := &cobra.Command{ Use: "checklevelprov", - GroupID: "attestation", + GroupID: "assessment", Short: "Checks the given commit against policy using & creating provenance", PreRunE: func(cmd *cobra.Command, args []string) error { if len(args) > 0 { diff --git a/internal/cmd/checktag.go b/internal/cmd/checktag.go index 21ee557f..321bad48 100644 --- a/internal/cmd/checktag.go +++ b/internal/cmd/checktag.go @@ -51,7 +51,7 @@ func addCheckTag(parentCmd *cobra.Command) { checktagCmd := &cobra.Command{ Use: "checktag", - GroupID: "attestation", + GroupID: "assessment", Short: "Checks to see if the tag operation should be allowed and issues a VSA", RunE: func(cmd *cobra.Command, args []string) error { return doCheckTag(opts) diff --git a/internal/cmd/prov.go b/internal/cmd/prov.go index 36c8d51e..79bc5340 100644 --- a/internal/cmd/prov.go +++ b/internal/cmd/prov.go @@ -41,7 +41,7 @@ func addProv(parentCmd *cobra.Command) { opts := provOptions{} provCmd := &cobra.Command{ Use: "prov", - GroupID: "attestation", + GroupID: "assessment", Short: "Creates provenance for the given commit, but does not check policy.", PreRunE: func(cmd *cobra.Command, args []string) error { if len(args) > 0 { diff --git a/internal/cmd/root.go b/internal/cmd/root.go index 1244a8dd..6934e19d 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -51,8 +51,8 @@ controls and much more. Title: "Verification Commands:", }, &cobra.Group{ - ID: "attestation", - Title: "Attestation & Evaluation Commands:", + ID: "assessment", + Title: "Assessment Commands:", }, &cobra.Group{ ID: "policy", @@ -67,9 +67,9 @@ controls and much more. // Verification commands addVerifyCommit(rootCmd) addAudit(rootCmd) - addStatus(rootCmd) - // Attestation & evaluation commands + // Assessment commands + addStatus(rootCmd) addCheckLevel(rootCmd) addCheckLevelProv(rootCmd) addCheckTag(rootCmd) diff --git a/internal/cmd/status.go b/internal/cmd/status.go index e340ec17..3f3c53c8 100644 --- a/internal/cmd/status.go +++ b/internal/cmd/status.go @@ -47,7 +47,7 @@ func (so *statusOptions) AddFlags(cmd *cobra.Command) { func addStatus(parentCmd *cobra.Command) { opts := &statusOptions{} statusCmd := &cobra.Command{ - GroupID: "verification", + GroupID: "assessment", Short: "Check the SLSA Source status of a repo/branch", Long: ` sourcetool status: Check the SLSA Source status of a repo/branch