{
  "identity": {
    "name": "incierge",
    "domain": "incierge.jp",
    "kind": "personal IP project",
    "canonical_url": "https://incierge.jp"
  },
  "purpose": "A record of what incierge claims, what it has tested, and what it has been wrong about, published so it can be checked rather than believed. Not a product description and not a company page.",
  "protocol_version": "0.2.0",
  "schema_version": "0.1.0",
  "mode": "live",
  "generated_at": "2026-08-16T00:52:38.377Z",
  "log_head": {
    "seq": 303,
    "hash": "e9edd34fe267fbaff3b13aff3357ec2758d14e315b42944fe5ef4346c413aef1"
  },
  "capabilities": [
    {
      "name": "read_state",
      "description": "Current derived state, projected from the event log.",
      "method": "GET",
      "url": "https://incierge.jp/api/state",
      "status": "available"
    },
    {
      "name": "read_capability",
      "description": "What incierge knows, does not know, and cannot yet settle without outside evidence.",
      "method": "GET",
      "url": "https://incierge.jp/api/capability",
      "status": "available"
    },
    {
      "name": "read_evidence",
      "description": "Measurements bearing on claims, with producer provenance.",
      "method": "GET",
      "url": "https://incierge.jp/api/evidence",
      "status": "available"
    },
    {
      "name": "read_log",
      "description": "The append-only hash-chained publication log.",
      "method": "GET",
      "url": "https://incierge.jp/api/events",
      "status": "available"
    },
    {
      "name": "read_schema",
      "description": "JSON Schema for every record type served here.",
      "method": "GET",
      "url": "https://incierge.jp/api/schema",
      "status": "available"
    },
    {
      "name": "submit_challenge",
      "description": "Submit a counterexample or failure report. Accepted as an untrusted observation: it never changes state directly and is never published automatically.",
      "method": "POST",
      "url": "https://incierge.jp/api/challenges",
      "status": "available"
    }
  ],
  "evidence_model": {
    "canonical": "append-only event log; every other document is a projection of it",
    "order": [
      "claim",
      "falsifier",
      "experiment",
      "measurement",
      "evidence"
    ],
    "rules": [
      "a claim cannot exist without a falsifier",
      "a falsified claim never returns to verified; a narrowed successor is a new claim",
      "evidence contradicting a claim cannot be deleted, only superseded",
      "events are hash-chained; any rewrite changes every subsequent hash"
    ],
    "verify": "https://incierge.jp/api/events"
  },
  "languages": {
    "canonical": "en",
    "localizations": [
      "ja"
    ]
  },
  "endpoints": {
    "state": "https://incierge.jp/api/state",
    "capability": "https://incierge.jp/api/capability",
    "claims": "https://incierge.jp/api/claims",
    "evidence": "https://incierge.jp/api/evidence",
    "experiments": "https://incierge.jp/api/experiments",
    "falsifications": "https://incierge.jp/api/falsifications",
    "limitations": "https://incierge.jp/api/limitations",
    "external": "https://incierge.jp/api/external",
    "challenges": "https://incierge.jp/api/challenges",
    "events": "https://incierge.jp/api/events",
    "schema": "https://incierge.jp/api/schema",
    "protocol": "https://incierge.jp/api/protocol"
  },
  "item_url_template": "https://incierge.jp/api/{collection}/{slug}.json",
  "capability_endpoint": "https://incierge.jp/api/capability",
  "challenge_submission_schema": {
    "method": "POST",
    "url": "https://incierge.jp/api/challenges",
    "content_types": {
      "application/json": "agent path. No human verification challenge, because a CAPTCHA is a test a person can pass and an agent cannot; rate limited more tightly instead.",
      "application/x-www-form-urlencoded": "browser path. Requires a Turnstile token."
    },
    "required": [
      "kind",
      "claim_target",
      "observation",
      "reproduction",
      "expected_failure"
    ],
    "optional": [
      "environment",
      "declared_source",
      "submitted_by"
    ],
    "kinds": [
      "counterexample",
      "failure_report",
      "repository_submission",
      "claim_challenge"
    ],
    "returns": {
      "challenge_id": "string",
      "received_at": "date-time",
      "trust": "untrusted_observation"
    }
  },
  "challenge_response_schema": {
    "url_template": "https://incierge.jp/api/challenges/{slug}.detail.json",
    "fields": [
      "challenge_status",
      "challenge",
      "related_claim",
      "experiment",
      "evidence",
      "falsification",
      "limitations",
      "provenance"
    ]
  },
  "trust_model": {
    "external_input": "untrusted_observation — never executed, never published automatically, and unable to change any claim's status directly",
    "verification": "internal — a claim moves only on a measurement produced by a named producer",
    "honest_ceiling": "no independent verifier exists yet; evidence here reaches self_verified at best"
  },
  "evidence_endpoint": "https://incierge.jp/api/evidence",
  "challenge_endpoint": "https://incierge.jp/api/challenges",
  "limitations": [
    {
      "id": "limitation/a-submission-never-ingested-reads-as-no-measurement",
      "statement": "The probe will not judge a submission the record has not taken up. Ingestion is non-blocking in the scheduled cycle by design — the queue holds items for 180 days and a network failure there must not stop the measurement that follows — so a cycle can complete and publish having ingested nothing. If the probe judged then, one skipped fetch would terminally falsify this claim over a submission the next cycle would have carried. So it waits, and if its window expires with the submission still un-ingested the run is recorded as no measurement. The blind spot that leaves is real and is the reason this record exists: a pipeline that stops ingesting altogether produces silence here rather than a refutation, which is the one failure mode this instrument cannot report. It is visible in the cycle log, where each failed ingest is written, and in the queue depth — but not in this claim. Closing it needs a separate measurement of ingestion itself, on a claim of its own, rather than a timeout dressed up as a verdict."
    },
    {
      "id": "limitation/a-test-appended-a-real-event-to-the-canonical-log",
      "statement": "Event pub/000301 is an attest on claim/scheduled-ingestion-carries-pending-challenges written by a regression test, not by anyone deciding to publish. Its actor reads agent:t, which is a fixture name. The content it binds is correct — the hash it carries is the claim's real content hash — so the record is not false, but the act was not intended and no one authorised it. The cause is worth stating exactly, because it is the second time in one session that a test reached a production path: scripts/lib/load.mjs derives ROOT from the module's own location, so a tool invoked with a different working directory still writes to the log sitting next to it. The test set cwd to a scratch directory and copied data/ and schemas/ there, believing that isolated it; it did not, and the mutation run of that very check appended this event. The test now copies scripts/ as well and invokes the copied tool, so the copy resolves its own ROOT into the scratch directory, and it asserts on every run that the real log did not grow. The event stays. It was committed and pushed to the branch production builds from before it was noticed, and removing it would rewrite a published chain, which is the single act this log exists to prevent. What has no mechanical guard is the general case: nothing stops another tool or test from resolving ROOT into the live tree, and the same class produced two separate incidents today — see limitation/two-probe-submissions-entered-the-queue-from-a-test."
    },
    {
      "id": "limitation/adapter-output-is-not-localized",
      "statement": "Records generated by an adapter from a real producer are published in English only. Translating them would mean a person writing Japanese prose for each run, which would put a human step back into a path that was built to avoid one. The Japanese pages therefore fall back to English on exactly these records and mark them untranslated. The fix is for adapters to emit both languages from the same template, not for someone to translate each run."
    },
    {
      "id": "limitation/chain-is-tamper-evident-not-tamper-proof",
      "statement": "The hash chain makes alteration detectable to someone holding an earlier head. It does not make alteration impossible, and three specific gaps are worth naming rather than leaving for a reader to find. First, actor and gate are self-attested: an event carrying actor.kind \"agent\" and gate \"automated\" asserts those facts, and nothing signs them, so the chain records who the writer said it was. Second, entity bodies are not bound to the chain — the replay binds entity_ref and status, so a statement inside an entity file can be edited without breaking any hash, and only the separate content scan and review would notice. Third, whoever can write the log can recompute it end to end; the promotion gate now refuses a head whose events.jsonl is not a byte-extension of the published one, which constrains the automated route specifically, but that is a check on one path and not a cryptographic property of the record. The practical consequence for a reader: pin a head you have seen. Fetching the log once tells you what is being asserted now, not that it is what was asserted before. Independent signatures and entity-body binding are not implemented, and until they are, this record is evidence that can be audited rather than evidence that cannot be forged."
    },
    {
      "id": "limitation/challenge-lifecycle-probe-window-was-shorter-than-the-cycle",
      "statement": "The instrument that refuted this claim could not have confirmed it. The lifecycle probe submitted a challenge to the production endpoint, waited five seconds, and then judged all four stages — while ingestion in this system runs once a day, on the scheduled cycle. No arrangement of the machinery could carry a submission to the public log inside that window, so the reading `stages_completed` could not exceed 1 and the verdict GREEN was unreachable for every possible state of the thing being measured. A test whose positive result is unreachable is not a strict test; it is a test that has already decided. The refutation recorded on 2026-08-13 was also true on the merits that day, because scheduled ingestion did not exist yet: it landed on 2026-08-14, and from then until 2026-08-16 the window alone held the reading down. This is disclosure, not repair of the verdict: the falsification stands as the record of what was said and measured, `falsified` is terminal here by design, and the corrected question is asked by a successor claim whose statement, falsifier and instrument all name the same window — one scheduled cycle. What this does not tell you is what the reading would have been between 2026-08-14 and 2026-08-16 had the window been right; nobody measured it, and the successor starts from now."
    },
    {
      "id": "limitation/default-client-user-agents-are-refused",
      "statement": "This surface is meant to be fetched by programs, and the edge refuses one of the commonest ways a program fetches. A request carrying Python's standard-library default User-Agent (Python-urllib/*) is answered 403 with Cloudflare error 1010 — the browser integrity check — before anything published here is consulted. The same URL returns 200 to curl, python-requests, ClaudeBot, GPTBot and a browser; measured 2026-08-15 against /api/state. The practical cost is borne by exactly the reader this site is for: the first ten lines a stranger writes to check the log, urllib.request.urlopen, come back refused, and a refusal at the edge is indistinguishable from the site not wanting to be read. Nothing in the record caused it and nothing in the record can repair it — the check is a zone setting, and the credential this project holds covers bot management and zone read only, so even reading that setting returns Unauthorized. Turning the check off across the whole site would pay for this with a protection that is otherwise doing its job; the narrower repair is to skip it for /api/ and /.well-known/, which needs a rule this project cannot currently write. Until one of those happens, the workaround is complete and costs one line: send any User-Agent header at all."
    },
    {
      "id": "limitation/lifecycle-audit-shares-its-own-rate-limit",
      "statement": "The producer that audits the challenge lifecycle submits through the same endpoint it audits, so consecutive runs hit that endpoint's per-agent rate limit and measure the auditor's request budget rather than the loop. One evidence record already published under this claim was produced that way: it reports zero stages completed with the first open stage as acceptance, which is an artifact of a 429 and not a property of the endpoint — a manual submission minutes earlier returned 201. The producer now reports rate limiting explicitly and records such runs as inconclusive. The earlier record is left in place because evidence is not deleted here; this limitation is how it is corrected."
    },
    {
      "id": "limitation/no-independent-verifier-yet",
      "statement": "No independent party has reproduced any evidence on this surface, so every verification level honestly stops at self_verified. The acceptance contract for independent verification exists (see /api/schema, verification.schema.json): a third party may submit the evidence id, their reproduced result, environment, method and result hash, and the transition to independently_reproduced happens only when the correspondence machine-checks — an external party declaring 'verified' moves nothing by itself. This limitation stays open until a real verifier appears; it is not satisfiable by this project simulating one."
    },
    {
      "id": "limitation/promotion-credential-is-operator-held",
      "statement": "Promotion to production is now automated, and the honest cost of that is stated here. The hosted route remains blocked: the platform does not allow an automation identity to bypass a branch rule on a personal repository, so the scheduled cycle promotes locally instead, using the operator-held credential that already lives on the operating machine, constrained by the same data-only gate (any diff touching anything outside data/ is refused, as is any non fast-forward). On a single-operator machine this separation is procedural, not cryptographic: the remote branch rule is a hard boundary only against the publisher's own key, and a process that fully controlled this machine could use the operator credential directly. The superseded record said reaching production requires a person; it no longer does, and this record replaces that claim with the actual remaining weakness."
    },
    {
      "id": "limitation/publication-is-automated-producer-is-not",
      "statement": "The publication path requires no human step: validation, projection, build and deploy run without anyone approving content, and /api/state reports how many events were automated versus human. What is NOT autonomous is the producer — the records themselves are still authored by an agent acting on a person's instruction, not generated by incierge observing itself. Calling this surface autonomously published would be true; calling it autonomously produced would not."
    },
    {
      "id": "limitation/sample-seed-data-only",
      "statement": "SAMPLE. Every record currently published is seed data that exists to exercise the pipeline. The mechanism is real; the contents are not yet incierge's actual claims."
    },
    {
      "id": "limitation/sample-self-verification-only",
      "statement": "SAMPLE. No independent verifier exists yet, so evidence on this surface can honestly reach self_verified and no further. The schema keeps independently_reproduced as a distinct level precisely so that this gap stays visible instead of being smoothed over by the word \"verified\"."
    },
    {
      "id": "limitation/site-copy-is-outside-the-log",
      "statement": "The log covers the record types under data/ — claims, experiments, evidence, challenges, falsifications, limitations and external observations — and nothing else. It does not cover the prose that ships inside the page templates and the interface strings: a change to what a page says is built and deployed with no event, no sequence number and no content hash, and the head is the same afterwards as it was before. Observed on 2026-08-15: commit 313a683 added a Source section to /protocol and reached production (build_ref 313a683, snapshot generated_at 2026-08-15T07:07:22Z) while the head stayed at pub/000222, which the scheduled cycle had written the previous evening. Until then the log page described itself as the canonical artifact of which the rest of the site is a projection; that was true of record content and false of page copy, and the wording has been narrowed to what the log actually covers rather than left to overstate it. Placing page copy under the chain would require an entity type that does not exist yet, so for now the gap is declared rather than closed, and no check prevents a future page edit from asserting more than the records support."
    },
    {
      "id": "limitation/submitter-prose-is-projected-only-as-the-falsifier",
      "statement": "One field of submitter prose is published, deliberately, and the superseded record denied it. The corrected account: (1) submitter free text does not enter the public pipeline except for expected_failure, which is projected because it is the submission's falsifier and a challenge protocol that discards the falsifier is not a challenge protocol — it is scanned at write time against a fixed list of secret shapes and withheld in its entirety on a hit, and no other free-text field is projected; (2) apart from that one field, only the structured allowlist projection computed at intake enters the public lifecycle, where it traverses to experiments and evidence mechanically; (3) the raw private fields are structurally invisible to the publication producer — the machine that builds public records is never given them, so no review step exists to skip; (4) the input's trust level is untrusted_observation from receipt to published terminal state, and nothing a submitter writes can change a claim's status directly. The superseded record opened by asserting that submitter free text never enters the public pipeline. The discovery document has described the expected_failure exception correctly since intake was built, so what was wrong was the limitation's own first clause, not the system it described. A limitation that overstates the guarantee is the same failure as a claim that overstates the result."
    },
    {
      "id": "limitation/the-lifecycle-probe-target-must-clear-both-the-intake-and-the-registry",
      "statement": "The probe that measures this claim cannot submit a challenge against the claim itself, and its target has to clear two independent gates that are easy to confuse. The first is the public intake, which matches the submitted target against the ITEMS of /api/claims.json and answers 400 unknown_claim_target for anything else — and a retracted claim is carried under `retired`, not `items`. The second is the producer registry, without an entry in which the deriving adapter marks the challenge unactionable, because the submitter's prose is withheld at intake by design and there is nothing else to derive a method from. The predecessor of this record named a target that cleared the registry and not the intake, which would have stopped the probe at stage one; before that it named a target that cleared neither. This claim's own measurement is two-phase and cannot be registered at all, so it can never be its own target. The probe now names claim/scheduled-ingestion-carries-pending-challenges, which is in the public items and has a registered producer that is a pure read of the record — deterministic, side-effect-free, and currently supporting its claim, so routing a challenge to it exercises the pipeline without disturbing what it measures. Two consequences remain, both real: the measurement says a submission travels, not that a submission about THIS claim travels; and if that target's producer ever returns an invalid measurement, no evidence is created and this claim reads RED for a reason that is about the target rather than about the traversal."
    },
    {
      "id": "limitation/the-producer-registry-cannot-route-a-two-phase-measurement",
      "statement": "A challenge submitted from outside is routed to a measurement through the producer registry, and that registry can only express one shape of measurement: run a script, read one verdict, finish. The lifecycle probe cannot be that shape. It submits in one scheduled cycle and reads back in the next, because the ingestion it measures runs once a day, so a single invocation has nothing to report yet. Under the registry's contract that reply is indistinguishable from a permanent inability to measure, and the deriving adapter would move the challenge's experiment to a terminal inconclusive state on the submission run alone. The consequence, stated plainly: a challenge whose target is claim/challenge-from-outside-completes-within-one-scheduled-cycle will be routed to no producer. If it carries a usable reproduction it still becomes an experiment; if it does not, it is marked unactionable and the reason is published, which is the honest outcome and not a silent drop. The claim itself is still measured every cycle, by the scheduled path rather than by challenge routing. Closing this needs the registry and the deriving adapter to carry a measurement that spans cycles — a change to the routing contract, not to the probe."
    },
    {
      "id": "limitation/the-read-back-boundary-took-three-attempts",
      "statement": "Deciding when it is fair to read back a submission took three attempts, and the first two failed in the same direction: they permitted the reading while the answer was still in transit, which produces a refutation about the instrument's timing rather than about the machinery. The first said 'within one scheduled cycle' and read production during that cycle — but a cycle ingests at its first step and publishes near its last, so what it read was the previous cycle's surface. The second said 'once the published head has moved past where it stood at submission' — but the cycle before the ingesting one publishes too, and its publication satisfies that test while containing nothing about this challenge. Both would have reported the same refutation regardless of how well the pipeline worked. The boundary that holds is synchronisation: read back when the public head equals this record's head, because only then is an absent stage absent rather than on its way. Each mis-windowed claim was retired unmeasured rather than amended, because a pre-registered falsifier that can be rewritten after the fact is not a pre-registration. Recorded as a limitation because the pattern is the point: an instrument that cannot return its positive verdict is not strict, it has already decided, and three of the four ways this one acquired that property were invisible until an independent reader looked at the ordering of the machinery rather than at the code."
    },
    {
      "id": "limitation/the-sealer-can-push-a-tree-that-cannot-build",
      "statement": "Everything the superseded record established still holds: a separate periodic process on this host seals working trees, stages the whole tree with no path restriction, commits under a registered exemption from the commit-scope check, and pushes to the default branch under the operator's credential, having been subscribed to this repository as a side effect of registering it as a tracked project. What that record could not yet state, it hedged: the in-progress edits it caught on 2026-08-13 were valid and the suite was green at that moment, which it called luck about timing rather than a control. On 2026-08-15T11:02:12Z the timing fell the other way. It caught a limitation record whose create and publish events had not been written yet, together with the interface string that referred to it, and pushed both. That tree does not pass the validator — an entity that never entered through the log is exactly what it refuses — and validation is the first step of the build, so no deployment could have been produced from it. The default branch carried a state that cannot build for about three minutes, until the missing events were appended and pushed. Two things follow, and they are the reason this record replaces its predecessor rather than sitting beside it. The sealer runs no gate of its own: the local suite the scheduled cycle must pass before it may commit is not on this path at all, so 'nothing that fails the suite reaches the default branch' is a property of the publisher and of no other writer here. And the exposure is not confined to an unfinished edit becoming visible; a partial write can also leave the repository unable to build, which is a failure the sealer cannot see because nothing on its path looks."
    },
    {
      "id": "limitation/thirty-eight-events-were-stamped-in-the-future",
      "statement": "Events pub/000231 through pub/000268 carry timestamps between 2026-08-16T00:52:00Z and 2026-08-16T03:05:00Z, and none of them can be true. They were written by hand during a session that ran from about 2026-08-15T15:40Z to 2026-08-15T17:10Z, and the author stamped them with the local wall clock — Japan Standard Time, nine hours ahead — while labelling the field Z. The log therefore asserts that work happened up to ten hours before it could have. Every other check passed: the schema accepted the shape, the chain verified, the content bindings matched, the local suite was green. Nothing compared a timestamp against the present, so a record whose whole value is that things happened, in this order, at these times, had no opinion about the third of those. The events are not corrected. They are published, and this log does not rewrite what it published; a wrong record that stays visible with its error described is worth more than a tidy one. What has changed is that the validator now refuses any event from pub/000269 onward dated more than five minutes ahead of the clock reading it, so the same mistake cannot be made silently again. Anyone reconstructing the ordering of that session should read the git commit times, which are correct."
    },
    {
      "id": "limitation/two-probe-submissions-entered-the-queue-from-a-test",
      "statement": "Two conforming challenges reached the live intake on 2026-08-15, between roughly 17:14Z and 17:16Z, from a regression test rather than from the measurement path. Both were accepted with HTTP 201 and are in the queue; the next scheduled cycle will ingest them, derive experiments named after them, and publish the results exactly as it would for any submission. Nothing about them is false — they carry declared_source producer/challenge-loop-audit and they conform — but they were not a measurement anyone intended to take, and a reader counting external submissions should know that two of them came from this machine. The cause: a test wrote an unreadable state file and ran the two-phase probe to check that it would not judge. With no pending probe the producer does the other thing it exists to do, which is submit. Because that suite runs inside the daily cycle, it would have added one submission per day indefinitely. The test now keeps every fixture on a branch that returns before the network, and says why. What this does not have is a mechanical guard: nothing stops a future test from reaching the submitting branch, and the queue has no path to withdraw a submission once accepted — by design, since an intake that can retract what it received is not an append-only record of what it received."
    }
  ],
  "write_surface": {
    "challenges": {
      "method": "POST",
      "url": "https://incierge.jp/api/challenges",
      "kinds": [
        "counterexample",
        "failure_report",
        "repository_submission",
        "claim_challenge"
      ],
      "note": "Human verification required. Submissions enter a private review queue and are never executed or published automatically."
    }
  }
}
