fix: update minutes permission hints to guide apply-permission with user confirmation

Replace "Ask the minute owner for permission" hints with actionable
commands that direct the agent to confirm with the user before running
`minutes +apply-permission`. This ensures permission requests are
user-initiated rather than automatically executed by AI agents.

Change-Id: I2df45e1e1786e7e868db2d4991d8cd60121b2c21
This commit is contained in:
calendar-assistant
2026-07-02 15:15:52 +08:00
parent c4cbcc6242
commit 49fe934e74
10 changed files with 13 additions and 13 deletions

View File

@@ -53,7 +53,7 @@ func fetchMinuteDetail(ctx context.Context, runtime *common.RuntimeContext, minu
if err != nil {
result := &minuteDetailItem{MinuteToken: minuteToken}
if p, ok := errs.ProblemOf(err); ok && p.Code == minutesDetailNoReadPermissionCode {
result.Error = fmt.Sprintf("No read permission for minute %s. Ask the minute owner for minute file read permission", minuteToken)
result.Error = fmt.Sprintf("No read permission for minute %s. Ask the user before running: minutes +apply-permission --minute-token %s --perm view", minuteToken, minuteToken)
} else {
result.Error = fmt.Sprintf("failed to query minute: %v", err)
}

View File

@@ -148,7 +148,7 @@ func minutesSpeakerReplaceError(err error, minuteToken, sourceSpeaker string) er
switch p.Code {
case minutesSpeakerReplaceNoEditPermission:
p.Message = fmt.Sprintf("No edit permission for minute %q: cannot replace the transcript speaker.", minuteToken)
p.Hint = "Ask the minute owner for minute edit permission"
p.Hint = fmt.Sprintf("Ask the user before running: minutes +apply-permission --minute-token %s --perm edit", minuteToken)
case minutesSpeakerReplaceSpeakerNotFoundCode:
p.Subtype = errs.SubtypeNotFound
p.Message = fmt.Sprintf("Speaker not found in minute %q: source speaker %q does not match an existing speaker in the transcript.", minuteToken, sourceSpeaker)

View File

@@ -404,7 +404,7 @@ func TestMinutesSpeakerReplace_NoEditPermission(t *testing.T) {
if !strings.Contains(p.Message, minutesSpeakerReplaceTestToken) {
t.Errorf("message should include minute token, got: %s", p.Message)
}
if !strings.Contains(p.Hint, "edit permission") {
t.Errorf("hint should mention edit permission, got: %s", p.Hint)
if !strings.Contains(p.Hint, "+apply-permission") {
t.Errorf("hint should mention apply-permission, got: %s", p.Hint)
}
}

View File

@@ -400,8 +400,8 @@ func TestMinutesTodo_NoEditPermission(t *testing.T) {
if !strings.Contains(p.Message, minutesSummaryTodoTestToken) {
t.Errorf("message should include minute token, got: %s", p.Message)
}
if !strings.Contains(p.Hint, "edit permission") {
t.Errorf("hint should mention edit permission, got: %s", p.Hint)
if !strings.Contains(p.Hint, "+apply-permission") {
t.Errorf("hint should mention apply-permission, got: %s", p.Hint)
}
}

View File

@@ -288,6 +288,6 @@ func minutesTodoError(err error, minuteToken string) error {
}
p.Subtype = errs.SubtypePermissionDenied
p.Message = fmt.Sprintf("No edit permission for minute %q: cannot update todos.", minuteToken)
p.Hint = "Ask the minute owner for minute edit permission"
p.Hint = fmt.Sprintf("Ask the user before running: minutes +apply-permission --minute-token %s --perm edit", minuteToken)
return err
}

View File

@@ -79,6 +79,6 @@ func minutesUpdateError(err error, minuteToken string) error {
return err
}
p.Message = fmt.Sprintf("No edit permission for minute %q: cannot update the title.", minuteToken)
p.Hint = "Ask the minute owner for minute edit permission"
p.Hint = fmt.Sprintf("Ask the user before running: minutes +apply-permission --minute-token %s --perm edit", minuteToken)
return err
}

View File

@@ -171,7 +171,7 @@ func TestMinutesUpdate_NoEditPermission(t *testing.T) {
if !strings.Contains(p.Message, minutesUpdateTestToken) {
t.Errorf("message should include minute token, got: %s", p.Message)
}
if !strings.Contains(p.Hint, "edit permission") {
t.Errorf("hint should mention edit permission, got: %s", p.Hint)
if !strings.Contains(p.Hint, "+apply-permission") {
t.Errorf("hint should mention apply-permission, got: %s", p.Hint)
}
}

View File

@@ -139,7 +139,7 @@ func minutesWordReplaceError(err error, minuteToken string) error {
case minutesWordReplaceNoEditPermission:
p.Subtype = errs.SubtypePermissionDenied
p.Message = fmt.Sprintf("No edit permission for minute %q: cannot replace transcript words.", minuteToken)
p.Hint = "Ask the minute owner for minute edit permission"
p.Hint = fmt.Sprintf("Ask the user before running: minutes +apply-permission --minute-token %s --perm edit", minuteToken)
case minutesWordReplaceOthersEditing:
p.Subtype = errs.SubtypeConflict
p.Message = fmt.Sprintf("Minute %q transcript is being edited by someone else.", minuteToken)

View File

@@ -68,7 +68,7 @@ func minutesReadError(err error, minuteToken string) error {
return err
}
p.Message = fmt.Sprintf("No read permission for minute %s: cannot query the minute.", minuteToken)
p.Hint = "Ask the minute owner for minute file read permission"
p.Hint = fmt.Sprintf("Ask the user before running: minutes +apply-permission --minute-token %s --perm view", minuteToken)
return err
}

View File

@@ -1255,7 +1255,7 @@ func TestMinutesReadError_ProblemOf_EnrichesMessage(t *testing.T) {
t.Errorf("error message not enriched: %q", errMsg)
}
hint, _ := note["hint"].(string)
if !strings.Contains(hint, "minute file read permission") {
if !strings.Contains(hint, "+apply-permission") {
t.Errorf("hint not surfaced: %q", hint)
}
}