vidbyte-cli 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vidbyte_cli/__init__.py +11 -0
- vidbyte_cli/__main__.py +6 -0
- vidbyte_cli/cli.py +18 -0
- vidbyte_cli/commands/__init__.py +86 -0
- vidbyte_cli/commands/agent_options.py +53 -0
- vidbyte_cli/commands/agents/__init__.py +31 -0
- vidbyte_cli/commands/agents/suggestion/__init__.py +38 -0
- vidbyte_cli/commands/agents/suggestion/prompts/__init__.py +3 -0
- vidbyte_cli/commands/agents/suggestion/prompts/all_categories.md +5 -0
- vidbyte_cli/commands/agents/suggestion/prompts/approaches.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/avoid.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/blockers.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/capability.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/categories.md +5 -0
- vidbyte_cli/commands/agents/suggestion/prompts/category.md +5 -0
- vidbyte_cli/commands/agents/suggestion/prompts/completed.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/constraint.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/context.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/count.md +5 -0
- vidbyte_cli/commands/agents/suggestion/prompts/critic_model.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/decision.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/dry_run.md +5 -0
- vidbyte_cli/commands/agents/suggestion/prompts/extra_compute.md +5 -0
- vidbyte_cli/commands/agents/suggestion/prompts/feedback_accept.md +7 -0
- vidbyte_cli/commands/agents/suggestion/prompts/feedback_group.md +7 -0
- vidbyte_cli/commands/agents/suggestion/prompts/feedback_project.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/feedback_reason.md +98 -0
- vidbyte_cli/commands/agents/suggestion/prompts/feedback_reject.md +7 -0
- vidbyte_cli/commands/agents/suggestion/prompts/feedback_suggestion.md +101 -0
- vidbyte_cli/commands/agents/suggestion/prompts/files.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/forbidden.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/goal.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/handoff.md +7 -0
- vidbyte_cli/commands/agents/suggestion/prompts/horizon.md +5 -0
- vidbyte_cli/commands/agents/suggestion/prompts/hypotheses.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/idea.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/in_progress.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/input.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/library.py +29 -0
- vidbyte_cli/commands/agents/suggestion/prompts/max_messages.md +5 -0
- vidbyte_cli/commands/agents/suggestion/prompts/max_output_tokens.md +5 -0
- vidbyte_cli/commands/agents/suggestion/prompts/max_total_tokens.md +5 -0
- vidbyte_cli/commands/agents/suggestion/prompts/mistakes.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/outcomes.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/project.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/project_create.md +7 -0
- vidbyte_cli/commands/agents/suggestion/prompts/project_description.md +98 -0
- vidbyte_cli/commands/agents/suggestion/prompts/project_group.md +7 -0
- vidbyte_cli/commands/agents/suggestion/prompts/project_key.md +96 -0
- vidbyte_cli/commands/agents/suggestion/prompts/project_list.md +7 -0
- vidbyte_cli/commands/agents/suggestion/prompts/project_title.md +99 -0
- vidbyte_cli/commands/agents/suggestion/prompts/provider.md +5 -0
- vidbyte_cli/commands/agents/suggestion/prompts/question.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/risks.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/rounds.md +5 -0
- vidbyte_cli/commands/agents/suggestion/prompts/run.md +5 -0
- vidbyte_cli/commands/agents/suggestion/prompts/success.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/timeout.md +5 -0
- vidbyte_cli/commands/agents/suggestion/prompts/trajectory.md +100 -0
- vidbyte_cli/commands/agents/suggestion/prompts/view.md +5 -0
- vidbyte_cli/commands/agents/suggestion/prompts/view_all.md +5 -0
- vidbyte_cli/commands/agents/suggestion/render.py +77 -0
- vidbyte_cli/commands/agents/suggestion/request_builder.py +240 -0
- vidbyte_cli/commands/agents/suggestion/suggest.py +154 -0
- vidbyte_cli/commands/agents/suggestion/suggestion_categories.py +77 -0
- vidbyte_cli/commands/agents/suggestion/suggestion_feedback.py +85 -0
- vidbyte_cli/commands/agents/suggestion/suggestion_handoff.py +67 -0
- vidbyte_cli/commands/agents/suggestion/suggestion_projects.py +95 -0
- vidbyte_cli/commands/auth/__init__.py +0 -0
- vidbyte_cli/commands/auth/login.py +100 -0
- vidbyte_cli/commands/auth/logout.py +41 -0
- vidbyte_cli/commands/auth/whoami.py +51 -0
- vidbyte_cli/commands/billing/__init__.py +20 -0
- vidbyte_cli/commands/billing/prompts/__init__.py +1 -0
- vidbyte_cli/commands/billing/prompts/confirm.md +16 -0
- vidbyte_cli/commands/billing/prompts/group.md +13 -0
- vidbyte_cli/commands/billing/prompts/idempotency_key.md +16 -0
- vidbyte_cli/commands/billing/prompts/library.py +18 -0
- vidbyte_cli/commands/billing/prompts/top_up.md +16 -0
- vidbyte_cli/commands/billing/top_up.py +65 -0
- vidbyte_cli/commands/config/__init__.py +0 -0
- vidbyte_cli/commands/config/get.py +45 -0
- vidbyte_cli/commands/config/set.py +39 -0
- vidbyte_cli/commands/provider/__init__.py +9 -0
- vidbyte_cli/commands/provider/login.py +102 -0
- vidbyte_cli/commands/provider/logout.py +45 -0
- vidbyte_cli/commands/provider/whoami.py +49 -0
- vidbyte_cli/commands/research/__init__.py +5 -0
- vidbyte_cli/commands/research/add.py +41 -0
- vidbyte_cli/commands/research/options.py +134 -0
- vidbyte_cli/commands/research/render.py +157 -0
- vidbyte_cli/commands/research/resume.py +37 -0
- vidbyte_cli/commands/research/start.py +37 -0
- vidbyte_cli/commands/research/status.py +32 -0
- vidbyte_cli/commands/research/thread.py +30 -0
- vidbyte_cli/commands/research/threads.py +35 -0
- vidbyte_cli/commands/research/watch.py +93 -0
- vidbyte_cli/commands/runtime/__init__.py +23 -0
- vidbyte_cli/commands/runtime/adversarial_team.py +41 -0
- vidbyte_cli/commands/runtime/doctor.py +44 -0
- vidbyte_cli/commands/runtime/list.py +47 -0
- vidbyte_cli/commands/runtime/persistence.py +141 -0
- vidbyte_cli/commands/runtime/same_host_ensemble.py +221 -0
- vidbyte_cli/commands/runtime/stages.py +553 -0
- vidbyte_cli/commands/runtime/task_board.py +1342 -0
- vidbyte_cli/commands/setup/__init__.py +0 -0
- vidbyte_cli/commands/setup/doctor.py +64 -0
- vidbyte_cli/commands/setup/prompts/__init__.py +1 -0
- vidbyte_cli/commands/setup/prompts/browser.md +7 -0
- vidbyte_cli/commands/setup/prompts/library.py +18 -0
- vidbyte_cli/commands/setup/prompts/star.md +13 -0
- vidbyte_cli/commands/setup/star.py +132 -0
- vidbyte_cli/lib/__init__.py +0 -0
- vidbyte_cli/lib/api/__init__.py +0 -0
- vidbyte_cli/lib/api/client.py +236 -0
- vidbyte_cli/lib/api/endpoints/__init__.py +0 -0
- vidbyte_cli/lib/api/endpoints/auth.py +24 -0
- vidbyte_cli/lib/api/endpoints/billing.py +36 -0
- vidbyte_cli/lib/api/endpoints/research.py +103 -0
- vidbyte_cli/lib/api/endpoints/runtime.py +113 -0
- vidbyte_cli/lib/api/problem.py +86 -0
- vidbyte_cli/lib/api/response.py +101 -0
- vidbyte_cli/lib/api/retry.py +116 -0
- vidbyte_cli/lib/api/runtime_payment.py +89 -0
- vidbyte_cli/lib/auth/__init__.py +16 -0
- vidbyte_cli/lib/auth/credentials.py +223 -0
- vidbyte_cli/lib/auth/input.py +59 -0
- vidbyte_cli/lib/auth/keyring_store.py +126 -0
- vidbyte_cli/lib/auth/provider_credentials.py +157 -0
- vidbyte_cli/lib/auth/provider_input.py +54 -0
- vidbyte_cli/lib/auth/provider_resolver.py +89 -0
- vidbyte_cli/lib/auth/provider_store.py +149 -0
- vidbyte_cli/lib/auth/provider_verifier.py +219 -0
- vidbyte_cli/lib/auth/resolver.py +63 -0
- vidbyte_cli/lib/auth/verifier.py +38 -0
- vidbyte_cli/lib/config/__init__.py +25 -0
- vidbyte_cli/lib/config/atomic.py +47 -0
- vidbyte_cli/lib/config/config.py +141 -0
- vidbyte_cli/lib/config/migration.py +81 -0
- vidbyte_cli/lib/config/models.py +145 -0
- vidbyte_cli/lib/config/paths.py +66 -0
- vidbyte_cli/lib/config/resolver.py +137 -0
- vidbyte_cli/lib/constants/__init__.py +1 -0
- vidbyte_cli/lib/constants/runtime.py +186 -0
- vidbyte_cli/lib/errors/__init__.py +12 -0
- vidbyte_cli/lib/errors/cli_error.py +86 -0
- vidbyte_cli/lib/errors/codes.py +43 -0
- vidbyte_cli/lib/errors/failures.py +2910 -0
- vidbyte_cli/lib/errors/handler.py +72 -0
- vidbyte_cli/lib/files/__init__.py +6 -0
- vidbyte_cli/lib/files/documents.py +94 -0
- vidbyte_cli/lib/files/store.py +156 -0
- vidbyte_cli/lib/io/__init__.py +16 -0
- vidbyte_cli/lib/io/attachments.py +129 -0
- vidbyte_cli/lib/io/codex_attachments.py +47 -0
- vidbyte_cli/lib/io/prompt.py +71 -0
- vidbyte_cli/lib/io/streams.py +37 -0
- vidbyte_cli/lib/io/terminal.py +66 -0
- vidbyte_cli/lib/output/__init__.py +7 -0
- vidbyte_cli/lib/output/formats.py +29 -0
- vidbyte_cli/lib/output/manager.py +95 -0
- vidbyte_cli/lib/output/models.py +49 -0
- vidbyte_cli/lib/runtime/__init__.py +9 -0
- vidbyte_cli/lib/runtime/application.py +134 -0
- vidbyte_cli/lib/runtime/context.py +250 -0
- vidbyte_cli/lib/runtime/options.py +159 -0
- vidbyte_cli/lib/runtime/version.py +30 -0
- vidbyte_cli/lib/runtime_primitives/__init__.py +28 -0
- vidbyte_cli/lib/runtime_primitives/executor.py +54 -0
- vidbyte_cli/lib/runtime_primitives/gate.py +105 -0
- vidbyte_cli/lib/runtime_primitives/hosts.py +45 -0
- vidbyte_cli/lib/runtime_primitives/planner.py +79 -0
- vidbyte_cli/lib/runtime_primitives/stages.py +338 -0
- vidbyte_cli/lib/runtime_primitives/task_board.py +982 -0
- vidbyte_cli/lib/runtime_primitives/task_board_checkpoints.py +473 -0
- vidbyte_cli/lib/runtime_primitives/task_board_system.md +33 -0
- vidbyte_cli/lib/runtime_primitives/task_board_tasks.py +111 -0
- vidbyte_cli/lib/runtime_primitives/verification.py +68 -0
- vidbyte_cli/services/__init__.py +5 -0
- vidbyte_cli/services/ensemble/__init__.py +7 -0
- vidbyte_cli/services/ensemble/prompts/__init__.py +6 -0
- vidbyte_cli/services/ensemble/prompts/implementer_system.md +546 -0
- vidbyte_cli/services/ensemble/prompts/implementer_turn.md +49 -0
- vidbyte_cli/services/ensemble/prompts/library.py +188 -0
- vidbyte_cli/services/ensemble/prompts/planner_system.md +728 -0
- vidbyte_cli/services/ensemble/prompts/planner_turn.md +6 -0
- vidbyte_cli/services/ensemble/prompts/role_system.md +104 -0
- vidbyte_cli/services/ensemble/prompts/role_turn.md +19 -0
- vidbyte_cli/services/ensemble/prompts/selector_final_turn.md +19 -0
- vidbyte_cli/services/ensemble/prompts/selector_round_turn.md +17 -0
- vidbyte_cli/services/ensemble/prompts/selector_system.md +89 -0
- vidbyte_cli/services/ensemble/runner.py +30 -0
- vidbyte_cli/services/ensemble/sdk.py +134 -0
- vidbyte_cli/services/ensemble/service.py +233 -0
- vidbyte_cli/services/ensemble/settings.py +60 -0
- vidbyte_cli/services/persistence/__init__.py +6 -0
- vidbyte_cli/services/persistence/prompts/__init__.py +6 -0
- vidbyte_cli/services/persistence/prompts/library.py +46 -0
- vidbyte_cli/services/persistence/prompts/persistence_system.md +1 -0
- vidbyte_cli/services/persistence/prompts/persistence_turn.md +3 -0
- vidbyte_cli/services/persistence/runner.py +35 -0
- vidbyte_cli/services/persistence/session.py +116 -0
- vidbyte_cli/services/suggestions/__init__.py +7 -0
- vidbyte_cli/services/suggestions/categories.py +270 -0
- vidbyte_cli/services/suggestions/context.py +222 -0
- vidbyte_cli/services/suggestions/extra_compute.py +53 -0
- vidbyte_cli/services/suggestions/handoff.py +173 -0
- vidbyte_cli/services/suggestions/message_tools.py +47 -0
- vidbyte_cli/services/suggestions/project.py +253 -0
- vidbyte_cli/services/suggestions/prompts/__init__.py +1 -0
- vidbyte_cli/services/suggestions/prompts/categories/__init__.py +3 -0
- vidbyte_cli/services/suggestions/prompts/categories/adjacent_opportunity.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/alternative.md +38 -0
- vidbyte_cli/services/suggestions/prompts/categories/big_bets.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/bottleneck.md +38 -0
- vidbyte_cli/services/suggestions/prompts/categories/business_growth.md +38 -0
- vidbyte_cli/services/suggestions/prompts/categories/completion.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/continuation.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/coordination.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/creative_exploration.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/cross_domain.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/delegation.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/experiment.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/feedback.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/goal_clarification.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/immediate_next_steps.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/investigation.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/learning.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/leverage.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/long_term_directions.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/preparation.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/prerequisite.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/prioritization.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/product_experience.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/quick_wins.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/reframing.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/risk_prevention.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/simplification.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/stop_or_defer.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/strategy.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/technical_possibilities.md +37 -0
- vidbyte_cli/services/suggestions/prompts/categories/verification.md +37 -0
- vidbyte_cli/services/suggestions/prompts/critic.md +209 -0
- vidbyte_cli/services/suggestions/prompts/critic_message.md +8 -0
- vidbyte_cli/services/suggestions/prompts/generator.md +64 -0
- vidbyte_cli/services/suggestions/prompts/library.py +72 -0
- vidbyte_cli/services/suggestions/prompts/message_generator_argument.md +1 -0
- vidbyte_cli/services/suggestions/prompts/message_generator_tool.md +1 -0
- vidbyte_cli/services/suggestions/prompts/message_parent_argument.md +1 -0
- vidbyte_cli/services/suggestions/prompts/message_parent_tool.md +1 -0
- vidbyte_cli/services/suggestions/prompts/message_receipt.md +1 -0
- vidbyte_cli/services/suggestions/prompts/revision.md +8 -0
- vidbyte_cli/services/suggestions/sdk.py +228 -0
- vidbyte_cli/services/suggestions/selection.py +78 -0
- vidbyte_cli/services/suggestions/service.py +540 -0
- vidbyte_cli/types/__init__.py +0 -0
- vidbyte_cli/types/api.py +101 -0
- vidbyte_cli/types/attachments.py +79 -0
- vidbyte_cli/types/ensemble.py +189 -0
- vidbyte_cli/types/provider.py +62 -0
- vidbyte_cli/types/research.py +260 -0
- vidbyte_cli/types/runtime.py +1098 -0
- vidbyte_cli/types/suggestions.py +518 -0
- vidbyte_cli-0.1.0.dist-info/METADATA +335 -0
- vidbyte_cli-0.1.0.dist-info/RECORD +269 -0
- vidbyte_cli-0.1.0.dist-info/WHEEL +5 -0
- vidbyte_cli-0.1.0.dist-info/entry_points.txt +2 -0
- vidbyte_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
- vidbyte_cli-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
"""Local suggestion projects: a catalog of keyed projects plus one feedback file per project.
|
|
2
|
+
|
|
3
|
+
`SuggestionProject` is the only place that decides what a project is, which file its memory
|
|
4
|
+
lives in, and how its title, description, and explicit feedback become run context. Reading,
|
|
5
|
+
validating, and atomically replacing the JSON documents is delegated to the general
|
|
6
|
+
`LocalDocumentStore`, so nothing here touches the filesystem directly.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import re
|
|
12
|
+
from collections.abc import Callable
|
|
13
|
+
from dataclasses import dataclass
|
|
14
|
+
from datetime import UTC, datetime
|
|
15
|
+
from typing import TypeVar
|
|
16
|
+
|
|
17
|
+
from ...lib.config import VidbytePaths
|
|
18
|
+
from ...lib.errors.failures import (
|
|
19
|
+
LocalDocumentInvalid,
|
|
20
|
+
LocalFileReadFailed,
|
|
21
|
+
LocalFileWriteFailed,
|
|
22
|
+
SuggestionProjectExists,
|
|
23
|
+
SuggestionProjectNotFound,
|
|
24
|
+
SuggestionProjectStateUnreadable,
|
|
25
|
+
SuggestionProjectWriteFailed,
|
|
26
|
+
)
|
|
27
|
+
from ...lib.files import LocalDocumentStore
|
|
28
|
+
from ...types.suggestions import (
|
|
29
|
+
FeedbackType,
|
|
30
|
+
SuggestionFeedback,
|
|
31
|
+
SuggestionFeedbackCapture,
|
|
32
|
+
SuggestionProjectCatalog,
|
|
33
|
+
SuggestionProjectMemory,
|
|
34
|
+
SuggestionProjectRecord,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
T = TypeVar("T")
|
|
38
|
+
|
|
39
|
+
_KEY_PATTERN = re.compile(r"[a-z0-9][a-z0-9_-]{0,63}")
|
|
40
|
+
_CATALOG_NAME = "projects.json"
|
|
41
|
+
_MEMORY_DIRECTORY = "projects"
|
|
42
|
+
_MAX_TITLE_CHARS = 200
|
|
43
|
+
_MAX_DESCRIPTION_CHARS = 4000
|
|
44
|
+
_MAX_FEEDBACK_CHARS = 8192
|
|
45
|
+
_FEEDBACK_COMMAND = "vidbyte-cli agents suggest feedback"
|
|
46
|
+
|
|
47
|
+
PROJECT_CONTEXT_KIND = "project"
|
|
48
|
+
ACCEPTED_FEEDBACK_KIND = "accepted_feedback"
|
|
49
|
+
REJECTED_FEEDBACK_KIND = "rejected_feedback"
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@dataclass(frozen=True, slots=True)
|
|
53
|
+
class SuggestionProjectKey:
|
|
54
|
+
"""One validated project selector, normalized once so every lookup compares equal text."""
|
|
55
|
+
|
|
56
|
+
value: str
|
|
57
|
+
|
|
58
|
+
def __post_init__(self) -> None:
|
|
59
|
+
# Keys become file names, so the pattern is also what keeps a key from naming a path.
|
|
60
|
+
if not isinstance(self.value, str):
|
|
61
|
+
raise TypeError("project key must be text")
|
|
62
|
+
normalized = self.value.strip()
|
|
63
|
+
if _KEY_PATTERN.fullmatch(normalized) is None:
|
|
64
|
+
raise ValueError(
|
|
65
|
+
"project key must be 1-64 lowercase letters, numbers, hyphens, or underscores"
|
|
66
|
+
)
|
|
67
|
+
object.__setattr__(self, "value", normalized)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@dataclass(frozen=True, slots=True)
|
|
71
|
+
class SuggestionProjectCreateInput:
|
|
72
|
+
"""Everything `create` needs, validated before any document is read."""
|
|
73
|
+
|
|
74
|
+
key: SuggestionProjectKey
|
|
75
|
+
title: str
|
|
76
|
+
description: str
|
|
77
|
+
|
|
78
|
+
def __post_init__(self) -> None:
|
|
79
|
+
# Surrounding whitespace is not meaning, so it is trimmed before the bounds apply.
|
|
80
|
+
title = self._bounded(self.title, "title", _MAX_TITLE_CHARS)
|
|
81
|
+
description = self._bounded(self.description, "description", _MAX_DESCRIPTION_CHARS)
|
|
82
|
+
object.__setattr__(self, "title", title)
|
|
83
|
+
object.__setattr__(self, "description", description)
|
|
84
|
+
|
|
85
|
+
@staticmethod
|
|
86
|
+
def _bounded(value: str, name: str, limit: int) -> str:
|
|
87
|
+
if not isinstance(value, str):
|
|
88
|
+
raise TypeError(f"project {name} must be text")
|
|
89
|
+
stripped = value.strip()
|
|
90
|
+
if not stripped or len(stripped) > limit:
|
|
91
|
+
raise ValueError(f"project {name} must be nonempty and at most {limit} characters")
|
|
92
|
+
return stripped
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@dataclass(frozen=True, slots=True)
|
|
96
|
+
class SuggestionFeedbackInput:
|
|
97
|
+
"""One explicit reaction to record, kept verbatim so the user's words are not rewritten."""
|
|
98
|
+
|
|
99
|
+
key: SuggestionProjectKey
|
|
100
|
+
feedback_type: FeedbackType
|
|
101
|
+
suggestion: str
|
|
102
|
+
reason: str | None = None
|
|
103
|
+
|
|
104
|
+
def __post_init__(self) -> None:
|
|
105
|
+
# Blank text is rejected, but surrounding spacing is preserved as the user supplied it.
|
|
106
|
+
if not isinstance(self.suggestion, str) or not self.suggestion.strip():
|
|
107
|
+
raise ValueError("suggestion must be nonempty")
|
|
108
|
+
if len(self.suggestion) > _MAX_FEEDBACK_CHARS:
|
|
109
|
+
raise ValueError(f"suggestion must be {_MAX_FEEDBACK_CHARS} characters or fewer")
|
|
110
|
+
if self.reason is not None and (
|
|
111
|
+
not isinstance(self.reason, str) or len(self.reason) > _MAX_FEEDBACK_CHARS
|
|
112
|
+
):
|
|
113
|
+
raise ValueError(f"reason must be {_MAX_FEEDBACK_CHARS} characters or fewer")
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class SuggestionProject:
|
|
117
|
+
"""Creates, looks up, and records feedback for local suggestion projects."""
|
|
118
|
+
|
|
119
|
+
def __init__(self, paths: VidbytePaths | None = None) -> None:
|
|
120
|
+
# Paths stay injectable so tests and commands never assume the user's data directory.
|
|
121
|
+
root = (paths or VidbytePaths.default()).suggestions_dir()
|
|
122
|
+
self._documents = LocalDocumentStore(root)
|
|
123
|
+
|
|
124
|
+
def create(self, request: SuggestionProjectCreateInput) -> SuggestionProjectRecord:
|
|
125
|
+
# Writes the memory file first and publishes the catalog link last, so a reader never
|
|
126
|
+
# sees a catalog entry pointing at a file that does not exist yet.
|
|
127
|
+
record = SuggestionProjectRecord(
|
|
128
|
+
key=request.key.value,
|
|
129
|
+
title=request.title,
|
|
130
|
+
description=request.description,
|
|
131
|
+
memory_file=f"{_MEMORY_DIRECTORY}/{request.key.value}.json",
|
|
132
|
+
)
|
|
133
|
+
catalog = self.catalog()
|
|
134
|
+
if self.project_exists(request.key) or self._state(
|
|
135
|
+
lambda: self._documents.exists(record.memory_file)
|
|
136
|
+
):
|
|
137
|
+
raise SuggestionProjectExists(record.key)
|
|
138
|
+
memory = SuggestionProjectMemory(project_key=record.key)
|
|
139
|
+
self._mutate(lambda: self._documents.write(record.memory_file, memory))
|
|
140
|
+
updated = catalog.model_copy(update={"projects": (*catalog.projects, record)})
|
|
141
|
+
try:
|
|
142
|
+
self._mutate(lambda: self._documents.write(_CATALOG_NAME, updated))
|
|
143
|
+
except SuggestionProjectWriteFailed:
|
|
144
|
+
# Rolls back the orphaned memory file so a retry with the same key can succeed.
|
|
145
|
+
self._mutate(lambda: self._documents.remove(record.memory_file))
|
|
146
|
+
raise
|
|
147
|
+
return record
|
|
148
|
+
|
|
149
|
+
def catalog(self) -> SuggestionProjectCatalog:
|
|
150
|
+
# An absent catalog is the first-run state, not an error.
|
|
151
|
+
stored = self._state(lambda: self._documents.read(_CATALOG_NAME, SuggestionProjectCatalog))
|
|
152
|
+
return stored or SuggestionProjectCatalog()
|
|
153
|
+
|
|
154
|
+
def list_projects(self) -> tuple[SuggestionProjectRecord, ...]:
|
|
155
|
+
# Key order keeps human and machine listings deterministic.
|
|
156
|
+
return tuple(sorted(self.catalog().projects, key=lambda item: item.key))
|
|
157
|
+
|
|
158
|
+
def project_exists(self, key: SuggestionProjectKey) -> bool:
|
|
159
|
+
return any(item.key == key.value for item in self.catalog().projects)
|
|
160
|
+
|
|
161
|
+
def get_project(self, key: SuggestionProjectKey) -> SuggestionProjectRecord:
|
|
162
|
+
# An unknown key is never created implicitly.
|
|
163
|
+
found = next((item for item in self.catalog().projects if item.key == key.value), None)
|
|
164
|
+
if found is None:
|
|
165
|
+
raise SuggestionProjectNotFound(key.value)
|
|
166
|
+
return found
|
|
167
|
+
|
|
168
|
+
def project_metadata(self, key: SuggestionProjectKey) -> tuple[str, ...]:
|
|
169
|
+
# Identity and scope reach the generator as ordinary labelled data.
|
|
170
|
+
project = self.get_project(key)
|
|
171
|
+
return (f"Project title: {project.title}", f"Project description: {project.description}")
|
|
172
|
+
|
|
173
|
+
def get_project_feedback(self, key: SuggestionProjectKey) -> tuple[SuggestionFeedback, ...]:
|
|
174
|
+
# A memory file missing or owned by another key means the catalog and disk disagree;
|
|
175
|
+
# both refuse rather than silently resetting the project's history to empty.
|
|
176
|
+
project = self.get_project(key)
|
|
177
|
+
memory = self._state(
|
|
178
|
+
lambda: self._documents.read(project.memory_file, SuggestionProjectMemory)
|
|
179
|
+
)
|
|
180
|
+
if memory is None:
|
|
181
|
+
raise SuggestionProjectStateUnreadable("the linked project memory file is missing")
|
|
182
|
+
if memory.project_key != project.key:
|
|
183
|
+
raise SuggestionProjectStateUnreadable("the project memory key does not match")
|
|
184
|
+
return memory.feedback
|
|
185
|
+
|
|
186
|
+
def record_feedback(self, request: SuggestionFeedbackInput) -> SuggestionFeedback:
|
|
187
|
+
# Appends after every earlier record; nothing is deduplicated or rewritten.
|
|
188
|
+
project = self.get_project(request.key)
|
|
189
|
+
history = self.get_project_feedback(request.key)
|
|
190
|
+
record = SuggestionFeedback(
|
|
191
|
+
type=request.feedback_type,
|
|
192
|
+
suggestion=request.suggestion,
|
|
193
|
+
reason=request.reason,
|
|
194
|
+
created_at=datetime.now(UTC).replace(microsecond=0).isoformat().replace("+00:00", "Z"),
|
|
195
|
+
)
|
|
196
|
+
memory = SuggestionProjectMemory(project_key=project.key, feedback=(*history, record))
|
|
197
|
+
self._mutate(lambda: self._documents.write(project.memory_file, memory))
|
|
198
|
+
return record
|
|
199
|
+
|
|
200
|
+
def context_fields(self, key: SuggestionProjectKey) -> dict[str, tuple[str, ...]]:
|
|
201
|
+
# Accepted and rejected reactions stay separate kinds so the service can suppress
|
|
202
|
+
# rejected directions without re-reading which kind a sentence was.
|
|
203
|
+
fields: dict[str, tuple[str, ...]] = {PROJECT_CONTEXT_KIND: self.project_metadata(key)}
|
|
204
|
+
feedback = self.get_project_feedback(key)
|
|
205
|
+
for feedback_type, kind in (
|
|
206
|
+
(FeedbackType.ACCEPTED, ACCEPTED_FEEDBACK_KIND),
|
|
207
|
+
(FeedbackType.REJECTED, REJECTED_FEEDBACK_KIND),
|
|
208
|
+
):
|
|
209
|
+
rendered = tuple(item.context_text() for item in feedback if item.type is feedback_type)
|
|
210
|
+
if rendered:
|
|
211
|
+
fields[kind] = rendered
|
|
212
|
+
return fields
|
|
213
|
+
|
|
214
|
+
@staticmethod
|
|
215
|
+
def feedback_capture(key: SuggestionProjectKey) -> SuggestionFeedbackCapture:
|
|
216
|
+
# Gives a parent agent copyable commands for this project without implying feedback.
|
|
217
|
+
options = f"--project {key.value} --suggestion '<text>' [--reason '<reason>']"
|
|
218
|
+
return SuggestionFeedbackCapture(
|
|
219
|
+
project_key=key.value,
|
|
220
|
+
instruction=(
|
|
221
|
+
"Call one command only after the user explicitly accepts or rejects a "
|
|
222
|
+
"suggestion; do not infer feedback from silence or ambiguity."
|
|
223
|
+
),
|
|
224
|
+
accept_command=f"{_FEEDBACK_COMMAND} accept {options}",
|
|
225
|
+
reject_command=f"{_FEEDBACK_COMMAND} reject {options}",
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
def _state(self, read: Callable[[], T]) -> T:
|
|
229
|
+
# One translation from the general store's failures to this feature's repair contract.
|
|
230
|
+
try:
|
|
231
|
+
return read()
|
|
232
|
+
except (LocalFileReadFailed, LocalDocumentInvalid) as error:
|
|
233
|
+
raise SuggestionProjectStateUnreadable(error.reason, error) from error
|
|
234
|
+
|
|
235
|
+
def _mutate(self, write: Callable[[], T]) -> T:
|
|
236
|
+
# A path refused before writing is invalid state; a refused write is a write failure.
|
|
237
|
+
try:
|
|
238
|
+
return write()
|
|
239
|
+
except LocalDocumentInvalid as error:
|
|
240
|
+
raise SuggestionProjectStateUnreadable(error.reason, error) from error
|
|
241
|
+
except LocalFileWriteFailed as error:
|
|
242
|
+
raise SuggestionProjectWriteFailed(error) from error
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
__all__ = [
|
|
246
|
+
"ACCEPTED_FEEDBACK_KIND",
|
|
247
|
+
"PROJECT_CONTEXT_KIND",
|
|
248
|
+
"REJECTED_FEEDBACK_KIND",
|
|
249
|
+
"SuggestionFeedbackInput",
|
|
250
|
+
"SuggestionProject",
|
|
251
|
+
"SuggestionProjectCreateInput",
|
|
252
|
+
"SuggestionProjectKey",
|
|
253
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Package marker for suggestion prompts."""
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Adjacent Opportunity
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
An adjacent opportunity is a nearby source of value that work already underway has made unusually cheap to reach. It sits outside the stated objective, so nothing about the original commitment depends on capturing it. What qualifies it is an enabling condition that exists right now and will not persist: access that has been granted, a system that is already set up, attention that is already focused, or information that is already in front of the person doing the work. The same action taken next quarter would cost materially more, and that cost difference is the whole argument. Proximity in topic is not proximity in this sense, because two efforts can share a subject and share no setup at all. The category exists to stop useful, perishable value from being discarded simply because it was not on the plan.
|
|
5
|
+
|
|
6
|
+
The suggestion must name the enabling connection explicitly rather than gesture at relatedness, because an unnamed connection is usually a second project in disguise. It must bound the additional effort and state where that effort stops, so the primary commitment cannot be displaced by something that was never required. Where the opportunity can be preserved rather than pursued, the suggestion should prefer the reversible capture: a note, an export, a measurement, a reservation, a short spike. It should say what is lost by waiting and how confident that loss estimate is, because a vague timing claim is the most common way this category is abused. It should also distinguish the incremental cost from the full cost of the adjacent work, since only the increment is enabled by the current effort. When the increment cannot be described concretely, the honest answer is that no adjacent opportunity has been found.
|
|
7
|
+
|
|
8
|
+
## Why use
|
|
9
|
+
Reach for this category when the value you have noticed is real but nobody asked for it, and the reason to raise it now is cost rather than importance. Most suggestion categories argue that something should be done; this one argues that something should be done *now*, while a temporary advantage holds. That is a different claim and it needs different evidence — not the worth of the adjacent work, which may be modest, but the size of the gap between doing it during the current effort and doing it cold later. An adjacent opportunity with a large payoff and no timing advantage is not an adjacent opportunity; it is an ordinary piece of work competing for priority like any other.
|
|
10
|
+
|
|
11
|
+
The category also earns its place by protecting the primary commitment from the thing it is most often lost to. Work expands through plausible neighbours, each individually reasonable, and a suggestion agent that cannot name this pattern will keep producing scope creep under the banner of helpfulness. Forcing the suggestion to carry an explicit stopping point and an explicit enabling condition makes expansion visible at the moment it is proposed rather than three steps later. The reversible-capture preference does the same job from the other side: it offers a way to keep the option without spending the commitment, which is usually the correct move when the opportunity's value is uncertain but its window is short.
|
|
12
|
+
|
|
13
|
+
Use it in preference to its neighbours when the distinguishing feature is enablement by current work. If the action is required for the goal, it belongs to prerequisite or continuation regardless of how convenient the timing is. If the payoff is large enough to reshape direction, the honest framing is strategy or big bets, because calling a major commitment "adjacent" understates what is being decided. If one asset is being built deliberately to serve many future tasks, that is leverage, which argues from reuse rather than from a closing window. Adjacent opportunity is the narrow case where the work is optional, the value is bounded, and the moment is what makes it worth raising at all.
|
|
14
|
+
|
|
15
|
+
## Use cases
|
|
16
|
+
- **Current work has exposed reusable information.** The task may surface data, contacts, patterns, or decisions that a nearby objective would otherwise have to rediscover. Suggest capture when recovering that information later would mean repeating the access or the analysis that produced it.
|
|
17
|
+
- **An existing setup can serve one more purpose.** A configured tool, a booked interview, a running prototype, or a loaded dataset may answer a second question at marginal cost. Name the extra step and keep it visibly separate from the original deliverable.
|
|
18
|
+
- **A short external window is open.** A launch, a meeting, a market event, or a moment of stakeholder attention may make a neighbouring action unusually timely. Use the category only when waiting would plausibly remove the advantage rather than merely make it less convenient.
|
|
19
|
+
- **Access has been granted that will lapse.** A credential, an environment, a permission, or an introduction may be available for a limited period. Suggest the smallest action that converts perishable access into a durable artifact.
|
|
20
|
+
- **A reversible capture preserves a future choice.** A note, an export, a measurement, or a reservation can hold an option open without committing to the adjacent project. Recommend it when the capture has a bounded cost and an obvious stopping point.
|
|
21
|
+
- **The adjacent value compounds the main artifact.** A small extension may make the current output reusable, discoverable, or easier to validate elsewhere. Use the category when the extra value comes out of the same work rather than from starting something unrelated.
|
|
22
|
+
- **A neighbouring team or user has the same problem.** The current work may solve a closely related need for another audience with a modest adaptation. Suggest it only when the relationship is concrete and the adaptation will not quietly become a second deliverable.
|
|
23
|
+
- **Capturing a decision now prevents a likely second pass.** Recording an interface, a convention, or a rationale while it is fresh may remove a duplicate investigation later. Use the category when the rework being prevented is specific rather than hypothetical.
|
|
24
|
+
- **A nearby observation would change a later decision.** A quick adjacent check may reveal whether a larger follow-on path is worth pursuing at all. Recommend it when the check completes independently of the main work and its result has a decision attached.
|
|
25
|
+
- **A one-time cost has already been paid.** Travel, setup, procurement, onboarding, or a long build may have a fixed component that a second use amortizes. Suggest the second use when the fixed cost genuinely dominates the marginal cost.
|
|
26
|
+
- **A participant is available who will be hard to reach again.** A customer, an expert, a departing colleague, or a partner may be reachable now and expensive to reconvene. Use the category to capture the specific question worth asking while the access holds.
|
|
27
|
+
- **The current environment reproduces a condition that is normally rare.** A load pattern, a data state, a failure mode, or a seasonal effect may be present only while this work runs. Suggest observing or recording it now, because recreating the condition deliberately is usually the expensive path.
|
|
28
|
+
|
|
29
|
+
## When not to use
|
|
30
|
+
- **The action is required for the stated goal.** Necessary work is not an opportunity, and framing it as optional hides a real dependency.
|
|
31
|
+
- **The connection to current work is thematic rather than enabling.** Sharing a topic does not lower the cost of the second effort.
|
|
32
|
+
- **The incremental effort is open-ended.** Without a stopping point, the suggestion is an invitation to displace the primary commitment.
|
|
33
|
+
- **The timing claim rests on a feeling.** If nothing concrete closes the window, the work can be scheduled on its merits instead.
|
|
34
|
+
- **The proposal changes the main direction.** A commitment that reshapes the plan should be argued as a direction, not smuggled in as a nearby convenience.
|
|
35
|
+
- **The full adjacent project is what is being proposed.** Only the increment enabled by current work belongs here.
|
|
36
|
+
|
|
37
|
+
Route the suggestion elsewhere when one of those signals holds. Required conditions belong to prerequisite, and the next agreed step belongs to continuation. A deliberate investment in one asset that pays back across many future tasks is leverage, and a direction that coordinates several actions is strategy. An ambitious, high-uncertainty commitment is big bets, and a nearby question that must be answered before anything is decided is investigation. If the opportunity is genuinely valuable but nothing about the present moment makes it cheaper, drop the timing argument and let it compete under prioritization.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Alternative
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
An alternative is a materially different route to an outcome that has already been agreed. It changes the method, the sequence, the resource mix, or the scope boundary, while leaving the intended result recognizable to the person who asked for it. The invariant is the outcome; everything else is negotiable and the suggestion must say which part it is trading. A variation that only renames steps or reorders cosmetic detail is not an alternative, because nothing about the decision changes. The value of the category comes from making a credible second option visible, since a committed path tends to hide the options it displaced. Presenting that option is useful only when it could actually be chosen.
|
|
5
|
+
|
|
6
|
+
The comparison must run on criteria that decide, not on a list of properties that merely differ. State what the alternative assumes, what it sacrifices, and what has to be paid once to move from the current route onto it, because transition cost is what usually decides between two viable paths. Say what is known to make the alternative credible rather than simply imaginable, and be explicit when that evidence is thin. Name the risks that disappear, the risks that remain, and the risks that move somewhere else, since a second route rarely reduces exposure without relocating some of it. Where the two routes cannot be separated by argument, propose the smallest comparison or pilot that would separate them. A suggestion that cannot name a criterion on which the alternative wins has not found one.
|
|
7
|
+
|
|
8
|
+
## Why use
|
|
9
|
+
Use this category when the current path is still viable but its cost, its risk, or its dependence on an untested premise makes a second option worth putting on the table. The claim is not that the current plan is wrong. It is that the decision was made against a smaller set of options than actually exists, and that widening the set is cheap compared with discovering the constraint later. This is why an alternative is most valuable early, when the transition cost is low, and why raising one late must come with an honest accounting of the work already sunk into the current route.
|
|
10
|
+
|
|
11
|
+
The category carries a specific discipline that generic advice does not: it forces the outcome to be held fixed. Much of what gets offered as an alternative is really a different goal wearing the same name, and the moment the outcome drifts, the comparison stops meaning anything. Requiring the suggestion to state the invariant makes that failure visible immediately. It also forces the transition to be priced. Two routes that look equivalent on a whiteboard are rarely equivalent from where the work actually stands, and the difference is almost always what it costs to switch.
|
|
12
|
+
|
|
13
|
+
Distinguish it carefully from the categories it neighbours. Creative exploration generates many possibilities without committing to a shared outcome, so it is the right choice when the aim is to widen the field rather than to choose between two routes. Reframing changes how the problem is understood, which changes the outcome itself and therefore breaks the invariant this category depends on. Strategy selects one direction that coordinates several actions over time, where an alternative concerns a single route to a single result. Stop or defer argues the outcome is not worth pursuing at all, which is a different conclusion from pursuing it another way.
|
|
14
|
+
|
|
15
|
+
## Use cases
|
|
16
|
+
- **The current route has grown expensive.** A different method may reach the same outcome with materially less time, money, or coordination. Raise it when the cost gap is large enough to survive the transition effort.
|
|
17
|
+
- **A required dependency cannot be secured.** The chosen path may rest on a person, tool, supplier, permission, or data source that will not be available. Offer a route that preserves the outcome instead of waiting on something that is not coming.
|
|
18
|
+
- **Repeated attempts are producing weak results.** When the failure lives in the method, repeating it more carefully does not help. Propose a route that changes the mechanism responsible for the poor output.
|
|
19
|
+
- **A load-bearing assumption is doubtful.** The plan may assume demand, capacity, access, or feasibility that has never been established. Use an alternative to make the decision robust to that uncertainty, not as a way to avoid testing it.
|
|
20
|
+
- **Risk is concentrated in one design choice.** A second route may remove a single point of failure or provide a fallback. Compare residual risk honestly rather than treating the newer route as automatically safer.
|
|
21
|
+
- **Sequence is causing avoidable friction.** The same work in a different order may cut waiting, rework, or handoffs. Recommend it when the reordered path still respects prerequisites and completion criteria.
|
|
22
|
+
- **A narrower commitment would still meet the goal.** A smaller route may deliver what is actually needed without the full scope of the current plan. Present the reduced scope as an explicit trade, never as a quiet failure to meet the goal.
|
|
23
|
+
- **A different resource mix changes what is feasible.** Borrowing expertise, automating a step, partnering, or reusing an existing asset may open a route the current team cannot walk. Suggest it when ownership and transition cost can be described concretely.
|
|
24
|
+
- **The current route has an unacceptable failure mode.** Even a likely-successful path may fail in a way that cannot be recovered from. Offer a route whose worst case is survivable, and say what it costs.
|
|
25
|
+
- **An external constraint has changed.** Pricing, regulation, tooling, availability, or organizational structure may have moved since the route was chosen. Re-open the comparison when the change plausibly reverses the original decision.
|
|
26
|
+
- **The route cannot be validated until the end.** A path that yields no signal until completion may be worth trading for one that produces evidence early. Argue from when learning arrives, not only from total cost.
|
|
27
|
+
- **A build-versus-adopt choice was never made.** The plan may be constructing something that already exists in usable form. Compare the two on integration cost, control, and long-term ownership rather than on effort alone.
|
|
28
|
+
- **The current route depends on sustained attention.** A path that only works if a specific person stays engaged may be fragile. Propose a route that survives ordinary interruption, and name what it gives up in exchange.
|
|
29
|
+
|
|
30
|
+
## When not to use
|
|
31
|
+
- **The current route is merely unfinished.** An incomplete plan whose assumptions still hold needs execution, not a competitor.
|
|
32
|
+
- **No shared outcome has been defined.** Without an invariant there is nothing for the two routes to be alternatives to.
|
|
33
|
+
- **The difference is cosmetic.** A relabelled sequence changes no decision and wastes the reader's judgment.
|
|
34
|
+
- **The proposed route changes what success means.** Once the outcome moves, this is a new goal rather than another way to reach the old one.
|
|
35
|
+
- **The aim is to widen the field rather than choose.** Generating many options is a different activity from comparing two.
|
|
36
|
+
- **The transition cost cannot be described at all.** An unpriced switch is not a decision anyone can make.
|
|
37
|
+
|
|
38
|
+
Route the suggestion elsewhere when one of those signals holds. An unfinished but sound plan belongs to continuation, and a final remaining obligation belongs to completion. Widening the option space without a fixed outcome is creative exploration, and changing how the problem itself is understood is reframing. A choice of direction spanning many actions is strategy, and abandoning the outcome is stop or defer. If the real blocker is that nobody knows which route is better, use investigation or experiment to produce the evidence first.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Big Bets
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
A big bet is an ambitious commitment whose potential upside is large and whose outcome is genuinely uncertain. What separates it from ordinary work is not ambition but exposure: its scale, its irreversibility, or the concentration of attention it demands can overwhelm the normal machinery of prioritization. A suggestion in this category is therefore proposing a decision, not a task, and it should read as one. The hoped-for gain has to be made concrete, because excitement, novelty, and status make poor substitutes for a described payoff. The commitment has to be made concrete too — the capital, the capability, the timing, and the failure exposure that placing the bet actually requires. Without both halves the proposal is an aspiration rather than a bet.
|
|
5
|
+
|
|
6
|
+
The suggestion should say which assumptions control the size and the probability of the payoff, since a bet is only as good as the beliefs holding it up. It should separate the reversible part of the commitment from the irreversible part, because those are governed differently and confusing them is how organizations lose more than they intended. A maximum acceptable loss belongs in the suggestion explicitly, stated against the core obligation the bet must not endanger. Staging can buy learning before the full commitment is placed, and where a staged path exists the suggestion should describe it along with the evidence that would justify advancing. Staging does not remove the underlying uncertainty, and a suggestion that implies otherwise is misleading. Name who has the authority to place the bet and who carries the downside, because a bet proposed past its decision-maker is not a bet but a surprise.
|
|
7
|
+
|
|
8
|
+
## Why use
|
|
9
|
+
Use this category when the honest framing of an opportunity is that it is large, uncertain, and consequential, and when saying anything smaller would misrepresent what is being asked for. Ordinary prioritization is built to compare bounded work against bounded work; it handles a commitment of this shape badly, usually by shrinking it into something safe that no longer captures the upside. Naming it a bet keeps the scale visible and puts the exposure in the same sentence as the reward, which is the only way the decision can be made on its real terms.
|
|
10
|
+
|
|
11
|
+
The category also exists to enforce honesty in the other direction. A great deal of ambitious language attaches to proposals with no material upside, no bounded downside, and no named assumptions, and a suggestion agent that cannot tell those apart will inflate ordinary work into strategy theatre. Requiring a described payoff, a loss limit, and a decision owner filters most of that out before it reaches a reader. What survives is a small number of proposals worth the concentrated attention this category asks for.
|
|
12
|
+
|
|
13
|
+
Keep the boundary against its neighbours sharp. Strategy chooses a direction that coordinates several actions, and a direction can be adopted incrementally without a concentrated, irreversible commitment. Long-term directions describes capability worth building over time without asserting that a decision is due now. Experiment runs a bounded test precisely to avoid a large commitment, so if a cheap test can answer the central question, the experiment is the correct suggestion and the bet can wait. Adjacent opportunity argues from a closing window on optional, bounded value, which is close to the opposite of the exposure this category describes. Use big bets only when the commitment is large, the uncertainty is irreducible by cheap means, and the upside justifies deliberate risk.
|
|
14
|
+
|
|
15
|
+
## Use cases
|
|
16
|
+
- **The upside would change the trajectory.** The opportunity may create a new level of reach, capability, revenue, or impact rather than an increment. Use the category when that step-change is plausible and material enough to matter.
|
|
17
|
+
- **The current ceiling is structurally limiting.** Incremental improvement may not touch the constraint preventing the desired scale or position. Raise a bet when the step-change is necessary and the exposure can be discussed honestly.
|
|
18
|
+
- **A rare window favours decisive action.** A technology shift, a market moment, a policy change, or unusual access may make a large move more valuable now than later. Use it when the window is evidenced and the cost of waiting can be stated.
|
|
19
|
+
- **A capability requires concentrated investment.** Some outcomes need a dedicated team, platform, partnership, or long build before any benefit appears. Suggest the bet when spreading effort thinly would simply fail to produce the capability.
|
|
20
|
+
- **A visible commitment would unlock complementary assets.** A decisive move may attract talent, partners, distribution, or credibility that small experiments cannot. Use it only when that enabling effect is more than a hopeful narrative.
|
|
21
|
+
- **The downside is bounded and survivable.** Large risk can be acceptable when failure does not threaten the core obligation or the ability to recover. State the loss limit and the conditions that keep survivability true.
|
|
22
|
+
- **The decision deserves explicit ownership.** A commitment may cross a threshold where ordinary task prioritization would conceal its consequences. Use the category to surface the decision and its evidence, never to route around governance.
|
|
23
|
+
- **A staged path can test the key assumption first.** Discovery work, a paid pilot, or a capability milestone may retire the most important uncertainty cheaply. Recommend it when the staged path still preserves a real route to the full upside.
|
|
24
|
+
- **Doing nothing is itself a large exposure.** Standing still may cede a position that cannot be re-entered later. Frame inaction as a bet with its own downside when that is the true shape of the decision.
|
|
25
|
+
- **An existing asset could be redeployed at scale.** A proprietary dataset, a distribution channel, a brand, or an unusual skill concentration may support a much larger move. Use the category when redeployment is a commitment rather than a side effect.
|
|
26
|
+
- **Several small efforts are competing for the same scarce resource.** Splitting a constrained budget or a scarce team across many bets may guarantee that none succeed. Propose concentration explicitly, and name what is being stopped to fund it.
|
|
27
|
+
- **The payoff depends on a belief the organization can test but has not.** A single unvalidated conviction may be doing all the work in the case for a large move. Name it, and say what evidence would raise or lower the commitment.
|
|
28
|
+
|
|
29
|
+
## When not to use
|
|
30
|
+
- **The proposal is an ordinary improvement.** Ambition in the wording does not make a bounded task a bet.
|
|
31
|
+
- **The cost has not been bounded.** A commitment with no stated loss limit cannot be responsibly placed.
|
|
32
|
+
- **A cheap test could answer the central question.** Spending large to learn something small is a failure of sequencing, not courage.
|
|
33
|
+
- **The upside is described only in adjectives.** Without a concrete payoff there is nothing to weigh the exposure against.
|
|
34
|
+
- **The downside threatens the core obligation.** A bet that can take the organization with it is not a bet worth framing as one.
|
|
35
|
+
- **No one named can actually decide it.** A proposal addressed to nobody will not be placed, and pretending otherwise wastes the reader's attention.
|
|
36
|
+
|
|
37
|
+
Route the suggestion elsewhere when one of those signals holds. A bounded test that retires uncertainty is experiment, and gathering the evidence behind it is investigation. A coordinating direction is strategy, and a capability worth growing without a decision due now is long-term directions. Preventing a specific plausible failure is risk prevention, and choosing among competing bounded commitments is prioritization. If the upside is real but the present moment is merely convenient rather than decisive, the honest category is adjacent opportunity.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Bottleneck
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
A bottleneck suggestion targets the one constraint that limits useful progress through a system. The constraint may be a person, a decision, a dependency, a resource, a queue, a capability, or a policy, and it is defined by what it holds back rather than by how busy it looks. The busiest stage is frequently not the limiting stage, and the most visible pain is frequently downstream of the real cause. What makes something a bottleneck is a traceable link between that point and a measurable loss of throughput, quality, or decision speed. Improving anything that is not the constraint produces activity without producing progress. It can also move the constraint somewhere less convenient, which is worse than leaving it alone.
|
|
5
|
+
|
|
6
|
+
The suggestion should identify the constraint by evidence — where work waits, where it returns, where many things depend on one thing — and say what downstream work is actually released if the constraint improves. It should classify what kind of constraint it is, because capacity, policy, information, quality, ownership, and dependency access have different repairs and are routinely confused. It should propose the smallest intervention that changes effective capacity at that point, since large reorganizations are rarely the cheapest way to relieve a specific limiter. It should consider whether raising input into the constraint would worsen the queue instead of helping, which is the most common way well-meant effort backfires here. It should name the flow measure expected to improve and the window over which that improvement should become visible. It should also anticipate where the constraint moves next, because relieving one limiter always promotes another.
|
|
7
|
+
|
|
8
|
+
## Why use
|
|
9
|
+
Use this category when progress is unsatisfying in a way that no individual's effort explains. Systems fail at their constraints, and the experience of a constrained system is diffuse frustration: people are working, work is happening, and yet very little finishes. A suggestion that names the constraint converts that diffuse frustration into one addressable target, which is the single most valuable thing that can be said in such a situation. Nothing else in the category set makes that particular move.
|
|
10
|
+
|
|
11
|
+
The category also guards against a specific and expensive error. Local optimization feels productive, reports well, and reliably fails to improve anything end to end when the optimized stage was not the limiter. A suggestion agent with no bottleneck vocabulary will keep recommending improvements to whichever area is most legible, and those recommendations will keep not working for reasons nobody can articulate. Requiring the suggestion to trace a dependency chain from the constraint to released downstream work is what separates a real diagnosis from a plausible-sounding one.
|
|
12
|
+
|
|
13
|
+
Hold the boundary against the categories it resembles. Prioritization chooses among competing commitments when attention is scarce, whereas a bottleneck is about flow through a system that has already agreed what it wants to do. Coordination resolves ownership, sequencing, or alignment between parties, which is one possible kind of bottleneck rather than a synonym for the category. Simplification removes complexity for its own benefits and may not touch the limiter at all. Stop or defer concludes the work is not worth doing, where this category assumes it is worth doing and asks why it is not moving. Use bottleneck only when one specific point demonstrably limits the whole, and relieving it would demonstrably help.
|
|
14
|
+
|
|
15
|
+
## Use cases
|
|
16
|
+
- **Work is accumulating at one point.** A queue, a review stage, a handoff, or an approval step may be gating everything behind it. Use the category when the accumulation persists and its downstream effect can be observed.
|
|
17
|
+
- **Many people are waiting on one decision.** A delayed choice can block otherwise ready work while consuming coordination effort. Suggest relief when clarifying ownership or decision criteria would release several dependent actions at once.
|
|
18
|
+
- **A scarce skill sets the pace.** One person or capability may be required by too many tasks to keep up. Use the category when load balancing, training, tooling, or resequencing would expand effective capacity at that point.
|
|
19
|
+
- **A dependency repeatedly interrupts flow.** External systems, suppliers, permissions, or data may cause the same work to stop and restart. Recommend changing the interface or adding a buffer when that would restore end-to-end movement.
|
|
20
|
+
- **Rework is consuming the constrained stage.** Defects or unclear inputs may send work back through a stage that is already the limiter. Improving the constraint's input quality is usually more useful than asking it to work faster.
|
|
21
|
+
- **Local optimization is hiding a system loss.** A team may be improving its own numbers while downstream work stays blocked. Name the system constraint that explains the mismatch.
|
|
22
|
+
- **The limiting resource has moved.** A surge, a new project, or a seasonal shift may have created a different constraint from the one everyone still optimizes. Identify the current limiter rather than yesterday's.
|
|
23
|
+
- **One small intervention would release a broad queue.** A template, a decision, an access grant, or a capacity shift may unblock many tasks at once. Recommend it when the leverage follows a traceable dependency chain and not optimism.
|
|
24
|
+
- **Throughput is flat despite added effort.** Adding people or hours without effect is strong evidence that the constraint is elsewhere. Use the category to locate it before more effort is spent.
|
|
25
|
+
- **Lead time is dominated by waiting, not working.** When most elapsed time is queueing, capacity at the active stages is not the problem. Target the wait, and say which wait.
|
|
26
|
+
- **A single shared environment or asset is contended.** A test environment, a data pipeline, a licence, or a physical resource may serialize work that could otherwise run in parallel. Suggest relieving contention when the serialization is the observable limiter.
|
|
27
|
+
- **A policy is the constraint.** An approval threshold, a compliance step, or an internal rule may be limiting flow independently of capacity. Treat the policy as the target, and propose a proportionate change rather than a workaround.
|
|
28
|
+
- **Batching is inflating the wait.** Work released in large infrequent batches may queue for reasons that have nothing to do with capacity. Recommend a smaller batch when it would shorten the cycle without weakening the stage's checks.
|
|
29
|
+
|
|
30
|
+
## When not to use
|
|
31
|
+
- **The problem is one unverified claim.** A single doubtful belief is a question to answer, not a constraint to relieve.
|
|
32
|
+
- **No repeated or system-level effect can be shown.** A one-off delay does not establish a limiter.
|
|
33
|
+
- **The goal itself is unclear.** Optimizing flow towards an undefined outcome produces faster motion in an unknown direction.
|
|
34
|
+
- **The proposed target is simply the busiest stage.** Busy is not the same as limiting, and confusing them moves effort away from the real constraint.
|
|
35
|
+
- **The work should not be flowing at all.** Relieving a constraint on work that is not worth doing accelerates waste.
|
|
36
|
+
- **Several commitments are competing for attention.** That is a choice about what to pursue, not a property of a pipeline.
|
|
37
|
+
|
|
38
|
+
Route the suggestion elsewhere when one of those signals holds. Competing commitments belong to prioritization, and work that is not worth continuing belongs to stop or defer. Unclear ownership or sequencing between parties is coordination, and an undefined outcome is goal clarification. A doubtful claim is verification, and a missing condition that must exist before work can proceed is prerequisite. If the intent is to reduce complexity for its own sake rather than to relieve a demonstrated limiter, use simplification.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Business and Growth
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
A business and growth suggestion improves reach, sustainability, revenue, customer value, or the conditions that make those durable. It must attach the proposed action to one identified growth mechanism rather than treating growth as a general justification for activity. The mechanisms are distinguishable and behave differently: acquisition, activation, retention, expansion, pricing, distribution, and operating leverage each change a different behaviour by a different party. Naming which one is in play is what makes the suggestion evaluable, because the evidence that supports a pricing change is not the evidence that supports a channel change. A credible suggestion says whose behaviour must change and how that change would be observed. Where neither can be stated, what is being proposed is an aspiration about growth rather than a growth action.
|
|
5
|
+
|
|
6
|
+
The suggestion must also account for what growth costs. Acquisition, service, delivery, and support costs scale with volume, and a mechanism that is unprofitable at small scale rarely becomes profitable at large scale by itself. Capacity has to be ready before demand is increased, or the growth converts directly into strain, failed delivery, and lost trust. The proposal should name the measure that captures delivered value rather than a volume number that can rise while value falls. It should consider harm to trust, quality, access, or existing customers, since several reliable growth mechanisms work by borrowing against exactly those. Where the mechanism is uncertain, the suggestion should propose a bounded test capable of separating channel, offer, and execution effects. A test that cannot make that separation will produce a number without producing knowledge.
|
|
7
|
+
|
|
8
|
+
## Why use
|
|
9
|
+
Use this category when the decision in front of the person is commercial or organizational rather than technical or task-level — when the question is whether the work will reach people, sustain itself, or be worth what it costs. Most suggestion categories operate inside an accepted objective. This one steps outside and asks whether the objective is connected to anything that keeps the effort alive, which is a question that goes unasked for long periods and then becomes urgent all at once.
|
|
10
|
+
|
|
11
|
+
It earns its place by demanding a mechanism. The most common failure in commercial suggestion-making is the unfalsifiable recommendation: do more marketing, find more users, raise prices, add a partnership. Each of those can be right, and none of them is a suggestion until someone says which behaviour changes, for whom, and how it is measured. Forcing that specification converts a slogan into something a reader can accept, reject, or test. It also exposes the proposals whose only argument is that the number should be larger.
|
|
12
|
+
|
|
13
|
+
Keep the boundary against neighbouring categories clear. Product and experience improves what people can use and how using it feels, which often drives growth but is argued from the interaction rather than from a commercial mechanism. Strategy chooses a coordinating direction, which may be commercial but does not have to name an acquisition or retention loop. Long-term directions concerns capability worth building over time without a near-term growth mechanism attached. Bottleneck relieves an operational limiter, which matters for growth but is a property of flow rather than of demand. Use business and growth when the primary decision genuinely concerns durable commercial or organizational value.
|
|
14
|
+
|
|
15
|
+
## Use cases
|
|
16
|
+
- **A valuable audience is not being reached.** The offer may be strong while discovery, distribution, or channel fit is weak. Use the category when a specific audience and a concrete route to reach it can both be named.
|
|
17
|
+
- **Interested people are not becoming active.** Friction in activation, onboarding, or time-to-first-value may be suppressing adoption despite real interest. Suggest a change when the behavioural step and its measure are clear.
|
|
18
|
+
- **Existing customers are not retained or expanded.** Value may go unrealized after the first transaction. Use it when a retention, renewal, cross-sell, or expansion mechanism can be tested without eroding trust.
|
|
19
|
+
- **Revenue does not reflect delivered value.** Pricing, packaging, or contract structure may be misaligned with what customers actually receive. Recommend the change when the economic hypothesis can be checked against customer and cost evidence.
|
|
20
|
+
- **Growth is creating operational strain.** Demand may be outrunning support, delivery, quality, or cash. Use the category to find the sustainable rate rather than to maximize a top-line number.
|
|
21
|
+
- **A repeatable acquisition loop is emerging.** Current work may have surfaced a channel, referral pattern, or message worth systematizing. Suggest it when repeatability and unit economics are both plausible.
|
|
22
|
+
- **A partnership could extend reach or capability.** Another organization may supply distribution, trust, supply, or complementary expertise. Use it when mutual value, ownership, and dependency risk can all be stated.
|
|
23
|
+
- **A commercial decision needs a bounded test.** A campaign, offer, channel, or retention intervention may warrant a trial before commitment. Recommend it when the trial can distinguish the mechanism from ordinary fluctuation.
|
|
24
|
+
- **Unit economics are unknown.** Decisions may be being made without knowing what a customer costs to acquire or serve. Suggest establishing the number when it would change what is worth scaling.
|
|
25
|
+
- **Concentration has become a risk.** Revenue, distribution, or supply may depend on a single customer, channel, or partner. Use the category when diversification is a commercial decision rather than an operational one.
|
|
26
|
+
- **Churn has a nameable cause.** Departures may cluster around a segment, a moment, or an unmet expectation. Recommend acting on the cause when it can be identified rather than inferred from a total.
|
|
27
|
+
- **A segment is being served at a loss.** Some customers may cost more to serve than they contribute. Use the category when the segment can be identified and the response is a commercial choice rather than a service failure.
|
|
28
|
+
- **Demand exists for something adjacent to the current offer.** Requests may consistently point at a capability that is not sold today. Suggest it when the willingness to pay is evidenced rather than assumed.
|
|
29
|
+
|
|
30
|
+
## When not to use
|
|
31
|
+
- **The task is internal and has no commercial mechanism.** Completing work is not growth merely because the organization benefits from it.
|
|
32
|
+
- **The only rationale is a larger number.** More users or more revenue, with no named customer value, is not a mechanism.
|
|
33
|
+
- **The change is about the interaction itself.** Improving how something feels to use is argued from the experience, not from a growth loop.
|
|
34
|
+
- **The proposal is a long-range capability.** Without a near-term mechanism it is a direction rather than a growth action.
|
|
35
|
+
- **The limiter is operational.** Demand-side suggestions do not help a system that cannot deliver what it already sells.
|
|
36
|
+
- **Whose behaviour changes cannot be stated.** An unattributed behaviour change cannot be observed, tested, or accepted.
|
|
37
|
+
|
|
38
|
+
Route the suggestion elsewhere when one of those signals holds. Interaction quality belongs to product and experience, and a coordinating commercial direction belongs to strategy. A capability worth building over time is long-term directions, and an ambitious, uncertain commercial commitment is big bets. An operational limiter is bottleneck, and an unproven commercial belief that must be settled first is investigation or experiment. If the organization does not yet agree what outcome it is pursuing, start with goal clarification.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Completion
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
A completion suggestion closes one specific unfinished obligation that still matters to the current task. It converts an open loop into a defined final action, an acceptance condition, and a stopping point. The obligation may be a missing deliverable, an unresolved decision, a final review, a handoff, a recorded result, or a cleanup step that makes the state safe to leave behind. What makes it a completion rather than more work is that the gap is the last one, and closing it changes the status of the whole from open to done. The category is narrow on purpose, because the failure it exists to prevent is the one where nearly finished work stays nearly finished indefinitely. Naming the remaining gap precisely is most of the value.
|
|
5
|
+
|
|
6
|
+
The suggestion must distinguish genuine completion from polish and from new scope, which are the two ways this category is usually misused. Polish improves something already sufficient; new scope adds capability that was never part of the obligation. Both feel like finishing and neither is. State the observable acceptance condition that proves the work is closed, since completion asserted without evidence tends to be re-litigated later. Name who or what is waiting, because an obligation with no waiting party is often not an obligation at all. Say what record or handoff makes the completed state durable, so the closure survives the attention of the person who created it. Give the stopping point explicitly, because without one the closing pass reliably becomes another round of improvement.
|
|
7
|
+
|
|
8
|
+
## Why use
|
|
9
|
+
Use this category when the highest-value action available is to finish rather than to start. Unfinished work carries a cost that is easy to underestimate: it holds context in someone's head, blocks whoever is downstream, and quietly accumulates until nobody can say what state anything is in. A suggestion that closes one obligation cleanly removes more drag than a suggestion that opens a promising new direction, and it is the less appealing recommendation, which is precisely why it needs a category of its own.
|
|
10
|
+
|
|
11
|
+
The category also enforces a definition of done that survives contact with optimism. Left unspecified, "finished" drifts towards whatever the person doing the work finds satisfying, and the same deliverable can be finished three times. Requiring an acceptance condition and a stopping point pins that definition to something observable. It converts a feeling into a check, which is what allows responsibility to transfer to someone else.
|
|
12
|
+
|
|
13
|
+
Distinguish it from the categories nearest to it. Continuation advances an accepted plan by its next bounded step, which may be one of many remaining; completion applies only when the gap being closed is the last one. Verification tests a claim that something is true, which may be part of completing but is argued from doubt rather than from an outstanding obligation. Quick wins looks for small, cheap value anywhere, where completion is specifically about the obligation already incurred. Stop or defer abandons the obligation rather than closing it, and it is the right category when finishing is no longer worth the remaining effort.
|
|
14
|
+
|
|
15
|
+
## Use cases
|
|
16
|
+
- **A deliverable is one omission from usable.** A single known gap may be all that stands between the work and acceptance. Suggest completion when the missing piece is specific and the acceptance condition is already knowable.
|
|
17
|
+
- **An open decision sits at the finish line.** The work may be technically done and blocked by one unmade choice. Use it when making and recording that choice closes the obligation rather than reopening the problem.
|
|
18
|
+
- **A final review has not happened.** A focused review may be the last condition before release or handoff. Recommend it when the review scope is bounded and findings have an owner and a response path.
|
|
19
|
+
- **A handoff is missing one artifact.** Another person or system may be waiting on instructions, credentials, context, or a summary. Use it when supplying that exact item transfers responsibility cleanly.
|
|
20
|
+
- **A result was checked but never recorded.** Work may have been validated informally and left without durable evidence. Suggest the smallest capture that makes the state observable to someone else.
|
|
21
|
+
- **Cleanup is a real completion condition.** Temporary files, feature flags, access grants, or stale branches may remain after the main work. Use the category when leaving them is a genuine hazard, not when tidiness is merely preferred.
|
|
22
|
+
- **The work is generating new open loops.** A short closeout pass may stop unfinished decisions from becoming future confusion. Recommend it when the pass has a defined inventory and a finish condition.
|
|
23
|
+
- **A stopping point is already available.** Further improvement is possible while the current result already meets the agreed threshold. Use completion to name the evidence that justifies closing instead of continuing.
|
|
24
|
+
- **Documentation required by the obligation is absent.** A runbook, a decision record, or an interface note may have been part of the agreed deliverable. Close it when the document was promised rather than merely desirable.
|
|
25
|
+
- **An approval or sign-off is outstanding.** The work may be waiting on a formal acceptance nobody has requested. Suggest requesting it explicitly, naming who signs and against what criteria.
|
|
26
|
+
- **A temporary measure needs to be retired or made permanent.** A workaround may be silently becoming the design. Use the category to force the choice and close the loop either way.
|
|
27
|
+
- **Partial results are unusable until assembled.** Several finished pieces may deliver nothing until someone integrates them. Recommend the assembly step when it is the final gap rather than a new build.
|
|
28
|
+
|
|
29
|
+
## When not to use
|
|
30
|
+
- **A prerequisite is missing.** Work blocked by an absent condition is not one step from done.
|
|
31
|
+
- **An unresolved uncertainty controls the outcome.** Closing around a question that has not been answered produces a false finish.
|
|
32
|
+
- **The proposed action adds capability.** New scope is not completion, however naturally it follows.
|
|
33
|
+
- **The action is polish on something already sufficient.** Improving a result past its threshold reopens work that was closed.
|
|
34
|
+
- **The step advances the plan without ending it.** A next move among several is continuation, not closure.
|
|
35
|
+
- **The obligation is no longer worth meeting.** Finishing work whose value has gone is an expensive way to feel tidy.
|
|
36
|
+
|
|
37
|
+
Route the suggestion elsewhere when one of those signals holds. A missing condition belongs to prerequisite, and an unanswered question belongs to investigation or verification. A next bounded step in an accepted plan is continuation, and abandoning the obligation is stop or defer. Added capability is usually continuation, alternative, or product and experience depending on what it changes. If the obligation is unclear because nobody agreed what finished means, the prior category is goal clarification.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Continuation
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
A continuation suggestion advances an already accepted plan from its current state to its next bounded step. It assumes the direction is settled and the desired outcome is clear enough to act on, which is what makes it the cheapest useful suggestion available when those assumptions hold. Its job is to identify what happens next without reopening anything that was already decided. The step must be concrete enough to start without further planning and narrow enough that finishing it produces a natural point to stop and reassess. A continuation is not a new strategy wearing execution language, and it is not a request to repeat effort that produced no learning. Where the direction is genuinely in doubt, the honest suggestion is something other than continuation.
|
|
5
|
+
|
|
6
|
+
The suggestion should name what has already been accepted, because a continuation that misidentifies the plan will carry work in the wrong direction efficiently. It should say what changed in the current state since the previous step, since that change is usually what makes the next action visible. It should supply the input, the owner, and the output that make the action startable, because unowned obvious steps are the ones that stall longest. It should give a bounded result that marks the step complete, so that momentum does not become drift. It should check whether executing the step would create an irreversible commitment ahead of a decision that has not been made yet. It should also name the condition under which reassessment replaces another continuation, because a plan that can never be interrupted is not a plan.
|
|
7
|
+
|
|
8
|
+
## Why use
|
|
9
|
+
Use this category when the situation needs movement rather than thought. A surprising amount of stalled work is not blocked by uncertainty at all; it is blocked because nobody has named the next action in terms concrete enough to begin. Naming it is a small act with a disproportionate effect, and it is the correct recommendation far more often than the more interesting categories are. A suggestion agent that reaches for strategy when continuation would do produces work that feels insightful and changes nothing.
|
|
10
|
+
|
|
11
|
+
The category also protects a plan from being reopened for no reason. Every re-examination has a cost — context reload, renegotiation, lost attention — and plans that are re-examined continuously never reach the point where their assumptions could be tested against reality. Continuation asserts that the prior decision stands and that the useful next act is to execute against it. That assertion should be made deliberately, which is why the suggestion must state what was accepted and what would trigger reassessment instead.
|
|
12
|
+
|
|
13
|
+
Keep the boundary against its neighbours firm. Completion applies when the step being proposed is the last one and closing it ends the obligation. Immediate next steps starts from the current state without assuming an accepted plan, which makes it the right category when the direction is only loosely agreed. Prerequisite applies when a condition required by the plan does not yet exist, and proposing the next step over a missing condition simply relocates the blockage. Alternative and strategy both reopen the route, which is the opposite of what this category does. Use continuation when the plan holds, the state is known, and one bounded action moves it forward.
|
|
14
|
+
|
|
15
|
+
## Use cases
|
|
16
|
+
- **An accepted plan has paused.** The direction is settled and the current state is known. Name the action that restores movement without reopening the plan.
|
|
17
|
+
- **A milestone has just been reached.** Completing one step may have made the next dependency visible. Suggest continuation when the new state supports a bounded follow-on rather than a fresh planning cycle.
|
|
18
|
+
- **The next step is obvious but unowned.** Work stalls even when no strategic question remains. Supply the action, owner, input, and completion signal that carry the plan forward.
|
|
19
|
+
- **A sequence has a natural next operation.** One stage may produce exactly what the following stage consumes. Recommend it when the dependency is explicit and the handoff is ready.
|
|
20
|
+
- **Restart cost is rising.** A long pause may require reloading context, rebuilding setup, or recapturing stakeholder attention. Use it when starting now has a real continuity benefit rather than an imagined one.
|
|
21
|
+
- **The next action can produce value independently.** A plan may continue while a later decision stays open. Suggest it when the step creates no irreversible commitment ahead of that decision.
|
|
22
|
+
- **An accepted task is still too broad to begin.** The plan may be clear while the immediate action is not. Reduce it to one executable slice with a stopping condition.
|
|
23
|
+
- **A predictable follow-up is part of the agreed path.** A review, measurement, deployment, or communication may already be an obligation of the plan. Recommend it as continuation rather than presenting it as a new idea.
|
|
24
|
+
- **A parallel track can start now.** An independent piece of the accepted plan may be startable while the main line waits. Use it when the parallel work needs nothing the blocked line is waiting for.
|
|
25
|
+
- **A step failed and the plan survives.** An attempt may have produced a correctable failure without invalidating the direction. Suggest the corrected next attempt when the learning is specific and the plan still holds.
|
|
26
|
+
- **New input has arrived that the plan expected.** Data, a decision, or an approval may have unblocked a step that was already scheduled. Name the step the arrival enables.
|
|
27
|
+
- **Work is proceeding without a defined stopping point.** An in-progress effort may need a bounded target more than it needs a new one. Propose the boundary as the continuation itself.
|
|
28
|
+
|
|
29
|
+
## When not to use
|
|
30
|
+
- **The direction is disputed.** Executing against a contested plan converts disagreement into wasted work.
|
|
31
|
+
- **The goal is unclear.** A next step towards an undefined outcome cannot be evaluated.
|
|
32
|
+
- **A required condition is missing.** Advancing over an absent prerequisite moves the blockage rather than removing it.
|
|
33
|
+
- **The proposed step is really a new idea.** An opportunity, a different route, or a broader direction should be argued as one.
|
|
34
|
+
- **This step is the last remaining obligation.** Closing work has different evidence requirements from advancing it.
|
|
35
|
+
- **Continuing is no longer worthwhile.** Momentum is not a reason to keep spending when the value has gone.
|
|
36
|
+
|
|
37
|
+
Route the suggestion elsewhere when one of those signals holds. A missing condition belongs to prerequisite, and a final obligation belongs to completion. A disputed route belongs to alternative or strategy, and an undefined outcome belongs to goal clarification. Work that no longer earns its cost belongs to stop or defer, and a plan that does not exist yet is better served by immediate next steps. If the step cannot start because one point in the system is holding everything up, use bottleneck instead.
|