Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ sidebar:
---

> [!CAUTION]
> **Deprecated.** The Effective Tokens (ET) metric is deprecated and is superseded by **AI Credits (AIC)**. AIC is a direct monetary metric (1 AIC = $0.01 USD) derived from actual provider pricing and provides a more actionable measure of inference cost. Effective Tokens remain available in `gh aw logs` and `gh aw audit` output for backward compatibility, but AIC is now the preferred metric for monitoring and budgeting. See [Cost Management](/gh-aw/reference/cost-management/) for AIC usage examples.
> **Deprecated.** The Effective Tokens (ET) metric is deprecated and is superseded by **AI Credits (AIC)**. AIC is a direct monetary metric (1 AIC = $0.01 USD) derived from actual provider pricing and provides a more actionable measure of inference cost. Effective Tokens remain available in `gh aw logs` and `gh aw audit` output for backward compatibility, but AIC is now the preferred metric for monitoring and budgeting. See [Cost Management](/gh-aw/reference/cost-management/) for AIC usage examples. Migration path: [AI Credits Specification](/gh-aw/specs/ai-credits-specification/).

---

Expand Down
10 changes: 8 additions & 2 deletions docs/src/content/docs/specs/forecast-specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,7 @@ This section maps normative forecast requirements to implementation files.
| Monte Carlo engine (Poisson/Bootstrap/Bernoulli) | `pkg/cli/forecast_montecarlo.go` |
| Forecast command orchestration and output fields | `pkg/cli/forecast.go`, `pkg/cli/forecast_command.go` |
| Workflow discovery, rate-limit backoff, and run sampling | `pkg/cli/forecast.go` |
| §10.7 Safeguards and Appendix F cross-reference | `pkg/cli/forecast.go`, `pkg/cli/forecast_render.go` |
| Forecast compliance tests (including rate-limit backoff and λ thresholds) | `pkg/cli/forecast_montecarlo_test.go` |

Sync procedure:
Expand All @@ -1049,8 +1050,13 @@ Sync procedure:

Sync follow-up tasks:

- **[Open]** Add and verify explicit AIC-primary / ET-legacy migration assertions for forecast
reporting paths so that ET-facing surfaces remain compatibility-only where applicable.
- **[Resolved 2026-07-07]** Added explicit AIC-primary / ET-legacy migration assertions for
forecast reporting paths. For `pkg/cli/forecast.go` output wiring, AIC-primary fields are:
`avg_aic`, `p50_aic_per_run`, `p95_aic_per_run`, `projected_aic`, `weekly_projected_aic`,
`monthly_projected_aic`, `actual_aic`, and Monte Carlo summary fields ending in
`_projected_aic`. ET-legacy compatibility-only status: no ET-named forecast output fields are
emitted by `gh aw forecast`; ET remains legacy compatibility surface in `gh aw logs`/`gh aw audit`.
Tracking: [#44083](https://github.com/github/gh-aw/issues/44083).
- **[Open]** Track promotion-gate evidence until three confirmed production runs are documented in
the Promotion Tracking table (§Status of This Document, criterion 1).
- **[Open]** Close the forecast compliance-test gap for promotion criterion 3 by recording sustained
Expand Down
11 changes: 11 additions & 0 deletions docs/src/content/docs/specs/frontmatter-hash-specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,17 @@ those prerequisites are met and the migration milestone is approved.
**Sync verification (2026-05-12)**: SPDD review reconfirmed that the 2026-05-08 text-based
resolution remains in force.

### Deferral acceptance criteria (Section 2 / v2.0.0)

Section 2 ("Field Selection") remains deferred pending completion of
[#31983](https://github.com/github/gh-aw/issues/31983). Reviewers SHOULD use this subsection as
the canonical acceptance checklist during Sync Notes review (without requiring issue-context lookup).

- [ ] Confirm and document a selective field-exclusion use case in [#31983](https://github.com/github/gh-aw/issues/31983).
- [ ] Draft a migration guide in [#31983](https://github.com/github/gh-aw/issues/31983), including lock-file invalidation and recompilation steps.
- [ ] Write candidate v2.0.0 cross-language test vectors in [#31983](https://github.com/github/gh-aw/issues/31983) and verify they pass in CI.
- [ ] Approve a rollout plan in [#31983](https://github.com/github/gh-aw/issues/31983), including backward-compatibility impact analysis.

**S-6 sync verification (2026-05-28)**: The 1 MiB cumulative input-size guard (S-6) is confirmed
implemented in `pkg/parser/frontmatter_hash.go` via `validateFrontmatterHashInputSize`. The function
accumulates normalized byte lengths across the main and all imported frontmatter texts and returns a
Expand Down
3 changes: 2 additions & 1 deletion docs/src/content/docs/specs/mcp-scripts-specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -1638,6 +1638,7 @@ and run `go test ./pkg/workflow/...` to verify conformance.
| §9 | Integration with MCP Gateway | `pkg/workflow/mcp_scripts_renderer.go` (`renderMCPScriptsMCPConfigWithOptions`), `pkg/workflow/mcp_scripts_generator.go` (`GenerateMCPScriptsMCPServerScript`, `GenerateMCPScriptsToolsConfig`) |
| §10 | Safeguards | `pkg/workflow/mcp_scripts_renderer.go`, `pkg/workflow/mcp_scripts_generator.go`, `actions/setup/js/mcp_scripts_mcp_server_http.cjs` |
| §11 | Norms | `pkg/workflow/mcp_scripts_renderer.go`, `pkg/workflow/mcp_scripts_parser.go` |
| §12.1.4 / T-MCP-051 | Secret-scope isolation conformance (SN-SCOPE-01..04) | `pkg/workflow/mcp_scripts_renderer_test.go` (`TestMCPScriptsScopeConformance`) — **[Open]** |

Sync follow-up tasks:

Expand Down Expand Up @@ -1694,7 +1695,7 @@ Sync follow-up tasks:
### Go Sandbox Constraints for `go` Language Tools

When `implementation: go` is specified, the tool executes inside a containerized Go
sandbox with the following constraints:
sandbox with the following constraints (see also §10 Safeguards for normative controls):

- **Network access**: No outbound network calls are permitted from within the Go tool sandbox
unless the workflow's `network.allowed` list explicitly includes the target host. The
Expand Down
32 changes: 32 additions & 0 deletions pkg/parser/schedule_fuzzy_scatter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -880,3 +880,35 @@ func TestScatterScheduleUsesPreferredWindows(t *testing.T) {
}
}
}

func TestWeightedDailyTimeSlotBestTierFrequency(t *testing.T) {
const sampleSize = 50000

var bestTotal, okTotal int

for i := range sampleSize {
identifier := fmt.Sprintf("scope-check-workflow-%05d", i)
hour, _ := weightedDailyTimeSlot(identifier)

if hour >= 2 && hour <= 5 {
bestTotal++
}
if hour >= 19 && hour <= 23 {
okTotal++
}
}

if okTotal == 0 {
t.Fatalf("unexpected zero OK-tier samples in weighted scatter distribution")
}

bestPerHour := float64(bestTotal) / 4.0 // BEST hours: 02-05
okPerHour := float64(okTotal) / 5.0 // OK hours: 19-23
ratio := bestPerHour / okPerHour

// The weighted pool gives each BEST hour weight 3 versus weight 1 for each OK hour.
// Allow tolerance for deterministic hash-modulo skew while preserving the intended 3x shape.
if ratio < 2.7 {
t.Fatalf("expected BEST-hour frequency to be near 3x OK-hour frequency, got ratio=%.3f (best_total=%d ok_total=%d)", ratio, bestTotal, okTotal)
}
Comment on lines +901 to +913
}
65 changes: 65 additions & 0 deletions pkg/workflow/mcp_scripts_renderer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
package workflow

import (
"encoding/json"
"strings"
"testing"
)

Expand Down Expand Up @@ -82,3 +84,66 @@ func TestCollectMCPScriptsSecretsStability(t *testing.T) {
}
}
}

func TestMCPScriptsScopeConformance(t *testing.T) {
config := &MCPScriptsConfig{
Tools: map[string]*MCPScriptToolConfig{
"alpha-tool": {
Name: "alpha-tool",
Env: map[string]string{
"ALPHA_ONLY": "${{ secrets.ALPHA_ONLY }}",
"SHARED_SECRET": "${{ secrets.SHARED_SECRET }}",
},
},
"beta-tool": {
Name: "beta-tool",
Env: map[string]string{
"BETA_ONLY": "${{ secrets.BETA_ONLY }}",
"SHARED_SECRET": "${{ secrets.SHARED_SECRET }}",
},
},
},
}

toolsJSON := GenerateMCPScriptsToolsConfig(config)
if strings.Contains(toolsJSON, "secrets.ALPHA_ONLY") ||
strings.Contains(toolsJSON, "secrets.BETA_ONLY") ||
strings.Contains(toolsJSON, "secrets.SHARED_SECRET") {
t.Fatalf("tools.json must not contain secret expressions: %s", toolsJSON)
}

var rendered MCPScriptsConfigJSON
if err := json.Unmarshal([]byte(toolsJSON), &rendered); err != nil {
t.Fatalf("failed to parse tools.json: %v", err)
}

var alphaEnv, betaEnv map[string]string
for _, tool := range rendered.Tools {
switch tool.Name {
case "alpha-tool":
alphaEnv = tool.Env
case "beta-tool":
betaEnv = tool.Env
}
}

if alphaEnv == nil || betaEnv == nil {
t.Fatalf("expected both alpha-tool and beta-tool in tools.json: %+v", rendered.Tools)
}

// SN-SCOPE-01/03: per-tool secret bindings are explicit and isolated in tools.json.
if alphaEnv["ALPHA_ONLY"] != "ALPHA_ONLY" || alphaEnv["SHARED_SECRET"] != "SHARED_SECRET" {
t.Fatalf("alpha-tool env bindings are incorrect: %+v", alphaEnv)
}
if betaEnv["BETA_ONLY"] != "BETA_ONLY" || betaEnv["SHARED_SECRET"] != "SHARED_SECRET" {
t.Fatalf("beta-tool env bindings are incorrect: %+v", betaEnv)
}

// SN-SCOPE-02: tool-specific bindings do not include other tool-only secrets.
if _, exists := alphaEnv["BETA_ONLY"]; exists {
t.Fatalf("alpha-tool env must not include beta-tool secret binding: %+v", alphaEnv)
}
if _, exists := betaEnv["ALPHA_ONLY"]; exists {
t.Fatalf("beta-tool env must not include alpha-tool secret binding: %+v", betaEnv)
}
}