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
18 changes: 18 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,24 @@ jobs:
chmod +x ci/e2e-onboarding-flows.sh
ci/e2e-onboarding-flows.sh

e2e-custom-routing:
name: E2E Custom Routing Contract (8 cells)
runs-on: ubuntu-latest
timeout-minutes: 5
# PR 5 of the 2026-05-10 architecture audit. Locks the
# phase_context routing contract: trust strict/normal,
# upstream_required vs optional, max_age_days override, solution
# tags, diarization paths/keywords. Backward compat: custom phases
# without phase_context keep the dependency-only behavior.
steps:
- uses: actions/checkout@v4
- name: jq is present
run: jq --version
- name: Run custom routing E2E
run: |
chmod +x ci/e2e-custom-routing.sh
ci/e2e-custom-routing.sh

e2e-graph-aware-session:
name: E2E Graph-aware Session + Next-step (10 cells)
runs-on: ubuntu-latest
Expand Down
37 changes: 37 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3366,6 +3366,43 @@ jobs:
fi
echo "OK: guard concurrency tier uses the phase registry."

custom-routing-contract:
name: Custom routing contract wired into resolve.sh
runs-on: ubuntu-latest
# PR 5 of the 2026-05-10 architecture audit. Locks that bin/resolve.sh
# reads phase_context from config and emits the routing block.
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- name: resolve.sh reads phase_context and emits routing
run: |
set -e
script=bin/resolve.sh
if ! grep -qF 'phase_context' "$script"; then
echo "FAIL: $script does not read phase_context from config."
exit 1
fi
if ! grep -qE '^\s*routing:' "$script"; then
echo "FAIL: $script does not emit a routing block in its JSON output."
exit 1
fi
for field in routing_trust routing_required routing_optional routing_max_age routing_solution_tags routing_solution_limit routing_diarization_paths routing_diarization_keywords; do
if ! grep -qF "$field" "$script"; then
echo "FAIL: $script does not surface $field."
exit 1
fi
done
echo "OK: custom routing contract wired into resolve.sh"
- name: Contract documented in reference/custom-stack-contract.md
run: |
set -e
if ! grep -qF 'phase_context' reference/custom-stack-contract.md; then
echo "FAIL: reference/custom-stack-contract.md does not document phase_context."
exit 1
fi
echo "OK: phase_context documented in the contract reference"

session-graph-aware-wiring:
name: session.sh + next-step.sh route through the phase registry
runs-on: ubuntu-latest
Expand Down
2 changes: 2 additions & 0 deletions EXTENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ Add your own skills that plug into Nanostack's workflow. Your skills save artifa
> ```
>
> The stack manifest schema, the directory contract any new stack must satisfy, and the runtime guarantees the framework gives a stack are documented in [`reference/custom-stack-examples-technical-spec.md`](reference/custom-stack-examples-technical-spec.md). The 15-cell runtime end-to-end harness for the example stack is at [`ci/e2e-custom-stack-examples.sh`](ci/e2e-custom-stack-examples.sh) (51 assertions).
>
> **Routing the context your skill needs.** A custom skill can declare a `phase_context` block in `.nanostack/config.json` so the resolver loads what the skill actually needs: strict integrity trust, required vs optional upstreams, per-phase age windows, tagged solutions from `know-how/solutions`, and diarizations filtered by path or keyword. The full contract lives in [`reference/custom-stack-contract.md`](reference/custom-stack-contract.md) under "Custom routing contract". Custom skills without a `phase_context` entry keep the dependency-only behavior, so the feature is opt-in.

## Configure your stack

Expand Down
Loading
Loading