Uh oh!
There was an error while loading. Please reload this page.
fix(spec): published agent prompts reference real exports — Object no longer binds the JS global (#9545) - #9615
Merged
Conversation
Three published agent-authoring prompts in packages/spec/prompts told agents to
import five symbols @objectstack/spec does not export. Four failed loudly. The
fifth did not: `import { Object } from '@objectstack/spec/data'` does not
resolve, so `export const AccountObject: Object = { ... }` bound to the
JavaScript global instead, and metadata authored from that prompt type-checked
against a type that constrains nothing -- false assurance handed to an
automated author.
Every substitution was measured against the built .d.ts, not guessed:
- Object -> ObjectSchema.create({ ... }), the house authoring convention (34
uses across the example apps; zero uses of the annotation form). Making the
form genuinely constrain exposed that the prompt's own example set
enable.audit / enable.workflow, neither of which exists; they are now
trackHistory / files, the pair the schema's own docstring uses.
- implement-objectql.md keeps the real Field and QuerySchema imports and
derives the metadata type as z.infer of typeof ObjectSchema, matching
prompts/instructions.md and spec's own src/contracts/schema-driver.ts. No
bare Object type is exported -- it would shadow the JS global.
- ManifestSchema -> ObjectStackDefinitionSchema on the package root. The
prompt's subject is objectstack.config.ts, which is neither /system manifest.
- IdentitySchema / PolicySchema have no bare referent anywhere in spec. Rule #2
now names RLSUserContextSchema and RowLevelSecurityPolicySchema from
@objectstack/spec/security.
- The three dead "Key Files to Watch" paths now point at stack.zod.ts,
security/rls.zod.ts and kernel/events.zod.ts.
The five baseline entries are deleted in the same commit; the gate is
reconciled in both directions and green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fs18A2DdXLVN2h8PaaFBcPContributor
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 113 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
os-steve
marked this pull request as ready for review
August 18, 2026 13:51
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 18, 2026
os-steve added a commit
that referenced
this pull request
Aug 18, 2026
…tract, not a seed count (#9649) The block claimed the file was "seeded from the five instances #9532 measured". It shipped with 16 entries (PR #9546) and has since shrunk to 0 through #9602, #9615 and #9581, so the sentence was wrong on day one and the gap kept changing meaning as the ledger shrank. Rewritten to state the contract rather than a number: what an entry is (one known instance still awaiting repair, debt not exemption), that the count is read from `entries` and never asserted in prose, that `entries: []` is the success state rather than a corrupt or deletable file, and that absence from the file means measured-and-clean rather than unscanned -- which is what the plugin-audit negative control now says for every package. No baseline entry is added, removed or edited. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
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 freeto 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.
Fixes#9545
Three published agent-authoring prompts in
packages/spec/prompts/told agents to import five symbols@objectstack/specdoes not export. Four failed loudly. The fifth did not — and that is the one this card exists for.Verified at
00ad76978(the final commit; the gate union below was re-run on that tree).Why the fifth one is different — demonstrated, not asserted
import { Object } from '@objectstack/spec/data'does not resolve, so the annotation inexport const AccountObject: Object = { ... }binds to the JavaScript globalObject. I compiled that exact shape against the built package:import { type Object } from '@objectstack/spec/data'TS2305: Module '"@objectstack/spec/data"' has no exported member 'Object'export const AccountObject: Object = { this_is_not_a_field: 'x', neither_is_this: 12345 }That second row is the defect: metadata authored from this prompt type-checks against a type that constrains nothing, and every signal says it passed.
Resolution proofs
Every substitution was measured against the built
.d.ts(pnpm --filter @objectstack/spec buildfirst), then compiled frompackages/objectql, which is both a real consumer and the literal audience ofimplement-objectql.md.ObjectSchema.create({ ... })TS2322on a bogus field typez.infer< typeof ObjectSchema >TS2353on an unknown keyObjectStackDefinitionSchema.parse(...)from@objectstack/specRLSUserContextSchema+RowLevelSecurityPolicySchemafrom@objectstack/spec/securityThe corrected
create-new-project.mdsnippet was extracted verbatim from the committed file and compiled: exit 0.Per-symbol before / after, with referent justification
1.
Object—create-new-project.md:52Referent: not a name-swap —
ObjectSchemais a Zod const, unusable as an annotation. The house authoring convention, measured rather than chosen:ObjectSchema.create({ ... })appears 34 times across the example apps, and the annotation form appears zero times.create-new-project.md:87-89legitimately callsObject.values(objects)— the JS global. Importing anything namedObjectwould shadow it. That alone rules out introducing a localObjectalias.enable.auditandenable.workflowdo not exist. The fabricated annotation had been hiding it. They are nowtrackHistory/files— the exact pair theenabledocstring indata/object.zod.tsuses, withtrackHistorydocumented as the audit-trail flag. Declared here because it is a same-class fix beyond a pure substitution.2.
type Object—implement-objectql.md:17Only the fabricated
type Objecthalf was dropped. Referent:FieldandQuerySchemaare real exports on./data, kept as-is. No bareObjecttype is exported — and the omission is deliberate, since every sibling has the full triple (Field/FieldParsed/FieldSchema) whileObjecthas onlyObjectSchema. Deriving it matchesprompts/instructions.md("interfaces must be inferred from Zod,z.infer< typeof X >") and spec's ownsrc/contracts/schema-driver.ts, which writestype DataObject = z.infer< typeof ObjectSchema >for exactly this reason.3.
ManifestSchema—implement-objectos.md:16Referent: the card framed this as
AppManifestSchemavsDeployManifestSchema; both are wrong. The prompt names its own subject —objectstack.config.ts— whose authoring surface isdefineStack/ObjectStackDefinitionSchema, on the root entry, not/system.AppManifestSchemainstalls an app into a running stack;DeployManifestSchemadescribes a deploy bundle. The subpath changes with the symbol.4.
IdentitySchema+PolicySchema—implement-objectos.md:25Referent:
/systemreturns zero matches forIdentity— there is noIdentitySchemaand no bareIdentityeither, so the card's own "measured reality" column was itself a fabrication. Substituting it as the card instructed would have written a new fabricated symbol into a published prompt.Rule #2's intent is "all request handlers validate identity; no operation proceeds without checking policy". The honest referents live on
./security:RLSUserContextSchema— documented insecurity/rls.zod.tsas "the current user's context for RLS evaluation", i.e. the per-request security context.RowLevelSecurityPolicySchema— the same file calls per-policy RLS "the live, enforced surface".A sentence was added stating plainly that no bare
Identity/Policyschema exists and that broader posture lives in the qualified schemas, so the next reader does not re-derive it.5. Three dead source paths —
implement-objectos.md"Key Files to Watch"Each now serves the same watch-purpose with a file that exists (all nine paths across both prompts re-verified present).
kernel/events.zod.tsis chosen overkernel/events/core.zod.tswhereEventSchemais physically declared, because that barrel documents itself as the stable entrypoint and theevents/*sub-modules as internal — the prompt now says so.Baseline reconciliation
The five prompt entries are deleted in this same PR (16 → 11). The diff is deletion-only — no reformatting.
pnpm build(71/71) precedes the run.Reverse verification
Re-added one fixed entry to the baseline. Predicted red on a stale entry (the baseline reconciles in both directions); observed exactly that, naming the entry:
Removed; green again, diff back to deletion-only.
Gates
Derived from the actual changed paths via
node scripts/pm/dispatch-gates.mjs, all green at00ad76978:check:published-readme-exports·check:nul-bytes(+ manual control-char scan) ·spec check:liveness·spec check:strictness-ledger·spec check:empty-state·spec check:variant-docs·check:merge-driver·check:type-source-resolution·check-dev-prereqs·docs-audit/check-affected-docsPlus
@objectstack/spectest 409 files / 10937 tests passed, andtypecheckOK.Out of scope
Rule #3namesRequestEnvelopeandResponseEnvelopein prose; neither exists as an export (onlyResponseEnvelopeConfig*). Prose symbols are the gate's structural blind spot and were explicitly kept in #9532's lane by the PM ruling, so they are filed separately rather than folded in here.#9544is a separate card and its README files are untouched.Generated by Claude Code