Commit Graph

29 Commits

Author SHA1 Message Date
Affaan Mustafa
4e028bd2d2 feat: orchestration harness, selective install, observer improvements 2026-03-14 12:55:25 -07:00
Affaan Mustafa
da4db99c94 fix: repair opencode config and project metadata 2026-03-11 01:52:10 -07:00
Affaan Mustafa
16bc7436c5 fix: raise observer analysis turn budget 2026-03-10 20:52:53 -07:00
Affaan Mustafa
4de776341e fix: handle null tool_response fallback 2026-03-10 19:14:56 -07:00
ispaydeu
708c265b4f fix: read tool_response field in observe.sh (#377)
Claude Code sends tool output as `tool_response` in PostToolUse hook
payloads, but observe.sh only checked for `tool_output` and `output`.
This caused all observations to have empty output fields, making the
observer pipeline blind to tool results.

Adds `tool_response` as the primary field to check, with backward-
compatible fallback to the existing `tool_output` and `output` fields.
2026-03-10 19:14:56 -07:00
Affaan Mustafa
af51fcacb7 fix: resolve PR 371 portability regressions 2026-03-09 22:49:43 -07:00
Affaan Mustafa
440178d697 fix: harden hook portability and plugin docs 2026-03-09 22:49:43 -07:00
Frank
e9577e34f1 fix: force UTF-8 for instinct CLI file IO (#353) 2026-03-07 14:47:35 -08:00
jtzingsheim1
9661a6f042 fix(hooks): scrub secrets and harden hook security (#348)
* fix(hooks): scrub secrets and harden hook security

- Scrub common secret patterns (api_key, token, password, etc.) from
  observation logs before persisting to JSONL (observe.sh)
- Auto-purge observation files older than 30 days (observe.sh)
- Strip embedded credentials from git remote URLs before saving to
  projects.json (detect-project.sh)
- Add command prefix allowlist to runCommand — only git, node, npx,
  which, where are permitted (utils.js)
- Sanitize CLAUDE_SESSION_ID in temp file paths to prevent path
  traversal (suggest-compact.js)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(hooks): address review feedback from CodeRabbit and Cubic

- Reject shell command-chaining operators (;|&`) in runCommand, strip
  quoted sections before checking to avoid false positives (utils.js)
- Remove command string from blocked error message to avoid leaking
  secrets (utils.js)
- Fix Python regex quoting: switch outer shell string from double to
  single quotes so regex compiles correctly (observe.sh)
- Add optional auth scheme match (Bearer, Basic) to secret scrubber
  regex (observe.sh)
- Scope auto-purge to current project dir and match only archived
  files (observations-*.jsonl), not live queue (observe.sh)
- Add second fallback after session ID sanitization to prevent empty
  string (suggest-compact.js)
- Preserve backward compatibility when credential stripping changes
  project hash — detect and migrate legacy directories
  (detect-project.sh)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(hooks): block $() substitution, fix Bearer redaction, add security tests

- Add $ and \n to blocked shell metacharacters in runCommand to prevent
  command substitution via $(cmd) and newline injection (utils.js)
- Make auth scheme group capturing so Bearer/Basic is preserved in
  redacted output instead of being silently dropped (observe.sh)
- Add 10 unit tests covering runCommand allowlist blocking (rm, curl,
  bash prefixes) and metacharacter rejection (;|&`$ chaining), plus
  error message leak prevention (utils.test.js)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(hooks): scrub parse-error fallback, strengthen security tests

Address remaining reviewer feedback from CodeRabbit and Cubic:

- Scrub secrets in observe.sh parse-error fallback path (was writing
  raw unsanitized input to observations file)
- Remove redundant re.IGNORECASE flag ((?i) inline flag already set)
- Add inline comment documenting quote-stripping limitation trade-off
- Fix misleading test name for error-output test
- Add 5 new security tests: single-quote passthrough, mixed
  quoted+unquoted metacharacters, prefix boundary (no trailing space),
  npx acceptance, and newline injection
- Improve existing quoted-metacharacter test to actually exercise
  quote-stripping logic

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(security): block $() and backtick inside quotes in runCommand

Shell evaluates $() and backticks inside double quotes, so checking
only the unquoted portion was insufficient. Now $ and ` are rejected
anywhere in the command string, while ; | & remain quote-aware.

Addresses CodeRabbit and Cubic review feedback on PR #348.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 14:47:31 -08:00
Affaan Mustafa
48b883d741 feat: deliver v1.8.0 harness reliability and parity updates 2026-03-04 14:48:06 -08:00
zzzhizhi
adc0f67008 fix(continuous-learning-v2): observer background process crashes immediately (#312)
* fix(continuous-learning-v2): observer background process crashes immediately

Three bugs prevent the observer from running:

1. Nested session detection: When launched from a Claude Code session,
   the child process inherits CLAUDECODE env var, causing `claude` CLI
   to refuse with "cannot be launched inside another session". Fix: unset
   CLAUDECODE in the background process.

2. set -e kills the loop: The parent script's `set -e` is inherited by
   the subshell. When `claude` exits non-zero (e.g. max turns reached),
   the entire observer loop dies. Fix: `set +e` in the background process.

3. Subshell dies when parent exits: `( ... ) & disown` loses IO handles
   when the parent shell exits, killing the background process. Fix: use
   `nohup /bin/bash -c '...'` for full detachment, and `sleep & wait`
   to allow SIGUSR1 to interrupt sleep without killing the process.

Additionally, the prompt for Haiku now includes the exact instinct file
format inline (YAML frontmatter with id/trigger/confidence/domain/source
fields), since the previous prompt referenced "the observer agent spec"
which Haiku could not actually read, resulting in instinct files that
the CLI parser could not parse.

* fix: address review feedback on observer process management

- Use `env` to pass variables to child process instead of quote-splicing,
  avoiding shell injection risk from special chars in paths
- Add USR1_FIRED flag to prevent double analysis when SIGUSR1 interrupts
  the sleep/wait cycle
- Track SLEEP_PID and kill it in both TERM trap and USR1 handler to
  prevent orphaned sleep processes from accumulating
- Consolidate cleanup logic into a dedicated cleanup() function

* fix: guard PID file cleanup against race condition on restart

Only remove PID file in cleanup trap if it still belongs to the
current process, preventing a restarted observer from losing its
PID file when the old process exits.
2026-03-02 22:23:01 -08:00
Affaan Mustafa
1df0a53f22 fix: resolve CI failures on main — lint, hooks validator, and test alignment
- Fix MD012 trailing blank lines in commands/projects.md and commands/promote.md
- Fix MD050 strong-style in continuous-learning-v2 (escape __tests__ as inline code)
- Extract doc-file-warning hook to standalone script to fix hooks validator regex parsing
- Update session-end test to match #317 behavior (always update summary content)
- Allow shell script hooks in integration test format validation

All 992 tests passing.
2026-03-02 22:15:46 -08:00
Harry Kwok
5818e8adc7 feat: project-scoped instinct isolation
* feat: add project-scoped instinct isolation

* fix(continuous-learning-v2): harden instinct loading and promotion safety; sync v2.1 command docs

* fix(ci): make copilot-setup-steps a valid GitHub Actions workflow

* fix(hooks): stabilize docs warning inline JS regex parsing
2026-03-01 12:07:13 -08:00
Affaan Mustafa
87fc2d5089 Add frontend slides skill across platforms 2026-02-27 05:39:31 -08:00
Affaan Mustafa
a9b104fc23 feat: add security guides and sanitize external links across repo
New articles:
- the-security-guide.md: "The Shorthand Guide to Securing Your Agent" (595 lines)
  Attack vectors, sandboxing, sanitization, OWASP Top 10, observability
- the-openclaw-guide.md: "The Hidden Danger of OpenClaw" (470 lines)
  Security analysis of OpenClaw, MiniClaw thesis, industry evidence

External link sanitization (22 files across EN, zh-CN, zh-TW, ja-JP, .cursor):
- Removed third-party GitHub links from skills and guides
- Replaced with inline descriptions to prevent transitive prompt injection
- Kept official org links (Anthropic, Google, Supabase, Mixedbread)
2026-02-25 07:20:42 -08:00
Affaan Mustafa
4dbc0aa966 Merge pull request #273 from bintocher/bintocher/issue-246
LGTM — Origin metadata for distributed skills. Pure metadata addition.
2026-02-24 09:24:28 -08:00
Stanislav Chernov
48dafdd288 fix: add origin metadata to skills for traceability
Add origin field to all skill files to track their source repository.
This enables users to identify where distributed skills originated from.
Fixes affaan-m/everything-claude-code#246
2026-02-23 19:00:57 +03:00
tsli
dbe737cc0b address review: remove .cursor/ duplicate, use is not None checks
Changes based on CodeRabbit review feedback:

1. Remove entire .cursor/ directory — it was an identical copy of the
   main skills/commands/agents/rules, causing maintenance drift.
   Users of Cursor can reference the canonical files directly.

2. Use explicit `is not None` checks instead of truthiness for
   parsed['input'] and parsed['output']. Empty strings or empty
   dicts are valid values that should be preserved.
2026-02-21 08:46:13 +08:00
tsli
cb4e4ca711 fix: use CLI argument for hook phase detection in observe.sh
The observe.sh script receives "pre" or "post" as $1 from the hook
config, but the Python code was looking for a "hook_type" field in
the stdin JSON. Claude Code does NOT include "hook_type" in the
JSON payload passed to hooks, so it always defaulted to "unknown",
causing all observations to be recorded as "tool_complete" —
PreToolUse events were never distinguished from PostToolUse.

Fix: capture $1 as HOOK_PHASE and pass it to Python via env var.
This also fixes TIMESTAMP export in the .cursor copy where inline
`VAR=val cmd` syntax didn't propagate to the python subprocess.
2026-02-21 08:45:54 +08:00
黄飞虹
1f74889dbf fix: correct TIMESTAMP environment variable syntax in observe.sh
The inline environment variable syntax `TIMESTAMP="$timestamp" echo ...` 
does not work correctly because:
1. The pipe creates a subshell that doesn't inherit the variable
2. The environment variable is set for echo, not for the piped python

Fixed by using `export` and separating the commands:
- export TIMESTAMP="$timestamp"
- echo "$INPUT_JSON" | python3 -c "..."

This ensures the TIMESTAMP variable is available to the python subprocess.

Fixes #227

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 21:25:50 +08:00
Affaan Mustafa
e9343c844b fix: include .md files in instinct-cli glob (completes #216)
The observer agent creates instinct files as .md with YAML frontmatter,
but load_all_instincts() only globbed *.yaml and *.yml. Add *.md to the
glob so instinct-cli status discovers all instinct files.
2026-02-13 01:26:37 -08:00
Affaan Mustafa
307ee05b2d fix: instinct-cli glob and evolve --generate (fixes #216, #217)
- Load both .yaml and .yml files in load_all_instincts() (#216)
  The *.yaml-only glob missed .yml files, causing 'No instincts found'
- Implement evolve --generate to create skill/command/agent files (#217)
  Previously printed a stub message. Now generates SKILL.md, command .md,
  and agent .md files from the clustering analysis into ~/.claude/homunculus/evolved/
2026-02-13 01:09:16 -08:00
Affaan Mustafa
e6e28882db docs: add 'When to Activate' sections to 14 skill definitions
Add activation triggers to skills that were missing them, helping
Claude Code determine when to load each skill contextually.
2026-02-12 15:34:25 -08:00
Affaan Mustafa
f3a4b33d41 fix: harden CI validators, shell scripts, and expand test suite
- Add try-catch around readFileSync in validate-agents, validate-commands,
  validate-skills to handle TOCTOU races and file read errors
- Add validate-hooks.js and all test suites to package.json test script
  (was only running 4/5 validators and 0/4 test files)
- Fix shell variable injection in observe.sh: use os.environ instead of
  interpolating $timestamp/$OBSERVATIONS_FILE into Python string literals
- Fix $? always being 0 in start-observer.sh: capture exit code before
  conditional since `if !` inverts the status
- Add OLD_VERSION validation in release.sh and use pipe delimiter in sed
  to avoid issues with slash-containing values
- Add jq dependency check in evaluate-session.sh before parsing config
- Sync .cursor/ copies of all modified shell scripts
2026-02-12 14:11:33 -08:00
Affaan Mustafa
36864ea11a fix: harden error handling, fix TOCTOU races, and improve test accuracy
Core library fixes:
- session-manager.js: wrap all statSync calls in try-catch to prevent
  TOCTOU crashes when files are deleted between readdir and stat
- session-manager.js: use birthtime||ctime fallback for Linux compat
- session-manager.js: remove redundant existsSync before readFile
- utils.js: fix findFiles TOCTOU race on statSync inside readdir loop

Hook improvements:
- Add 1MB stdin buffer limits to all PostToolUse hooks to prevent
  unbounded memory growth from large payloads
- suggest-compact.js: use fd-based atomic read+write for counter file
  to reduce race window between concurrent invocations
- session-end.js: log when transcript file is missing, check
  replaceInFile return value for failed timestamp updates
- start-observer.sh: log claude CLI failures instead of silently
  swallowing them, check observations file exists before analysis

Test fixes:
- Fix blocking hook tests to send matching input (dev server command)
  and expect correct exit code 2 instead of 1
2026-02-12 13:40:14 -08:00
Affaan Mustafa
e41ee0c858 fix: resolve multiple reported issues (#205, #182, #188, #172, #173) (#207)
* fix: resolve multiple reported issues (#205, #182, #188, #172, #173)

- fix(observe.sh): replace triple-quote JSON parsing with stdin pipe to
  prevent ~49% parse failures on payloads with quotes/backslashes/unicode
- fix(hooks.json): correct matcher syntax to use simple tool name regexes
  instead of unsupported logical expressions; move command/path filtering
  into hook scripts; use exit code 2 for blocking hooks
- fix(skills): quote YAML descriptions containing colons in 3 skill files
  and add missing frontmatter to 2 skill files for Codex CLI compatibility
- feat(rules): add paths: filters to all 15 language-specific rule files
  so they only load when working on matching file types
- fix(agents): align model fields with CONTRIBUTING.md recommendations
  (opus for planner/architect, sonnet for reviewers/workers, haiku for
  doc-updater)

* ci: use AgentShield GitHub Action instead of npx

Switch from npx ecc-agentshield to uses: affaan-m/agentshield@v1
for proper GitHub Action demo and marketplace visibility.
2026-02-11 23:48:45 -08:00
ericcai
e4e94a7e70 fix: preserve content after frontmatter in parse_instinct_file() (#161)
parse_instinct_file() was appending the instinct and resetting state
when frontmatter ended (second ---), before any content lines could be
collected. This caused all content (Action, Evidence, Examples) to be
lost during import.

Fix: only set in_frontmatter=False when frontmatter ends. The existing
logic at the start of next frontmatter (or EOF) correctly appends the
instinct with its collected content.

Fixes #148
2026-02-06 01:00:48 -08:00
Affaan Mustafa
e9dfcdffd0 fix: use CLAUDE_PLUGIN_ROOT for continuous-learning-v2 paths
Fixes #113

The instinct commands referenced hardcoded paths that only work with
manual installation (~/.claude/skills/...). When installed as a plugin,
files are at ~/.claude/plugins/cache/.../skills/...

Changes:
- Updated instinct-status, instinct-import, evolve commands to use
  ${CLAUDE_PLUGIN_ROOT} with fallback to manual path
- Updated observe.sh hook documentation with both install methods
- Updated SKILL.md with plugin vs manual installation instructions
- Removed duplicate commands from skills/continuous-learning-v2/commands/
  (already exist in commands/)

Users should use ${CLAUDE_PLUGIN_ROOT} in their hooks config when
installed as a plugin.
2026-01-29 12:23:53 -08:00
Affaan Mustafa
5c63fa9006 feat: v1.1.0 release - session ID tracking, async hooks, new skills
- Add session ID to session filenames (Issue #62)
- Add getSessionIdShort() helper for unique per-session tracking
- Add async hooks documentation with example
- Create iterative-retrieval skill for progressive context refinement
- Add continuous-learning-v2 skill with instinct-based learning
- Add ecc.tools ecosystem section to README
- Update skills list in README

All 67 tests passing.
2026-01-25 18:21:27 -08:00