This file tracks factual remediation status for the current release cycle. It is intentionally short and only lists actionable open items.
mapWithConcurrencynow short-circuits scheduling on first mapper failure while preserving index-stable output ordering.parseGitHubRemotenow handles trailing slashes and common SSH/HTTPS URL forms without overmatching.- CLI unhandled error rendering now hides stacks by default and only prints stack traces when explicit verbose env flags are enabled (
MAESTRO_VERBOSEorMAESTRO_VERBOSE_ERRORS). GitAdapter.isCleanbehavior (--untracked-files=no) is now explicitly documented in user-facing CLI docs and architecture guardrails.- Dependency simplification recommendations from the review were converted into explicit decisions:
defureplacingdeepmerge: rejected for now;p-map,git-url-parse,fast-json-stable-stringify: deferred with rationale in stack governance docs.
- Full validation gate passes after remediation (
pnpm -s check).
- Completed:
- resource leak remediation applied in test suites by replacing test-local temp directories with
createManagedTempDir(...); - mock lifecycle normalized with
clearMocks: trueinvitest.config.tsand reset boilerplate removed from targeted files; - unsafe
as nevermock typing removed from targeted unit tests via typed fixtures/builders; - YAML helper added as
tests/utils/yaml.tsand adopted intests/unit/workspace-resolution.test.ts; git-adapter.test.tsreclassified to integration (tests/integration/git-adapter.test.ts) and adapter instantiation isolated per test viabeforeEach;- timer-based tests in
fs-performanceandexecution-servicenow use fake timers for deterministic execution.
- resource leak remediation applied in test suites by replacing test-local temp directories with
- Remaining:
- optional follow-up: migrate large inline YAML fixtures in
tests/integration/workflow.test.tstowriteYaml(...)for full consistency.
- optional follow-up: migrate large inline YAML fixtures in
- Completed:
devcontainer.baseImageis now strictly validated in schema to block newline/injection payloads.- task branch name creation now sanitizes
taskNamedefensively insidecreateTaskBranchName(...). - pack source boundary checks are now consistent for absolute and relative sources.
- PR generation is resilient to per-repository adapter failures (issues are recorded and processing continues).
DiffSizeLimitPolicynow rejects invalid numeric thresholds explicitly (DIFF_LIMIT_INVALID_NUMBER).- execution defaults are schema-owned, and manual
normalizeExecutionlogic has been removed from workspace resolution. - dead
SchemaAdaptertype surface was removed. - official
@types/proper-lockfilehas replaced the manual shim declaration. - agent discovery file resolution now uses deterministic extension probing (
.toml,.md,.json) rather than broad filename-prefix scanning.
- Remaining:
- remove
getRepositoryReferenceBranch(...)and inlinerepository.branchdirectly across call sites (schema already defaults the branch). - compatibility follow-up:
pr-report.jsonnow stores{ results, issues }; any external consumer expecting a raw array should be migrated.
- remove
- Do not mark an item done without command output proving validation.
- Keep this file aligned with
docs/architecture/review-remediation.md. - Remove completed items from this file as they are validated and merged.
As the project scales from a robust MVP to a platform-agnostic enterprise CLI, adopting stricter architectural boundaries will ensure long-term maintainability.
- Explicit Port Interfaces: Replace inline types like
Pick<GitAdapter, ...>insrc/core/command-context.tswith pure interfaces defined in asrc/core/ports/directory (e.g.,IGitProvider,IGitHubProvider). Core should only depend on these interfaces. - Dependency Inversion: This allows swapping out implementations (e.g.,
MockGitProvider,InMemoryFileSystem) for testing without hitting the disk, eliminating the need to clean up/tmpfolders in unit tests. - Abstract the File System: Move
src/utils/fs.ts(directnode:fsusage) behind anIFileSysteminterface injected into the context.
- Rename Core Commands: The distinction between
src/cli/commandsandsrc/core/commandsis confusing. Renamesrc/core/commandstosrc/core/use-casesorsrc/core/workflows. - Separation of Concerns: A "Command" in
src/clishould strictly handle routing, argument parsing, and stdin/stdout. A "Use Case" insrc/coreshould handle pure business logic (SyncWorkspaceUseCase,BootstrapRepositoryUseCase).
- Extract a Renderer/Presenter:
src/cli/main.tsdirectly usesprocess.stdout.write(JSON.stringify(report)). Core use cases should return pure DTOs (Domain Transfer Objects) or Result objects. - Pluggable Output: The CLI layer should invoke a
JsonRendererorInteractiveConsoleRendererbased on flags. This separates what is computed from how it is displayed, allowing you to easily add interactive spinners (e.g.,clackorora) without polluting core logic. - Progress Reporting Abstraction: Inject an
IObserverorIReporterintoCommandContextso core operations can emit progress events (RepositoryCloned,PackResolved) that the CLI layer can subscribe to for interactive feedback.
- Error Code Registry:
MaestroErroraccepts a stringcode. Introduce a strict TypeScript Enum or String Union for Error Codes (e.g.,MaestroErrorCode = 'WORKSPACE_NOT_FOUND' | 'GIT_UNCOMMITTED_CHANGES'). This prevents typos and enables exhaustiveness checking. - Result Types: Consider returning a Result Monad (e.g., using
neverthrowor a customResult<T, E>) for expected domain errors instead of throwing exceptions. Reservethrowstatements strictly for unexpected, unrecoverable panics.
- Centralize Configuration: Magic numbers like
RESOLUTION_CONCURRENCY_LIMIT = 4insrc/core/workspace-service.tsshould be lifted into anAppConfiginterface injected at startup, potentially defaulting toos.cpus().length. - Application Context Builder: Instead of manually creating and passing
CommandContextdown the chain, consider a lightweight DI container or a robust context builder at the CLI entry point.
- Rich Domain Models: Currently,
src/types.tsandsrc/workspace/types.tsdefine mostly plain data structures. As logic grows, consider moving towards a richersrc/domain/layer where business entities encapsulate their own validation and invariants (e.g., aWorkspaceclass that guarantees its manifest is valid).