Skip to content

feat(arc-kit-au): retrofit SysmlBlock onto existing node types - #193

Merged
elasticdotventures merged 7 commits into
feat/requirement-decision-cost-visualizationfrom
feat/sysml-derive-retrofit-existing-nodes
Aug 23, 2026
Merged

feat(arc-kit-au): retrofit SysmlBlock onto existing node types#193
elasticdotventures merged 7 commits into
feat/requirement-decision-cost-visualizationfrom
feat/sysml-derive-retrofit-existing-nodes

Conversation

@elasticdotventures

Copy link
Copy Markdown
Member

Summary

  • Retrofits #[derive(SysmlBlock)] (from sysml-derive, feat(sysml-derive): spike a Rust-AST-to-SysML-v2 derive macro #183) onto the 8
    pre-existing arc-kit-au node structs that predate the systems-modeling
    registry epic: SourceDoc, ExtractedRow, Transaction,
    Classification, ModelProposal, OperatorApproval, ValidationIssue,
    WorkbookRow.
  • This is the second of two follow-ons deferred out of task 3 (feat: widen ArtifactKind/NodeType/OperationKind with Requirement/Decision/Cost #184); the
    first (HasVisualization/viz_manifest wiring for
    Requirement/Decision/Cost) already landed earlier in this stack.
  • No behavior change to existing serialization/hashing — the macro only
    adds a new sysml_block_def() assoc. fn per struct; it does not touch
    Serialize/Deserialize/node_id() or any existing derive/impl.
  • The macro is purely syntactic (walks named fields via syn, stringifies
    each field's type via quote!), so it applies uniformly to all 8
    structs regardless of field type (String, Decimal, Option<T>,
    Vec<NodeId>, DateTime<Utc>, etc.) — confirmed by re-reading
    crates/sysml-derive/src/lib.rs before applying, not assumed.

Stacked on feat/requirement-decision-cost-visualization per the
established branch-stacking pattern for this epic (main
feat/sysml-derive-spike (#183) → feat/requirement-decision-cost-kinds
(#184) → feat/zlayer-systems-model-variant (#185) →
feat/reqif-opa-mcp-client-spike (#186) → this branch's base).

Test plan

  • cargo test -p sysml-derive — 2 tests pass
  • cargo test -p arc-kit-au — 46 tests pass (unchanged count from
    pre-retrofit baseline)
  • cargo check --workspace --all-features — clean (one pre-existing,
    unrelated warning in ledgerr-mcp/src/fbar.rs)
  • cargo clippy -p arc-kit-au --all-features — clean

…ypes

Applies the sysml-derive macro (feat/sysml-derive-spike, #183) to the 8
pre-existing arc-kit-au node structs that predate the systems-modeling
epic: SourceDoc, ExtractedRow, Transaction, Classification,
ModelProposal, OperatorApproval, ValidationIssue, WorkbookRow.

This was the second of two explicitly-deferred follow-ons from task 3
(#184) — the first (HasVisualization/viz_manifest wiring for
Requirement/Decision/Cost) landed as part of this same stack. The
derive is purely syntactic (walks named fields via syn, stringifies
each field's type via quote!) so it applies uniformly regardless of
field type — no per-struct special-casing needed, confirmed by
re-reading crates/sysml-derive/src/lib.rs before applying.

Verified: cargo test -p sysml-derive (2 tests), cargo test -p
arc-kit-au (46 tests, unchanged from pre-retrofit baseline), cargo
check --workspace --all-features (clean, one pre-existing unrelated
warning in ledgerr-mcp/src/fbar.rs), cargo clippy -p arc-kit-au
--all-features (clean).
elasticdotventures added a commit that referenced this pull request Aug 22, 2026
Task 6 (ledgrrr#186's second commit) added import_requirement/
record_decision/record_cost to ledgerr_evidence's EVIDENCE_TOOL actions
in contract.rs but never re-ran regen-docs, so the checked-in
mcp-capability-contract.md drifted — caught by CI's check-drift step
on downstream stacked PRs (#190, #193).

Ran: cargo run -p ledgerr-mcp --bin regen-docs
…isualization' into feat/sysml-derive-retrofit-existing-nodes
…isualization' into feat/sysml-derive-retrofit-existing-nodes
elasticdotventures added a commit that referenced this pull request Aug 22, 2026
…al SysML v2 grammar

Same bug holon-viz's SysmlV2Emitter had (ledgrrr#197): SysML v1 called
this construct Block/'block def'; SysML v2 renamed it to 'part def', and
'block' is not a SysML v2 keyword at all. Confirmed via the newly-wired
ufo_types::sysml::validate_sysml_v2 (real sysml-v2-parser crate, not a
hand-rolled heuristic) that the fixed output actually parses.

Adds tests/real_grammar_validation.rs: runs the actual generated
sysml_block_def() text for Transaction/Requirement/ExtractedRow/
ModelProposal/WorkbookRow (mirroring the real production structs from
#184/#193) through the real parser. This replaces the 'no angle brackets'
manual check used to validate the earlier DateTime/bool/usize scalar
mapping fix with genuine grammar validation, closing out ledgrrr#195.
…isualization' into feat/sysml-derive-retrofit-existing-nodes
…isualization' into feat/sysml-derive-retrofit-existing-nodes
@elasticdotventures
elasticdotventures merged commit f464d5d into feat/requirement-decision-cost-visualization Aug 23, 2026
13 checks passed
@elasticdotventures
elasticdotventures deleted the feat/sysml-derive-retrofit-existing-nodes branch August 23, 2026 06:32
elasticdotventures added a commit that referenced this pull request Aug 23, 2026
…ision/Cost (#190)

* feat(iso): HasVisualization + viz_manifest wiring for Requirement/Decision/Cost

Adds dedicated SemanticType::{Requirement,Decision,Cost} variants
(iso.rs) and HasVisualization impls for arc_kit_au::node::{Requirement,
Decision,Cost} (iso_objects.rs, gated behind the arc-kit-au feature,
matching ontology.rs's arc_kit_bridge precedent), all routed to
ZLayer::SystemsModel (added in ledgrrr#185).

Wires the 3 new types into xtask's export_viz_manifest (now 31 domain
types, up from 28) and regenerates the checked-in viz-manifest.json.
Updates pipeline_e2e.rs's EXPECTED_ENTRY_COUNT and representative-type
assertions to match.

Verified: cargo test -p ledger-core --lib (185 passed), cargo test -p
ledgerr-mcp --test pipeline_e2e (manifest count test passes), cargo
check --workspace --all-features clean.

This closes out the one remaining gap from ledgrrr#185 (task 4 in
docs/systems-modeling-registry-rescope.md's §6), left explicitly
unfinished there pending this larger change.

* feat(arc-kit-au): retrofit #[derive(SysmlBlock)] onto existing node types (#193)

Applies the sysml-derive macro (feat/sysml-derive-spike, #183) to the 8
pre-existing arc-kit-au node structs that predate the systems-modeling
epic: SourceDoc, ExtractedRow, Transaction, Classification,
ModelProposal, OperatorApproval, ValidationIssue, WorkbookRow.

This was the second of two explicitly-deferred follow-ons from task 3
(#184) — the first (HasVisualization/viz_manifest wiring for
Requirement/Decision/Cost) landed as part of this same stack. The
derive is purely syntactic (walks named fields via syn, stringifies
each field's type via quote!) so it applies uniformly regardless of
field type — no per-struct special-casing needed, confirmed by
re-reading crates/sysml-derive/src/lib.rs before applying.

Verified: cargo test -p sysml-derive (2 tests), cargo test -p
arc-kit-au (46 tests, unchanged from pre-retrofit baseline), cargo
check --workspace --all-features (clean, one pre-existing unrelated
warning in ledgerr-mcp/src/fbar.rs), cargo clippy -p arc-kit-au
--all-features (clean).
elasticdotventures added a commit that referenced this pull request Aug 23, 2026
* feat(reqif-mcp-spike): Rust MCP client for reqif-opa-mcp + Requirement converter

Spike per decision 6 (docs/systems-modeling-registry-rescope.md §5/§6
task 5): reqif-opa-mcp is wrapped over MCP, not ported to Rust;
arc-kit-au stays the canonical decision+cost ledger.

New crate reqif-mcp-spike:
- McpHttpClient: minimal blocking client for reqif-opa-mcp's Streamable-
  HTTP MCP server (FastMCP 3.0.0b1, protocol 2024-11-05). Handles the
  initialize handshake + mcp-session-id header, the mandatory
  notifications/initialized follow-up, and tools/call, extracting the
  JSON-RPC result out of the single-frame SSE response body.
- RequirementRecord: mirrors reqif-opa-mcp's requirement-record.schema.json
  exactly (uid/key/subtypes/status/policy_baseline/rubrics/text/attrs).
- requirement_record_to_node(): converts a RequirementRecord into the
  arc-kit-au Requirement struct from ledgrrr#184 (ArtifactKind::Requirement /
  NodeType::Requirement). requirement_id<-uid, title<-key, rationale<-text,
  source<-attrs.source_standard(+source_url) falling back to the policy
  baseline id, status passed through, related_decisions always empty
  (reqif-opa-mcp carries no decision links; those are created later in
  arc-kit-au itself).

Verified live end-to-end against a real reqif-opa-mcp checkout
(uv sync --extra ingest-lite; uv run python -m reqif_mcp --http --port
8123) parsing both its own sample derived baselines,
samples/standards/derived/{nist_ssdf_dogfood,owasp_asvs_cwe}.reqif (4
and 7 requirements respectively), through reqif_parse -> reqif_query ->
requirement_record_to_node -> Requirement::node_id(), all producing
correct, deterministic req: NodeIds. That live run is captured as an
#[ignore]'d integration test (tests/live_server.rs) since it needs an
external repo checkout + Python/uv, not something CI or a fresh clone
has; re-run manually with REQIF_MCP_URL set to a running server.

cargo test -p reqif-mcp-spike: 5 unit tests pass, 1 ignored (live).
cargo check --workspace --all-features: clean. cargo clippy -p
reqif-mcp-spike --all-targets: clean.

* feat(ledgerr-mcp): wire Requirement/Decision/Cost into contract.rs (task 6)

- EvidenceArgs gains import_requirement/record_decision/record_cost
  actions, each constructing the corresponding arc-kit-au node
  (Requirement/Decision/Cost from ledgrrr#184) and inserting it into the
  evidence graph via EvidenceGraph::add_node. DuplicateNode is treated as
  idempotent success (content-hash dedup), matching the idempotent
  semantics already established for EvidenceBuilder's ensure_* methods.
- parse_evidence_node_type gains requirement/req, decision/dec, cost
  (plus previously-missing rnd_activity/tax_offset, same class of gap).
- Summary's node_counts and ListNodes' invalid-type error message
  extended to include the 3 new types.
- EVIDENCE_TOOL's contract.rs action list and purpose string updated.

Verified: new tests/evidence_requirement_decision_cost.rs (3 tests,
covering import+list+detail+summary, record_decision+record_cost, and
idempotent re-import) all pass; cargo build -p ledgerr-mcp --features
legacy clean (1 pre-existing unrelated warning).

* docs: regenerate mcp-capability-contract.md (drift from task 6)

Task 6 (ledgrrr#186's second commit) added import_requirement/
record_decision/record_cost to ledgerr_evidence's EVIDENCE_TOOL actions
in contract.rs but never re-ran regen-docs, so the checked-in
mcp-capability-contract.md drifted — caught by CI's check-drift step
on downstream stacked PRs (#190, #193).

Ran: cargo run -p ledgerr-mcp --bin regen-docs

* docs: regenerate viz-manifest.json (stale version field, 1.9.0 -> 1.10.0)

Pre-existing drift, unrelated to Requirement/Decision/Cost content (28
objects, unchanged) -- the workspace version was bumped to 1.10.0 at
some point after this artifact was last regenerated. Only surfaced now
because check-drift's earlier mcp-capability-contract.md failure (fixed
in dd168f7) was masking this second, independent drift.

Ran: cargo run -p xtask-mcpb -- export-viz-manifest

* feat(iso): HasVisualization + viz_manifest wiring for Requirement/Decision/Cost (#190)

* feat(iso): HasVisualization + viz_manifest wiring for Requirement/Decision/Cost

Adds dedicated SemanticType::{Requirement,Decision,Cost} variants
(iso.rs) and HasVisualization impls for arc_kit_au::node::{Requirement,
Decision,Cost} (iso_objects.rs, gated behind the arc-kit-au feature,
matching ontology.rs's arc_kit_bridge precedent), all routed to
ZLayer::SystemsModel (added in ledgrrr#185).

Wires the 3 new types into xtask's export_viz_manifest (now 31 domain
types, up from 28) and regenerates the checked-in viz-manifest.json.
Updates pipeline_e2e.rs's EXPECTED_ENTRY_COUNT and representative-type
assertions to match.

Verified: cargo test -p ledger-core --lib (185 passed), cargo test -p
ledgerr-mcp --test pipeline_e2e (manifest count test passes), cargo
check --workspace --all-features clean.

This closes out the one remaining gap from ledgrrr#185 (task 4 in
docs/systems-modeling-registry-rescope.md's §6), left explicitly
unfinished there pending this larger change.

* feat(arc-kit-au): retrofit #[derive(SysmlBlock)] onto existing node types (#193)

Applies the sysml-derive macro (feat/sysml-derive-spike, #183) to the 8
pre-existing arc-kit-au node structs that predate the systems-modeling
epic: SourceDoc, ExtractedRow, Transaction, Classification,
ModelProposal, OperatorApproval, ValidationIssue, WorkbookRow.

This was the second of two explicitly-deferred follow-ons from task 3
(#184) — the first (HasVisualization/viz_manifest wiring for
Requirement/Decision/Cost) landed as part of this same stack. The
derive is purely syntactic (walks named fields via syn, stringifies
each field's type via quote!) so it applies uniformly regardless of
field type — no per-struct special-casing needed, confirmed by
re-reading crates/sysml-derive/src/lib.rs before applying.

Verified: cargo test -p sysml-derive (2 tests), cargo test -p
arc-kit-au (46 tests, unchanged from pre-retrofit baseline), cargo
check --workspace --all-features (clean, one pre-existing unrelated
warning in ledgerr-mcp/src/fbar.rs), cargo clippy -p arc-kit-au
--all-features (clean).
elasticdotventures added a commit that referenced this pull request Aug 23, 2026
* feat(iso): add dedicated ZLayer::SystemsModel variant

Requirement/Decision/Cost content (ledgrrr#184) gets its own isometric
layer rather than folding into the existing 6 or the still-unimplemented
proposed Domain layer (docs/ontological-implementation-spec.md §6.1),
per decision 2 in docs/systems-modeling-registry-rescope.md: independent
toggle/color in the renderer over reusing an ontological-concepts layer.

index=6, base_z=816.0 (continuing the existing 136.0 spacing), color
#be185d (distinct from all 6 existing hexes). No HasVisualization impls
wired yet for Requirement/Decision/Cost themselves — that requires also
touching xtask's viz_manifest export + the checked-in viz-manifest.json
per iso_objects.rs's own convention, tracked as a follow-on alongside
task 6 (ledgerr-mcp/contract.rs wiring), not done here.

* feat: spike reqif-opa-mcp over MCP + Requirement converter (#186)

* feat(reqif-mcp-spike): Rust MCP client for reqif-opa-mcp + Requirement converter

Spike per decision 6 (docs/systems-modeling-registry-rescope.md §5/§6
task 5): reqif-opa-mcp is wrapped over MCP, not ported to Rust;
arc-kit-au stays the canonical decision+cost ledger.

New crate reqif-mcp-spike:
- McpHttpClient: minimal blocking client for reqif-opa-mcp's Streamable-
  HTTP MCP server (FastMCP 3.0.0b1, protocol 2024-11-05). Handles the
  initialize handshake + mcp-session-id header, the mandatory
  notifications/initialized follow-up, and tools/call, extracting the
  JSON-RPC result out of the single-frame SSE response body.
- RequirementRecord: mirrors reqif-opa-mcp's requirement-record.schema.json
  exactly (uid/key/subtypes/status/policy_baseline/rubrics/text/attrs).
- requirement_record_to_node(): converts a RequirementRecord into the
  arc-kit-au Requirement struct from ledgrrr#184 (ArtifactKind::Requirement /
  NodeType::Requirement). requirement_id<-uid, title<-key, rationale<-text,
  source<-attrs.source_standard(+source_url) falling back to the policy
  baseline id, status passed through, related_decisions always empty
  (reqif-opa-mcp carries no decision links; those are created later in
  arc-kit-au itself).

Verified live end-to-end against a real reqif-opa-mcp checkout
(uv sync --extra ingest-lite; uv run python -m reqif_mcp --http --port
8123) parsing both its own sample derived baselines,
samples/standards/derived/{nist_ssdf_dogfood,owasp_asvs_cwe}.reqif (4
and 7 requirements respectively), through reqif_parse -> reqif_query ->
requirement_record_to_node -> Requirement::node_id(), all producing
correct, deterministic req: NodeIds. That live run is captured as an
#[ignore]'d integration test (tests/live_server.rs) since it needs an
external repo checkout + Python/uv, not something CI or a fresh clone
has; re-run manually with REQIF_MCP_URL set to a running server.

cargo test -p reqif-mcp-spike: 5 unit tests pass, 1 ignored (live).
cargo check --workspace --all-features: clean. cargo clippy -p
reqif-mcp-spike --all-targets: clean.

* feat(ledgerr-mcp): wire Requirement/Decision/Cost into contract.rs (task 6)

- EvidenceArgs gains import_requirement/record_decision/record_cost
  actions, each constructing the corresponding arc-kit-au node
  (Requirement/Decision/Cost from ledgrrr#184) and inserting it into the
  evidence graph via EvidenceGraph::add_node. DuplicateNode is treated as
  idempotent success (content-hash dedup), matching the idempotent
  semantics already established for EvidenceBuilder's ensure_* methods.
- parse_evidence_node_type gains requirement/req, decision/dec, cost
  (plus previously-missing rnd_activity/tax_offset, same class of gap).
- Summary's node_counts and ListNodes' invalid-type error message
  extended to include the 3 new types.
- EVIDENCE_TOOL's contract.rs action list and purpose string updated.

Verified: new tests/evidence_requirement_decision_cost.rs (3 tests,
covering import+list+detail+summary, record_decision+record_cost, and
idempotent re-import) all pass; cargo build -p ledgerr-mcp --features
legacy clean (1 pre-existing unrelated warning).

* docs: regenerate mcp-capability-contract.md (drift from task 6)

Task 6 (ledgrrr#186's second commit) added import_requirement/
record_decision/record_cost to ledgerr_evidence's EVIDENCE_TOOL actions
in contract.rs but never re-ran regen-docs, so the checked-in
mcp-capability-contract.md drifted — caught by CI's check-drift step
on downstream stacked PRs (#190, #193).

Ran: cargo run -p ledgerr-mcp --bin regen-docs

* docs: regenerate viz-manifest.json (stale version field, 1.9.0 -> 1.10.0)

Pre-existing drift, unrelated to Requirement/Decision/Cost content (28
objects, unchanged) -- the workspace version was bumped to 1.10.0 at
some point after this artifact was last regenerated. Only surfaced now
because check-drift's earlier mcp-capability-contract.md failure (fixed
in dd168f7) was masking this second, independent drift.

Ran: cargo run -p xtask-mcpb -- export-viz-manifest

* feat(iso): HasVisualization + viz_manifest wiring for Requirement/Decision/Cost (#190)

* feat(iso): HasVisualization + viz_manifest wiring for Requirement/Decision/Cost

Adds dedicated SemanticType::{Requirement,Decision,Cost} variants
(iso.rs) and HasVisualization impls for arc_kit_au::node::{Requirement,
Decision,Cost} (iso_objects.rs, gated behind the arc-kit-au feature,
matching ontology.rs's arc_kit_bridge precedent), all routed to
ZLayer::SystemsModel (added in ledgrrr#185).

Wires the 3 new types into xtask's export_viz_manifest (now 31 domain
types, up from 28) and regenerates the checked-in viz-manifest.json.
Updates pipeline_e2e.rs's EXPECTED_ENTRY_COUNT and representative-type
assertions to match.

Verified: cargo test -p ledger-core --lib (185 passed), cargo test -p
ledgerr-mcp --test pipeline_e2e (manifest count test passes), cargo
check --workspace --all-features clean.

This closes out the one remaining gap from ledgrrr#185 (task 4 in
docs/systems-modeling-registry-rescope.md's §6), left explicitly
unfinished there pending this larger change.

* feat(arc-kit-au): retrofit #[derive(SysmlBlock)] onto existing node types (#193)

Applies the sysml-derive macro (feat/sysml-derive-spike, #183) to the 8
pre-existing arc-kit-au node structs that predate the systems-modeling
epic: SourceDoc, ExtractedRow, Transaction, Classification,
ModelProposal, OperatorApproval, ValidationIssue, WorkbookRow.

This was the second of two explicitly-deferred follow-ons from task 3
(#184) — the first (HasVisualization/viz_manifest wiring for
Requirement/Decision/Cost) landed as part of this same stack. The
derive is purely syntactic (walks named fields via syn, stringifies
each field's type via quote!) so it applies uniformly regardless of
field type — no per-struct special-casing needed, confirmed by
re-reading crates/sysml-derive/src/lib.rs before applying.

Verified: cargo test -p sysml-derive (2 tests), cargo test -p
arc-kit-au (46 tests, unchanged from pre-retrofit baseline), cargo
check --workspace --all-features (clean, one pre-existing unrelated
warning in ledgerr-mcp/src/fbar.rs), cargo clippy -p arc-kit-au
--all-features (clean).
elasticdotventures added a commit that referenced this pull request Aug 23, 2026
…sion/Cost (#184)

* feat: widen ArtifactKind/NodeType/OperationKind with Requirement/Decision/Cost

Task 3 from docs/systems-modeling-registry-rescope.md (epic part 2,
ledgrrr#181), backed by sysml-derive (#183) per the resolved LinkML
comparison (#3a).

arc-kit-au:
- NodeType gains Requirement/Decision/Cost variants (prefixes req/dec/cost)
- New Requirement/Decision/Cost structs, following the existing
  Transaction/Classification pattern (content-hashed node_id()), each
  annotated with #[derive(SysmlBlock)] from sysml-derive
- EvidenceNode gains matching variants; node_id()/node_type()/tx_id()
  updated (tx_id() -> None for all three, same as SourceDoc/ExtractedRow)
- arc-kit-au now depends on sysml-derive

ledger-core:
- ArtifactKind gains matching variants + canonical_name() arms
- arc_kit_bridge's From<ArtifactKind> for NodeType maps them explicitly
  (was previously falling through the _ => Unknown wildcard)
- OperationKind gains RecordDecision/RecordCost/ImportRequirement, each
  with a corresponding LedgerOperation impl (content-hashed, idempotent,
  same shape as CheckTaxDeadlineOp) and wired into
  OperationDispatcher::from_scheduled_events

ledgerr-mcp:
- evidence_node_type_label() (behind the legacy feature) gets the 3
  new NodeType arms it was missing

Verified: cargo test -p arc-kit-au (46 tests), cargo test -p ledger-core
--lib (184 tests), cargo build -p ledgerr-mcp --features legacy, and
cargo check --workspace --all-features all pass. clippy clean on the
touched files.

Retrofitting existing variants (Transaction/TaxCategory/etc.) onto
sysml-derive is a tracked follow-on, not done here, per the doc's own
scoping.

* fix(sysml-derive): map primitive scalars + DateTime to SysML ScalarValues

DateTime<Utc> previously emitted the literal, invalid text
`DateTime<Utc>` as a SysML v2 attribute type -- SysML v2's grammar has
no angle-bracket generic-parameter syntax, so this would fail to parse
under any conformant SysML v2 tool. bool/usize/etc. also passed through
as bare Rust keywords with no corresponding SysML type.

Map DateTime<_> -> ScalarValues::String, bool -> ScalarValues::Boolean,
unsigned ints -> ScalarValues::Natural, signed ints ->
ScalarValues::Integer, floats -> ScalarValues::Rational. Any other
single-type-argument generic is now a compile error instead of a
silent invalid-syntax emission. Opaque domain types (NodeId,
Confidence, Decimal) still pass through as bare names -- documented as
an intentional modeling assumption, not a bug.

Adds regression tests for the field types introduced by #184/#193
(Decimal, Confidence, bool, usize, DateTime<Utc>) that basic.rs never
exercised. Closes ledgrrr#195.

* fix(holon-viz): emit valid SysML v2 (part def, not block def); wire real parser validation into ufo-types

Ran SysmlV2Emitter's own output through the real sysml-v2-parser crate
(docs/sysml-v2-parser-spike.md, an existing unmerged spike) and confirmed
two bugs make it non-parseable:

- The closing '}' was on the same line as a trailing '//' comment, so the
  comment swallowed it -- the block was never syntactically closed.
- The emitter used SysML v1's 'block def' keyword. SysML v2 renamed this
  construct to 'part def'; 'block' is not a SysML v2 keyword at all.

Fixed both. Added ufo_types::sysml -- a shared Constraint/Satisfies-based
SysML v2 syntax validator wired to sysml-v2-parser (pinned to =0.54.0 per
the spike's crate-health findings; not wasm32-compatible, so this must
stay out of holon-viz's runtime dependency graph -- added to holon-viz
only as a dev-dependency, used in a new round-trip test that feeds the
emitter's own output through the real parser instead of just asserting on
substrings.

This is the concrete round-trip-closed signal the existing spike (PR #187)
called out as the next step.

* fix(sysml-derive): emit part def (not block def); validate against real SysML v2 grammar

Same bug holon-viz's SysmlV2Emitter had (ledgrrr#197): SysML v1 called
this construct Block/'block def'; SysML v2 renamed it to 'part def', and
'block' is not a SysML v2 keyword at all. Confirmed via the newly-wired
ufo_types::sysml::validate_sysml_v2 (real sysml-v2-parser crate, not a
hand-rolled heuristic) that the fixed output actually parses.

Adds tests/real_grammar_validation.rs: runs the actual generated
sysml_block_def() text for Transaction/Requirement/ExtractedRow/
ModelProposal/WorkbookRow (mirroring the real production structs from
#184/#193) through the real parser. This replaces the 'no angle brackets'
manual check used to validate the earlier DateTime/bool/usize scalar
mapping fix with genuine grammar validation, closing out ledgrrr#195.

* test(arc-kit-au): update block def -> part def assertion (sysml-derive fix)

* chore: regenerate viz-manifest.json (version drift, ledgrrr#194)

* feat(iso): dedicated ZLayer::SystemsModel variant (#185)

* feat(iso): add dedicated ZLayer::SystemsModel variant

Requirement/Decision/Cost content (ledgrrr#184) gets its own isometric
layer rather than folding into the existing 6 or the still-unimplemented
proposed Domain layer (docs/ontological-implementation-spec.md §6.1),
per decision 2 in docs/systems-modeling-registry-rescope.md: independent
toggle/color in the renderer over reusing an ontological-concepts layer.

index=6, base_z=816.0 (continuing the existing 136.0 spacing), color
#be185d (distinct from all 6 existing hexes). No HasVisualization impls
wired yet for Requirement/Decision/Cost themselves — that requires also
touching xtask's viz_manifest export + the checked-in viz-manifest.json
per iso_objects.rs's own convention, tracked as a follow-on alongside
task 6 (ledgerr-mcp/contract.rs wiring), not done here.

* feat: spike reqif-opa-mcp over MCP + Requirement converter (#186)

* feat(reqif-mcp-spike): Rust MCP client for reqif-opa-mcp + Requirement converter

Spike per decision 6 (docs/systems-modeling-registry-rescope.md §5/§6
task 5): reqif-opa-mcp is wrapped over MCP, not ported to Rust;
arc-kit-au stays the canonical decision+cost ledger.

New crate reqif-mcp-spike:
- McpHttpClient: minimal blocking client for reqif-opa-mcp's Streamable-
  HTTP MCP server (FastMCP 3.0.0b1, protocol 2024-11-05). Handles the
  initialize handshake + mcp-session-id header, the mandatory
  notifications/initialized follow-up, and tools/call, extracting the
  JSON-RPC result out of the single-frame SSE response body.
- RequirementRecord: mirrors reqif-opa-mcp's requirement-record.schema.json
  exactly (uid/key/subtypes/status/policy_baseline/rubrics/text/attrs).
- requirement_record_to_node(): converts a RequirementRecord into the
  arc-kit-au Requirement struct from ledgrrr#184 (ArtifactKind::Requirement /
  NodeType::Requirement). requirement_id<-uid, title<-key, rationale<-text,
  source<-attrs.source_standard(+source_url) falling back to the policy
  baseline id, status passed through, related_decisions always empty
  (reqif-opa-mcp carries no decision links; those are created later in
  arc-kit-au itself).

Verified live end-to-end against a real reqif-opa-mcp checkout
(uv sync --extra ingest-lite; uv run python -m reqif_mcp --http --port
8123) parsing both its own sample derived baselines,
samples/standards/derived/{nist_ssdf_dogfood,owasp_asvs_cwe}.reqif (4
and 7 requirements respectively), through reqif_parse -> reqif_query ->
requirement_record_to_node -> Requirement::node_id(), all producing
correct, deterministic req: NodeIds. That live run is captured as an
#[ignore]'d integration test (tests/live_server.rs) since it needs an
external repo checkout + Python/uv, not something CI or a fresh clone
has; re-run manually with REQIF_MCP_URL set to a running server.

cargo test -p reqif-mcp-spike: 5 unit tests pass, 1 ignored (live).
cargo check --workspace --all-features: clean. cargo clippy -p
reqif-mcp-spike --all-targets: clean.

* feat(ledgerr-mcp): wire Requirement/Decision/Cost into contract.rs (task 6)

- EvidenceArgs gains import_requirement/record_decision/record_cost
  actions, each constructing the corresponding arc-kit-au node
  (Requirement/Decision/Cost from ledgrrr#184) and inserting it into the
  evidence graph via EvidenceGraph::add_node. DuplicateNode is treated as
  idempotent success (content-hash dedup), matching the idempotent
  semantics already established for EvidenceBuilder's ensure_* methods.
- parse_evidence_node_type gains requirement/req, decision/dec, cost
  (plus previously-missing rnd_activity/tax_offset, same class of gap).
- Summary's node_counts and ListNodes' invalid-type error message
  extended to include the 3 new types.
- EVIDENCE_TOOL's contract.rs action list and purpose string updated.

Verified: new tests/evidence_requirement_decision_cost.rs (3 tests,
covering import+list+detail+summary, record_decision+record_cost, and
idempotent re-import) all pass; cargo build -p ledgerr-mcp --features
legacy clean (1 pre-existing unrelated warning).

* docs: regenerate mcp-capability-contract.md (drift from task 6)

Task 6 (ledgrrr#186's second commit) added import_requirement/
record_decision/record_cost to ledgerr_evidence's EVIDENCE_TOOL actions
in contract.rs but never re-ran regen-docs, so the checked-in
mcp-capability-contract.md drifted — caught by CI's check-drift step
on downstream stacked PRs (#190, #193).

Ran: cargo run -p ledgerr-mcp --bin regen-docs

* docs: regenerate viz-manifest.json (stale version field, 1.9.0 -> 1.10.0)

Pre-existing drift, unrelated to Requirement/Decision/Cost content (28
objects, unchanged) -- the workspace version was bumped to 1.10.0 at
some point after this artifact was last regenerated. Only surfaced now
because check-drift's earlier mcp-capability-contract.md failure (fixed
in dd168f7) was masking this second, independent drift.

Ran: cargo run -p xtask-mcpb -- export-viz-manifest

* feat(iso): HasVisualization + viz_manifest wiring for Requirement/Decision/Cost (#190)

* feat(iso): HasVisualization + viz_manifest wiring for Requirement/Decision/Cost

Adds dedicated SemanticType::{Requirement,Decision,Cost} variants
(iso.rs) and HasVisualization impls for arc_kit_au::node::{Requirement,
Decision,Cost} (iso_objects.rs, gated behind the arc-kit-au feature,
matching ontology.rs's arc_kit_bridge precedent), all routed to
ZLayer::SystemsModel (added in ledgrrr#185).

Wires the 3 new types into xtask's export_viz_manifest (now 31 domain
types, up from 28) and regenerates the checked-in viz-manifest.json.
Updates pipeline_e2e.rs's EXPECTED_ENTRY_COUNT and representative-type
assertions to match.

Verified: cargo test -p ledger-core --lib (185 passed), cargo test -p
ledgerr-mcp --test pipeline_e2e (manifest count test passes), cargo
check --workspace --all-features clean.

This closes out the one remaining gap from ledgrrr#185 (task 4 in
docs/systems-modeling-registry-rescope.md's §6), left explicitly
unfinished there pending this larger change.

* feat(arc-kit-au): retrofit #[derive(SysmlBlock)] onto existing node types (#193)

Applies the sysml-derive macro (feat/sysml-derive-spike, #183) to the 8
pre-existing arc-kit-au node structs that predate the systems-modeling
epic: SourceDoc, ExtractedRow, Transaction, Classification,
ModelProposal, OperatorApproval, ValidationIssue, WorkbookRow.

This was the second of two explicitly-deferred follow-ons from task 3
(#184) — the first (HasVisualization/viz_manifest wiring for
Requirement/Decision/Cost) landed as part of this same stack. The
derive is purely syntactic (walks named fields via syn, stringifies
each field's type via quote!) so it applies uniformly regardless of
field type — no per-struct special-casing needed, confirmed by
re-reading crates/sysml-derive/src/lib.rs before applying.

Verified: cargo test -p sysml-derive (2 tests), cargo test -p
arc-kit-au (46 tests, unchanged from pre-retrofit baseline), cargo
check --workspace --all-features (clean, one pre-existing unrelated
warning in ledgerr-mcp/src/fbar.rs), cargo clippy -p arc-kit-au
--all-features (clean).
elasticdotventures added a commit that referenced this pull request Aug 23, 2026
* feat(sysml-derive): spike a Rust-AST-to-SysML-v2 derive macro

New crate: #[derive(SysmlBlock)] walks a struct's named fields via syn
and generates a sysml_block_def() associated fn returning the
equivalent SysML-v2 'block def' text at compile time (matching
holon-viz's SysmlV2Emitter 'block def' terminology).

Field-type mapping: Vec<T> -> T[*], Option<T> -> T[0..1], everything
else -> plain T. Not yet checked against a real SysML-v2 grammar/parser
(Part 1's Tier 0 candidates) -- this is the spike from
docs/systems-modeling-registry-rescope.md #2a/#6 task 1, proving the
AST-walk direction before comparing it against the LinkML spike
(task 2) and wiring either into the real ArtifactKind/NodeType widening
(task 3).

Tests mirror arc-kit-au::Transaction's and ::Classification's field
shapes (name+type only, no dependency on arc-kit-au itself -- wiring
the derive onto the real production structs is task 3, not this spike)
and assert on the emitted block def text for both the Vec and Option
multiplicity branches.

Same technique this codebase already approved for a different target:
AGENTS.md (PM-3, 2026-05-13) sanctions #[derive(specta::Type)] for
Rust-to-TypeScript; this is Rust-to-SysML-v2/KerML instead.

* chore: regenerate viz-manifest.json (version drift 1.9.0 -> 1.10.0)

* feat: widen ArtifactKind/NodeType/OperationKind with Requirement/Decision/Cost (#184)

* feat: widen ArtifactKind/NodeType/OperationKind with Requirement/Decision/Cost

Task 3 from docs/systems-modeling-registry-rescope.md (epic part 2,
ledgrrr#181), backed by sysml-derive (#183) per the resolved LinkML
comparison (#3a).

arc-kit-au:
- NodeType gains Requirement/Decision/Cost variants (prefixes req/dec/cost)
- New Requirement/Decision/Cost structs, following the existing
  Transaction/Classification pattern (content-hashed node_id()), each
  annotated with #[derive(SysmlBlock)] from sysml-derive
- EvidenceNode gains matching variants; node_id()/node_type()/tx_id()
  updated (tx_id() -> None for all three, same as SourceDoc/ExtractedRow)
- arc-kit-au now depends on sysml-derive

ledger-core:
- ArtifactKind gains matching variants + canonical_name() arms
- arc_kit_bridge's From<ArtifactKind> for NodeType maps them explicitly
  (was previously falling through the _ => Unknown wildcard)
- OperationKind gains RecordDecision/RecordCost/ImportRequirement, each
  with a corresponding LedgerOperation impl (content-hashed, idempotent,
  same shape as CheckTaxDeadlineOp) and wired into
  OperationDispatcher::from_scheduled_events

ledgerr-mcp:
- evidence_node_type_label() (behind the legacy feature) gets the 3
  new NodeType arms it was missing

Verified: cargo test -p arc-kit-au (46 tests), cargo test -p ledger-core
--lib (184 tests), cargo build -p ledgerr-mcp --features legacy, and
cargo check --workspace --all-features all pass. clippy clean on the
touched files.

Retrofitting existing variants (Transaction/TaxCategory/etc.) onto
sysml-derive is a tracked follow-on, not done here, per the doc's own
scoping.

* fix(sysml-derive): map primitive scalars + DateTime to SysML ScalarValues

DateTime<Utc> previously emitted the literal, invalid text
`DateTime<Utc>` as a SysML v2 attribute type -- SysML v2's grammar has
no angle-bracket generic-parameter syntax, so this would fail to parse
under any conformant SysML v2 tool. bool/usize/etc. also passed through
as bare Rust keywords with no corresponding SysML type.

Map DateTime<_> -> ScalarValues::String, bool -> ScalarValues::Boolean,
unsigned ints -> ScalarValues::Natural, signed ints ->
ScalarValues::Integer, floats -> ScalarValues::Rational. Any other
single-type-argument generic is now a compile error instead of a
silent invalid-syntax emission. Opaque domain types (NodeId,
Confidence, Decimal) still pass through as bare names -- documented as
an intentional modeling assumption, not a bug.

Adds regression tests for the field types introduced by #184/#193
(Decimal, Confidence, bool, usize, DateTime<Utc>) that basic.rs never
exercised. Closes ledgrrr#195.

* fix(holon-viz): emit valid SysML v2 (part def, not block def); wire real parser validation into ufo-types

Ran SysmlV2Emitter's own output through the real sysml-v2-parser crate
(docs/sysml-v2-parser-spike.md, an existing unmerged spike) and confirmed
two bugs make it non-parseable:

- The closing '}' was on the same line as a trailing '//' comment, so the
  comment swallowed it -- the block was never syntactically closed.
- The emitter used SysML v1's 'block def' keyword. SysML v2 renamed this
  construct to 'part def'; 'block' is not a SysML v2 keyword at all.

Fixed both. Added ufo_types::sysml -- a shared Constraint/Satisfies-based
SysML v2 syntax validator wired to sysml-v2-parser (pinned to =0.54.0 per
the spike's crate-health findings; not wasm32-compatible, so this must
stay out of holon-viz's runtime dependency graph -- added to holon-viz
only as a dev-dependency, used in a new round-trip test that feeds the
emitter's own output through the real parser instead of just asserting on
substrings.

This is the concrete round-trip-closed signal the existing spike (PR #187)
called out as the next step.

* fix(sysml-derive): emit part def (not block def); validate against real SysML v2 grammar

Same bug holon-viz's SysmlV2Emitter had (ledgrrr#197): SysML v1 called
this construct Block/'block def'; SysML v2 renamed it to 'part def', and
'block' is not a SysML v2 keyword at all. Confirmed via the newly-wired
ufo_types::sysml::validate_sysml_v2 (real sysml-v2-parser crate, not a
hand-rolled heuristic) that the fixed output actually parses.

Adds tests/real_grammar_validation.rs: runs the actual generated
sysml_block_def() text for Transaction/Requirement/ExtractedRow/
ModelProposal/WorkbookRow (mirroring the real production structs from
#184/#193) through the real parser. This replaces the 'no angle brackets'
manual check used to validate the earlier DateTime/bool/usize scalar
mapping fix with genuine grammar validation, closing out ledgrrr#195.

* test(arc-kit-au): update block def -> part def assertion (sysml-derive fix)

* chore: regenerate viz-manifest.json (version drift, ledgrrr#194)

* feat(iso): dedicated ZLayer::SystemsModel variant (#185)

* feat(iso): add dedicated ZLayer::SystemsModel variant

Requirement/Decision/Cost content (ledgrrr#184) gets its own isometric
layer rather than folding into the existing 6 or the still-unimplemented
proposed Domain layer (docs/ontological-implementation-spec.md §6.1),
per decision 2 in docs/systems-modeling-registry-rescope.md: independent
toggle/color in the renderer over reusing an ontological-concepts layer.

index=6, base_z=816.0 (continuing the existing 136.0 spacing), color
#be185d (distinct from all 6 existing hexes). No HasVisualization impls
wired yet for Requirement/Decision/Cost themselves — that requires also
touching xtask's viz_manifest export + the checked-in viz-manifest.json
per iso_objects.rs's own convention, tracked as a follow-on alongside
task 6 (ledgerr-mcp/contract.rs wiring), not done here.

* feat: spike reqif-opa-mcp over MCP + Requirement converter (#186)

* feat(reqif-mcp-spike): Rust MCP client for reqif-opa-mcp + Requirement converter

Spike per decision 6 (docs/systems-modeling-registry-rescope.md §5/§6
task 5): reqif-opa-mcp is wrapped over MCP, not ported to Rust;
arc-kit-au stays the canonical decision+cost ledger.

New crate reqif-mcp-spike:
- McpHttpClient: minimal blocking client for reqif-opa-mcp's Streamable-
  HTTP MCP server (FastMCP 3.0.0b1, protocol 2024-11-05). Handles the
  initialize handshake + mcp-session-id header, the mandatory
  notifications/initialized follow-up, and tools/call, extracting the
  JSON-RPC result out of the single-frame SSE response body.
- RequirementRecord: mirrors reqif-opa-mcp's requirement-record.schema.json
  exactly (uid/key/subtypes/status/policy_baseline/rubrics/text/attrs).
- requirement_record_to_node(): converts a RequirementRecord into the
  arc-kit-au Requirement struct from ledgrrr#184 (ArtifactKind::Requirement /
  NodeType::Requirement). requirement_id<-uid, title<-key, rationale<-text,
  source<-attrs.source_standard(+source_url) falling back to the policy
  baseline id, status passed through, related_decisions always empty
  (reqif-opa-mcp carries no decision links; those are created later in
  arc-kit-au itself).

Verified live end-to-end against a real reqif-opa-mcp checkout
(uv sync --extra ingest-lite; uv run python -m reqif_mcp --http --port
8123) parsing both its own sample derived baselines,
samples/standards/derived/{nist_ssdf_dogfood,owasp_asvs_cwe}.reqif (4
and 7 requirements respectively), through reqif_parse -> reqif_query ->
requirement_record_to_node -> Requirement::node_id(), all producing
correct, deterministic req: NodeIds. That live run is captured as an
#[ignore]'d integration test (tests/live_server.rs) since it needs an
external repo checkout + Python/uv, not something CI or a fresh clone
has; re-run manually with REQIF_MCP_URL set to a running server.

cargo test -p reqif-mcp-spike: 5 unit tests pass, 1 ignored (live).
cargo check --workspace --all-features: clean. cargo clippy -p
reqif-mcp-spike --all-targets: clean.

* feat(ledgerr-mcp): wire Requirement/Decision/Cost into contract.rs (task 6)

- EvidenceArgs gains import_requirement/record_decision/record_cost
  actions, each constructing the corresponding arc-kit-au node
  (Requirement/Decision/Cost from ledgrrr#184) and inserting it into the
  evidence graph via EvidenceGraph::add_node. DuplicateNode is treated as
  idempotent success (content-hash dedup), matching the idempotent
  semantics already established for EvidenceBuilder's ensure_* methods.
- parse_evidence_node_type gains requirement/req, decision/dec, cost
  (plus previously-missing rnd_activity/tax_offset, same class of gap).
- Summary's node_counts and ListNodes' invalid-type error message
  extended to include the 3 new types.
- EVIDENCE_TOOL's contract.rs action list and purpose string updated.

Verified: new tests/evidence_requirement_decision_cost.rs (3 tests,
covering import+list+detail+summary, record_decision+record_cost, and
idempotent re-import) all pass; cargo build -p ledgerr-mcp --features
legacy clean (1 pre-existing unrelated warning).

* docs: regenerate mcp-capability-contract.md (drift from task 6)

Task 6 (ledgrrr#186's second commit) added import_requirement/
record_decision/record_cost to ledgerr_evidence's EVIDENCE_TOOL actions
in contract.rs but never re-ran regen-docs, so the checked-in
mcp-capability-contract.md drifted — caught by CI's check-drift step
on downstream stacked PRs (#190, #193).

Ran: cargo run -p ledgerr-mcp --bin regen-docs

* docs: regenerate viz-manifest.json (stale version field, 1.9.0 -> 1.10.0)

Pre-existing drift, unrelated to Requirement/Decision/Cost content (28
objects, unchanged) -- the workspace version was bumped to 1.10.0 at
some point after this artifact was last regenerated. Only surfaced now
because check-drift's earlier mcp-capability-contract.md failure (fixed
in dd168f7) was masking this second, independent drift.

Ran: cargo run -p xtask-mcpb -- export-viz-manifest

* feat(iso): HasVisualization + viz_manifest wiring for Requirement/Decision/Cost (#190)

* feat(iso): HasVisualization + viz_manifest wiring for Requirement/Decision/Cost

Adds dedicated SemanticType::{Requirement,Decision,Cost} variants
(iso.rs) and HasVisualization impls for arc_kit_au::node::{Requirement,
Decision,Cost} (iso_objects.rs, gated behind the arc-kit-au feature,
matching ontology.rs's arc_kit_bridge precedent), all routed to
ZLayer::SystemsModel (added in ledgrrr#185).

Wires the 3 new types into xtask's export_viz_manifest (now 31 domain
types, up from 28) and regenerates the checked-in viz-manifest.json.
Updates pipeline_e2e.rs's EXPECTED_ENTRY_COUNT and representative-type
assertions to match.

Verified: cargo test -p ledger-core --lib (185 passed), cargo test -p
ledgerr-mcp --test pipeline_e2e (manifest count test passes), cargo
check --workspace --all-features clean.

This closes out the one remaining gap from ledgrrr#185 (task 4 in
docs/systems-modeling-registry-rescope.md's §6), left explicitly
unfinished there pending this larger change.

* feat(arc-kit-au): retrofit #[derive(SysmlBlock)] onto existing node types (#193)

Applies the sysml-derive macro (feat/sysml-derive-spike, #183) to the 8
pre-existing arc-kit-au node structs that predate the systems-modeling
epic: SourceDoc, ExtractedRow, Transaction, Classification,
ModelProposal, OperatorApproval, ValidationIssue, WorkbookRow.

This was the second of two explicitly-deferred follow-ons from task 3
(#184) — the first (HasVisualization/viz_manifest wiring for
Requirement/Decision/Cost) landed as part of this same stack. The
derive is purely syntactic (walks named fields via syn, stringifies
each field's type via quote!) so it applies uniformly regardless of
field type — no per-struct special-casing needed, confirmed by
re-reading crates/sysml-derive/src/lib.rs before applying.

Verified: cargo test -p sysml-derive (2 tests), cargo test -p
arc-kit-au (46 tests, unchanged from pre-retrofit baseline), cargo
check --workspace --all-features (clean, one pre-existing unrelated
warning in ledgerr-mcp/src/fbar.rs), cargo clippy -p arc-kit-au
--all-features (clean).
elasticdotventures added a commit that referenced this pull request Aug 23, 2026
* docs: systems modeling & action registry re-scope (epic part 2)

Re-scopes ledgrrr from its README's tax-accounting framing to a general
systems modeling process and action registry, with ReqIF (requirements),
LinkML (schema), and a decision+cost ledger as new domain verticals on
the existing substrate (arc-kit-au identity, ArtifactKind/NodeType
ontology graph, ZLayer visualization, Rhai policy).

All 6 open questions resolved:
1. Widen ArtifactKind/NodeType core enums (not custom kinds)
2. New dedicated ZLayer variant (not the existing proposed Domain layer)
3. reqif-opa-mcp (first-party) chosen over third-party ReqIF wraps
4. LinkML: spike before committing
5. sysgit.io: reference vibe only, not a feature-parity backlog
6. reqif-opa-mcp: wrap over MCP; arc-kit-au stays the canonical
   decision+cost ledger; OPA/Rego and Rhai coexist, one per domain

Addendum folded in during review: existing ledger types (Transaction,
TaxCategory) and new ones (Requirement/Decision/Cost) should be concrete
specializations of generic SysML v2 types, generated via a Rust
AST-walking derive macro (new sysml-derive crate) rather than
hand-maintained per-type emitter logic -- same technique already
approved here for specta's Rust-to-TypeScript codegen, aimed at
SysML-v2/KerML instead. Task list reordered so this spike gates the
ArtifactKind widening and runs alongside the LinkML spike as a direct
comparison.

* docs: mark sysml-derive spike (task 1) done, link ledgrrr#183

* docs: LinkML vs sysml-derive spike comparison, decision 4 resolved

Ran the actual spike: installed linkml, confirmed gen-rust is real,
authored the same 5-field Requirement schema sysml-derive's test
suite mirrors, generated + built the Rust output, and consumed it
from a throwaway crate.

Findings: gen-rust works but produces 1219 lines for one class,
pulls in pyo3/serde_yml scaffolding unconditionally, compiles with
7 warnings out of the box, and -- the deciding finding --
silently serializes a single-element Vec<String> as a bare JSON
scalar instead of an array via its generated
serialize_primitive_list_or_single_value helper. Same class of
surprise already flagged for sysmlpy during the ReqIF survey, now
found independently in LinkML's own generator.

Decision: sysml-derive (Rust-native, macro-driven, ledgrrr#183) wins
over LinkML for authoring Requirement/Decision/Cost's Rust shape --
Rust-first fit, no correctness surprise, no extra toolchain, matches
the existing specta precedent. LinkML is not rejected for the whole
epic, just this role. Task 3 (widen ArtifactKind/NodeType) is now
unblocked.

* docs: mark task 3 (ArtifactKind/NodeType/OperationKind widening) done, link ledgrrr#184

* docs: mark task 4 (ZLayer::SystemsModel variant) done, link ledgrrr#185

* docs: mark task 5 (reqif-opa-mcp MCP client spike) done, link ledgrrr#186

* docs: mark task 6 (contract.rs wiring) + README correction done, link ledgrrr#186/#188

All 6 tasks in epic part 2's §6 task list are now complete.

* docs: mark HasVisualization wiring, retrofit, and DVC scoping done (#190/#193/#191)

* chore: regenerate viz-manifest.json (version drift from v1.10.0 bump)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant