wogiflow 2.33.0 → 2.34.2

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 (58) hide show
  1. package/.workflow/templates/partials/methodology-rules.hbs +3 -1
  2. package/lib/scheduled-mode.js +12 -15
  3. package/lib/skill-export-claude-plugin.js +41 -1
  4. package/lib/skill-portability.js +21 -3
  5. package/lib/workspace-channel-server.js +116 -3
  6. package/lib/workspace-channel-tracking.js +102 -1
  7. package/lib/workspace-dispatch-tracking.js +28 -0
  8. package/lib/workspace-messages.js +32 -4
  9. package/lib/workspace-subtask-state.js +215 -0
  10. package/lib/workspace.js +81 -0
  11. package/package.json +2 -2
  12. package/scripts/flow +17 -0
  13. package/scripts/flow-constants.js +3 -1
  14. package/scripts/flow-io.js +17 -0
  15. package/scripts/flow-paths.js +81 -0
  16. package/scripts/flow-schedule.js +23 -6
  17. package/scripts/flow-scheduled-runner.js +53 -8
  18. package/scripts/flow-standards-checker.js +37 -0
  19. package/scripts/flow-utils.js +2 -0
  20. package/scripts/hooks/adapters/claude-code.js +6 -2
  21. package/scripts/hooks/core/git-safety-gate.js +34 -15
  22. package/scripts/hooks/core/long-input-enforcement.js +49 -39
  23. package/scripts/hooks/core/overdue-dispatches.js +28 -6
  24. package/scripts/hooks/core/phase-gate.js +34 -5
  25. package/scripts/hooks/core/phase-read-gate.js +62 -10
  26. package/scripts/hooks/core/session-start-worker.js +52 -0
  27. package/scripts/hooks/core/stop-orchestrator.js +17 -2
  28. package/scripts/hooks/core/validation.js +8 -0
  29. package/scripts/hooks/core/worker-continuation-gate.js +487 -0
  30. package/scripts/hooks/core/workspace-stop-gates.js +21 -0
  31. package/scripts/hooks/core/workspace-stop-notify.js +174 -59
  32. package/scripts/hooks/entry/claude-code/post-tool-use.js +26 -0
  33. package/.claude/rules/README.md +0 -36
  34. package/.claude/rules/_internal/README.md +0 -64
  35. package/.claude/rules/_internal/document-structure.md +0 -77
  36. package/.claude/rules/_internal/dual-repo-management.md +0 -174
  37. package/.claude/rules/_internal/feature-refactoring-cleanup.md +0 -87
  38. package/.claude/rules/_internal/github-releases.md +0 -71
  39. package/.claude/rules/_internal/model-management.md +0 -35
  40. package/.claude/rules/_internal/self-maintenance.md +0 -87
  41. package/.claude/rules/_internal/worker-tool-first-turn.md +0 -82
  42. package/.claude/rules/alternative-execpolicy-toml-command-policy.md +0 -11
  43. package/.claude/rules/alternative-hand-edit-ready-json-to-register-orpha.md +0 -11
  44. package/.claude/rules/alternative-hook-args-exec-form.md +0 -6
  45. package/.claude/rules/alternative-permission-ruleset-per-phase.md +0 -11
  46. package/.claude/rules/alternative-short-name.md +0 -12
  47. package/.claude/rules/alternative-wogi-flow-as-mcp-client-oauth-manager.md +0 -11
  48. package/.claude/rules/architecture/component-reuse.md +0 -38
  49. package/.claude/rules/architecture/hook-three-layer.md +0 -68
  50. package/.claude/rules/code-style/naming-conventions.md +0 -107
  51. package/.claude/rules/dual-repo-architecture-2026-02-28.md +0 -18
  52. package/.claude/rules/github-release-workflow-2026-01-30.md +0 -16
  53. package/.claude/rules/operations/git-workflows.md +0 -92
  54. package/.claude/rules/operations/scratch-directory.md +0 -54
  55. package/.claude/skills/figma-analyzer/knowledge/learnings.md +0 -11
  56. package/.workflow/specs/architecture.md.template +0 -24
  57. package/.workflow/specs/stack.md.template +0 -33
  58. package/.workflow/specs/testing.md.template +0 -36
@@ -1,87 +0,0 @@
1
- ---
2
- alwaysApply: false
3
- description: "Cleanup checklist when refactoring or renaming features"
4
- globs:
5
- - "scripts/*.js"
6
- - ".claude/skills/**/*"
7
- ---
8
-
9
- # Feature Refactoring Cleanup
10
-
11
- When refactoring, renaming, or replacing a feature, ensure complete cleanup of the old implementation.
12
-
13
- ## Mandatory Cleanup Checklist
14
-
15
- When a feature is refactored or renamed, you MUST:
16
-
17
- ### 1. Remove Old Code
18
- - [ ] Delete old script files (e.g., `flow-old-feature.js`)
19
- - [ ] Remove old skill directories (e.g., `.claude/skills/old-feature/`)
20
- - [ ] Remove old hook files if applicable
21
-
22
- ### 2. Update Configuration
23
- - [ ] Rename config keys (e.g., `oldFeature` → `newFeature`)
24
- - [ ] Remove from `skills.installed` array if skill was removed
25
- - [ ] Update any feature flags
26
-
27
- ### 3. Update Documentation
28
- - [ ] Rename/update doc files in `.claude/docs/`
29
- - [ ] Update command references in `commands.md`
30
- - [ ] Update skill-matching.md if skill changed
31
- - [ ] Search for old name in all `.md` files
32
-
33
- ### 4. Clean References
34
- - [ ] Search codebase: `grep -r "old-feature-name" .`
35
- - [ ] Update imports in dependent scripts
36
- - [ ] Update any hardcoded references
37
-
38
- ### 5. Update State Files
39
- - [ ] Clean `.workflow/state/` of old state files
40
- - [ ] Update `ready.json` if tasks reference old feature
41
- - [ ] Archive old change specs
42
-
43
- ## Search Commands
44
-
45
- Run these to find lingering references:
46
-
47
- ```bash
48
- # Find all references to old feature
49
- grep -r "old-feature-name" --include="*.js" --include="*.md" --include="*.json" .
50
-
51
- # Find in config
52
- grep "oldFeatureName" .workflow/config.json
53
-
54
- # Find skill references
55
- grep -r "old-feature" .claude/
56
- ```
57
-
58
- ## Why This Matters
59
-
60
- Incomplete cleanup causes:
61
- - **Confusion**: Old commands/skills appear to work but don't
62
- - **Bloat**: Dead code accumulates
63
- - **Errors**: Old references cause runtime failures
64
- - **Documentation drift**: Docs describe non-existent features
65
-
66
- ## Example: transcript-digestion → long-input-gate
67
-
68
- When this refactoring happened without proper cleanup:
69
-
70
- | Artifact | Status | Should Have Been |
71
- |----------|--------|------------------|
72
- | `.claude/skills/transcript-digestion/` | Left behind | Deleted |
73
- | `config.transcriptDigestion` | Left as-is | Renamed to `longInputGate` |
74
- | `skills.installed` array | Still listed | Removed |
75
- | `skill-matching.md` | Old references | Updated |
76
- | `transcript-digestion.md` doc | Still existed | Renamed/rewritten |
77
-
78
- ## Automation Opportunity
79
-
80
- Consider adding a `flow refactor-cleanup <old-name> <new-name>` command that:
81
- 1. Searches for all references
82
- 2. Shows what needs updating
83
- 3. Optionally auto-updates simple cases
84
-
85
- ---
86
-
87
- Last updated: 2026-01-14
@@ -1,71 +0,0 @@
1
- ---
2
- description: "GitHub release workflow - prevents race conditions in npm publish"
3
- alwaysApply: false
4
- globs: package.json
5
- ---
6
-
7
- # GitHub Release Workflow
8
-
9
- **Source**: Repeated failures (10+ times) in npm publish automation
10
- **Priority**: Critical - prevents wasted releases and broken npm versions
11
-
12
- ## Problem
13
-
14
- Running `git push` followed immediately by `gh release create` causes a race condition. The release tag gets created on the remote's HEAD before the push fully propagates, pointing to an old commit.
15
-
16
- ## Pre-Release Quality Gate (MANDATORY)
17
-
18
- Before ANY release, verify the codebase is in a releasable state:
19
-
20
- 1. **Check outstanding findings**: Read `.workflow/state/last-review.json` — if unresolved critical/high findings exist, STOP and fix them first
21
- 2. **Run lint** (if configured): `npm run lint`
22
- 3. **Run typecheck** (if configured): `npm run typecheck`
23
- 4. **Verify no uncommitted changes**: `git status` should be clean
24
-
25
- The `preRelease` and `outstandingFindings` quality gates in `flow-done.js` enforce this automatically for `release` type tasks. For manual releases, check these yourself.
26
-
27
- ## Correct Procedure
28
-
29
- ```bash
30
- # 0. Verify codebase is releasable (pre-release gate)
31
- # (automated by flow-done.js for release-type tasks)
32
-
33
- # 1. Push commits first
34
- git push origin master
35
-
36
- # 2. Create tag LOCALLY on the correct commit
37
- git tag vX.Y.Z HEAD
38
-
39
- # 3. Push the tag explicitly
40
- git push origin vX.Y.Z
41
-
42
- # 4. THEN create the release (it will use the existing tag)
43
- gh release create vX.Y.Z --title "vX.Y.Z" --notes "..."
44
- ```
45
-
46
- ## Never Do This
47
-
48
- ```bash
49
- # BAD - race condition, tag may point to wrong commit
50
- git push origin master && gh release create vX.Y.Z ...
51
- ```
52
-
53
- ## Recovery Procedure
54
-
55
- If a release fails with wrong version:
56
-
57
- 1. Delete the bad release: `gh release delete vX.Y.Z --yes`
58
- 2. Delete the bad remote tag: `git push origin --delete vX.Y.Z`
59
- 3. Delete local tag if exists: `git tag -d vX.Y.Z`
60
- 4. Follow the correct procedure above
61
-
62
- ## Verification
63
-
64
- Before creating the release, verify:
65
- ```bash
66
- git show vX.Y.Z --quiet --format="%H" # Should match HEAD
67
- git show vX.Y.Z:package.json | grep version # Should show X.Y.Z
68
- ```
69
-
70
- ---
71
- Last updated: 2026-01-30
@@ -1,35 +0,0 @@
1
- ---
2
- globs: scripts/flow-model*.js
3
- alwaysApply: false
4
- description: "Model management architecture - two separate systems for different purposes"
5
- ---
6
-
7
- # Model Management Architecture
8
-
9
- **Context**: Phase 1 introduced model registry and stats system alongside existing model-adapter.
10
-
11
- ## Two Model Systems
12
-
13
- ### 1. flow-model-adapter.js - Prompt Adaptation
14
-
15
- - `getCurrentModel()` returns normalized model name (string)
16
- - Focus: Per-model prompt adjustments, learning, and corrections
17
- - Imports: Used by flow-knowledge-router.js
18
-
19
- ### 2. flow-models.js - Registry and Stats
20
-
21
- - `getCurrentModel()` returns `{name, info, source}` object
22
- - Focus: Model listing, routing recommendations, cost tracking
23
- - Standalone CLI commands: `flow models [subcommand]`
24
-
25
- ## Design Decision
26
-
27
- **Keep them separate** because:
28
- - Different return types serve different consumers
29
- - Adapter system needs just the name for pattern matching
30
- - Registry system needs full model metadata for display/routing
31
- - Merging would create unnecessary coupling
32
-
33
- ## Future Consideration
34
-
35
- Could extract shared model detection logic into a common utility if they drift apart, but avoid premature abstraction.
@@ -1,87 +0,0 @@
1
- ---
2
- description: "Patterns for modifying WogiFlow itself (scripts, templates, config)"
3
- alwaysApply: false
4
- globs: "scripts/**,*.workflow/**,.claude/**,templates/**,agents/**,lib/**"
5
- ---
6
-
7
- # WogiFlow Self-Maintenance Patterns
8
-
9
- When modifying WogiFlow's own code (scripts/, templates/, config, hooks), follow these patterns.
10
-
11
- ## 1. Template-First Changes
12
-
13
- CLAUDE.md is **generated**, not hand-edited. Changes must go through the template system:
14
-
15
- ```
16
- .workflow/templates/claude-md.hbs # Main template
17
- .workflow/templates/partials/*.hbs # Partial templates
18
- ```
19
-
20
- After editing templates, regenerate:
21
- ```bash
22
- node scripts/flow-bridge.js sync claude-code
23
- ```
24
-
25
- **Never edit CLAUDE.md directly** - changes will be overwritten on next sync.
26
-
27
- ## 2. Three-Layer Hook Architecture
28
-
29
- All hooks follow: Entry → Core → Adapter
30
-
31
- ```
32
- scripts/hooks/entry/claude-code/<name>.js # CLI-specific entry point
33
- scripts/hooks/core/<name>.js # CLI-agnostic logic
34
- scripts/hooks/adapters/claude-code.js # Transform results
35
- ```
36
-
37
- When adding/modifying hooks:
38
- - Logic goes in `core/` (not entry)
39
- - Entry files only parse input and call core
40
- - Register hook in `.claude/settings.local.json`
41
- - Add config toggle in `.workflow/config.json` under `hooks.rules`
42
-
43
- ## 3. Config Changes Need Documentation
44
-
45
- When adding config keys:
46
- - Use `_comment_<keyName>` for inline documentation of non-obvious settings
47
- - Update config.schema.json if it exists
48
- - Ensure `lib/installer.js` handles the new key for fresh installs
49
-
50
- ## 4. State File Templates
51
-
52
- For files in `.workflow/state/` that target projects need:
53
- - Create both the file AND a `.template` version
54
- - Templates go in `.workflow/state/<name>.template` (for init/onboard)
55
- - Also add to `templates/` directory (for npm distribution)
56
-
57
- ## 5. Slash Commands Are Flat Files
58
-
59
- Slash commands in `.claude/commands/` must be flat `.md` files:
60
- ```
61
- .claude/commands/wogi-start.md ← Correct (flat file)
62
- .claude/commands/wogi-start/ ← Wrong (directory)
63
- ```
64
-
65
- ## 6. Two Agent Directories
66
-
67
- | Directory | Purpose | Used By |
68
- |-----------|---------|---------|
69
- | `agents/` | 11 persona files | Health checks, CLI |
70
- | `.workflow/agents/` | Review checklists | wogi-review |
71
-
72
- Don't confuse them. `agents/security.md` (persona) is different from `.workflow/agents/security.md` (OWASP checklist).
73
-
74
- ## 7. Regression Prevention
75
-
76
- When modifying flow-*.js scripts:
77
- - Run `node --check scripts/<file>.js` after edits
78
- - Run `npm test` — WogiFlow has a native-Node test suite (50+ files under `tests/`, 1800+ assertions) covering hooks, flow-io, security, session state, workspace gates, and more
79
- - Check for circular dependencies when moving shared functions
80
-
81
- ## 8. Feature Refactoring Cleanup
82
-
83
- When renaming/replacing a feature, follow the full checklist in `.claude/rules/architecture/feature-refactoring-cleanup.md`. Key steps:
84
- - Remove old script files
85
- - Update config keys
86
- - Update documentation references
87
- - Search all `.md` files for old name
@@ -1,82 +0,0 @@
1
- ---
2
- alwaysApply: false
3
- description: "Worker tool-first-turn contract — workspace worker mode only (WOGI_WORKSPACE_ROOT set, WOGI_REPO_NAME !== 'manager')"
4
- globs: "scripts/hooks/core/worker-tool-first-gate.js,.workflow/templates/worker-rules.md"
5
- ---
6
-
7
- # Worker Tool-First Turn Contract
8
-
9
- **Applies to**: workspace worker mode (`WOGI_WORKSPACE_ROOT` set + `WOGI_REPO_NAME !== 'manager'`).
10
-
11
- **Rule**: Every worker turn that follows a `UserPromptSubmit` (channel dispatch from the manager) MUST contain at least one tool call. In **strict mode** (default), the first assistant content block MUST be a tool call, not text.
12
-
13
- ## Three violations enforced as one rule
14
-
15
- The Stop hook detects three distinct violations and labels all of them under the unified rule name `worker-tool-first-turn`:
16
-
17
- | Gate | Violation | Detection |
18
- |------|-----------|-----------|
19
- | **G1** | `silent-halt` | Zero `tool_use` blocks across the entire turn (pure-text response). |
20
- | **G4** | `text-before-tool-call` | First assistant content block is `text`, not `tool_use`. Strict mode only. |
21
- | **G6** | documented contract | The named rule referenced in block messages so the worker sees one coherent contract, not three independent gates. |
22
-
23
- ## Why the contract exists
24
-
25
- Workers communicate with the manager via tool calls:
26
- - Channel dispatches (`curl` POST to the manager port)
27
- - File edits (`Edit`, `Write`)
28
- - Test runs (`Bash`)
29
- - Structured `## Results` payloads posted back to the manager channel
30
-
31
- A pure-text response from a worker is **invisible to the user** — the user only sees the manager terminal. Worker text disappears into the transcript with no downstream consumer. It also disqualifies the worker from the three-state end-of-turn contract (`ACTION` | `ESCALATION` | `IDLE`) documented in CLAUDE.md under "Workspace Autonomous-Mode Action-After-Completion Contract".
32
-
33
- ## Allowed turn shapes (pass)
34
-
35
- - Pure action: `tool_use` → `tool_use` → end
36
- - Action with narration after: `tool_use` → `text` → `tool_use` → end
37
- - Escalation: `tool_use` (channel dispatch of `## QUESTION:`) → end
38
- - Reply: `tool_use` (channel dispatch of `## Results:`) → end
39
- - Idle (pre-user-message): zero assistant blocks — not gated since no dispatch happened
40
-
41
- ## Blocked turn shapes (fail)
42
-
43
- - **G1**: `text` → end (no tool_use anywhere in turn)
44
- - **G4**: `text` → `tool_use` → end (strict mode: first block must be tool_use)
45
-
46
- ## Configuration
47
-
48
- `.workflow/config.json → workspace.toolFirstTurnGate`:
49
-
50
- ```json
51
- {
52
- "enabled": true,
53
- "strict": true
54
- }
55
- ```
56
-
57
- - `enabled: false` — disables the gate entirely (silent-halt + text-first both allowed).
58
- - `strict: false` — G1 still enforced (zero-tool-call blocked), G4 relaxed (text-first allowed as long as a tool_use eventually fires).
59
-
60
- Default is `enabled: true, strict: true` — maximum worker discipline.
61
-
62
- ## Fail-open behavior
63
-
64
- The gate fails open on:
65
- - Missing transcript path
66
- - Unreadable / malformed transcript file
67
- - Config read errors
68
- - Any unexpected exception
69
-
70
- Rationale: a silent-halt false-negative is recoverable (the worker will be retried on the next manager cycle via the dispatch-tracking overdue check). A false-positive block on every turn would make the worker unusable — unrecoverable without a code deploy.
71
-
72
- ## Related gates (same epic, same integration point)
73
-
74
- - **Existing — "Gap B" (v2.20.0)**: blocks end-of-turn when queued dispatches exist but no task is in-progress. Complements this gate — Gap B runs at the queue boundary; tool-first runs at every turn.
75
- - **Existing — AI Worker Question Classifier (v2.21.0)**: Haiku classifier detects when a worker ends with a user-facing question. Complements this gate — question classifier is semantic; tool-first is structural.
76
- - **Existing — Worker Boundary Gate**: blocks `AskUserQuestion` in worker mode. Complements this gate — boundary gate blocks a specific tool; tool-first requires any tool.
77
-
78
- ## Enforcement
79
-
80
- - Core logic: `scripts/hooks/core/worker-tool-first-gate.js`
81
- - Wired into: `scripts/hooks/entry/claude-code/stop.js` (after Gap B, before AI question classifier)
82
- - Template updated: `.workflow/templates/worker-rules.md` carries the contract verbatim so workers see it in every system prompt.
@@ -1,11 +0,0 @@
1
- ---
2
- alwaysApply: false
3
- description: "Alternative: execpolicy-style TOML Bash allow/deny policy layer - Rejected: 2026-04-24"
4
- ---
5
-
6
- # Alternative: execpolicy-style TOML Bash allow/deny policy layer
7
-
8
- **Rejected**: 2026-04-24
9
- **Reason**: The spec framed WogiFlow as owner of Bash allow/deny wildcards. It isn't — `.claude/settings.local.json → permissions.{allow,deny,ask}` are enforced by Claude Code *before* any WogiFlow hook runs, and Claude Code already supports all three modes natively (see `.claude/rules/security/security-patterns.md` §6). WogiFlow's PreToolUse Bash gates (`git-safety-gate`, `deploy-gate`, `strike-gate`, `scope-mutation-gate`, `commit-log-gate`) are content-aware — not wildcard lists — so there is nothing for a TOML allowlist to "replace." Implementing the spec as written would duplicate Claude Code's native permission system with a strictly worse version (no UI integration, no session-scope memory, no settings-source hierarchy).
10
- **Chose instead**: Lean on Claude Code's native `permissions.{allow,deny,ask}` for allow/deny semantics. The only genuinely-additive piece of the D2 spec — **per-phase command overlay** (AC3) — should be re-specced as a small feature that reads phase-scoped overrides from `.workflow/config.json` and augments the existing `pre-tool-orchestrator.js`, if the need resurfaces from a real incident. Don't build it speculatively.
11
- **Source**: wf-ac2a8074 scope-confidence audit (user chose option A: drop the story entirely)
@@ -1,11 +0,0 @@
1
- ---
2
- alwaysApply: false
3
- description: "Alternative: Hand-edit ready.json to register orphaned specs - Rejected: 2026-04-15"
4
- ---
5
-
6
- # Alternative: Hand-edit ready.json to register orphaned specs
7
-
8
- **Rejected**: 2026-04-15
9
- **Reason**: CLAUDE.md memory-hierarchy rule forbids hand-editing `.workflow/state/` files to create tasks. Doing so bypasses routing telemetry and breaks the bypass-counter signal that surfaces actual workflow gaps.
10
- **Chose instead**: One-off script using `flow-utils` `getReadyData` / `saveReadyData` API. The script is self-documenting (kept in `.workflow/scratch/` for the auto-cleanup pass) and uses the same write path the runtime uses.
11
- **Source**: wf-a3cc5f2a session, state-sync between progress.md and ready.json after epic-episodic-memory wave.
@@ -1,6 +0,0 @@
1
- # Alternative: Migrate generated hook registrations to the `args: string[]` exec form
2
-
3
- **Rejected**: 2026-05-12
4
- **Reason**: Claude Code 2.1.139 added an `args: string[]` field for hook entries that spawns the command directly without a shell, so path placeholders never need quoting. WogiFlow's generated hook registrations (`generateConfig()` in `scripts/hooks/adapters/claude-code.js`) already emit `command: \`node "${absolutePath}"\`` — the absolute script path is double-quoted, which already handles spaces in the project path. Switching to `args` would buy only marginal robustness (paths containing a literal `"` or shell metacharacters — vanishingly rare for real project directories) while introducing a real regression: `args` is silently ignored on Claude Code < 2.1.139, and since it *replaces* `command` rather than augmenting it, a hook entry that emits only `args` would do nothing on older Claude Code — breaking task gating, validation, routing enforcement, etc. for any user not yet on 2.1.139. WogiFlow does not currently require a minimum Claude Code version that high (`postinstall.js` version-gates individual hook *events*, but the base hook set must work on much older CC). The shell-chain commands that actually have gnarly quoting (the `&&`/`2>/dev/null`/`$(...)` one-liners) live in the **permissions allow-list**, not in hook registrations, and cannot use exec form at all (no shell = no `&&`).
5
- **Chose instead**: Keep `command: \`node "${path}"\``. If WogiFlow's minimum supported Claude Code version ever reaches 2.1.139, revisit — at that point `buildHookEntry()` could emit `args: ["node", scriptPath]` for the `command` transport and drop the manual quoting. Until then, the double-quoted `command` form is correct and maximally compatible.
6
- **Source**: wf-cb951e91 — "Respond to Claude Code v2.1.139 changelog" (AC2).
@@ -1,11 +0,0 @@
1
- ---
2
- alwaysApply: false
3
- description: "Alternative: Permission-ruleset-per-phase via WogiFlow hooks - Rejected: 2026-04-24"
4
- ---
5
-
6
- # Alternative: Permission-ruleset-per-phase via WogiFlow hooks
7
-
8
- **Rejected**: 2026-04-24
9
- **Reason**: Same root cause as wf-ac2a8074 (D2). `.claude/settings.json → permissions.{allow,deny,ask}` is Claude Code's permission system, enforced by Claude Code itself before any WogiFlow hook fires. Making it phase-aware would require Claude Code to be phase-aware — out of WogiFlow's scope. WogiFlow's PreToolUse gates are content-aware (`git-safety-gate`, `scope-mutation-gate`, etc.), not wildcard permission lists, so there's nothing to "phase-scope" at this layer either.
10
- **Chose instead**: If real per-phase restrictions surface as a need from incident data, extend `pre-tool-orchestrator.js` with phase-scoped content-aware checks (e.g., "block `rm -rf` during validating phase"). Build that narrow thing from a real incident, not speculative per-phase rulesets.
11
- **Source**: wf-c6c75841 scope-confidence batch audit (user chose "drop H2" as part of the 1+2+3 combination)
@@ -1,12 +0,0 @@
1
- ---
2
- alwaysApply: false
3
- description: "Alternative: <short name> - Rejected: <YYYY-MM-DD>"
4
- ---
5
-
6
- # Alternative: <short name>
7
-
8
- **Rejected**: <YYYY-MM-DD>
9
- **Reason**: <why we said no — be specific>
10
- **Chose instead**: <what we did instead, and where it lives>
11
- **Source**: <task ID, audit, or session that produced this decision>
12
- -->
@@ -1,11 +0,0 @@
1
- ---
2
- alwaysApply: false
3
- description: "Alternative: WogiFlow-as-MCP-client OAuth manager - Rejected: 2026-04-24"
4
- ---
5
-
6
- # Alternative: WogiFlow-as-MCP-client OAuth manager (Cline McpHub pattern)
7
-
8
- **Rejected**: 2026-04-24
9
- **Reason**: WogiFlow is a workflow layer that runs *inside* a Claude Code session — it is not an MCP client. No `@modelcontextprotocol/sdk` dependency, no transport/stdio/server-connect code; existing `scripts/flow-mcp-*` scripts only *discover* capabilities Claude Code already exposes (`ToolSearch`, `ListMcpResourcesTool`). Cline's `McpHub` works because Cline owns the MCP client lifecycle. In our stack, Claude Code owns it — by the time a WogiFlow SessionStart hook fires, Claude Code has already loaded (or declined to load) its MCP servers, so "reconnect at session start" has no connection object to attach tokens to.
10
- **Chose instead**: Rely on Claude Code 2.1+ native MCP OAuth. If a future WogiFlow-as-standalone-agent runtime hosts its own MCP clients, revisit then with a fresh spec grounded in that runtime's lifecycle.
11
- **Source**: wf-8e97ac77 scope-confidence audit (user chose option C: drop the story entirely)
@@ -1,38 +0,0 @@
1
- ---
2
- globs: src/components/**/*
3
- alwaysApply: false
4
- description: "Component reuse policy - always check app-map.md before creating components"
5
- ---
6
-
7
- # Component Reuse Policy
8
-
9
- **Rule**: Always check `app-map.md` before creating any component.
10
-
11
- ## Priority Order
12
-
13
- 1. **Use existing** - Check if component already exists in app-map
14
- 2. **Add variant** - Extend existing component with a new variant
15
- 3. **Extend** - Create a wrapper/HOC around existing component
16
- 4. **Create new** - Only as last resort
17
-
18
- ## Before Creating Components
19
-
20
- ```bash
21
- # Check app-map first
22
- cat .workflow/state/app-map.md | grep -i "button"
23
-
24
- # Or search codebase
25
- grep -r "Button" src/components/
26
- ```
27
-
28
- ## Variant vs New Component
29
-
30
- Prefer variants when:
31
- - Same base functionality, different appearance
32
- - Same HTML structure, different styling
33
- - Same component, different size/color/state
34
-
35
- Create new component when:
36
- - Fundamentally different functionality
37
- - Different DOM structure
38
- - Different state management
@@ -1,68 +0,0 @@
1
- ---
2
- alwaysApply: false
3
- description: "Three-layer hook architecture: Entry → Core → Adapter. Applies to all hooks under scripts/hooks/."
4
- globs: scripts/hooks/**/*.js
5
- ---
6
-
7
- # Hook Three-Layer Architecture
8
-
9
- **Rule**: Every WogiFlow hook follows a strict three-layer separation: Entry → Core → Adapter. Entry files parse CLI-harness input and dispatch to core. Core files contain all business logic and are CLI-agnostic. Adapter files translate core results into the target CLI's expected output format.
10
-
11
- ## Layer contract
12
-
13
- | Layer | Location | Responsibility | Dependencies allowed |
14
- |-------|----------|----------------|---------------------|
15
- | **Entry** | `scripts/hooks/entry/<cli-name>/<hook>.js` | Parse stdin JSON, delegate to core, pass result to adapter, write adapter output. Minimal logic. | `core/`, `adapters/` |
16
- | **Core** | `scripts/hooks/core/<hook>.js` | All business logic: gate decisions, state reads/writes, classifications, enforcement. CLI-agnostic. | `scripts/flow-*.js`, `lib/`, each other |
17
- | **Adapter** | `scripts/hooks/adapters/<cli-name>.js` | Transform core's uniform return shape into the CLI's expected output format (stdout JSON, exit codes, block messages). | None (pure functions) |
18
-
19
- ## What belongs in each layer
20
-
21
- **Entry layer MUST**:
22
- - Read stdin, parse JSON
23
- - Call exactly one core function (the hook's entry point)
24
- - Wrap the core's return with the adapter
25
- - Write adapter output to stdout and exit
26
-
27
- **Entry layer MUST NOT**:
28
- - Contain business logic (gate decisions, state enforcement, classifications)
29
- - Import from other `core/` modules directly (only the hook's own core)
30
- - Call other CLI's adapters
31
- - Contain more than ~100 LOC total
32
-
33
- **Core layer MUST**:
34
- - Own all gate logic and state mutations
35
- - Export pure-ish functions (I/O allowed; network not)
36
- - Be testable without any CLI harness
37
-
38
- **Core layer MUST NOT**:
39
- - Import from `entry/` or `adapters/` (those import core, not vice versa)
40
- - Know about stdin JSON shapes or stdout formats
41
- - Reference specific CLI tool names (Claude Code, Cursor, etc.)
42
-
43
- **Adapter layer MUST**:
44
- - Accept a uniform core-return shape as input
45
- - Produce CLI-specific output (JSON shape, exit codes)
46
-
47
- ## Why this matters
48
-
49
- Past incidents (pre-v2.26): `pre-tool-use.js` grew to 560 LOC + 84 branches with gate logic inline in the entry file. This was the origin of `arch-001` audit finding. Same pattern plagued `session-start.js` (307 LOC inline) and `stop.js` (188 LOC inline). When business logic lives in entry files:
50
- - It can't be unit-tested without spawning a full process
51
- - It's tied to one CLI harness; cross-CLI support requires copying
52
- - New gates drift from the established enforcement pattern
53
-
54
- The three-layer split is enforced mechanically:
55
- - `flow-standards-checker.js` (standards gate) flags entry files over 120 LOC
56
- - `flow-standards-checker.js` flags entry files that import from multiple `core/` modules (suggests orchestration logic inline)
57
- - `flow-standards-checker.js` flags `core/` files that reference CLI-specific shapes (e.g., `input.tool_name` vs accepting `toolName` as a normalized param)
58
-
59
- ## Enforcement
60
-
61
- Standards-gate checks (added in wf-0f2e0f16):
62
- 1. Entry files (`scripts/hooks/entry/**/*.js`) must be ≤ 120 LOC (allows room for imports + dispatch)
63
- 2. Entry files must import from at most 2 `core/` modules (single-entry-point principle)
64
- 3. Core files (`scripts/hooks/core/**/*.js`) must not contain strings matching known CLI-specific identifiers (`claude-code`, `cursor`, etc.) in comments or code
65
-
66
- Gate runs during `/wogi-review` and per-commit via the standards lane of `/wogi-done`.
67
-
68
- **Exemption**: If a legitimate reason requires breaking a rule (e.g., a hook that genuinely needs to fan out to 3 core modules), document it in the entry file header and add the file to `config.standardsCheck.hookThreeLayer.exemptions`.
@@ -1,107 +0,0 @@
1
- ---
2
- alwaysApply: true
3
- description: "Naming conventions for files and code variants"
4
- globs: "**/*.{js,ts,jsx,tsx,mjs,cjs}"
5
- ---
6
-
7
- # Naming Conventions
8
-
9
- ## File Names
10
-
11
- Use **kebab-case** for all file names in this project.
12
-
13
- Examples:
14
- - `flow-health.js` (correct)
15
- - `flowHealth.js` (incorrect)
16
- - `flow_health.js` (incorrect)
17
-
18
- ## Variant Names (UI Projects Only)
19
-
20
- When working on projects with UI components, use consistent variant names:
21
-
22
- | Category | Values |
23
- |----------|--------|
24
- | Size | `sm`, `md`, `lg`, `xl` |
25
- | Intent | `primary`, `secondary`, `danger`, `success`, `warning` |
26
- | State | `default`, `hover`, `active`, `disabled` |
27
-
28
- Skip this section for backend-only or library projects (no UI components).
29
-
30
- ## Catch Block Variables
31
-
32
- Use `err` for all catch blocks in this codebase.
33
-
34
- **Avoid**: `e`, `error`, `ex`, `exception` - these cause confusion with loop variables.
35
-
36
- ```javascript
37
- // Good
38
- try {
39
- doSomething();
40
- } catch (err) {
41
- console.error(err.message);
42
- }
43
-
44
- // Bad - 'e' conflicts with common iterator variables
45
- try {
46
- items.map(e => e.value); // 'e' used as iterator
47
- } catch (e) {
48
- console.error(e.message); // Easy to confuse with iterator 'e'
49
- }
50
- ```
51
-
52
- **Reason**: Standardizing on `err` prevents mix-ups when `.map(e => ...)` is used nearby.
53
-
54
- ### Unused Catch Variables
55
-
56
- When the catch block intentionally ignores the error, prefix with underscore: `_err`.
57
-
58
- ```javascript
59
- // Good - _err signals "intentionally unused"
60
- try {
61
- JSON.parse(input);
62
- } catch (_err) {
63
- return defaultValue;
64
- }
65
-
66
- // Bad - looks like a bug (unused variable without underscore)
67
- try {
68
- JSON.parse(input);
69
- } catch (err) {
70
- return defaultValue;
71
- }
72
- ```
73
-
74
- This convention is used across 100+ files in the codebase and satisfies no-unused-vars lint rules.
75
-
76
- ## Default Value Operators: `||` vs `??`
77
-
78
- Use **nullish coalescing (`??`)** for defaults where the left operand could legitimately be `0`, `false`, or `""`.
79
-
80
- Use **logical OR (`||`)** only when falsy values (0, false, empty string) should genuinely fall through to the default.
81
-
82
- ```javascript
83
- // Use ?? — timeout=0 is valid (means "no timeout"), not "use default"
84
- this.timeout = options.timeout ?? TIMEOUTS.HTTP_DEFAULT;
85
-
86
- // Use ?? — numeric config values where 0 is meaningful
87
- const retries = config.maxRetries ?? 3;
88
- const threshold = config.similarityThreshold ?? 0.5;
89
-
90
- // Use ?? — boolean config where false is the intended value
91
- const strictMode = config.enforcement?.strictMode ?? false;
92
-
93
- // Use ?? — array/object defaults guarding against null/undefined
94
- const items = data.inProgress ?? [];
95
- const settings = config.hybrid ?? {};
96
-
97
- // Use || — empty string should fall through to a display default
98
- const branch = status.git.branch || 'unknown';
99
-
100
- // Use || — lookup fallback where undefined means "not found"
101
- const name = cliNames[type] || type;
102
-
103
- // Use || — join() returns "" for empty arrays, want a fallback message
104
- const summary = facts.join('; ') || 'No data available';
105
- ```
106
-
107
- **Rule of thumb**: If you are defaulting a config value, numeric parameter, boolean flag, or array/object from a potentially-null source, use `??`. If you are providing a display fallback where empty string should show a placeholder, use `||`.