Repository navigation
feat(e90): dev-environment hardening — config consolidation, CI gates, tooling debt - #311
Conversation
Fixtures a throwaway root via BIGBASE_ENV_DOC_ROOT so the gate can be exercised against missing-key, missing-workflow and empty-declaration cases instead of only the live repository. Red: the gate ignores the override and dies at git rev-parse (exit 128).
GREEN for the e90s01 drift tests: BIGBASE_ENV_DOC_ROOT overrides the git-derived root so missing-key and skip paths are testable without touching the live .env.example. Default behaviour is unchanged.
Covers opening/separator/closing markers, non-anchored false positives, and the CHANGELOG.md + specs/archive exemptions that the inline CI step handles today. Red: scripts/check-conflict-markers.sh does not exist yet (8/8 failing).
GREEN for the e90s02 marker tests. One implementation of the marker contract (git-tracked scan + explicit-path mode) so CI and pre-commit stop carrying copies of the same regex.
Replaces the inline git-grep copy in the verify job and adds the same gate to pre-commit, so both paths share one implementation and one set of exemptions.
Leftover from a conflict-resolution session; it matched nothing and shadowed the intent of the surrounding dev-tooling block.
AGENTS.md demotes ctxo to optional-when-fresh, but the task table still read "REQUIRED First Call" — the contradiction that made agents block on a stale index. Also lands the setup-dev.sh onboarding script that sets core.hooksPath and warms the index.
The -race CI job observed status=stopped with status_history frozen at "running". Reproduces deterministically: draining a deployment with no in-memory app entry records nothing in status_history. Red: history stays empty (status written by a raw UPDATE in stopDeployment).
GREEN for the app-less drain test. Two defects were hiding behind the -race failure: - stopDeployment() wrote status with a raw UPDATE, so force-stops (orphan drain, DELETE) never reached status_history. It now goes through forceStatus(), which appends the transition. - drainDeployment() skipped the draining transition entirely when no in-memory app existed, and a second collect could force-stop a deployment while the first drain was still running. The drain intent is now recorded before the branch and duplicate drains are skipped. Full -race suite for deploy/functions/realtime/monitoring is green.
scripts/gen-mcp-configs.sh tells contributors to run `make mcp`, but no Makefile target existed. Also asserts opencode.jsonc still mirrors the canonical .mcp.json server list. Red: "No rule to make target `mcp'" (1 of 3 failing).
GREEN for the MCP adapter tests. The Makefile was an untracked scratch file with no mcp target even though gen-mcp-configs.sh documents one; track it with mcp/mcp-check wired to the canonical generator.
The async-assert guideline was correct but did not mention the deploy audit trail, the case that actually flaked in the -race CI job: status is committed before status_history, so readers must poll for the transition. Also refreshes the generated conventions wiki.
AGENTS.md is the only agent instruction file; CLAUDE.md and GEMINI.md are symlinks to it. Regenerates the OKF agent-guide pages from that source and trace-tags the scripts that implement the e90 stories.
The drift script only checked prose. These fixtures assert the configurations too: CI GO_VERSION/NODE_VERSION against go.mod/.nvmrc and the toolchain.toml Go floor. Red: 3 of 6 failing (no configuration checks yet).
GREEN for the configuration drift tests. Adds a BIGBASE_VERSION_ROOT override, then compares the CI GO_VERSION/NODE_VERSION env pins and the toolchain.toml Go floor with the declarations in go.mod and .nvmrc.
The new fixture tests (env-doc, conflict-marker, MCP adapter, version drift) were only runnable locally. Wire them into verify so a gate that silently stops detecting drift fails CI, and expose them as `make test-scripts`.
audit-code follow-up: forceStatus read the current status outside the mutex TransitionState uses for its history read-modify-write, so a concurrent transition could land in between and leave the recorded "from" stale. Read, write and append now share the same critical section; deploy package stays green under -race.
request-review F-1: a bare "story:" tag on a file that does not obviously implement the story reads as tag-padding. Both markers now name the relationship so the trace matrix stays auditable.
request-review F-2: the script used relative paths with no root resolution, so run outside the checkout it read nothing and exited 0 — a green gate that checked nothing. It now resolves the root (override or git rev-parse) and documents the loud-failure behaviour.
e90 grows past the flat-shard limit: nine stories, threat model, test plan and per-task verify commands. Moves it to specs/epics/e90-dev-environment-hardening/ with epic.yaml plus one spec and one -tasks.yaml per story, updates release-plan.yaml to the capsule form, and records the scoped e90 requirement set.
All nine stories are done in execution-status.yaml, the epic and its release-plan entry read done, state.yaml carries the ten gate decisions and the handoff to release-branch, and each story has a -verify.yaml with a terminal verdict. Also refreshes the traceability matrix, blind-spot report and spec drift report (0 blind spots, 1 reviewed drift link).
The deploy package sits at ~250-300s under -race on a loaded machine and hit the old 300s per-package budget as a timeout panic. Bump -timeout to 600s (job still allows 20 minutes). One later 423s failure was not reproduced across 10+ clean runs (count=2, count=3, count=5 stress) and never produced a DATA RACE report; recorded in state.yaml decisions.
Preflight green, zero active bugs, zero failing tests.
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Explore these optional code suggestions:
|
User description
Summary
Epic e90 — Dev-Environment Hardening (WSJF 9.0), built end-to-end and verified.
What ships
BIGBASE_ROOT_ENCRYPTION_KEY) — fixture-testable, enforced in pre-commit + CIscripts/check-conflict-markers.sh) backing CI + pre-commit; stray.gitignore<stdin>pattern removed-raceCI job + UI lint/typecheck/test/build gate; fixed a real defect the race job exposed — drain transitions now reachstatus_history(forceStatus+ idempotent drain guard).mcp.jsoncanonical source +make mcp/make mcp-checktoolchain.tomlfloorwaitForStatusHistorycanonical exampleAlso carries 5 prior readiness-gates commits (all
chore:) that were merged to local main but never pushed.Test plan
verify)trace-stories --strictexit 0; 0 blind spotsNote on merge
This branch contains
feat:/fix:commits, so merging will cause big-release to auto-publish a release and deploy.yml to auto-deploy to production. Flagged for confirmation before merge.PR Type
Enhancement, Bug fix, Tests, Documentation
Description
Add reusable conflict/env/version gate scripts
Fix drain race with idempotent guard and history
Add gate-script tests wired into CI verify
Consolidate AGENTS.md; remove CLAUDE/GEMINI adapters
Add git hooks and Make targets
Diagram Walkthrough
flowchart LR A["Reusable gate scripts"] --> B["CI verify + pre-commit"] C["Drain idempotence + forceStatus"] --> D["status_history audit trail"] E["AGENTS.md consolidation"] --> F["CLAUDE/GEMINI removal"] G["Gate-script tests"] --> BFile Walkthrough
3 files
Idempotent drain guard and early draining transitionforceStatus appends audit history under mutexAdd draining map to prevent duplicate drains5 files
Poll status history and orphan drain testPin conflict marker gate failure pathsPin env doc gate failure and skip pathsPin CI and toolchain version drift failuresVerify canonical MCP adapter generation4 files
Raise race timeout, reuse gates, run script testsEnforce Conventional Commits and no AI attributionRun conflict marker gate on commitBlock manual pushes to protected main5 files
Add reusable conflict marker gate scriptSupport fixture root for env gateExtend drift checks to CI and toolchain pinsRestrict strict dark checks to active epicAdd build, test, script, and MCP targets3 files
Consolidate agent rules and demote ctxo mandateAdd commands, never-do list, async polling guidanceRemove Claude-specific adapter in favor of AGENTS.md20 files