Repository evolution
This OpenSpec workspace describes evolution of the alwaldend/src repository
itself: its shared structure, build system and development workflows.
specs/repository/spec.md records that contract;
changes/ records proposed and completed changes to it.
Each component owns a separate OpenSpec workspace beside its source:
projects/<project>/openspec/ holds that project’s specs and changes.tools/<project>/openspec/ holds that tool project’s specs and changes.infra/<project>/openspec/ holds that infrastructure project’s specs and changes.infra/src/openspec/ holds the repository’s own specs and changes.
Select the narrowest owner of the requested behavior. A project change belongs
in that project’s workspace, including when it has a standalone Bazel module.
Changes to shared repository structure belong here. Work spanning owners
keeps each affected contract with its owner and links related changes.
Component READMEs and build declarations retain their existing authority.
Run OpenSpec
The pinned CLI runs from the Git worktree
root. It selects infra/src by default; use OPENSPEC_PROJECT for a component:
bazel_agent bazel run //tools/openspec -- list --specs
OPENSPEC_PROJECT=tools/agents bazel_agent bazel run //tools/openspec -- list
OPENSPEC_PROJECT=infra/vault bazel_agent bazel run //tools/openspec -- list --specs
Use new change, status, instructions, validate, and archive with the
same owner selection. The packaged Repository OpenSpec skill
documents continuation and acceptance. No global install or assistant
configuration rewrite is needed. The CLI isolates configuration and disables
telemetry.
Repository validation checks every component workspace as well as this one:
bazel_agent bazel test //infra/src/openspec/validation:validate_test //infra/src/openspec/validation:archive_test
Validation checks artifact structure and, for archives, task completion.
Requirement acceptance still needs evidence from the owning implementation.
Infrastructure specs describe checked-in definitions, not observed deployment.
Maintain work
In the selected workspace, changes/<name>/proposal.md states outcome and
scope, design.md records decisions and continuation, tasks.md records
remaining actions, and specs/<capability>/spec.md contains requirement deltas.
Read an existing matching change before creating another. Keep temporary
notes, raw logs and validation receipts under ignored out/<task>/.
On interruption, preserve the candidate, evidence, execution state and next
action. Keep blocked or unfinished work explicit. OpenSpec files and Git do
not supply the removed legacy goal store’s transaction locks or evidence verdicts;
one coordinator owns a change and reconciles concurrent edits.
After acceptance, validate and archive the change in its owning workspace,
then inspect the resulting baseline specs. Specifications and generated
instructions neither expand user authority nor introduce an approval gate.
Goal migration
migration.md maps the nine maintained goals to their current
owner-local changes. It records a repository workflow migration; the actual
history and work state live with Agents, MCP Cordis and Renders. Original
history, checksums and acceptance states are preserved. Historical deltas
were archived without applying them to current specs. Reimu Fumo remains
open and blocked.
The legacy goal tool, its skill, and its store have been removed. New
maintained work uses the owning OpenSpec workspace; the migration record above
preserves the historical record.
1 - Goal migration to OpenSpec
On 2026-09-08, all nine tracked maintained project goal records at source commit 550d7e79b1f5fdbc2b6017b75178471d6914082f were migrated into native OpenSpec changes. Each change now lives in its owning project’s openspec/ workspace. Eight completed records are imported as archived history. The Reimu Fumo change remains open with blocked execution and no accepted candidate.
The machine-readable inventory maps all 222 tracked source files (834,320 bytes) to byte-identical provenance snapshots. Test fixtures and ignored task scratch are outside the maintained-record inventory.
Record mapping
Mapping and acceptance
- Objective and scope map to
proposal.md; accepted plans, decisions, rejected approaches, and constraints map to design.md. - The latest acceptance criteria map to
tasks.md and meaningful capability delta requirements. Each YAML criterion keeps its stable ID and revision in migration.json; original revisions, attempts, review verdicts, and evidence remain in provenance. - Completed task checkboxes reproduce explicit historical acceptance reviews. They do not revalidate today’s source. The Markdown Cordis record declares Complete and no failing criteria; its absent execution field stays unavailable rather than being guessed.
- Reimu acceptance and continuation tasks remain unchecked. A supported authorized unblock can change execution while the outcome remains open until every required criterion passes.
- Completed records were placed directly in their owner’s
openspec/changes/archive/2026-09-08-<id>/. No archive or spec-sync command applied their historical deltas. Current baseline specifications were derived separately from maintained owner source. Do not reapply historical deltas. - Historical Phase 5 acceptance includes an explicit fixture-gap inventory. Its accepted review and still-pending prose are both retained; migration does not claim the missing infrastructure fixtures were implemented.
Provenance and navigation
Each change has migration.json, a checksum inventory at provenance/manifest.json, original record bytes at provenance/source/, and a provenance navigation guide. The old agent goal landing and BUILD file are also retained under the repository-agent-system archive. The historical BUILD snapshot uses .original to preserve bytes without creating a new Bazel package.
Among preserved Markdown links, 47 links depend on the former location; companion navigation tables resolve them where the referenced artifact exists. 46 historical targets are unavailable in the checkout. Original bytes and historical Git identities are not rewritten to disguise unavailable scratch or superseded paths.
The former maintained goal directories are removed, and the legacy goal tool and its store were later removed as well; native OpenSpec work is the continuation surface. Provenance files are excluded from generic formatting so their source digests remain stable. The migration inventory is import evidence, not an alternate work scheduler or mutable status catalog. The removal change is remove-deprecated-goal-component.
2.1.1 - Anki Go Protobuf Integration Specification
Purpose
Make all protobuf schemas from the pinned upstream Anki source available to Go applications through reproducible repository builds.
Sources: dependency ownership,
schema catalog,
binding generation,
and consumer aliases.
Requirements
Requirement: Complete pinned Go schemas
The dependency integration SHALL generate Go messages and declared gRPC clients for every upstream Anki proto, retaining upstream import paths and the existing immutable source pin.
Scenario: Consume a previously omitted service
- WHEN an application imports the pinned tags or i18n schema package
- THEN its generated messages, descriptors and declared clients compile and can be used against the native backend
Requirement: Restricted schema consumption
Schema targets SHALL retain repository-internal consumer visibility.
Scenario: Intended application consumes all schemas
- WHEN anki_as_code links all pinned schema packages
- THEN its build succeeds through the dependency package’s declared aliases
2.2.1 - go-mod-version Specification
Purpose
Keep tracked go.mod files on the Go version configured for
tools/go_mod.
Sources: tool README,
tool BUILD, and
archive.
Requirements
The repository SHALL provide a tools/go_mod command that discovers every
tracked go.mod file and sets its go directive to the version configured in
the tool’s BUILD file. The command MUST offer an update mode and a check mode.
Scenario: Update module files
- WHEN a user runs the update target
- THEN every tracked
go.mod file whose go directive differs from the
configured version is rewritten to that version - AND files already on the configured version remain unchanged
Scenario: Check module files
- WHEN the check test runs
- THEN it fails if any tracked
go.mod file has a go directive
different from the configured version - AND it passes when every tracked
go.mod file matches
Requirement: Repository quality integration
The go.mod version check MUST run as part of //:repo_quality_test so a
version mismatch fails repository quality.
Scenario: Quality suite covers the check
- WHEN a
go.mod file’s go directive differs from the configured
version - THEN
//:repo_quality_test fails
2.3.1 - python-import-validation Specification
Purpose
Enforce module namespace imports in tracked first-party Python source through repository quality.
Requirements
Requirement: Validate namespaced Python imports
The repository quality suite SHALL reject individual symbol imports in tracked
first-party Python source using the existing pinned syntax linter, except direct
public re-exports listed in explicit __all__ in __init__.py. Wildcard imports
SHALL remain forbidden. Module imports
and qualified member access SHALL be accepted, including importing a verified
module with from package.path import module. Long module paths SHALL use this
form. Downloaded external source SHALL
remain outside this first-party check. The Python skill SHALL describe the
convention and its owning validation target.
Scenario: Reject a member import
- WHEN tracked Python imports individual members outside explicit package re-exports or uses a star from-import
- THEN repository quality fails with a namespaced-import diagnostic
Scenario: Accept namespaced imports and inert text
- WHEN source imports modules, including verified module from-imports, or includes from-import text only in comments or strings
- THEN the import check passes
Scenario: Preserve existing consumers
- WHEN existing first-party imports are migrated to the enforced convention
- THEN their module references and supported package exports remain usable
Scenario: Accept explicit package re-exports
- WHEN
__init__.py imports direct symbols and lists their bound names in explicit __all__ - THEN the import check accepts those exports, including relative imports
2.4.1 - Repository Evolution Specification
Purpose
Define how the alwaldend/src monorepo evolves its shared structure, build
system and development workflows. Component behavior is specified in each
owner’s local OpenSpec workspace. This baseline was inspected at source revision
550d7e79b1f5fdbc2b6017b75178471d6914082f on 2026-09-08 and incorporates the
OpenSpec migration delivered with this specification. Changes in infra/src
record repository evolution; they do not collect unrelated component work or claim
runtime health or deployed infrastructure.
Sources: repository map, agent policy,
root build, project boundary,
infrastructure boundary,
tool boundary, OpenSpec workflow,
workspace procedure,
and goal migration record.
Requirements
Requirement: Component ownership and source boundaries
The repository MUST keep component purpose and publication boundaries in the
nearest owner README, executable and dependency structure in BUILD and MODULE
files, and agent policy in the applicable AGENTS.md chain. Specifications SHALL
describe component requirements with links to these owners.
Scenario: Select an implementation owner
- WHEN a change affects a project, tool or infrastructure component
- THEN its owning documents and Bazel workspace determine the affected
paths and supported consumers
- AND a repository-wide catalog or specification does not grant broader
publication or execution authority
Requirement: Reproducible Bazel development
Repository agent build and test operations MUST use bazel_agent bazel in the
owning workspace with pinned dependencies and the repository’s shared agent
configuration. Generated dependency and catalog files MUST be updated through
their owning generator.
Every nested module that declares MODULE.bazel MUST declare only
dependencies its own sources use, with a resolvable version or an override
that applies when that module is the root. Every nested module directory MUST
appear in the root .bazelignore so root target expansion does not cross the
workspace boundary. Each nested workspace MUST build and test standalone.
Scenario: Change a shared dependency
- WHEN an implementation adds an external build input
- THEN its owner records an immutable version and integrity information
- AND applicable generated locks and package checks validate the declared
dependency through the pinned build workflow
Scenario: Build a nested module standalone
- WHEN a nested Bazel workspace is built or tested on its own
- THEN its module graph resolves without depending on root-only overrides
- AND the workspace builds and tests through its shared configuration
Scenario: Expand root targets across a nested boundary
- WHEN the root workspace expands targets beneath a nested module directory
- THEN the nested workspace is excluded by the root ignore list
- AND root expansion neither loads nor silently omits that module
Requirement: Isolated implementation and evidence
Repository modifications MUST use a dedicated feature branch and linked
worktree. The repository SHALL own that procedure in a repo-workspace skill
that runs before the first mutation or task-scratch write, so isolation and
scratch placement are established before repo-delivery is loaded. Task
scratch MUST remain under ignored out/<task>/ in the applicable workspace,
and configurable temporary and cache locations SHALL point there. Delivery
SHALL exclude disposable build outputs and include required
generator-maintained files updated through their owning workflow. Acceptance
SHALL identify the candidate and relevant checks and representative output
before delivery.
Scenario: Finish a repository change
- WHEN an authorized implementation is ready for delivery
- THEN task-owned changes pass applicable formatting, quality and semantic
checks and are committed and published through the repository procedure
- AND unrelated edits, scratch and protected data are excluded
Scenario: Begin a task that writes
- WHEN a task will modify repository files or write task-owned scratch
- THEN the agent verifies the feature worktree and branch before the first
write
- AND task-owned scratch and configurable temporary locations stay under
the ignored
out/<task>/ directory
Scenario: Prepare the delivery candidate
- WHEN the delivery procedure stages the candidate
- THEN disposable build outputs are excluded
- AND required generator-maintained files are included after their owning
workflow regenerates them
Requirement: Declarative infrastructure authority
Persistent infrastructure configuration MUST be defined in checked-in owning
infrastructure code. Infrastructure operations MUST require the user’s exact
operation and scope authorization; an implementation validation request SHALL
NOT authorize live deployment.
Scenario: Validate an infrastructure specification
- WHEN an agent adds or updates an infra component specification
- THEN it inspects source and runs applicable offline checks
- AND it does not infer deployed state or execute live apply or deployment
from the existence of the specification
Requirement: OpenSpec coverage and work state
Each direct project in projects/ and infra/ SHALL keep its baseline
specifications and maintained changes in its own openspec/ workspace.
infra/src/openspec SHALL describe evolution of the repository itself,
including shared structure, build system and development workflows. The
repository root SHALL NOT collect component specifications or change records.
Every repository change MUST use an OpenSpec change in its owning workspace,
including trivial edits, documentation, configuration, and dependency changes.
A matching active change SHALL be reused when available, and artifacts SHALL
remain proportional to scope. Read-only questions and reviews do not require
a change record. Maintained work SHALL preserve outcome, decisions, tasks and
requirement deltas. Existing task authority MUST survive workflow transitions.
Scenario: Change a component contract
- WHEN a change affects a project’s supported behavior
- THEN its specifications and change artifacts remain in that project’s
openspec/ directory - AND the pinned CLI and context routing select that owner workspace
Scenario: Evolve the repository itself
- WHEN a change affects the monorepo’s shared structure or development workflow
- THEN
infra/src/openspec records its repository requirements and evolution - AND component contracts remain with their respective owners
Scenario: Resume unfinished maintained work
- WHEN an agent resumes a named OpenSpec change
- THEN it reads that owner’s change artifacts, candidate, evidence and next action
- AND unfinished or blocked acceptance remains explicit until evidence
supports completion
Scenario: Validate a standalone project
- WHEN a project has its own Bazel module
- THEN repository OpenSpec validation still checks its declared local workspace
- AND a successful repository check does not omit that project’s requirements
Scenario: Make a trivial change
- WHEN an agent makes a one-line repository correction
- THEN it selects or creates a matching owner-local OpenSpec change before
editing, with small artifacts and skip_specs if behavior is unchanged
- AND the record adds no approval gate to already authorized work
Scenario: Conduct a read-only review
- WHEN the task only inspects a bounded change set and reports findings
- THEN no new OpenSpec change is required for that review
- AND the review itself does not authorize implementation or publication
Requirement: Removed legacy goal record
The repository MUST NOT carry a goal tool, goal store, or goal skill, and MUST
NOT reintroduce a goal record format as a maintained work channel. Maintained
work SHALL use the owning component’s OpenSpec workspace. The change SHALL
identify the removed component.
- WHEN an agent needs durable intent, tasks, or continuation state
- THEN it uses the owning component’s
openspec/ workspace through the
pinned CLI - AND no goal command, skill, or store is available or documented as an
active channel
Scenario: A reader needs the removed implementation
- WHEN a reader needs a file from the removed goal component
- THEN the change and migration record name the removed tree
- AND the reader retrieves the file from git history at the removal
commit’s parent
Requirement: Rule scripts and generated documentation
Bazel rules MUST NOT embed templated executable content in rule source. A rule
that needs an executable MUST reference an ordinary checked-in script and
supply its inputs as declared arguments or data files. Every public rule set
MUST generate stardoc documentation for its public .bzl entry points, and the
repository’s main documentation output MUST include that generated
documentation.
Scenario: A rule needs to run scripted logic
- WHEN an implementation needs a rule to run a script
- THEN the script is checked in as a normal file with its own target and receives data through arguments or a declared data file
- AND generated shell or program text does not live in the
.bzl source
Scenario: A rule set exposes public rules
- WHEN a project publishes a public Bazel rule or macro
- THEN it declares stardoc coverage for the declaring file
- AND the generated pages appear in the repository documentation build
First-party standalone Bazel rule modules SHALL live under tools/<module>/.
Their relocation MUST preserve module names, supported public rule and macro
interfaces, standalone workspace resolution, generated rule documentation,
and owner-local specifications. Repository consumers and discovery mechanisms
MUST resolve their new source locations through the owning declarations.
Scenario: Consume a relocated rule module
- WHEN a root or nested workspace loads a relocated rule module through its
supported module name and public rule interface
- THEN the module resolves from its new tool-owned location
- AND its supported build behavior remains available without changing the
public module identity
Scenario: Discover a relocated owner’s specifications and rules
- WHEN repository documentation, skill discovery, or OpenSpec validation
traverses the relocated modules
- THEN it selects the modules’ new owner paths
- AND generated rule documentation and existing component specifications
remain included in their declared outputs and checks
The relocated rule modules SHALL have no dedicated project landing-site
configuration. After authorized retirement, their selected landing repository
and DNS declarations MUST be absent from the owning infrastructure, and
shared-catalog consumers MUST exclude those retired repositories. Retirement
MUST preserve unrelated repositories, sites, access grants, and authentication
resources.
Scenario: Build or import the remaining repository catalog
- WHEN the catalog is projected for GitHub or GitLab after rule-landing
retirement
- THEN the retired landing repositories are absent
- AND remaining repositories retain their catalog identities, names, and
configured access behavior
Scenario: Retire a selected landing site
- WHEN the owning declarative workflows execute the user’s explicitly
authorized retirement scope
- THEN the selected Pages repository and matching DNS record are removed
- AND the reviewed plans and postconditions show no unrelated deletion or
replacement
Requirement: Thin CI workflow wrappers
Repository CI workflows MUST be maximally thin wrappers. Executable logic SHALL
be implemented in bazel run targets or committed scripts; workflow YAML SHALL
contain only declarative orchestration and short command invocations. The
discoverable repo-ci skill SHALL document this rule and link owning sources.
Scenario: A workflow needs executable job logic
- WHEN a workflow requires resource checks, authentication, parsing, loops,
or other executable behavior
- THEN that behavior resides in a committed implementation invoked by the
workflow, preferably through
bazel run - AND inline programs, heredocs, and composite-action YAML do not substitute
for the implementation
Scenario: An agent changes repository CI
- WHEN an agent discovers the repository skills for CI work
- THEN
repo-ci explains the workflow and command boundaries, authentication
constraints, and applicable offline and live validation entry points
Requirement: Shared repository CI entry point
Every repository CI workflow SHALL use the local tools/ci/action action
after checkout. The action SHALL launch bazel run --config=ci //tools/ci
without a shell and propagate its failure.
The entry point SHALL build and test all normal targets in the root and nested
Bazel workspaces, continuing to attempt both phases and remaining workspaces
after a failure and returning failure if any command fails. It SHALL discover
nested workspace boundaries from the root .bazelignore and MODULE.bazel
files. Runner infrastructure acceptance probes SHALL NOT be part of normal CI.
Scenario: Run normal CI
- WHEN a repository CI workflow runs
- THEN the shared command builds and tests each workspace with the CI profile
- AND normal Bazel exclusions for manual and incompatible targets apply
Scenario: One build fails
- WHEN one workspace’s build phase fails
- THEN its test phase and the remaining workspaces are still attempted
- AND the entry point reports failure
Requirement: Compose repository policy with skill routing
The root AGENTS.md SHALL keep repository-wide constraints visible: fact
ownership, infrastructure and approval authority, mandatory delivery,
worktree isolation, protection of unrelated work, confidentiality, and naming
and communication standards. Execution detail SHALL live with the skill that
owns it, and the root document SHALL route to that skill through one compact
“When to load a skill” table ordered by task phase. Each routing entry SHALL
name the trigger and the skill without restating the skill’s procedure.
Initial reads SHALL depend on the task: applicable policy and the owning
README first, and BUILD or MODULE declarations only when implementation or
validation depends on them.
Scenario: An agent starts an unfamiliar task
- WHEN an agent begins work in a subtree
- THEN it reads the applicable
AGENTS.md chain and the owning README.md - AND it inspects BUILD or MODULE declarations only when the task depends
on them
- AND it loads the skill whose routing trigger matches the current phase
Scenario: A procedure needs to change
- WHEN a repository-wide procedure changes
- THEN the change belongs with the skill that owns it, not in the root
policy
- AND the root document retains only the routing entry and any
repository-wide constraint
Requirement: One authoritative source per fact
Each fact SHALL have one authoritative source. Independently maintained
duplicates SHALL be treated as defects even when the original is hard to
reach; the owner SHALL be extended or parameterized instead of copied.
Generated projections, fixtures, and concise summaries that identify their
source are projections rather than duplicates.
Scenario: A generated file restates an owned fact
- WHEN a checked-in generated file, fixture, or summary restates a fact
owned elsewhere
- THEN it identifies its source and regeneration workflow
- AND it is not treated as an independently maintained duplicate