Skip to content
Open
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
113 changes: 112 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@ on:
branches: ["**"]
pull_request:
workflow_dispatch:
inputs:
require_trinity_logs:
description: "Fail observability job when no Trinity session logs are discovered."
required: false
type: boolean
default: false
trinity_logs_glob:
description: "Optional additional recursive glob for Trinity session logs."
required: false
type: string
default: ""
require_eval_publish:
description: "Require external eval publish to succeed."
required: false
type: boolean
default: false
schedule:
- cron: "0 2 * * *" # daily drift audit (UTC)

Expand Down Expand Up @@ -65,10 +81,105 @@ jobs:
- name: Lint adversarial fixtures (same mechanism as fixtures)
run: python -m specdev_tools.cli fixtures-lint spec

trinity-observability:
name: Trinity Replay & Eval Dashboard
needs: validate
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
cache: "pip"
- name: Install tooling
run: pip install -e tools/
- name: Discover Trinity session logs
id: discover
env:
TRINITY_LOGS_GLOB: ${{ inputs.trinity_logs_glob }}
run: |
python - <<'PY'
import glob
import os
paths = set(glob.glob(".trinity/sessions/*.jsonl"))
paths.update(glob.glob("**/.trinity/sessions/*.jsonl", recursive=True))
extra = os.getenv("TRINITY_LOGS_GLOB", "").strip()
if extra:
paths.update(glob.glob(extra, recursive=True))
paths = sorted(paths)
os.makedirs(".trinity/eval", exist_ok=True)
with open(".trinity/eval/session_logs.txt", "w", encoding="utf-8") as f:
for p in paths:
f.write(p + "\n")
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as out:
out.write(f"count={len(paths)}\n")
print(f"Discovered {len(paths)} session logs")
PY
- name: Enforce logs for verification run
if: github.event_name == 'workflow_dispatch' && inputs.require_trinity_logs == true && steps.discover.outputs.count == '0'
run: |
echo "require_trinity_logs=true but no session logs were found." >&2
exit 1
- name: Build replay/export artifacts
if: steps.discover.outputs.count != '0'
run: |
while IFS= read -r log; do
[ -z "$log" ] && continue
base="$(basename "$log" .jsonl)"
rows_out=".trinity/eval/${base}_rows.jsonl"
replay_out=".trinity/eval/${base}_replay.json"
remediation_out=".trinity/eval/${base}_remediation.json"
python -m specdev_tools.cli trinity-export-eval "$log" --repo-root . --out "$rows_out"
python -m specdev_tools.cli trinity-replay "$log" --repo-root . --out "$replay_out"
python -m specdev_tools.cli trinity-remediate "$replay_out" --repo-root . --session-log "$log" --out "$remediation_out" --json > /dev/null
done < .trinity/eval/session_logs.txt
- name: Build dashboard summary
if: steps.discover.outputs.count != '0'
run: |
python -m specdev_tools.cli trinity-dashboard \
--rows-glob ".trinity/eval/*_rows.jsonl" \
--replay-glob ".trinity/eval/*_replay.json" \
--out-json ".trinity/eval/dashboard.json" \
--out-md ".trinity/eval/dashboard.md"
cat .trinity/eval/dashboard.md >> "$GITHUB_STEP_SUMMARY"
- name: Publish eval bundle (optional external sink)
if: steps.discover.outputs.count != '0'
env:
TRINITY_EVAL_EXPORT_ENDPOINT: ${{ secrets.TRINITY_EVAL_EXPORT_ENDPOINT }}
TRINITY_EVAL_EXPORT_TOKEN: ${{ secrets.TRINITY_EVAL_EXPORT_TOKEN }}
run: |
REQUIRE_PUBLISH=""
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ inputs.require_eval_publish }}" = "true" ]; then
REQUIRE_PUBLISH="--require-publish"
fi
python -m specdev_tools.cli trinity-publish-eval \
--rows-glob ".trinity/eval/*_rows.jsonl" \
--replay-glob ".trinity/eval/*_replay.json" \
--dashboard-json ".trinity/eval/dashboard.json" \
--out ".trinity/eval/export_bundle.json" \
--endpoint-env "TRINITY_EVAL_EXPORT_ENDPOINT" \
--auth-token-env "TRINITY_EVAL_EXPORT_TOKEN" \
--source "github-actions:${GITHUB_REPOSITORY}:${GITHUB_RUN_ID}" \
${REQUIRE_PUBLISH}
- name: No logs summary
if: steps.discover.outputs.count == '0'
run: |
echo "## Trinity Eval Dashboard" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "- No session logs found in this run." >> "$GITHUB_STEP_SUMMARY"
- name: Upload Trinity observability artifacts
uses: actions/upload-artifact@v4
with:
name: trinity-observability
path: .trinity/eval/
if-no-files-found: warn

deploy-staging:
name: Deploy Staging (placeholder)
if: ${{ github.ref == 'refs/heads/main' }}
needs: redteam
needs: [redteam, trinity-observability]
runs-on: ubuntu-latest
steps:
- run: echo "Deploy to staging goes here (wire your real deploy step)."
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ devspec_env/
.vscode/
.idea/
.DS_Store

# Trinity runtime
.trinity/
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ All detailed version records are stored in the [`changelog/`](./changelog/) dire

| Version | Release Date | Documentation | Migration Spec | Status |
| :--- | :--- | :--- | :--- | :--- |
| **[0.3.0]** | 2026-02-14 | [v0.3.0.md](changelog/v0.3.0.md) | [v0.3.0.yaml](changelog/v0.3.0.yaml) | ⚠️ **Breaking** (Spec Optimization + Prompt Refactor) |
| **[0.2.3]** | 2026-02-12 | [v0.2.3.md](changelog/v0.2.3.md) | [v0.2.3.yaml](changelog/v0.2.3.yaml) | ⚠️ **Breaking** |
| **[0.2.2]** | 2026-02-12 | [v0.2.2.md](changelog/v0.2.2.md) | [v0.2.2.yaml](changelog/v0.2.2.yaml) | ✅ Patch |
| **[0.2.1]** | 2026-02-07 | [v0.2.1.md](changelog/v0.2.1.md) | [v0.2.1.yaml](changelog/v0.2.1.yaml) | ⚠️ **Breaking** |
| **[0.2.0]** | 2026-01-17 | [v0.2.0.md](changelog/v0.2.0.md) | [v0.2.0.yaml](changelog/v0.2.0.yaml) | ⚠️ **Breaking** (Schema Hardening) |
| **[0.1.1]** | 2026-01-13 | [v0.1.1.md](changelog/v0.1.1.md) | [v0.1.1.yaml](changelog/v0.1.1.yaml) | ✅ Patch (Fixes) |
Expand Down
27 changes: 27 additions & 0 deletions changelog/v0.2.3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# v0.2.3 - 2026-02-12

### Added
- Step 16 schema now requires all core plan sections: `summary`, `docs_impact`, `spec_alignment`, and `review_requirements`.
- Structured reviewer delivery verification fields:
- `review.delivery_status.dashboards_verified[]`
- `review.delivery_status.alerts_verified[]`

### Changed
- If `plan.delivery.status == planned`, reviewer output must include delivery verification entries.
- Step 16 deep validator now enforces planned dashboard/alert mapping to matching verified entries.
- Step 16 prompts were aligned:
- Planner prompt schema guidance includes required `docs_impact`.
- Reviewer prompt guidance uses `dashboards_verified` / `alerts_verified` and planned-delivery gate rule.
- Anchor prompt quick reference now marks `plan.review_requirements` as required.
- Developer workflow docs now reflect required Step 16 plan sections and structured delivery verification evidence.

### Testing
- Added failing fixtures for missing required plan sections.
- Added valid/invalid fixtures for planned delivery verification behavior.
- Added integration tests for new Step 16 schema and validator expectations.

### Breaking
- Existing Step 16 artifacts that omit any required plan section will fail validation.
- Existing Step 16 artifacts with `plan.delivery.status == planned` but missing reviewer verification evidence will fail validation.

[0.2.3]: https://github.com/vichitracollective/devspec_toolkit/releases/tag/v0.2.3
56 changes: 56 additions & 0 deletions changelog/v0.2.3.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
version: "0.2.3"
release_date: "2026-02-12"
breaking: true
description: |
Hardens Step 16 plan requirements, adds structured delivery verification fields
for reviewer artifacts, and aligns validator/test/prompt behavior with the new contract.

changes:
- type: add_constraint
step_id: "16_impl_context"
path: "plan.required"
description: "Step 16 plan now requires summary, docs_impact, spec_alignment, and review_requirements."
migration:
action: ai_assisted
prompt: template_add_required_fields.md

- type: add_field
step_id: "16_impl_context"
path: "review.delivery_status.dashboards_verified[]"
required: false
migration:
action: auto
operations:
- add_field

- type: add_field
step_id: "16_impl_context"
path: "review.delivery_status.alerts_verified[]"
required: false
migration:
action: auto
operations:
- add_field

- type: add_constraint
step_id: "16_impl_context"
path: "plan.delivery.status=planned -> review.delivery_status"
description: "If plan.delivery.status is planned, review.delivery_status must include at least one verification entry."
migration:
action: ai_assisted
prompt: template_add_field.md

- type: add_constraint
step_id: "16_impl_context"
path: "plan.delivery.(dashboards|alerts) -> review.delivery_status.(dashboards_verified|alerts_verified)"
description: "Planned dashboard/alert items must have matching verified entries in reviewer output."
migration:
action: ai_assisted
prompt: template_add_field.md

- type: add_constraint
step_id: "16_impl_context"
path: "prompts/16a,16c + validators/step_16 + tests/fixtures/step_16"
description: "Prompts, deep validator, and integration fixtures/tests are aligned with the new schema constraints."
migration:
action: auto
16 changes: 16 additions & 0 deletions changelog/v0.3.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# v0.3.0 (2026-02-14)

## Trinity Spec Optimization & Disk-Only Prompts

This release focuses on optimizing the Trinity Specification for better token efficiency and refactoring all prompts to enforce "disk-only" artifact creation, removing older "fenced code block" output styles.

### Optimized
- **Trinity Specification**: Refactored `trinity_spec.md` to reduce token count while maintaining all normative rules. Replaced inline JSON with schema references.
- **Project Charter**: Updated `project_charter-trinity.json` structure.

### Changed
- **Prompts**: Refactored `00_project_charter.md` through `06_invariants.md` (and others) to strictly instruct Agents to write artifacts to disk using tools, rather than outputting markdown code blocks.
- **Workflow**: Agents now operate in a more autonomous "disk-first" mode.

### Fixed
- **Schema Validation**: Various schema fixes in `spec` files to align with the new stricter validation rules.
14 changes: 14 additions & 0 deletions changelog/v0.3.0.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: "0.3.0"
release_date: "2026-02-14"
changes:
- type: usage_update
step_id: "all"
description: "Prompts now enforce disk-only artifact creation. Agents should not expect or generate fenced code blocks for artifacts."
migration:
action: manual
details: "Ensure any custom agent workflows are updated to look for files on disk instead of parsing chat output."
- type: optimization
step_id: "trinity_spec"
description: "Trinity Spec refactored for token efficiency (approx 30% reduction)."
migration:
action: auto
10 changes: 6 additions & 4 deletions docs/agents/agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ This toolkit uses a two‑phase interaction to maximize completeness without har
- Stop and wait for human answers.
4. **Phase B — Emit**
- Once answers resolve gating items, run the same prompt to generate the artifact.
- Output exactly one fenced `json` code block that validates against the embedded schema; no extra prose.
- Write or update the artifact JSON file at the expected `spec/...` path.
- Return only a concise confirmation with artifact path and validation status (no fenced JSON).
- Populate `seed_refs` with the seeds actually used.
5. **Persist Artifact**
- Replace the contents of `spec/NN_name.json` with the generated block.
- Ensure `spec/NN_name.json` was written with the generated content.
- Preserve the `$schema` field already present in the file.
6. **Validate**
- Run the [core validation commands](../developers/reference.md#core-validation-commands) and inspect results.
Expand All @@ -58,7 +59,7 @@ This toolkit uses a two‑phase interaction to maximize completeness without har
| 13a | `spec/13a_completeness_assessment.json` | Check for gaps before Roadmap |
| 14 | `spec/14_roadmap.json` | Initiate JIT implementation loop |
| 15 | `spec/15_scaffold.json` | Implement scaffold manually |
| 16a | `spec/impl_context/{step_id}.json` | Trinity Plan: Tasks, Security, Delivery, Drift |
| 16a | `spec/impl_context/{step_id}.json` | Trinity Plan: Checklist, Security, Delivery, Drift |
| 16b | `spec/impl_context/{step_id}.json` | Trinity Build: Code, Configs, Docs |
| 16c | `spec/impl_context/{step_id}.json` | Trinity Review: Verification & closure |

Expand All @@ -79,14 +80,15 @@ When reporting back to humans, include:
2. Commands executed and whether they succeeded.
3. Outstanding issues or reasons for escalation.

During Phase A (Clarify), output only a bulleted list of questions grouped by topic. During Phase B (Emit), output only the single fenced `json` block.
During Phase A (Clarify), output only a bulleted list of questions grouped by topic. During Phase B (Emit), write the artifact to disk and output only a concise confirmation (no fenced JSON).

## 8. Runner Tips
- Treat prompts as the contract; do not modify them at runtime.
- Honor `interaction_mode` and `phase_triggers` from the manifest; switch phases only when conditions are met.
- Read only the paths listed in the prompt’s “Context To Ingest” for that step; avoid external sources.
- Build private ledgers in memory only; never persist them or include them in outputs.
- In Phase A, emit only grouped, concise questions; never include JSON, code fences, or speculative answers.
- In Phase B, treat the filesystem artifact as the source of truth and return concise status text only; do not paste artifact JSON in chat.
- Stop generation when the self‑audit gate is not met; wait for human input rather than guessing.
- Prefer deterministic decoding to keep outputs stable across retries.
- De‑duplicate questions and prioritize gating items that block emission.
Expand Down
12 changes: 7 additions & 5 deletions docs/agents/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
"emit": {
"purpose": "Generate the canonical JSON artifact.",
"output_contract": {
"type": "json_artifact",
"fenced_code_block": true,
"language": "json",
"type": "disk_artifact_status",
"fenced_code_block": false,
"language": "none",
"restrictions": [
"Exactly one fenced json block"
"Write artifact to disk first",
"Return concise status only",
"Do not emit fenced JSON"
]
}
}
Expand Down Expand Up @@ -77,4 +79,4 @@
]
}
]
}
}
Loading
Loading