Repository navigation
Releases: rsaglobaltech/specgate
Release list
v1.0.0-rc.8
The documentation site carries both versions, with a picker at the top left and a page of what 1.0 adds; the pipelines are fewer and clearer — one CI, one release, one scheduled workflow — and npm audit and the licence check pass again.
Added
- The site carries both versions (REQ-400, REQ-401). The documentation site showed only the stable line, so a reader had no way to see that a 1.0 candidate existed or what it adds. Built with
--channel stable|next --versions stable=…,next=…, every page and the landing page have a version picker at the top left: the stable entry opens the stable docs, the candidate's opens what 1.0 adds. The candidate's pages, published undernext/, say they document a candidate, lead back to the stable docs and editnext/1.0. Built without--versions, the badge is as it was. - What is new in 1.0 (REQ-402). docs/whats-new-1.0.md explains each feature of 1.0 with its commands, and names every candidate; a test fails when a candidate in this changelog is missing from it.
Changed
- One release workflow.
release.ymlreplacespublish-npm.yml,publish-docker.ymlandpublish-github-packages.yml: av*tag runs the whole ofci.ymlon the tagged commit, then publishes to npm with provenance, then pushes the image, which now waits for npm instead of publishing on its own. The version and the dist-tag are decided once; a prerelease is still published undernextand its image tagged with the version only (REQ-281). New versions are no longer published to GitHub Packages; the versions there stay installable. - CI calls the E2E journeys, and runs the OS-independent checks once.
e2e.ymlis now only called (byci.yml, and so by the release) or run by hand. The agent-contract check, the self-validation, the registry build and the snapshot tests run once on Ubuntu instead of on all six matrix legs, and the core unit suite no longer runs a second time after the coverage run that already includes it. - The weekly checks are one workflow.
scheduled.ymlreplacesdocs-nightly.yml,mutation.ymlandopenspec-compat.yml, runs only in this repository, not in forks, and checks the terminal recordings on the Node major they were made with: on Node 22 against recordings made on Node 24, every recording read as out of date, which is why the nightly check failed every night. - The workflows follow one set of rules. Read-only permissions unless a job needs more, one concurrency group per workflow and ref, a timeout on every job, third-party actions pinned to a commit (Dependabot bumps them). Security also runs on
next/**, and its SBOM job no longer fails onargparse3, whose PSF-2.0 licence is now allowed; overrides forqs,fast-uriandzodclearnpm audit. On a pull request that touches the docs,pages.ymlbuilds the site without deploying it.
v1.0.0-rc.7
After the sixth microservices run of truck-flote: a part that uses the contracts is written after them, and a requirement still being drafted that waits for another repository is the order the story is built in, not a failure of the workspace check.
Fixed
- A part is written after the contracts it uses (REQ-395). The parts of a story were written at the same time, and tracking, finding nothing in contracts, designed an API of its own that web then used directly (truck-flote, MS6-1).
change authornow refuses the specs, design or tasks of a part that shares a criterion with the contracts repository while the contracts' part specifies nothing (author_contracts_first);--forcewrites it anyway. - A waiting requirement of an open change is the build order (REQ-396). Before the build,
workspace checkfailed withworkspace_dependency_pendingfor every requirement waiting for another repository, though the story harness builds them in that order (MS6-2). For a requirement still in an open change it is now a warning; a delivered requirement whose dependency is not still fails.
v1.0.0-rc.6
After the fifth microservices run of truck-flote: the architect who decides that a requirement waits for another repository writes it into the requirement, so the story harness builds the parts in order, and a quoted placeholder operation is no longer taken for a citation.
Fixed
- The design carries its dependencies into the traces (REQ-390). The specs of a layered change are written before its design, so an architect who decided that a requirement waits for
contracts:REQ-002wrote it only in design.md, and the story harness, which orders the parts from the traces, built them all at once (truck-flote, MS5-1). The rules ofchange instructions design, and so the prompt ofchange author design, now say that adepends=orapi=the design decides goes into the requirement'sspecgate:traceunderspecs/too, and the story context of a sub-change's design says the same. - A placeholder operation is no citation (REQ-391). A design quoting
api=contracts/fleet.openapi.yaml#<operationId>as guidance was reported aslayer_design_dependency_untraced; anapi=whose operation is a placeholder is now guidance (MS5-2).
v1.0.0-rc.5
After the fourth microservices run of truck-flote: a contract cited by a requirement not yet built is a warning until it is delivered, so the contracts repository builds its requirements one by one, and a service or web requirement of a story that cites nothing of the contracts repository is pointed out.
Fixed
- A contract is written one requirement at a time (REQ-385, REQ-335):
validatefailedapi_contract_missingfor a requirement still Draft that cites a contract file it will write, so the contracts repository's first requirement was refused for its later ones (truck-flote, MS4-2). A citation that does not resolve is now an error only for a delivered requirement or the one being delivered, and a warning otherwise. - A part that shares a criterion with the contracts cites them (REQ-386): in a story with a contracts repository,
change validatewarnslayer_no_contract_citedfor a requirement of another repository that cites none of its requirements or operations (MS4-1).
v1.0.0-rc.4
After the third microservices run of truck-flote: an agent that ticks its own task is no longer refused for touching the specification, the dependencies and operations a design names are checked against the traces, and the contracts repository's agent writes the contract its requirements describe.
Fixed
- What a design says a requirement waits for reaches its trace (REQ-380, REQ-381): in the third microservices run the panel's design named
depends=contracts:REQ-002,depends=tracking:REQ-002and the operations it uses, its traces carried none, andchange validatesaid ✔. Eachdepends=orapi=design.md names and nospecgate:tracecarries is now alayer_design_dependency_untracedwarning, naming the requirement on that line. - The contracts repository writes its contracts (REQ-382): its agent described them in requirements and wrote no file, so nothing could cite an operation. The story context now asks the contracts member for the OpenAPI or AsyncAPI file under
contracts/andapi=contracts/<file>#<operationId>on each requirement, and the other members to cite it withdepends=andapi=. - Ticking a task is not an edit of the contract (REQ-375): an agent that marked the task it had just delivered was refused as
agent_touched_protected_path, every attempt, though the harness writes the same tick itself (truck-flote microservices run 3). A change to a change'stasks.mdthat only changes the box of its tasks is now accepted; any other edit of it is still refused, and the prompt says the harness ticks the tasks. - A quoted story title is read whole (REQ-376):
workspace draftlisted"Optimización de rutas— the front matter was split at the comma inside the quotes.
v1.0.0-rc.3
After the second microservices run of truck-flote: a tick in tasks.md no longer withdraws an approval, so a change is built past its first requirement; the workspace's agent proposes the stories, a story says which criteria each repository answers and keeps its questions, the agents that write a sub-change see the whole story, and the story is built only as far as its dependencies are delivered.
Fixed
- A delivered requirement no longer un-approves its change (REQ-370, REQ-371): delivering a requirement ticks its task in
tasks.md(REQ-353), and the tick changed the hash the tasks' approval was bound to, so the harness refused the change's second requirement as "not approved: tasks". A layer is now hashed with every task box read as open: a tick, by the harness or a person, keeps the approval, and any other edit still asks for it again. Approvals recorded by 1.0.0-rc.1 and rc.2 keep counting. - A prompt file Windows still holds never fails the command (REQ-372): four
change authorruns side by side ended inEBUSY … unlinkafter their agents had written their layers. Removing a prompt file now retries briefly and then leaves it to the system — inchange author, the drafting agents and the harness. - An agent proposes the brief's stories (REQ-360):
workspace draft --agentwith no story named ran no agent and said nothing; the agent now fills the front matter'sstories:, writing onlydocs/brief.md, and the client's text is put back if it moved. With stories named,--agentwithout a story id is refused. - Each criterion names its repositories (REQ-361, REQ-362): a story's
## Repositorieslists the criteria each answers (- fleet: AC-1, AC-2); each Discover says which are its own and which the others', andworkspace checkwarns about a criterion no repository answers or two claim. - A story's questions wait for their answers (REQ-363): they go in
docs/stories/<id>/questions.md;workspace proposerefuses while one is open, unless--allow-open-questions. - A drafted story keeps none of its form's hints (REQ-364).
- The Discover stays business (REQ-365, REQ-344): the guidance on
depends=andapi=that trippedlayer_discover_technicalin every repository moves to the sub-change'sdesign.md. change authorhears of the story (REQ-366):story.jsonin each sub-change names its workspace, and the prompt for any layer carries the story's other parts and their requirements.- A requirement waits for what it depends on (REQ-367):
workspace harness run --storystarts only the requirements whose dependencies are delivered, names the others waiting, and exits 1.
v1.0.0-rc.2
After the first microservices run of truck-flote (five repositories, one story across three of them, nine requirements delivered in parallel): the workspace takes the client's brief and drafts its stories, a story's intent and criteria reach every repository, the story is built in the order of its dependencies, and init --yes adopts the folder it is run in.
Breaking
specgate init --yesadopts a folder that already has code (REQ-249, modified): it scaffolded a separate project inside it (my-spec-driven-app/), so a scriptedinitin a repository made a second one.--yesnow only skips the questions;--new,--out,--config,--multi-stackand--forjastill scaffold.
Fixed
change validatereports whatchange approverefuses (REQ-350): a layered change validated, then approval refused it for requirements with no kind. Validation now fails withchange_not_approvablefor each finding approval would block on.- The agent writing a change's requirements is told what they need (REQ-351):
kind=,actor=, and a feature file of its own. - Two requirements naming one feature file are reported (REQ-352):
change validateandchange archiverefuse withchange_feature_shared; archiving would have kept only one's scenarios. - A delivered requirement ticks its tasks (REQ-353):
done, which the harness runs, ticks the tasks of the open change that name the requirement. change --helpdescribes the three layers (REQ-354), and docs/migrating-to-1.0.md says how to install a candidate just published (--prefer-online) and how to move a forja project to it.- The workspace takes the client's brief (REQ-339..341):
specgate workspace draftputs a rootbrief.mdbelow a front matter that names the brief's stories and their repositories,workspace draft <story> --agent "<cmd>"drafts a story's intent and criteria from the brief, confined to the story, andspecgate statusin a workspace repository shows the workspace and the next step instead of failing on a missing matrix. - Every repository receives the story (REQ-342..344):
workspace proposetakes a drafted story, copies its intent and criteria into each sub-change'sdiscover.mdand names the story's other repositories and how to writedepends=andapi=;workspace checkwarnsworkspace_story_divergedwhen a repository's criteria are not the story's; each harness is told the story's other parts. - A story is built in dependency order (REQ-345):
workspace harness run --storystarts a repository whose part waits on another's undelivered requirement after that repository has finished; the dry run shows the levels. - The live view and the story's cost (REQ-346, REQ-347): every JSON document of the studio says
charset=utf-8, and a story's cost counts its archived parts. - Short repository names, and the logs ignored (REQ-348, REQ-349):
workspace initnamestruck-flote-fleetasfleet, prints name, path and role in their own columns, and ignores.specgate/workspace-runs/.
v1.0.0-rc.1
The first candidate of the 1.0 line, for teams of several repositories and roles: a change in three layers with their owners, a workspace of repositories with stories across them and its own live view, approvals per layer and harness packages per role, the backlog following the phases, the two gaps measured, principles, drift and API contracts checked, and specgate migrate 1.0 to move a 0.27 project. Published under the npm dist-tag next; latest stays 0.27. See Migrating to 1.0.
Breaking
depends=<repo>:REQ-NNNis a dependency on another repository (REQ-294): inside a repository it is no longer anunknown_dependency; the workspace judges it.- A change has three layers, each with its owner (REQ-282..REQ-289, ADR-0042):
change new,propose,propose --from-briefand--from-ticketwritediscover.md(product: context, use case, acceptance criteria- AC-1: …),design.md(architect) andtasks.md(developer) under the newlayeredschema, and no longer writeproposal.md.change new --schema spec-drivenkeeps the 0.27 layout. A change written with 0.27 stays valid: itsproposal.mdis read as its Discover, and a missingdesign.mdis a warning namingspecgate migrate 1.0. depends=<repo>:REQ-NNNis a dependency on another repository (REQ-294): inside a repository it is no longer anunknown_dependency; the workspace judges it.- A 1.0 change is built once it is approved (REQ-315, ADR-0043):
harness runskips a requirement of an open change of thelayeredschema until every written layer has its approvals, withharness_not_approved.approvals: { required: never }inharness.config.yamlkeeps the 0.27 behaviour,alwaysasks it of 0.27 changes too. - A change has three layers, each with its owner (REQ-282..REQ-289, ADR-0042):
change new,propose,propose --from-briefand--from-ticketwritediscover.md(product: context, use case, acceptance criteria- AC-1: …),design.md(architect) andtasks.md(developer) under the newlayeredschema, and no longer writeproposal.md.change new --schema spec-drivenkeeps the 0.27 layout. A change written with 0.27 stays valid: itsproposal.mdis read as its Discover, and a missingdesign.mdis a warning namingspecgate migrate 1.0.
Added
specgate migrate 1.0(REQ-325..REQ-329): on a committed 0.27 project, moves each open change into the three layers —proposal.mdtodiscover.mdword for word, adesign.mddrafted from it,tasks.mdkept,schema: layered— never touching the archive, and writesdocs/specs/migration-1.0.mdwith what it did and what is left to a person.--dry-runchanges nothing and prints the same report; a second run does nothing; a dirty tree is refused.specgate statusnames the command while an open change is still written for 0.27. Every breaking change, and how to stay on 0.27: Migrating to 1.0.- The workspace, live (REQ-320..REQ-324):
specgate studioin a workspace repository serves its/live— a panel per repository with the requirement in flight, its gate step and the agent's last step; each story with its parts open, building, archived or missing, and the parts waiting on another repository's undelivered requirement named; the cost per repository and per story.specgate workspace harness run --story <id>starts every repository's harness for its part at once, and none when one repository's base already fails the gate.workspace live --jsonprints the model. - The organization's principles (REQ-330..REQ-332):
docs/specs/principles.mdwithprinciples_versionandsource(a principles file, orpack:<pack_id>when a domain pack delivers it).specgate checknames the version and warnsprinciples_behindwhen the source has a newer one; a principle withrun=orforbid=…in=is checked by the gate (principle_failed;level=warnfor advice). - Behaviour changed without a specification (REQ-333, REQ-334):
checkwarnsspec_driftfor each commit since the base that changes production code and names no requirement in its message or in a test it changes;specgate driftreports it for CI, anddrift: gatein harness.config.yaml fails both. - A requirement points at an API operation (REQ-335, REQ-336):
api=in its trace comment, a JSON pointer or an operationId of an OpenAPI or AsyncAPI contract;validatefails when it does not resolve, andspecgate contract checklists the operations no requirement cites. specgate adopt --scope <path>(REQ-337, REQ-338): specify one area of a large repository; adoption warnsadopt_too_bigwhen it finds more areas than the eight it proposes.- The two gaps (REQ-300..REQ-304):
harness reportsays, for each requirement that needed rework, whether the spec was clear and the code diverged (spec → implementation) or the spec missed part of the use case (intent → spec). It suggests one from what it recorded — a rejection the agent fixed, naming the check that caught it; an answered question, a review note or a modified delta — and a person sets it with--classify REQ-NNN --gap spec-impl|intent-spec --reason "...". The report shows both shares overall and per module and what to strengthen; the studio's report shows both shares. The run ledger now records the gate stage that rejected each attempt. - The board follows the change (REQ-305):
alm syncmoves each change's ticket — itsticket:ororigin: alm:<key>— to the state of its phase:proposed,buildingonce a requirement has aharness/REQ-NNNbranch or is Implemented,archived. Each provider has a default (Jira status category, Azure Boards state, a GitHub label or a closed issue, a Linear state type) andphases:inalm.config.yamlnames a board's own. A move already made is not made again (.specops/alm-phases.json), and--dry-runprints each move.mirror: falsekeepsalm syncfrom creating an issue per requirement where the tickets are the source. - What the ticket gains comes back as notes (REQ-306):
alm pullbrings each open change's new comments, and a note when the ticket's description changed, into itsreview.md— never into the proposal or the delta. - One sub-issue per repository (REQ-307): a change that lists
repositories:gets a sub-issue of its ticket for each, created once. - Linear (REQ-308), a fourth built-in provider through its GraphQL API:
team_keyandtoken_env. alm phaseandalm move(REQ-309): where a change stands, without the network, and its ticket moved there now; both are MCP tools (specgate_alm_phase,specgate_alm_move). New provider capabilities (phase,subIssues,comments,readText) are optional, so a community provider written for 0.27 still loads.- A workspace of repositories (REQ-290..298, ADR-0041):
specgate.workspace.yamlnames the repositories of one product, andspecgate workspace init|status|check|proposesay where the product stands, run every repository's gate at once, resolve ids qualified with their repository (tracking:REQ-012), hold a requirement back until the one it depends on in another repository is delivered, and split a business story into a change in each repository it touches — done when every one is archived. See docs/workspace.md. - Roles and an approval per layer (REQ-310..REQ-315, REQ-319, ADR-0043):
roles:inharness.config.yamlnames who holds each role;change approve <id> --layer discover|design|tasksrecords an approval by the layer's owner — product, architect, developer — withapprovals.quorumfor how many people a layer needs. Each approval goes in the change'sapprovals.jsonwith a hash of the layer, kept in the archive; editing an approved layer asks for its approval again. The studio's Review shows each layer's approvals and approves the layer the viewer owns. - Role packages (REQ-316..REQ-318, ADR-0043):
harness/<role>.md, withapplies-toby kind, capability or tag, reaches the prompt of the requirements it concerns under "Role constraints"; the prompt event, the run record, the live view andharness reportname each package asrole@version, and the review check gives one line of advice per package. - The layer rules (REQ-284..REQ-287):
change validatewarns when the Discover names a technology, when the design does not answer an acceptance criterion, when a task names no requirement, and when the Discover differs from the version it was agreed at.change validate --strictfails on them. - The layers are named where people look (REQ-288, REQ-289):
change statuslists discover, specs, design and tasks with their owner ("Write discover.md (product)"), the drafting guides say which layer the agent writes, and the studio's review lists each layer with its owner and whether it is written.
Fixed
- A release candidate is never installed by default (REQ-281): every publish workflow treated a pushed
v*tag aslatest, so av1.0.0-rc.1would have become the defaultnpm installand thelatestimage. A version with a prerelease part is now published under the dist-tagnext, and its image is tagged with its version only.
v0.27.9
After the seventh truck-flote run: the harness checks Docker before it starts, the report names scenarios as the spec does, a date is one value, and the kept agent is seen live.
Fixed
- D6 reads a date or a time as one value (REQ-277): "at 2026-10-29 10:00:00" was read as the numbers "29", "00" and so on, and the agent had to list each one in
assumptions.mdbefore the draft could be reviewed. An ISO date, a time and a date-time are now one value each. - The agent
config set agentkeeps for Claude Code is seen live (REQ-278): the commandstatussuggests,claude -p < {prompt_file}, is now kept with--output-format stream-json --verboseand piped intospecgate harness events --from claude, so the studio's live view shows the agent and not only the gate. A command that already pipes or sets an output format is kept as it is. - A stopped Docker is said before any agent runs (REQ-279): with Docker Desktop stopped,
harness runpassed the specification and the architecture, then spent its three attempts on tests that failed in fifteen seconds with "Could not find a valid Docker environment", each handed to the agent as a failing test.harness runand the studio's Build now check Docker first when a quality check runs in it or the tests use Testcontainers, and refuse with the fix; a test command that cannot reach Docker stops the requirement and is told to the person, not the agent. - The studio's report titles each scenario from the specification (REQ-280): a delivered requirement of a draft showed
SCN-002 � <what happens>, the template line of the draft'sDRAFTING.md. Titles now come from the open changes' deltas, the capability specs andspec.mdonly.
v0.27.8
0.27.7 as it was meant to ship. Its publish stopped on four new tests whose repositories had no git identity on the CI runners; the Docker image 0.27.7 was published, the npm package was not.
Fixed
- The tests of REQ-264, REQ-267, REQ-269 and REQ-271 give their repositories a git identity, as the other harness tests do.
- The REQ-266 test compares real paths as Windows names them (
RUNNER~1andrunneradminare one folder), and the coverage run in CI has a larger heap: on macOS it ran out once every test had passed.
[0.27.7] � 2026-10-28
After the sixth truck-flote run: the harness agent can write, a Docker check works in a worktree, every gate step is seen while it runs, and a reviewed draft no longer turns the branch red.
Fixed
- The client's brief at the root goes below the front matter (REQ-259): with
brief.mdpushed first and forja's template indocs/brief.md,draft --agentwrote the front matter over the "Paste the client's brief here" placeholder and the person pasted the text by hand.draftnow puts the root file's text there first, keeps the root file, and says so; a body the person wrote is left alone. BRIEF-SETUP.mdis removed once the front matter is complete (REQ-260): it stayed untracked, and the harness refuses a tree that is not clean.- D6 reads a value made of listed parts (REQ-261): "1234-BCD � Ejes" and "Luc�a Mart�n � E000001234567890" were unlisted although every part was; a value joined with
�,�or�is listed when each part is. - An answer in
questions.mdno longer leaves its requirement blocked unnoticed (REQ-262, REQ-263): the draft said Ready to review andstatuskept four answered requirements "Waiting for an answer". The checklist now reports each answered question whose requirement is stillNeeds Clarification, with the fix and--agent, andstatuslists it under "Answered � update the spec". - The
sbomcheck writes the bill of materials of a Quarkus application (REQ-276): its pom skips deploy, and CycloneDX then wrote nothing ("Skipping CycloneDX goal, because module skips deploy"), so the dependency scan had nothing to read. It now runs with-Dcyclonedx.skipNotDeployed=false. - Every gate step is seen while it runs (REQ-273..REQ-275):
harness runprintedattempt 1/3and nothing more for 19 minutes, and/livestayed empty, while a semgrep check hung. The setup command,validate --strict, the end-to-end test, the architecture check, the test command and each quality check are now agate-startevent and agateevent with itsms, written as each happens � the quality checks used to be reported only once every check of the stage had run � and astarted �andpassed � in 3m 05sline of the run, without--verboseand whatever the agent command is./livenames the step that is running, with its image and how long it has run, and the studio's Build moves to Revisa la calidad when a quality check starts. - The harness gives Claude Code permission to write (REQ-264):
claude -p < {prompt_file}, the command the docs gave, wrote nothing in print mode and spent three attempts on "the agent produced no files". The harness now adds--permission-mode acceptEditsright afterclaude, as the drafting commands do, and says so; an attempt that writes nothing ends the requirement instead of running the same command again, pointing atdocs/agent-setup.md. - A
./inside quotes stays as written on Windows (REQ-265): an agent's allowance'Bash(./mvnw:*)'reached Claude Code as'Bash(.\mvnw:*)'. - Docker checks work in the harness's worktrees (REQ-266): a worktree's
.gitnames a host folder the container does not have, so semgrep failed to list files and hung until its 15-minute timeout. The repository's git folder is now mounted read-only, withGIT_DIRandGIT_WORK_TREEpointing at the worktree. - A check that could not run is reported to you, not to the agent (REQ-267): a gate check that is to write SARIF and wrote none � it timed out or failed first � stops the requirement with its output, instead of telling the agent to "fix what the check found" for two more attempts.
- The reviewer and the adversary read a draft's requirement (REQ-268): their prompts said
spec.mdhad no section for a requirement of a reviewed, unarchived draft; they are now built from the project as the harness judges it, like the implementer's. harness reportcounts each requirement once (REQ-269): a failed run and a passing one of the same requirement read "1 of 2 passed". The latest outcome counts, every run's time stays in the cost, and a run stopped by hand is in the ledger, its requirement reported as stopped.- The studio's report judges the project as
checkdoes (REQ-270): after--chaindelivered a draft's requirement, the report said "No pasa" for a feature the written matrix has no row for until the draft is archived. - The agent is kept once (REQ-271):
specgate config set agent "<command>"writes it toharness.config.yaml, with the permission above;statusnames the step while it is missing, and aharness run --agent �ends with the command that keeps it.