Repository navigation
Releases: openreachtech/hora-core
Release list
0.16.0
What's Changed
🤖 New Skills
/hora-replacedescribes a running system from its code, in several passes that each start from a different point, before anyone specifies its replacement. It proposes a scope for a person to approve group by group, then starts/hora-speconce the files it wrote are placed./horanever starts it, because whether a system is to be replaced is a person's call. It writes only under.hora/replace/<version>/and leavesspecs/and the reference code untouched. The passes are expensive, so it states the size of the reference and waits for a yes before it starts. Seedocs/adopting.md, "Replacing a system instead of adopting it", anddocs/commands.md
💪 Improvements
- A feature can carry one frontend gate per frontend row. Where
targetnames several rows, checkpoints 10 to 17 run once for each, intargetorder, and checkpoint 18 runs once after the last. A newrowsannotation narrows a version to the rows it touches; the checkpoints of a row it leaves out are marked not-applicable asaccepted in <version>. A feature with one frontend row is unchanged. A spec that names several rows will plan and report differently, so re-run/hora-planfor it - Checkpoint 15 now confirms every screen in a real browser. The main session opens each screen at a narrow and a wide viewport once every screen's unit has returned, since unit tests compute no layout. Where no browser can launch,
/hora-buildraises alacked-environmentquestion and leaves the checkpoint open - Checkpoints 6 and 16 write the tests and leave running them to
/hora-build. The wording had implied that the unit running the checkpoint also runs the suite
Change Log
Full Changelog: 0.15.0...0.16.0
0.15.0
What's Changed
- 🐛 Tell add-ons where a progress line of their own is written by @StewEucen in #301
- 📦️ Update package version to
0.15.0by @StewEucen in #304 - Release
0.15.0> Main by @StewEucen in #306
Full Changelog: 0.14.0...0.15.0
0.14.0
What's Changed
🤖 Progress Lines
- A checkpoint or stage that passes now opens with
✅️in place of📍—✅️ checkpoint 6 passed | every criterion #attendance covers has a passing test | -> checkpoint 7. - Two passes above a checkpoint take marks of their own:
🎯when checkpoint 18 passes and a feature is accepted, and🏁when the sweep passes and the version is done. - Where the run stops to ask a person, the line before the question opens with
🤔—🤔 checkpoint 2 waiting | whether a manager may edit a closed month | -> checkpoint 3 once answered. 📍now opens the indented line said while a checkpoint is still under way, which used to open with…./hora-build,/hora-acceptand/hora-specwrite each line themselves, in the same reply that records what it reports, instead of invoking/hora-progressfor it./hora-progresskeeps the rules behind the lines.- The default of
[wing] How to report progressindocs/addons.mdnow describes these marks.
Change Log
Full Changelog: 0.13.0...0.14.0
0.13.0
What's Changed
💪 Add-on Wings
New [wing] sections
Each one holds what the skill already did, so a project without an add-on runs exactly as it did on 0.12.0. An add-on may now extend it.
| skill | [wing] section |
default |
|---|---|---|
/hora (spec-format.md) |
How to write the repository layout |
one row per repository, in the section's columns, and nothing more about a row |
/hora (spec-format.md) |
How to write manual verification |
the middleware table, and nothing else |
/hora-spec (stages.md) |
Whether stage 5 may pass by carry-over |
yes, where the version adds no screen and changes none |
/hora-build (checkpoints.md) |
Whether a row runs the frontend gate |
yes, where the repository layout gives the row a frontend origin |
/hora-build (checkpoints.md) |
How to stand up the local test environment |
the local end-to-end container stack, built through the skills covering it |
/hora-build |
Whether consecutive checkpoints may go to one implementer |
no: each implementing checkpoint gets its own runs and its own verification |
/hora-build |
Whether an audit finding may be accepted without a person |
no: a finding is accepted only by a person answering its audit-finding question |
/hora-build |
How to lint a checkpoint's files |
npx eslint --fix, then npx eslint, on exactly the files the checkpoint touched |
/hora-build |
How to test a checkpoint's files |
npx jest on exactly the files the checkpoint wrote, its output read from a file |
/hora-accept |
Whether a feature gate drives the product live |
yes, where a person asks for it in the run or the run pays a listed feature's deferred acceptance. The sweep always drives |
/hora-accept |
How to confirm the environment |
the local end-to-end container stack, brought up through the skills covering it |
/hora-accept |
Whether a feature gate takes the UX findings step |
yes, where a person asks for it in the run. The sweep always takes it |
/hora-accept |
Whether a feature gate takes the security audit step |
yes, where a person asks for it in the run. The sweep always takes it |
/hora-accept |
How to cite a run's evidence |
what the delegate reported, inside the finding it backs |
/hora-hotfix |
How to record a defect no test can catch |
reproduced: no with the reason, and a measurement before and after |
The full list, with every earlier section, is in docs/addons.md.
Writing an add-on
- A skill now calls a
[wing]section by its heading text alone, with the#signs and the marker left out — "stop, unlessWhether the run may go on past an open blocking questionsays yes". Removing the marker from a heading leaves every line that calls it as it was. - While Hora Kit is in beta (
0.x.x),horaKitmay take a range such as>=0.10.0 <1.0.0as an exception, since a caret there stops at the next minor — though any0.xminor may then rename a section the wings extend. The example indocs/addons.mdreads^1.0.0.
🤖 Progress Lines
- A line reporting a pass now opens with
📍—📍 checkpoint 6 passed | every criterion #attendance covers has a passing test | -> checkpoint 7. - A verdict that sends the run back is reported in one line too, opening with
⏳️ [n], wherencounts the send-backs one checkpoint or stage has made on one feature —⏳️ [3] #attendance checkpoint 8 sent back to checkpoint 6 | N5, N6 (MEDIUM) | -> a per-account limit on sign-in. /hora-build,/hora-specand now/hora-acceptinvoke/hora-progressfor those lines. A retry that re-enters nothing prints nothing.
🐛 Bug Fixes
- The link to
docs/in the README now points at the repository rather than a relative path, so it resolves from the package page on npm as well.
Change Log
Full Changelog: 0.12.0...0.13.0
0.12.0
What's Changed
🤖 Progress Lines
- A new skill,
/hora-progress, holds the one line a checkpoint or a stage pass is reported in, and what may be said between two of them./hora-buildand/hora-specinvoke it at every pass; a person never does. - The shape sits under
[wing] How to report progress, which an add-on may extend.
💪 Checkpoints
- While an agent runs, the next checkpoint is not entered — not even to prepare it.
- Checkpoint 9 calls the built API the way its client does, the same transport and encoding, as the stack handbook states.
📦️ Dependencies
overrides:
New in this version. old version is what the tree resolved to before it.
| package name | old version | new version | semver | note |
|---|---|---|---|---|
js-yaml under @istanbuljs/load-nyc-config |
3.15.2 |
^4.3.2 |
Major | Resolves an npm audit report. Contradicts the ^3.13.1 that @istanbuljs/load-nyc-config 1.1.0 declares, so it wants revisiting at that dependant's next major |
Change Log
Full Changelog: 0.11.0...0.12.0
0.11.0
What's Changed
💪 Enhancements
/hora-fast opens a dependent feature before its dependency is finished
/hora-fast used to start a feature only once every one of its depends was finished. Each gate now opens on its own:
| The dependent's | Opens once each unfinished dependency has |
|---|---|
| spec gate (1, 2) and checkpoints 3 to 8 | nothing, once the foundation is fixed |
| checkpoint 9 | merged its backend gate into release/<version> |
| frontend gate (10 to 17) | merged its frontend gate |
| acceptance gate (18) | passed its own checkpoint 18 |
- The foundation builds every module a dependent imports.
/hora-planmarks each one in the dependent's feature file asImports: <module> from #<id>. Where the mark missed a module, the feature stops at that checkpoint and waits for the dependency's backend gate to merge. The miss is recorded under the foundation in_fast.md /hora-planwalks every use case through the pinned contracts, field by field. A step whose caller cannot make the call with what it holds is anunmet-usecase(blocking: yes), fixed at/hora-spec, stage 4- A feature waiting at checkpoint 9 keeps its worktree and its place under the limit, because its database stays up. A feature waiting at the entrance of a gate leaves the flight and holds neither
- A dependency's later gate that changes code a dependent built on reopens the dependent, with
reopened-by: dependency /horais unchanged. It builds one feature to acceptance before the next
For add-ons: /hora-build gains [wing] Whether a gate may open while a dependency is unfinished, and only /hora-fast reads it. [wing] Whether a feature is ready to build keeps its heading and its answer, so an add-on that names it is unaffected.
A plan written before this version carries no Imports: marks. It still runs: each imported module falls back to the wait at the checkpoint that first needs it.
🐛 Bug Fixes
- The links from
docs/to the skill and agent files resolve from the installed package. They pointed atkit/, which the package does not ship, and each now carries the file's full GitHub URL
Change Log
Full Changelog: 0.10.1...0.11.0
0.10.1
What's Changed
🐛 Bug Fixes
A declared add-on is declared per version only
An add-on declared under .hora/tasks/_all/ stayed on in every later version without a record of its own, so a run that ends per version never ended. Resolving now reads .hora/tasks/<version>/_<addon-name>.md alone, and .hora/tasks/_all/ is no longer read.
What to do: where a project declared an add-on in .hora/tasks/_all/_<addon-name>.md, write the line <addon-name>: on into .hora/tasks/<version>/_<addon-name>.md for each version it is to be on in. An add-on that is to be on for every version says so in its definition, as "activeWhen": "always".
Change Log
Full Changelog: 0.10.0...0.10.1
0.10.0
What's Changed
🛡️ Security
npm audit reports nothing outstanding for this version.
GHSA-q2hr-2g5m-vwhr, GHSA-qhr7-859c-m2p7 and GHSA-6j4f-fj2g-mc7p (brace-expansion, high) reached this repository through devDependencies alone, on three major lines: 1.1.18 under eslint, 2.1.4 and 5.0.9 under jest and @typescript-eslint/typescript-estree. All three are resolved at their patched releases, 1.1.21, 2.1.7 and 5.0.12, and pinned there through overrides: — see the table below.
dependencies: is empty, so the advisories never reached anybody who installed the package.
🤖 New Skills
/hora-addon — add-ons for the hora skills
An add-on is a package installed beside Hora Kit that changes where a hora skill's decision goes, without editing the skill. /hora-addon is the rule every hora skill follows about them, and it names no add-on in particular.
- A decision an add-on may change now sits in a
[wing]section, in/hora-plan,/hora-build,/hora-fast,asking.mdandstructure.md. Each section's own text is what the skill does today, so a project with no add-on runs exactly as before - An add-on's installer writes
.hora/wings/and.hora/addons/, and Hora Kit's own installer never touches either. An add-on states the Hora Kit it was built for ashoraKitin its definition —^0.10.0or later — and its installer refuses a Hora Kit outside that range - Where two add-ons disagree, the precedence a person set in
.hora/addon/config.jsoncomes first, set through/hora-addon. The invariants instructure.mdcarry no[wing], so no add-on can change them
docs/addons.md and docs/addons.ja.md walk the whole mechanism.
Update your .gitignore. The example in the README no longer ignores .hora/ whole: it ignores .hora/*.json, .hora/wings/ and .hora/addons/, what the installers write, and leaves .hora/tasks/, .hora/addon/config.json and the other records the skills write to be committed.
💪 Enhancements
- A sweep's pass is bound to the release tips it drove. Every
_sweep.mdblock records the commit each declared row'srelease/<version>stood at, and/horamerges only while those tips still stand. After upgrading, a version that already passed its sweep runs/hora-acceptonce more before/horamerges it, since a_sweep.mdwritten before this carries notips:line - Every closing report opens with what the person must do.
structure.mdgains "The closing report": Needs you, Decided for you, Done, Next, in that order, and a block with nothing in it saysnone - The verification loop is tighter. A checkpoint's run record gains
at:, the commit each repository stood at when step 9 judged. Each criterion names the test that would fail if it broke, and one with none ismissingTests. Checkpoint 8's findings are kept in.hora/verification/<version>/<feature-id>.md, so a finding over unchanged files is not handed again - A narrowed hotfix proves what its skipped suites rest on, as a
suites-rest-on:line in its record. A fact no command could prove readsunproven, and the next sweep's full suites prove it - Five rules hora left unstated are now written down: a question whose answer decides another's options is asked first, the spec's Terminology gains a
Not calledcolumn,docs/adopting.mddecides every rule of an existingCLAUDE.mdbefore/hora-setupreads it, and/hora-hotfixnames no cause until a command has failed its test
🐛 Bug Fixes
- A criterion no test can reach yet is reported as
specIssueseverywhere.spec-format.mdand/hora-plannow say whathora-verifieralready did, so it no longer reads as a missing test that sends an implementer off to write one - The links to the recommended way of running in
docs/reach it. The section lives inhora-boilerplate's README, so each link now carries that README's full URL
📦️ Dependencies
devDependencies:
| package name | old version | new version | semver | note |
|---|---|---|---|---|
jest |
^30.5.1 |
^30.5.2 |
Patch |
overrides:
brace-expansion@1 and brace-expansion@2 are new in this version, and brace-expansion@5 is raised. old version is what the tree resolved to before them.
| package name | old version | new version | semver | note |
|---|---|---|---|---|
brace-expansion@1 |
1.1.18 |
^1.1.21 |
Patch | Closes the three brace-expansion advisories. minimatch under eslint asks for ^1.1.7, which still admits the vulnerable releases |
brace-expansion@2 |
2.1.4 |
^2.1.7 |
Patch | Closes the same advisories on the 2.x line, under jest |
brace-expansion@5 |
5.0.9 |
^5.0.12 |
Patch | Closes the same advisories on the 5.x line. Its dependants ask for ^5.0.5 and ^5.0.8, which still admit the vulnerable releases |
dependencies: is empty, so nothing above reaches an install of this package. engines is unchanged at node >=20.0.0.
Change Log
Full Changelog: 0.9.0...0.10.0
0.9.0
What's Changed
💪 Enhancements
Questions are put in terms of what changes for the person
asking.md gains a section, "What changes for the person": a check, a proposal or a question says what the product will do differently, and the design that delivers it follows in one clause. "You would be able to fill in every entry under one heading at once" rather than "I will link this column to that one — all right?". Where nothing observable turns on the answer — a repository name, a middleware version — it says so and asks in plain technical terms.
- It reaches the question file too, since whoever edits
specs/next reads it long after the conversation - An option's description says what it changes for the person, and what it costs. The label stays short
/hora-spec-backendputs the data model as what the product remembers rather than which columns hold it, and asks an operation's kind as what the operation does/hora-spec-securitystates each current authorization setting as what somebody could do with it today, never as the filter's name/hora-spec-usecasesoffers thebuilt:choices as what a person can use:spec,backend,frontendandnot builtkeep their values and change their descriptionsasking.mdnow also governs/hora-buildand/hora-fastat checkpoints 1, 2, 9 and 11, which run in conversation, and/hora-accept
A passing checkpoint or stage is reported in one line
structure.md gains "Reporting progress". When a checkpoint or a stage passes, it is reported in one line:
<checkpoint or stage> passed | <the one fact it established> | <the blocker or decision, or -> what comes next>
/hora-buildreports it at step 11 of every checkpoint, and/hora-specthe moment a stage's box is written- The line replaces narration only. It never restates what the feature file or
_stages.mdrecords, and a check, a proposal, a question or a section shown for approval keeps the formasking.mdgives it
A step's inspection runs as one batch
structure.md gains "Inspecting a repository". While a checkpoint or a stage runs, every command a step needs is planned first and run as one Bash call, with an echo marker before each. Each command still runs in its own repository, and a command a skill names runs exactly as written. A class-name match is anchored to a word boundary, since one class name can be the tail of another.
📄 Documentation
- A second template exists, for native Android and iOS projects:
hora-boilerplate-mobile.README.md,docs/README.md,docs/architecture.mdanddocs/quick-start.mdname it besidehora-boilerplate, which remains the template for a web project. The method is the same either way; what differs is the stack, the origin catalog, and which skill libraries a row equips docs/commands.mdcarries both changes above;docs/adopting.mdcarries the first
Every document is changed in both its English and its Japanese version.
Change Log
Full Changelog: 0.8.0...0.9.0
0.8.0
What's Changed
🛡️ Security
npm audit reports nothing outstanding for this version.
GHSA-2883-xcg3-v3hh (js-yaml, high, published 2026-09-08) reached this repository twice, both times through devDependencies: 4.3.1 under eslint → @eslint/eslintrc, and 3.15.1 under jest → babel-plugin-istanbul → @istanbuljs/load-nyc-config. Both are resolved at 4.3.2 and 3.15.2 in package-lock.json.
No declared range moved for it, so no row in the tables below carries the fix — it is a lockfile move, and a clone of this repository picks it up from there. dependencies: is empty, so the advisory never reached anybody who installed the package.
🤖 New Skills
/hora-fast — the parallel scheduler
/hora builds one feature to acceptance before the next starts. /hora-fast builds the files two features would both write once, then builds the features side by side, each in its own git worktree, and drives the version live once at the end.
- It writes exactly what
/horawrites — the same spec, plan, feature files, eighteen checkpoints and acceptance records — so either scheduler continues what the other started /horanever starts it. Whether a version is worth building in parallel is a person's call, so it is invoked directly, the way/hora-hotfixis- It estimates before anything else, from the pace the run records hold, and it asks whether there is a date rather than assuming one. A version whose time sits on the four conversation checkpoints gains nothing from it, and it says so
- It adds one record file —
.hora/tasks/<version>/_fast.md, holding who chose it, the limit, and the foundation - Switching back takes a drain.
/horanow runsgit worktree listfor every declared row at step 0, and stops where it finds a worktree under.worktrees/instead of building beside a parallel run - What it gives up: a regression is attributed at the merge rather than at the checkpoint that caused it, screens are driven once at the sweep, and each feature in flight needs a second working copy and a second database
docs/parallel.md and docs/parallel.ja.md walk the whole route; docs/commands.md carries the summary.
💪 Enhancements
- Every checkpoint line now carries a run record — a second comment holding
cleared:,reopened-by:,agents:,agent-time:,verify-time:andwall-time:, added whether the checkpoint passed or not, and surviving whoever rewrites the line. The first comment is untouched, so/hora-planstill reads<!-- n/a: … -->by its text. This is the record/hora-fastreads a version's pace from - A checkpoint's change set is derived in one place and handed to
hora-verifier— at checkpoint 8 as before, and now at step 9 as well. It comes from the repository (git merge-base, the untracked files, and the commits already landed) plus the surface the feature declares under.hora/contracts/<version>/, never from what an implementer reported. Files are markedthis-checkpointorunreported: a marked file is what the verifier judges, the rest is the map, and the set is a starting point rather than a ceiling - The spec trailer's form is now stated: one line reading
spec: <version>#<id>./hora-buildfinds a landed commit by that exact line, so a repository whose git conventions squash or reword it gets a set that comes back empty or wider — absorbed by the working-tree half of the derivation, but worth knowing /hora-acceptnames/hora-fastbeside/hora-buildas the caller of its feature gate, at both the gate and the whole-version sweep
🛡️ Supply Chain
One install script is newly allowed to run: @parcel/watcher@2.6.0. jest@30.5.1 brings it in through jest-haste-map, it declares hasInstallScript, and it is dev only — so it runs for somebody working on this repository, never for somebody installing the package.
fsevents and unrs-resolver stay denied, and overrides: is unchanged: brace-expansion@5 at ^5.0.9, flatted at ^3.4.2.
📦️ Dependencies
devDependencies:
| package name | old version | new version | semver | note |
|---|---|---|---|---|
jest |
^30.4.2 |
^30.5.1 |
Minor | Brings @parcel/watcher@2.6.0 into the tree — see 🛡️ Supply Chain |
@openreachtech/mentsu-rootpath |
^1.1.1 |
^1.1.3 |
Patch | |
@openreachtech/renchan-env |
^1.0.4 |
^1.0.6 |
Patch |
dependencies: is empty, so nothing above reaches an install of this package. engines is unchanged at node >=20.0.0.
Change Log
Full Changelog: 0.7.0...0.8.0