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
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ jobs:
- name: Run core.transition-action-status example smoke
run: TRAVERSE_REPO_ROOT="$PWD" bash scripts/ci/core_transition_action_status_example_smoke.sh

- name: Run core.assign-ownership example smoke
run: TRAVERSE_REPO_ROOT="$PWD" bash scripts/ci/core_assign_ownership_example_smoke.sh

- name: Run capability new E2E smoke
run: TRAVERSE_REPO_ROOT="$PWD" bash scripts/ci/capability_new_e2e_smoke.sh

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ jobs:
- name: Run core.transition-action-status example smoke
run: TRAVERSE_REPO_ROOT="$PWD" bash scripts/ci/core_transition_action_status_example_smoke.sh

- name: Run core.assign-ownership example smoke
run: TRAVERSE_REPO_ROOT="$PWD" bash scripts/ci/core_assign_ownership_example_smoke.sh

- name: Run capability new E2E smoke
run: TRAVERSE_REPO_ROOT="$PWD" bash scripts/ci/capability_new_e2e_smoke.sh

Expand Down
17 changes: 14 additions & 3 deletions crates/traverse-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3325,6 +3325,13 @@ fn prepare_and_open_registry_pr(
runner: &dyn PublishProcessRunner,
registry_repo: &str,
) -> Result<String, (&'static str, String, Option<String>)> {
// `gh release create` runs with cwd = registry checkout, so relative artifact
// paths from the Traverse workspace fail with "no matches found". Always pass
// an absolute path when one can be resolved.
let artifact_for_release = request
.artifact_path
.canonicalize()
.unwrap_or_else(|_| request.artifact_path.clone());
run_publish_command(
runner,
&request.registry_repo_path,
Expand All @@ -3333,7 +3340,7 @@ fn prepare_and_open_registry_pr(
"release".to_string(),
"create".to_string(),
plan.artifact_release_tag.clone(),
request.artifact_path.display().to_string(),
artifact_for_release.display().to_string(),
"--repo".to_string(),
registry_repo.to_string(),
"--title".to_string(),
Expand Down Expand Up @@ -3456,8 +3463,10 @@ fn run_publish_command(
}

fn capability_publish_pr_body(plan: &CapabilityPublishPlan) -> String {
// Governing specs must be from the *registry* approved-spec set, not Traverse's.
// Declaring Traverse-only IDs (056/054/102) fails registry `spec-alignment`.
format!(
"## Summary\n\n- publish `{}` version `{}` to the public capability registry\n- add `{}`\n\n## Governing Spec\n\n- `001-registry-foundation`\n- `002-capability-validation`\n- `056-capability-publish`\n- `054-public-scope-registry-ref`\n- `102-contract-surface-coverage`\n\n## Project Item\n\n- Capability publish via traverse-cli\n\n## Validation\n\n- local capability contract validation passed\n- contract surface coverage (action enum ⊆ use_cases) passed\n- use_cases persona_ref resolution against registry personas passed\n- artifact digest computed: `{}`\n- release artifact: `{}`\n",
"## Summary\n\n- publish `{}` version `{}` to the public capability registry\n- add `{}`\n\n## Governing Spec\n\n- `001-registry-foundation`\n- `002-capability-validation`\n- `005-yank-deprecation`\n- `006-public-scope-and-identity`\n- `007-artifact-hosting`\n\n## Project Item\n\n- Capability publish via traverse-cli\n\n## Validation\n\n- local capability contract validation passed\n- contract surface coverage (action enum ⊆ use_cases) passed\n- use_cases persona_ref resolution against registry personas passed\n- artifact digest computed: `{}`\n- release artifact: `{}`\n",
plan.capability_id,
plan.version,
plan.registry_relative_path.display(),
Expand Down Expand Up @@ -6679,7 +6688,9 @@ mod tests {
assert!(commands.contains("gh release create artifacts/traverse-starter.process-1.0.0"));
assert!(commands.contains("git checkout -B publish/traverse-starter.process-1.0.0"));
assert!(commands.contains("gh pr create"));
assert!(commands.contains("056-capability-publish"));
assert!(commands.contains("001-registry-foundation"));
assert!(commands.contains("007-artifact-hosting"));
assert!(!commands.contains("056-capability-publish"));
assert_eq!(json["registry_repo"], "traverse-framework/registry");
assert!(commands.contains("--repo traverse-framework/registry"));
}
Expand Down
6 changes: 6 additions & 0 deletions examples/core-assign-ownership/DEV-JOURNAL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# core.assign-ownership — dev journal

- Source: Loop capability package v2 `core.assign-ownership@1.0.0`.
- Guest: `#![no_std]` resolver (id/email/name + fallback).
- Smoke: `bash scripts/ci/core_assign_ownership_example_smoke.sh`.
- Ticket: traverse-framework/traverse#1031.
22 changes: 22 additions & 0 deletions examples/core-assign-ownership/NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# core.assign-ownership

Third Loop package capability adapted for registry publication
([#1031](https://github.com/traverse-framework/traverse/issues/1031)).

Resolves a suggested owner (id / email / name) against workspace members with
configurable fallback (`creator` | `unassigned` | `fail`).

## Run

```bash
bash scripts/ci/core_assign_ownership_example_smoke.sh
```

## Coverage

| ID | Fixture | Expected |
|----|---------|----------|
| UC-01 | `uc01-name-match.json` | `ok` / `name_match` → `user-ada` |
| UC-02 | `uc02-email-match.json` | `ok` / `email_match` → `user-bob` |
| UC-03 | `uc03-null-fallback-creator.json` | `ok` / `fallback_creator` → `user-carol` |
| UC-04 | `uc04-unresolved-fail.json` | `unresolved` |
Binary file not shown.
42 changes: 42 additions & 0 deletions examples/core-assign-ownership/build-fixture.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bash

set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
artifact_dir="$script_dir/artifacts"
artifact_path="$artifact_dir/core-assign-ownership.wasm"
manifest_path="$script_dir/manifest.json"

mkdir -p "$artifact_dir"

rustup run "$(rustup show active-toolchain | awk '{print $1}')" rustc "$script_dir/src/agent.rs" \
--target wasm32-unknown-unknown --crate-type cdylib -O -C panic=abort -C strip=symbols \
--remap-path-prefix "$script_dir=/traverse-repo/agent" -o "$artifact_path"

digest="$(python3 - "$artifact_path" <<'PY'
import sys
from pathlib import Path

data = Path(sys.argv[1]).read_bytes()
h = 0xcbf29ce484222325
for b in data:
h ^= b
h = (h * 0x100000001b3) & 0xFFFFFFFFFFFFFFFF
print(f"fnv1a64:{h:016x}")
PY
)"

python3 - "$manifest_path" "$digest" <<'PY'
import json
import sys
from pathlib import Path

manifest = Path(sys.argv[1])
digest = sys.argv[2]
data = json.loads(manifest.read_text())
data.setdefault("binary", {})["expected_digest"] = digest
manifest.write_text(json.dumps(data, indent=2) + "\n")
print(f"updated {manifest}: binary.expected_digest={digest}")
PY

printf 'built %s\n' "$artifact_path"
Loading
Loading