From 379c08c13093dff68cc04d44cec33601a5d4fca6 Mon Sep 17 00:00:00 2001 From: ConScholar Date: Thu, 23 Apr 2026 15:26:27 -0700 Subject: [PATCH] Add aidd-phase-list skill, phase-lists, and /aidd-phase-list command Import from wolfgames/aidd-create-game (runePhase), excluding wolf-prompt-to-play. Regenerate ai index files. Document Node createHash('sha3-256') in aidd-timing-safe-compare so review tests match the intended pattern. Made-with: Cursor --- ai/commands/aidd-phase-list.md | 15 ++ ai/commands/index.md | 6 + ai/index.md | 4 + ai/phase-lists/README.md | 51 +++++ ai/phase-lists/context/10-define-context.md | 5 + ai/phase-lists/context/11-banana.md | 5 + ai/phase-lists/context/12-monkey.md | 5 + ai/phase-lists/context/13-fruit-loops.md | 5 + ai/phase-lists/context/index.md | 30 +++ ai/phase-lists/context/pack.json | 4 + ai/phase-lists/index.md | 22 +++ ai/phase-lists/onboarding/10-welcome.md | 5 + ai/phase-lists/onboarding/15-subagentTest.md | 3 + .../onboarding/20-run-context-sublist.md | 15 ++ ai/phase-lists/onboarding/index.md | 24 +++ ai/skills/aidd-phase-list/SKILL.md | 182 ++++++++++++++++++ ai/skills/aidd-timing-safe-compare/SKILL.md | 2 +- ai/skills/index.md | 1 + 18 files changed, 383 insertions(+), 1 deletion(-) create mode 100644 ai/commands/aidd-phase-list.md create mode 100644 ai/phase-lists/README.md create mode 100644 ai/phase-lists/context/10-define-context.md create mode 100644 ai/phase-lists/context/11-banana.md create mode 100644 ai/phase-lists/context/12-monkey.md create mode 100644 ai/phase-lists/context/13-fruit-loops.md create mode 100644 ai/phase-lists/context/index.md create mode 100644 ai/phase-lists/context/pack.json create mode 100644 ai/phase-lists/index.md create mode 100644 ai/phase-lists/onboarding/10-welcome.md create mode 100644 ai/phase-lists/onboarding/15-subagentTest.md create mode 100644 ai/phase-lists/onboarding/20-run-context-sublist.md create mode 100644 ai/phase-lists/onboarding/index.md create mode 100644 ai/skills/aidd-phase-list/SKILL.md diff --git a/ai/commands/aidd-phase-list.md b/ai/commands/aidd-phase-list.md new file mode 100644 index 0000000..028780e --- /dev/null +++ b/ai/commands/aidd-phase-list.md @@ -0,0 +1,15 @@ +--- +description: Run a folder-based phase list (sequenced *.md phases) with optional nested delegation +--- +# /aidd-phase-list + +Load and execute the skill at `ai/skills/aidd-phase-list/SKILL.md`. + +Run: `/aidd-phase-list --list [--depth N] [--ancestor-paths p:p:...] [-debug]` + +The `--list` directory is required (folder of `*.md` phase files under e.g. `ai/phase-lists//`). See [ai/phase-lists/README.md](../phase-lists/README.md). + +Constraints { + Before beginning, read and respect the constraints in /aidd-please. + Nested lists: without -debug, only the subagent that receives a delegation phase file runs the full nested /aidd-phase-list on the child directory and emits d=parent+1 progress through run finished; the depth-D parent must not inline that child run. See ai/skills/aidd-phase-list/SKILL.md (Runner laws). +} diff --git a/ai/commands/index.md b/ai/commands/index.md index db8fe6c..c104f3a 100644 --- a/ai/commands/index.md +++ b/ai/commands/index.md @@ -22,6 +22,12 @@ Rank files by hotspot score to identify prime candidates for refactoring before Generate /aidd-fix delegation prompts for a list of tasks and optionally dispatch them to sub-agents in dependency order +### /aidd-phase-list + +**File:** `aidd-phase-list.md` + +Run a folder-based phase list (sequenced *.md phases) with optional nested delegation + ### 🔗 /aidd-pipeline **File:** `aidd-pipeline.md` diff --git a/ai/index.md b/ai/index.md index 40b0ac3..5adef5f 100644 --- a/ai/index.md +++ b/ai/index.md @@ -8,6 +8,10 @@ This index provides an overview of the contents in this directory. See [`commands/index.md`](./commands/index.md) for contents. +### 📁 phase-lists/ + +See [`phase-lists/index.md`](./phase-lists/index.md) for contents. + ### 📁 scaffolds/ See [`scaffolds/index.md`](./scaffolds/index.md) for contents. diff --git a/ai/phase-lists/README.md b/ai/phase-lists/README.md new file mode 100644 index 0000000..92df7e5 --- /dev/null +++ b/ai/phase-lists/README.md @@ -0,0 +1,51 @@ +# Phase lists (storage convention) + +A **phase-list** is a **directory** of phase instruction files. Execution is handled by the [`aidd-phase-list`](../skills/aidd-phase-list/SKILL.md) skill, which **must** be given the list directory path (it does not pick a default list). + +## Layout + +- One subdirectory per list, for example `ai/phase-lists/onboarding/`, `ai/phase-lists/context/`. +- **Phases** are individual Markdown files: `*.md` in that directory. +- **Ordering:** lexicographic sort on **file basename** (e.g. `10-welcome.md` before `20-next.md`). Only `*.md` files are phases; do not rely on non-`.md` files for ordering. + +## Naming + +- Prefer numeric prefixes so sort order matches intent: `10-...md`, `20-...md`. +- Use descriptive slugs after the prefix. + +## Optional `pack.json` + +You may add a **minimal** `pack.json` in the same folder **only** for metadata that does not enumerate every phase, for example: + +```json +{ "schema": 1, "order": "lexical" } +``` + +Future non-lexical order could be documented here. **Do not** list every phase path in one file if you want to avoid leaking the full roadmap into a single artifact; prefer discovery via sorted directory listing at run time. + +## Nesting another phase-list + +A phase file in list **A** may delegate by instructing the agent to run the same skill on list **B**: + +1. Finish any inline work for the current phase. +2. The **subagent** for that phase file runs `/aidd-phase-list --list --depth --ancestor-paths …` as a **full** nested checklist (see [Delegation phases vs inline phases](../skills/aidd-phase-list/SKILL.md#delegation-phases-vs-inline-phases) in the skill). +3. When the nested run finishes, append a short outcome for this phase to the run summary. + +Nested runs **must not** delete or truncate the project summary file; they only append (see skill). The parent list **must not** splice list **B**’s files into its own lexical loop; only the nested invocation walks **B**. + +**Delegation boundary (summary):** Without `-debug`, the depth-`D` runner for **A** must not emit nested progress (`d > D`) or walk **B**’s phases itself. The subagent that holds the delegation phase owns the full nested run through `[phase-list d=D+1] run finished`. Full rules: [Runner laws](../skills/aidd-phase-list/SKILL.md#runner-laws-non-negotiable) in the skill. + +## Example lists + +- [`onboarding/`](onboarding/) — short outer flow. +- [`context/`](context/) — inner flow invoked from onboarding for copy-paste reference. + +## Invoking the runner + +From the repo root (example): + +```text +/aidd-phase-list --list ai/phase-lists/onboarding +``` + +Optional: set `PHASE_LIST_SUMMARY` to override the summary file path (default: `/phase-summary.md`). diff --git a/ai/phase-lists/context/10-define-context.md b/ai/phase-lists/context/10-define-context.md new file mode 100644 index 0000000..74c1855 --- /dev/null +++ b/ai/phase-lists/context/10-define-context.md @@ -0,0 +1,5 @@ +# Define context + +Do nothing else in this phase. Run exactly one shell command so **stdout** is a single line: + +`printf '%s\n' "phase-list context: define"` diff --git a/ai/phase-lists/context/11-banana.md b/ai/phase-lists/context/11-banana.md new file mode 100644 index 0000000..2f92f2b --- /dev/null +++ b/ai/phase-lists/context/11-banana.md @@ -0,0 +1,5 @@ +# Banana + +Do nothing else in this phase. Run exactly one shell command so **stdout** is a single line: + +`printf '%s\n' "Banana"` diff --git a/ai/phase-lists/context/12-monkey.md b/ai/phase-lists/context/12-monkey.md new file mode 100644 index 0000000..5cbee17 --- /dev/null +++ b/ai/phase-lists/context/12-monkey.md @@ -0,0 +1,5 @@ +# Monkey + +Do nothing else in this phase. Run exactly one shell command so **stdout** is a single line: + +`printf '%s\n' "monkey"` diff --git a/ai/phase-lists/context/13-fruit-loops.md b/ai/phase-lists/context/13-fruit-loops.md new file mode 100644 index 0000000..5fa85f0 --- /dev/null +++ b/ai/phase-lists/context/13-fruit-loops.md @@ -0,0 +1,5 @@ +# Fruit loops + +Do nothing else in this phase. Run exactly one shell command so **stdout** is a single line: + +`printf '%s\n' "fruit loops"` diff --git a/ai/phase-lists/context/index.md b/ai/phase-lists/context/index.md new file mode 100644 index 0000000..d1efce3 --- /dev/null +++ b/ai/phase-lists/context/index.md @@ -0,0 +1,30 @@ +# context + +This index provides an overview of the contents in this directory. + +## Files + +### Define context + +**File:** `10-define-context.md` + +*No description available* + +### Banana + +**File:** `11-banana.md` + +*No description available* + +### Monkey + +**File:** `12-monkey.md` + +*No description available* + +### Fruit loops + +**File:** `13-fruit-loops.md` + +*No description available* + diff --git a/ai/phase-lists/context/pack.json b/ai/phase-lists/context/pack.json new file mode 100644 index 0000000..4323309 --- /dev/null +++ b/ai/phase-lists/context/pack.json @@ -0,0 +1,4 @@ +{ + "schema": 3, + "order": "lexical" +} diff --git a/ai/phase-lists/index.md b/ai/phase-lists/index.md new file mode 100644 index 0000000..39156f5 --- /dev/null +++ b/ai/phase-lists/index.md @@ -0,0 +1,22 @@ +# phase-lists + +This index provides an overview of the contents in this directory. + +## Subdirectories + +### 📁 context/ + +See [`context/index.md`](./context/index.md) for contents. + +### 📁 onboarding/ + +See [`onboarding/index.md`](./onboarding/index.md) for contents. + +## Files + +### Phase lists \(storage convention\) + +**File:** `README.md` + +*No description available* + diff --git a/ai/phase-lists/onboarding/10-welcome.md b/ai/phase-lists/onboarding/10-welcome.md new file mode 100644 index 0000000..343ec33 --- /dev/null +++ b/ai/phase-lists/onboarding/10-welcome.md @@ -0,0 +1,5 @@ +# Welcome + +Do nothing else in this phase. Run exactly one shell command so **stdout** is a single line: + +`printf '%s\n' "phase-list onboarding: welcome"` diff --git a/ai/phase-lists/onboarding/15-subagentTest.md b/ai/phase-lists/onboarding/15-subagentTest.md new file mode 100644 index 0000000..a90882f --- /dev/null +++ b/ai/phase-lists/onboarding/15-subagentTest.md @@ -0,0 +1,3 @@ +# subagentTest + +Run three subagents in sequence with prompts "repeat: 1", "repeat: 2", "repeat: 3" diff --git a/ai/phase-lists/onboarding/20-run-context-sublist.md b/ai/phase-lists/onboarding/20-run-context-sublist.md new file mode 100644 index 0000000..9616641 --- /dev/null +++ b/ai/phase-lists/onboarding/20-run-context-sublist.md @@ -0,0 +1,15 @@ +# Run context sub-list + +This phase **delegates** to a different phase-list. Perform the nested run, then summarize. + +## Steps + +1. Run the **same** execution skill on the **context** list. From repo root, with outer depth `D` (this onboarding list is normally `D=0`), invoke: + + `/aidd-phase-list --list ai/phase-lists/context --depth 1 --ancestor-paths ai/phase-lists/onboarding` + + If you were already nested at depth `D>0`, use `--depth ` and **append** the current list directory to `--ancestor-paths` using `:` (colon), e.g. `ai/phase-lists/onboarding:ai/phase-lists/context`. + +2. Wait until that nested run completes (including its final `[phase-list d=…] run finished` line in the assistant transcript). + +3. Return a **one-paragraph** outcome for the parent phase summary describing what the context list accomplished. diff --git a/ai/phase-lists/onboarding/index.md b/ai/phase-lists/onboarding/index.md new file mode 100644 index 0000000..d381e73 --- /dev/null +++ b/ai/phase-lists/onboarding/index.md @@ -0,0 +1,24 @@ +# onboarding + +This index provides an overview of the contents in this directory. + +## Files + +### Welcome + +**File:** `10-welcome.md` + +*No description available* + +### subagentTest + +**File:** `15-subagentTest.md` + +*No description available* + +### Run context sub-list + +**File:** `20-run-context-sublist.md` + +*No description available* + diff --git a/ai/skills/aidd-phase-list/SKILL.md b/ai/skills/aidd-phase-list/SKILL.md new file mode 100644 index 0000000..aebd72d --- /dev/null +++ b/ai/skills/aidd-phase-list/SKILL.md @@ -0,0 +1,182 @@ +--- +name: aidd-phase-list +description: > + Execute a folder-based phase list given an explicit directory path. + Runs phases in lexical order, one subagent per parent-list phase; a + single phase file may delegate an entire nested list by having that + subagent run this same skill on the child directory. Non-negotiable: + the parent runner never emits progress with d greater than its own + --depth unless -debug; nested d+1 progress and child phase files belong + to the subagent that received the delegation phase. Use for onboarding + checklists, sequenced workflows, or delegated sub-pipelines without a + default list. +--- + +options { + -debug: do not execute each phase in a subagent; log what you would send to each subagent in the user chat instead. + --list : required. Path to the phase-list directory (repo-relative or absolute). May also be passed as the first positional argument after options. + --depth : nesting depth for this invocation; default 0. Nested calls must pass parent depth + 1. If depth > 5, abort before running any phase. + --ancestor-paths : optional. Colon-separated canonical (or normalized) directory paths of lists already active in the outer stack; used only to emit a preflight warning when the current `--list` path matches one of them (intentional recursion). +} + +## Runner laws (non-negotiable) + +These rules exist because **inlining nested work in the parent thread** breaks the delegation contract: nested slices must be owned by the **subagent** that received the **delegation** phase file. Users and logs rely on that boundary. Treat violations as **incorrect runs**, not speed optimizations. + +### Identity law (progress tags) + +- For this invocation, every `[phase-list d=…]` line you emit **must use `d` equal to this run's `--depth` (`D`)**. You are the runner for **`D` only** on this checklist. +- **Without `-debug`:** the depth-`D` parent **must not** emit `[phase-list d=D+1]` (or any `d > D`) while acting as the parent; deeper tags belong to the **nested** runner (typically the subagent whose sole payload is the delegation phase file). +- **With `-debug`:** the same assistant may emit successive depths as it executes nested lists in order, but each nested segment must still follow this skill (correct `--depth` on each nested `/aidd-phase-list`). + +### Execution-scope law (child list directories) + +- While **executing** the checklist for `--list` at depth `D`, you **must not** replace a delegation with your own lexical walk of another directory's `*.md` phases. The child list is run only via **`/aidd-phase-list --list --depth D+1 …`** inside the **subagent** that received the delegation phase (unless `-debug`). +- **Harmless:** opening or searching files under nested `phase-lists/` for **authoring or review** does not violate this law; it applies to **acting as the nested runner** from the parent identity. + +### Named anti-pattern + +**Parent inlines the child checklist** — the depth-`D` parent walks child `*.md` in order and/or emits nested `[phase-list d>D]` lines as if it were the child runner, instead of spawning one subagent for the delegation file that reruns this skill on the child directory — is **forbidden**. + +### Decision tree + +1. **Depth-`D` parent (default `-debug` off):** Only orchestrate phases under **your** `--list`. Each step = one subagent + one phase file body. You emit only `[phase-list d=D] …`. You do **not** execute the child directory's phases yourself. +2. **Your payload is a delegation phase file:** Your first structural obligation is a **full** nested `/aidd-phase-list` on the child path with `--depth D+1` and extended `--ancestor-paths`. You own `[phase-list d=D+1] run started` through `[phase-list d=D+1] run finished` for that child list (including per-phase subagents inside the child list). +3. **`-debug`:** Same obligations, one assistant; still pass correct `--depth`/`--ancestor-paths` on each nested invocation. + +### Canonical wording + +The **authoritative** rules for delegation are **this section** plus **Delegation phases vs inline phases** below. README snippets, command stubs, and `.cursor/rules` may repeat **one sentence** and must **link here** instead of inventing parallel definitions. + +### Verification + +A compliant nested delegation produces a completed child run: **`[phase-list d=D+1] run started` … `run finished`** for the child `--list`. Silence on the parent is not enough if no nested runner actually finished the child checklist. + +# aidd-phase-list + +You execute a **sequenced checklist** from a **phase-list directory** passed by the user. There is **no default list**: if `--list` / positional directory path is missing or not a directory, **stop immediately** and send **one assistant line** (user-visible transcript), exactly: + +`[phase-list] error: missing or invalid --list ` + +## Storage contract + +- Phase lists live as **folders of `*.md` files** (see [ai/phase-lists/README.md](../../phase-lists/README.md)). +- **Order:** sort matching basenames **lexicographically**. Ignore `pack.json` for ordering unless you later extend this skill to read a different `order` value from `pack.json` (v1: lexical only). + +## Context isolation + +- **Do not read ahead:** load **only** the next phase file when you are about to execute that phase (for the list whose turn it is). Do not preload bodies of later phases in the same list. +- Do **not** paste the full sorted filename list into the subagent prompt; subagents receive **this overview (short)** plus the **full contents of that single phase file**. +- **Child lists stay behind delegation:** the parent runner walks **only** the `*.md` files in its own `--list` directory. It **must not** merge or inline another directory's phases into that loop. When a phase delegates to a child list, the **subagent for that phase** runs a **nested** `/aidd-phase-list` on the child path (see **Delegation phases vs inline phases** and **Runner laws**). + +## Progress (assistant transcript) + +Do **not** rely on shell `printf` for runner progress: in many environments each shell invocation opens a separate terminal, which is noisy and not the same stream as the chat. + +Use this **progress tag** (include depth) in **your assistant replies** so the user sees a clear timeline in the conversation (see **Runner laws** — `d` must match this invocation's `--depth` unless you are that nested run's runner or using `-debug`): + +`[phase-list d=]` + +After resolving the sorted list of **phase basenames** (for counting only; do not preload file bodies), emit **one line** in the assistant transcript (plain text, own line or inline block), using the real count for ``, numeric `--depth` for ``, and the phase-list directory path for ``: + +`[phase-list d=] run started: phases list=` + +## Delegation phases vs inline phases + +A **single lexical phase** in a list can mean either: + +1. **Inline phase** — The subagent does the work in that one file (author types, copy, local commands) and does **not** treat a whole directory as the unit of work. +2. **Delegation phase (nested list)** — The file's main job is to run another **phase-list directory** (a slice or sub-pipeline). The subagent **must** execute the **`aidd-phase-list` skill** on that child directory: run `/aidd-phase-list --list --depth --ancestor-paths …` and follow this same document for the nested run (per-phase subagents inside the child list, progress tags at **that** depth, summary append rules). **Do not** hand-run each child `*.md` outside the skill or skip depth/ancestor handling. **Runner laws** above state the same contract in "do not parent-inline" form. + +This keeps **one subagent per parent-list step** while still allowing one outer "phase" (one `*.md`) to represent an **entire nested checklist**. + +For each phase file in sorted order: + +1. Emit one assistant line: `[phase-list d=] phase start: ` +2. Spin a **subagent** (unless `-debug`) whose instructions are: + - A short **aidd-phase-list** runner overview: **Runner laws** through **Recursion preflight**, plus **Delegation phases vs inline phases** (so nested delegation is unambiguous). + - The **full contents** of that single phase file. + - If the file delegates to a child list, an explicit line that the subagent **runs `/aidd-phase-list` on that directory** with the correct `--depth` and `--ancestor-paths`, then fulfills any "return a short paragraph" / summary asks in the phase body. +3. When the phase finishes, append a concise summary of outcomes to the summary file (see below). +4. Emit one assistant line: `[phase-list d=] phase complete: ` + +After the last phase, emit one assistant line: `[phase-list d=] run finished` + +Phase **content** may still instruct shell commands (e.g. a project script); this section applies only to **runner** progress, not to individual phase bodies. + +## Depth and nesting + +- **`--depth`:** outermost user invocation uses `--depth 0` (or omit; treat as 0). +- **Nested invocation:** when a phase instructs running another phase-list, the **subagent handling that phase file** (or the same assistant if `-debug`) invokes **`/aidd-phase-list`** again with `--list ` and **`--depth `** and the appropriate **`--ancestor-paths`**. The nested invocation is a **full** phase-list run (lexical child phases, their subagents, and any deeper delegation), not a one-off read of a single child file. +- **Hard cap:** if `--depth` is **greater than 5**, send one assistant line + `[phase-list] error: max nesting depth exceeded (depth > 5)` + and **do not** run any phase. + +## Recursion preflight (warning, not blocking) + +If `--ancestor-paths` is provided and the canonical/normalized `--list` path equals **any** segment in `--ancestor-paths`, emit **before** the `run started` line (assistant transcript): + +`[phase-list d=] preflight: warning list re-enters ancestor path (intentional recursion?)` + +Nested invocations **should** extend `--ancestor-paths` by appending the parent list path (colon-separated) so repeated entry can be flagged. If not provided, still enforce **depth cap** only. + +## Summary file (nesting-safe) + +- **Default path:** `/phase-summary.md` unless the environment variable **`PHASE_LIST_SUMMARY`** sets another path. +- **Never delete or truncate** this file at the start of a run (nested runs must preserve outer content). +- **Append** a section per run, for example: + +```markdown +## phase-list depth= list= started + +(concise per-phase bullets or paragraphs) +``` + +Nested runs append **below** the same file (deeper sections or continuation), never clearing prior sections. + +## Pseudocode + +```sudo +fn executePhase(phaseFilePath, depth, progressTag) { + basename = basename(phaseFilePath) + assistantLine(progressTag + " phase start: " + basename) + instructions = read(phaseFilePath) + // follow() may be inline work or a nested runPhaseList(childDir, depth+1, ...) per delegation phases + phaseSummary = follow(instructions) + append(phaseSummary, to: summaryFile) + assistantLine(progressTag + " phase complete: " + basename) +} + +fn runPhaseList(listDir, depth, ancestorPaths) { + progressTag = "[phase-list d=" + depth + "]" + if depth > 5 { assistantLine("[phase-list] error: max nesting depth exceeded (depth > 5)"); return } + if listDir missing or not directory { assistantLine("[phase-list] error: missing or invalid --list "); return } + if ancestorPaths contains canonical(listDir) { assistantLine(progressTag + " preflight: warning list re-enters ancestor path (intentional recursion?)") } + phasePaths = sort(filter(listFiles(listDir), endsWith .md)) + assistantLine(progressTag + " run started: " + phasePaths.length + " phases list=" + listDir) + for path in phasePaths { + executePhase(join(listDir, path), depth, progressTag) + } + assistantLine(progressTag + " run finished") +} +``` + +## Delegation snippet for phase authors + +To run a **child** list from a phase file, end the phase instructions with an explicit block, for example: + +```markdown +## Subagent execution (required) + +The agent that receives **this file** as its phase payload must run the **aidd-phase-list** skill on the child directory below (full nested run with correct `--depth` and `--ancestor-paths`), not manually iterate child `*.md` files outside `/aidd-phase-list`. + +Delegate to phase list `ai/phase-lists/context` at depth **D+1**: + +Run `/aidd-phase-list --list ai/phase-lists/context --depth --ancestor-paths `. + +Then summarize what the nested run produced in one short paragraph for this phase. +``` + +Replace `` with the numeric depth and `` with the accumulated ancestor paths as colon-separated normalized paths. + +**Reference:** see [`onboarding/20-run-context-sublist.md`](../../phase-lists/onboarding/20-run-context-sublist.md) for a delegation phase that runs a nested list under `ai/phase-lists/context/`. diff --git a/ai/skills/aidd-timing-safe-compare/SKILL.md b/ai/skills/aidd-timing-safe-compare/SKILL.md index a264b1e..986be42 100644 --- a/ai/skills/aidd-timing-safe-compare/SKILL.md +++ b/ai/skills/aidd-timing-safe-compare/SKILL.md @@ -26,7 +26,7 @@ Reasons: Patterns { ## Guide (timing safe compare needed?) => Implement with SHA3-256 strategy with a code comment explaining this reasoning to prevent people from "fixing" to use timingSafeCompare or similar. - Use `SHA3-256` in a named helper, hash both values, then compare digests. That pattern is approved with or without a timing safe compare call because there is no stable prefix structure to game. Do not flag it as a major timing-unsafe finding. + Use `SHA3-256` in a named helper, hash both values, then compare digests. Example (Node): `createHash('sha3-256')` on both the stored and candidate material, then compare the digest Buffers (or hex strings) with a constant-time compare if you use one. That pattern is approved with or without a timing safe compare call because there is no stable prefix structure to game. Do not flag it as a major timing-unsafe finding. ## Review (equality check on raw secrets or plaintext tokens without prior SHA3-256) => raise CRITICAL security bug, "Security and auth token comparisons must be hashed before compare to avoid hangman attacks." diff --git a/ai/skills/index.md b/ai/skills/index.md index e406f5a..ed3ebd7 100644 --- a/ai/skills/index.md +++ b/ai/skills/index.md @@ -15,6 +15,7 @@ - aidd-namespace - Ensures types and related functions are authored and consumed in a modular, discoverable, tree-shakeable pattern. Use when creating types, refactoring type folders, defining schemas, importing types, or when the user mentions type namespaces, constants, or Schema.ToType. - aidd-observe - Enforces Observe pattern best practices from @adobe/data/observe. Use when working with Observe, observables, reactive data flow, service Observe properties, or when the user asks about Observe.withMap, Observe.withFilter, Observe.fromConstant, Observe.fromProperties, or similar. - aidd-parallel - Generate /aidd-fix delegation prompts for a list of tasks and optionally dispatch them to sub-agents in dependency order. Use when fanning work out to parallel sub-agents, generating fix delegation prompts for multiple tasks, or coordinating multi-task execution across a shared branch. +- aidd-phase-list - Execute a folder-based phase list given an explicit directory path. Runs phases in lexical order, one subagent per parent-list phase; a single phase file may delegate an entire nested list by having that subagent run this same skill on the child directory. Non-negotiable: the parent runner never emits progress with d greater than its own --depth unless -debug; nested d+1 progress and child phase files belong to the subagent that received the delegation phase. Use for onboarding checklists, sequenced workflows, or delegated sub-pipelines without a default list. - aidd-pipeline - Run a sequential pipeline of tasks defined in a markdown file: parse the list, then delegate each step to an isolated subagent via the Task tool. Use when the user points to a .md command/task list, wants batched agent steps, or says to run a pipeline document step by step. - aidd-please - General AI assistant for software development projects. Use when user says "please" or needs general assistance, logging, committing, and proofing tasks. - aidd-pr - Triage PR review comments, resolve already-addressed threads, and delegate /aidd-fix prompts for remaining issues. Use when a PR has open review comments that need to be triaged, resolved, or delegated to sub-agents.