Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
31ea773
feat(instructions): require task entity creation on actionable user i…
castor-agent May 19, 2026
54fe96b
feat(instructions): strengthen agent guidance for entity relationship…
castor-agent May 19, 2026
9615b86
ci(review): post comment explaining why automatic review was skipped
castor-agent May 20, 2026
004ed9c
feat(inspector): bump submodule, search fix, and shadcn docs
castor-agent May 20, 2026
73b04ff
feat(skills): add skill entity seed schema and boot-time registration
castor-agent May 20, 2026
e3a1892
docs(skills): add user-facing skills guide and Feature guides entry
castor-agent May 20, 2026
641f79f
feat(skill): auto-create REFERS_TO from workout_session to source con…
castor-agent May 19, 2026
022d849
fix(schema): graceful fallback when update_schema_incremental called …
castor-agent May 19, 2026
4432bdb
docs(schema): standardize source field semantics across entity types …
castor-agent May 19, 2026
d105b3c
feat(instructions): prompt for issue-filing consent on first encounte…
castor-agent May 19, 2026
0ebbc1a
feat(security): sandbox mode resolver + boot-time topology gating (pl…
castor-agent May 19, 2026
5689503
fix(inspector): bump submodule to fix usage page TS errors
castor-agent May 20, 2026
1fc66b2
fix(config): load project .env before user config so worktree can ove…
castor-agent May 20, 2026
902f573
Wire local_sandbox mode into auth middleware — per-install sandbox pr…
castor-agent May 20, 2026
7fb9ada
feat: mode taxonomy + inspector bundling + content-negotiation unific…
castor-agent May 20, 2026
fce8e97
chore(test-catalog): regenerate automated test catalog
castor-agent May 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions .claude/rules/change_guardrails_rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,6 @@ These rules sit between subsystems. Each canonical doc covers its own surface; o
16. Authority over loopback / proxy / `X-Forwarded-For` trust lives in `src/actions.ts` (`isLocalRequest`, `forwardedForValues`, `isProductionEnvironment`) and the matching helpers in `src/services/root_landing/**`. Any new code that needs to know "is this request local?" MUST consume those exports — not a bare `req.socket.remoteAddress` check, not a `Host` header read, not an inlined fork (`docs/security/threat_model.md`). Treat the v0.11.1 advisory shape as a regression class, not a one-off.
17. Every new Express route MUST land in `scripts/security/protected_routes_manifest.json` (auth-required) or in the runtime allow-list with a stated `reason`. Run `npm run security:manifest:write` in the same change; CI's `security_gates` job runs `--check` and rejects drift.
18. Every release that the diff classifier (`scripts/security/classify_diff.js`) labels `sensitive=true` MUST land with a filled `docs/releases/in_progress/<TAG>/security_review.md` and a supplement `Security hardening` section linking it. `none` provider mode is acceptable, manual fill is mandatory.
19. Every new **destructive or data-mutating operation** (DB migration, encryption migration, repair command, bulk-rewrite over user data) MUST ship with a real round-trip integration test that operates on a real file, not in-memory stubs. The test MUST cover: identity (forward→inverse leaves the data unchanged), dry-run non-mutation, idempotency on re-run, and NULL preservation. See `docs/testing/testing_standard.md` § Destructive operations.
20. Every new **external-file-shape parser** (harness transcripts, SQLite imports, third-party config formats) MUST ship with a test that exercises the actual parsing path against a fixture file in the supported format. Detection-only tests (asserting `detectSource` returns the right tag) are not coverage of parsing.
21. Every new **HTTP server runtime-config knob** (timeouts, connection behavior, header policy) MUST ship with a test that asserts the *runtime* behavior — a response header value, a socket lifetime, an observable connection property — not just the source string. A constant declared in code with no runtime assertion regresses silently.

### MUST NOT

Expand Down Expand Up @@ -152,11 +149,6 @@ Before opening a PR that touches any surface in the Touchpoint Matrix, confirm:
- [ ] `npm run security:classify-diff` recorded; if `sensitive=true`, `npm run security:lint` is clean, `npm run security:manifest:check` passes, `npm run test:security:auth-matrix` passes, and `docs/releases/in_progress/<TAG>/security_review.md` exists with a sign-off verdict.
- [ ] New Express routes registered in `protected_routes_manifest.json` (or runtime unauth allow-list with a `reason`); manifest regenerated via `npm run security:manifest:write` when needed.
- [ ] No bare `req.socket.remoteAddress`, `X-Forwarded-For`, or `Host` reads outside `src/actions.ts` / `src/services/root_landing/**`; auth-local fallbacks (`!auth && isLocalRequest`) gated through `assertExplicitlyTrusted`.
- [ ] **User-facing-surface coverage**: any new CLI command, new CLI flag, new destructive/data-mutating operation, new external-file-shape parser, or new HTTP runtime-config knob has a test that exercises the **user-observable behavior end-to-end**, not just a helper function. A test file with the right name that only covers an internal helper is not coverage. Required regression tests by surface class:
- Destructive operations (DB migrations, encryption migrations, repair commands): real round-trip test against a real file — encrypt→decrypt identity, dry-run non-mutation, idempotency on re-run, NULL preservation.
- External-file-shape parsers (harness transcripts, SQLite imports, third-party config): at least one fixture per supported format that exercises the actual parser path, not just `detectSource`.
- Discovery / detection / parser pairs: a roundtrip test asserting paths emitted by discovery are parseable by the parser.
- HTTP runtime config (timeouts, headers, keep-alive): a test that asserts the *runtime* behavior (response header, socket lifetime), not just the source string.

## Canonical doc index

Expand Down
37 changes: 37 additions & 0 deletions .claude/rules/gmail_proactive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
description: Agents MUST use the Gmail MCP proactively to check email whenever task context makes it relevant, without waiting to be asked.
globs:
alwaysApply: true
---

<!-- Source: foundation/agent_instructions/cursor_rules/gmail_proactive.mdc -->


# Gmail Proactive Check Rule

## Purpose

Ensures agents check Gmail proactively when task context implies email may contain relevant information, rather than waiting for an explicit instruction to check.

## Trigger Patterns

Agents MUST check Gmail proactively when:

- Waiting on an external action that sends email confirmation (account signups, invitations, verifications, notifications)
- A workflow step is blocked pending an email (e.g. invitation acceptance, token delivery, approval)
- The user asks about status of something that would be communicated via email
- Setting up third-party integrations that send credentials or confirmation links by email
- Any context where "did the email arrive?" is a natural next question

## Agent Actions

1. Use `mcp__aa7dd3ca-ee1b-423d-8787-cf03044822ee__search_threads` with a targeted query (recipient, sender, subject keywords, time window)
2. If relevant emails are found, surface the key details and next action
3. If no relevant emails are found, report that and suggest next steps

## Constraints

- MUST check Gmail proactively when task context implies email is a dependency — do not wait for the user to say "check my email"
- MUST use targeted queries (narrow by sender, recipient, subject, or time) rather than fetching all mail
- MUST store any emails retrieved in Neotoma per the external-tool store-first rule
- MUST NOT check Gmail in unrelated contexts where email is not a plausible dependency
81 changes: 81 additions & 0 deletions .claude/rules/inspector_shadcn_rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
description: Enforce shadcn/ui primitives in Inspector UI work; prefer existing inspector components over native HTML controls.
globs:
- inspector/**
alwaysApply: false
---

<!-- Source: docs/ui/inspector_shadcn_rules.mdc -->


# Inspector shadcn UI Rules

## Purpose

Keep the Inspector app visually and behaviorally consistent with the Neotoma design system by using shadcn/ui-style primitives from `inspector/src/components/ui/` instead of ad hoc native HTML controls and one-off Tailwind patterns.

Inspector is an inspection surface, not a marketing or agentic UI. Prefer consistency, accessibility, and design tokens over decorative variation.

## Canonical references

- `docs/ui/shadcn_components.md` — component inventory and Select vs DropdownMenu guidance
- `docs/ui/design_system/implementation_notes.md` — prefer shadcn over native HTML, tokens, dark mode, WCAG AA
- `docs/ui/inspector_shadcn_audit.md` — route-level adoption backlog (if present)

## Installed primitives (`inspector/src/components/ui/`)

Prefer these when they fit the interaction. Do not add new primitives in feature work without a short justification.

**Core (use first):** `Button`, `Input`, `Label`, `Textarea`, `Select`, `Card`, `Badge`, `Separator`, `Dialog`, `Sheet`, `Alert`, `Skeleton`, `Tooltip`, `ScrollArea`, `Tabs`, `Switch`, `DropdownMenu`

**Composites (preserve mirror contract):** `DataTable`, `Pagination`, `ConfirmDialog` — keep in sync with `frontend/src/components/ui/` when editing; see comments in those files.

**Available but often unused in pages:** `Checkbox`, `Popover`, `Toggle`, `ToggleGroup` — use them before inventing custom segmented controls or native checkboxes.

**Not present in Inspector yet (add only with plan):** shadcn `Table` markup inside `DataTable`, `AlertDialog` (prefer `ConfirmDialog` until added), `Command` for search/command palettes.

## MUST

### Control selection

- **MUST** use `Select` from `@/components/ui/select` for single-value dropdowns. **MUST NOT** use native `<select>` (including `agent_filter.tsx` and similar filters).
- **MUST** use `DropdownMenu` for context menus, column visibility, and action menus — not `Select`.
- **MUST** use `Button` with appropriate `variant` and `size` instead of raw `<button>` with hand-rolled border/background classes.
- **MUST** use `Checkbox` + `Label` for boolean row selection and multi-select lists — not native `<input type="checkbox">`.
- **MUST** use `Textarea` for multi-line text entry — not unstyled native `<textarea>` except where a documented exception applies.
- **MUST** use `ToggleGroup` / `ToggleGroupItem` for segmented filters (e.g. open/closed/all, formatted/raw) — not custom `role="group"` button clusters unless accessibility requirements cannot be met with shadcn.
- **MUST** use `Badge` for status, labels, and compact chips — not ad hoc `rounded-full` span pills with hard-coded palette classes.
- **MUST** use `Alert` or shared `QueryErrorAlert` for errors — not bare `<p className="text-destructive">` alone.
- **MUST** use `ConfirmDialog` (or `AlertDialog` once added) for destructive confirmations — **MUST NOT** use `window.confirm`.

### Layout and tokens

- **MUST** use design tokens from `inspector/src/index.css` (`--background`, `--foreground`, `--primary`, `--border`, `--muted`, `--destructive`, sidebar/popover tokens, etc.). **MUST NOT** hard-code one-off hex colors for product chrome (graph node styling may use theme-aware variables when touched).
- **MUST** preserve semantic `<Link>` from `react-router-dom` for navigation; do not replace links with `Button` unless the control is an action, not navigation.

### Data display

- **MUST** use shared `DataTable` for tabular data — do not add parallel raw `<table>` layouts in pages.
- **MUST** use `Card` / `CardHeader` / `CardContent` for grouped content blocks when replacing hand-built bordered `div` list cards (e.g. sources list, issue rows) unless a feed-specific layout is intentionally feed-only.

## SHOULD

- **SHOULD** use `Sheet` for slide-over detail (markdown preview, large JSON) where a side panel pattern already exists.
- **SHOULD** use `Skeleton` / shared loading helpers from `components/shared/query_status.tsx` for loading states.
- **SHOULD** migrate highest-traffic inconsistency surfaces first: `pages/issues.tsx`, `pages/issue_detail.tsx`, `components/shared/agent_filter.tsx`, then segmented controls in `entity_detail.tsx` and `components/shared/inspector_theme_toggle.tsx`.

## MUST NOT

- **MUST NOT** introduce new UI primitives under `inspector/src/components/ui/` without updating `docs/ui/shadcn_components.md` and noting why.
- **MUST NOT** duplicate full shadcn component source into pages — import from `@/components/ui/*` and `@/lib/utils` (`cn`).
- **MUST NOT** edit files under `.claude/rules/` or `.claude/skills/` — edit this file and run `npm run setup:cursor` (or `./scriptsscripts/setup_claude_instructions.sh.sh`).

## Validation

Before marking Inspector UI work complete:

- [ ] No new native `<select>` for product controls in touched files
- [ ] No new raw `<button>` for primary actions in touched files (except inside shadcn `Button` composition patterns)
- [ ] Errors and confirmations use shared alert/confirm patterns
- [ ] `npm run lint` and `npm run build` succeed in `inspector/`
- [ ] Smoke-test changed routes (especially Issues, Settings, entity detail) in light and dark mode
86 changes: 86 additions & 0 deletions .claude/rules/publish_plan_prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
description: Prompt to publish plan to GitHub Discussions after any plan file is created or updated.
globs:
- "docs/releases/in_progress/**/release_plan.md"
- "docs/feature_units/in_progress/**/*_spec.md"
- ".cursor/plans/**/*.md"
- ".cursor/plans/**/*.plan.md"
alwaysApply: false
---

<!-- Source: foundation/agent_instructions/cursor_rules/publish_plan_prompt.mdc -->


# Publish Plan Prompt Rule

## Purpose

Ensures users are offered the option to share a newly written plan as a
GitHub Discussion post for pre-execution public input, without blocking
the workflow if they decline.

## Trigger Patterns

Offer the publish-plan prompt after any of the following:

- A release plan file is created or substantially updated
(`docs/releases/in_progress/**/release_plan.md`)
- A feature unit spec is created or substantially updated
(`docs/feature_units/in_progress/**/*_spec.md`)
- A plan file is created under `.cursor/plans/`
- The user completes the `create-release` or `create-feature-unit` skill
- The user writes or edits a file whose name includes `plan`, `spec`, or
`release_plan` and the file contains a goal, scope, or decisions section

Do NOT trigger when:
- The plan file already has a corresponding GitHub Discussion linked
- The user explicitly declined in the same session
- The file is a template, example, or stub (fewer than 30 lines)

## Agent Actions

### Step 1: Detect plan creation

After writing a plan file that meets the trigger conditions, check
whether a publish-plan prompt is appropriate:

1. Confirm the file has substantive content (goal, approach, or scope
section present).
2. Confirm the file is not a template or stub.
3. Confirm the user has not already declined in this session.

### Step 2: Offer the prompt

Present a single, non-blocking offer immediately after reporting that
the plan file was created:

```
Plan saved to {path}.

Would you like to share this as a GitHub Discussion for pre-execution
input? Run /publish-plan {path} to generate a public-facing post.
```

- One line, no pressure, no follow-up questions.
- Do not re-offer if the user does not respond or says no.
- Do not block any subsequent workflow steps on the user's answer.

### Step 3: If user says yes

Invoke the `publish-plan` skill:

```
/publish-plan {path}
```

Pass the plan file path as the argument. Let the skill handle all
subsequent steps (stripping PII, drafting the post, posting to
Discussions).

## Constraints

- MUST offer the prompt at most once per plan file per session.
- MUST NOT block workflow continuation on the user's response.
- MUST NOT re-offer after a decline.
- MUST pass the exact file path to `/publish-plan` without modification.
- MUST NOT offer for templates, stubs, or files under 30 lines.
14 changes: 1 addition & 13 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"env": {},
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "cd /Users/markmhendrickson/repos/neotoma && npm run mirror:plans 2>&1 | tail -5"
}
]
}
]
}
"hooks": {}
}
11 changes: 7 additions & 4 deletions .claude/skills/analyze/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
name: analyze
description: Analyze Project
---

<!-- Source: foundation/.cursor/skills/analyze/SKILL.md -->

---
name: analyze
description: Analyze codebase or context per foundation analyze command.
Expand Down Expand Up @@ -400,7 +407,6 @@ This command performs systematic analysis following the framework defined in `fo
**If no foundational docs exist:**

```
⚠️ Warning: No foundational documents found in `docs/foundation/`.
Analysis will proceed without repo-specific context.

Recommendation: Create foundational documents for better analysis:
Expand Down Expand Up @@ -431,7 +437,6 @@ Enter choice (1/2/3):
**If `docs/private/` doesn't exist:**

```
⚠️ Warning: Private docs directory not found at `docs/private/`.

Output will be saved to:
- docs/competitive/[target_name]_competitive_analysis.md
Expand All @@ -448,7 +453,6 @@ Proceed? (yes/no)
**If web scraper URL is provided but MCP server is not configured:**

```
⚠️ Notice: Web scraper MCP server not configured for URL "[url]".

Falling back to browser tools for research.

Expand All @@ -462,7 +466,6 @@ Proceeding with browser tools...
**If web scraper MCP tool fails:**

```
⚠️ Warning: Web scraper failed for URL "[url]".

Error: [error message]

Expand Down
12 changes: 4 additions & 8 deletions .claude/skills/audit/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
---
name: audit
description: Audit a Neotoma database for graph-health issues (duplicate or redundant entity types, misused types, excessive raw_fragments, non-humanreadable canonical names, orphans, cycles, schema drift). Runs deterministic checks first; LLM-assisted checks are opt-in. Detection separate from repair — emits structured remediation hints pointing at existing tools (merge_entities, correct, register_schema, split_entity, delete_entity).
triggers:
- audit
- /audit
- audit neotoma
- check database health
- find duplicates in neotoma
- clean up neotoma graph
description: audit
---

<!-- Source: .cursor/skills/audit/SKILL.md -->


# audit

## Purpose
Expand Down
15 changes: 11 additions & 4 deletions .claude/skills/commit/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---
name: commit
description: commit
---

<!-- Source: foundation/.cursor/skills/commit/SKILL.md -->

---
name: commit
description: Commit submodules and/or main repo with structured messages; supports /commit repo, /commit <submodule>.
Expand Down Expand Up @@ -292,14 +299,14 @@ Run entire test suite and resolve any errors as necessary. Proceed to analyze al

**CRITICAL: PRE-COMMIT SECURITY AUDIT** - MUST RUN BEFORE STAGING:

Execute security audit from `foundation/agent_instructions/cursor_rules/security.md` (or `.cursor/rules/foundation_security.md` if installed) before staging ANY files:
Execute security audit from `foundation/agent_instructions/cursor_rules/security.md` (or `.claude/rules/foundation_security.md` if installed) before staging ANY files:

1. **Run security audit script:**
```bash
# Use foundation security audit script if available
if [ -f "foundation/security/pre-commit-audit.sh" ]; then
./foundation/security/pre-commit-audit.sh
elif [ -f ".cursor/rules/foundation_security.md" ]; then
elif [ -f ".claude/rules/foundation_security.md" ]; then
# Follow security rule checks
# (Implementation depends on how security rules are executed)
fi
Expand Down Expand Up @@ -719,7 +726,7 @@ development:
# Use foundation security audit script or rules
if [ -f "foundation/security/pre-commit-audit.sh" ]; then
./foundation/security/pre-commit-audit.sh
elif [ -f ".cursor/rules/foundation_security.md" ]; then
elif [ -f ".claude/rules/foundation_security.md" ]; then
# Follow security rule checks
fi

Expand All @@ -729,7 +736,7 @@ fi

If final security check passes, proceed to git commit with the comprehensive commit message and push to origin. **If push is rejected** (remote has new commits): run `git pull --rebase origin <current_branch>` (or `git pull origin <current_branch> --no-rebase --no-edit`), resolve any conflicts, then `git push origin HEAD` again. Always reconcile and retry before reporting push failure.

**WORKTREE DETECTION:** Follow the Worktree Rule (`.cursor/rules/foundation_worktree_env.md` or `foundation/agent_instructions/cursor_rules/worktree_env.md`) to restrict all commit activity to the current worktree.
**WORKTREE DETECTION:** Follow the Worktree Rule (`.claude/rules/foundation_worktree_env.md` or `foundation/agent_instructions/cursor_rules/worktree_env.md`) to restrict all commit activity to the current worktree.

**COMMIT MESSAGE DISPLAY**: After successfully committing and pushing, always display the full commit message to the user by running `git log -1 --pretty=format:"%B"` and showing the output. This allows the user to review what was committed.

Expand Down
Loading