Inspiration
Every week, construction teams export a new MS Project or Primavera P6 schedule. Hundreds of linked activities move a little; one of them quietly loses its last day of float and the completion date slips. Large contractors pay planners and tools (Acumen Fuse and Touchstone, SmartPM, Primavera Cloud) to catch this. Smaller firms often have no planner, so nobody looks until the delay is visible on site.
The same firms already pay an MSP to run their IT. Schedule Risk Agent lets the MSP add a weekly schedule review to that contract and run it for many customers at a known cost per report: built for construction, reusable across project-driven industries, delivered by MSPs. The MSP already holds the contract, the billing and the file access; schedule tools sell to planners that small firms do not have. At an illustrative price of $149 per project per month (our assumption, not a quote), 4.33 weekly reports cost about $0.23–0.64 a month in estimated AWS run cost.
What it does
- For the customer: a private portal. They drop this week's schedule; the service compares it with last week's and returns a report: finish movement, activities that entered or left the critical path (float before and after), failed checks (10 DCMA-style checks), a 3-week look-ahead and owner-ready actions. An Evidence table traces every number to the source file or a deterministic calculation, labels the agent's interpretations as such, cites activity IDs and writes N/A instead of guessing.
- An agent that investigates, not a summarizer: after the overview, the agent decides which risks,
if any, need a closer look (at most three) and calls
task_detailfor them: what drives the task's start, whether a date constraint really holds it, the chain it drives, and whether another path meets it at the same point. It is told never to state a cause as fact, and a fixed-pattern check flags any sentence that still does, which one small model call rewrites (added after the evaluation below, so not part of its numbers; it shows in the audit trail ascause_check; if the rewrite fails, a fixed rule softens the sentence instead). A second deterministic check compares the Evidence table's forecast finish, BEI and checks-passed values with the tool output and sets any miscopied value back to the tool value (fact_checkin the audit trail). Example on the sample project: the flooring constraint holds its start 4 working days, but a second path (doors, painting, HVAC test) meets the flooring chain at Snagging on the same day, so "removing this delay alone may not bring completion forward". The tool's own wording is "Removing this task's delay alone would not move Snagging (ID 26) earlier: another predecessor drives it at the same time (assuming the other path stays as scheduled)": a statement about the schedule's links, not a proven cause. Every tool call and the agent's one-line reason are kept as an audit trail next to the report. - For the MSP: an operations console: onboard a customer, give them a private portal link, see each run with tokens, seconds, estimated AWS cost and its audit trail, delete a customer and all its data, and a weekly job (EventBridge Scheduler, every Monday) that reports on each customer with a new version and logs "No new schedule" for the rest.
- For the MSP's copilot: six operator tools over MCP through Amazon Bedrock AgentCore Gateway (IAM).
- Same engine, another industry: a manufacturing sample (packaging-line install with a plant shutdown window) runs through the same tools and agent with no industry-specific code. It is a technical reuse demo, not a customer case.
This is risk detection and reporting, not prediction: no probabilities of delay.
How we built it
- Deterministic analysis first, then the agent: MPXJ (JVM) reads .mpp/.xml/.xer; dates, float and critical flags come from the scheduling tool's own values, with a marked calculated fallback.
- Strands Agents SDK agent with 8 tools: seven overview tools plus
task_detail, which it uses selectively. Limits: 3 investigated tasks, 16 tool calls, 10 model calls, a 40k input / 6k output token budget checked before each model call, capped tool output, $0.40 reserved per run. - Amazon Bedrock AgentCore Runtime hosts the ARM64 container in isolated sessions.
- Amazon Bedrock AgentCore Memory: exact per-customer snapshots of each report (forecast finish, critical path, failed checks, BEI) as short-term events read back by customer, plus long-term facts (e.g. a recurring supplier delay) from its semantic strategy as context. Activity-level comparisons use the previous schedule file in S3, never a semantic search.
- Amazon Bedrock AgentCore Gateway exposes six tools over MCP (IAM-authenticated, Lambda target).
- Claude Sonnet 4.6 on Amazon Bedrock chooses what to investigate and writes the report.
- Lambda function URL, DynamoDB, S3, EventBridge Scheduler, ECR, SSM Parameter Store, CloudFormation, GitHub Actions with OIDC, CloudWatch, AWS Budgets.
Does the investigation step help? (measured)
Same model, engine and files; only the agent design differs (the new prompt with its fact/structure/cause rules plus task_detail), so the gain belongs to the whole updated design, not to one tool. Five situations on new projects written after round 1 (newly critical task,
a constraint that holds, a constraint with no effect, a quiet week, many changes), 5 runs each per
version. The answer key was written before any run by a separate AI reviewer (a fresh Claude session that
saw only the schedule facts); grading was blind and done by a Claude model call, so counts compare the two
versions rather than measure error rates. Grader noise is real: the unchanged fixed version scored 39 and 30
forbidden claims in two identical round-2 runs
(docs/evaluation.md, raw data in docs/evidence/):
| Blind-graded by a Claude judge, 25 runs each (round 2) | Original (first submission) | Updated agent |
|---|---|---|
| Cause stated without evidence | 15 | 1 |
| Claims the answer key forbids | 30 | 14 |
| Key risks missed | 39 | 24 |
| Got the scenario's key nuance right | 0 of 25 | 13 of 25 |
| Median agent time / cost per report | 18.7 s / $0.041 | 24.0 s / $0.070 |
It caught the trap (a date constraint that has no effect) in 5 of 5 runs, and skipped any closer look in all 5 quiet-week runs. Weak spot we did not tune away: when a constraint really does hold a start, it looked closer in only 1 of 5 runs.
Round 1 showed the quiet week getting worse (generic, speculative actions); one prompt change followed
and round 2 used new projects and a new answer key. Round 2 ran twice: the table is the deployed prompt,
which also batches tool calls to cut cost on large files. The run before that change scored better on
forbidden claims (10), missed risks (18) and nuance (14 of 25), and looked closer at the holding
constraint in 5 of 5 runs; both runs are in docs/evaluation.md. These are our own tests on synthetic schedules,
not customer validation or an independent expert review.
Operating it safely
- Isolation: one authorization rule for the web API; a customer's token sees only its own runs and reports. The agent's tools are bound to the request's customer and files, so text inside an uploaded schedule cannot point a tool at another customer. Every deploy re-checks this on the live stack: customer A's token cannot read or run customer B, or reach the operator API or MCP console.
- Cost: per-role daily quotas, a monthly limit for anonymous runs and a cumulative cost cap, enforced with conditional DynamoDB updates. Each run reserves its worst case ($0.40) and settles to its estimated cost. The last $15 of the cap is kept for the MSP's console, copilot and weekly job.
- Reliability: a report is keyed by the contents of the files it compares, so re-uploads, retries and re-triggers never produce or bill a second report.
- Logs: traces keep tool names, timings and tokens; message, prompt and tool input/output content
is redacted, and no report text goes to stdout. We found customer task names in runtime logs during
this review, fixed it, and check it with a read-only audit workflow (
tests/ops/log_audit.py). Runtime and API logs expire after 14 days. - Retention: customer schedules, reports, run history and Memory events expire after 90 days, demo uploads after 7; long-term Memory facts stay until the customer is deleted, which removes its files, run history and Memory.
Measured results
Live runs on 100-, 500- and 1,000-activity schedules (docs/benchmark.md):
- 24–36 seconds from upload to stored report and an estimated $0.05–0.15 per report (one run per size and week; larger comparisons can cost more, as input tokens grow with the number of changes). The deterministic analysis takes under 0.4 s.
- Cost is an estimate (measured tokens and runtime seconds at on-demand prices; Memory, Gateway and storage excluded; not the AWS bill). The MSP console shows AWS run cost as a share of an assumed price; staff, support and sales costs are not included, so we do not claim a margin.
- Planner time saved is not measured.
What we learned / limits
P6 writes its own dates and float into the XER file, so we validated against them: of 20 distinct
public XER files (up to 1,000 activities), 15 hold stored values, and all 1,604 finish dates and 792
float values we read match the values P6 stored in those files (docs/p6-validation.md). When a file does not store float, the service
calculates it from dates, logic and working calendars; with P6's stored float removed it finds exactly
P6's critical activities on the 4 consistent, rescheduled files and reports N/A where dates break their
own logic. MS Project files were checked the same way by a separate AI review agent: 44 public MSPDI
files, 1,874 comparable tasks, 0 mismatches in dates, baselines, % complete, stored slack and status
dates (3 completed tasks differ on the stored critical flag)
(docs/ms-project-validation.md). The agent's investigation was evaluated as above.
The two demo samples are synthetic files that store float for only a few tasks; the rest is calculated
(tasks the file flags as critical get 0).
Limits: no live customer project has been checked; the evaluation uses synthetic schedules; the largest
public MS Project file was 110 tasks; task_detail describes structure and does not reschedule the
project, so it never proves a cause.
What's next
A what-if reschedule (release one constraint, recompute) so a cause can be tested, not only suggested; Email/Teams delivery; customer SSO with AgentCore Identity; P6 EPPM API ingestion.
Built during the submission period
All code in this repository was written from 2026-11-08 onwards for this hackathon. The first commit (8 Nov) adds the working prototype built that day; every change after it is in the commit history. It reuses the open-source MPXJ library for reading schedule files.
Built With
- amazon-bedrock
- amazon-bedrock-agentcore
- amazon-cloudwatch
- amazon-dynamodb
- amazon-ecr
- amazon-eventbridge
- amazon-web-services
- aws-cloudformation
- aws-lambda
- mpxj
- python
- strands-agents