Releases: danielPoloWork/pgs-eados
Release list
v2.7.0 — post-v2.6.0 hardening & the #203 audit-trail epic
v2.7.0 is a MINOR, additive release: it hardens the phase engine, the learning loop, the renderer's write path, and the self-lint, and completes the #203 audit-trail epic. It groups 13 merged PRs (#204–#218) across issues #194–#202 + the epic children #213/#214/#215. No breaking changes; a legacy manifest renders unchanged.
Added
- Phase-state transitions are enforced — a
delivery-state-consistentcheck rejects phase-skips (#199).delivery_state.checkpointsmust be a legal, contiguous chain ending at the current phase, withconfirmed_byon human-gated moves; a hallucinating agent can no longer setphase: scaffoldwithout the intervening checkpoints. - Fail-closed phase gates under
--strict; the dead--linksplumbing dropped (#200). Gate marks distinguishskipped(not applicable) fromneeds-input(a checkable input was withheld);--strictfails the phase onneeds-input, so a gate can't be satisfied by omission. - Interview provenance is enforced complete, not just well-shaped (#201). Every answer-bearing section needs a provenance entry (+
questionnaire_version), so a partial block no longer silently starves the learning loop. - The
agent-registryself-lint is now bidirectional (#202). A dead index link (a renamed/deleted persona) is caught, not just a missing persona. - Live
gate_resultsin a transition's checkpoint — the phase audit trail (#213). The checkpoint records the runner's own live evaluation of the deterministic gates, and — withat/confirmed_by— is the phase-tagged action record for every transition. - Optimistic concurrency for the manifest —
manifest_rev+--expect-rev(#214). Parallel sessions can no longer silently lose an update; a stale write is refused with aCONFLICT. - Learning-loop coverage (#215). A refactor-phase
--failurechannel + phase-tagged records, a corpus-scaledautotuneconfidence floor, and redaction of sensitive override values.
Fixed
yamlminirejects folded>block scalars instead of silently dropping the body (#194) — the fix also recovered thenotesbodies in every language profile.- A second same-day run record no longer requires falsifying its date (#197).
- The learning-loop miners skip a malformed record instead of aborting the analysis (#198).
Security
- The renderer refuses to clobber pre-existing files — additive by default,
--forceto regenerate (#195). - A
.gitpath segment is rejected at validation time, not just at write time (#196).
Verified on main: 16 self-lint checks green (incl. version-lockstep + i18n-freshness), 44/44 test scripts pass. Full detail in CHANGELOG.md.
v2.6.0 — M13: audit remediation & the learning loop
v2.6.0 — M13: audit remediation & the learning loop
This release completes milestone M13: a full-repo council audit turned into 14 focused fixes,
whose centrepiece is a closed, mechanical, human-gated learning loop. MINOR — every change is
additive; nothing removed or breaking.
The learning loop, closed and mechanical
record_run.py(#172) — one command writes a run record;overridesderive mechanically
from the manifest's interview provenance, with durablefailuresandrubricchannels.lesson_audit.py(#173) — a report-only watchdog: regressions against a recorded lesson,
dead lessons, and low rubric trends — the trigger to promote an advisory lesson to a gate.- Review-time lesson capture (#174) — an optional PR
Lesson:field (a merged PR body is
owner-approved by construction),lesson_sweep.pyto harvest it, and the historical
L-0003 / L-0004 backfill. run-recordsschema gate (#175) —learning/runs/**moves inside the enforcement
perimeter; a malformed record now fails CI instead of silently poisoning the auto-tuner.
Render & interview hardening
- Interview provenance recorded in the manifest — asked vs defaulted vs imported (#169).
- A spec-substance floor in
validate_manifest— no more hollow repositories (#170). - No silent
it/d4npnamespace fallback (#163); domain overlays are actually applied for
game / web / mobile projects (#165).
Factory internals
render.py --check(validate-only) plus a gate-executability lint (#164).yamlminiextracted as a loud loader that rejects the #153 truncation constructs (#166);
a leading UTF-8 BOM no longer breaks manifest parsing.- The lint reporter is threaded through every check (#167); a test discovery runner means new
tests need zero CI edits (#168).
Docs
- The Recall/Record steps are wired into the generation playbook (#171).
- README sweep (#176): a grouped tools table (all 27 tools), a new "How EADOS learns"
section, and date-stamped model claims (the stale "Fable 5 not yet available" is fixed).
Full changelog: see CHANGELOG.md → [2.6.0].
v2.5.0 — M11 delivery-workflow codification + M12 interview completeness
Two milestones, purely additive. M11 codifies the delivery workflow as data; M12 closes every gap the interview-completeness audit found in the intake interview. No breaking changes.
✨ Added — M12: interview completeness (#149–#154)
- Environment preflight (#154). A dependency-free
tools/preflight.pyverifiespython/git/gh(+gh auth) up front with OS-specific install hints and a non-zero exit — no more mid-run stack traces on a missing tool. The installers carry a non-Python bootstrap hint for the Python-missing case. - First-class
webdomain + enterprise posture (#149, ADR-0015). A shippeddomains/web.yaml(hard accessibility + Core Web Vitals budgets, UX/content pipeline,accessibility-review+web-vitals-budgetgates) — andenterprisemodelled as an orthogonalgovernance.postureflag that raises the bar on any domain, deliberately not a fourth domain. - Architecture-style & pattern elicitation (#151).
Q5.4captures a structured style (Layered / Hexagonal / Clean / …), expected patterns, and anadvisory | enforceddiscipline posture — and seeds the generated pattern catalogue instead of shipping it empty. - Optional layered package scaffold (#152). A service/app/web project can opt into
controller / service / repository / dto / mapper / …packages under bothsrc/mainandsrc/test, recorded in the generated ADR-0002; a library keeps the flat shape. - Spec import-and-validate (#153). Phase 5 opens with
Q5.0 — provenance: bring an existing PRD/SRS, get it mapped onto the six-section shape and gap-audited for testability — only the gaps are asked. - Authoring languages (#150, ADR-0016). Doc + code-comment language are asked unconditionally (defaults confirmed, never silent); a non-English choice renders a recorded exception into the generated
AGENTS.md§2 while identifiers/API/commits stay English.
✨ Added — M11: delivery-workflow codification (#141–#144)
- PR-metadata contract as data (
git.yamlpr.metadata+ advisorypr_metadata_check.py). - Full roadmap milestone seeding (
seed_milestones.pycreates everyMN — namemilestone, not just the first). - Explicit "CI live & green" bootstrap gate — per-milestone PR delivery opens only after the bootstrap PR's CI is green.
- Verbose squash-body policy — the squash commit carries the PR's context/change/verification body, never a one-liner.
🐛 Fixed
questionnaire.yamlsilent truncation (#153 discovery). The hand-rolled loader doesn't fold multi-line quoted scalars or multi-line flow lists and silently dropped everything after the first one — phases 4–5 were partly invisible to machine consumers. Data reflowed to the loader-supported subset, with a full-parse guard + a PyYAML differential now running in CI.
Full detail in CHANGELOG.md. The factory bundle, SHA256SUMS, and the setup.* installers attach automatically when this release is published.
v2.4.0 — M10 post-audit hardening
M10 — post-audit hardening. The follow-up to a full post-v2.3.0 repository audit: correctness, security, and documentation hardening. No breaking changes, no new user-facing features.
🔒 Security
- Installer tar-slip guard (#129).
setup.sh/setup.ps1now refuse any symlink/hardlink entry in a downloaded bundle before extracting — defeating a path-escape via a malicious link target — and the guard runs even under--no-verify.
🐛 Fixed
- UTF-8 stdio on Windows (#128). Every CLI tool forces UTF-8 on stdout/stderr, so non-ASCII output no longer mojibakes and the central self-lint no longer crashes on a
cp1252console. - Defensive hardening of latent edge cases (#131). Fail-safe guards in
risk_score,cleanup_installer, andeados_lint(gate-coverage), plus clean errors instead of tracebacks on bad input across thedoctor/eados/phase_runner/traceability/rfc_checkCLIs. - Docs accuracy sweep (#130). SECURITY.md version, a 404
USAGE.mdlink in the translated READMEs, thecontributionOS-spec index row, the RFC roadmap pointer (M1→M9), and thetemplates/.githubsummary.
📝 Changed
- ADR-0009 addendum (#132). Records that generated-repo profile CI actions stay version-tag-pinned (Dependabot-managed) by design — an apparent inconsistency surfaced on re-audit, not a design gap.
Full detail in CHANGELOG.md. The factory bundle, SHA256SUMS, and the setup.* installers attach automatically when this release is published.
v2.3.0 — guided installer + README overhaul
MINOR (additive) — everything since v2.2.0. This is the first release to ship the guided installer.
Highlights
M9 — guided cross-platform installer
A guided installer (setup.{sh,command,ps1,bat}) downloads the bundle, verifies its SHA256 (fail-closed), and extracts it additively (never overwriting an existing file). It is interactive when run bare (asks new-vs-existing repo, path, and the name; git inits a new repo) and fully scriptable via flags. /eados init tidies the installer's leftovers afterward.
This release also attaches a SHA256SUMS manifest + the installer scripts, so these become stable links:
https://github.com/danielPoloWork/pgs-eados/releases/latest/download/setup.sh…/setup.ps1(plussetup.command,setup.bat)
README — comprehensive overhaul
Retitled to EADOS — Enterprise Agentic Delivery OS; standalone framing, a License & ownership section, a downloads badge, a table of contents, Why EADOS (incl. the vs-cookiecutter positioning), Capabilities at a glance, the phase-pipeline table, a Security posture section, and a FAQ — with the zh-Hans + ja translations in lockstep.
Also
- Carry-through release default — the agent tags + drafts a release; the human publishes.
Install (one step)
curl -fsSL https://github.com/danielPoloWork/pgs-eados/releases/latest/download/setup.sh -o setup.sh && sh setup.shWindows: download setup.ps1 and double-click setup.bat. Full options + the double-click notes are in USAGE §6.
Full details: CHANGELOG [2.3.0].
v2.2.0 — onboarding, contributor-safety hardening, inbound contribution review
The first release since v2.1.0 (M6). Additive + backward-compatible (MINOR) — the factory and the opt-in phase pipeline are unchanged.
M7 — onboarding & docs
- Prerequisites: getting an AI coding agent (Claude Code / Gemini Antigravity / ChatGPT Codex), plus the no-agent deterministic path.
- Windows/PowerShell install + render variants beside every Unix snippet.
- The
project.yamlmanifest documented field-by-field (+ amanifest-templateguard so it can't silently break). - An end-to-end phase walkthrough (
init → audit) against a worked example. - The
rfc_checkscope clarified — a repo's own meta-RFCs are out of scope by design.
Contributor-safety hardening (eados_lint #13–#16)
- gate-coverage meta-gate + data-file-validity floor: no factory file can ship ungated — a new ungated file class fails CI.
- manifest-template + workflow-safety gates: the consumer-copied manifest stays valid, and the sensitive CI triggers (
pull_request_target/workflow_run) need a justification — in this repo and in the workflow templates shipped to every generated repo.
M8 — inbound contribution review
- The contribution policy as data (
os/contribution/), thecontribution-reviewerrole,pr_review.py, the/eados reviewcommand, and the cross-cuttingcontribution-reviewgate. - The principle (ADR-0014): never merge a non-owner's commits — adopt a good idea via a co-author re-implementation; the human disposes; always thank.
Full notes: CHANGELOG.md. The consumer bundle (pgs-eados-bundle.tar.gz / .zip) attaches automatically once this release is published.
v2.1.0 — M6 hardening & UX
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 status doctor,
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-cutting cross-spec-consistency).
Added
- M6 / 6.8 — cross-spec gate extended to cross-cutting gates (#72).
traceability-lint(the
git-spec CI gate, not a phase-transition gate) is now registered inworkflow.yaml's gate list
(cross-cutting,required_for: []), andeados_lint'scross-spec-consistencyvalidates
git.yaml'straceability.gateagainst that registry — so a typo'd cross-cutting gate id is
caught too (the scope deferred from #62).test_cross_spec.pycovers the resolve + typo cases.
Completes M6. No pipeline behavior change. - M6 / 6.7 — version-lockstep dogfooding (F4, #69). EADOS now dogfoods the
version-lockstep
gate it ships to generated repos: a neweados_lintcheck asserts every README release badge
(EN +docs/i18n/*) and the CHANGELOG's "the latest is vX.Y.Z" prose match the CHANGELOG's
latest released## [X.Y.Z]heading — so a release bump must move all of them in lockstep or the
self-lint fails. Pureversion_lockstep_problems(); covered by
tools/tests/test_version_lockstep.py. No pipeline behavior change. - M6 / 6.6 — auto-derive traceability links from PR bodies (F2, #67). A new
tools/derive_links.pybuilds the{pr, rfc, milestone, commit, release}traceability edges from
merged PRs —pr/commit/milestonefromghmetadata,rfcparsed from the body,release
from a release PR's title — and emits alinks.yamlthattraceability.py --linksconsumes, so
the 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 tested
gh-free; the optional fetch degrades cleanly (clear message, exit 2) whenghis absent,
unauthenticated, or offline — CI never depends on the network. Covered by
tools/tests/test_derive_links.py. No pipeline behavior change. - M6 / 6.5 — thin CLI phase orchestrator (G3, #64). A new
tools/eados.py <phase> <manifest>
runs a phase's deterministic outgoing gates — read fromworkflow.yaml(no hardcoded chain) —
evaluating the ones it can (manifest-valid,rfc-approved,roadmap-covers-rfcs) via the
sibling tools and marking render-time / human gates[manual], then prints the legal next
transitions and points at the procedure;eados.py statusdelegates to the doctor (6.4). It is
the executable spine beneath the markdown/eados <phase>procedures — it reports and gates,
never authoring or advancing state. Covered bytools/tests/test_eados.py. No pipeline behavior
change. - M6 / 6.4 —
/eados statusdoctor (F1, #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, viaphase_runner), the recordedrfcs/milestonesrefs, and traceability
coverage (roadmap-covers-rfcs, plustraceability-lintwhen a links file is present, via
traceability). It composes the existing tools — never re-implements — and exits non-zero on an
actionable problem (undeclared phase, uncovered RFC, dangling edge), doubling as a pre-flight
check. Covered bytools/tests/test_doctor.py. Read-only; no pipeline behavior change. - M6 / 6.3 — single-artifact render for the
refactorphase (G2, #63). A new
tools/render_artifact.pyrenders one template with the manifest context — reusing
render.py's engine and thevalidate_manifest+ unresolved-placeholder gates, so a single
artifact 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 the
missing artifact → sandbox" stepcommands/refactor.mddescribes (now invoked there instead of
done by hand). Covered bytools/tests/test_render_artifact.py. Factory tooling; no pipeline
behavior change. - CI — Dependabot pin-sync now auto-re-triggers via a GitHub App (ADR-0013 addendum). The
dependabot-pin-syncworkflow mints a short-lived App token (actions/create-github-app-token,
SHA-pinned) whenSYNC_APP_ID+SYNC_APP_PRIVATE_KEYare set and pushes the pin re-sync with it,
so CI re-triggers and the failedaction-pinscheck goes green by itself; absent the App
secrets it falls back toGITHUB_TOKEN(the fix still lands, check re-runs on the next event). The
setup guide is rewritten App-first;DEPENDABOT_SYNC_TOKENis now the swap-in PAT fallback, not the
default. Factory-only; no pipeline behavior change. - M6 / 6.1 — end-to-end phase-flow smoke (G4, #65). A new
tools/tests/test_phase_smoke.py
threads one coherent fixture project (manifest + RFC + ROADMAP + links) throughdesign → 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 good
fixture and fails on a deliberately broken one, thatphase_runner --proposereports every
transition declared inworkflow.yamlLEGAL (and rejects an undeclared one), and that each entry
gate'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. - M6 / 6.2 — risk-model weights as data (F3, #68). The factor weights (security surface, size,
blast radius), theblast_radius_threshold, and the points→level cutoffs move out of
risk_score.pyintorisk.yamlas data — each per-domain overridable (weights shallow-merged),
exactly asmandatory_gate_levelalready was (OQ2). The scorer reads them via a new
resolve(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 new
keys; covered by the expandedtest_risk_score.py. Knowledge as data — no special-casing in code. - M6 / 6.9 — auto-sync shared action pins into the rendered templates (#76). A new
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
— reusingeados_lint's pin regex so the fixer and theaction-pinsgate can never disagree. A
weekly Dependabotgithub-actionsbump now needs no manual template edit to pass the lockstep
gate. The newdependabot-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 bytools/tests/test_sync_action_pins.py. Factory-only
(generated repos render no templates). No pipeline behavior change. - Docs —
DEPENDABOT_SYNC_TOKENsetup guide.maintenance/dependabot-sync-token.mddocuments
the 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 viagh secret set, verification, and rotation. Linked from the stay-current routine.
Maintainer-facing; no behavior change.
Security
v2.0.0 — EAAO → EADOS: the delivery operating system
EAAO → EADOS: the delivery operating system
The language-agnostic factory becomes a phase-based delivery operating system — init → design → plan → scaffold → audit → refactor, with the classic factory as the scaffold phase. State-driven, role-owned, every phase mechanically gated; humans hold the terminal gates.
⚠️ Breaking — EAAO → EADOS rename (ADR-0012)
Repository pgs-eaao → pgs-eados, factory folder .eaao-core/ → .eados-core/, self-lint eados_lint.py, dev sentinel .eados-dev, distribution bundle pgs-eados-bundle.*, command surface /eados. Consumers who vendored the bundle must update their .eados-core/ path and re-download the new asset. Old GitHub URLs auto-redirect.
Added — the delivery OS (M1–M5)
- Design package — RFC-0001 + 6 schema-first OS specs under
orchestrator/os/(workflow, authority, git, rfc, plan, risk), each_schema.md+ reference instance + aneados_lintgate. - Domain axis —
orchestrator/domains/{software,game,mobile}.yamlparallel to the language profiles (PRD vs GDD, NFR hard-budgets, SemVer vs Alpha/Beta/RC). - Phases & tools — persistent reference-based manifest;
phase_runner,rfc_check,authority_check,traceability,risk_score,brownfield,migration_planner,sandbox;/eados {init,design,plan,scaffold,audit,refactor}command surfaces. cross-spec-consistencygate (#62) — referential integrity across the OS specs (anti-fragmentation).
Fixed / Security
- B1 (#60) —
roadmap-covers-rfcsmatched RFC ids by raw substring (false coverage); now matched on a word boundary. - B2 (#61, security) — the refactor sandbox rejected
.gitonly at the top level; now refused at any depth (a nested/submodule.git/).
The full, itemized changelog is in CHANGELOG.md → 2.0.0. On publish, release.yml attaches the pgs-eados-bundle.{tar.gz,zip} factory bundle automatically.
v1.2.1 — generated projects carry their own owner
PATCH. A repo generated by anyone now ships its own copyright, not EAAO's.
Fixed
- The renderer copied EAAO's root
LICENSEverbatim into every generated repo (Copyright (c) 2026 Daniel Polo) even though the README rendered the maintainer's{{AUTHOR}}. A newtemplates/LICENSE.tmpl(Copyright (c) {{YEAR}} {{AUTHOR}}) renders the project's own copyright into itsLICENSEinstead. EAAO's ownLICENSEis unchanged. - The interview no longer defaults the reverse-domain group path to the reference's
it/d4np— it asks the maintainer's own.
Get it: download the prefix-less bundle and extract at your project repo root:
curl -L -o /tmp/pgs-eaao-bundle.tar.gz https://github.com/danielPoloWork/pgs-eaao/releases/latest/download/pgs-eaao-bundle.tar.gz
tar xzf /tmp/pgs-eaao-bundle.tar.gz # .eaao-core/ lands in the CWDFull changelog: v1.2.0...v1.2.1
v1.2.0 — in-place generation, full roadmap, prefix-less bundle
Third release. MINOR, backward-compatible.
Added
- In-place generation —
render.py --in-placewrites the generated project into the folder holding.eaao-core/(the bundle copied into your own repo,<repo>/.eaao-core/), so the project files land in<repo>/next to it. The rendered.gitignoreexcludes.eaao-core/; a root.eaao-devsentinel keeps the factory's dev repo safe.--out <dir>still renders a separate copy. - Full roadmap up front — the interview elicits all milestones at generation;
ROADMAP.md+ the README milestone table render every one (spec.milestones+ a nested{{#ITEMS}}loop). - Releases auto-attach the factory bundle —
release.ymluploads the version-less bundle on every published release.
Changed
- Prefix-less bundle — extracting it at the root of your project repo drops
.eaao-core/there directly (not in a subfolder). - README getting-started reworked consumer-first; copy-paste commands fixed to
.eaao-core/paths.
Get it: download the prefix-less bundle and extract at your project repo root:
curl -L -o /tmp/pgs-eaao-bundle.tar.gz https://github.com/danielPoloWork/pgs-eaao/releases/latest/download/pgs-eaao-bundle.tar.gz
tar xzf /tmp/pgs-eaao-bundle.tar.gz # .eaao-core/ lands in the CWDFull changelog: v1.1.0...v1.2.0