Module: Woods

Defined in:
lib/woods/console/eval_guard.rb,
lib/woods.rb,
lib/woods/tasks.rb,
lib/woods/builder.rb,
lib/woods/railtie.rb,
lib/woods/version.rb,
lib/woods/ast/node.rb,
lib/woods/extractor.rb,
lib/woods/retriever.rb,
lib/woods/ast/parser.rb,
lib/woods/cost_model.rb,
lib/woods/mcp/errors.rb,
lib/woods/mcp/server.rb,
lib/woods/atomic_file.rb,
lib/woods/db/migrator.rb,
lib/woods/retry_after.rb,
lib/woods/token_utils.rb,
lib/woods/update_check.rb,
lib/woods/flow_document.rb,
lib/woods/notion/client.rb,
lib/woods/notion/mapper.rb,
lib/woods/ruby_analyzer.rb,
lib/woods/chunking/chunk.rb,
lib/woods/console/bridge.rb,
lib/woods/console/server.rb,
lib/woods/extracted_unit.rb,
lib/woods/feedback/store.rb,
lib/woods/filename_utils.rb,
lib/woods/flow_assembler.rb,
lib/woods/git_provenance.rb,
lib/woods/graph_analyzer.rb,
lib/woods/index_artifact.rb,
lib/woods/storage/qdrant.rb,
lib/woods/formatting/base.rb,
lib/woods/mcp/bearer_auth.rb,
lib/woods/notion/exporter.rb,
lib/woods/obsidian/errors.rb,
lib/woods/resolved_config.rb,
lib/woods/util/host_guard.rb,
lib/woods/console/redactor.rb,
lib/woods/dependency_graph.rb,
lib/woods/embedding/openai.rb,
lib/woods/flow_precomputer.rb,
lib/woods/mcp/bootstrapper.rb,
lib/woods/mcp/index_reader.rb,
lib/woods/mcp/origin_guard.rb,
lib/woods/model_name_cache.rb,
lib/woods/retrieval/ranker.rb,
lib/woods/storage/pgvector.rb,
lib/woods/unblocked/client.rb,
lib/woods/cache/cache_store.rb,
lib/woods/db/schema_version.rb,
lib/woods/embedding/indexer.rb,
lib/woods/export/unit_facts.rb,
lib/woods/console/table_gate.rb,
lib/woods/console/tool_specs.rb,
lib/woods/embedding/provider.rb,
lib/woods/evaluation/metrics.rb,
lib/woods/mcp/provider_probe.rb,
lib/woods/unblocked/exporter.rb,
lib/woods/console/tools/tier1.rb,
lib/woods/console/tools/tier2.rb,
lib/woods/console/tools/tier3.rb,
lib/woods/console/tools/tier4.rb,
lib/woods/mcp/bootstrap_state.rb,
lib/woods/mcp/config_resolver.rb,
lib/woods/notion/rate_limiter.rb,
lib/woods/storage/graph_store.rb,
lib/woods/storage/snapshotter.rb,
lib/woods/ast/method_extractor.rb,
lib/woods/console/audit_logger.rb,
lib/woods/console/confirmation.rb,
lib/woods/console/safe_context.rb,
lib/woods/cost_model/estimator.rb,
lib/woods/evaluation/evaluator.rb,
lib/woods/evaluation/query_set.rb,
lib/woods/obsidian/name_mapper.rb,
lib/woods/session_tracer/store.rb,
lib/woods/storage/vector_store.rb,
lib/woods/console/sql_validator.rb,
lib/woods/feedback/gap_detector.rb,
lib/woods/notion/mappers/shared.rb,
lib/woods/obsidian/note_builder.rb,
lib/woods/obsidian/vault_assets.rb,
lib/woods/cache/cache_middleware.rb,
lib/woods/formatting/gpt_adapter.rb,
lib/woods/storage/metadata_store.rb,
lib/woods/unblocked/rate_limiter.rb,
lib/woods/ast/call_site_extractor.rb,
lib/woods/cache/redis_cache_store.rb,
lib/woods/cache/solid_cache_store.rb,
lib/woods/console/bridge_protocol.rb,
lib/woods/console/model_validator.rb,
lib/woods/console/rack_middleware.rb,
lib/woods/cost_model/storage_cost.rb,
lib/woods/embedding/text_preparer.rb,
lib/woods/embedding/token_counter.rb,
lib/woods/obsidian/vault_exporter.rb,
lib/woods/operator/pipeline_guard.rb,
lib/woods/temporal/snapshot_store.rb,
lib/woods/unblocked/sync_manifest.rb,
lib/woods/console/credential_index.rb,
lib/woods/console/response_context.rb,
lib/woods/extractors/job_extractor.rb,
lib/woods/extractors/lib_extractor.rb,
lib/woods/formatting/human_adapter.rb,
lib/woods/operator/error_escalator.rb,
lib/woods/operator/status_reporter.rb,
lib/woods/chunking/semantic_chunker.rb,
lib/woods/console/dispatch_pipeline.rb,
lib/woods/console/embedded_executor.rb,
lib/woods/console/sql_table_scanner.rb,
lib/woods/cost_model/embedding_cost.rb,
lib/woods/extractors/i18n_extractor.rb,
lib/woods/extractors/poro_extractor.rb,
lib/woods/formatting/claude_adapter.rb,
lib/woods/retrieval/search_executor.rb,
lib/woods/ruby_analyzer/fqn_builder.rb,
lib/woods/session_tracer/file_store.rb,
lib/woods/session_tracer/middleware.rb,
lib/woods/console/connection_manager.rb,
lib/woods/console/credential_scanner.rb,
lib/woods/console/sql_noise_stripper.rb,
lib/woods/coordination/pipeline_lock.rb,
lib/woods/evaluation/baseline_runner.rb,
lib/woods/extractors/event_extractor.rb,
lib/woods/extractors/model_extractor.rb,
lib/woods/extractors/phlex_extractor.rb,
lib/woods/extractors/route_extractor.rb,
lib/woods/formatting/generic_adapter.rb,
lib/woods/mcp/tool_response_renderer.rb,
lib/woods/observability/health_check.rb,
lib/woods/resilience/circuit_breaker.rb,
lib/woods/resilience/index_validator.rb,
lib/woods/retrieval/query_classifier.rb,
lib/woods/session_tracer/redis_store.rb,
lib/woods/storage/snapshotter/vector.rb,
lib/woods/unblocked/document_builder.rb,
lib/woods/cost_model/provider_pricing.rb,
lib/woods/evaluation/report_generator.rb,
lib/woods/extractors/engine_extractor.rb,
lib/woods/extractors/mailer_extractor.rb,
lib/woods/extractors/policy_extractor.rb,
lib/woods/extractors/pundit_extractor.rb,
lib/woods/extractors/view_engines/erb.rb,
lib/woods/mcp/renderers/json_renderer.rb,
lib/woods/notion/mappers/model_mapper.rb,
lib/woods/retrieval/context_assembler.rb,
lib/generators/woods/install_generator.rb,
lib/woods/console/adapters/job_adapter.rb,
lib/woods/extractors/caching_extractor.rb,
lib/woods/extractors/callback_analyzer.rb,
lib/woods/extractors/concern_extractor.rb,
lib/woods/extractors/factory_extractor.rb,
lib/woods/extractors/graphql_extractor.rb,
lib/woods/extractors/manager_extractor.rb,
lib/woods/extractors/service_extractor.rb,
lib/woods/extractors/view_engines/base.rb,
lib/woods/mcp/renderers/plain_renderer.rb,
lib/woods/notion/mappers/column_mapper.rb,
lib/woods/ruby_analyzer/class_analyzer.rb,
lib/woods/ruby_analyzer/trace_enricher.rb,
lib/woods/storage/inapplicable_backend.rb,
lib/woods/storage/snapshotter/metadata.rb,
lib/woods/temporal/json_snapshot_store.rb,
lib/generators/woods/pgvector_generator.rb,
lib/woods/extractors/behavioral_profile.rb,
lib/woods/mcp/renderers/claude_renderer.rb,
lib/woods/observability/instrumentation.rb,
lib/woods/resilience/retryable_provider.rb,
lib/woods/ruby_analyzer/method_analyzer.rb,
lib/woods/console/adapters/cache_adapter.rb,
lib/woods/console/scope_predicate_parser.rb,
lib/woods/db/migrations/001_create_units.rb,
lib/woods/db/migrations/002_create_edges.rb,
lib/woods/extractors/decorator_extractor.rb,
lib/woods/extractors/migration_extractor.rb,
lib/woods/extractors/rake_task_extractor.rb,
lib/woods/extractors/validator_extractor.rb,
lib/woods/ruby_analyzer/mermaid_renderer.rb,
lib/woods/db/migrations/006_rename_tables.rb,
lib/woods/extractors/controller_extractor.rb,
lib/woods/extractors/middleware_extractor.rb,
lib/woods/extractors/serializer_extractor.rb,
lib/woods/mcp/renderers/markdown_renderer.rb,
lib/woods/mcp/version_aware_tool_dispatch.rb,
lib/woods/notion/mappers/migration_mapper.rb,
lib/woods/observability/structured_logger.rb,
lib/woods/ruby_analyzer/dataflow_analyzer.rb,
lib/woods/console/adapters/sidekiq_adapter.rb,
lib/woods/extractors/ast_source_extraction.rb,
lib/woods/extractors/route_helper_resolver.rb,
lib/woods/session_tracer/solid_cache_store.rb,
lib/woods/console/adapters/good_job_adapter.rb,
lib/woods/console/console_response_renderer.rb,
lib/woods/extractors/action_cable_extractor.rb,
lib/woods/extractors/rails_source_extractor.rb,
lib/woods/extractors/shared_utility_methods.rb,
lib/woods/extractors/test_mapping_extractor.rb,
lib/woods/flow_analysis/operation_extractor.rb,
lib/woods/db/migrations/004_create_snapshots.rb,
lib/woods/extractors/configuration_extractor.rb,
lib/woods/extractors/database_view_extractor.rb,
lib/woods/extractors/scheduled_job_extractor.rb,
lib/woods/extractors/state_machine_extractor.rb,
lib/woods/extractors/view_template_extractor.rb,
lib/woods/flow_analysis/response_code_mapper.rb,
lib/woods/db/migrations/003_create_embeddings.rb,
lib/woods/extractors/view_component_extractor.rb,
lib/woods/console/adapters/solid_queue_adapter.rb,
lib/woods/extractors/shared_dependency_scanner.rb,
lib/woods/session_tracer/session_flow_document.rb,
lib/woods/session_tracer/session_flow_assembler.rb,
lib/woods/db/migrations/005_create_snapshot_units.rb

Overview

See Also:

Defined Under Namespace

Modules: Ast, AtomicFile, Cache, Chunking, Console, Coordination, CostModel, Db, Embedding, Evaluation, Export, Extractors, Feedback, FilenameUtils, FlowAnalysis, Formatting, Generators, MCP, ModelNameCache, Notion, Observability, Obsidian, Operator, Resilience, Retrieval, RetryAfter, RubyAnalyzer, SessionTracer, Storage, Tasks, Temporal, TokenUtils, Unblocked, UpdateCheck, Util Classes: Builder, Configuration, ConfigurationError, DependencyGraph, Error, ExtractedUnit, ExtractionError, Extractor, FlowAssembler, FlowDocument, FlowPrecomputer, GitProvenance, GraphAnalyzer, IndexArtifact, Railtie, ResolvedConfig, Retriever, SessionTracerError

Constant Summary collapse

CONFIG_MUTEX =
Mutex.new
DEFAULT_CONSOLE_REDACTED_COLUMNS =

Console MCP secure defaults — Layer 3 column-name redaction.

Columns named here are replaced with [REDACTED] in every MCP tool response. This list targets credential columns that appear with the same names across Devise, Doorkeeper, Rodauth, has_secure_password, devise-two-factor, OAuth integrations, and hand-rolled auth code.

Intentionally omitted because they cause over-redaction in apps that use them for non-secret purposes:

- `key` — ActiveStorage blob keys, EAV key columns, translation keys
- `name` — universal non-secret identifier
- PII columns (`ssn`, `tax_id`, `dob`) — org-specific compliance concern

Host apps extend this by reassigning console_redacted_columns to Woods::DEFAULT_CONSOLE_REDACTED_COLUMNS + %w[extra_column], or override entirely to remove a default.

%w[
  password
  password_digest
  password_salt
  encrypted_password
  crypted_password
  salt
  otp_secret
  encrypted_otp_secret
  two_factor_secret
  backup_codes
  consumed_timestep
  reset_password_token
  confirmation_token
  unlock_token
  remember_token
  invitation_token
  access_token
  refresh_token
  auth_token
  api_token
  api_key
  bearer_token
  client_secret
  webhook_secret
  signing_secret
  session_secret
  private_key
  encrypted_private_key
  key_hash
  token
  secret
].freeze
DEFAULT_CONSOLE_BLOCKED_TABLES =

Console MCP secure defaults — Layer 1 table-level blocking.

Tables named here are rejected outright before any SQL reaches the database. This list targets authentication and credential storage tables that carry secrets or session state across all major auth stacks (Devise, Doorkeeper, Rodauth, has_secure_password, Sorcery, OmniAuth, and hand-rolled token systems).

Intentionally omitted to avoid over-blocking benign apps:

- `users` / `accounts` — many apps expose safe columns from these
tables and operators should decide explicitly.
- PII-heavy but auth-unrelated tables (`payments`, `addresses`) —
org-specific compliance concern, not a universal default.

To keep the defaults and add more tables:

Woods.configure { |c| c.console_blocked_tables =
Woods::DEFAULT_CONSOLE_BLOCKED_TABLES + %w[extra_table] }

To replace the defaults entirely (including removing entries):

Woods.configure { |c| c.console_blocked_tables = %w[only_this] }

To disable Layer 1 (gate becomes inactive; other layers still apply):

Woods.configure { |c| c.console_blocked_tables = [] }
%w[
  sessions
  api_keys
  credentials
  oauth_applications
  oauth_access_tokens
  oauth_refresh_tokens
  identities
  active_storage_blobs
].freeze
VERSION =
'1.6.0'

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.configurationObject

Returns the value of attribute configuration.



296
297
298
# File 'lib/woods.rb', line 296

def configuration
  @configuration
end

Class Method Details

.build_retrieverRetriever

Build a Retriever wired with adapters from the current configuration.

Returns:

  • (Retriever)

    A fully wired retriever instance



349
350
351
# File 'lib/woods.rb', line 349

def build_retriever
  Builder.new(configuration).build_retriever
end

.configureObject



298
299
300
301
302
303
304
# File 'lib/woods.rb', line 298

def configure
  CONFIG_MUTEX.synchronize do
    self.configuration ||= Configuration.new
    yield(configuration) if block_given?
    configuration
  end
end

.configure_with_preset(name) {|config| ... } ⇒ Configuration

Configure the module using a named preset and optional block customization.

Valid preset names: :local, :postgresql, :production

Parameters:

  • name (Symbol)

    Preset name

Yields:

  • (config)

    Optional block for further customization after preset is applied

Yield Parameters:

Returns:



314
315
316
317
318
319
320
# File 'lib/woods.rb', line 314

def configure_with_preset(name)
  CONFIG_MUTEX.synchronize do
    self.configuration = Builder.preset_config(name)
    yield configuration if block_given?
    configuration
  end
end

.extract!(output_dir: nil) ⇒ Hash

Perform full extraction

Parameters:

  • output_dir (String) (defaults to: nil)

    Override output directory

Returns:

  • (Hash)

    Extraction results



366
367
368
369
370
371
372
# File 'lib/woods.rb', line 366

def extract!(output_dir: nil)
  require_relative 'woods/extractor'

  dir = output_dir || configuration.output_dir
  extractor = Extractor.new(output_dir: dir)
  extractor.extract_all
end

.extract_changed!(changed_files) ⇒ Array<String>

Perform incremental extraction

Parameters:

  • changed_files (Array<String>)

    List of changed files

Returns:

  • (Array<String>)

    Re-extracted unit identifiers



378
379
380
381
382
383
# File 'lib/woods.rb', line 378

def extract_changed!(changed_files)
  require_relative 'woods/extractor'

  extractor = Extractor.new(output_dir: configuration.output_dir)
  extractor.extract_changed(changed_files)
end

.resolve_notion_token(config = configuration) ⇒ String?

Resolve the effective Notion API token.

A non-blank NOTION_API_TOKEN env var takes precedence; otherwise the configured notion_api_token is used. A set-but-blank env var — common with docker-compose ${NOTION_API_TOKEN} interpolation of an unset host variable — is treated as absent, so it never masks a valid configured token nor slips through as a blank bearer. This is the single resolution point shared by the Notion exporter, the MCP notion_sync tool + its registration gate, and the rake task, so all four agree on a given host.

Parameters:

  • config (Configuration) (defaults to: configuration)

    configuration to read the fallback from

Returns:

  • (String, nil)

    the resolved token, or nil when neither source supplies a non-blank value



336
337
338
339
340
341
342
343
344
# File 'lib/woods.rb', line 336

def resolve_notion_token(config = configuration)
  env = ENV.fetch('NOTION_API_TOKEN', nil)
  return env unless env.nil? || env.strip.empty?

  configured = config.respond_to?(:notion_api_token) ? config.notion_api_token : nil
  return nil if configured.nil? || configured.to_s.strip.empty?

  configured
end

.retrieve(query, **opts) ⇒ Retriever::RetrievalResult

Retrieve context for a natural language query using the current configuration.

Parameters:

  • query (String)

    Natural language query

  • opts (Hash)

    Options passed through to the retriever (e.g., budget:)

Returns:



358
359
360
# File 'lib/woods.rb', line 358

def retrieve(query, **opts)
  build_retriever.retrieve(query, **opts)
end