← hgraph DevelopmentCONTENT HISTORY

Update to hgraph Development

Snapshot Sep 30, 2026 · 23:14 UTC · version 0.1.0

Collection source: not recorded for this historical snapshot.

WHAT CHANGED · RULE-BASED ANALYSIS

First saved snapshot

No earlier snapshot is available to establish a change.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "Implement or review composable C++ hgraph graphs and Python `@graph` functions. Use when adding or changing graph composition, wiring-time type or scalar decisions, graph overloads and polymorphism, `GlobalState` or `LOGGER` graph injection, conditional wiring, graph documentation, or native/Python graph behavior tests.",
  "included_files": [
    {
      "relative_path": "agents/openai.yaml",
      "size_in_bytes": 219
    }
  ],
  "name": "hgraph-write-graphs",
  "skill_md_contents": "---\nname: hgraph-write-graphs\ndescription: Implement or review composable C++ hgraph graphs and Python `@graph` functions. Use when adding or changing graph composition, wiring-time type or scalar decisions, graph overloads and polymorphism, `GlobalState` or `LOGGER` graph injection, conditional wiring, graph documentation, or native/Python graph behavior tests.\n---\n\n# Write HGraph Graphs\n\nBuild behavior by composing small typed nodes and graphs at wiring time. Prefer\ngraphs as the ordinary unit of reuse; reserve new nodes for genuine runtime\nprimitives or demonstrated performance needs.\n\n## Start from the existing contract\n\n1. Read the current repository's `AGENTS.md`, the relevant operator and graph\n   code, and nearby tests before editing.\n2. Establish whether the task targets hgraph core or a downstream extension:\n   - In the hgraph core checkout, read the applicable parts of\n     `docs/source/user_guide/cpp/authoring_graphs.rst`,\n     `docs/source/user_guide/python/tutorial/graph.rst`, and\n     `docs/source/developer_guide/graph_wiring.rst`.\n   - In a downstream project, use that project's graph conventions and tests,\n     plus the public hgraph documentation for its pinned hgraph version. Do\n     not assume the hgraph core source tree is present.\n3. Identify the existing nodes, operators and graphs that already provide the\n   required primitives. Compose them before creating a new primitive.\n4. Preserve equivalent first-class C++ wiring and Python authoring behavior\n   for every public cross-language feature.\n\nApply all repository documentation and type-system rules. A graph is not a\nshortcut around signature validation, generic resolution or operator dispatch.\n\n## Prefer a graph to a node\n\nStart new behavior as a graph. A graph combines small, purpose-specific,\nefficient and well-tested nodes into more complicated behavior, reducing the\nnew runtime code and validation surface.\n\nCreate a node only when the behavior requires a new per-tick primitive, side\neffect, lifecycle service, runtime state transition, or a measured performance\nimprovement that composition cannot provide. Document that reason. Apply\n`$hgraph-compute-sink-node` when implementing or reviewing the node.\n\nKeep the trade-off explicit:\n\n- Prefer composition and reuse by default.\n- Measure before replacing a clear graph with a fused node for performance.\n- Keep a justified fused node narrow and expose it through the same operator or\n  graph contract where practical.\n\n## Keep graph work at wiring time\n\nA C++ graph's `compose` method and a Python `@graph` function execute once while\nthe graph is wired. Graphs flatten into their nodes and do not exist as runtime\nevaluation objects.\n\nKeep the graph's wiring implementation in `compose` or the decorated graph\nfunction. Extract a helper only when it is a well-defined operation with its\nown clear contract or is genuinely shared by multiple callers. Do not scatter\none graph's composition across single-use helper functions.\n\n- Treat ports as typed wiring handles, never as current values.\n- Inspect scalars, resolved types and wiring metadata only to choose topology.\n- Do not retain runtime state or expect the graph body to run on a tick.\n- Do not perform runtime side effects in a graph body.\n- Move lifecycle and tick-dependent behavior into nodes.\n\nThe topology, overloads, bindings and policies selected by the graph are fixed\nwhen graph composition returns.\n\n## Compose for reuse and polymorphism\n\nUse graphs as the primary workers for reusable behavior:\n\n- Factor repeated compositions into small graphs with precise typed\n  signatures.\n- Compose graphs from other graphs; do not duplicate their internal nodes.\n- Use generic graph signatures for type-safe reuse across compatible schemas.\n- Use operator overloads when callers need polymorphic selection by type,\n  shape or wiring-time algorithm policy.\n- Use higher-order graph parameters when the caller should supply behavior.\n- Keep wiring-time policy selection out of every node's `eval` path.\n\nPrefer an operator contract over exposing one concrete graph when multiple\nvalid graph or node implementations may exist.\n\n## Limit graph injectables\n\nGraphs support only `GlobalState` and `LOGGER` as injectables.\n\n- In Python, declare either injectable with a `None` default and never supply\n  it from a graph call.\n- Use `GlobalState` for graph-scoped wiring configuration and values that seed\n  the built graph. Runtime reads or writes still belong in nodes.\n- Use `LOGGER` to report wiring choices, resolved types and selected policies.\n  It is the logger selected for graph wiring, not a per-tick node view.\n- In C++, access the equivalent services through `Wiring::global_state()` and\n  `Wiring::logger()`.\n- Do not inject `STATE`, `RECORDABLE_STATE`, `SCHEDULER`, `CLOCK`,\n  `EvaluationEngineApi`, `Traits` or `NODE` into a graph. Put behavior that\n  needs a runtime service in a node.\n\nUse a node `LoggerView` or the logging operator for runtime values. A graph\nlogger cannot observe ticks because the graph body has already finished.\n\n## Make wiring choices explicit\n\nA graph may inspect resolved type information, scalar configuration and wiring\nmetadata; perform ordinary conditional logic; select overloads; and log why it\nmade a choice.\n\n- Base Python type decisions on resolved annotations, `AUTO_RESOLVE` values and\n  supported metadata APIs.\n- Base C++ decisions on concrete template types and wiring-time scalar values.\n- Log a material type, policy or implementation choice when it helps explain\n  the built topology.\n- Use runtime control-flow operators such as selection, switching, mapping and\n  mesh when a time-series value must change behavior after wiring.\n\nNever read a time-series value to choose topology. Never imply that a logged\nwiring choice can change later in the run.\n\n## Preserve documentation and type rules\n\n- Give every graph a complete input and output signature.\n- Keep generic variables linked consistently across inputs, outputs and scalar\n  resolution parameters.\n- Return the declared time-series shape and preserve the established `REF`,\n  dereference and structural binding rules.\n- Keep scalar policies at wiring time and use enums where several named\n  trade-offs are supported.\n- Document public behavior, wiring-time choices, supported types, error cases\n  and any measured reason for choosing a node over a graph.\n- Update authoritative operator and type documentation with the implementation.\n\n## Test through public wiring\n\n1. Test graph behavior through `eval_node` with concrete public signatures.\n2. Add equivalent native C++ and Python coverage for Python-visible behavior.\n3. Cover every conditional wiring branch, generic type specialization and\n   exposed algorithm policy.\n4. Assert invalid types and unsupported graph injectables fail during wiring.\n5. Test wiring-time logging without confusing it with runtime log output.\n6. Prefer behavior assertions over internal node-count or index assumptions,\n   except when topology itself is the contract.\n7. Run focused tests while iterating, then every acceptance gate required by\n   the current repository `AGENTS.md`.\n\nBefore handing off, review the final diff for runtime work left in the graph\nbody, a new node that could be a composition, time-series-dependent wiring,\nunsupported injectables, unresolved type variables, and wiring decisions that\nare not documented or tested.\n"
}

SHA-256 of public snapshot: f4be5b383704bc43c0e30e4a4aa61a729932275bfdb973499a58ff0d918b7292