docs: the host is the source of truth, not the record - #238
Merged
Merged
Conversation
The page had the idempotency table and nothing about what happens when somebody changes the host outside osapi, which is the case these operations exist to handle. The rule existed only in osapi-io/osapi@c3e028e8. Two decisions in the file provider trusted the record and both let real drift stand. A config edited by hand still carries the SHA the last deploy wrote, so comparing against that SHA called it unchanged and skipped the one file that needed the deploy. Ownership compared the requested owner against the recorded owner, so a chown by somebody else was invisible. States the rule, the two consequences that are easy to get wrong, and why this is the one place the filesystem abstraction is not enough. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FuKUsHFG1EqZXamffh9M2c
|
Thank you for contributing to this project! 😊🕹️ |
The page had the idempotency table and nothing about what happens when somebody changes a managed resource outside osapi, which is the case these operations exist to handle. The rule existed only in osapi-io/osapi@c3e028e8. osapi is what the resource is supposed to look like and an edit by hand does not change that, so the next operation overwrites it. Overwriting drift means seeing it, and a provider cannot see it by consulting its own record, because the record says what osapi last wrote and that is exactly what drift makes untrue. The decision is made by reading the resource; the record is written, not read. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FuKUsHFG1EqZXamffh9M2c
This was referenced Oct 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
One section in
components/osapi/providers.md.The page has the idempotency table and says nothing about what happens when somebody changes the host outside osapi. That is the case these operations exist to handle, and the rule lived only in a commit message: osapi-io/osapi@c3e028e8.
What that commit found
Two decisions in the file provider trusted the record instead of the host, and both let real drift stand.
The idempotency check compared the content it was asked to deploy against the SHA the last deploy recorded. A config edited by hand still carries that SHA, so the check called it unchanged and walked away. The one case a deploy exists to fix was the one it skipped.
Ownership had the same shape. The requested owner and group were compared with the ones recorded, so a
chownby somebody else was invisible.What the section says
The comparison is against the file on disk and against the file's actual uid and gid. The state record is written, not read: it serves status, staleness and audit, and does not decide.
Plus the two consequences that are easy to get wrong:
passwdentry needs.chownruns.And why this is the one place the filesystem abstraction is not enough: reading uid and gid needs the stat structure it does not carry, so that read goes to the OS behind an injectable seam.
Why it goes here
It is a rule every provider obeys, so it belongs in the contract page rather than in the skill. A rule restated in a skill drifts from the one in the corpus, and the copy an agent happened to load wins.
First of several. Next are the 58 dead
FR-pointers inadd-a-domain, then the domain naming divergence, then the per-domain pages.just testpasses.🤖 Generated with Claude Code
https://claude.ai/code/session_01FuKUsHFG1EqZXamffh9M2c