> For the complete documentation index, see [llms.txt](https://faction-os.gitbook.io/faction-os-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://faction-os.gitbook.io/faction-os-docs/.spec_system/archive/sessions/phase18-session07-scan-orchestration-and-quest-ignore-patterns/spec.md).

# Session Specification

**Session ID**: `phase18-session07-scan-orchestration-and-quest-ignore-patterns` **Phase**: 18 - Quest Board Suggestion Parity **Status**: Complete **Created**: 2026-06-10 **Package**: Cross-package (apps/server, apps/web) **Package Stack**: TypeScript

***

## 1. Session Overview

This session turns the Session 06 scanner primitives into an operator-facing Quest Board scan workflow. The server will own full, diff, and daily codebase scan orchestration, track the last scan commit and in-progress status, and persist scan results through the existing `SuggestionManager` path so Quest Board snapshots stay canonical.

The session also adds configurable Quest ignore patterns. The historical evidence used `.agentcraftignore`; this implementation records the FactionOS runtime name as `.factionos-questignore` and merges that repo-level file with browser Settings patterns sent by the scan request. The merged ignore list must apply consistently to TODO-family, git status, lint, build/typecheck, and test failure scanners.

Primary implementation lives in `apps/server`. The `apps/web` work is limited to persisting a bounded Quest ignore pattern field in Settings and sending it with the existing local scan action. Quest Board card rendering, action buttons, analysis engines, project scans, and keyboard shortcuts remain later sessions.

***

## 2. Objectives

1. Implement full, diff, and daily scan orchestration over the Session 06 codebase issue scanners.
2. Track scan status, last completed time, last error, and last scanned commit through manager-owned Quest Board state.
3. Add `.factionos-questignore` plus Settings-backed ignore patterns and apply them to every codebase issue scanner.
4. Ship `POST /suggestions/scan` and `GET /suggestions/scan/status` under root and `/api`, with validation, in-flight guards, and unsupported-route reconciliation.

***

## 3. Prerequisites

### Required Sessions

* [x] `phase18-session01-protocol-suggestion-contract-parity` - provides scan status, scan mode, scan scope, REST response, and Quest Board snapshot contracts.
* [x] `phase18-session02-server-suggestion-manager-and-persistence` - provides manager-owned persisted suggestion state and atomic local writes.
* [x] `phase18-session03-suggestion-routes-and-websocket-parity` - provides suggestion route mounting under root and `/api` plus update emission.
* [x] `phase18-session04-idle-lifecycle-engine-parity` - establishes bounded server lifecycle work with in-flight guards and fallback behavior.
* [x] `phase18-session05-session-summary-engine-and-noise-filtering` - proves session summary state can coexist with analysis filtering and snapshots.
* [x] `phase18-session06-codebase-issue-scanners` - provides default-off local TODO, git status, lint, build/typecheck, and test scanners.

### Required Tools/Knowledge

* Node 26.2.0 or newer with npm workspaces.
* Existing `SuggestionManager`, `codebaseIssueScanners`, `unsupportedRoutes`, `llmPrivacy`, server route, and Settings drawer patterns.
* Phase 18 PRD Appendix A as traceability evidence only; no historical code, bundle, or asset import.

### Environment Requirements

* Work from the repository root.
* Use package-relative monorepo paths from the repo root.
* Keep all generated and edited files ASCII-only with Unix LF line endings.

***

## 4. Scope

### In Scope (MVP)

* Operators can trigger a codebase scan through `POST /suggestions/scan`, with a `full=true` or equivalent force-full option.
* Operators can read scan state through `GET /suggestions/scan/status`, with explicit idle, running, succeeded, and failed states.
* The server can run a full scan over all enabled codebase issue scanners and persist results through the manager.
* The server can run a commit-aware diff scan that discovers working, staged, and committed changed files since the last scanned commit.
* Diff scans reuse cached TODO-family issues for unchanged files and fall back to a full scan when no prior commit or usable cache exists.
* The server stores the last scanned commit and last scan timestamps in manager-owned scan status.
* The server starts a non-blocking daily/staleness full scan when the 24-hour codebase scan freshness window has lapsed.
* Quest ignore patterns merge browser Settings patterns with a repo-level `.factionos-questignore` file.
* Ignore matching applies before source-file scanning and before command-output issues are stored.
* The web Settings drawer adds a bounded Quest ignore pattern field and sends patterns with the local scan request.
* Focused tests cover full/diff selection, commit tracking, cache reuse, ignored path exclusion, route validation, in-flight status, and web settings persistence.

### Out of Scope (Deferred)

* On-demand analysis and project-scan engines and routes - *Reason: Session 08 owns LLM-backed analysis and project scans.*
* Typed multi-source Quest Board card rendering - *Reason: Session 09 owns web card normalization and rendering.*
* Quest Board action buttons, assignment flows, and keyboard shortcuts - *Reason: Session 10 owns interactions.*
* Accepting codebase issues as quests - *Reason: Phase 18 deliberately limits codebase issues to dismiss-only parity.*
* Historical suggestion telemetry and entitlement gates - *Reason: Phase 18 explicitly excludes analytics capture and entitlement gating.*

***

## 5. Technical Approach

### Architecture

Add a server orchestration boundary in `apps/server/src/lib/codebaseScanOrchestrator.ts`. It will coordinate full, diff, and daily scans, own single-flight behavior, set `SuggestionManager` scan status before and after each run, and emit canonical suggestion updates whenever scan state or issue state changes.

Add a Quest ignore helper in `apps/server/src/lib/questIgnore.ts`. It should normalize line-based patterns from the request and `.factionos-questignore`, drop comments and blank lines, reject absolute paths and parent traversal, and match safe relative paths with deterministic behavior. Matching should be small and dependency-free; use path-segment and simple wildcard handling rather than adding a new glob package.

Extend the Session 06 scanner boundary so callers can provide a changed-file subset and an ignore predicate. Full scans pass the entire approved root; diff scans pass the changed files and then merge cached TODO-family issues for unchanged files. Command-backed scanner issues are filtered through the same ignore predicate after parser normalization.

### Design Patterns

* Manager-owned state: scan status and issue replacement happen through `SuggestionManager`.
* Single-flight lifecycle: route and startup scans share one orchestrator so duplicate triggers report a conflict or current status instead of racing.
* Pure helpers before side effects: git output parsing, ignore matching, and diff selection stay deterministic and fixture-testable.
* Bounded local commands: git helpers and scanner commands use timeouts, bounded output, and compact failure mapping.
* Local-first privacy: no provider calls, no hosted transfer, no raw command logs, no absolute path persistence, and no file-content persistence.

### Technology Stack

* TypeScript in `apps/server` and `apps/web`.
* Existing Express 5 route mounting, in-process rate limiting, and local auth.
* Existing `@factionos/protocol` suggestion scan status contracts.
* Existing Zustand Settings store and React Settings drawer.
* Vitest for server and web tests.

***

## 6. Deliverables

### Files to Create

| File                                                 | Purpose                                                                                                                  | Est. Lines |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ---------- |
| `apps/server/src/lib/questIgnore.ts`                 | Normalize request and `.factionos-questignore` patterns, load repo ignore file, and match safe relative paths            | \~220      |
| `apps/server/src/lib/codebaseScanOrchestrator.ts`    | Full, diff, and daily scan orchestration with single-flight status, git commit helpers, cache reuse, and manager updates | \~420      |
| `apps/server/tests/questIgnore.test.ts`              | Ignore pattern parsing, safe path filtering, file loading, and path matching tests                                       | \~180      |
| `apps/server/tests/codebaseScanOrchestrator.test.ts` | Full/diff/daily orchestration, commit tracking, fallback, cache reuse, status, and ignored path tests                    | \~360      |

### Files to Modify

| File                                            | Changes                                                                                                         | Est. Lines |
| ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ---------- |
| `apps/server/src/lib/codebaseIssueScanners.ts`  | Accept changed-file subsets and ignore predicates; filter source and command issues consistently                | \~120      |
| `apps/server/src/managers/suggestionManager.ts` | Add manager-owned issue replacement or clear-and-replace helper for scan result transactions if needed          | \~80       |
| `apps/server/src/routes/suggestions.ts`         | Add scan trigger and status routes with validated input and duplicate-trigger prevention                        | \~180      |
| `apps/server/src/server.ts`                     | Instantiate the scan orchestrator, pass it into suggestion routes, and schedule non-blocking stale startup scan | \~80       |
| `apps/server/src/lib/unsupportedRoutes.ts`      | Remove shipped scan route prefixes while keeping analyze and project-scan routes planned                        | \~30       |
| `apps/server/tests/suggestionRoutes.test.ts`    | Cover scan route validation, status responses, and root plus `/api` behavior                                    | \~180      |
| `apps/server/tests/unsupportedRoutes.test.ts`   | Update planned route expectations after scan routes ship                                                        | \~40       |
| `apps/server/README_server.md`                  | Document scan orchestration, `.factionos-questignore`, route behavior, and privacy limits                       | \~70       |
| `apps/web/src/store/useSettingsStore.ts`        | Persist bounded `questIgnorePatterns` plus setter and hydration fallback                                        | \~80       |
| `apps/web/src/lib/scanCodebase.ts`              | Send Quest ignore patterns to the scan route and parse status-style responses                                   | \~120      |
| `apps/web/src/components/SettingsDrawer.tsx`    | Add accessible Quest ignore pattern control and wire it into the local scan action                              | \~120      |
| `apps/web/tests/useSettingsStore.test.ts`       | Cover persisted Quest ignore patterns and malformed snapshot recovery                                           | \~80       |
| `apps/web/tests/SettingsScan.test.tsx`          | Cover ignore-pattern field rendering, persistence, request payload, and scan status feedback                    | \~160      |
| `apps/web/README_web.md`                        | Document the Settings ignore pattern field and local-only scan payload boundary                                 | \~40       |

***

## 7. Success Criteria

### Functional Requirements

* [ ] `POST /suggestions/scan` accepts a validated scan trigger, starts a scan, prevents duplicate in-flight triggers, and returns current scan status.
* [ ] `GET /suggestions/scan/status` returns accurate in-progress, last-start, last-complete, last-error, and last-commit state.
* [ ] Full scans run all Session 06 codebase issue scanners and persist manager-owned Quest Board issues.
* [ ] Diff scans include working, staged, and committed changed files since the last scanned commit.
* [ ] Diff scans reuse cached TODO-family issues for unchanged files and fall back to full scans when no prior commit or cache exists.
* [ ] Startup daily scan runs without blocking server readiness when the 24-hour codebase scan freshness window has lapsed.
* [ ] `.factionos-questignore` and Settings ignore patterns are merged and applied to every scanner before issues are stored.
* [ ] Scan routes are no longer classified as unsupported; analyze and project-scan routes remain planned.

### Testing Requirements

* [ ] Server unit tests cover ignore parsing, path matching, and unsafe pattern rejection.
* [ ] Server unit tests cover full/diff selection, commit tracking, fallback, cache reuse, status updates, and ignored path exclusion.
* [ ] Server route tests cover validation, duplicate-trigger behavior, root and `/api` mounting, and compact error mapping.
* [ ] Web tests cover Settings persistence, malformed snapshots, request payloads, loading, error, offline, and status display.

### Non-Functional Requirements

* [ ] Scan orchestration does not send prompts, file contents, command bodies, raw command logs, absolute paths, or scan payloads to providers or hosted services.
* [ ] Local command execution uses timeouts, bounded output, and failure-path handling.
* [ ] Server startup remains non-blocking even when stale-scan work is queued.
* [ ] Settings UI preserves keyboard, pointer, and screen-reader access.

### Quality Gates

* [ ] All files ASCII-encoded.
* [ ] Unix LF line endings.
* [ ] Code follows project conventions.
* [ ] Focused server and web tests pass.
* [ ] `npm --workspace apps/server run typecheck` and `npm --workspace apps/web run typecheck` pass.

***

## 8. Implementation Notes

### Key Considerations

* Use `.factionos-questignore` for the repo-level ignore file. Record it in package docs so the historical `.agentcraftignore` name stays evidence-only.
* Route parsing must accept the historical `?full=true` branch while also supporting a typed body option such as `{ "forceFull": true }`.
* Startup stale scans should be fire-and-forget after server creation, but the orchestrator must still expose cleanup so shutdown cannot leave pending timers or status stuck in `running`.
* The existing `/llm/scan-codebase` route is separate from Quest Board scan orchestration. Do not remove it in this session unless implementation proves a no-drift compatibility path.

### Potential Challenges

* Diff cache correctness: reuse cached TODO-family issues only when their file path is unchanged and not ignored; fall back to a full scan if cache shape is ambiguous.
* Git availability: missing git, detached state, or non-repository roots should degrade to a full scan or compact failure without exposing raw command output.
* Settings-to-server drift: browser patterns are local preferences, so startup daily scans can only use `.factionos-questignore` and server-side defaults.

### Relevant Considerations

* \[P03-packages/protocol] **Protocol leads cross-package work**: Session 01 already owns shared scan status contracts; only change protocol if an implementation blocker appears.
* \[P17-apps/server] **Manager-owned persistence and cleanup**: Keep scan status, issue replacement, and shutdown cleanup inside server-owned boundaries.
* \[P17-apps/web] **Pure normalization before store mutation**: Normalize persisted Settings patterns before committing them to Zustand state.
* \[P01-apps/server] **Anthropic transfer is two-level opt-in**: This session does not need provider calls; keep scan orchestration local-only.
* \[P03-apps/server] **Local server boundary must stay conservative**: New routes must keep validation, rate limits, auth, body caps, and compact errors.
* \[P07] **Redaction is boundary-specific**: Ignore patterns, scan output, and route responses must avoid broad absolute paths, raw command logs, secrets, file contents, prompts, and transcripts.
* \[P03] **Stable docs are the current contract**: Update package README notes for shipped scan orchestration without using `EXAMPLES/` as runtime source.

### Behavioral Quality Focus

Checklist active: Yes Top behavioral risks for this session:

* Duplicate scan triggers can race and corrupt status or issue state.
* Startup daily scans can leave status stuck in `running` if shutdown or git failure interrupts work.
* Ignore patterns can be over-broad or unsafe if absolute paths, traversal, or malformed wildcards are accepted without normalization.
* Settings scan UI can show stale status or leak raw root paths if request and response parsing are not bounded.

***

## 9. Testing Strategy

### Unit Tests

* `apps/server/tests/questIgnore.test.ts`: pattern normalization, comment and blank-line handling, unsafe pattern rejection, `.factionos-questignore` loading, and safe relative path matching.
* `apps/server/tests/codebaseScanOrchestrator.test.ts`: full scan status, diff changed-file selection, last commit tracking, fallback to full scan, cached TODO issue reuse, ignored path exclusion, and stale daily scan decisioning.
* `apps/web/tests/useSettingsStore.test.ts`: persisted `questIgnorePatterns`, malformed snapshots, reset behavior, and storage fallback.

### Integration Tests

* `apps/server/tests/suggestionRoutes.test.ts`: root and `/api` scan routes, validation failures, duplicate in-flight trigger handling, status response, and suggestion update side effects.
* `apps/server/tests/unsupportedRoutes.test.ts`: shipped scan routes are no longer planned unsupported routes while analyze and project scan remain planned.
* `apps/web/tests/SettingsScan.test.tsx`: Settings ignore field, request body, loading state, status summary, error state, and offline state.

### Manual Testing

* Start the server with an approved local scan root.
* Create a `.factionos-questignore` file that ignores a known TODO file.
* Trigger a full scan through Settings and verify ignored files do not appear in Quest Board scan results.
* Trigger a second scan and verify diff/status behavior without broad path leakage.

### Edge Cases

* Missing git executable or non-git scan root.
* No prior commit or no cached TODO-family issues.
* Empty ignore file and empty Settings patterns.
* Pattern attempts using absolute paths, `..`, backslashes, or NUL bytes.
* Duplicate scan trigger while a scan is running.
* Server shutdown while startup stale scan is queued.

***

## 10. Dependencies

### External Libraries

* None. Use existing Node APIs and current dependencies only.

### Other Sessions

* **Depends on**: `phase18-session06-codebase-issue-scanners`
* **Depended by**: `phase18-session08-on-demand-analysis-and-project-scan-engines`, `phase18-session10-quest-actions-and-keyboard-shortcuts`, `phase18-session11-validation-documentation-and-handoff`

***

## Next Steps

Run the implement workflow step to begin AI-led implementation.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://faction-os.gitbook.io/faction-os-docs/.spec_system/archive/sessions/phase18-session07-scan-orchestration-and-quest-ignore-patterns/spec.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
