docs(contract): make the Website Appraisal the active repo truth - #58
Conversation
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
📝 WalkthroughWalkthroughThe repository identifies The Website Appraisal as TinyStudio’s current offer. It documents human-reviewed delivery, preserves Agent Desk legacy behavior, marks older specifications as historical or superseded, and adds product contract tests to the main test command. ChangesWebsite Appraisal product contract
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: eec3fe3904
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| ## Boundaries | ||
|
|
||
| - The public app stores email and lightweight usage metadata only; submitted business context is processed to generate output and is not stored. |
There was a problem hiding this comment.
Disclose the stored appraisal URL
For every appraisal submission to /api/signups, the required website value is normalized and persisted in email_signups (src/worker.js:299-321, backed by migrations/0004_signup_website.sql), so this newly declared boundary is false: the app stores a user-submitted page/business identifier in addition to email and usage metadata. Because this is now the active product contract and README/MEMORY repeat the claim, either disclose website storage explicitly or stop persisting it.
Useful? React with 👍 / 👎.
| if (text.includes(OLD_README_LEAD)) { | ||
| issues.push("README must not present the retired Agent Desk as the product lead"); | ||
| } | ||
| if (text.includes(OLD_MEMORY_LINE)) { | ||
| issues.push("MEMORY must not present the Agent Desk reopening framing"); |
There was a problem hiding this comment.
Reject active Agent Desk wording, not only old literals
If a future top-level document says, for example, The Agent Desk is the current product while retaining mentions of The Website Appraisal and human-reviewed delivery elsewhere, currentFramingIssues() returns no violation because it rejects only these exact historical sentences; the remaining assertions merely look for retired and legacy anywhere. Consequently, npm test can pass the active-Agent-Desk regression this new guard claims to prevent, so the check should validate the current-product section or explicitly reject active/current Agent Desk framing rather than matching only old byte strings.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/test-product-contract.mjs`:
- Around line 34-39: Strengthen currentFramingIssues and the package description
assertions to reject mixed current-product and legacy Agent Desk framing, not
just isolated substrings or exact old phrases. Add a mixed-framing fixture
covering Website Appraisal/current-product language alongside Agent Desk claims.
Require README and MEMORY checks to associate retirement and legacy wording
specifically with Agent Desk, and reject any package.json description containing
Agent Desk.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 64597126-d3ff-4702-8345-cfd20a483263
📒 Files selected for processing (12)
MEMORY.mdREADME.mdpackage.jsonscripts/test-product-contract.mjsspecs/001-public-buyer-page/plan.mdspecs/001-public-buyer-page/spec.mdspecs/001-public-buyer-page/tasks.mdspecs/002-minimal-input-agent-desk/plan.mdspecs/002-minimal-input-agent-desk/spec.mdspecs/002-minimal-input-agent-desk/tasks.mdspecs/003-wellness-clinic-launch/plan.mdspecs/004-website-appraisal/plan.md
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4d6d6f444d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| - `/agent-desk` (and `/agent-desk.html`): the retired self-serve Agent Desk surface. Explicitly framed as retired, `noindex`, absent from the sitemap, and not the current offer. | ||
| - `/api/agent-audit`: the legacy generation endpoint (Pipeline Brief, Implementation Checklist, Weekly Fix Report) used by the retired Agent Desk surface. Still live and operational; never described as the current offer or as removed. | ||
| - D1 usage metadata and daily rate-limit counters continue to operate for the legacy surface. | ||
| - `app.tinystudio.io` and `api.tinystudio.io` return intentional retired responses. |
There was a problem hiding this comment.
Update the retired-host responses to the current offer
When users visit app.tinystudio.io or api.tinystudio.io, the routes at src/worker.js:1324-1329 still return messages stating that TinyStudio.io “now runs the self-serve Agent Desk” (src/worker.js:1269 and 1291). That publicly presents the newly retired product as current, contradicting the contract introduced here; update both retirement responses to point to The Website Appraisal.
Useful? React with 👍 / 👎.
| if (AGENT_DESK_NEGATED.test(line)) continue; | ||
| if (AGENT_DESK_DEMOTED.test(line)) continue; |
There was a problem hiding this comment.
Check active framing before accepting demotion words
If a top-level file says The retired Agent Desk is now the current product, the active pattern matches, but this short-circuit discards the line merely because it also contains retired, allowing the contradictory framing through npm test. The new line-level demotion short-circuit is fresh evidence beyond the prior review comment: demotion and negation terms need to be associated with the product claim rather than exempting the entire line.
Useful? React with 👍 / 👎.
| const negated = section.split(/\r?\n/).some( | ||
| (line) => GUARANTEE_TERMS.test(line) && GUARANTEE_NEGATIONS.test(line) | ||
| ); |
There was a problem hiding this comment.
Reject positive guarantees even when a disclaimer remains
If the Boundaries section retains one disclaimer such as No revenue guarantees but adds another line such as We guarantee ten booked calls, this existential check still returns no issue. Because future edits will normally leave the existing disclaimer in place, the regression guard can pass the exact positive guarantee it claims to prohibit; inspect guarantee-bearing lines for unnegated promises instead of only requiring one negated occurrence.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 65a713d820
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // document body. | ||
| function hasLeadingStatus(text, marker) { | ||
| const banner = leadingStatusBanner(text); | ||
| return banner !== null && banner.includes(marker); |
There was a problem hiding this comment.
Match the complete status declaration
When a leading banner merely references the marker—such as > Previously Status: CURRENT; now retired.—this substring check returns true, and the conflict scan also misses the lowercase retirement wording. The contract test can therefore accept a retired plan as current even though the repository instructions depend on identifying the current plan unambiguously; parse an actual status declaration or require a bounded, exact marker instead.
AGENTS.md reference: AGENTS.md:L2-L3
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
|
/review-bugbot |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 96a10b3bfa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const activeMatch = AGENT_DESK_ACTIVE_PATTERNS | ||
| .map((pattern) => line.match(pattern)) | ||
| .find((match) => match !== null); | ||
| if (activeMatch === undefined) continue; |
There was a problem hiding this comment.
Evaluate every active Agent Desk claim on each line
When a line contains a safely negated match before a later active claim—for example, The Agent Desk is not reopening; the Agent Desk remains the current product—.find() selects only the first /reopen/ match, whose clause contains not, and the later current-product claim is never evaluated. The contract test therefore accepts active Agent Desk framing it is intended to reject. Fresh evidence beyond the prior demotion-word comment is that the revised implementation still short-circuits after the first pattern match; evaluate every matching claim before accepting the line.
AGENTS.md reference: AGENTS.md:L2-L3
Useful? React with 👍 / 👎.
| for (const line of section.split(/\r?\n/)) { | ||
| for (const clause of clausesOf(line)) { | ||
| if (!GUARANTEE_TERMS.test(clause)) continue; | ||
| if (GUARANTEE_NEGATIONS.test(clause)) { | ||
| negated = true; | ||
| continue; |
There was a problem hiding this comment.
Tie each negation to the guarantee it negates
When a positive guarantee shares a comma-delimited clause with an unrelated negation—for example, We guarantee ten booked calls, with no refunds—clausesOf() keeps the text together and this check treats the word no anywhere in it as negating the guarantee. Fresh evidence beyond the prior positive-guarantee comment is that the new clause-level implementation still accepts the specifically prohibited booked-call guarantee; require the negation to govern the guarantee/promise rather than merely occur in the same clause.
AGENTS.md reference: AGENTS.md:L2-L3
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
scripts/test-product-contract.mjs (2)
514-527: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd fixtures for
websiteStorageDisclosed.The fixture test covers status markers, Agent Desk framing, and guarantee clauses. It does not cover
websiteStorageDisclosed. That helper is currently exercised only through the realspecs/004-website-appraisal/plan.md, so its negative branch is never proven. The reversed-order gap reported on lines 252-259 would be caught by such a fixture.♻️ Suggested fixtures
+ // Website-storage disclosure: a positive disclosure passes, and a denial + // must not count as disclosure in either word order. + assert.equal( + websiteStorageDisclosed("- `/api/signups` stores the email and the normalized website URL in D1."), + true, + "an explicit storage disclosure must pass" + ); + assert.equal( + websiteStorageDisclosed("- The submitted website URL is not stored."), + false, + "a denial must not count as disclosure" + ); + assert.equal( + websiteStorageDisclosed("- We do not store the submitted website URL."), + false, + "a verb-first denial must not count as disclosure" + ); });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/test-product-contract.mjs` around lines 514 - 527, Extend the fixture tests in scripts/test-product-contract.mjs to cover websiteStorageDisclosed, including a negative fixture that exercises the reversed-order case described in the comment. Assert that undisclosed website-storage usage is reported while properly disclosed usage is accepted, using the existing fixture-test patterns and the websiteStorageDisclosed helper.
336-339: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueCompute the Boundaries issues once.
Line 336 calls
boundaryGuaranteeIssues(plan)twice. Node evaluates the message argument even when the assertion passes. Store the result in a local constant.♻️ Proposed refactor
- assert.deepEqual(boundaryGuaranteeIssues(plan), [], boundaryGuaranteeIssues(plan).join("; ")); + const guaranteeIssues = boundaryGuaranteeIssues(plan); + assert.deepEqual(guaranteeIssues, [], guaranteeIssues.join("; "));🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/test-product-contract.mjs` around lines 336 - 339, Update the boundary assertion in the contract test to compute boundaryGuaranteeIssues(plan) once, store the result in a local constant, and reuse it for both the deep-equality check and its joined failure message.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/test-product-contract.mjs`:
- Around line 134-139: Update AGENT_DESK_ACTIVE_PATTERNS so the verb alternation
in pattern 4 requires a word boundary before is, remains, and becomes. Also add
word boundaries to the bare status terms in patterns 2 and 3, preventing matches
inside words such as “This,” “inactive,” or “feedback” while preserving
legitimate Agent Desk activity matches.
- Around line 252-259: Update WEBSITE_NOT_STORED and websiteStorageDisclosed so
negated statements with the verb before “website” are detected, including
patterns such as “do not store ... website.” Preserve the existing website-first
negation check and ensure either word order prevents websiteStorageDisclosed
from returning true.
- Around line 218-219: Update GUARANTEE_TERMS to match inflected forms such as
“guaranteed” and “promised,” while preserving the existing word-boundary
behavior and coverage of singular and plural guarantee/promise terms. Keep
GUARANTEE_NEGATIONS unchanged.
---
Nitpick comments:
In `@scripts/test-product-contract.mjs`:
- Around line 514-527: Extend the fixture tests in
scripts/test-product-contract.mjs to cover websiteStorageDisclosed, including a
negative fixture that exercises the reversed-order case described in the
comment. Assert that undisclosed website-storage usage is reported while
properly disclosed usage is accepted, using the existing fixture-test patterns
and the websiteStorageDisclosed helper.
- Around line 336-339: Update the boundary assertion in the contract test to
compute boundaryGuaranteeIssues(plan) once, store the result in a local
constant, and reuse it for both the deep-equality check and its joined failure
message.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: fb174d72-8e3e-4be5-a58e-5e003b6e5f37
📒 Files selected for processing (2)
scripts/test-product-contract.mjsspecs/004-website-appraisal/plan.md
🚧 Files skipped from review as they are similar to previous changes (1)
- specs/004-website-appraisal/plan.md
| const AGENT_DESK_ACTIVE_PATTERNS = [ | ||
| /reopen/gi, | ||
| /Agent Desk[^\n.]{0,120}(current|active|alive|returning|back)/gi, | ||
| /(current|active|alive|returning)[^\n.]{0,120}Agent Desk/gi, | ||
| /Agent Desk[^\n.]{0,160}(is|remains|becomes?)\s+(the|our|a)?\s*(current\s+)?(product|offer)/gi | ||
| ]; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Add word boundaries to the verb alternation in pattern 4.
(is|remains|becomes?) has no leading \b. The engine can match the is inside words such as This, basis, or crisis. A legitimate legacy line then trips the guard. Example: The legacy Agent Desk page links to this offer matches Agent Desk ... is offer through Th|is| offer and carries no clause negation, so it reports a false violation.
The same applies to the bare alternations in patterns 2 and 3, where back matches inside feedback and active matches inside inactive.
🐛 Proposed fix
const AGENT_DESK_ACTIVE_PATTERNS = [
/reopen/gi,
- /Agent Desk[^\n.]{0,120}(current|active|alive|returning|back)/gi,
- /(current|active|alive|returning)[^\n.]{0,120}Agent Desk/gi,
- /Agent Desk[^\n.]{0,160}(is|remains|becomes?)\s+(the|our|a)?\s*(current\s+)?(product|offer)/gi
+ /Agent Desk[^\n.]{0,120}\b(current|active|alive|returning|back)\b/gi,
+ /\b(current|active|alive|returning)\b[^\n.]{0,120}Agent Desk/gi,
+ /Agent Desk[^\n.]{0,160}\b(is|remains|becomes?)\s+(the|our|a)?\s*(current\s+)?(product|offer)\b/gi
];📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const AGENT_DESK_ACTIVE_PATTERNS = [ | |
| /reopen/gi, | |
| /Agent Desk[^\n.]{0,120}(current|active|alive|returning|back)/gi, | |
| /(current|active|alive|returning)[^\n.]{0,120}Agent Desk/gi, | |
| /Agent Desk[^\n.]{0,160}(is|remains|becomes?)\s+(the|our|a)?\s*(current\s+)?(product|offer)/gi | |
| ]; | |
| const AGENT_DESK_ACTIVE_PATTERNS = [ | |
| /reopen/gi, | |
| /Agent Desk[^\n.]{0,120}\b(current|active|alive|returning|back)\b/gi, | |
| /\b(current|active|alive|returning)\b[^\n.]{0,120}Agent Desk/gi, | |
| /Agent Desk[^\n.]{0,160}\b(is|remains|becomes?)\s+(the|our|a)?\s*(current\s+)?(product|offer)\b/gi | |
| ]; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/test-product-contract.mjs` around lines 134 - 139, Update
AGENT_DESK_ACTIVE_PATTERNS so the verb alternation in pattern 4 requires a word
boundary before is, remains, and becomes. Also add word boundaries to the bare
status terms in patterns 2 and 3, preventing matches inside words such as
“This,” “inactive,” or “feedback” while preserving legitimate Agent Desk
activity matches.
| const GUARANTEE_TERMS = /\b(guarantee|guarantees|promise|promises)\b/gi; | ||
| const GUARANTEE_NEGATIONS = /\b(no|not|never|must not|without)\b/i; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Cover inflected guarantee and promise forms.
GUARANTEE_TERMS matches only guarantee, guarantees, promise, and promises. A positive claim written as The report is guaranteed within 90 days. or We promised ten booked calls. passes the guard. The Boundaries contract intends to reject those claims.
🐛 Proposed fix
-const GUARANTEE_TERMS = /\b(guarantee|guarantees|promise|promises)\b/gi;
+const GUARANTEE_TERMS = /\b(guarantee[ds]?|guaranteeing|promise[ds]?|promising)\b/gi;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const GUARANTEE_TERMS = /\b(guarantee|guarantees|promise|promises)\b/gi; | |
| const GUARANTEE_NEGATIONS = /\b(no|not|never|must not|without)\b/i; | |
| const GUARANTEE_TERMS = /\b(guarantee[ds]?|guaranteeing|promise[ds]?|promising)\b/gi; | |
| const GUARANTEE_NEGATIONS = /\b(no|not|never|must not|without)\b/i; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/test-product-contract.mjs` around lines 218 - 219, Update
GUARANTEE_TERMS to match inflected forms such as “guaranteed” and “promised,”
while preserving the existing word-boundary behavior and coverage of singular
and plural guarantee/promise terms. Keep GUARANTEE_NEGATIONS unchanged.
| const WEBSITE_STORED = | ||
| /(?:\bwebsite\b[^\n.;]{0,90}\b(?:persist|store|save|keep|kept|retain|record|write)[a-z]*\b|\b(?:persist|store|save|keep|kept|retain|record|write)[a-z]*\b[^\n.;]{0,90}\bwebsite\b)/i; | ||
| const WEBSITE_NOT_STORED = | ||
| /\bwebsite\b[^\n.;]{0,90}\bnot\b[^\n.;]{0,25}\b(?:persist|store|save|keep|kept|retain|record|write)[a-z]*\b/i; | ||
|
|
||
| function websiteStorageDisclosed(section) { | ||
| return WEBSITE_STORED.test(section) && !WEBSITE_NOT_STORED.test(section); | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Detect the reversed word order in the "not stored" contradiction check.
WEBSITE_STORED accepts both orders: website ... store and store ... website. WEBSITE_NOT_STORED accepts only website ... not ... store. A Boundaries sentence such as We do not store the submitted website URL. therefore satisfies WEBSITE_STORED through the second alternative and escapes WEBSITE_NOT_STORED. websiteStorageDisclosed returns true for a document that denies the storage it must disclose.
Add the verb-first negated form.
🐛 Proposed fix
const WEBSITE_NOT_STORED =
- /\bwebsite\b[^\n.;]{0,90}\bnot\b[^\n.;]{0,25}\b(?:persist|store|save|keep|kept|retain|record|write)[a-z]*\b/i;
+ /(?:\bwebsite\b[^\n.;]{0,90}\bnot\b[^\n.;]{0,25}\b(?:persist|store|save|keep|kept|retain|record|write)[a-z]*\b|\b(?:not|never)\b[^\n.;]{0,25}\b(?:persist|store|save|keep|kept|retain|record|write)[a-z]*\b[^\n.;]{0,90}\bwebsite\b)/i;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const WEBSITE_STORED = | |
| /(?:\bwebsite\b[^\n.;]{0,90}\b(?:persist|store|save|keep|kept|retain|record|write)[a-z]*\b|\b(?:persist|store|save|keep|kept|retain|record|write)[a-z]*\b[^\n.;]{0,90}\bwebsite\b)/i; | |
| const WEBSITE_NOT_STORED = | |
| /\bwebsite\b[^\n.;]{0,90}\bnot\b[^\n.;]{0,25}\b(?:persist|store|save|keep|kept|retain|record|write)[a-z]*\b/i; | |
| function websiteStorageDisclosed(section) { | |
| return WEBSITE_STORED.test(section) && !WEBSITE_NOT_STORED.test(section); | |
| } | |
| const WEBSITE_STORED = | |
| /(?:\bwebsite\b[^\n.;]{0,90}\b(?:persist|store|save|keep|kept|retain|record|write)[a-z]*\b|\b(?:persist|store|save|keep|kept|retain|record|write)[a-z]*\b[^\n.;]{0,90}\bwebsite\b)/i; | |
| const WEBSITE_NOT_STORED = | |
| /(?:\bwebsite\b[^\n.;]{0,90}\bnot\b[^\n.;]{0,25}\b(?:persist|store|save|keep|kept|retain|record|write)[a-z]*\b|\b(?:not|never)\b[^\n.;]{0,25}\b(?:persist|store|save|keep|kept|retain|record|write)[a-z]*\b[^\n.;]{0,90}\bwebsite\b)/i; | |
| function websiteStorageDisclosed(section) { | |
| return WEBSITE_STORED.test(section) && !WEBSITE_NOT_STORED.test(section); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/test-product-contract.mjs` around lines 252 - 259, Update
WEBSITE_NOT_STORED and websiteStorageDisclosed so negated statements with the
verb before “website” are detected, including patterns such as “do not store ...
website.” Preserve the existing website-first negation check and ensure either
word order prevents websiteStorageDisclosed from returning true.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e5ce980df2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| - `/api/signups` stores the submitted email and the normalized submitted website URL in D1 alongside lightweight request metadata (source/page path, referer, user agent, timestamps); submitted page content and media are processed to generate output and are not stored, and the website URL is used for appraisal and request handling. | ||
| - No invented outcomes, prices, or guarantees: no revenue, ranking, ROAS, conversion, booked-call, or sales-volume promises anywhere in owned copy. | ||
| - Human review gates fit, claims, client-facing work, delivery/acceptance, and renewal. | ||
| - Current-offer truth lives in `/offer.md` and `/llms.txt`; `README.md`, `MEMORY.md`, and `package.json` must mirror it without contradicting it. |
There was a problem hiding this comment.
Correct the canonical data-handling disclosure
The new plan fixes the earlier storage disclosure, but this line now designates /llms.txt as canonical current-offer truth while public/llms.txt:79-81 still says the app stores only email/usage metadata and does not store submitted business context. Appraisal submissions persist the normalized website URL in src/worker.js:299-323, so machine readers receive a false data-handling statement; update the machine-readable truth and its mirror/guard alongside this plan. This remaining canonical-surface contradiction is fresh evidence beyond the earlier comment about the plan and top-level docs.
AGENTS.md reference: AGENTS.md:L2-L3
Useful? React with 👍 / 👎.
| for (const pattern of AGENT_DESK_ACTIVE_PATTERNS) { | ||
| for (const match of line.matchAll(pattern)) { | ||
| const claimEnd = match.index + match[0].length; | ||
| if (!AGENT_DESK_NEGATED.test(clauseAround(line, claimEnd - 1))) { |
There was a problem hiding this comment.
Bind negation to the Agent Desk claim
When a top-level truth file says The Agent Desk, not The Website Appraisal, is the current human-reviewed product, clauseAround() returns the whole clause and the unrelated not makes this condition accept the active Agent Desk claim; currentFramingIssues() returns no issues and npm test passes. Fresh evidence beyond the earlier line-level comments is that the revised clause-scoped implementation still treats any negation in the clause as governing the matched claim, so the check must associate negation with the Agent Desk predicate itself.
AGENTS.md reference: AGENTS.md:L2-L3
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
…t offer The public site already sells The Website Appraisal (free leak audit of high-ticket service homepages) through a human-reviewed desk, with the self-serve Agent Desk retired but still live at /agent-desk and /api/agent-audit. README, MEMORY, and package.json still described the Agent Desk as the current product; specs 001-003 read as live plans. - README/MEMORY/package.json: name The Website Appraisal and human-reviewed delivery as current truth; document the Agent Desk as retired legacy. - specs 001/002: mark HISTORICAL (retired); spec 003: mark SUPERSEDED with body, pricing, and legal text untouched. - specs/004-website-appraisal/plan.md: new CURRENT plan covering public surfaces, legacy mechanics, boundaries, verification. - scripts/test-product-contract.mjs: deterministic regression guard wired into npm test (no new dependencies) that rejects a return to active Agent Desk framing and validates the current/historical markers.
Refine the candidate Website Appraisal contract guard: - README.md and MEMORY.md now point directly at the current plan, specs/004-website-appraisal/plan.md, so 'read the current plan' resolves unambiguously. - The contract test no longer asserts the exact devDependencies key list, no longer reads unchanged public/ and src/ implementation files, and no longer couples to exact pricing/legal sentence fragments (spec 003's money/legal body stays preserved in-file, unchecked). - It still rejects the retired Agent Desk framings, enforces the HISTORICAL/SUPERSEDED/CURRENT spec markers and current-plan pointers, requires README/MEMORY to carry the current-plan path, and keeps the clean /audit, /agents, /pricing surfaces guarded. - npm test still executes the guard via test:contract.
e5ce980 to
8dffdce
Compare
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8dffdce35c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const WEBSITE_NOT_STORED = | ||
| /\bwebsite\b[^\n.;]{0,90}\bnot\b[^\n.;]{0,25}\b(?:persist|store|save|keep|kept|retain|record|write)[a-z]*\b/i; |
There was a problem hiding this comment.
Detect verb-first website-storage denials
When the Boundaries text uses the natural wording ``/api/signups does not store the submitted website URL in D1, `WEBSITE_STORED` matches `store ... website`, but this negative pattern misses it because it only recognizes `website ... not ... store`; `websiteStorageDisclosed()` therefore returns true for an explicit denial of the storage the current plan requires disclosing. Fresh evidence beyond the earlier disclosure comments is that the final guard itself accepts this contradictory wording, so match both word orders (and add a fixture) before treating the disclosure as valid.
AGENTS.md reference: AGENTS.md:L2-L3
Useful? React with 👍 / 👎.
… against current main (#72) The round-1 candidate lane for the finding 'repository product contract still identifies the retired Agent Desk as current' was abandoned with uncommitted refinements in its worktree (tinystudio-io-lane1-20260810-004533): a test-product-contract.mjs review-gap hardening draft (bounded banner status declaration, per-claim Agent Desk evaluation, negation-precedes-term guarantee check, /api/signups website-URL storage disclosure guard) and the matching plan.md Boundaries disclosure. The same work was already harvested through later rounds and merged as PR #58 (11864a7), whose contract files are content-identical to the abandoned improve branch (8dffdce). This lane re-verified against the current head (1cc7a4e): the abandoned uncommitted plan.md is identical to main; main's script is a refactored superset of the draft with the same semantics plus extra regression fixtures; npm run test:contract passes 8/8 and the full suite passes (headings 6/6, sitemap 7/7, worker 53/53, ui 16/16, check clean). Nothing further to change.
…act item against current main and live (#99) The backlog item 'Replace the retired Agent Desk as the repository's active product contract - README, MEMORY, package metadata, and the current plan still direct agents to rebuild the wrong homepage' (scout 2026-08-09) was already fixed and merged as PR #58 (11864a7), whose contract files are content-identical to the round-1 improve branch, and the abandoned round-1 candidate lane was closed out by PR #72 (872fd23). The item's last annotation (still-seen 2026-08-11) is stale product-checkout evidence that contradicts current origin/main. This lane re-verified every acceptance criterion against the current head (872fd23) and live (2026-08-11): README/MEMORY/package.json describe The Website Appraisal and human-reviewed delivery as the active product contract; specs 001/002 are HISTORICAL - retired, 003 SUPERSEDED, 004 CURRENT; scripts/test-product-contract.mjs is wired into npm test and rejects the old Agent Desk framings (8/8); npm run check passes and npm test passes 90/90 (headings 7/7, sitemap 6/6, worker incl. legacy /api/agent-audit 53/53, UI + AI-answer readiness 16/16, contract 8/8); live / titles 'TinyStudio - The Website Appraisal', /agent-desk titles 'TinyStudio - the retired Agent Desk', and llms.txt/offer.md mark the Agent Desk demoted. Nothing further to change.
…idate worktrees against current main (#117) Judges the seven round-1 candidate worktrees (tsio-product-contract-20260810-{1..5}, tsio-product-contract-refine-20260810-{1,2}) for finding f168b00e05 (repo product contract still identified the retired Agent Desk as current). The premise of 'finished, uncommitted diffs' was stale: every candidate's work is committed and pushed (origin/candidate/*), with only stray .pyc deletions uncommitted. Winner lineage: candidate-1 (docs, tree-identical to improve@4a97738) + refine-1 (guard, tree-identical to improve@eec3fe3) were carried by improve/repository-product-contract-a121ce8c and merged as PR #58 (11864a7); contract files remain byte-identical on current origin/main apart from the wrangler bump. Candidates 2-5 and refine-2 were superseded alternatives, preserved on origin/candidate/*. Full suite green on current head 18128e8: check passed, headings 6/6, sitemap 7/7, worker 55/55, ui 16/16, contract 8/8. Nothing further to change; round closed with a reason.
…on current main and live (#169) Re-verify the abandoned round-1 candidate worktree (/home/nish/workspaces/agent-worktrees/tinystudio-io-lane1-20260810-004533, branch improve/repository-product-contract-a121ce8c, HEAD 96a10b3) for tracker item f168b00e05 ("repository product contract still identifies the retired Agent Desk as current") against origin/main at 47537d6 and the live tinystudio.io surfaces. The contract-bearing work (docs + product-contract guard) and the review-gap refinements the abandoned lane carried as uncommitted hardening have all landed on current main and pass: - scripts/test-product-contract.mjs: 8/8 (incl. WEBSITE_STORED boundary assertion at line 339, matchAll per-claim evaluation, bounded status banner, negation-precedes-term guarantee check) - specs/004-website-appraisal/plan.md: Boundaries discloses /api/signups stores the normalized submitted website URL alongside email - README/MEMORY/package.json: still name The Website Appraisal as current and the Agent Desk as retired - live: homepage titled "TinyStudio — The Website Appraisal"; /llms.txt and /offer.md explicitly demote the Agent Desk Total 109 tests pass, exit 0, zero not ok. Live surfaces match. Round-1 harvest is closed with reason: candidate work harvested through PR #58 and re-verified against 47537d6 and live; nothing further to change. Co-authored-by: fleet-dispatch-lane-worker-tinystudio-io-1 <worker@tinystudio.io>
Makes The Website Appraisal the active repository truth and keeps the retired Agent Desk bounded as legacy mechanics.
intended-outcome: repository instructions and plans identify The Website Appraisal and human-reviewed delivery as current, keep the retired Agent Desk bounded as legacy mechanics, and fail deterministically if active repo truth regresses.
verify: node --test scripts/test-product-contract.mjs
The
verifycommand fails onorigin/mainbecause the product-contract guard is absent there, and passes on this branch (7/7). This change is repository instructions and plans only: no live deployment and no customer-facing behavior changed.Changes: README.md and MEMORY.md now describe The Website Appraisal and the human-reviewed desk as current and point at
specs/004-website-appraisal/plan.md; specs 001/002 are marked HISTORICAL and spec 003 SUPERSEDED (body untouched); the retired/agent-desksurface and/api/agent-auditendpoint stay documented as operational legacy mechanics;package.jsonwirestest:contractintonpm test; a new deterministic regression guard (scripts/test-product-contract.mjs) fails if active repo truth regresses to the Agent Desk framing.Co-Authored-By: Claude noreply@anthropic.com
Summary by CodeRabbit
Documentation
Tests