v2.1.0 — M6 hardening & UX #93
danielPoloWork
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
M6 — hardening & UX. The post-v2.0.0 hardening milestone: the automation/completeness gaps
(G2–G4) and feature suggestions (F1–F4) surfaced by the v2.0.0 enterprise review, plus the deferred
cross-spec scope (#72). All opt-in and behind the unchanged pipeline — a MINOR release, no breaking
changes. Highlights: a thin executable phase orchestrator (
eados.py), the/eados statusdoctor,single-artifact render for
refactor, an end-to-end phase smoke, risk-model weights as data,auto-derived traceability links, hands-off Dependabot action-pin sync, and two new dogfooded gates
(
version-lockstep, cross-cuttingcross-spec-consistency).Added
traceability-lint(thegit-spec CI gate, not a phase-transition gate) is now registered inworkflow.yaml's gate list(cross-cutting,
required_for: []), andeados_lint'scross-spec-consistencyvalidatesgit.yaml'straceability.gateagainst that registry — so a typo'd cross-cutting gate id iscaught too (the scope deferred from feat(lint): cross-spec-consistency gate — referential integrity across the OS specs #62).
test_cross_spec.pycovers the resolve + typo cases.Completes M6. No pipeline behavior change.
version-lockstepgate it ships to generated repos: a new
eados_lintcheck asserts every README release badge(EN +
docs/i18n/*) and the CHANGELOG's "the latest is vX.Y.Z" prose match the CHANGELOG'slatest released
## [X.Y.Z]heading — so a release bump must move all of them in lockstep or theself-lint fails. Pure
version_lockstep_problems(); covered bytools/tests/test_version_lockstep.py. No pipeline behavior change.tools/derive_links.pybuilds the{pr, rfc, milestone, commit, release}traceability edges frommerged PRs —
pr/commit/milestonefromghmetadata,rfcparsed from the body,releasefrom a release PR's title — and emits a
links.yamlthattraceability.py --linksconsumes, sothe graph runs on real data instead of a hand-maintained file. By default it emits only delivery
PRs (those with an rfc or milestone);
--allemits every PR. The parser is pure and testedgh-free; the optional fetch degrades cleanly (clear message, exit 2) when
ghis absent,unauthenticated, or offline — CI never depends on the network. Covered by
tools/tests/test_derive_links.py. No pipeline behavior change.tools/eados.py <phase> <manifest>runs a phase's deterministic outgoing gates — read from
workflow.yaml(no hardcoded chain) —evaluating the ones it can (
manifest-valid,rfc-approved,roadmap-covers-rfcs) via thesibling tools and marking render-time / human gates
[manual], then prints the legal nexttransitions and points at the procedure;
eados.py statusdelegates to the doctor (6.4). It isthe executable spine beneath the markdown
/eados <phase>procedures — it reports and gates,never authoring or advancing state. Covered by
tools/tests/test_eados.py. No pipeline behaviorchange.
/eados statusdoctor (F1, F1 — /eados status (doctor) #66). A new read-onlytools/doctor.py(the/eados statussurface,commands/status.md) reports a project's delivery health at a glance:current phase (+ its owning role and what it produces), the legal next transitions (+ gates and
human-gating, via
phase_runner), the recordedrfcs/milestonesrefs, and traceabilitycoverage (
roadmap-covers-rfcs, plustraceability-lintwhen a links file is present, viatraceability). It composes the existing tools — never re-implements — and exits non-zero on anactionable problem (undeclared phase, uncovered RFC, dangling edge), doubling as a pre-flight
check. Covered by
tools/tests/test_doctor.py. Read-only; no pipeline behavior change.refactorphase (G2, G2 — single-artifact render for the refactor phase #63). A newtools/render_artifact.pyrenders one template with the manifest context — reusingrender.py's engine and thevalidate_manifest+ unresolved-placeholder gates, so a singleartifact is byte-identical to its whole-render twin — and writes it into a target repo through
tools/sandbox.py(safe_write: contained, never.git, additive). It performs the "render themissing artifact → sandbox" step
commands/refactor.mddescribes (now invoked there instead ofdone by hand). Covered by
tools/tests/test_render_artifact.py. Factory tooling; no pipelinebehavior change.
dependabot-pin-syncworkflow mints a short-lived App token (actions/create-github-app-token,SHA-pinned) when
SYNC_APP_ID+SYNC_APP_PRIVATE_KEYare set and pushes the pin re-sync with it,so CI re-triggers and the failed
action-pinscheck goes green by itself; absent the Appsecrets it falls back to
GITHUB_TOKEN(the fix still lands, check re-runs on the next event). Thesetup guide is rewritten App-first;
DEPENDABOT_SYNC_TOKENis now the swap-in PAT fallback, not thedefault. Factory-only; no pipeline behavior change.
tools/tests/test_phase_smoke.pythreads one coherent fixture project (manifest + RFC + ROADMAP + links) through
design → plan → auditby invoking the real phase tool CLIs (rfc_check,traceability,risk_score,phase_runner) the way an agent runs a phase. It asserts each gate passes on the goodfixture and fails on a deliberately broken one, that
phase_runner --proposereports everytransition declared in
workflow.yamlLEGAL (and rejects an undeclared one), and that each entrygate's backing tool exists on disk — catching tool-integration (seam) bugs the per-tool unit
tests cannot. Wired into the CI self-lint job. No pipeline behavior change.
blast radius), the
blast_radius_threshold, and the points→level cutoffs move out ofrisk_score.pyintorisk.yamlas data — each per-domain overridable (weights shallow-merged),exactly as
mandatory_gate_levelalready was (OQ2). The scorer reads them via a newresolve(cfg, domain)with built-in fallbacks, so a pre-6.2risk.yamlstill scores identically(back-compat) and the shipped default scores are unchanged.
risk/_schema.mddocuments the newkeys; covered by the expanded
test_risk_score.py. Knowledge as data — no special-casing in code.tools/sync_action_pins.py(--check/--fix) rewrites the workflow templates'(
templates/.github/workflows/*.tmpl) action pins to the factory CI's pin for each shared action— reusing
eados_lint's pin regex so the fixer and theaction-pinsgate can never disagree. Aweekly Dependabot
github-actionsbump now needs no manual template edit to pass the lockstepgate. The new
dependabot-pin-syncworkflow (workflow_run, notpull_request_target;ADR-0013) applies the fix automatically on a Dependabot PR — true zero-touch — gated to genuine
in-repo Dependabot PRs; the same
--fixis the manual/local fallback (stay-current routine).Deterministic and dependency-free; covered by
tools/tests/test_sync_action_pins.py. Factory-only(generated repos render no templates). No pipeline behavior change.
DEPENDABOT_SYNC_TOKENsetup guide.maintenance/dependabot-sync-token.mddocumentsthe optional token for green-by-itself Dependabot pin auto-sync (ADR-0013): fine-grained PAT
(drop-in) vs GitHub App (robust, with the workflow snippet), least-privilege (Contents-write only),
storage via
gh secret set, verification, and rotation. Linked from the stay-current routine.Maintainer-facing; no behavior change.
Security
This discussion was created from the release v2.1.0 — M6 hardening & UX.
Beta Was this translation helpful? Give feedback.
All reactions