Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ The [synthetic tool-library example](examples/tool-library/README.md) includes a

The [version-2 contract](docs/verifier-v2.md) and [synthetic fixture](examples/verifier/valid.json) specify the finite semantics. Use `--scenario S1 --view` to retrieve a context slice, while running checks against the full model. The [FHWA slice](docs/fhwa-merge-slice.md) is an unaccepted formalization proposal. [FRET reuse](docs/fret-spike.md), [context measurement](docs/context-measurement.md), and the separate [protected-runner boundary](docs/protected-runner.md) record limits and next work.

The optional [engineering view-quality checks](docs/engineering-view-quality.md)
validate declared function roots/levels/parent links and ordered participant
exchanges, with task-specific counts, coverage, timing, and justified exceptions.
The skills assess action meaning and engineering adequacy with the engineer;
structural acceptance does not establish either. Existing unannotated models
retain their current checks. Try the neutral fixture with
`python3 scripts/sysml.py examples/sysml/views/sample-handling.sysml --syntax-only --view-profile examples/sysml/views/task-profile.json`.

## Use the skills

The repository registers its three skills through symlinks under `.agents/skills/`, which Codex discovers when you open this project. They remain independently invocable and are scoped to this repository. Start a new project conversation if the skill selector has not refreshed. [Codex skill discovery](https://learn.chatgpt.com/docs/build-skills) documents repository scope and symlink support.
Expand Down
154 changes: 154 additions & 0 deletions docs/engineering-view-quality.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# Function and operational view quality

Use rigor appropriate to the question, model maturity, and requested deliverable.
Identify the task brief's requested views, levels, scope, timing, and completeness
before drafting; carry these into an explicit task profile when computable. No
universal breadth, depth, number of functions, or timing requirement is implied.
Do not substitute an academic rubric for a general engineering rule.

Functions describe actions or transformations. Prefer verb-object names such as
`CaptureSample`, with context, inputs, and outputs where useful. Parts/components
and actors name the entities that perform or participate in actions; a component
list is not a function decomposition. A dictionary of verbs or a naming regex
cannot determine whether a function has engineering meaning. The engineer must
assess that meaning, relevance, abstraction, coverage, and any naming exceptions.

A **function tree** shows decomposition: one explicit level-0/root function,
numbered decomposition levels, and parent-child traceability. It does not specify
execution order. An **activity diagram** shows actions and control/object flow,
including decisions, concurrency, and loops as appropriate. A **sequence diagram**
shows participants and meaningful exchanges in order; it does not establish a
function hierarchy. Do not claim that a tree or an ordered narrative is an
executable activity/interaction model. Permitted behavior loops are distinct from
invalid cycles in a function decomposition.

When a hierarchy is requested, record its root, each node's level, and its parent;
check requested levels and scope, including skipped levels, orphans, cycles, and
duplicate IDs. Establish breadth/depth/count constraints only from the actual task
or an engineer-directed profile. A shallow exploration may be sufficient. When
sequences are requested, establish the participants and ordered exchanges with
clear purpose and content. Include timing ranges when required by the brief or
rubric, or when useful and supported: numeric nonnegative min <= max, duration
units, and a timing reference/basis. Preserve unresolved timing instead of inventing
numbers. Review meaning and completeness with the engineer; machine structure
checks cannot settle either.

## Opt-in documentary checks in the authoritative SysML model

The existing three skill entry points support the same command:

```sh
python3 skills/develop-system-concept/scripts/cse.py check \
examples/sysml/views/sample-handling.sysml --syntax-only \
--view-profile examples/sysml/views/task-profile.json --json
```

Use the actual skill/runtime path from another directory. `--kind` can still be
added for the requested skill's ordinary draft-shape check. Existing models with
no `cseViews` annotation and no profile retain their earlier checks. Legacy
version-1 JSON helpers keep their existing semantics; do not retrofit their prose
with executable logic or claim they perform these new checks.

One package-owned `doc cseViews` block across the explicitly supplied model files
contains a `CSE-VIEWS/1.0` header followed by a JSON object with a `views` list.
Duplicate JSON keys, unknown fields in supported records, and malformed values
are errors. This is **documentary metadata**, not native SysML decomposition,
ownership, allocation, flow, or timing constraints. It stays within the model,
and binds uniquely by exact qualified name to extracted native elements. The
checker never manufactures missing elements or changes native model semantics.
Unsupported bindings require explicit modeling support rather than proxies.

The [synthetic example](../examples/sysml/views/sample-handling.sysml) and
[task profile](../examples/sysml/views/task-profile.json) demonstrate both kinds:

| Record | Fields and interpretation |
| --- | --- |
| Function tree | `id`, `kind: "function_tree"`, `nodes` list. Each node has `id`, `element` (native action definition or usage qualified name), `level` (nonnegative integer), and `parent` (node ID or null for root). One explicit level-0 root; each child is exactly one level below its parent. Native action bindings and IDs must be unique within this view. |
| Sequence | `id`, `kind: "sequence"`, `participants`, `exchanges`. Participants have `id` and `element` (native part **usage** qualified name). Participant bindings must be unique in the view. Exchanges are in list order, each with `id`, `from`, `to`, and nonempty `message`. Self exchanges are permitted. |
| Exchange timing | Optional `timing: {min, max, unit, basis}`. Both bounds are finite, nonnegative JSON numbers, min <= max. Units: singular/plural millisecond, second, minute, hour. `basis` states what elapsed interval is described. No conversion, timing execution, or cross-exchange arithmetic is performed. |

View IDs are unique across the block. Node IDs are unique within a tree.
Participant and exchange IDs share a unique namespace within each sequence.
The same native element may appear in different views; refer to it by qualified
name rather than assuming identical local IDs imply a cross-view trace.
The current parser extracts only part usages outside part definitions for
participant binding. Other native structures remain outside this bounded checker.
An empty tree or sequence fails. An unrecognized kind, including `activity`, is
`unsupported`; existing activity models without this annotation remain unaffected.

## Compatibility with maintained workflow metadata

The unmerged `codex/cse-foundation-20261012` line already provides native role
bindings, acyclic `decomposes` relations, hierarchy parent checks, documentary
step precedence, and a source/geometry-qualified function diagram adapter.
This increment adds task-specific levels/counts/coverage and participant message
timing checks; it does not replace those features or change their renderer.

If a supplied model also contains `cseWorkflow`, the new metadata supplements
that existing hierarchy. The checker reads its exact `CSE-WORKFLOW/1.0` header,
`workflow-1.0` version and identity/relation surface with strict JSON parsing.
Each tree node must use the unique existing **function ID** for its exact native
action binding. Its parent edges must match existing `decomposes` edges in the
selected scope, including any external parent of a nonroot selected node.
A scoped root may retain an outside parent as context. Omitted children outside
the selected scope are listed in `workflow_reconciliation.omitted_children`;
the task profile and engineer determine whether those omissions are appropriate.
Conflicting or ambiguous representations refuse the result. A documentary
`precedes`, information, or control relationship is never converted to hierarchy.

This bounded comparison covers selected identities and decomposition edges; it
is not a full workflow, source, decision, or source-diagram validation. Run the
maintained workflow checks separately when using that runtime. The existing
workflow sequence view represents step precedence; the new participant/exchange
annotation is explicitly a distinct documentary sequence contract. Do not infer
cross-view order or native behavior from either. No unpublished branch dependency
is imported by this increment.

## Task profile and justified tailoring

`--view-profile PATH.json` supplies version 1 and a `views` list. Each entry
requires `id` and `kind`, identifying a required view. The profile is explicit
input, never discovered or derived from the draft to claim independent review.
The report binds it by a content digest. No profile is a protected acceptance
channel; the engineer retains authority over scope and exceptions.

Optional profile fields:

| Field | Meaning |
| --- | --- |
| `required_levels` | Function tree only: unique nonnegative integer levels that must be represented. |
| `level_counts` | Function tree only: map of decimal level strings to `{min, max}` count bounds (either bound may be omitted). Counts include only nodes in this view. |
| `child_counts` | Function tree only: map of parent node IDs to count bounds for direct children. The parent must exist, even for min 0. |
| `required_ids` | Required node IDs for a tree, or participant/exchange IDs for a sequence. This checks declared coverage, not engineering completeness. |
| `require_timing` | Sequence only: Boolean, default false. When true, each exchange needs timing. |
| `exceptions` | List of `{rule, target, rationale}` for actual task-profile gaps. Each rationale must be nonempty. Rules: `required_level`, `level_count`, `child_count`, `required_id`, or sequence `timing`. Targets are level strings, node IDs, or exchange IDs as applicable. |

Counts have no default limits. To tailor a one-level study, request only its
needed levels; do not impose deeper decomposition. To retain a justified gap,
record the actual rationale in the task profile, for example:

```json
{"rule": "timing", "target": "E2", "rationale": "Exploratory archive interface; timing deferred pending measurement."}
```

The report exposes every used exception; unused/duplicate exceptions are errors.
A rationale string does not authenticate engineer approval. Exceptions cannot
waive malformed structure, cycles, orphans, duplicate IDs, wrong native bindings,
or invalid timing values. Revise consequential scope or exceptions as a proposal
for the engineer; do not silently relax them to obtain success.

## What the result means

The nested `view_checks` report has claim scope `documentary_view_structure`.
Malformed contract/input gives `error`, structurally invalid declarations give
`fail`, missing requested views/levels/coverage/timing give `unknown`, and
unimplemented kinds give `unsupported`. These findings propagate into the parent
check status; none can yield an overall successful requested check. A pass with
exceptions means the declared structure and explicitly tailored profile passed.

The report always identifies outstanding human assessments. Nonempty names,
messages, and rationale cannot prove action meaning, exchange usefulness,
adequate decomposition, task completeness, source truth, stakeholder acceptance,
realistic timing, or actual system behavior. Syntax, documentary structure,
controlled-clause compilation, synthetic tests, and supplied behavior evidence
remain separate claims. A local check is not protected execution.
36 changes: 36 additions & 0 deletions examples/sysml/views/sample-handling.sysml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package SampleHandling {
doc /* Entirely synthetic view-check example. No engineering acceptance claimed. */
part def Operator;
part def Station;
part def Archive;
part operator : Operator;
part station : Station;
part archive : Archive;

action def ProcessSample;
action def CaptureSample;
action def StoreSample;
action def ValidateSample;

doc cseViews /*
CSE-VIEWS/1.0
{"views": [
{"id": "FT", "kind": "function_tree", "nodes": [
{"id": "F0", "element": "SampleHandling::ProcessSample", "level": 0, "parent": null},
{"id": "F1", "element": "SampleHandling::CaptureSample", "level": 1, "parent": "F0"},
{"id": "F2", "element": "SampleHandling::StoreSample", "level": 1, "parent": "F0"},
{"id": "F3", "element": "SampleHandling::ValidateSample", "level": 2, "parent": "F1"}
]},
{"id": "SQ", "kind": "sequence", "participants": [
{"id": "OP", "element": "SampleHandling::operator"},
{"id": "ST", "element": "SampleHandling::station"},
{"id": "AR", "element": "SampleHandling::archive"}
], "exchanges": [
{"id": "E1", "from": "OP", "to": "ST", "message": "Submit sample for capture",
"timing": {"min": 0, "max": 2, "unit": "seconds", "basis": "Elapsed after synthetic scenario trigger"}},
{"id": "E2", "from": "ST", "to": "AR", "message": "Send validated sample record",
"timing": {"min": 1, "max": 4, "unit": "seconds", "basis": "Elapsed after E1 completes"}}
]}
]}
*/
}
19 changes: 19 additions & 0 deletions examples/sysml/views/task-profile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": 1,
"views": [
{
"id": "FT",
"kind": "function_tree",
"required_levels": [0, 1, 2],
"required_ids": ["F0", "F1", "F2", "F3"],
"level_counts": {"1": {"min": 2, "max": 4}},
"child_counts": {"F0": {"min": 2, "max": 2}}
},
{
"id": "SQ",
"kind": "sequence",
"required_ids": ["OP", "ST", "AR", "E1", "E2"],
"require_timing": true
}
]
}
2 changes: 1 addition & 1 deletion scripts/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def main():
suites = ("test_develop_conops.py", "test_scenario_split.py", "test_concept.py", "test_verifier.py",
"test_language.py", "test_language_oracle.py", "test_influence.py", "test_events.py",
"test_public_language_cases.py", "test_sysml.py", "test_sysml_views.py",
"test_sysml_public.py", "test_skill_runtime.py")
"test_sysml_public.py", "test_skill_runtime.py", "test_engineering_views.py")
for suite in suites:
result = subprocess.run([sys.executable, "-B", str(ROOT / "tests" / suite)],
cwd=ROOT, env=environment, text=True,
Expand Down
10 changes: 9 additions & 1 deletion scripts/sysml.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,20 @@ def main():
parser.add_argument("--syntax-only", action="store_true", help="check SysML syntax and references without compiling CSE clauses")
parser.add_argument("--kind", choices=("concept", "conops", "scenario"),
help="also check the minimal model shape for this skill")
parser.add_argument("--view-profile", help="explicit task requirements for documentary function trees/sequences")
parser.add_argument("--json", action="store_true")
args = parser.parse_args()
try:
view_profile = load_json(args.view_profile) if args.view_profile is not None else None
if args.view_profile is not None and not isinstance(view_profile, dict):
raise ValueError("View profile must be a JSON object, not null or another JSON value")
manifest = load_json(args.manifest) if args.manifest else None
evidence = load_json(args.evidence) if args.evidence else None
except (OSError, ValueError) as exc:
print(f"Cannot read input: {exc}", file=sys.stderr)
return 2
report = check_sysml(args.model, manifest=manifest, evidence=evidence, review=args.review,
syntax_only=args.syntax_only, kind=args.kind)
syntax_only=args.syntax_only, kind=args.kind, view_profile=view_profile)
if args.json:
print(json.dumps(report, sort_keys=True, indent=2))
else:
Expand All @@ -42,6 +46,10 @@ def main():
else:
description = "supplied behavior evidence"
print(f"{report['status']}: {description}, {len(report['results'])} compiled obligation(s)")
if "view_checks" in report:
print(f" documentary view structure: {report['view_checks']['status']}; action names, exchange meaning, and engineering adequacy need human review")
for exception in report['view_checks']['exceptions']:
print(f" exception {exception['view']}/{exception['rule']}/{exception['target']}: {exception['rationale']}")
issues = report.get("parser_issues", [])
for issue in issues[:8]:
print(f" {issue.get('severity', 'ISSUE')} {issue.get('source')}:{issue.get('line')}: {issue.get('message')}")
Expand Down
2 changes: 2 additions & 0 deletions skills/develop-conops/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ The engineer directs scope, interpretation, priorities, accepted assumptions, an
3. Integrate relevant scenarios, external responsibilities, and evaluation plans. Expose disagreement, coverage gaps, and reasons for deferral. Plan needed data and environments; distinguish improvement goals from accepted thresholds and test claims with suitable programs or evidence.
4. Incorporate feedback into affected work. Return the useful change, material findings, and any next engineer decision. Stop at the requested boundary; omit filler and repeated questionnaires.

Establish function and view quality proportionately to the requested task. Functions express actions or transformations; recommend verb-object names, distinguish them from component and actor names, and assess meaning with the engineer rather than a naive verb dictionary. A function tree expresses decomposition, an activity diagram control/object flow, and a sequence diagram ordered participant exchanges; none substitutes for another. For a requested hierarchy, establish an explicit level-0/root, numbered decomposition levels, and parent-child traceability. Check requested levels, orphans, cycles, and duplicate IDs. Tailor breadth, depth, counts, and completeness to the brief; no fixed counts apply universally. Sequences need identified participants and meaningful ordered exchanges; add numeric min <= max timing ranges with units and a timing basis when the task requires them. Keep unsupported timing unresolved. Preserve justified exceptions explicitly and consequential changes as proposals. Use the optional documentary view checks described in [the SysML record guidance](references/sysml.md); distinguish machine-verifiable structure from human assessment of action meaning, adequacy, and completeness.

For new recorded work, maintain a SysML v2 `.sysml` model as the authoritative CONOPS artifact; respect discussion-only requests. Read [the SysML record guidance](references/sysml.md) and use [the validated synthetic template](templates/default.sysml) when useful. Keep stakeholder concerns, operating modes, use cases, and qualitative uncertainties distinct. Run `python3 <skill-dir>/scripts/cse.py check <model>.sysml --syntax-only --kind conops` after edits; this launcher resolves the shared engine regardless of the current directory. Compile designated CSE clauses with its `check` command and run `--review` only when independent scope and supplied evidence exist. Narrative alone supplies no executable guard or effect.

When a supported sampled requirement is present, run `python3 <skill-dir>/scripts/cse.py testgen <model>.sysml` as part of local draft evaluation and show the synthetic pass/fail variable-influence pairs. If none is present, say what remains qualitative or unsupported without inventing a threshold. Report uncovered variables and search limits; generated tests are not observed behavior evidence or FLIP coverage.
Expand Down
Loading
Loading