On this page: Project · Sources · Tracking · Profile · Ranking · Sync · Brief and Review · Video
Reading this file
Only project.id and project.name are required when writing a file from scratch; Setup creates them. Omitted fields take the defaults below. Unknown fields fail validation. Relative paths are resolved against the directory containing frontier.yaml, except the video script, which Render also resolves from that directory. Run frontier config validate --config frontier.yaml after editing and frontier schema config --format json for machine-readable types.
Use stable profile.topics[].id values across searches. Changing a date window under the same ID allows Discovery to report what entered the new scope; it does not claim that every returned paper was just published. The checked-in frontier.yaml.example is an offline development fixture, not your active file. The Config Skill writes a *.candidate.yaml proposal, validates and diffs it, then applies it to frontier.yaml.
schema_version: "0.1"
project: {id: agent-harness, name: Agent Harness Watch}
sources:
openalex: {enabled: true, mode: live, max_results: 200}
profile:
topics:
- id: agent-harness
description: execution harnesses for AI coding agents
search:
providers: [openalex]
query: 'agent harness coding'
published_from: 2026-01-01
brief:
outputs: [html, slides]Dates use YYYY-MM-DD. The OpenAlex query searches title, abstract, and keywords; the topic description and profile keywords drive the separate local relevance score.
Project and schema
| Field | Default / effect |
|---|---|
schema_version | "0.1" only. Rejects incompatible schemas. |
project.id | Required stable project slug; Setup derives one from the workspace name. |
project.name | Required display name; Setup uses the workspace name unless told otherwise. |
project.timezone | UTC. Stored in config; current run timestamps remain UTC, so this does not change scheduling or date filtering. |
project.language | en. Language tag used in briefing output; it does not translate source text or guarantee translated narration. |
project.workspace_dir | .frontier. Internal runs, cache, and state directory. |
project.output_dir | frontier_output. Public Discovery and briefing files. |
Sources
Every source starts disabled. Set enabled: true and, for remote sources, mode: live before expecting network results. Fixture mode requires a JSON fixture_path; it is for testing, not a substitute for a live subscription. Provider keys and passwords never belong in YAML; see Credentials.
| Source | Live behavior and required target |
|---|---|
sources.openalex | Topic works search. Requires at least one profile.topics[].search.providers containing openalex. Paginates each bounded query up to max_results; reports truncation. API key optional for basic use. |
sources.alphaxiv | MCP discover_papers for a topic; requires a topic provider entry and 3–4 search.keywords. Needs an API key for this harness's headless client. Returns a small ranked top-k, never a complete corpus. |
sources.arxiv | arXiv Atom API. Live mode requires paper_ids, queries, or categories. It does not use profile.topics[].search to form its query. |
sources.semantic_scholar | Tracks papers of stable Semantic Scholar author IDs from tracking.scholars. It is not a general keyword search adapter. API key optional, subject to upstream limits. |
sources.openreview | OpenReview API 2 submission invitations for tracking.venues. Requires a token or username and password. Venue selection does not automatically cover every conference or year. |
sources.local_library | Reads files under configured local roots, no remote credential. PDF uses PyMuPDF; Markdown and text use a plain-text parser. |
Common remote-source fields
The following fields belong to sources.semantic_scholar, sources.arxiv, sources.openalex, and sources.alphaxiv. A field may be accepted by the shared schema but only used by some adapters; the last column is explicit about that.
| Field within source | Default / actual use |
|---|---|
enabled | false; disabled source is skipped. |
mode | fixture or live; default fixture. |
fixture_path | Unset. Required when an enabled source uses fixture mode; path relative to the config file. |
overlap_days | 3; accepted but the current live adapters re-query their scope and do not use this overlap setting. |
api_key_env | Unset. Name of an environment variable, not the secret itself. OpenAlex and Semantic Scholar use it if present; alphaXiv falls back to ALPHAXIV_API_KEY and requires a value in live mode; arXiv ignores it. |
base_url | Unset; adapters use their built-in endpoints. Set only for a compatible endpoint or test server. |
user_agent | FrontierOps/0.1; sent by arXiv, Semantic Scholar, and OpenAlex HTTP adapters, not the MCP client. |
request_timeout_seconds | 30, positive; per-request HTTP/MCP timeout. |
request_delay_seconds | 3.0, nonnegative; pause between arXiv/OpenAlex pages. Not currently used by Semantic Scholar or alphaXiv. |
page_size | 100, 1–1000 in schema. OpenAlex caps each actual API page at 100; arXiv and Semantic Scholar use it. alphaXiv MCP has no pagination here. |
max_results | 100, positive; arXiv/Semantic Scholar query cap, OpenAlex cap per topic, alphaXiv clip of its returned top-k list. |
paper_ids | Empty list; arXiv ID list only. Other live adapters ignore it. |
queries | Empty list; arXiv search expressions only. Other live adapters ignore it. |
categories | Empty list; arXiv category terms such as cs.AI only. Other live adapters ignore it. |
Local library and OpenReview fields
| Field | Default / effect |
|---|---|
sources.local_library.enabled | false; local files are skipped until enabled. |
sources.local_library.roots | Empty list. Directories to scan, relative to frontier.yaml unless absolute. |
sources.local_library.recursive | true; walk nested directories. |
sources.local_library.allowed_extensions | [.pdf, .md, .txt]; only these three extension values are valid. |
sources.local_library.allow_outside_project_root | false; prevents roots or followed files from escaping the project. Enable only if deliberate. |
sources.openreview.enabled | false; OpenReview is skipped until enabled. |
sources.openreview.mode | fixture by default; live uses API 2. |
sources.openreview.fixture_path | Unset; required for enabled fixture mode. |
sources.openreview.base_url | https://api2.openreview.net; API 2 endpoint. |
sources.openreview.username_env | OPENREVIEW_USERNAME; environment-variable name for account username/email. |
sources.openreview.password_env | OPENREVIEW_PASSWORD; environment-variable name for account password. |
sources.openreview.token_env | OPENREVIEW_TOKEN; environment-variable name for an existing API 2 session token. Token takes precedence over username/password. |
sources.openreview.include_replies | true; request replies so decisions and review context can be read. |
Scholar and venue tracking
tracking.scholars and tracking.venues default to empty lists. Display names are not stable identities. Currently, live scholar fetching is implemented only for Semantic Scholar author IDs; google_scholar is accepted in the schema but has no live adapter.
| Field within item | Default / effect |
|---|---|
tracking.scholars[].id | Required local stable ID for your subscription. |
tracking.scholars[].name | Required display name; not used as the remote lookup key. |
tracking.scholars[].aliases | Empty list; stored for identity context, not used by the live fetcher. |
tracking.scholars[].identities | Required mapping; set semantic_scholar: <author-id> to use the current live author adapter. |
tracking.scholars[].providers | Required list of semantic_scholar, arxiv, or google_scholar; only Semantic Scholar author tracking is currently wired to a live scholar-specific fetcher. |
tracking.scholars[].backfill_days | 365; accepted but not applied by the current author fetcher. |
tracking.scholars[].always_include_new_publications | true; accepted, but no bypass of ranking Gates is currently implemented. |
tracking.venues[].provider | Required literal openreview. |
tracking.venues[].venue_id | Required exact OpenReview group ID, including year, such as ICLR.cc/2026/Conference. |
tracking.venues[].decisions | Empty list means no decision filter. When nonempty, the current adapter filters only notes with a detected decision; notes without one remain, so do not treat this as a strict accepted-only guarantee. |
Research profile and topic search
profile defaults to empty topics and keyword lists. profile.topics[].search is optional until a topic provider is enabled. Topic search determines what OpenAlex/alphaXiv request; the topic description and include keywords separately determine the local lexical relevance feature. The search query is not a perfect semantic relevance gate.
| Field | Default / effect |
|---|---|
profile.topics[].id | Required stable topic ID; keep it unchanged across runs to compare the same interest. |
profile.topics[].description | Required description; its words become weighted lexical relevance terms. |
profile.topics[].weight | 1.0, nonnegative; weights description terms in lexical relevance, not the API query or final score directly. |
profile.topics[].search.providers | Empty list; choose openalex, alphaxiv, or both. The corresponding source must also be enabled in live mode. |
profile.topics[].search.query | Required when search exists. Sent to OpenAlex title/abstract/keywords search and as alphaXiv's semantic question. |
profile.topics[].search.keywords | Empty list; alphaXiv requires exactly 3–4 concise terms. OpenAlex does not use this list. |
profile.topics[].search.published_from | Unset; inclusive lower publication-date boundary. |
profile.topics[].search.published_to | Unset; inclusive upper publication-date boundary; cannot precede published_from. |
profile.topics[].search.alphaxiv_difficulty | 5, 1–10; retrieval-effort setting for alphaXiv only. |
profile.keywords.include | Empty list; contributes English/alphanumeric terms to lexical relevance. |
profile.keywords.exclude | Empty list; matching text forces lexical relevance to 0, but is not itself a hard exclusion. Add a relevance Gate if a hard cutoff is needed. |
Gates and ranking
A Gate decides whether a candidate is excluded, warned, or exempted; enabled ranking.features weights order candidates afterward. A score measures the configured heuristic, not scientific quality. ranking.gates defaults to an empty list: no paper is excluded by default.
ranking:
gates:
- {id: recent, type: publication_year, min_year: 2025, on_fail: exclude}
- {id: citations, type: citation, minimum_count: 3, exempt_if_age_days_lte: 90, on_fail: warn}
- {id: topical, type: relevance, minimum: 0.25, on_fail: exclude}
| Field | Default / effect |
|---|---|
ranking.gates[].id | Required label shown in the Gate trace. |
ranking.gates[].type | Required: publication_year, citation, or relevance. |
ranking.gates[].enabled | true; disabled Gate is reported as exempt. |
ranking.gates[].on_fail | exclude or warn; default exclude. |
ranking.gates[].min_year | Required for publication_year; missing publication year fails the Gate. |
ranking.gates[].minimum_count | Required nonnegative citation threshold for citation. Missing citation data warns regardless of on_fail. |
ranking.gates[].exempt_if_age_days_lte | 0; exempt a paper this many days old or newer from a citation Gate when age is known. |
ranking.gates[].minimum | Required 0–1 lexical score threshold for relevance. |
ranking.features.lexical_relevance | {enabled: true, weight: 0.55}; title + abstract overlap with description/include terms. |
ranking.features.citation | {enabled: true, weight: 0.15}; logarithmic citation count, clipped at 1. |
ranking.features.freshness | {enabled: true, weight: 0.15}; decay from publication date. |
ranking.features.reliability | {enabled: true, weight: 0.15}; configured value for the source provider; an absent provider value contributes 0. |
ranking.features.*.enabled | Boolean switch for each feature. |
ranking.features.*.weight | Nonnegative weight. Enabled weights are normalized by their sum; all zero weights give a score of 0. |
ranking.citation_scale | 100, positive; count at which the citation feature reaches 1. |
ranking.freshness_half_life_days | 180, positive; freshness halves after this many days. |
ranking.source_reliability | Empty mapping; provider names to numeric feature values. Prefer 0–1 values; the schema does not enforce that range. |
ranking.deep_enrich_top_k | 5, positive; attempt deterministic explanation/full-text enrichment for the top eligible candidates. |
ranking.max_fulltext_pages | 20, positive; limit local full-text pages used for enrichment/visual extraction. Does not cap an alphaXiv MCP response. |
Sync policy
Sync runs only after a researcher requests Discover or an operator invokes the CLI. The current implementation compares stable provider IDs and content fingerprints with saved state; topical searches also preserve every current observation for cross-run comparison.
| Field | Default / effect |
|---|---|
sync.trigger_mode | Only manual is accepted; no scheduler. |
sync.baseline | Only last_successful_sync is accepted; current state is stored in .frontier/state/. |
sync.default_lookback_days | 14; accepted but not yet applied to live provider queries. |
sync.on_provider_error | fail or partial; default fail. Current Sync does not yet implement partial recovery; a provider exception stops the run in either mode. |
sync.preserve_raw_responses | true; accepted, but the current repository always caches normalized source-record snapshots, not the original HTTP response body. |
Briefing and Review
| Field | Default / effect |
|---|---|
brief.target_duration_seconds | 300 (five minutes), positive; set any desired target in seconds. |
brief.maximum_developments | 5, positive; maximum selected developments in one draft. |
brief.maximum_seconds_per_development | 75, positive; cap for each paper's section. Raise this as well when requesting a longer single-paper briefing. |
brief.narration_words_per_minute | 140, positive; caps draft narration words from the allocated seconds. |
brief.outputs | [html, slides, video] at schema level; Setup writes [html, slides]. Choose any combination of those values. Video additionally requires rendering.video.enabled. |
review.required | true; stored but does not bypass the current Brief → Review → Render requirement if set false. |
review.fail_on_missing_evidence | true; controls error versus warning for missing factual claim evidence. The strict briefing schema still rejects factual claims without references. |
review.fail_on_broken_source | true; block unknown Evidence IDs when true. |
review.fail_on_unsupported_number | true; block numbers absent from cited Evidence. This is a string-level check, not semantic fact checking. |
review.fail_on_duration_over_budget | true; block sections whose total duration exceeds the target. |
review.fail_on_duplicate_development | true; block repeated development IDs or headlines. |
review.auto_fix | safe_only or none; safe normalization trims headings/claims and deduplicates Evidence IDs, not research claims. |
Optional video preview
rendering.video is disabled by default. Enabling it requires a path to a HeyGen TTS adapter script and may incur external service costs. A generated HyperFrames HTML preview is not a rendered MP4.
| Field | Default / effect |
|---|---|
rendering.video.enabled | false; must be true in addition to including video in brief.outputs. |
rendering.video.provider | Only hyperframes accepted; schema marker. |
rendering.video.tts_provider | Only heygen accepted; schema marker. |
rendering.video.heygen_tts_script | Unset; required when enabled. Executable adapter path, relative to the config directory if not absolute. |
rendering.video.voice_id | Unset; passed to the TTS adapter when provided. |
rendering.video.language | Unset; narration language override, otherwise inferred from script. |
rendering.video.width | 1920, positive; preview canvas width. |
rendering.video.height | 1080, positive; preview canvas height. |
rendering.video.fps | 30; allowed 24, 30, 60. Accepted but not currently used by preview generation. |
rendering.video.quality | looks; allowed draft, looks, delivery. Accepted but not currently used by preview generation. |