@pennixrv/trellis 0.6.45 → 0.7.0-beta.10

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.
Files changed (92) hide show
  1. package/dist/cli/index.d.ts.map +1 -1
  2. package/dist/cli/index.js +21 -3
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/commands/mem.d.ts.map +1 -1
  5. package/dist/commands/mem.js +6 -13
  6. package/dist/commands/mem.js.map +1 -1
  7. package/dist/commands/workflow.d.ts +17 -0
  8. package/dist/commands/workflow.d.ts.map +1 -1
  9. package/dist/commands/workflow.js +222 -0
  10. package/dist/commands/workflow.js.map +1 -1
  11. package/dist/configurators/claude.d.ts.map +1 -1
  12. package/dist/configurators/claude.js.map +1 -1
  13. package/dist/configurators/dsh.d.ts +16 -19
  14. package/dist/configurators/dsh.d.ts.map +1 -1
  15. package/dist/configurators/dsh.js +38 -26
  16. package/dist/configurators/dsh.js.map +1 -1
  17. package/dist/configurators/gemini.d.ts.map +1 -1
  18. package/dist/configurators/gemini.js.map +1 -1
  19. package/dist/configurators/opencode.d.ts.map +1 -1
  20. package/dist/configurators/opencode.js +4 -0
  21. package/dist/configurators/opencode.js.map +1 -1
  22. package/dist/migrations/manifests/0.6.17.json +2 -2
  23. package/dist/migrations/manifests/0.7.0-beta.10.json +9 -0
  24. package/dist/migrations/manifests/0.7.0-beta.4.json +9 -0
  25. package/dist/migrations/manifests/0.7.0-beta.4.pennix.1.json +9 -0
  26. package/dist/migrations/manifests/0.7.0-beta.5.json +9 -0
  27. package/dist/migrations/manifests/0.7.0-beta.6.json +9 -0
  28. package/dist/migrations/manifests/0.7.0-beta.7.json +9 -0
  29. package/dist/migrations/manifests/0.7.0-beta.8.json +9 -0
  30. package/dist/migrations/manifests/0.7.0-beta.9.json +9 -0
  31. package/dist/templates/claude/hooks/statusline.py +7 -0
  32. package/dist/templates/claude/settings.json +22 -0
  33. package/dist/templates/codex/hooks/session-start.py +20 -1
  34. package/dist/templates/codex/hooks.json +25 -0
  35. package/dist/templates/common/bundled-skills/trellis-channel/references/subnode-work.md +32 -3
  36. package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +2 -2
  37. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-task-lifecycle.md +1 -0
  38. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +2 -1
  39. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +3 -2
  40. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +1 -1
  41. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +5 -4
  42. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +1 -0
  43. package/dist/templates/common/bundled-skills/trellis-session-insight/SKILL.md +2 -2
  44. package/dist/templates/common/bundled-skills/trellis-session-insight/references/cli-quick-reference.md +3 -2
  45. package/dist/templates/common/commands/continue.md +4 -2
  46. package/dist/templates/common/skills/brainstorm.md +14 -6
  47. package/dist/templates/copilot/hooks/session-start.py +20 -1
  48. package/dist/templates/copilot/prompts/brainstorm.prompt.md +16 -6
  49. package/dist/templates/dsh/DSH.md +61 -37
  50. package/dist/templates/dsh/agents/trellis-check.md +99 -0
  51. package/dist/templates/dsh/agents/trellis-implement.md +106 -0
  52. package/dist/templates/dsh/agents/trellis-research.md +134 -0
  53. package/dist/templates/dsh/index.d.ts +12 -11
  54. package/dist/templates/dsh/index.d.ts.map +1 -1
  55. package/dist/templates/dsh/index.js +14 -12
  56. package/dist/templates/dsh/index.js.map +1 -1
  57. package/dist/templates/opencode/plugins/inject-spec-context.js +121 -0
  58. package/dist/templates/opencode/plugins/inject-workflow-state.js +111 -10
  59. package/dist/templates/pi/extensions/trellis/index.ts.txt +164 -10
  60. package/dist/templates/shared-hooks/index.d.ts +8 -2
  61. package/dist/templates/shared-hooks/index.d.ts.map +1 -1
  62. package/dist/templates/shared-hooks/index.js +13 -1
  63. package/dist/templates/shared-hooks/index.js.map +1 -1
  64. package/dist/templates/shared-hooks/inject-shell-session-context.py +3 -3
  65. package/dist/templates/shared-hooks/inject-spec-context.py +844 -0
  66. package/dist/templates/shared-hooks/inject-workflow-state.py +35 -9
  67. package/dist/templates/shared-hooks/session-start.py +22 -1
  68. package/dist/templates/trellis/agents/subnode.md +11 -4
  69. package/dist/templates/trellis/config.yaml +49 -0
  70. package/dist/templates/trellis/index.d.ts +3 -0
  71. package/dist/templates/trellis/index.d.ts.map +1 -1
  72. package/dist/templates/trellis/index.js +6 -0
  73. package/dist/templates/trellis/index.js.map +1 -1
  74. package/dist/templates/trellis/scripts/common/active_task.py +26 -4
  75. package/dist/templates/trellis/scripts/common/cli_adapter.py +38 -6
  76. package/dist/templates/trellis/scripts/common/config.py +18 -0
  77. package/dist/templates/trellis/scripts/common/context_projection.py +2 -2
  78. package/dist/templates/trellis/scripts/common/git_context.py +34 -2
  79. package/dist/templates/trellis/scripts/common/paths.py +28 -0
  80. package/dist/templates/trellis/scripts/common/spec_inject.py +439 -0
  81. package/dist/templates/trellis/scripts/common/spec_match.py +395 -0
  82. package/dist/templates/trellis/scripts/common/task_store.py +88 -1
  83. package/dist/templates/trellis/scripts/common/trellis_config.py +46 -7
  84. package/dist/templates/trellis/scripts/common/workflow_phase.py +3 -2
  85. package/dist/templates/trellis/scripts/common/workflow_selection.py +177 -0
  86. package/dist/templates/trellis/scripts/subnode_artifact.py +153 -15
  87. package/dist/templates/trellis/scripts/task.py +160 -0
  88. package/dist/templates/trellis/workflow.md +49 -34
  89. package/dist/types/ai-tools.d.ts.map +1 -1
  90. package/dist/types/ai-tools.js +26 -13
  91. package/dist/types/ai-tools.js.map +1 -1
  92. package/package.json +2 -2
@@ -5,7 +5,7 @@ Trellis connects the same local architecture to different AI tools. `.trellis/`
5
5
  When a local AI modifies Trellis, it should distinguish two file categories first:
6
6
 
7
7
  - **Shared files**: `.trellis/workflow.md`, `.trellis/tasks/`, `.trellis/spec/`, `.trellis/scripts/`.
8
- - **Platform files**: `.claude/`, `.snow/`, `.codex/`, `.cursor/`, `.opencode/`, `.kiro/`, `.gemini/`, `.qoder/`, `.codebuddy/`, `.github/`, `.factory/`, `.pi/`, `.trae/`, `.kilocode/`, `.agent/`, `.devin/`, `.reasonix/`, `.zcode/`, `.kimi-code/`, and similar directories.
8
+ - **Platform files**: `.claude/`, `.snow/`, `.codex/`, `.cursor/`, `.opencode/`, `.kiro/`, `.gemini/`, `.qoder/`, `.codebuddy/`, `.github/`, `.factory/`, `.pi/`, `.trae/`, `.kilocode/`, `.agent/`, `.devin/`, `.reasonix/`, `.zcode/`, `.kimi-code/`, `.dsh/`, and similar directories.
9
9
 
10
10
  Platform files do not store business state. They let the corresponding AI tool read Trellis state, call Trellis scripts, and load Trellis skills/agents/hooks.
11
11
 
@@ -19,14 +19,14 @@ This page lists common Trellis file locations in a user project by platform. Whe
19
19
  | CodeBuddy | `--codebuddy` | `.codebuddy/` | `.codebuddy/skills/` | `.codebuddy/agents/` | `.codebuddy/hooks/` + `.codebuddy/settings.json` |
20
20
  | GitHub Copilot | `--copilot` | `.github/` | `.github/skills/` | `.github/agents/` | `.github/copilot/hooks/` + prompts |
21
21
  | Factory Droid | `--droid` | `.factory/` | `.factory/skills/` | `.factory/droids/` | `.factory/hooks/` + settings |
22
- | DeepSeek Harness (dsh) | `--dsh` | `.dsh/` | `.agents/skills/` (shared) + `.dsh/skills/` (entry skills) | None (workflow skills run implement/check inline) | None (class-2 pull-based; no project hooks/settings) |
23
22
  | Pi Agent | `--pi` | `.pi/` | `.agents/skills/` | `.pi/agents/` | `.pi/extensions/trellis/` (native `trellis_subagent` tool) + `.pi/settings.json` |
24
23
  | Trae IDE | `--trae` | `.trae/` | `.trae/skills/` | `.trae/agents/` | `.trae/hooks/` + `.trae/hooks.json` |
25
24
  | Reasonix | `--reasonix` | `.reasonix/` | `.reasonix/skills/` | None — sub-agents are skills with `runAs: subagent` frontmatter | None |
26
25
  | ZCode | `--zcode` | `.zcode/` | `.zcode/skills/` | `.zcode/agents/` | `.zcode/hooks/` + `.zcode/config.json` (SessionStart + UserPromptSubmit + PreToolUse Agent/Task); sub-agents use hook-injected context |
27
26
  | Grok Build | `--grok` | `.grok/` | `.grok/skills/` | `.grok/agents/` | pull-based prelude (no hooks; flat `.grok/commands/trellis-*.md`) |
28
- | Kimi Code | `--kimi` | `.kimi-code/` | `.agents/skills/` (shared) + `.kimi-code/skills/` | `.kimi-code/agents/` (custom sub-agents; same prompts also ship as skills) | None (pull-based prelude; no project hooks/settings) |
27
+ | Kimi Code | `--kimi` | `.kimi-code/` | `.agents/skills/` (shared) + `.kimi-code/skills/` | None — agent prompts are skills under `.kimi-code/skills/` and dispatch to the built-in `coder` | None (pull-based prelude; no project hooks/settings) |
29
28
  | Snow CLI | `--snow` | `.snow/` | `.snow/skills/` | `.snow/agents/` (auto-discovered; primary path) | class-1: auto inject + project agents + `beforeSubAgentStart` (`.snow/hooks/` `session`/`user`/`subagent` modes -> `additionalContext` JSON); no legacy sub-agent JSON; commands `.snow/commands/trellis-*.json` |
29
+ | DeepSeek Harness | `--dsh` | `.dsh/` | `.agents/skills/` (shared) + `.dsh/skills/` | None — role prompts are collision-free `trellis-agent-*` skills under `.dsh/skills/` | None installed by Trellis (pull-based roles; optional `dsh-trellis` adds event-driven wait, otherwise foreground dispatch) |
30
30
 
31
31
  ## Capability Groups
32
32
 
@@ -49,8 +49,9 @@ These platforms usually have `trellis-research`, `trellis-implement`, and `trell
49
49
  - Reasonix (delivered as skills with `runAs: subagent` under `.reasonix/skills/`, not as a separate `agents/` directory)
50
50
  - ZCode
51
51
  - Grok Build (`.grok/agents/`; dispatch via `spawn_subagent` with `subagent_type`)
52
- - Kimi Code (`.kimi-code/agents/`; the same prompts are also delivered as skills under `.kimi-code/skills/`)
52
+ - Kimi Code (delivered as skills under `.kimi-code/skills/`; dispatched to the built-in `coder`, including research because it must persist files)
53
53
  - Snow CLI (`.snow/agents/`; auto-discovered project agents + class-1 hooks)
54
+ - DeepSeek Harness (role prompts delivered as `.dsh/skills/trellis-agent-*/SKILL.md`; dispatched through the continuable `subagent` tool)
54
55
 
55
56
  When changing implementation/check/research behavior, look for the corresponding platform agent files first.
56
57
 
@@ -74,7 +75,7 @@ When changing behavior, inspect workflows and skills first. Do not assume Trelli
74
75
 
75
76
  ### Shared `.agents/skills/`
76
77
 
77
- Codex, Gemini CLI, Pi Agent, Kimi Code, and DeepSeek Harness (dsh) write the shared `.agents/skills/` layer. Some tools that support agentskills.io can also read this directory. If the user wants multiple compatible tools to share one skill, consider `.agents/skills/` first, but do not assume every platform reads it. ZCode keeps Trellis-managed skills under `.zcode/skills/`.
78
+ Codex, Gemini CLI, Pi Agent, Kimi Code, and DeepSeek Harness write the shared `.agents/skills/` layer. Some tools that support agentskills.io can also read this directory. If the user wants multiple compatible tools to share one skill, consider `.agents/skills/` first, but do not assume every platform reads it. ZCode keeps Trellis-managed skills under `.zcode/skills/`.
78
79
 
79
80
  ## Decision Rules When Modifying Platform Files
80
81
 
@@ -34,6 +34,7 @@ Trellis workflow skills usually share one semantic set: brainstorm, before-dev,
34
34
  | Reasonix | `.reasonix/skills/` |
35
35
  | ZCode | `.zcode/skills/`, `.zcode/commands/` |
36
36
  | Kimi Code | `.agents/skills/`, `.kimi-code/skills/` (commands delivered as `/skill:trellis-*` skills) |
37
+ | DeepSeek Harness | `.agents/skills/`, `.dsh/skills/` (entry skills load by bare `trellis-*` names; role prompts use `trellis-agent-*`) |
37
38
 
38
39
  In a user project, use the files actually generated by init as authoritative.
39
40
 
@@ -11,7 +11,7 @@ It is intentionally a **capability skill, not a workflow**. There is no fixed ou
11
11
 
12
12
  ## What `trellis mem` is
13
13
 
14
- A local CLI that indexes the user's past Claude Code, Codex, Pi Agent, and ZCode conversation logs and lets you list, search, slice by Trellis task boundaries, and dump cleaned dialogue from them. Claude and Codex use `~/.claude/projects/` and `~/.codex/sessions/`. Pi uses its default or environment-configured session root, global `~/.pi/agent/settings.json`, and the scoped project's `.pi/settings.json`; relative `sessionDir` values resolve from the settings file directory. Project-local Pi settings require project-scoped lookup through the current cwd or `--cwd`. ZCode uses `~/.zcode/cli/db/db.sqlite`. OpenCode logs are not yet indexable (provider adapter pending) — when an OpenCode session is the obvious target, surface that limitation rather than guessing.
14
+ A local CLI that indexes the user's past Claude Code, Codex, Devin CLI, Grok, OpenCode, Pi Agent, and ZCode conversation logs and lets you list, search, slice by Trellis task boundaries, and dump cleaned dialogue from them. Claude and Codex use `~/.claude/projects/` and `~/.codex/sessions/`. Devin CLI (Cognition terminal agent, not `trellis init --devin` Desktop) uses `~/.local/share/devin/cli/sessions.db`. Grok uses `~/.grok/sessions/`. OpenCode uses `~/.local/share/opencode/opencode.db` (zero-dependency SQLite reader). Pi uses its default or environment-configured session root, global `~/.pi/agent/settings.json`, and the scoped project's `.pi/settings.json`; relative `sessionDir` values resolve from the settings file directory. Project-local Pi settings require project-scoped lookup through the current cwd or `--cwd`. ZCode uses `~/.zcode/cli/db/db.sqlite`.
15
15
 
16
16
  Nothing in `mem` is uploaded. All reads are local.
17
17
 
@@ -68,7 +68,7 @@ trellis mem list --cwd <project-path>
68
68
  trellis mem projects # → list active project cwds, then narrow
69
69
  ```
70
70
 
71
- Phase slicing (`--phase brainstorm|implement|all`) cuts the session at `task.py create` and `task.py start` boundaries. For a finish-work review of the current task, `--phase brainstorm` recovers the planning discussion and `--phase implement` recovers the execution loop. Default is `all`.
71
+ Phase slicing (`--phase brainstorm|implement|all`) cuts the session at `task.py create`/`replan` and `task.py start` boundaries. For a finish-work review of the current task, `--phase brainstorm` recovers the planning discussion and `--phase implement` recovers the execution loop. Default is `all`.
72
72
 
73
73
  ## Triggering patterns
74
74
 
@@ -16,14 +16,14 @@ Full flag reference for the five subcommands. Pin this as the authoritative sour
16
16
 
17
17
  | Flag | Subcommands | Meaning |
18
18
  | --------------------------------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
19
- | `--platform claude\|codex\|opencode\|pi\|all` | all | Default `all`. OpenCode adapter is currently a stub on `0.6.0-beta.*` — see "Caveats" below. |
19
+ | `--platform claude\|codex\|devin\|grok\|opencode\|pi\|zcode\|all` | all | Default `all`. `devin` is Cognition Devin CLI (`sessions.db`), not `trellis init --devin` (Desktop). |
20
20
  | `--since YYYY-MM-DD` | list / search | Inclusive lower date bound. |
21
21
  | `--until YYYY-MM-DD` | list / search | Inclusive upper date bound. |
22
22
  | `--global` | list / search | Include sessions from every project on this machine. Default is the current project `cwd`. |
23
23
  | `--cwd <path>` | list / search | Force a specific project cwd instead of inferring from where you are. |
24
24
  | `--limit N` | list / search | Cap output rows. Default `50`. |
25
25
  | `--grep KW` | extract / context | Filter turns by keyword. Multi-token AND when whitespace-separated. |
26
- | `--phase brainstorm\|implement\|all` | extract | Slice session by Trellis task boundaries. `brainstorm` = `[task.py create, task.py start)`. `implement` = turns outside brainstorm windows. Default `all`. |
26
+ | `--phase brainstorm\|implement\|all` | extract | Slice session by Trellis task boundaries. `brainstorm` = `[task.py create/replan, task.py start)`. `implement` = turns outside brainstorm windows. Default `all`. |
27
27
  | `--turns N` | context | Number of hit turns to return. Default `3`. |
28
28
  | `--around N` | context | Surrounding turns to include per hit. Default `1`. |
29
29
  | `--max-chars N` | context | Total character budget. Default `6000` (~1500 tokens). |
@@ -56,6 +56,7 @@ trellis mem projects
56
56
  ## Caveats
57
57
 
58
58
  - **OpenCode adapter is a stub on `0.6.0-beta.*`.** When `--platform` resolves to OpenCode (or `all` and OpenCode would be included), `mem` prints a one-line "reader unavailable" notice and continues with the other platforms. Don't promise OpenCode coverage in your reply until the adapter ships.
59
+ - **`--platform devin` is Cognition Devin CLI** (`~/.local/share/devin/cli/sessions.db`). It is not `trellis init --devin` (Devin Desktop / Cascade) and not Factory Droid.
59
60
  - **`--phase` slicing depends on `task.py create` / `task.py start` invocations appearing in the recorded bash calls of the session.** Sessions where the user ran `task.py` from a different terminal — outside the recorded AI loop — will not have phase boundaries. `--phase all` is the safe fallback.
60
61
  - **`mem` indexes platform JSONL files directly.** If the user has cleared their Claude / Codex / Pi session storage, `mem` cannot recover what is no longer on disk.
61
62
  - **`mem` is read-only.** No remote sync, no edits to platform JSONL. Any write you do based on `mem` findings is your own follow-up call into the editing tools available to you.
@@ -24,11 +24,13 @@ Shows the Phase Index (Plan / Execute / Finish) with routing + skill mapping.
24
24
 
25
25
  `get_context.py` shows the active task's `status` field. Route by `status` + artifact presence. This command replaces the user needing to remember the Trellis flow; it does not itself approve implementation.
26
26
 
27
- - `status=planning` + `task.json.meta.delivery_mode = "analysis_only"` → complete the PRD's bounded evidence work, verify its acceptance criteria and no-change boundary, then commit task artifacts and archive directly. Do not run `task.py start`; a protected-target change requires a separate change-bearing task.
27
+ - `status=planning` + `task.json.meta.delivery_mode = "analysis_only"` → first confirm the task still satisfies the bounded evidence-only eligibility rule; then complete the PRD's evidence work, verify its acceptance criteria and no-change boundary, and archive directly. Do not run `task.py start`; a protected-target change requires a separate change-bearing task.
28
28
  - `status=planning` + no `prd.md` → **1.1** (load `trellis-brainstorm`)
29
+ - `status=planning` + a recorded `decision-needed` or unsealed decision chain → return to the planning frontier and load `pennix-decision-gates` when independent material questions can be batched.
30
+ - `status=in_progress` + a material unresolved decision → record the reason and run `task.py replan <task> "<reason>"`; do not ask a native question during implementation.
29
31
  - `status=planning` + `prd.md` only → decide whether the task is lightweight or complex. Lightweight can move to **1.4** review; complex returns to **1.1** to add `design.md` + `implement.md`.
30
32
  - `status=planning` + complex artifacts complete + sub-agent jsonl not curated (empty, or only a legacy `_example` placeholder row) → **1.3**
31
- - `status=planning` + required artifacts complete + required jsonl curated or inline mode → **1.4** (ask for start review; only run `task.py start` after user confirms)
33
+ - `status=planning` + required artifacts complete + required jsonl curated or inline mode → run the Planning Seal closure pass, then **1.4** (ask for start review; only run `task.py start` after user confirms)
32
34
  - `status=in_progress` + implementation not started → **2.1**
33
35
  - `status=in_progress` + implementation done, not yet checked → **2.2**
34
36
  - `status=in_progress` + check passed → **3.3** (spec update) → **3.4** (commit)
@@ -6,12 +6,14 @@ A request to build, implement, fix, refactor, or "go ahead" is not approval to l
6
6
 
7
7
  For every non-trivial task, the user must respond at least once after the initial request before implementation begins. If no clarification is needed, that response must approve the final planning summary described below.
8
8
 
9
- While any user-owned product, scope, UX, compatibility, risk, or acceptance decision remains unresolved, end the turn with exactly one highest-value question. Do not edit product code, dispatch implementation, or run `task.py start`.
9
+ While any user-owned product, scope, UX, compatibility, risk, or acceptance decision remains unresolved, keep the task in planning. First inventory evidence and decision dependencies. If at least two independent material decisions remain and `pennix-decision-gates` is available, delegate one bounded batch of up to three frontier questions; otherwise ask the single highest-value question. Do not edit product code, dispatch implementation, or run `task.py start` until the decision chain is sealed.
10
10
 
11
11
  ## Analysis-Only Exception
12
12
 
13
13
  When `task.json.meta.delivery_mode = "analysis_only"` exactly and the PRD names a bounded evidence deliverable plus a no-change boundary for product source, runtime configuration, deployment, credentials, and external systems, task-creation consent authorizes that evidence work. Do not require a second planning approval or run `task.py start`: perform the declared research, audit, or design work while status remains `planning`, record the evidence, verify acceptance criteria and the boundary, commit task artifacts, and archive directly. If the evidence recommends a protected-target change, record it and create a separate change-bearing task before doing it.
14
14
 
15
+ This exception is eligible only for a bounded evidence deliverable with no material user decision, design or implementation plan, cross-owner coordination, security or deployment change, release or credential action, or protected downstream task. Calling work "research", deferring source edits, or working in an audit/root repository does not make it analysis-only. If any of those conditions apply, use the normal complex planning and implementation-approval path.
16
+
15
17
  All other tasks follow the planning and implementation approval gates below.
16
18
 
17
19
  ## Non-Negotiable Evidence Rule
@@ -24,6 +26,10 @@ Do not ask the user to confirm facts that the repository can answer. Ask only fo
24
26
 
25
27
  Repository evidence establishes current behavior and technical constraints. The user's intended behavior, feature scope boundaries, and UX preferences are never answerable by repository evidence alone, even when an existing pattern exists; existing patterns are options and recommendation evidence, not decisions.
26
28
 
29
+ ## Evidence Units For Read-Heavy Work
30
+
31
+ When research, audit, review, or investigation is too large to leave one independently useful conclusion in the current bounded session, split it into evidence units. Each unit must have one question or scope, a minimal evidence range, a destination artifact, and a stop condition; write its facts, conclusion or blocker, unknowns, and recovery point before starting another unit. Size units so one normal context window can finish and persist one useful result; do not promise an exact token or time limit. Routine navigation and transient tool output do not need an artifact. Create a child task only when the unit has an independent owner, lifecycle, and acceptance contract.
32
+
27
33
  ---
28
34
 
29
35
  Use this skill during Phase 1 planning to turn the user's request into clear requirements and planning artifacts.
@@ -54,18 +60,18 @@ Use a concise title from the user's request. Both the title and `--description`
54
60
  - product intent still needed from the user
55
61
  - scope or risk decisions still needed from the user
56
62
  - likely out-of-scope items
57
- 4. If a user-owned decision remains, ask the single highest-value question, include your recommendation and trade-off, then stop. Do not perform implementation work in the same turn.
58
- 5. After each user answer, update `prd.md`, recompute the decision inventory, and repeat from step 2.
63
+ 4. If user-owned decisions remain, calculate the independent frontier. Use `pennix-decision-gates` for a bounded batch when two or more independent material decisions are ready; otherwise ask the single highest-value question. Include recommendation and trade-off. Yield only while the answer is unavailable.
64
+ 5. When the host returns the current continuation's answer, immediately persist it in `prd.md` or the decision artifact, recheck evidence and conflicts, recalculate the frontier, and continue the same planning loop. Do not create a second Trellis lifecycle for the same decision chain. Stop only for a new unresolved frontier, a real capability or authority block, or a final sealed summary awaiting implementation approval.
59
65
  6. When no user-owned decision remains, create or update `design.md` and `implement.md` for complex tasks.
60
- 7. Run the requirement convergence gate, then the PRD convergence pass.
66
+ 7. Run the requirement convergence gate, then the PRD convergence pass. Finish with one Planning Seal closure pass.
61
67
  8. Present the final planning summary and stop. Do not run `task.py start` or edit product code in the same turn.
62
- 9. Only a subsequent user message that explicitly approves the latest planning summary authorizes `task.py start` and implementation. If the artifacts change materially after approval, repeat the final review.
68
+ 9. Only a subsequent user message that explicitly approves the latest planning summary authorizes `task.py start` and implementation. If implementation reveals a material unresolved decision, record `decision-needed`, run `task.py replan <task> "<reason>"`, and return through this planning flow; do not open a popup during implementation.
63
69
 
64
70
  Do not invent a project-specific product/spec hierarchy. If the repository already has product, domain, or spec docs, use them. If it does not, proceed with the evidence that exists.
65
71
 
66
72
  ## Question Rules
67
73
 
68
- Ask only one question per message.
74
+ Ask one bounded batch per message: include up to three independent material frontier questions. Ask exactly one question only when it is the sole remaining material decision or later decisions depend on its answer.
69
75
 
70
76
  Each question must include:
71
77
 
@@ -140,6 +146,8 @@ Lightweight tasks may omit `design.md` and `implement.md`; they may not skip evi
140
146
 
141
147
  The final planning summary must show Goal, In Scope, Out of Scope, Acceptance Criteria, Key Decisions, relevant Risks or Deferred Items, and artifact status.
142
148
 
149
+ The Planning Seal closure pass must reconcile `task.json`, `prd.md`, `design.md`, `implement.md`, research, decision records, and manifests; verify the actual modification targets and branches, ordered dependencies and release steps, validation and rollback, dynamic-fact dispositions and replan triggers, and that every material decision has an owner and a fixed outcome. Remove static ambiguity before implementation: no `TBD`, `TODO`, `decision-needed`, unowned option, unspecified branch, open implementation path, validation gap, or conditional acceptance may remain. A material discovery invalidates the seal and returns to planning; implementation may consume only a sealed plan.
150
+
143
151
  ## Artifact Rules
144
152
 
145
153
  `prd.md` records requirements and acceptance:
@@ -452,6 +452,25 @@ def _strip_breadcrumb_tag_blocks(content: str) -> str:
452
452
  return re.sub(r"\n{3,}", "\n\n", stripped).strip()
453
453
 
454
454
 
455
+ def _resolve_workflow_md(root: Path, input_data: dict) -> Path:
456
+ """Resolve the active task's workflow file, falling back to the global one.
457
+
458
+ The per-task resolution rule lives in common.workflow_selection inside
459
+ .trellis/scripts. Older installed projects may not ship that module, and
460
+ hooks must never crash the session — ANY failure (import error, old
461
+ scripts tree, resolver bug) falls back to the global workflow.md.
462
+ """
463
+ try:
464
+ scripts_dir = root / ".trellis" / "scripts"
465
+ if str(scripts_dir) not in sys.path:
466
+ sys.path.insert(0, str(scripts_dir))
467
+ from common.workflow_selection import resolve_workflow_md # type: ignore[import-not-found]
468
+
469
+ return resolve_workflow_md(root, input_data, platform="copilot")
470
+ except Exception:
471
+ return root / ".trellis" / "workflow.md"
472
+
473
+
455
474
  def _build_workflow_toc(workflow_path: Path) -> str:
456
475
  """Inject only the compact Phase Index summary for SessionStart."""
457
476
  content = read_file(workflow_path)
@@ -503,7 +522,7 @@ Trellis compact SessionStart context. Use it to orient the session; load details
503
522
  output.write("\n</current-state>\n\n")
504
523
 
505
524
  output.write("<trellis-workflow>\n")
506
- output.write(_build_workflow_toc(trellis_dir / "workflow.md"))
525
+ output.write(_build_workflow_toc(_resolve_workflow_md(project_dir, hook_input)))
507
526
  output.write("\n</trellis-workflow>\n\n")
508
527
 
509
528
  output.write("<guidelines>\n")
@@ -10,7 +10,11 @@ A request to build, implement, fix, refactor, or "go ahead" is not approval to l
10
10
 
11
11
  For every non-trivial task, the user must respond at least once after the initial request before implementation begins. If no clarification is needed, that response must approve the final planning summary described below.
12
12
 
13
- While any user-owned product, scope, UX, compatibility, risk, or acceptance decision remains unresolved, end the turn with exactly one highest-value question. Do not edit product code, dispatch implementation, or run `task.py start`.
13
+ While any user-owned product, scope, UX, compatibility, risk, or acceptance decision remains unresolved, keep the task in planning. First inventory evidence and decision dependencies. If at least two independent material decisions remain and `pennix-decision-gates` is available, delegate one bounded batch of up to three frontier questions; otherwise ask the single highest-value question. Do not edit product code, dispatch implementation, or run `task.py start` until the decision chain is sealed.
14
+
15
+ ## Analysis-Only Exception
16
+
17
+ When `task.json.meta.delivery_mode = "analysis_only"` exactly and the PRD names a bounded evidence deliverable plus a no-change boundary for product source, runtime configuration, deployment, credentials, and external systems, task-creation consent authorizes that evidence work. Keep status `planning`, record and verify the evidence, commit task artifacts, and archive directly; do not run `task.py start` or wait for a second implementation approval. This exception is eligible only when there is no material user decision, design or implementation plan, cross-owner coordination, security or deployment change, release or credential action, or protected downstream task. Otherwise use normal complex planning.
14
18
 
15
19
  ## Non-Negotiable Evidence Rule
16
20
 
@@ -22,6 +26,10 @@ Do not ask the user to confirm facts that the repository can answer. Ask only fo
22
26
 
23
27
  Repository evidence establishes current behavior and technical constraints. The user's intended behavior, feature scope boundaries, and UX preferences are never answerable by repository evidence alone, even when an existing pattern exists; existing patterns are options and recommendation evidence, not decisions.
24
28
 
29
+ ## Evidence Units For Read-Heavy Work
30
+
31
+ When research, audit, review, or investigation is too large for one independently useful conclusion in the current session, split it into evidence units. Each unit has one question or scope, a minimal evidence range, a destination artifact, and a stop condition; persist facts, conclusion or blocker, unknowns, and a recovery point before starting another unit. Size each unit for one normal context window without promising an exact token or time limit.
32
+
25
33
  ---
26
34
 
27
35
  Use this skill during Phase 1 planning to turn the user's request into clear requirements and planning artifacts.
@@ -52,18 +60,18 @@ Use a concise title from the user's request. Both the title and `--description`
52
60
  - product intent still needed from the user
53
61
  - scope or risk decisions still needed from the user
54
62
  - likely out-of-scope items
55
- 4. If a user-owned decision remains, ask the single highest-value question, include your recommendation and trade-off, then stop. Do not perform implementation work in the same turn.
56
- 5. After each user answer, update `prd.md`, recompute the decision inventory, and repeat from step 2.
63
+ 4. If user-owned decisions remain, calculate the independent frontier. Use `pennix-decision-gates` for a bounded batch when two or more independent material decisions are ready; otherwise ask the single highest-value question. Include recommendation and trade-off. Yield only while the answer is unavailable.
64
+ 5. When the host returns the current continuation's answer, persist it in `prd.md` or the decision artifact, recheck evidence and conflicts, recalculate the frontier, and continue the same planning loop. Stop only for a new unresolved frontier, a real capability or authority block, or a final sealed summary awaiting implementation approval.
57
65
  6. When no user-owned decision remains, create or update `design.md` and `implement.md` for complex tasks.
58
- 7. Run the requirement convergence gate, then the PRD convergence pass.
66
+ 7. Run the requirement convergence gate, then the PRD convergence pass. Finish with one Planning Seal closure pass.
59
67
  8. Present the final planning summary and stop. Do not run `task.py start` or edit product code in the same turn.
60
- 9. Only a subsequent user message that explicitly approves the latest planning summary authorizes `task.py start` and implementation. If the artifacts change materially after approval, repeat the final review.
68
+ 9. Only a subsequent user message that explicitly approves the latest planning summary authorizes `task.py start` and implementation. If implementation reveals a material unresolved decision, record `decision-needed`, run `task.py replan <task> "<reason>"`, and return through this planning flow; do not open a popup during implementation.
61
69
 
62
70
  Do not invent a project-specific product/spec hierarchy. If the repository already has product, domain, or spec docs, use them. If it does not, proceed with the evidence that exists.
63
71
 
64
72
  ## Question Rules
65
73
 
66
- Ask only one question per message.
74
+ Ask one bounded batch per message: include up to three independent material frontier questions. Ask exactly one question only when it is the sole remaining material decision or later decisions depend on its answer.
67
75
 
68
76
  Each question must include:
69
77
 
@@ -95,6 +103,8 @@ Lightweight tasks may omit `design.md` and `implement.md`; they may not skip evi
95
103
 
96
104
  The final planning summary must show Goal, In Scope, Out of Scope, Acceptance Criteria, Key Decisions, relevant Risks or Deferred Items, and artifact status.
97
105
 
106
+ The Planning Seal closure pass reconciles `task.json`, `prd.md`, `design.md`, `implement.md`, research, decision records, and manifests; verifies targets, branches, dependencies, release, validation, rollback, dynamic-fact dispositions, and replan triggers; and fixes every material decision to an owner and outcome. No `TBD`, `TODO`, `decision-needed`, unowned option, unspecified branch, open implementation path, validation gap, or conditional acceptance may remain. Any material discovery invalidates the seal and returns to planning.
107
+
98
108
  ## Artifact Rules
99
109
 
100
110
  `prd.md` records requirements and acceptance:
@@ -1,15 +1,17 @@
1
1
  # Trellis on DeepSeek Harness (dsh)
2
2
 
3
- dsh is a **class-2 pull-based** Trellis host: no session-start hook auto-injects
4
- workflow context, so the agent loads the Trellis skills on demand through its
5
- skill-loader tool.
3
+ dsh is a **class-2 pull-based** Trellis host. It discovers Trellis skills from
4
+ the project, uses native continuable sub-agents for isolated implementation and
5
+ review roles, and exposes a stable `DSH_SESSION_ID` to every managed shell.
6
6
 
7
- | Capability | Status |
8
- | --- | --- |
9
- | Skills (`.agents/skills/trellis-*/SKILL.md`) | Works — dsh discovers this shared root natively |
10
- | Entry skills (`.dsh/skills/trellis-*/SKILL.md`) | Works — dsh's own project skill root (highest rank) |
11
- | Context hooks | None — pull-based: skills read `.trellis/` files directly |
12
- | Sub-agents | None shipped — implement/check/research run inline via the workflow skills |
7
+ | Capability | Without companion plugin | With `dsh-trellis` |
8
+ | --- | --- | --- |
9
+ | Shared and entry skills | Works | Works |
10
+ | Session-scoped active task | Works through verified `DSH_SHELL=1` + `DSH_SESSION_ID`, including nested launches | Managed per-execution identity can forward a distinct child session |
11
+ | Implement/check/research roles | Foreground native sub-agent | Background native sub-agent |
12
+ | Per-turn workflow breadcrumb | Not available | Injected from `workflow.md` |
13
+ | Event-driven child wait | Not available | `trellis_wait` |
14
+ | Utility commands | Not available | `/trellis-status`, `/trellis-finish` |
13
15
 
14
16
  ## Quick start
15
17
 
@@ -20,37 +22,59 @@ dsh web # or: dsh --profile headless "start a Trellis task for ..."
20
22
 
21
23
  In dsh:
22
24
 
23
- 1. Open a session in the project root and describe the work in natural
24
- language. For a new task the agent should load the `trellis-start` skill,
25
- which reads the current task state from `.trellis/` and routes to
26
- `trellis-brainstorm` (unclear requirements), `trellis-before-dev` (about to
27
- write code), `trellis-check` (done coding), or `trellis-update-spec`
28
- (learned something worth capturing).
29
- 2. Entry skills are `trellis-start` / `trellis-continue` / `trellis-finish-work`
30
- in `.dsh/skills/`. You can also ask for them by name at any time.
31
- 3. Type `/trellis:finish-work` is a slash-command convention from other hosts —
32
- dsh has no slash palette, so say "finish the trellis task" instead, and the
33
- agent loads `trellis-finish-work`.
25
+ 1. Describe the work in natural language and load `trellis-start` when a
26
+ session needs explicit Trellis bootstrap.
27
+ 2. The main session dispatches `trellis-agent-research`,
28
+ `trellis-agent-implement`, and `trellis-agent-check` through DSH's native
29
+ `subagent` tool. Each child loads exactly one matching role skill.
30
+ 3. Finish through `trellis-finish-work`, which preserves the required order:
31
+ commit, archive, then journal.
32
+
33
+ ## Companion plugin fallback contract
34
+
35
+ The Trellis adapter does not install a DSH profile plugin. Before dispatching a
36
+ role, check whether the `trellis_wait` tool is available:
37
+
38
+ - If available, use DSH's default continuable background mode, continue
39
+ independent work, then call `trellis_wait` once per dependent child id and
40
+ consume each native settlement notice before entering the dependent gate.
41
+ - If unavailable, dispatch every child with `run_in_background: false` from the outset
42
+ so the dependent workflow gate cannot overtake it.
43
+
44
+ Never replace either path with shell sleep, polling loops, `job_output`, or
45
+ repeated agent-list polling.
46
+
47
+ ## Nested host sessions
48
+
49
+ DSH inherits ordinary environment variables from the process that launches it.
50
+ If that outer process is already an active Trellis session,
51
+ `TRELLIS_CONTEXT_ID` would otherwise override the inner `DSH_SESSION_ID`.
52
+ DSH rebuilds its complete `DSH_*` namespace for each managed shell, so the beta
53
+ adapter treats `DSH_SHELL=1` together with `DSH_SESSION_ID` as the current DSH
54
+ identity and resolves it before an inherited generic override, even without the
55
+ plugin. The optional plugin additionally contributes a trusted
56
+ `DSH_TRELLIS_CONTEXT_ID` when it must forward a child identity that differs
57
+ from the shell's own session id.
34
58
 
35
59
  ## File map
36
60
 
37
- - `.agents/skills/` — auto-triggered workflow skills (`trellis-before-dev`,
38
- `trellis-brainstorm`, `trellis-check`, `trellis-break-loop`,
39
- `trellis-update-spec`) plus the bundled `trellis-meta` /
40
- `trellis-spec-bootstrap` / `trellis-session-insight` skills. Byte-identical
41
- to Codex / Gemini CLI / Pi / Kimi writes into the same shared root.
42
- - `.dsh/skills/` — dsh-private entry skills (`trellis-start` /
43
- `trellis-continue` / `trellis-finish-work`).
44
- - `.trellis/` — specs, tasks, workspace memory, and the shared scripts the
45
- skills invoke (`get_context.py`, `task.py`, ...).
61
+ - `.agents/skills/` — shared workflow and bundled skills, byte-identical to
62
+ the other Agent Skills writers.
63
+ - `.dsh/skills/trellis-{start,continue,finish-work}/` — DSH-private entry
64
+ skills.
65
+ - `.dsh/skills/trellis-agent-{research,implement,check}/` — child-only role
66
+ skills; implement/check include the pull-based task context prelude.
67
+ - `.dsh/DSH.md` — this operator guide.
68
+ - `.trellis/` — workflow, specs, tasks, workspace journal, and shared scripts.
46
69
 
47
70
  ## Notes
48
71
 
49
- - Skill scripts pass `--platform dsh` to `get_context.py`; the value is used
50
- as a platform-scoped context key.
51
- - The shipped `minimal` agent preset composes only `bash` +
52
- `str_replace_editor`; the default presets include `web_search` and the
53
- filesystem/terminal tools the skills assume.
54
- - dsh has no project-level sub-agent definition surface, so Trellis ships no
55
- `trellis-implement` / `trellis-check` / `trellis-research` agent prompts
56
- here — the workflow skills run those phases inline in the main session.
72
+ - Generated Python commands use `python3` in source templates and are rendered
73
+ to the detected Windows launcher during `trellis init` / `trellis update`.
74
+ - Role dispatch prompts start with `Active task: <task path>`. This exact task
75
+ path is the child's primary context source; children must not guess globally.
76
+ - Each `dsh --profile headless` invocation creates a fresh DSH session. Do not
77
+ expect an active-task pointer to persist across separate headless calls; keep
78
+ the workflow in one session or explicitly resume its returned session id.
79
+ - The optional companion plugin is maintained separately at
80
+ <https://github.com/SajoLuo/dsh-trellis>.
@@ -0,0 +1,99 @@
1
+ ---
2
+ name: trellis-check
3
+ user-invocable: false
4
+ description: |
5
+ Child-agent-only quality role for Trellis. Main sessions must not load this
6
+ skill directly. Reviews code changes against specs and self-fixes issues.
7
+ ---
8
+ # Check Agent
9
+
10
+ You are the Check Agent in the Trellis workflow.
11
+
12
+ ## Recursion Guard
13
+
14
+ You are already the `trellis-check` sub-agent that the main session dispatched. Do the review and fixes directly.
15
+
16
+ - Do NOT spawn another `trellis-check` or `trellis-implement` sub-agent.
17
+ - If workflow.md, workflow-state breadcrumbs, or the parent prompt say to dispatch `trellis-implement` / `trellis-check`, treat that as a main-session instruction that is already satisfied by your current role.
18
+ - Only the main session may dispatch Trellis implement/check agents. If more implementation work is needed, report that recommendation instead of spawning.
19
+
20
+ dsh does not auto-inject SessionStart task context. Always pull context as required below.
21
+
22
+ ## Context
23
+
24
+ Before checking, read:
25
+ - `.trellis/spec/` - Development guidelines
26
+ - Pre-commit checklist for quality standards
27
+
28
+ ## Core Responsibilities
29
+
30
+ 1. **Get code changes** - Use git diff to get uncommitted code
31
+ 2. **Check against specs** - Verify code follows guidelines
32
+ 3. **Self-fix** - Fix issues yourself, not just report them
33
+ 4. **Run verification** - typecheck and lint
34
+
35
+ ## Important
36
+
37
+ **Fix issues yourself**, don't just report them.
38
+
39
+ You have write and edit tools, you can modify code directly.
40
+
41
+ ---
42
+
43
+ ## Workflow
44
+
45
+ ### Step 1: Get Changes
46
+
47
+ ```bash
48
+ git diff --name-only # List changed files
49
+ git diff # View specific changes
50
+ ```
51
+
52
+ ### Step 2: Check Against Specs
53
+
54
+ Read relevant specs in `.trellis/spec/` to check code:
55
+
56
+ - Does it follow directory structure conventions
57
+ - Does it follow naming conventions
58
+ - Does it follow code patterns
59
+ - Are there missing types
60
+ - Are there potential bugs
61
+
62
+ ### Step 3: Self-Fix
63
+
64
+ After finding issues:
65
+
66
+ 1. Fix the issue directly (use edit tool)
67
+ 2. Record what was fixed
68
+ 3. Continue checking other issues
69
+
70
+ ### Step 4: Run Verification
71
+
72
+ Run project's lint and typecheck commands to verify changes.
73
+
74
+ If failed, fix issues and re-run.
75
+
76
+ If a required command cannot run, is skipped, or still exits non-zero, report
77
+ the quality gate as **blocked** or **failed**. Never label it passed, weaken or
78
+ rewrite acceptance criteria, or substitute an easier command just to advance
79
+ the workflow.
80
+
81
+ ---
82
+
83
+ ## Report Format
84
+
85
+ ```markdown
86
+ ## Self-Check Complete
87
+
88
+ ### Files Checked
89
+
90
+ - list changed files
91
+
92
+ ### Issues Fixed
93
+
94
+ - what you fixed
95
+
96
+ ### Verification
97
+
98
+ - Lint / typecheck results
99
+ ```
@@ -0,0 +1,106 @@
1
+ ---
2
+ name: trellis-implement
3
+ user-invocable: false
4
+ description: |
5
+ Child-agent-only implementation role for Trellis. Main sessions must not
6
+ load this skill directly. Understands specs and requirements, then
7
+ implements features. No git commit allowed.
8
+ ---
9
+ # Implement Agent
10
+
11
+ You are the Implement Agent in the Trellis workflow.
12
+
13
+ ## Recursion Guard
14
+
15
+ You are already the `trellis-implement` sub-agent that the main session dispatched. Do the implementation work directly.
16
+
17
+ - Do NOT spawn another `trellis-implement` or `trellis-check` sub-agent.
18
+ - If workflow.md, workflow-state breadcrumbs, or the parent prompt say to dispatch `trellis-implement` / `trellis-check`, treat that as a main-session instruction that is already satisfied by your current role.
19
+ - Only the main session may dispatch Trellis implement/check agents. If more parallel work is needed, report that recommendation instead of spawning.
20
+
21
+ dsh does not auto-inject SessionStart task context. Always pull context as required below.
22
+
23
+ ## Context
24
+
25
+ Before implementing, read:
26
+ - `.trellis/workflow.md` - Project workflow
27
+ - `.trellis/spec/` - Development guidelines
28
+ - Task `prd.md` - Requirements document
29
+ - Task `design.md` / `implement.md` if present
30
+
31
+ ## Core Responsibilities
32
+
33
+ 1. **Understand specs** - Read relevant spec files in `.trellis/spec/`
34
+ 2. **Understand requirements** - Read prd.md and design/implement artifacts
35
+ 3. **Implement features** - Write code following specs and design
36
+ 4. **Self-check** - Ensure code quality
37
+ 5. **Report results** - Report completion status
38
+
39
+ ## Forbidden Operations
40
+
41
+ **Do NOT execute these git commands:**
42
+
43
+ - `git commit`
44
+ - `git push`
45
+ - `git merge`
46
+
47
+ ---
48
+
49
+ ## Workflow
50
+
51
+ ### 1. Understand Specs
52
+
53
+ Read relevant specs based on task type:
54
+
55
+ - Spec layers: `.trellis/spec/<package>/<layer>/`
56
+ - Shared guides: `.trellis/spec/guides/`
57
+
58
+ ### 2. Understand Requirements
59
+
60
+ Read the task's prd.md and design/implement files:
61
+
62
+ - What are the core requirements
63
+ - Key points of technical design
64
+ - Which files to modify/create
65
+
66
+ ### 3. Implement Features
67
+
68
+ - Write code following specs and technical design
69
+ - Follow existing code patterns
70
+ - Only do what's required, no over-engineering
71
+
72
+ ### 4. Verify
73
+
74
+ Run project's lint and typecheck commands to verify changes.
75
+
76
+ ---
77
+
78
+ ## Report Format
79
+
80
+ ```markdown
81
+ ## Implementation Complete
82
+
83
+ ### Files Modified
84
+
85
+ - `src/components/Feature.tsx` - New component
86
+ - `src/hooks/useFeature.ts` - New hook
87
+
88
+ ### Implementation Summary
89
+
90
+ 1. Created Feature component...
91
+ 2. Added useFeature hook...
92
+
93
+ ### Verification Results
94
+
95
+ - Lint: Passed
96
+ - TypeCheck: Passed
97
+ ```
98
+
99
+ ---
100
+
101
+ ## Code Standards
102
+
103
+ - Follow existing code patterns
104
+ - Don't add unnecessary abstractions
105
+ - Only do what's required, no over-engineering
106
+ - Keep code readable