Tracing Every Place a PeopleSoft Field Is Updated Using an AI Agent and the psLens MCP Server
Every PeopleSoft developer and functional analyst has been asked a version of this question:
“Where in the system does
STDNT_CAR_TERM.TUITION_CALC_REQget set to'Y'?”
On a traditional codebase stored in Git, ripgrep answers that question in two seconds. In PeopleSoft, a single flag can be flipped across seven different architectural layers:
- Record Field Defaults stored in
PSRECFIELD(DEFFIELDNAME/DEFRECNAME) - Record Field PeopleCode (
RowInit,FieldChange,SavePreChange,SavePostChange) - Scroll Buffer Functions (
UpdateValue()targeting the record or a view over the record) - Database Views (
STDNT_CAR_TE_VW) that write through to the underlying table - Inline
SQLExecStatements with hardcodedUPDATE PS_STDNT_CAR_TERMstrings - Application Packages & Application Engine Programs (both PeopleCode and SQL actions)
- COBOL Stored SQL Statements in
PS_SQLSTMT_TBL - Online Pages and Component Interfaces where users or integrations toggle the field directly
Worse, raw text searches in Application Designer or against PSPCMTXT routinely return false positives from commented-out code (/* ... */ or REM), miss updates that happen through SQLExec("UPDATE PS_STDNT_CAR_TERM ..."), and ignore COBOL stored SQL entirely.
Here is what happens when you hand that exact prompt to an AI coding agent connected to a PeopleSoft Campus Solutions 9.2 environment through the psLens MCP Server.
The Prompt
The entire investigation started with a single one-line prompt in the IDE:
Use pslens to find all areas where STDNT_CAR_TERM.TUITION_CALC_REQ gets set to "Y".
Notice the subtle trap in the prompt itself: the human asked for TUITION_CALC_REQ (after the page label “Tuition Calc Required”), whereas the actual PeopleSoft column name on STDNT_CAR_TERM is truncated to 13 characters: TUIT_CALC_REQ.
Here is the exact sequence of MCP tool calls the agent executed to resolve the schema, trace every dependency layer, verify the source code, and eliminate false positives.
flowchart TD
P["User Prompt:\nFind where STDNT_CAR_TERM.TUITION_CALC_REQ = 'Y'"]
T1["list_databases\nIdentify connected CS 9.2 instance"]
T2["get_record_schema\nInspect STDNT_CAR_TERM fields & defaults"]
T3["analyze_record_field_impact\nBlast radius across pages, CIs, views & PeopleCode"]
T4["search_code_sql\nSearch PeopleCode, App Engine SQL & SQL Objects"]
T5["query_table (SQLSTMT_TBL)\nInspect COBOL stored UPDATE/INSERT statements"]
T6["get_peoplecode\nRead full event source & filter commented-out code"]
R["Complete Cross-Layer Impact Report"]
P --> T1 --> T2 --> T3 --> T4 --> T5 --> T6 --> RStep-by-Step: How the Agent Used the psLens MCP Tools
Discovering the Environment and Resolving the Field Name
First, the agent called list_databases to see which PeopleSoft environments were connected, followed by get_record_schema on STDNT_CAR_TERM:
{
"tool": "get_record_schema",
"arguments": {
"db": "CS92DEV-CHG",
"record_name": "STDNT_CAR_TERM"
}
}
From get_record_schema, the agent immediately spotted two critical facts without human intervention:
- The column on
STDNT_CAR_TERMisTUIT_CALC_REQ(notTUITION_CALC_REQ). - In
PSRECFIELD,STDNT_CAR_TERM.TUIT_CALC_REQhas a Record Field Default pointing toBUS_UNIT_TBL_SF.TERM_ACT_INIT_SET(Term Activation Initial Setting). WheneverTERM_ACT_INIT_SET = 'Y'on the Student Financials Business Unit, any newSTDNT_CAR_TERMrow orSetDefault(STDNT_CAR_TERM.TUIT_CALC_REQ)call automatically initializesTUIT_CALC_REQto'Y'.
Running a Record.Field Blast Radius Analysis
Next, the agent called analyze_record_field_impact to map every PeopleSoft object that references STDNT_CAR_TERM.TUIT_CALC_REQ:
{
"tool": "analyze_record_field_impact",
"arguments": {
"db": "CS92DEV-CHG",
"record_name": "STDNT_CAR_TERM",
"field_name": "TUIT_CALC_REQ"
}
}
In a single round trip, analyze_record_field_impact returned:
- Online Pages displaying
STDNT_CAR_TERM.TUIT_CALC_REQ(STDNT_TUITION_CALC,WITHDRAWAL,QUICK_ADMIT_WRK2,OEE_ENRL_DATES) and whether each page field is editable or display-only. - Component Interfaces exposing the field and their access mode (
ENRL_GRADESandENRL_TERM_ACTIVTNas Read/Write;CHI_STDNT_ACTIVATIONas Read-Only). - Direct PeopleCode References to
STDNT_CAR_TERM.TUIT_CALC_REQ.
Searching PeopleCode, App Engine SQL, and SQL Objects
Direct RECORD.FIELD metadata references only tell part of the story. In Campus Solutions, many programs update PS_STDNT_CAR_TERM via raw SQLExec("UPDATE PS_STDNT_CAR_TERM SET TUIT_CALC_REQ = 'Y' ..."), through the view STDNT_CAR_TE_VW, or via Application Engine SQL actions.
The agent invoked search_code_sql across peoplecode, appengine, and sqlobject scopes:
{
"tool": "search_code_sql",
"arguments": {
"db": "CS92DEV-CHG",
"query": "TUIT_CALC_REQ",
"scope": "all"
}
}
This surfaced 89 PeopleCode matches and all Application Engine SQL steps referencing TUIT_CALC_REQ, including batch SQL updates in the Student Group process (SCC_STD_GRP steps MVOVRD.MVOVRD45 and MVTRGT.MVTRGT45) and SQLExec updates buried inside Residency (RESIDENCY_OFF), Optional Fees (OPT_FEE_STDNT), Student Equation Variables (STDNT_EQUTN_VAR), Student Groups (STDNT_GRPS), and Student Waivers (SSF_STD_WAIVER / SSF_SWVR_PS).
Checking COBOL Stored SQL in SQLSTMT_TBL
Campus Solutions relies heavily on COBOL batch programs (SRPCENRL, SRPCCUMM, SFPBCALC, SFPRCALC) whose SQL statements live in PS_SQLSTMT_TBL, completely outside App Designer’s PeopleCode and SQL definitions.
Using query_table, the agent queried SQLSTMT_TBL for statements touching TUIT_CALC_REQ or updating PS_STDNT_CAR_TERM:
{
"tool": "query_table",
"arguments": {
"db": "CS92DEV-CHG",
"record_name": "SQLSTMT_TBL",
"fields": ["PGM_NAME", "STMT_TYPE", "STMT_NAME", "STMT_TEXT"],
"filters": [
{ "field": "STMT_TEXT", "op": "like", "value": "%TUIT_CALC_REQ%" }
],
"limit": 100
}
}
That query separated the COBOL programs that clear the flag (SFPBCALC, SFPBHECS, SFPCCALC, SFPCLCAN, SFPRCALC, SFPREFND, which all run SET TUIT_CALC_REQ = 'N') from the COBOL program that updates it during enrollment and term statistics processing: SRPCCUMM (STMT_NAME = 'CUMTERM'), which executes:
UPDATE PS_STDNT_CAR_TERM
SET ...,
FA_STATS_CALC_REQ = 'Y',
TUIT_CALC_REQ = :54,
...
WHERE EMPLID = :63
AND ACAD_CAREER = :64
AND INSTITUTION = :65
AND STRM = :66
Reading Full Event Context and Catching Commented-Out Code
A substring search for TUIT_CALC_REQ matched STDNT_CAR_SEQ.STDNT_CAR_NBR.SavePreChange at line 156:
UpdateValue(STDNT_CAR_TE_VW.TUIT_CALC_REQ, &I, "Y");
If you only look at a single matching line from a grep or SQL query on PSPCMTXT, you would list STDNT_CAR_SEQ.STDNT_CAR_NBR.SavePreChange as an active trigger. Instead, the agent called get_peoplecode to inspect the surrounding program:
{
"tool": "get_peoplecode",
"arguments": {
"db": "CS92DEV-CHG",
"name": "STDNT_CAR_SEQ.STDNT_CAR_NBR",
"event_or_step": "SavePreChange"
}
}
Inspecting the full PeopleCode event revealed that Oracle had wrapped lines 150–159 of STDNT_CAR_SEQ.STDNT_CAR_NBR.SavePreChange inside a /* ... */ block comment and moved the active logic to DERIVED_CS.ROW_NUMBER.SavePreChange! The agent also used get_peoplecode on STDNT_CAR_TERM.REG_CARD_DATE.SavePreChange to extract the exact list of 20 FieldChanged(...) conditions that trigger tuition recalculation when a student’s term record is edited.
The Complete Research Output
Within seconds, the agent produced a complete inventory of every mechanism that sets STDNT_CAR_TERM.TUIT_CALC_REQ to 'Y':
Record Field Default (PSRECFIELD)
STDNT_CAR_TERM.TUIT_CALC_REQ(andSTDNTCARTERM_DR.TUIT_CALC_REQ) defaults fromBUS_UNIT_TBL_SF.TERM_ACT_INIT_SET. WhenTERM_ACT_INIT_SET = 'Y', any new row orSetDefault(STDNT_CAR_TERM.TUIT_CALC_REQ)call (such as inSTDNT_CAR_TERM.STRM.FieldChangeline 41 andSTDNT_CAR_TERM.STDNT_CAR_NBR.FieldChangeline 40) setsTUIT_CALC_REQto'Y'.
Record Field PeopleCode
STDNT_CAR_TERM.EMPLID.RowInit(line 362): SetsSTDNT_CAR_TERM.TUIT_CALC_REQ = "Y"when%Mode = "A"(Add mode).STDNT_CAR_TERM.REG_CARD_DATE.SavePreChange(line 33): InTERM_HISTORYorSTDNT_ACTIVATION, setsSTDNT_CAR_TERM.TUIT_CALC_REQ = "Y"on an existing term row if any of these 20 fields onSTDNT_CAR_TERMchanged:ACADEMIC_LOAD,ACAD_LEVEL_BOT,ACAD_LEVEL_PROJ,ACAD_LOAD_APPR,STDNT_CAR_NBR,ACAD_PROG_PRIMARY,ACAD_YEAR,BILLING_CAREER,CUR_RESIDENT_TERMS,TRF_RESIDENT_TERMS,ELIG_TO_ENROLL,FORM_OF_STUDY,FULLY_ENRL_DT,LAST_DATE_ATTENDED,PROJ_BILL_UNT,OVRD_BILL_UNITS,WITHDRAW_CODE,WITHDRAW_DATE,INSTITUTION, orSTRM.STDNT_CAR_TERM.OVRD_TUIT_GROUP.FieldChange(line 3): InSTDNT_ACTIVATIONorTUITION_CALC, setsSTDNT_CAR_TERM.TUIT_CALC_REQ = "Y"whenOVRD_TUIT_GROUPchanges.DERIVED_CS.ROW_NUMBER.SavePreChange(line 26): InACAD_PLAN(Student Program/Plan), setsSTDNT_CAR_TE_VW.TUIT_CALC_REQ = "Y"for terms>= &TERMwhenACAD_PROG.PROG_STATUSis"AC","AD", or"AP".DERIVED_CS.UPDATE_CUM.SavePreChange(line 23) &FUNCLIB_CS.TOT_CUMULATIVE.FieldFormula(get_cur_term, line 426): SetSTDNT_CAR_TERM.TUIT_CALC_REQto"Y"viaUpdateValue(STDNT_CAREER.EMPLID, ..., STDNT_CAR_TERM.TUIT_CALC_REQ, 1, "Y")when updating term/cumulative enrollment statistics.STDNT_ENRL_OEE.END_DT.FieldChange(lines 2–3): InOEE_CALENDAR, setsGetLevel0()(1).STDNT_CAR_TERM(1).STDNT_CAR_TERM.TUIT_CALC_REQ.Value = "Y".SSR_HECS_ELEC.SSR_HECS_XMPT_STAT.SavePreChange(line 3): SetsSTDNT_CAR_TERM.TUIT_CALC_REQ = "Y"whenFieldChanged(SSR_HECS_ELEC.SSR_HECS_XMPT_STAT).RESIDENCY_OFF.INSTITUTION.SavePostChange(lines 14, 16, 21): InRESIDENCY_ADMA,RESIDENCY_ADMP, orRESIDENCY_PERS, whenDERIVED_CC.TUIT_CALC_REQ = "Y"(set byFieldChangeonRESIDENCY_OFF.EFFECTIVE_TERM,INSTITUTION,RESIDENCY, orTUITION_RES) or when a residency row is deleted, runsSQLExec("UPDATE PS_STDNT_CAR_TERM SET TUIT_CALC_REQ = 'Y' WHERE EMPLID = :1 AND ACAD_CAREER = :2 AND INSTITUTION = :3 AND STRM >= :4", ...).OPT_FEE_STDNT.VALID_VALUE.SavePreChange(line 5): WhenRecordChanged(OPT_FEE_STDNT.VALID_VALUE), runsSQLExec("update ps_stdnt_car_term set tuit_calc_req = 'Y' where emplid = :1 and institution = :2 and strm = :3 and billing_career = :4", ...).STDNT_EQUTN_VAR.STRM.SavePostChange(lines 7, 10): RunsSQLExec("UPDATE PS_STDNT_CAR_TERM SET TUIT_CALC_REQ = 'Y' WHERE EMPLID = :1 AND BILLING_CAREER = :2 AND INSTITUTION = :3 AND STRM = :4", ...)for bothSTDNT_EQUTN_VAR.STRMand&PRIOR_TERM.STDNT_GRPS.INSTITUTION.SavePostChange(lines 32, 49, 71): InSTDNT_GROUPS_ADMA,STDNT_GROUPS_ADMP, orSTDNT_GROUPS_PERS, when&TUIT_RECALC_REQ = "Y"(or a student group row is deleted), runsSQLExec("UPDATE PS_STDNT_CAR_TERM SET TUIT_CALC_REQ = 'Y' WHERE EMPLID = :1 AND INSTITUTION = :2 AND ACAD_CAREER = :3 AND STRM = :4", ...)for terms withTERM_BEGIN_DT >= &STDNT_GROUP_EFFDT.
Application Package PeopleCode
SSR_CAREER_TERM:Accessors:StudentTerm(OnExecute):- Lines 1284 / 4268: Sets
%This.TUIT_CALC_REQ = &recBUS_UNIT_TBL_SF.TERM_ACT_INIT_SET.Valueduring term creation. - Lines 1785 / 4769: Sets
%This.TUIT_CALC_REQ = "Y"using the same field-change rules asSTDNT_CAR_TERM.REG_CARD_DATE.SavePreChange. - Lines 2629 / 5613: Property setter
set TUIT_CALC_REQassigns%This.data.TUIT_CALC_REQ.Value = &NewValue.
- Lines 1284 / 4268: Sets
SSR_FA_DATA_UPD:ProcessFAUnits(OnExecute, line 244): Sets&REC_stdntcarTerm.TUIT_CALC_REQ.Value = "Y"and updatesSTDNT_CAR_TERM.SCC_POP_UPDATE:APEngine:STDNT_EQUTN_VAR(line 63),SCC_POP_UPDATE:APEngine:PopUpdateCommonProcessing(lines 734, 1234), andSCC_POP_UPDATE:APEngine:RowByRowProcessing(lines 734, 1234):- When Population Update inserts or updates
STDNT_EQUTN_VAR, it loadsSTDNT_CAR_TERMby key, sets&StudentCarTerm.TUIT_CALC_REQ.Value = "Y", and calls.Update(). - When Population Update modifies
STDNT_CAR_TERM.OVRD_TUIT_GROUP, it also setsTUIT_CALC_REQto"Y".
- When Population Update inserts or updates
SSF_TUITION_AND_FEES:Components:SSF_STD_WAIVER(OnExecute, line 414): RunsSQLExec("UPDATE PS_STDNT_CAR_TERM SET TUIT_CALC_REQ = 'Y' WHERE EMPLID = :1 AND INSTITUTION = :2 AND STRM = :3", SSF_STDNT_WVR.EMPLID, &Institution, SSF_STDNT_WVR.STRM)when saving student waivers.
Application Engine Programs
SSF_SWVR_PS(LINEPROC.OnExecutePeopleCode, line 11): RunsSQLExec("UPDATE PS_STDNT_CAR_TERM SET TUIT_CALC_REQ = 'Y' WHERE EMPLID = :1 AND INSTITUTION = :2 AND STRM = :3", SSF_SWVR_PS_AET.EMPLID, &Institution, SSF_SWVR_PS_AET.STRM).SCC_STD_GRP(MVOVRD.MVOVRD45andMVTRGT.MVTRGT45SQL actions): UpdatesPS_STDNT_CAR_TERM A SET A.TUIT_CALC_REQ = 'Y'whereSTDNT_GRP_AET.TUIT_CALC_REQ_LBL = 'Y',A.TUIT_CALC_REQ = 'N', andTERM_BEGIN_DT >= ASOFDATE.
COBOL Stored SQL (SQLSTMT_TBL)
SRPCCUMM(CUMTERM): UpdatesPS_STDNT_CAR_TERM SET ..., FA_STATS_CALC_REQ = 'Y', TUIT_CALC_REQ = :54, ...during enrollment and cumulative statistics processing (SRPCENRL/SRPCENVB).
Online Pages & Component Interfaces
- Online Pages:
STDNT_CAR_TERM.TUIT_CALC_REQis directly editable onSTDNT_TUITION_CALC(componentsSTDNT_ACTIVATIONandTUITION_CALC),WITHDRAWAL(componentTERM_HISTORY), andQUICK_ADMIT_WRK2(componentQUICK_ADMIT). - Component Interfaces: Exposed as Read/Write (
BCACCESS = 2) onENRL_GRADESandENRL_TERM_ACTIVTN.
Why This Changes PeopleSoft Impact Analysis
Answering this question manually in Application Designer typically takes an experienced PeopleSoft developer an hour or more of cross-referencing Find Definition References, Find In across PeopleCode and SQL, checking record field properties, and writing custom SQL against PS_SQLSTMT_TBL — assuming they even remember to check views like STDNT_CAR_TE_VW and COBOL stored statements.
With the psLens MCP Server, an AI agent in Google Antigravity, Claude Code, Cursor, or VS Code has read-only, whitelisted access to the entire PeopleSoft metadata graph and code repository:
| MCP Tool Used | Role in the Investigation |
|---|---|
list_databases | Identified the target Campus Solutions 9.2 database (CS92DEV-CHG) |
get_record_schema | Resolved TUITION_CALC_REQ → TUIT_CALC_REQ and uncovered the BUS_UNIT_TBL_SF.TERM_ACT_INIT_SET default |
analyze_record_field_impact | Mapped every page, component, Component Interface, and direct PeopleCode reference |
search_code_sql | Found inline SQLExec("UPDATE PS_STDNT_CAR_TERM ...") calls, view updates (STDNT_CAR_TE_VW), and App Engine SQL actions |
query_table | Inspected COBOL stored SQL statements in PS_SQLSTMT_TBL (SRPCCUMM vs. SFPBCALC) |
get_peoplecode | Verified full event logic, extracted the 20 trigger fields on REG_CARD_DATE.SavePreChange, and filtered out commented-out legacy code |
Try It on Your Own Environment
The embedded MCP server ships inside psLens with zero extra infrastructure required:
- Read the MCP Server & Agent Skills Documentation for setup instructions across Google Antigravity, Claude Code, VS Code, and Claude Desktop.
- Explore the Connecting AI Agents to PeopleSoft with MCP architecture overview.
- Book a live demo to see psLens MCP answer impact analysis and security questions against a live PeopleSoft environment.
Subscribe for Updates
If you found this article helpful, subscribe to get notified of new PeopleSoft technical notes and psLens updates.