FE-1413: Cover petrinaut-cli in the architecture docs and attach a usage manual - #9227
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
a44e5b9 to
b3a63f6
Compare
b3a63f6 to
b61d919
Compare
PR SummaryLow Risk Overview Documentation moves replace Arch-docs build adds Reviewed by Cursor Bugbot for commit c43ebe7. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
Pull request overview
Registers Petrinaut CLI in the architecture documentation and centralizes its usage documentation.
Changes:
- Adds CLI architecture layers, dependency rules, and diagram styling.
- Introduces an attached CLI usage manual and redirects existing documentation.
- Warns when registered libraries expose no importable entry points.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
libs/@local/petrinaut-arch-docs/src/graph.ts |
Adds missing-entry-point diagnostics. |
libs/@local/petrinaut-arch-docs/src/emit/d2.ts |
Adds CLI diagram styling. |
libs/@local/petrinaut-arch-docs/content/cli/usage-manual.mdx |
Provides the consolidated CLI manual. |
libs/@local/petrinaut-arch-docs/architecture.config.ts |
Registers the CLI and dependency rule. |
libs/@hashintel/petrinaut/docs/examples.md |
Updates the optimization documentation link. |
libs/@hashintel/petrinaut-cli/src/runtime/README.md |
Declares and documents the runtime layer. |
libs/@hashintel/petrinaut-cli/src/commands/README.md |
Declares and documents the commands layer. |
libs/@hashintel/petrinaut-cli/src/cli.ts |
Declares the CLI root layer. |
libs/@hashintel/petrinaut-cli/README.md |
Replaces duplicated reference material with a manual link. |
libs/@hashintel/petrinaut-cli/PYTHON_INTEGRATION.md |
Redirects optimization guidance to the manual. |
libs/@hashintel/petrinaut-cli/OPTIMIZATION_INTEGRATION.md |
Replaces moved content with a redirect stub. |
libs/@hashintel/petrinaut-cli/MODEL_EXAMPLES.md |
Updates the optimization manual reference. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
b61d919 to
da68f97
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated no new comments.
Suppressed comments (2)
libs/@local/petrinaut-arch-docs/content/cli/usage-manual.mdx:12
- This conflates the two transport lifecycles. Socket mode does not observe stdin; it waits for SIGINT/SIGTERM (see
src/commands/serve.ts:147-169), whereas only stdio exits at EOF (src/commands/stdio.ts:128-132). A socket caller must not expect closing stdin to stop the server, so document the lifecycles separately.
and only then reports readiness on stderr. From that point it answers one
JSON-lines request at a time until stdin closes or it is signalled.
libs/@local/petrinaut-arch-docs/content/cli/usage-manual.mdx:261
- The documented build only creates
dist/cli.js; this private workspace does not install apetrinautexecutable on the caller'sPATH. The existing integration launchesnodewith that file (PYTHON_INTEGRATION.md:25-45), so the bare invocations at lines 44, 47, 50, and here fail after following this page's build step (the Python call raisesFileNotFoundError). Either usenode libs/@hashintel/petrinaut-cli/dist/cli.jsconsistently or document and use an actual installation/linking step.
["petrinaut", "serve", "--optimization", manifest_path, "--stdio"],
da68f97 to
1b55e3d
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated no new comments.
Suppressed comments (1)
libs/@local/petrinaut-arch-docs/architecture.config.ts:54
- The CLI rejects every optimization source when
--socketis selected (libs/@hashintel/petrinaut-cli/src/cli.ts:82-88), so this generated package description incorrectly says optimization studies are served over a Unix socket. This conflicts with the new usage manual's transport table and will mislead architecture-doc readers; distinguish the stdio-only optimization path from model runs.
"JSON-lines CLI serving one compiled model per process: run requests and optimization studies over stdio or a Unix socket. No HTTP, no React.",
c6c97b0 to
bf54ed8
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated no new comments.
Suppressed comments (1)
libs/@local/petrinaut-arch-docs/content/cli/usage-manual.mdx:12
- The socket transport does not observe stdin:
serve()waits for SIGINT/SIGTERM (seesrc/commands/serve.ts:147-170), whereas onlyserveStdio()exits when stdin closes. As written, a socket-mode supervisor that closes stdin based on this lifecycle contract will leave the CLI running. Distinguish the two shutdown conditions explicitly.
and only then reports readiness on stderr. From that point it answers one
JSON-lines request at a time until stdin closes or it is signalled.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 17 changed files in this pull request and generated no new comments.
Suppressed comments (2)
libs/@local/petrinaut-arch-docs/architecture.config.ts:54
- The CLI rejects every optimization source with
--socket(libs/@hashintel/petrinaut-cli/src/cli.ts:78-84), and the usage manual correctly marks both optimization sources as stdio-only. This description instead says optimization studies run over stdio or a Unix socket; the same ambiguity appears inlibs/@hashintel/petrinaut-cli/README.md:4-6andsrc/README.md:6-7. Clarify in all three places that the socket transport supports model/run requests only.
"JSON-lines CLI serving one compiled model per process: run requests and optimization studies over stdio or a Unix socket. No HTTP, no React.",
libs/@local/petrinaut-arch-docs/src/graph.ts:119
- The exemption checks for any
bin, not a bin-only package. If a registered package exposes both a command and module exports but alias derivation yields no entries, this suppresses the warning even though imports of that package still disappear from the graph. Exempt only manifests that havebinand noexports.
if (aliases.length === 0 && manifest.bin === undefined) {
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 34 out of 35 changed files in this pull request and generated no new comments.
Suppressed comments (2)
libs/@local/petrinaut-arch-docs/content/cli/usage-manual.mdx:307
libs/@local/petrinaut-pythondoes not exist in this repository, while the PR description says those bindings are upcoming in FE-1270. Consequently both examples in this section fail atfrom petrinaut import ...instead of documenting a usable interim wrapper. Keep this section based on the existing subprocess/JSON-lines client (for examplepetrinaut-cli/examples/python_stdio.py) until the bindings package lands.
## Driving the CLI from Python
The [`@local/petrinaut-python`](https://github.com/hashintel/hash/tree/main/libs/@local/petrinaut-python)
bindings wrap the protocol: a session owns one CLI process, requests are
methods, and error frames become exceptions. Running a model:
libs/@hashintel/petrinaut-cli/src/runtime/optimization.ts:273
- The online update is not a numerically valid mean for all finite objectives: with replicates
Number.MAX_VALUEand-Number.MAX_VALUE, the true mean is0, butreplicate.objective - meanoverflows and this rejects the trial. The new test atoptimization.test.ts:464-479explicitly codifies that incorrect result. Compute the weighted terms before adding (for example,mean * (index / (index + 1)) + replicate.objective / (index + 1)) and update that test to expect zero, so valid finite replicate sets produce their documented mean.
const objective = replicates.reduce(
(mean, replicate, index) =>
mean + (replicate.objective - mean) / (index + 1),
0,
);
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 34 out of 35 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
libs/@local/petrinaut-arch-docs/content/cli/usage-manual.mdx:307
- This manual documents a package and API that are not present in the repository: there is no
libs/@local/petrinaut-python,PetrinautSession, orOptimizationSession, so the link is a 404 and both examples fail at import time. The PR description also identifies the bindings as upcoming FE-1270. Replace this section with the current subprocess/JSON-lines wrapper (the existingPYTHON_INTEGRATION.mdis available) or explicitly mark the bindings as forthcoming rather than presenting them as usable now.
The [`@local/petrinaut-python`](https://github.com/hashintel/hash/tree/main/libs/@local/petrinaut-python)
bindings wrap the protocol: a session owns one CLI process, requests are
methods, and error frames become exceptions. Running a model:
libs/@local/petrinaut-arch-docs/src/build.ts:275
buildBundledocuments thatincludeDiagrams: falsemakes pages omit image references (src/build.ts:75-77), but this unconditional rewrite still emitsdiagrams/*.svglinks in authored pages. A caller requesting a no-diagram bundle therefore receives an authored usage page pointing at SVGs it explicitly said would not exist. Gate authored diagram embedding onincludeDiagramsand omit these image nodes in that mode.
const illustrated = resolveDiagramImages(
imported.contents,
slug,
authoredDiagramNames,
);
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 36 out of 37 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
libs/@hashintel/petrinaut-cli/src/runtime/optimization.ts:273
- This online update overflows when finite objectives have opposite signs: for
[Number.MAX_VALUE, -Number.MAX_VALUE],replicate.objective - meanbecomes-Infinity, so the trial is rejected even though its required arithmetic mean is0. The new test currently codifies that incorrect result. Use a sign-aware online mean (the weighted formmean * index / (index + 1) + value / (index + 1)when signs differ) and update the extreme-value test to expect the finite mean.
const objective = replicates.reduce(
(mean, replicate, index) =>
mean + (replicate.objective - mean) / (index + 1),
0,
);
libs/@local/petrinaut-arch-docs/src/emit/mdx.ts:230
- This raw replacement also transforms references inside fenced and inline code. For example, the newly added snippet at
content/maintaining/declaring-layers.mdx:110-112is emitted with a page-relative path instead of the documented@diagrams/...authoring syntax. Exclude Markdown/MDX code regions from resolution and add a fenced-code test.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 29 changed files in this pull request and generated no new comments.
Suppressed comments (2)
libs/@local/petrinaut-arch-docs/src/emit/mdx.ts:142
- CommonMark code can also use
~~~fences and code spans delimited by two or more backticks, but this splitter protects only triple-backtick fences and single-backtick spans. For example,[text](doc:missing)inside a~~~mdblock is still rewritten and reported as unresolved, so authored examples can be corrupted or makelint:arch-docsfail. Parse Markdown/MDX nodes or scan matching fence/span delimiter lengths, and cover both cases in the tests.
.split(/(```[\s\S]*?```|`[^`\n]*`)/gu)
libs/@local/petrinaut-arch-docs/content/cli/model-examples.mdx:12
- The PR and the CLI README advertise a complete request for every model in
examples/, but this page has no sections forexamples/deployment-pipeline.jsonorexamples/production-with-machine-failure.json; the usage manual repeats the same promise at lines 366–369. Add runnable requests for those two models, or narrow all of these claims if they are intentionally excluded.
The models below ship in
[`libs/@hashintel/petrinaut-cli/examples/`](https://github.com/hashintel/hash/tree/main/libs/@hashintel/petrinaut-cli/examples).
Each section gives a complete `run` request for one of them, so the differences
between an uncolored place, a colored place, and a model with an objective
metric are visible side by side.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 29 changed files in this pull request and generated no new comments.
Suppressed comments (2)
libs/@local/petrinaut-arch-docs/content/cli/usage-manual.mdx:164
- The same seed alone does not guarantee the same result: changing parameters, initial state, metrics, or run limits changes the response. The deterministic behavior verified by the compiled-model contract applies to otherwise identical run configurations, so qualify this statement to avoid promising reproducibility across different requests.
Every `run` starts from fresh simulation state, so two requests with the same
seed return the same result.
libs/@local/petrinaut-arch-docs/content/cli/model-examples.mdx:12
- This page says it provides a complete
runrequest for every model inexamples/, matching the PR description, but the directory also containsproduction-with-machine-failure.jsonanddeployment-pipeline.jsonand neither has a section here. Add complete requests for those two models (or explicitly narrow the documented scope); otherwise the new consolidated reference is incomplete.
Each section gives a complete `run` request for one of them, so the differences
between an uncolored place, a colored place, and a model with an objective
metric are visible side by side.
…age manual Registers @hashintel/petrinaut-cli in the architecture bundle with a cli root layer and cli.commands/cli.runtime sub-layers, plus a rule that core must not import cli, and a diagram colour. The package's long-form docs move into an authored usage manual attached to the cli layer, rewritten and reorganized from README.md and OPTIMIZATION_INTEGRATION.md, which become stubs pointing at it. Links into the old files are updated. Authored pages can now embed hand-written diagrams: content/diagrams holds .d2 sources, the build renders each one to SVG beside the generated diagrams, and a page references one as an image. An unknown name or a collision with a generated diagram fails the check. The manual uses two of them. The alias deriver warns when a registered package exposes no importable entry points, since imports of such a package would be missing from the graph. Bin-only packages are exempt. @local/petrinaut-arch-docs takes a devDependency on the CLI so the scanned package survives turbo prune in the docs-site job.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 38 out of 42 changed files in this pull request and generated no new comments.
Suppressed comments (1)
libs/@local/petrinaut-arch-docs/content/index.mdx:76
- The PR description says the deleted
MODEL_EXAMPLES.mdcontent moved to a second authored page,content/cli/model-examples.mdx, but this checkout contains onlycontent/cli/usage-manual.mdxand deletes every file underpetrinaut-cli/examples/. As a result, the promised per-model requests and several runnable model examples are removed rather than published in the architecture bundle. Add the authored model-examples page (and retain or relocate the models it documents), or stop deleting the source material.
`@hashintel/petrinaut-cli` is the headless JSON-lines CLI that scripts and the
Python optimizer service drive; its [usage manual](doc:cli/usage-manual) covers
the transports, the protocol, and optimization studies.
YannisZa
left a comment
There was a problem hiding this comment.
Love this @kube! Minor comment on the testing instructions:
turbo run test:unit --filter @hashintel/petrinaut-cli --filter @local/petrinaut-python
gave me back
× No package found with name '@local/petrinaut-python' in workspace
I couldn't find any petrinaut-python app or lib on the branch.
Yes sorry, indeed it comes in the next PR. |
🌟 What is the purpose of this PR?
The architecture docs covered
petrinaut-coreandpetrinautonly. The CLI's long-form documentation lived in package-local markdown that the docs site does not publish. This PR registers the CLI in the architecture bundle and moves its documentation into an authored usage manual attached to the newclilayer.Stack #9226: FE-1410, FE-1411, and FE-1408 have merged, so this PR now sits on
main. Above it: FE-1270 (Python bindings) → FE-1412.🔗 Related links
🔍 What does this change?
Architecture bundle
@hashintel/petrinaut-cliand declares three layers from README frontmatter:cliinsrc/,cli.commandsinsrc/commands/, andcli.runtimeinsrc/runtime/. The bundle reports 40 layers, 182 edges, and 421 files.coremust not importcli, and a diagram colour for thecliroot.deriveAliaseswarns when a registered package exposes no importable entry points, because imports of such a package would be missing from the graph. Bin-only packages such as the CLI are exempt.@local/petrinaut-arch-docstakes a devDependency on@hashintel/petrinaut-cli. The docs-site CI job builds inside aturbo pruneclosure, which drops the CLI's sources without it.Hand-written diagrams
content/diagrams/holds.d2sources. The build renders each one to SVG beside the generated diagrams, and an authored page embeds one as. An unknown name, or a name that collides with a generated diagram, fails the check.d2renderer, an authored page drops the image the same way a generated page omits its diagram, and the.d2source still ships.Link and image rewriting
doc:,layer:,@diagrams/and image targets are rewritten in prose only. The page that documents these schemes shows them in examples, and rewriting an example published the resolved path instead of the syntax being taught.Usage manual (
content/cli/usage-manual.mdx, attached tocli)subprocesswrapper. FE-1270 replaces that wrapper with the bindings package.Package-local documents are deleted rather than redirected
MODEL_EXAMPLES.md,OPTIMIZATION_INTEGRATION.md, andPYTHON_INTEGRATION.mdare removed.README.mdkeeps a short description of the package and a link to the manual, and links elsewhere in the repository are updated, including the one in the editor'sdocs/examples.md.PYTHON_INTEGRATION.mdthat the manual lacked moved into it: everyrunstarts from fresh simulation state, so repeating an identical request with the same seed returns the same result.The
examples/directory is deletedlibs/@hashintel/petrinaut-cli/test-fixtures/:sir-model.jsonandsatellites-launcher.json(whichtransports.test.tsuses for its colored-token case), andsupply-chain-profit-optimization.json. Four test files read them —transports.test.ts,optimization.test.ts,optimization-manifest.fixtures.ts, and the bindings'test_e2e_cli.py.deployment-pipeline.json,production-with-machine-failure.json,supply-chain-profit-model.json,supply-chain-with-disruption.json, andpython_stdio.pyare removed. Nothing reads them. The same models exist as TypeScript inpetrinaut-core/src/examples/, which is what the editor and the core tests use.serve:examplescript, theCOPYofsupply-chain-profit-model.jsoninto the petrinaut-opt image (no code in the repository reads that path), and the manifest pointer inapps/petrinaut-opt/README.md../my-model.jsonrather than a checked-in file.Build fix
arch-docs buildused to warn that it was writing a bundle without rendered diagrams and then fail trying to render them, exiting 1 wheneverd2was unavailable. It now skips rendering in that mode and exits 0. The failure predates this PR; the flag it depends on is the one this PR extends to authored diagrams.content/maintaining/running-locally.mdx) already tells readers the build only warns whend2is absent. That is now true.Pre-Merge Checklist 🚀
🚢 Has this modified a publishable library?
This PR:
libs/@hashintel/petrinaut/docs/examples.md, which ships inside the publishable@hashintel/petrinaut; a link target needs no release, so there is no changeset.📜 Does this require a change to the docs?
The changes in this PR:
🕸️ Does this require a change to the Turbo Graph?
The changes in this PR:
turbo.json's have been updated to reflect this@hashintel/petrinaut-cliin the arch-docs package's graph, so the docs job's prune closure keeps the sources it scans.🛡 What tests cover this?
resolveDiagramImages, one for the no-renderer path, and one proving a documented example inside a code fence survives verbatim.lint:arch-docs, which fails on an unannotated file, an undeclared ancestor, a rule violation, or an unresolveddoc:/layer:target.turbo run build --filter @apps/petrinaut-docs, which proves both pages and the diagrams render, and that everydoc:andlayer:link in them resolves.markdownlint, and a per-file check that nothing in the repository still references any deleted document or the oldexamples/path.d2present, three SVGs render and the manual references both authored diagrams; withmiseoff the path, the build exits 0, ships the.d2sources, and the manual references no SVG.❓ How to test this?
turbo run dev --filter @apps/petrinaut-docs/architecture/cli: the layer page carries the three layers, the two hand-written diagrams, and a link to the usage manual.🤖 Generated with Claude Code