Builder Receipt: Rebuilding Cypher’s Core

Cypher kept giving me the wrong schedule even when the right information was already stored. After enough failures, the problem was no longer whether it needed another patch. The problem was whether the system responsible for deciding what was true had reached its limit.

The Schedule Failures Were Not Isolated Bugs

Most of my work on Cypher this week started with schedule questions that should have been easy.

I had already told Cypher that I would be working from 8:00 a.m. to 4:00 p.m., Monday through Friday, for one week. The record had been saved with the correct dates, expiration, confidence, and write verification. When I asked what I was working that week, Cypher gave me my normal 2-2-3 overnight rotation instead.

Another day changed from 8:00 a.m. to 4:00 p.m. to noon through midnight, with six hours of training followed by six hours working control. Cypher acknowledged the change correctly. I asked for the schedule again, and it returned the old daytime hours. I corrected it, Cypher repeated the new schedule, and then the next question brought the old schedule back again.

Later, I told Cypher that work was finished and I had the next two days off. That statement was also stored correctly, including the Saturday and Sunday date range. When I asked whether I was working Saturday, Cypher still told me I was scheduled.

Those failures mattered because schedule awareness is not a side feature inside Cypher. My schedule affects sleep, training, family time, meal preparation, daily planning, and the way Cypher should interpret almost everything happening around me. If the schedule is wrong, the rest of the context becomes questionable.

The first step was determining whether Cypher had forgotten the information or had failed to use it. The backups showed that the records existed. The dates and hours were present. The write verification had passed. The problem was happening after storage.

Cypher’s regular rotation had an unfair advantage. The baseline schedule was calculated locally and injected into every response. Temporary changes depended on general memory retrieval finding the correct record. The permanent schedule was always available, while an override was only available when retrieval worked.

The prompt told the model that temporary schedule changes should take priority, but that instruction could not help when the override never reached the model. Cypher could not apply a record it had not been given.

Future schedules created another problem. One temporary schedule began on Monday, but I asked about it on Sunday. The memory system excluded records whose effective date was still in the future, even when the question explicitly concerned that future period. Cypher could store an upcoming plan, but it could not reliably retrieve the plan before it became active.

That might be acceptable for some kinds of current-state information. It does not work for schedules. A personal assistant has to answer questions about tomorrow, next week, upcoming shifts, appointments, and future obligations. A dated record should be available whenever the requested range overlaps it, not only after its start date arrives.

The correction system had its own flaw. I had supplied a temporary schedule covering July 13 through July 19. It said I would work 11:00 a.m. to 11:00 p.m. on Monday, Tuesday, Thursday, Friday, and Saturday, with Wednesday and Sunday off. When Cypher later claimed I was working Sunday, I corrected it.

The correction was valid, but the system created a one-day Sunday record and marked the full seven-day schedule as superseded. The weekly record was not wrong. It already said Sunday was off. A narrow confirmation had destroyed a broader record containing the rest of the week.

That failure exposed the missing rule. A correction should control only the dates it actually changes. If Friday changes, Friday changes. If the weekend becomes days off, Saturday and Sunday change. The surrounding schedule remains intact.

Cypher was treating similarity as contradiction. It needed to understand scope.

Moving Schedule Truth Out of General Memory

The first major change was moving effective schedule resolution out of the language model.

Instead of giving the model a normal rotation and whatever schedule memories happened to be retrieved, Cypher began resolving the schedule in PHP before the answer was written. The resolver gathered the regular rotation, temporary weekly schedules, date-specific changes, one-day exceptions, days-off records, corrections, and overlapping schedule information.

It then merged those records by date using a clear precedence order. The regular rotation established the baseline. A schedule for a specific week overrode the baseline. A date-specific exception overrode the weekly schedule. A newer correction for the same date overrode the older exception.

The language model could still explain the schedule naturally, but it would no longer decide which record controlled the date.

That was an important boundary. Determining whether I work on Tuesday, when the shift begins, and when it ends is structured operational logic. It should not depend on which text fragment sounds most relevant to a model.

I tested the exact failure that had exposed the future-record problem. The current date was Sunday, July 19, and the question was, “What is this week’s schedule?” The correct result needed to be the upcoming Monday-through-Sunday workweek, with 8:00 a.m. to 4:00 p.m. Monday through Friday and the weekend off.

The first repair improved most of the behavior, but two tests still failed. Cypher treated “this week” on Sunday as the week ending that day instead of the upcoming workweek. It also failed to restore the historical July 13 through July 19 schedule after the one-day Sunday correction had damaged it.

That result stopped me from declaring the upgrade complete.

Relative date language needed an explicit rule. A question such as “What did I work this week?” is retrospective. A question such as “What is this week’s schedule?” is forward-looking. On Sunday, those questions can refer to different ranges.

I moved direct schedule questions onto a deterministic response path and anchored their date interpretation to the local Indianapolis time captured when the message was submitted. The model could no longer receive a correct range and then reinterpret it using broader conversation context.

The repair migration also needed a better containment rule. The first version failed because the one-day Sunday record sat on the final date of the weekly schedule. I changed the comparison so a one-day record on the first or final date of a broader range is still treated as contained inside that range. It can layer over the date without replacing the full week.

After that change, Cypher correctly returned the upcoming daytime schedule, the correct Friday hours, Sunday off, and the restored July 13 through July 19 schedule. It also gave the same historical answer when I called that range “last week.”

Then the noon-to-midnight shift exposed another problem.

The model understood the phrase. The structured resolver did not. Cypher could repeat the correction from recent conversation context, but the authoritative schedule system could not convert “noon to midnight” into a usable time range. The conversation and the schedule database were operating from different versions of reality.

I added deterministic parsing for clear schedule updates, including noon, midnight, and the six-hour training followed by six-hour control breakdown. Obvious schedule changes should not rely completely on an AI memory extractor deciding whether they are worth storing.

The regression passed.

I installed the upgrade and asked Cypher for the schedule.

It still returned 8:00 a.m. to 4:00 p.m.

The test had proven that the parser could create an override in isolation. It had not proven that the live chat path saved the record or that the installed upgrade repaired the existing message.

I had tested the middle of the pipeline and treated that as evidence that the entire pipeline worked.

The installed behavior proved otherwise.

A Passing Test Was Not Proof of a Working Upgrade

The deeper failure was inside the upgrade migration.

The new files had been copied into place, but the migration ran during a PHP request that had already loaded the previous version of Cypher’s functions. The migration depended on a parser introduced by the new version. That parser existed on disk, but it was not available inside the already-running process.

The migration checked for the function, failed to find it, returned quietly, and was still marked complete.

The upgrade looked successful. The schedule backfill had never run.

The original message containing the noon-to-midnight change remained in the conversation history, but no authoritative schedule record had been created from it. When Cypher answered the question again, the resolver returned the only structured record it actually had, which was the older 8:00 a.m. to 4:00 p.m. schedule.

I replaced the failed migration with a repair that contained the parsing logic it needed instead of depending on newly loaded application functions. It used the original message timestamp to resolve “today” to Thursday, July 23, 2026, created the noon-to-midnight override, and retained the training and control details.

I also changed the migration failure behavior. A required backfill cannot quietly exit and still be recorded as successful. If the write fails, the upgrade must fail visibly.

A visible failure is better than a successful-looking upgrade that leaves the system operating from stale data.

The replacement regression reproduced the real upgrade condition. It simulated the older PHP process, ran the repair against the original user message, verified the database record, passed that record through the actual schedule resolver, and asked for the schedule twice.

Both lookups returned noon through midnight.

I installed the upgrade and asked Cypher directly. It returned Thursday, July 23, from 12:00 p.m. to 12:00 a.m., with six hours of training followed by six hours working control.

That live result was the real confirmation.

The next failure involved my weekend off. Cypher had stored the correct dates, but the record was classified as days_off. The schedule resolver only searched records labeled work_schedule, so it ignored the time-off information and allowed the older weekly schedule to control the answer.

The problem was not forgetting. The system had decided that the correct record did not count.

I changed schedule resolution so verified time-off records can participate regardless of whether they were classified as work schedules, days off, or another recognized schedule topic. The resolver now evaluates the dates, meaning, scope, recency, and authority of the information instead of depending on one exact label.

Common phrases such as “the next two days off,” “this weekend off,” “next weekend off,” and explicit multiday ranges now become dated schedule exceptions. A newer time-off record can override the dates it covers without erasing the surrounding week.

In the original failure, Friday remained an 8:00 a.m. to 4:00 p.m. workday, while Saturday and Sunday correctly became days off.

I tested the exact July 25 sequence, explicit dates, natural wording, multiday time off, later corrections, reversals, fresh conversations, and application restarts. The corrected schedule persisted outside the conversation where I first gave it.

The individual schedule defects were fixed, but the work had exposed something larger.

General memory was being asked to perform too many different jobs.

The Problem Was Authority, Not Memory

Cypher’s memory system contained long-term facts, current feelings, temporary plans, work schedules, project states, completed events, uploaded documents, conversation history, corrections, and assistant interpretations.

Those types of information do not behave the same way.

A stable preference may remain true for years. A feeling about a job may only describe the current period. A completed event belongs in history. A correction should change the current truth without deleting proof that the old record once existed. A schedule needs exact dates, overlapping ranges, overnight boundaries, precedence rules, and deterministic answers.

Cypher needed to know which system owned each kind of truth.

I stopped treating every failure as another schedule parser problem and began rebuilding the context core.

Schedules moved into dedicated operational state.

Personal facts moved into a typed knowledge layer.

Health information moved into structured observations.

Source events preserved what I originally said, uploaded, corrected, or confirmed.

Answer audits began retaining the exact records and resolver output behind consequential answers.

The language model remained responsible for reasoning, interpretation, and communication. It was no longer allowed to decide foundational facts based on whichever retrieved text sounded strongest.

Once scheduling had its own source of truth, I tested the broader personal memory system.

Cypher could explain complicated parts of my employment history, recovery, Johnson County, Centerstone, my current work frustration, and Bonumark Stream. Then I asked who my pets were.

It knew I had cats. It could not retrieve Blu, Milo, Hawkeye, or Winnie.

That showed how heavily memory quality depended on the source. Information found in resumes, published writing, structured imports, or repeatedly discussed subjects was easier to retrieve. Smaller but stable personal facts mentioned in ordinary conversation could remain buried.

I did not create a pet-specific fix.

I built a broader personal knowledge layer for people, relationships, pets, employment, preferences, projects, and current state. The system uses typed entities, aliases, relationships, claims, evidence, effective dates, expiration dates, supersession, confidence, and source authority.

Direct corrections and direct user statements carry the most authority. Uploaded documents, structured imports, verified records, archived user messages, and published work can support claims. Assistant-generated summaries and interpretations cannot become authoritative facts by themselves.

That boundary matters because an assistant can create a polished explanation containing an inference I never stated. Fluency is not evidence.

The migration promoted only facts that could be supported from actual sources. Ambiguous material remained historical or entered review rather than being forced into the new ledger.

Questions could then route according to the type of truth involved. Family questions use verified entities and relationships. Work-history questions use dated employment records. Current-job questions use time-bound state. Schedule questions remain inside the schedule resolver.

The model writes the final answer, but the factual core comes from the system responsible for the information.

The automated suite passed. My first live question did not.

I asked Cypher who my pets were and received SQLSTATE[HY093]: Invalid parameter number.

The new query reused the same named SQL placeholder twice. The test environment allowed it, but the native prepared statements in my actual MySQL setup did not.

The failure was not limited to pets. Any personal-knowledge lookup could have triggered the same error.

I replaced the reused placeholder with separate bindings and added a regression that reproduces the native MySQL behavior. After installing the repair, Cypher correctly identified Blu and Milo as my cats and Hawkeye and Winnie as my dogs. It also correctly handled family relationships, employment history, current job context, projects, and schedules.

The knowledge layer worked.

Then a correct answer exposed the next weakness.

Correct Answers Needed a Traceable Evidence Path

I asked Cypher what I was working Tuesday.

It correctly answered that I worked Tuesday, July 28, from 5:00 p.m. through Wednesday, July 29, at 5:00 a.m.

Then I asked what records supported the answer.

Cypher said the records did not support the shift and claimed it had overstated the result.

The original answer was correct. The evidence follow-up was wrong.

The backup showed that July 28 was part of a long week under my normal 2-2-3 rotation. Tuesday was correctly configured as a shift-start day. The schedule resolver had done its job.

The audit had not preserved the exact Tuesday result. When I asked for evidence, Cypher rebuilt context around the current date instead of opening the records behind the answer it had just given.

A correct answer became untrustworthy because the system could not prove why it was correct.

I added a direct provenance requirement. Every authoritative answer must remain connected to the exact records and resolver output that produced it.

Schedule audits now preserve the requested date or range, the result for each date, the controlling source, whether the baseline or an override won, the applicable rotation, shift-start days, start and end times, conflicting candidates, shadowed records, and unresolved conflicts.

Evidence follow-ups now route to the immediately previous answer audit. Cypher does not perform another general search or switch back to today. It opens the evidence behind the actual answer.

For older audits that lack the new detail, Cypher reruns the exact audited range through authoritative state instead of using the current date.

I repeated the Tuesday test. Cypher returned the correct shift. When I asked for the supporting records, it identified the requested date, the long-week rotation, the scheduled shift-start days, the start and end times, the absence of a date-specific override, and the lack of any unresolved conflict.

It also clarified that the shift began Tuesday evening. It was not a Monday shift that happened to end Tuesday morning.

The answer was correct, and the evidence matched it.

That same continuity problem appeared in document retrieval.

I had uploaded my resume because I wanted Cypher to understand my complete work history. The file was stored, divided into seven chunks, and fully embedded. When I asked Cypher to find it, older conversational excerpts outranked the actual document and filled the retrieval limit before the resume appeared.

A follow-up such as “look for it” lost the subject because Cypher searched those words without carrying forward what “it” referred to. The system also gave too little weight to filenames and source titles. A document literally called “Resume” could lose to loosely related semantic matches.

I changed document retrieval so exact source names, original filenames, and title matches outrank weaker conversation fragments. Recent user context now helps resolve references across follow-up questions. Resume, employment history, career history, complete work history, and common misspellings are normalized into the same retrieval path.

The first repair found the resume. Then I asked for my complete work history in chronological order, and Cypher failed again.

The follow-up did not repeat the word “resume,” so the source was dropped. The test also exposed a prompt-construction defect. Resume chunks were approximately 1,600 characters long, but only the first 1,200 characters of each chunk were passed to the model. The chunks overlapped by 200 characters, so trimming 400 characters created gaps.

Four complete job headings and their dates disappeared. The prompt preserved only 9 of the 13 positions in the resume.

Cypher could truthfully say it found the document while still lacking enough of the document to answer accurately.

I added source continuity across follow-up questions, increased full-document retrieval to support up to 24 ordered chunks, and stopped trimming expanded chunks. Each chunk is now labeled with its source and position inside the document.

The exact two-turn conversation became a regression test:

“Now look for my resume.”

“Give me my complete work history in chronological order.”

The repaired path kept the document active and preserved all 13 employment entries and date ranges.

Storage was not enough.

Retrieval was not enough.

Source continuity and document completeness had to work too.

Rebuilding the Core Without Rebuilding the Entire Application

As I tightened authority and verification, I introduced another set of regressions.

The first integrated context upgrade added interaction modes for conversation, reflection, coaching, factual lookup, writing, correction, project work, status, and action. It also added an effective waking-day state, project records, decision records, memory lifecycle states, and deterministic response validation.

The initial test suite passed.

Then I said hello.

Cypher replied that it could not verify a reliable answer from the active context records.

The validator had been given too much authority. It used word overlap as evidence that a response matched the request. “Hi, Jim” did not repeat the word “hello,” so a normal greeting was rejected and replaced with a database-style failure message.

That was not a missing phrase. It was a bad design decision.

A weak heuristic had been allowed to overwrite ordinary conversation.

I changed the boundary. Casual conversation no longer requires a formal assurance record. Word overlap remains available as an audit signal, but it cannot block a natural reply. Strict verification stays active for schedules, publishing, deployments, migrations, completed work, and other consequential claims.

The failed greeting became a permanent regression test.

The same assurance layer also broke daily recaps. The recap system already used user messages, timeline events, and confirmed published posts as evidence. The new validator used a different reference format and could erase an otherwise valid recap after it had been built.

I aligned the evidence formats and changed the failure behavior. Malformed references can still be recorded for review, but the validator cannot delete a valid recap. Strict blocking remains reserved for actions where unsupported certainty creates actual risk.

The largest regression involved schedule persistence. I gave Cypher a mixed schedule for the following week, corrected Friday, and later clarified that Saturday and Sunday were off. Cypher acknowledged every change correctly, but every schedule lookup returned the old rotating baseline.

The conversation sounded correct. The authoritative database was wrong.

The backup showed the entire failure chain. The schedule update had been classified as ordinary conversation. The deterministic parser returned nothing. The learning system discarded the schedule because it was temporary. No dated records were created. The model still said “got it.” The resolver continued reading the baseline.

My complaint that Cypher was not retaining schedule changes was then misread as a preference that schedules should not be retained.

That was the point where another instruction would have been dishonest.

I replaced the schedule write path.

Clear schedule updates now bypass general memory learning and become individual dated records. Each date carries its own work status, off status, start time, end time, and overnight boundary. A mixed week is no longer stored as one vague sentence.

The update is atomic. Cypher either writes and verifies every affected date or retains none of the change. Corrections apply only to the dates named.

Most importantly, Cypher cannot confirm that it retained the schedule until it reads the stored records back through the same resolver used for later answers.

The model saying “got it” no longer counts as proof that anything was saved.

At that point, the direction was clear. I did not need to rebuild the entire application. Cypher already had working authentication, conversations, attachments, health imports, publishing integrations, backups, administrative tools, and a usable interface.

The application shell was not the problem.

The context engine was.

I kept the shell and rebuilt the core around stronger rules. Original statements, corrections, uploads, imports, attachments, and confirmed actions remain preserved as source events. Schedule truth resolves through dated shift occurrences. Personal facts resolve through an authoritative ledger. Health information resolves through structured observations. Stronger sources outrank weaker interpretations. Corrections replace current authority without erasing history. A write is not confirmed until readback proves the same resolver can retrieve it later.

That became Cypher 2.0.

The new schedule system ties every shift to the date it begins, with an explicit start and end time. That makes overnight work clear. If a Monday shift ends Tuesday morning, Cypher can distinguish between being at work Tuesday morning and being scheduled to begin a new shift Tuesday evening.

Possible plans remain possibilities until I confirm them. Repeated corrections are idempotent. Invalid dates are rejected. Changing one day does not erase another. Opening a new conversation does not return the system to an older schedule.

The first installation attempt failed with a MariaDB syntax error because a migration used a placeholder inside SHOW TABLES LIKE ?. I replaced that check with a compatible information-schema query and made the migration resumable.

The next attempt failed because the upgrade request had already loaded the previous version’s PHP functions. Even though the new files were on disk, the migration called the old definitions during the same request. I isolated the migration runtime and gave it its own function names.

The next failure came from another reused named SQL parameter. The schedule write had succeeded, but Cypher crashed while building the confirmation response. I rewrote the query so every condition had its own binding and audited the rest of the code for the same pattern.

Those failures were frustrating, but they were useful. Static analysis and isolated regressions could not reproduce every MariaDB and same-request runtime behavior. Installing and using the upgrade could.

Testing the Rebuilt System Through Real Use

Once Cypher 2.0 installed correctly, I tested it through ordinary language instead of only through fixtures.

I supplied a complete seven-day schedule containing daytime shifts, overnight shifts, and days off. Cypher stored and returned every date correctly.

I changed one day from a daytime shift to noon through midnight. Only that date changed.

I asked whether I was scheduled to begin a shift on an off day after an overnight shift. Cypher correctly said no. I asked whether I would still be at work early that morning, and Cypher correctly said yes because the previous shift had not ended.

I changed another workday to off and confirmed that the surrounding dates remained intact. I repeated an identical correction and verified that no duplicate shift appeared.

I told Cypher I might work an off day, but nothing was confirmed. The day remained off. When I later confirmed the shift, Cypher replaced the off entry and correctly identified the following morning as the shift’s end.

I supplied an impossible date. Cypher rejected it and verified that no record had been created.

I opened a new conversation and asked about the corrected schedule. The answer remained correct, proving that the schedule came from authoritative storage rather than recent conversational context.

The broader migration testing exposed additional gaps. A precise recovery milestone had not been promoted into the authoritative ledger, while a weaker relative statement had. I repaired the migration so the strongest direct source controlled the fact and the weaker statement became historical.

An older relationship statement beginning with “This is my wife” had been parsed as if the person’s name were “This.” I repaired the record from the original user-authored source and added a deterministic relationship lookup to prevent the model from embellishing simple factual answers.

The health system answered a single-day sleep question correctly but failed when I requested a total and average across several dates. The date parser recognized the first date and stopped. I expanded it to understand natural ranges where the month or year appears only once.

After the repair, Cypher retrieved all four verified sleep records, calculated the correct total and average, and listed the individual dates.

The data had existed all along. The problem was how the request reached it.

I also tightened backup retention during the same cycle. Cypher created automatic, manual, pre-upgrade, pre-restore, and application-file backups, but only one category had a clear quantity limit. Other backups could accumulate indefinitely.

I defined one age-based policy across the system. Server-side backups now remain for seven rolling days. Cleanup runs after new backups and during normal Cypher activity. Expired files and matching database records are removed, and the audit log records what happened.

Retention failures do not turn a successful backup, restore, upgrade, or request into a reported failure. Cypher records the cleanup problem and leaves the primary operation intact.

A backup system is not complete because it creates files. The lifecycle also needs verification, retention, deletion, and safe failure handling.

What This Week Proved

The work started with Cypher giving me the wrong schedule.

It ended with a rebuilt authority model.

That progression matters because the original failures looked like memory problems. I told Cypher something, it acknowledged me, and later it answered incorrectly.

The deeper issue was that storage, retrieval, interpretation, authority, and verification were being treated as though they were the same thing.

They are not.

A fact can be stored and still lose retrieval ranking. A document can be found and still be incomplete. A correction can be understood in conversation and never reach authoritative state. A model can give the right answer while the evidence path points somewhere else. A test can pass while the installed migration never runs. A validator can protect consequential answers while destroying ordinary conversation. A temporary schedule can be time-bounded and still be authoritative.

The only way to find those failures was to follow the full path.

What did I actually say?

How was the message classified?

Did deterministic parsing activate?

Was a record written?

Was the write read back?

Which record won?

What reached the prompt?

What did the model say?

What evidence did the answer preserve?

Did the same result survive another question, another conversation, and the live installation?

That is the standard I am using for Cypher now.

It cannot claim it remembered something because the model said: “got it.” It cannot let an older schedule win because the correct record used a different topic label. It cannot allow a one-day correction to erase a week. It cannot turn a possibility into a confirmed shift. It cannot let assistant-generated language become a fact about me. It cannot give a consequential answer without retaining the records that produced it.

Cypher 2.0 is not finished in the sense that it will never expose another failure. That is not a realistic standard for a private assistant that continues growing with my life.

The difference is that the core now has clearer ownership.

Schedules belong to authoritative schedule state. Personal facts belong to the knowledge ledger. Health measurements belong to structured observations. Source events preserve what I originally said or supplied. Corrections change current truth without erasing history. Answer audits preserve the path from evidence to response.

The model still reasons, interprets, and communicates.

It just does not get to decide reality by itself.

This week did not end with another schedule patch. It ended with a stronger foundation for deciding what Cypher knows, what information currently controls the answer, and what the system can prove.


New Here?

Read Next:


Get the Work
Articles on discipline, recovery, identity, and ownership. Delivered when published.