Shared research publishing technical case study
External overview | 19 October 2026
John Bojanski’s reporting solution combines evidence-based AI review with controlled static publishing. It supports research on JCB Technology and shares approved published reports with johnbojanski.com, a personal career website. The architecture keeps research, editorial review and production release as separate responsibilities.
Four Azure AI Foundry prompt agents are implemented: AI Usage, Cloud Services, Workforce and Cloud Advisory. The reviewed advisory edition is published on both production sites. The personal website consumes published research and does not expose a model endpoint or require visitors to use AI services.
Design goals
Keep reports useful to readers, preserve source attribution and limitations, prevent unreviewed drafts from reaching production, and update shared research without maintaining two independent copies. Use intermittent automation and existing hosting rather than an always-on reporting service.
| Layer | Tools and purpose |
|---|---|
| Research | Azure AI Foundry prompt agents using a shared gpt-5.4-mini deployment; Node.js source collection and validation |
| State | Private Azure Blob Storage for evidence, versioned candidates, usage receipts and reservations |
| Automation | GitHub Actions with federated Azure identity and environment-specific deployment controls |
| Publishing | Astro for the research site; Python static generation and personalization for the career site |
| Hosting | Azure Static Web Apps with separate staging review environments |
| Verification | SHA-256 manifests, publication audits and Playwright browser checks |
The implementation distinguishes a successful technical staging release from editorial acceptance. Automated checks improve consistency and traceability; human review remains necessary for interpretation and production approval. Research schedules are defined but remain gated at the October 2026 documentation baseline.
Data flow and publication controls
Source collection and publishing run in application code. Agents receive curated evidence and return structured draft findings; they do not browse, manage infrastructure or publish. The browser receives static pages and permitted public datasets. Private excerpts, provider responses and credentials stay outside website output.
The personal site checks published research daily. It records source URLs and file hashes, preserves research dates and approved report structure, and applies personal navigation and privacy controls. Unchanged content produces no new release. A changed edition goes to staging for review before production promotion.
Foundry agents and evidence responsibilities
| Agent role | Review responsibility | Status |
|---|---|---|
| AI Usage | Observed model and application activity from OpenRouter datasets | Implemented; version 2 |
| Cloud Services | AWS, Azure, Google Cloud and Oracle Cloud capabilities and catalog proposals | Implemented; version 1 |
| Workforce | Disclosures across six major technology employers and company investment measures | Implemented; version 1 |
| Cloud Advisory | Scoped evidence review of six subjects and a preserved seven-page reference library | Implemented v1 |
AI Usage
The collector validates reporting windows, identifiers and token counts before model review. The agent produces a short summary, evidence-linked observations and limitations. Missing observations remain unknown. Application and model totals can overlap. The resulting report describes observed activity on a particular platform and does not establish worldwide AI market share.
Cloud Services
The agent reviews four cloud providers independently using official sources and an existing service catalog. It proposes supported findings and limited catalog changes while preserving preview, retirement, regional and availability qualifications. Comparable services are not assumed to have identical features, APIs or commercial terms. Existing mappings are a baseline, not evidence of parity.
Workforce
The agent reviews Microsoft, Amazon, Alphabet, Meta, Oracle and Salesforce using company disclosures and structured filing evidence. It separates job postings from hiring, layoffs from attrition, and company-wide capital spending from AI-only investment. Reporting periods, actual spending, forecasts and lease measures retain their distinct meanings. Supported findings remain available for separate editorial review without automatically rewriting the approved narrative.
Shared model controls
All four use strict structured output, bounded input and output, evidence identifiers and an empty tool list. Application code checks the expected agent definition before calling it and validates returned claims. The shared deployment supports independent agent definitions; provider or company subjects are review units within those agents. The model cannot change schedules, budgets, resources or release decisions.
Reliability security and operating model
Traceable publication
Meaningful content is fingerprinted and saved as immutable candidates. Repeated compatible input can reuse prior results instead of requesting another model review. Publication checks compare public data and rendered report versions before marking a staging candidate technically accepted. Research periods, collection times, generation times and copy times are recorded separately so a recent import does not imply newly researched facts.
Failure and recovery
Collection, schema or evidence failures stop the candidate from progressing. Previous validated content remains available. Recovery uses saved artifacts where possible; unknown provider outcomes are not blindly repeated. Restoring data uses a compatible renderer and requires verification of the resulting page. Human editorial approval is separate from technical success.
Privacy and security
Federated workload identity avoids a long-lived Azure client secret for research jobs. Private storage and scoped roles separate evidence from public reports. Static output is allowlisted, model text is escaped, and the personal site generates content security policies from its final pages. Same-origin framing supports the deployment map while limiting external embedding. Public résumé assets omit direct personal phone and email details, and public contact is routed through LinkedIn.
Cost discipline
Runs reserve conservative allowances before paid work. Shared limits and per-report attempt ceilings constrain admission. Reserved allowances remain distinct from returned token usage and actual provider invoices. There is no claim of a guaranteed invoice cap. Intermittent runners, bounded model calls and unchanged-content reuse reduce avoidable work without allowing agents to control spending policy.
Results and next steps
Technical staging records demonstrate all four implemented agents producing and publishing verifiable candidates. The personal site has a daily synchronization path from the research production site to its own staging environment. The reviewed advisory edition was promoted to both production sites on 19 October. Research schedule enablement remains separate. Production promotion remains under human control.
Public sites: https://jcbtechnology.io and https://johnbojanski.com. This overview describes the architecture as of 20 October 2026; staged research capabilities and planned work are identified separately from production publishing.
Detailed component and authority map
Logical component and trust map. The research runner reads and writes private state and invokes Foundry; the personal importer reads only the public production edition. Approval transitions represent separately controlled release steps, not model tools. Source: implemented workflows and pipelines, baseline 19 October 2026.
| Actor | Read authority | Write authority |
|---|---|---|
| Research runner | Approved sources, agent metadata and private report state | Private candidates and receipts; staging website upload |
| Foundry prompt agent | Only the evidence supplied in its request | Structured response only; no direct storage or publication tools |
| Personal sync runner | Published research HTML and allowed dependencies | Personal staging report snapshot and staging workflow dispatch |
| John and release process | Staged pages, verification receipts and source changes | Separate editorial decision and approved production release |
| Visitor browser | Published static site and permitted public downloads | No reporting-state or research publishing authority |
The model provides editorial review inside application controls. Independent agents keep separate report pointers. The downstream personal site needs no private research storage role or model credential.
Separate release paths
JCB research overlays modify a disposable build checkout without a content commit. Personal synchronization commits the public snapshot to staging for reproducibility. Design releases preserve accepted staged data; production releases must not inherit unapproved staging pointers.
AI Usage request sequence and contract
AI Usage processing sequence. Each actor is application or workflow code except the bounded review call. Reuse avoids inference, but collection may still occur. Source: source.mjs, review.mjs and pipeline.mjs, reviewed 19 October 2026.
| Contract field | Meaning and validation |
|---|---|
| Reporting window | Complete UTC windows; collection time is not the period being measured |
| Model and application rows | Identifiers, decimal counts, coverage and duplicates validated before review; aggregates overlap |
| Review payload | Summary, observations with evidence IDs, limitations and an evidence register |
| Output bound | At most three observations; 2,000 output-token cap; a short summary requested |
| Coverage and growth | Partial model rows stay explicit; growth uses only supplied complete-window comparisons |
The runner chooses at most three listed models with the largest absolute changes among complete weekly observations. This selection is a stated sampling rule, not a worldwide ranking. Numeric screening compares generated numbers with supplied evidence, but it remains a heuristic. The fixed renderer displays coverage separately so a missing prose caveat cannot silently remove it.
On 17 October, the successful live staged AI Usage run made four source requests and one model call, returning 769 input and 349 output tokens in 3,356 ms. This single historical inference duration excludes collection, CI, build and deployment; it is not an end-to-end latency target or service guarantee. Source: the first live publication record in the AI Usage pipeline documentation.
Monthly research sequence and claim validation
Monthly flow uses four or six subject calls within one agent definition per report. Subject pacing is distinct from retrying a failed request. Sources checked and usable excerpts are not unique websites or an accuracy score. Source: monthly-pipeline.mjs and report configs, baseline 19 October 2026.
| Rule | Cloud Services | Workforce |
|---|---|---|
| Subject calls | Four provider subjects per new candidate | Six company subjects per new candidate |
| Evidence type | Official capability, lifecycle and service documentation | Official disclosures, SEC facts and reviewed company evidence |
| Baseline role | 141-row comparison seed; existing mapping is not parity evidence | Approved report presentation and source semantics remain intact |
| Generated output | Findings and limited catalog proposals | Findings for a separate review artifact |
| Unsupported items | Withhold unknown parity, regions or lifecycle meaning | Withhold unsupported totals, periods and causal claims |
Each subject must cite evidence from its own scope. Literal support excerpts are constrained; instructions prohibit deriving new unsupported numbers or inferring that layoffs finance AI investment. Application code canonicalizes permitted labels and validates the precise contract. A model response can be syntactically valid while a finding is withheld for evidence or numeric reasons.
Workforce report structure and section-level research remain editorially controlled. The existing collector and separate review file do not automatically complete every country-level hiring or layoff comparison. Missing research is not proof of company non-disclosure. The published report can receive independently curated corrections without a new paid model run.
Data artifacts concurrency and recovery
Artifact lifecycle and failure boundaries. A failure retains its reservation. If an upload succeeds but verification fails, live content and the accepted pointer can differ; inspect the live site before recovery. Source: store.mjs and staging finalizers, baseline 19 October 2026.
| Record | Mutability and purpose |
|---|---|
| Monthly budget ledger | ETag-protected conditional updates; month, run keys, committed allowances, component totals and completion state |
| Evidence and raw responses | Private acquisition/attempt records; distinguish successful, failed and unknown provider outcomes |
| Immutable candidate | Content version, schema, source/definition fingerprints, validated findings and provenance |
| Accepted staging pointer | Current and previous artifact reference; advance only after successful public verification |
| Public download | Limited report data and source metadata; excludes private excerpts and provider responses |
Conditional ledger writes may retry on contention up to eight times without repeating a source or model call. New immutable artifacts use create-if-absent semantics. Run completion records distinguish reused, candidate-ready and failed-reservation-retained. A retained financial reservation is not evidence that a failed call was billed, and a zero usage receipt must not be inferred from an unknown outcome.
Restore selects an existing compatible artifact and renders it with the current code. It is a data rollback, not a byte-identical historical website restore. Monthly recovery additionally requires an audited plan pinning evidence, baseline and definition hashes; it reuses successful responses and permits only verified unattempted subjects. It cannot silently reset attempt limits or treat a throttled request as a successful response.
Synchronization controls and publication sequence
Personal report synchronization does not invoke Foundry or copy private evidence. No-change runs produce no new commit or deployment. Source: sync-reports.yml, report_sync.py and build.py, baseline 19 October 2026.
| Control | Configured limit or behavior |
|---|---|
| Source trust | HTTPS, approved source origin and report paths; redirects rejected |
| Collection size | 40 files maximum; 25 MB per bundle; 8 MB per file; 40 seconds per request |
| Failure isolation | Collect before writing; no partial report update committed or published after failed validation |
| Scope isolation | Prune only declared report assets; keep personal data and deployment explorer separate |
| Content preservation | Compare report heading sequences and table structure before publication |
| Schedule semantics | Daily 13:17 UTC; best-effort GitHub delivery; production promotion remains separate |
The production sync on 19 October contains seventeen source files and ten report or AI HTML pages. The complete personal build produces sixteen HTML pages. These are different denominators: imported files include required CSS, JavaScript and JSON, whereas report-page counts include HTML only. The saved report snapshot was copied on 19 October 2026; original research dates remain unchanged.
An import timestamp is not a new source review. If JCB production changes while a personal release is being prepared, review the exact staged commit and bundle fingerprint rather than approving a moving branch name. Future manual changes must reconcile staging first because the scheduled job may have advanced it. The importer never requires access to private JCB source code or agent evidence.
Measured verification results
Observed source coverage on 17 October 2026: Cloud Services 53 of 59 (89.8%); Workforce 25 of 27 (92.6%). Percentages are derived from the dated verification record and rounded to one decimal. Usability is a collection result, not an accuracy or editorial-approval score.
Historical returned usage for the two published staging editions, 17 October 2026. Cloud Services total 22,614; Workforce total 14,455. Reused saved responses are counted once. These are different research workloads and do not establish comparative model efficiency or actual invoice totals.
| Result on 17 October | Cloud Services | Workforce |
|---|---|---|
| Supported findings | 11 | 11 |
| Catalog proposals | 3 | 0 |
| Withheld items | 5 | 5 |
| Subject reviews | 4 | 6 |
| Public data and HTML version checks | Matched | Matched |
These measurements describe the technically published staged editions recorded on 17 October. They do not imply that all approved source pages were available, that withheld items were false, or that the report has a measured accuracy percentage. Successful publication checks establish artifact consistency, not factual completeness or editorial acceptance. Source: the monthly staging verification record; arithmetic uses only the displayed counts.
Operations failure handling and next decisions
Read only verification before release
Confirm the selected environment, source commit, saved bundle integrity, staged report behavior and current workflow state. Install reviewed dependencies before running the audits. Inspect actual public pages after upload rather than relying on a green workflow alone. No infrastructure changes or paid research calls are required to verify the personal static snapshot.
python3 scripts/sync-jcb-content.py --verify
python3 scripts/test_report_sync.py
python3 scripts/test_security.py
python3 scripts/build.py
python3 scripts/audit-site.py
These commands run from the personal-site checkout and are documentation examples. A browser regression pass additionally requires the secure preview server and the locked Playwright dependency. Use staging mode for preview; the reviewed production release selects production mode explicitly through its workflow.
| Failure | Required response |
|---|---|
| Source unavailable or bundle rejected | Keep the previous saved release; inspect the source/path/size failure before trying again |
| Agent definition mismatch | Stop before inference; compare the reviewed definition and saved version |
| Unknown provider outcome | Retain reservation and attempt evidence; do not blindly replay |
| Upload passes but version check fails | Inspect actual staged content; do not mark accepted; restore a known compatible artifact if needed |
| Personal staging moved since review | Reconcile commits and recheck the candidate; approval applies to an exact reviewed release |
Operating decisions still required
All four agents are implemented; John approved the advisory production edition on 19 October. Research schedules remain separately gated. Reconcile actual charges with token and reservation records, define recovery objectives and complete an authorized restore drill. Publication checks do not establish billing guarantees or cost alerts.
Evidence register: dated reporting verification receipts, agent definitions, source registries, validators, private-state code, personal manifest and release audits. Results retain their observation dates; diagrams show logical control and data flows.
Cloud Advisory transition and production closeout
The fourth Foundry agent completed its transition on 19 October 2026. It reviews six subjects: market changes, customer shifts, provider customers, multicloud, adoption and pricing. One saved prompt definition serves six bounded subject requests; the hub and six linked reports retain their approved presentation.
| Control or result | Verified behavior |
|---|---|
| Evidence and review | 29 source checks; 22 usable excerpts; 7 unavailable checks; 8 screened findings and 7 withheld items |
| Model receipt | 10,818 returned input tokens and 2,229 output tokens; dated model-only estimate USD 0.0199584, not an invoice |
| Freshness correction | Ten dated primary-source updates integrated into the news table and affected references through 19 October |
| Publication checks | 85 reporting tests in the final staging run; seven exact JCB page hashes and public data checked before acceptance |
| Personal release | 17 imported files; six sync and four security tests; 16-page privacy, structure, dependency and CSP audit |
| Production status | JCB and personal production releases succeeded on 19 October; live pages and linked JSON downloads verified |
The initial migration kept old July news. The reviewed editorial correction updated the core news table and affected financial and product references. It reused the original evidence and model responses with their original review window clearly labeled; it was not a new paid inference run. Historical prices and unsupported customer mappings remain dated and are not silently recertified.
Production promotion commits the exact reviewed JCB snapshot to the release branch before the manual production build. The personal importer then reads public JCB production, including the two advisory JSON downloads, verifies its manifest and publishes personal staging. A separately approved personal production release applies personal navigation and canonical URLs. The daily sync continues to target staging only.
Recovery restores a compatible saved staging artifact without new research calls. Production recovery uses a reviewed release reversal and live page/data verification, followed by a new public import and separately approved personal promotion. Failed or unknown model attempts retain their receipts and reservations; they are not blindly replayed. Research schedules remain separately gated.
Public editions: https://jcbtechnology.io/reports/cloud-advisory/index.html and https://www.johnbojanski.com/reports/cloud-advisory/index.html. Public review data and the dated update register are linked inside the report. Verification establishes publication consistency, not exhaustive research coverage or semantic certainty.
CI/CD pipeline and production promotion
GitHub Actions builds, validates and deploys both websites to Azure Static Web Apps. Website releases are manually dispatched: merging a pull request does not automatically deploy production. Staging provides the review destination; production promotion is a separate, deliberate release from the main branch. The flows below distinguish website releases, report synchronization and live deployment-content updates.
1. Website code and reviewed report releases
- Commit changes and review the proposed release
- Manually dispatch the staging workflow
- Build, validate and deploy to staging
- Review the staged website and promote the reviewed changes to main
- Manually dispatch production; rebuild, validate and deploy
- Verify the live pages, assets and report data
2. Shared report synchronization
- Publish the reviewed report edition to JCB production
- Personal importer runs daily at 13:17 UTC or on manual request
- Fetch allowed public reports and verify the saved manifest and hashes
- Build, audit and check report interactions when the content changes
- Commit changed snapshots to personal staging and dispatch its deployment
- Review staging, then separately promote and deploy personal production
3. Live deployment-content updates
- Owner signs in to the production admin portal
- Protected API validates authorization and the record version
- Save to production Cosmos DB with change history
- Both sites’ maps read the sanitized public API after refresh
| Pipeline | Build and release controls |
|---|---|
| JCB website | Manual environment selection; production requires main. Node and Astro build with branding and advisory-register checks, production destination validation, and generated security headers and editor configuration. Staging can restore accepted report overlays; production uses the reviewed report snapshot committed to its release branch. |
| Personal website | Manual dispatch from staging or main selects staging or production. Python builds the static site; security tests, report-import tests and the publication/privacy/CSP audit must pass before upload. GitHub Actions dependencies are pinned to reviewed commit versions. |
| Personal report synchronization | The scheduled workflow always targets staging and reads JCB production. A changed bundle receives browser checks before its snapshot commit. Unchanged content creates no new commit or deployment. Import or validation failures prevent publication of a partial update. The schedule is best effort; it grants no production approval. |
| Identity and deployment credentials | JCB staging research-storage access uses federated Azure identity. Static Web Apps uploads use deployment tokens held in GitHub secrets; JCB tokens are scoped to the selected GitHub environment. Credentials and private research evidence are excluded from published site assets. |
| Production deployment editor | Owner-only authorization, conditional writes and private change history protect live content updates. A stale browser tab must reload before saving. Static website code and career narrative still follow the website release path. |
These are controlled CI/CD workflows with manual production releases. The documentation does not imply automatic deployment on every push or an enforced GitHub reviewer approval gate. A failed build or validation step stops the workflow before upload. Recovery uses a reviewed prior release or compatible saved report artifact, followed by live verification.
Implementation references: JCB .github/workflows/deploy-azure.yml; personal .github/workflows/azure-static-web-apps.yml and .github/workflows/sync-reports.yml. Workflow behavior and the production editor were checked on 20 October 2026.