Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d33aecc
Add scrum-master scenario: Scrum Master autopilot using Node.js SDK
keshavk-msft Jul 23, 2026
feb98d9
Add Jira sample-data seed script + SharePoint schema doc
keshavk-msft Jul 23, 2026
1c5a4af
Rewrite README: intro-features-prereqs-setup structure
keshavk-msft Jul 24, 2026
251de83
Add observability + docs polish (safe additions only)
keshavk-msft Jul 24, 2026
ca578fa
Address Copilot review feedback on PR #334
keshavk-msft Jul 24, 2026
aa27069
Add m365-visitor-stats tracking pixel to README
keshavk-msft Jul 27, 2026
ff11662
Harden calendar tool: detect garbage LLM output shape
keshavk-msft Jul 29, 2026
2335201
Wire A365 observability + address open review comments
keshavk-msft Aug 10, 2026
5e8a957
Complete observability instrumentation + fix Task-N label mapping
keshavk-msft Aug 11, 2026
0c5b4a7
Resolve remaining Copilot review comments
keshavk-msft Aug 25, 2026
812c25d
Fix scrum-master build scope and document fresh setup troubleshooting
keshavk-msft Oct 22, 2026
94afea8
Fix scrum-master PR review feedback
keshavk-msft Oct 29, 2026
69bc367
Upgrade scrum-master to patched Zod and compatible OpenAI SDKs
keshavk-msft Oct 29, 2026
a371dc1
Address latest Scrum Master review feedback
keshavk-msft Nov 1, 2026
08a7d3d
Merge current upstream main into Scrum Master PR
keshavk-msft Nov 1, 2026
38160d3
Fix Linux scenario tests and vulnerable hosting MSAL
keshavk-msft Nov 1, 2026
f0d35a6
Patch OpenTelemetry and make Node 22 compatibility tests independent
keshavk-msft Nov 1, 2026
e9d68a5
Patch Jaeger propagator and verify safe header handling
keshavk-msft Nov 1, 2026
98cbda7
Document conversation isolation and project-scoped Jira reads
keshavk-msft Nov 1, 2026
247229a
Use verified upstream redirect security release
keshavk-msft Nov 1, 2026
7bfb010
Fix standup lifecycle review feedback and patch protobuf runtime
keshavk-msft Nov 2, 2026
9034de4
Align protobuf lockfile placement with Node 22 npm
keshavk-msft Nov 2, 2026
f472fd7
Use patched Zod across hosting and activity validation
keshavk-msft Nov 2, 2026
621135e
Complete verified standup and report review requirements
keshavk-msft Nov 2, 2026
946e39e
Make older-review regression loader portable on Linux
keshavk-msft Nov 2, 2026
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
34 changes: 34 additions & 0 deletions .github/workflows/ci-nodejs-scrum-master.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

name: CI - Scrum Master Scenario

on:
workflow_call:
workflow_dispatch:

permissions:
contents: read

jobs:
scrum-master:
name: Scrum Master (Node 22)
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./scenarios/scrum-master
steps:
- name: Checkout repository
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- name: Set up Node.js 22
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '22'
cache: npm
cache-dependency-path: scenarios/scrum-master/package-lock.json
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Test
run: npm test
192 changes: 95 additions & 97 deletions .github/workflows/ci-orchestrator.yml
Original file line number Diff line number Diff line change
@@ -1,97 +1,95 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

name: CI Orchestrator

on:
push:
branches: [main, master]
pull_request:
branches: [main, master]

permissions:
contents: read

jobs:
# .NET Jobs - Call existing workflows
dotnet-agentframework:
name: .NET Agent Framework
uses: ./.github/workflows/ci-dotnet-agentframework-sampleagent.yml

dotnet-semantickernel:
name: .NET Semantic Kernel
uses: ./.github/workflows/ci-dotnet-semantickernel-sampleagent.yml

# Node.js Jobs - Call existing workflows
nodejs-claude:
name: Node.js Claude
uses: ./.github/workflows/ci-nodejs-claude-sampleagent.yml

nodejs-langchain:
name: Node.js LangChain
uses: ./.github/workflows/ci-nodejs-langchain-sampleagent.yml

nodejs-openai:
name: Node.js OpenAI
uses: ./.github/workflows/ci-nodejs-openai-sampleagent.yml

nodejs-vercelsdk:
name: Node.js Vercel SDK
uses: ./.github/workflows/ci-nodejs-vercelsdk-sampleagent.yml

# Python Jobs - Call existing workflows
python-agentframework:
name: Python Agent Framework
uses: ./.github/workflows/ci-python-agentframework-sampleagent.yml

python-googleadk:
name: Python Google ADK
uses: ./.github/workflows/ci-python-googleadk-sampleagent.yml

python-openai:
name: Python OpenAI
uses: ./.github/workflows/ci-python-openai-sampleagent.yml

python-claude:
name: Python Claude
uses: ./.github/workflows/python-claude-sample.yml

observability:
name: Observability Offline Tests
uses: ./.github/workflows/ci-observability.yml

# Final status check - ALWAYS runs and reports success
# This is the ONLY check you need to mark as "Required" in branch protection
ci-status:
name: CI Status
runs-on: ubuntu-latest
needs:
- dotnet-agentframework
- dotnet-semantickernel
- nodejs-claude
- nodejs-langchain
- nodejs-openai
- nodejs-vercelsdk
- python-agentframework
- python-googleadk
- python-openai
- python-claude
- observability
if: always()
steps:
- name: Check CI Status
run: |
echo "Checking CI job results..."

# Get all job results (skipped jobs are fine, failed jobs are not)
results="${{ needs.dotnet-agentframework.result }} ${{ needs.dotnet-semantickernel.result }} ${{ needs.nodejs-claude.result }} ${{ needs.nodejs-langchain.result }} ${{ needs.nodejs-openai.result }} ${{ needs.nodejs-vercelsdk.result }} ${{ needs.python-agentframework.result }} ${{ needs.python-googleadk.result }} ${{ needs.python-openai.result }} ${{ needs.python-claude.result }} ${{ needs.observability.result }}"

echo "Job results: $results"

# Check if any job failed or was cancelled
if echo "$results" | grep -qE "failure|cancelled"; then
echo "❌ One or more CI jobs failed or were cancelled"
exit 1
fi

echo "✅ All CI jobs passed"
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

name: CI Orchestrator

on:
push:
branches: [main, master]
pull_request:
branches: [main, master]

permissions:
contents: read

jobs:
# .NET Jobs - Call existing workflows
dotnet-agentframework:
name: .NET Agent Framework
uses: ./.github/workflows/ci-dotnet-agentframework-sampleagent.yml

dotnet-semantickernel:
name: .NET Semantic Kernel
uses: ./.github/workflows/ci-dotnet-semantickernel-sampleagent.yml

# Node.js Jobs - Call existing workflows
nodejs-claude:
name: Node.js Claude
uses: ./.github/workflows/ci-nodejs-claude-sampleagent.yml

nodejs-langchain:
name: Node.js LangChain
uses: ./.github/workflows/ci-nodejs-langchain-sampleagent.yml

nodejs-openai:
name: Node.js OpenAI
uses: ./.github/workflows/ci-nodejs-openai-sampleagent.yml

nodejs-vercelsdk:
name: Node.js Vercel SDK
uses: ./.github/workflows/ci-nodejs-vercelsdk-sampleagent.yml

nodejs-scrum-master:
name: Node.js Scrum Master
uses: ./.github/workflows/ci-nodejs-scrum-master.yml

# Python Jobs - Call existing workflows
python-agentframework:
name: Python Agent Framework
uses: ./.github/workflows/ci-python-agentframework-sampleagent.yml

python-googleadk:
name: Python Google ADK
uses: ./.github/workflows/ci-python-googleadk-sampleagent.yml

python-openai:
name: Python OpenAI
uses: ./.github/workflows/ci-python-openai-sampleagent.yml

python-claude:
name: Python Claude
uses: ./.github/workflows/python-claude-sample.yml

observability:
name: Observability Offline Tests
uses: ./.github/workflows/ci-observability.yml

# This aggregate check is required in branch protection.
ci-status:
name: CI Status
runs-on: ubuntu-latest
needs:
- dotnet-agentframework
- dotnet-semantickernel
- nodejs-claude
- nodejs-langchain
- nodejs-openai
- nodejs-vercelsdk
- nodejs-scrum-master
- python-agentframework
- python-googleadk
- python-openai
- python-claude
- observability
if: always()
steps:
- name: Check CI Status
run: |
echo "Checking CI job results..."
results="${{ needs.dotnet-agentframework.result }} ${{ needs.dotnet-semantickernel.result }} ${{ needs.nodejs-claude.result }} ${{ needs.nodejs-langchain.result }} ${{ needs.nodejs-openai.result }} ${{ needs.nodejs-vercelsdk.result }} ${{ needs.nodejs-scrum-master.result }} ${{ needs.python-agentframework.result }} ${{ needs.python-googleadk.result }} ${{ needs.python-openai.result }} ${{ needs.python-claude.result }} ${{ needs.observability.result }}"
echo "Job results: $results"
if echo "$results" | grep -qE "failure|cancelled"; then
echo "❌ One or more CI jobs failed or were cancelled"
exit 1
fi
echo "✅ All CI jobs passed"
109 changes: 109 additions & 0 deletions scenarios/scrum-master/.env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# OpenAI Configuration
# Use EITHER standard OpenAI OR Azure OpenAI (not both)

# Option 1: Standard OpenAI API
OPENAI_API_KEY=
OPENAI_MODEL=gpt-4o

# Option 2: Azure OpenAI (takes precedence if AZURE_OPENAI_API_KEY is set)
AZURE_OPENAI_API_KEY=
AZURE_OPENAI_ENDPOINT=
AZURE_OPENAI_DEPLOYMENT=
AZURE_OPENAI_API_VERSION=2024-10-21

# MCP Tooling Configuration
BEARER_TOKEN=

# Enable to use observability exporter, default is false which means using console exporter.
# MUST be true in any deployed/dev-tunnel environment or MAC Activity stays empty.
ENABLE_A365_OBSERVABILITY_EXPORTER=false
# Use by the sample to demo using custom token resolver and token cache when it is true, otherwise use the built-in AgenticTokenCache
Use_Custom_Resolver=true
# optional - set to enable observability logs, value can be 'info', 'warn', or 'error', default to 'none' if not set
A365_OBSERVABILITY_LOG_LEVEL=
# Uncomment together with A365_OBSERVABILITY_LOG_LEVEL to debug export failures.
# OTEL_LOG_LEVEL=INFO

# --- A365 observability identity ---
# Runtime agent identity (the AGENTIC INSTANCE, not the blueprint). Normally
# populated automatically from activity.recipient.agenticAppId. Set explicitly
# only if you invoke the observability helpers outside the standard A365
# hosting flow (e.g. a stand-alone script). See src/observability.ts.
agent365Observability__agentInstanceId=

# Environment Settings
NODE_ENV=development # Retrieve mcp servers from ToolingManifest
HOST=127.0.0.1 # Agents Playground connects to 127.0.0.1; set this so the server binds to the same address

# Telemetry and Tracing Configuration
DEBUG=agents:*

# --- Scenario-level logging (this sample only) -------------------------------
# Level-based logger in src/util/logger.ts.
# LOG_LEVEL: error | warn | info | debug | trace (default=info)
# LOG_HTTP: when 'true', traces instrumented axios requests (including Jira)
# with status + latency. Not Graph/fetch or MCP transport tracing.
# Credentials are redacted. Keep false in production.
LOG_LEVEL=info
LOG_HTTP=false

# Use Agentic Authentication rather than OBO
USE_AGENTIC_AUTH=false

# Service Connection Settings
connections__service_connection__settings__clientId=
connections__service_connection__settings__clientSecret=
connections__service_connection__settings__tenantId=

# Set service connection as default
connectionsMap__0__serviceUrl=*
connectionsMap__0__connection=service_connection

# AgenticAuthentication Options
agentic_type=agentic
agentic_altBlueprintConnectionName=service_connection
agentic_scopes=ea9ffc3e-8a23-4a7d-836d-234d7c7565c1/.default # Prod Agentic scope

# =============================================================================
# Scrum Master Assistant POC configuration (added on top of the base sample)
# =============================================================================

# --- Jira (Atlassian Cloud) ---
# Set JIRA_MODE=mock to run against the built-in mock sprint (no Atlassian creds needed).
JIRA_MODE=mock # live | mock
JIRA_BASE_URL=https://your-org.atlassian.net
JIRA_EMAIL=
JIRA_API_TOKEN=
JIRA_PROJECT_KEY=SCRUM # mock board key; replace for live Jira
JIRA_BOARD_ID=1

# --- SharePoint (Microsoft Graph, delegated) ---
# Site URL of the site that will host the SMA_* lists + SprintReports library.
SHAREPOINT_SITE_URL=
SHAREPOINT_LISTS_PREFIX=SMA_
# App registration used by scripts/setup-sharepoint.ts (device-code) and runtime Graph calls.
GRAPH_TENANT_ID=common
# Blank uses Microsoft Graph Command Line Tools public client
# (14d82eec-204b-4c2f-b7e8-296a70dab67e). Tenant policy/admin consent still applies.
# For production, register your own public client and set its app id here.
GRAPH_CLIENT_ID=

# --- Scrum ceremony scheduling ---
STANDUP_CRON=0 30 3 * * 1-5 # UTC = 09:00 Asia/Kolkata on weekdays
NIGHTLY_CRON=0 0 19 * * * # UTC = 00:30 Asia/Kolkata daily
Comment on lines +92 to +93

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should fix: Cron defaults are documented as UTC, but node-cron evaluates them in TIMEZONE, so the standup fires at 03:30 IST

The template describes these as UTC expressions (0 30 3 * * 1-5 # UTC = 09:00 Asia/Kolkata), and the README calls them 'UTC cron'. But the local scheduler passes { timezone: cfg.timezone } to node-cron, which matches the expression against wall-clock time in that zone.

With TIMEZONE=Asia/Kolkata:

  • The in-process standup fires at 03:30 IST on weekdays (22:00 UTC the previous evening).
  • With the 4-hour cutoff, the summary posts around 07:30 IST, before the team is online.
  • The nightly warn/report runs at 19:00 IST instead of 00:30.

config.ts uses the same UTC strings as defaults, so leaving the vars unset has the same problem. The local scheduler and the Azure Function timers (which run these strings as UTC NCRONTAB) also fire 5.5 hours apart, not 'simultaneously'. README.md:221 calls TIMEZONE 'Display only', but it drives scheduling, the T-2 gate in sprint-summary and the meeting-slot search.

Evidence
  • .env.template:88-89: STANDUP_CRON=0 30 3 * * 1-5 # UTC = 09:00 Asia/Kolkata on weekdays and NIGHTLY_CRON=0 0 19 * * * # UTC = 00:30 Asia/Kolkata daily.
  • .env.template:91: TIMEZONE=Asia/Kolkata. .env.template:98: LOCAL_CRON=true.
  • src/cron/local-scheduler.ts:37-44: cron.schedule(cfg.standupCron, async () => {...}, { timezone: cfg.timezone }); (same at :46-52 for nightly).
  • src/config.ts:106-109 defaults: '0 30 3 * * 1-5', '0 0 19 * * *', timezone: optional('TIMEZONE', 'Asia/Kolkata').
  • node-cron's timezone option compares against the time in that zone, so 0 30 3 * * 1-5 matches at 03:30 Asia/Kolkata.
  • Compare azure-functions/src/index.ts:31-34: // 09:00 Asia/Kolkata Mon–Fri = 03:30 UTC, schedule: '0 30 3 * * 1-5', as NCRONTAB in UTC.
  • README.md:218-219 say 'UTC cron — default = 09:00 IST weekdays'; README.md:221 says TIMEZONE is 'Display only'. Yet getScheduleConfig().timezone is used in local-scheduler.ts:44/52, sprint-summary.ts:253-263 and chase.ts:332.

Scenario: create .env from the template and run npm run dev on Monday. Standup cards are DM'd at 03:30 IST and the cutoff summary posts at about 07:30 IST.

With the Function App also deployed:

  1. The Function fires Mon 03:30 UTC (standupId 101#<Mon>).
  2. It summarizes and evicts the session (standup.ts:524).
  3. The local cron fires Mon 22:00 UTC with the same UTC-date standupId and fans out again.

Suggested fix: Pick one convention and make the template, config defaults and README agree:

  • Simplest: run node-cron in UTC ({ timezone: 'Etc/UTC' } in local-scheduler.ts). The documented values and the Function App timers then line up.
  • Or keep the TIMEZONE option and change the template, config defaults and README to 0 0 9 * * 1-5 and 0 30 0 * * *, described as 'evaluated in TIMEZONE'.

In either case, drop 'Display only' for TIMEZONE in the README.

Comment on lines +92 to +93

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should fix: Cron defaults are documented as UTC, but node-cron evaluates them in TIMEZONE, so the standup fires at 03:30 IST

The template describes these as UTC expressions (0 30 3 * * 1-5 # UTC = 09:00 Asia/Kolkata), and the README calls them 'UTC cron'. But the local scheduler passes { timezone: cfg.timezone } to node-cron, which matches the expression against wall-clock time in that zone.

With TIMEZONE=Asia/Kolkata:

  • The in-process standup fires at 03:30 IST on weekdays (22:00 UTC the previous evening).
  • With the 4-hour cutoff, the summary posts around 07:30 IST, before the team is online.
  • The nightly warn/report runs at 19:00 IST instead of 00:30.

config.ts uses the same UTC strings as defaults, so leaving the vars unset has the same problem. The local scheduler and the Azure Function timers (which run these strings as UTC NCRONTAB) also fire 5.5 hours apart, not 'simultaneously'. README.md:221 calls TIMEZONE 'Display only', but it drives scheduling, the T-2 gate in sprint-summary and the meeting-slot search.

Evidence
  • .env.template:88-89: STANDUP_CRON=0 30 3 * * 1-5 # UTC = 09:00 Asia/Kolkata on weekdays and NIGHTLY_CRON=0 0 19 * * * # UTC = 00:30 Asia/Kolkata daily.
  • .env.template:91: TIMEZONE=Asia/Kolkata. .env.template:98: LOCAL_CRON=true.
  • src/cron/local-scheduler.ts:37-44: cron.schedule(cfg.standupCron, async () => {...}, { timezone: cfg.timezone }); (same at :46-52 for nightly).
  • src/config.ts:106-109 defaults: '0 30 3 * * 1-5', '0 0 19 * * *', timezone: optional('TIMEZONE', 'Asia/Kolkata').
  • node-cron's timezone option compares against the time in that zone, so 0 30 3 * * 1-5 matches at 03:30 Asia/Kolkata.
  • Compare azure-functions/src/index.ts:31-34: // 09:00 Asia/Kolkata Mon–Fri = 03:30 UTC, schedule: '0 30 3 * * 1-5', as NCRONTAB in UTC.
  • README.md:218-219 say 'UTC cron — default = 09:00 IST weekdays'; README.md:221 says TIMEZONE is 'Display only'. Yet getScheduleConfig().timezone is used in local-scheduler.ts:44/52, sprint-summary.ts:253-263 and chase.ts:332.

Scenario: create .env from the template and run npm run dev on Monday. Standup cards are DM'd at 03:30 IST and the cutoff summary posts at about 07:30 IST.

With the Function App also deployed:

  1. The Function fires Mon 03:30 UTC (standupId 101#<Mon>).
  2. It summarizes and evicts the session (standup.ts:524).
  3. The local cron fires Mon 22:00 UTC with the same UTC-date standupId and fans out again.

Suggested fix: Pick one convention and make the template, config defaults and README agree:

  • Simplest: run node-cron in UTC ({ timezone: 'Etc/UTC' } in local-scheduler.ts). The documented values and the Function App timers then line up.
  • Or keep the TIMEZONE option and change the template, config defaults and README to 0 0 9 * * 1-5 and 0 30 0 * * *, described as 'evaluated in TIMEZONE'.

In either case, drop 'Display only' for TIMEZONE in the README.

Comment on lines +92 to +93

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should fix: Cron defaults are documented as UTC, but node-cron evaluates them in TIMEZONE, so the standup fires at 03:30 IST

The template describes these as UTC expressions (0 30 3 * * 1-5 # UTC = 09:00 Asia/Kolkata), and the README calls them 'UTC cron'. But the local scheduler passes { timezone: cfg.timezone } to node-cron, which matches the expression against wall-clock time in that zone.

With TIMEZONE=Asia/Kolkata:

  • The in-process standup fires at 03:30 IST on weekdays (22:00 UTC the previous evening).
  • With the 4-hour cutoff, the summary posts around 07:30 IST, before the team is online.
  • The nightly warn/report runs at 19:00 IST instead of 00:30.

config.ts uses the same UTC strings as defaults, so leaving the vars unset has the same problem. The local scheduler and the Azure Function timers (which run these strings as UTC NCRONTAB) also fire 5.5 hours apart, not 'simultaneously'. README.md:221 calls TIMEZONE 'Display only', but it drives scheduling, the T-2 gate in sprint-summary and the meeting-slot search.

Evidence
  • .env.template:88-89: STANDUP_CRON=0 30 3 * * 1-5 # UTC = 09:00 Asia/Kolkata on weekdays and NIGHTLY_CRON=0 0 19 * * * # UTC = 00:30 Asia/Kolkata daily.
  • .env.template:91: TIMEZONE=Asia/Kolkata. .env.template:98: LOCAL_CRON=true.
  • src/cron/local-scheduler.ts:37-44: cron.schedule(cfg.standupCron, async () => {...}, { timezone: cfg.timezone }); (same at :46-52 for nightly).
  • src/config.ts:106-109 defaults: '0 30 3 * * 1-5', '0 0 19 * * *', timezone: optional('TIMEZONE', 'Asia/Kolkata').
  • node-cron's timezone option compares against the time in that zone, so 0 30 3 * * 1-5 matches at 03:30 Asia/Kolkata.
  • Compare azure-functions/src/index.ts:31-34: // 09:00 Asia/Kolkata Mon–Fri = 03:30 UTC, schedule: '0 30 3 * * 1-5', as NCRONTAB in UTC.
  • README.md:218-219 say 'UTC cron — default = 09:00 IST weekdays'; README.md:221 says TIMEZONE is 'Display only'. Yet getScheduleConfig().timezone is used in local-scheduler.ts:44/52, sprint-summary.ts:253-263 and chase.ts:332.

Scenario: create .env from the template and run npm run dev on Monday. Standup cards are DM'd at 03:30 IST and the cutoff summary posts at about 07:30 IST.

With the Function App also deployed:

  1. The Function fires Mon 03:30 UTC (standupId 101#<Mon>).
  2. It summarizes and evicts the session (standup.ts:524).
  3. The local cron fires Mon 22:00 UTC with the same UTC-date standupId and fans out again.

Suggested fix: Pick one convention and make the template, config defaults and README agree:

  • Simplest: run node-cron in UTC ({ timezone: 'Etc/UTC' } in local-scheduler.ts). The documented values and the Function App timers then line up.
  • Or keep the TIMEZONE option and change the template, config defaults and README to 0 0 9 * * 1-5 and 0 30 0 * * *, described as 'evaluated in TIMEZONE'.

In either case, drop 'Display only' for TIMEZONE in the README.

STANDUP_CUTOFF_HOURS=4
TIMEZONE=Asia/Kolkata
# Both schedulers evaluate the expressions in UTC. TIMEZONE controls local
# date-based gates, card labels and meeting-slot searches, not cron evaluation.
# Leave WEBSITE_TIME_ZONE unset on the Functions app.

# --- Warn thresholds (Sprint risk detection) ---
WARN_TODO_PCT=0.40 # >40% of committed points still in To Do
WARN_SPRINT_PROGRESS_PCT=0.50 # ... once >=50% of sprint duration has elapsed

# --- Runtime toggles ---
LOCAL_CRON=true # run the in-process scheduler in dev; false in prod
AGENT_CALLBACK_URL= # Functions app setting: reachable agent base URL (no /api/messages suffix)
INTERNAL_TRIGGER_TOKEN= # required nonempty unless NODE_ENV is exactly development
# Cloud agent overrides: NODE_ENV=production, HOST=0.0.0.0, LOCAL_CRON=false
# when Functions timers are deployed. Do not copy the development values above.
36 changes: 36 additions & 0 deletions scenarios/scrum-master/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# dependencies + build
node_modules/
!package-lock.json
dist/
*.tsbuildinfo

# TS compile artefacts inside src (only source .ts should be tracked)
src/**/*.js
src/**/*.d.ts
src/**/*.js.map
azure-functions/src/**/*.js
azure-functions/src/**/*.d.ts
azure-functions/src/**/*.js.map

# env & secrets — never commit
.env
.env.local
.env.*.local
.mstoken-cache.json

# generated at first `npx a365` run — contains tenant/agent IDs
a365.generated.config.json
a365.config.json
.a365-workspace-detection.local.json

# dev logs
dev-out.txt
seed-out.txt
setup-out.txt
*.log

# agent skills installed via `gh skill add microsoft/agent365-skills` — workspace-local
.agents/
.claude/
.github/copilot-instructions.md
.github/copilot-instructions.md.bak
Loading
Loading