Specification

format: https://specscore.md/feature-specification status: Draft

Feature: Repo Config

SpecScore.Studio: | Explore | Edit | Ask question | Request change |

Status: Draft Source Ideas: β€”

Summary

Defines specscore.yaml, the single mandatory repository-level config file for SpecScore projects. Specifies the file name, the mandatory schema-pointer header comment, the optional project identity block, related-project navigation hints, explicit Plan-repository routing, top-level dir-name overrides, modules with code roots, studio configuration, publication policy, and inference defaults.

Contents

Directory Description
_tests/ Test scenarios for repo-config requirements

Problem

SpecScore needs a single, predictable, repo-level config file. The legacy specscore-spec-repo.yaml carried Synchestra-flavored naming (the spec-repo / state-repo / code-repo split) that does not apply to SpecScore proper, and its schema did not support modular layouts (e.g., a frontend and a backend module sharing one repo). Tools that render the studio toolbar in artifact documents (the four canonical verbs: Explore, Edit, Ask question, Request change) need a name-agnostic place to read studio settings; the legacy viewer: block (with its single-link "View in …" model) is out of date and is superseded by studio:.

This feature replaces project-definition with a simpler, more flexible schema.

Behavior

Lesson classifications

REQ: lessons-classifications

A repository that uses Lessons MUST declare lessons.classifications in specscore.yaml as a non-empty list of unique lowercase, hyphen-separated strings. The list is the controlled vocabulary for Lesson **Classifications:**; removing a value while any Lesson still uses it is a validation error. Repositories with no Lessons MAY omit the lessons: block until their first Lesson is created.

File name and location

The config file is specscore.yaml and lives at the repository root.

REQ: file-name

Every SpecScore project MUST have a file named exactly specscore.yaml at the repository root. Any other name (including specscore-project.yaml, specscore-spec-repo.yaml, .specscore.yaml) is invalid.

Schema-pointer header comment

Every specscore.yaml is self-identifying. Line 1 of the file is a fixed comment that names the schema. The comment is required even when the rest of the file is empty.

REQ: schema-header-comment

Line 1 of specscore.yaml MUST be exactly:

# SpecScore Repo Config Schema: https://specscore.md/repo-config

A file whose line 1 is anything else β€” including a blank line, a different comment, a YAML document marker (---), or a leading BOM followed by other content β€” is invalid. Lint MUST emit a hard error.

REQ: empty-config-valid

A specscore.yaml containing only the schema-header comment (with an optional trailing newline) is valid. All field defaults defined by this feature apply.

Project identity

The optional project: block declares the project's identity. Every field within it is also optional; missing fields are inferred from the git remote or from the working directory.

Field Default Description
title git repository name Human-readable project name
host parsed from origin git remote Repository host (e.g., github.com)
org parsed from origin git remote Repository org / owner
repo parsed from origin git remote Repository name
repositories β€” List of code repository URLs associated with this project

REQ: project-block-optional

The project: block MAY be omitted entirely. When omitted, every field below is inferred from the git remote and working directory; the file remains valid.

REQ: project-title-default

When project.title is omitted, the effective title is the basename of the repository's working directory. When project.title is present, its value is used as-is.

REQ: source-reference-overrides

project.host, project.org, and project.repo override origin git-remote inference for source-reference URL building. Tools resolving same-repo references MUST prefer explicit values when present. This handles forks, mirrors, and non-standard remote names. See the Source References feature.

REQ: project-repositories

project.repositories is an OPTIONAL list of repositories associated with this project. The list MUST round-trip on read/write. SpecScore validates the structural shape (entry shape, role enum, required url and non-empty roles) but does not act on the role values β€” interpretation is left to downstream orchestration tools (e.g., Synchestra). Every entry MUST be a role-tagged object per repositories-entry-shape; flat URL strings are not accepted.

REQ: repositories-entry-shape

Each entry in project.repositories is a YAML mapping (object) with the following fields. Flat scalar entries (URL strings, single tokens) are a hard error.

Field Required Description
url yes Repository URL or short-path (same forms accepted everywhere project.repositories entries are written)
roles yes Non-empty list of role values; see repositories-roles-list and repositories-roles-enum
title no Human-readable repository name
comment no Free-form annotation

A mapping entry that is missing url, has an empty roles list, or has a missing roles field is a hard error. Unknown fields inside a role-tagged entry MUST round-trip unchanged per unknown-fields-preserved.

REQ: repositories-roles-list

roles is a mandatory, non-empty YAML sequence (list) of one or more role values. Omitting roles, providing it as an empty list (roles: []), or providing a scalar value (e.g., roles: code instead of roles: [code]) is each a hard error β€” the field is always a non-empty list. Duplicate role values within a single entry's roles list are de-duplicated by tools and SHOULD emit a lint advisory; they are not a hard error.

REQ: repositories-roles-enum

Each value in a roles list MUST be drawn from the canonical role enum:

Role Meaning
code Source-code repository β€” scanned by code tooling for specscore: annotations
specification SpecScore-managed spec repository β€” has its own specscore.yaml and spec/ tree
state Orchestrator state repository β€” managed by tools like Synchestra; not specscore-managed
docs Documentation-only repository
runner Remote runner / executor repository β€” referenced by orchestrator runner features

A repository entry MAY combine multiple roles (e.g., roles: [specification, code]) β€” a single repo often plays several roles. Unknown role values are a hard error. The enum is closed in v1; future additions require a SpecScore Feature revision.

Related projects

The optional root-level projects: field is a list of related SpecScore projects worth navigating to from this one. The relationship direction (parent, child, sibling, dependency) is unspecified; entries are navigation aids.

projects:
  - https://github.com/org/parent-project          # external repo URL
  - ./packages/api                                  # path to dir with its own specscore.yaml

REQ: projects-list

projects: is an OPTIONAL root-level list. Each entry MUST be either:

  1. A URL to an external repository (any scheme parseable as a URI), or
  2. A path (relative or starting with ./) to a directory in the current repository.

REQ: projects-local-path-must-resolve

When a projects: entry is a local path, that path MUST resolve to a directory containing its own specscore.yaml file. Lint MUST emit an error for local-path entries pointing at directories that do not exist or do not contain specscore.yaml.

Plan repository routing

Plan storage is resolved by SpecScore itself. It does not depend on WB or another orchestrator. Routing uses portable repository identities, while checkout paths are kept in machine-local configuration.

Repository identities use either owner/repo shorthand (the source repository's host is implied) or the full host/owner/repo form. Normalization MUST preserve all three logical components and MUST reject absolute paths, . or .. segments, and malformed identities.

The committed project config and its local override select one destination with a scalar:

plans_repo: specscore/specscore

User and organization config may route several source projects to a destination:

plan_repos:
  sneat-co/workbench:
    - datatug/datatug
    - github.com/datatug/dashboardius

repo_checkouts:
  sneat-co/workbench: /work/checkouts/sneat-co/workbench

REQ: plans-repo-project-selection

plans_repo in specscore.local.yaml or the repository's committed specscore.yaml MUST be a non-empty scalar repository identity. It selects the Plan destination for that source project. The local value overrides the committed value. Setting it to the source repository's own identity explicitly selects same-repository Plan storage; omission does not imply same-repository storage.

REQ: plan-repos-aggregate-routing

plan_repos in organization or user config MUST map destination repository identities to lists of source repository identities. A source MUST resolve to at most one destination within a layer; duplicate mappings to different normalized destinations are a hard error. Repository/local plans_repo overrides organization routing, which overrides user routing.

REQ: plan-route-required

Every Plan operation MUST resolve an explicit route from plans_repo or plan_repos. If none matches the source project, the Plan operation MUST fail before reading or writing Plan artifacts and explain where routing can be configured. Feature, Idea, Proposal, Lesson, and other non-Plan operations MUST remain independent of Plan routing.

REQ: repo-checkouts-machine-local

repo_checkouts maps a repository identity to an absolute path whose git top-level and origin identity match that repository. It MAY appear in user, organization, or specscore.local.yaml configuration and MUST NOT appear in committed specscore.yaml. Missing, relative, nested-subdirectory, non-repository, or identity-mismatched paths are hard errors when an external Plan checkout is required. Symlinks are resolved before these checks.

REQ: plan-config-precedence

Plan routing precedence is specscore.local.yaml then committed specscore.yaml, then organization .specscore.yaml, then user ~/.specscore.yaml. Checkout precedence is local, organization, then user; committed project config is forbidden from contributing machine paths. The organization file is the .specscore.yaml inside the organization directory containing the canonical source clone, so linked worktrees share the same organization policy.

Directory names

Top-level overrides for the spec and docs directory names. These apply uniformly across all modules. Per-module, per-artifact-kind overrides are provided separately by path_overrides (see Path overrides below), which currently covers only the ideas directory.

Field Default Description
specs_dir_name specs Name of the specs directory inside each module
docs_dir_name docs Name of the docs directory inside each module

REQ: specs-dir-name-default

When specs_dir_name is omitted, tools MUST treat the value as specs. The same name applies to every module.

REQ: docs-dir-name-default

When docs_dir_name is omitted, tools MUST treat the value as docs. The same name applies to every module.

Path overrides

Per-module overrides for where individual artifact kinds live, declared under a module's optional path_overrides mapping. Unlike specs_dir_name/docs_dir_name (repo-wide, name-only), path_overrides is per-module and takes a full module-relative path, so a kind can be relocated out of the spec tree entirely. In v1 the only interpreted key is ideas_path; the resolution behavior is owned by the Configurable Ideas Path Feature.

modules:
  - path: ""
    path_overrides:
      ideas_path: ideas        # ideas live at ./ideas instead of ./spec/ideas

REQ: path-overrides-optional

A module's path_overrides is an OPTIONAL mapping. When absent, every artifact kind uses its default location. Keys other than ideas_path MUST round-trip on read/write unchanged (per unknown-fields-preserved) but are not interpreted in v1.

REQ: ideas-path-field

path_overrides.ideas_path, when present, MUST be a module-relative path string giving the directory for that module's Ideas; when absent the default is spec/ideas. An absolute path (leading /) or a value escaping the module root via ../ is a hard error naming the offending module. The path's resolution semantics are defined by Configurable Ideas Path.

Modules

A module is a code area within the repository, optionally with its own specs and docs subdirectories. The feature graph is unified across modules; modules partition where files live, not the graph itself.

modules:
  - name: Highlevel        # specs at ./specs/, docs at ./docs/
  - name: Backend
    path: backend          # specs at ./backend/specs/, docs at ./backend/docs/
    code:
      - pkg/               # ./backend/pkg/
      - go.mod             # ./backend/go.mod
      - go.sum             # ./backend/go.sum
  - path: frontend         # name deduced as "frontend"

REQ: modules-default

When modules: is omitted, tools MUST behave as if a single module {} were declared β€” one module at the repository root with no code: paths.

REQ: module-name-deduction

When a module's name field is omitted, the effective name is the basename of path. When both name and path are omitted, the effective name is default.

REQ: module-path-resolution

A module's specs directory is {module.path}/{specs_dir_name}/. Its docs directory is {module.path}/{docs_dir_name}/. Each entry in code: is resolved as a path (file or directory) relative to {module.path}/. When module.path is omitted, all resolution is relative to the repository root.

REQ: module-code-list

code: is an OPTIONAL per-module list of paths (files or directories). Tools scanning code for specscore: annotations MUST use these paths as scan roots, scoped to the module's effective path. A module without a code: list is spec-only β€” no code is attributed to it.

REQ: module-paths-unique

Two modules MUST NOT have the same effective path (where omitted path is treated as .). Duplicate module paths are a hard error.

REQ: module-paths-non-nested

Two modules with explicit path: values MUST NOT have an ancestor-descendant relationship (i.e., one path is a prefix of the other interpreted as filesystem paths). A module with no path: (the implicit-root module) MAY coexist with any number of explicit-path modules. Nested explicit-path modules are a hard error.

Studio

The optional studio: block names the upstream studio (Spec Studio web app) that renders SpecScore artifacts in a browser and serves the toolbar. Tools that emit the toolbar line in artifact documents (e.g., feature READMEs) read this block.

studio:
  name: SpecScore.Studio
  url: https://specscore.studio/
Field Required Description
name yes (when studio: is present as a mapping) Display name shown in the toolbar brand attribution
url yes (when studio: is present as a mapping) Base URL of the studio; toolbar links point under this URL

REQ: studio-default-when-omitted

When studio: is omitted entirely, tools MUST use the defaults name: SpecScore.Studio and url: https://specscore.studio/. The studio toolbar MUST be rendered in artifact documents with these defaults.

REQ: studio-explicit-values

When studio: is present as a mapping, both name (string) and url (valid URL) MUST be present. Partial mappings (e.g., studio: { name: X } without a URL) are a hard error. Defaults do not apply to a partially-specified studio: block β€” defaults apply only when the whole block is absent.

REQ: studio-null-opts-out

When studio: is explicitly set to null (YAML null, ~, or an empty value), tools MUST NOT render any studio toolbar in artifact documents. This is the only way to suppress the toolbar; omitting the block falls back to defaults.

REQ: studio-toolbar-mandatory-unless-opted-out

Tools rendering artifact documents that support a studio toolbar (e.g., the lint studio-toolbar rule operating on feature READMEs) MUST emit such a toolbar unless studio: null is explicitly set. Implementations MUST NOT silently omit the toolbar for any other reason. The toolbar's rendering convention β€” its line position, byte form, verb set, separator, and URL grammar β€” is owned by the studio-toolbar Feature, not by this Feature; repo-config owns only the studio: schema (defaults, opt-out, explicit-values rules, trailing-slash validation).

REQ: studio-url-trailing-slash

studio.url MUST end with exactly one trailing / character. A studio.url value with no trailing slash (e.g., https://specscore.studio) or with multiple trailing slashes (e.g., https://specscore.studio//) is a hard error. This schema-level validation is owned by repo-config; the studio-toolbar Feature consumes the validated value and strips the single trailing / before joining it with the toolbar URL path grammar.

Grade values

The optional grade: block declares the repository's allowed **Grade:** body-metadata values:

grade:
  values: [A, B, C, D, F]

grade.values is an OPTIONAL list of allowed grade tokens. When the block (or its values: key) is omitted, the built-in default A, B, C, D, F applies. This Feature owns only the presence of the grade: key in the specscore.yaml schema; the value-set shape rules, the default, and how **Grade:** is parsed, placed, and validated are owned by the Grade body-metadata field Feature.

Publication policy

The optional publication: block declares project-level publication policy for SpecScore producers. It is consumed by SpecStudio skills and by specscore CLI helpers that need durable defaults for whether artifact changes are left unstaged, staged, committed, or pushed.

publication:
  default:
    actions: [stage]
  events:
    idea.approved:
      actions: [stage, commit]
  commands:
    implement:
      events:
        feature.approved:
          actions: [stage, commit]
  push:
    allow_branches: ["feature/*"]
    deny_branches: ["main", "release/*"]

REQ: publication-block-optional

The publication: block MAY be omitted entirely. Absence means no project-level publication policy is configured; consumers fall back to user, session, task, or built-in defaults owned by their respective features.

REQ: publication-schema-delegated

When publication: is present, its durable shape and validation rules are owned by the Publication Policy Config Feature. Repo Config owns the top-level key and the requirement that unknown fields under publication: round-trip unchanged with the rest of specscore.yaml.

Recaps and journal storage targets

The optional recaps: and journal: blocks declare where machine-generated recap/verify artifacts and the activity journal are stored. Per Decision D-0002, storage always targets the hub repo β€” a configured location, default a dedicated repo, that may be configured to equal the current code repo (covering the case before the Hub backend exists and repos that are not SpecScore-managed). The drift recap, verify report, and session recap all resolve their storage target through these blocks.

recaps:
  enabled: true
  repo: ~/work-hub     # hub-repo path (may point at the current repo); layered-config-gated
  user: alice          # explicit username override; layered-config-gated
  users:               # email→username map (never raw emails in paths)
    alice@example.com: alice

journal:
  enabled: true
  repo: ~/work-hub     # layered-config-gated (Phase 2)

REQ: recaps-journal-storage-target

specscore.yaml MAY carry recaps: and journal: blocks. Storage always targets the hub repo β€” recaps.repo / journal.repo is the configured hub-repo location (default a dedicated repo) and may be configured to equal the current code repo, in which case artifacts are written into it directly. There is no separate local mode: writing into the current repo is the degenerate case where the hub repo points at it, so resolution stays uniform (one storage target, one read path). The durable shape of these blocks is owned by the session-recap, drift-recap, and journal-and-summary artifacts; Repo Config owns only the presence of the top-level keys and that unknown fields under them round-trip unchanged.

REQ: recaps-journal-layered-config-gated

Because recaps.repo, recaps.user, and journal.repo are per-user/per-machine values that MUST NOT be committed into a shared project specscore.yaml, the loader MUST reject them with a clear error pointing at the layered-config Feature (Under Review; not yet implemented) (specscore.local.yaml β†’ specscore.yaml β†’ ~/.specscore.yaml) until that Feature ships. recaps.enabled / journal.enabled alone are accepted in the project file. This is the same posture the activity-journal cross-repo key carries.

Unknown fields

Orchestration tools (e.g., Synchestra) MAY extend specscore.yaml with additional fields at any level. SpecScore tooling preserves them.

# Example: orchestrator extension
state_repo: https://github.com/org/project-state
planning:
  auto_create: false

REQ: unknown-fields-preserved

SpecScore MUST ignore unknown fields at the root, inside project:, inside any project.repositories entry, and inside any module entry. Unknown fields MUST round-trip unchanged on read/write. They MUST NOT cause a validation warning or error. Unknown fields under publication: MUST also round-trip unchanged per Publication Policy Config.

Example

A maximal specscore.yaml exercising every documented field:

# SpecScore Repo Config Schema: https://specscore.md/repo-config

project:
  title: Acme Service
  host: github.com
  org: acme
  repo: service
  repositories:
    - url: https://github.com/acme/service-api
      title: Service API
      roles: [code]
    - url: https://github.com/acme/service-web
      title: Service Web
      roles: [code]
    - url: https://github.com/acme/service-spec
      title: Service Spec
      comment: SpecScore-managed spec repo for the service
      roles: [specification, code]
    - url: https://github.com/acme/service-state
      title: Service State
      roles: [state]

projects:
  - https://github.com/acme/platform
  - ./packages/shared

specs_dir_name: specs
docs_dir_name: docs

studio:
  name: SpecScore.Studio
  url: https://specscore.studio/

grade:
  values: [A, B, C, D, F]

publication:
  default:
    actions: [stage]
  events:
    idea.approved:
      actions: [stage, commit]
  push:
    allow_branches: ["feature/*"]
    deny_branches: ["main", "release/*"]

modules:
  - name: Highlevel
  - name: Backend
    path: backend
    code:
      - pkg/
      - go.mod
      - go.sum
  - path: frontend

Dependencies

Interaction with Other Features

Feature Interaction
Source References project.host, project.org, project.repo provide overrides for git-remote inference when expanding same-repo references.
Feature Feature READMEs carry the studio toolbar (see studio-toolbar) rendered using studio.name and studio.url from this block.
Studio Toolbar The studio: block defined here provides studio.name and studio.url consumed by the studio-toolbar Feature's renderer and lint rule.
Document Types Registry This feature is registered in the canonical document-types table; its consumer path is specscore.yaml.
Grade body-metadata field The optional grade: block defined here carries grade.values; that Feature owns the field's parsing, placement, default, and lint semantics.
Publication Policy Config The optional publication: block defined here carries project-level publication policy; that Feature owns policy shape, action validation, command/event scopes, branch rules, and user-config parity.
Layered Config Supplies local, repository, organization, and user origins and enforces that repo_checkouts never enters committed project config.
Plan Consumes the resolved destination and source identity to select the authoritative Plan namespace while leaving source Features read-only.

Acceptance Criteria

AC: file-recognized

Requirements: repo-config#req:file-name, repo-config#req:schema-header-comment, repo-config#req:empty-config-valid

A file named specscore.yaml at the repository root with the exact schema-header comment on line 1 is recognized as a SpecScore repo config. A file with any other name, or with a missing or misplaced header comment, is not.

AC: identity-inferred

Requirements: repo-config#req:project-block-optional, repo-config#req:project-title-default, repo-config#req:source-reference-overrides, repo-config#req:project-repositories

Project identity (title, host, org, repo) is inferred from the working directory and git remote when fields are omitted. Explicit values override inference. project.repositories round-trips without being interpreted by SpecScore tooling.

AC: repositories-role-tagged

Requirements: repo-config#req:repositories-entry-shape, repo-config#req:repositories-roles-list, repo-config#req:repositories-roles-enum

Given a specscore.yaml whose project.repositories is a list of role-tagged object entries (including at least one entry with multi-valued roles, e.g. [specification, code], and at least one optional title / comment field) When tools load the config and round-trip it back to disk Then the on-disk bytes after the round-trip are identical to the input for every well-formed entry, every entry's url, title, comment, and roles list (including multi-valued combinations) is preserved, and any unknown fields inside an entry survive unchanged.

AC: repositories-shape-errors

Requirements: repo-config#req:repositories-entry-shape, repo-config#req:repositories-roles-list, repo-config#req:repositories-roles-enum

Given a specscore.yaml whose project.repositories contains any of the following malformed entries β€” a flat-string entry (e.g. - https://example.com/repo), an entry missing url, an entry with roles: omitted, an entry with roles: [], an entry with a scalar roles: code instead of a list, or an entry containing an unknown role value (e.g. roles: [helm-chart]) When tools load the config Then the load fails with a hard error that names the offending entry by its index and the violated REQ (one of repositories-entry-shape, repositories-roles-list, repositories-roles-enum); no implicit defaults are applied; the file is not silently rewritten.

AC: related-projects-validated

Requirements: repo-config#req:projects-list, repo-config#req:projects-local-path-must-resolve

Each projects: entry is recognized as a URL or a local directory path. Local paths are validated to exist and to contain a nested specscore.yaml; entries that fail validation are reported as errors.

AC: plan-route-resolved

Requirements: repo-config#req:plans-repo-project-selection, repo-config#req:plan-repos-aggregate-routing, repo-config#req:plan-route-required, repo-config#req:plan-config-precedence

A local or committed scalar plans_repo selects one Plan destination and overrides organization and user mappings. Without either form of explicit routing, every Plan operation fails before Plan access, while unrelated artifact operations continue normally. Shorthand and full repository identities normalize to the same host/owner/repo identity, and conflicting mappings fail.

AC: plan-checkout-separated

Requirements: repo-config#req:repo-checkouts-machine-local

An external Plan destination resolves only through an absolute machine-local repo_checkouts entry whose checkout root and origin match the destination. Committed checkout paths, relative or nested paths, wrong origins, and unresolved symlinks fail without touching either repository.

AC: modules-resolved

Requirements: repo-config#req:modules-default, repo-config#req:module-name-deduction, repo-config#req:module-path-resolution, repo-config#req:module-code-list, repo-config#req:module-paths-unique, repo-config#req:module-paths-non-nested

Modules resolve their specs, docs, and code paths relative to module.path. Module names are deduced from path when omitted. Duplicate or nested explicit module paths produce hard errors. The implicit-root module (no path:) coexists with explicit-path modules.

AC: studio-rules

Requirements: repo-config#req:studio-default-when-omitted, repo-config#req:studio-explicit-values, repo-config#req:studio-null-opts-out, repo-config#req:studio-toolbar-mandatory-unless-opted-out, repo-config#req:studio-url-trailing-slash

Given a specscore.yaml with any of the following studio: configurations β€” the block omitted entirely, the block present as a mapping with both name and url, the block present as a partial mapping (only name or only url), the block set to null / ~ / empty, or the block present with a studio.url lacking or doubling its trailing slash When tools load the config and render artifact documents Then an omitted studio: block applies defaults (name: SpecScore.Studio, url: https://specscore.studio/) and the studio toolbar is rendered; a full mapping uses its explicit values and the toolbar is rendered; a partial mapping is a hard error and no defaults are applied; studio: null suppresses the studio toolbar entirely; and a studio.url without a single trailing / is a hard error. The studio toolbar is mandatory in artifact documents unless explicitly opted out via studio: null.

AC: extensions-preserved

Requirements: repo-config#req:unknown-fields-preserved

Unknown fields at any level survive read/write without warnings. Orchestrators can extend the config without breaking SpecScore validation.

AC: publication-block-delegated

Requirements: repo-config#req:publication-block-optional, repo-config#req:publication-schema-delegated

Given a specscore.yaml with a top-level publication: block containing event policy, command policy, push branch rules, and an unknown future field When SpecScore tooling reads and writes an unrelated config key Then the publication: block remains a top-level project config block, its known fields are available to consumers under the Publication Policy Config schema, and the unknown future field round-trips unchanged.

AC: recaps-journal-storage-target-gated

Requirements: repo-config#req:recaps-journal-storage-target, repo-config#req:recaps-journal-layered-config-gated

Given a project specscore.yaml with a recaps: block setting enabled: true, and a second one additionally setting recaps.repo while the layered-config Feature has not shipped When the config loader runs Then recaps.enabled is accepted (storage always targets the hub repo, which may be configured to equal the current code repo), and recaps.repo (likewise recaps.user / journal.repo) is rejected with a clear error pointing at the layered-config dependency; unknown fields under the blocks round-trip unchanged.

AC: path-overrides-loaded

Requirements: repo-config#req:path-overrides-optional, repo-config#req:ideas-path-field

Given a specscore.yaml with one module declaring path_overrides.ideas_path: ideas plus an unknown override key, one module with no path_overrides, and one module declaring path_overrides.ideas_path: /ideas (absolute) When the config loader runs Then the first module's ideas_path is read as ideas and its unknown key round-trips unchanged, the second module defaults to spec/ideas, and the third fails with a hard error naming that module and the absolute-path violation.

Open Questions


This document follows the https://specscore.md/feature-specification

View as Markdown